github.com/docker/compose-on-kubernetes@v0.5.0/internal/convert/statefulSet_test.go (about)

     1  package convert
     2  
     3  import (
     4  	"runtime"
     5  	"testing"
     6  
     7  	"github.com/docker/compose-on-kubernetes/internal/stackresources"
     8  	. "github.com/docker/compose-on-kubernetes/internal/test/builders"
     9  	"github.com/stretchr/testify/assert"
    10  	appsv1 "k8s.io/api/apps/v1"
    11  	apiv1 "k8s.io/api/core/v1"
    12  	"k8s.io/apimachinery/pkg/api/resource"
    13  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    14  )
    15  
    16  func TestStatefulSet(t *testing.T) {
    17  	s, err := StackToStack(*Stack("demo",
    18  		WithService("nginx",
    19  			Image("nginx"),
    20  			WithVolume(Source("mydata"), Target("/data"), Volume),
    21  		),
    22  	), loadBalancerServiceStrategy{}, stackresources.EmptyStackState)
    23  	assert.NoError(t, err)
    24  
    25  	replicas := int32(1)
    26  	revisionHistoryLimit := int32(3)
    27  
    28  	expectedLabels := map[string]string{
    29  		"com.docker.stack.namespace": "demo",
    30  		"com.docker.service.name":    "nginx",
    31  		"com.docker.service.id":      "demo-nginx",
    32  	}
    33  
    34  	statefulSet := s.Statefulsets["nginx"]
    35  
    36  	expectedStatefulSet := appsv1.StatefulSet{
    37  		ObjectMeta: metav1.ObjectMeta{
    38  			Name:        "nginx",
    39  			Labels:      expectedLabels,
    40  			Annotations: expectedAnnotationsOnCreate,
    41  		},
    42  		Spec: appsv1.StatefulSetSpec{
    43  			Selector: &metav1.LabelSelector{
    44  				MatchLabels: expectedLabels,
    45  			},
    46  			Replicas:             &replicas,
    47  			RevisionHistoryLimit: &revisionHistoryLimit,
    48  			Template: apiv1.PodTemplateSpec{
    49  				ObjectMeta: metav1.ObjectMeta{
    50  					Labels: expectedLabels,
    51  				},
    52  				Spec: apiv1.PodSpec{
    53  					Containers: []apiv1.Container{
    54  						{
    55  							Name:            "nginx",
    56  							Image:           "nginx",
    57  							ImagePullPolicy: apiv1.PullIfNotPresent,
    58  							VolumeMounts: []apiv1.VolumeMount{
    59  								{
    60  									Name:      "mydata",
    61  									MountPath: "/data",
    62  								},
    63  							},
    64  						},
    65  					},
    66  					Affinity: makeExpectedAffinity(
    67  						kv(kubernetesOs, "linux"),
    68  						kv(kubernetesArch, "amd64"),
    69  					),
    70  				},
    71  			},
    72  			VolumeClaimTemplates: []apiv1.PersistentVolumeClaim{
    73  				{
    74  					ObjectMeta: metav1.ObjectMeta{
    75  						Name: "mydata",
    76  					},
    77  					Spec: apiv1.PersistentVolumeClaimSpec{
    78  						AccessModes: []apiv1.PersistentVolumeAccessMode{
    79  							apiv1.ReadWriteOnce,
    80  						},
    81  						Resources: apiv1.ResourceRequirements{
    82  							Requests: apiv1.ResourceList{
    83  								apiv1.ResourceStorage: resource.MustParse("100Mi"),
    84  							},
    85  						},
    86  					},
    87  				},
    88  			},
    89  		},
    90  	}
    91  
    92  	assert.Equal(t, expectedStatefulSet, statefulSet)
    93  }
    94  
    95  func TestStatefulSetWithBind(t *testing.T) {
    96  	if runtime.GOOS == "windows" {
    97  		t.Skip("on windows, source path validation is broken (and actually, source validation for windows workload is broken too). Skip it for now, as we don't support it yet")
    98  		return
    99  	}
   100  	stack := Stack("demo",
   101  		WithService("nginx",
   102  			Image("nginx"),
   103  			WithVolume(
   104  				Source("/var/run/postgres/postgres.sock"),
   105  				Target("/var/run/postgres/postgres.sock"),
   106  				Mount,
   107  			),
   108  		),
   109  	)
   110  	s, err := StackToStack(*stack, loadBalancerServiceStrategy{}, stackresources.EmptyStackState)
   111  	assert.NoError(t, err)
   112  	d := s.Deployments["nginx"]
   113  	assert.NotNil(t, d)
   114  	assert.Equal(t, 1, len(d.Spec.Template.Spec.Volumes))
   115  	assert.Equal(t, "/var/run/postgres", d.Spec.Template.Spec.Volumes[0].HostPath.Path)
   116  	assert.Equal(t, "postgres.sock", d.Spec.Template.Spec.Containers[0].VolumeMounts[0].SubPath)
   117  	assert.Equal(t, "/var/run/postgres/postgres.sock", d.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath)
   118  }
   119  
   120  func TestStatefulSetWithVolume(t *testing.T) {
   121  	s, err := StackToStack(*Stack("demo",
   122  		WithService("nginx",
   123  			Image("nginx"),
   124  			WithVolume(
   125  				Source("dbdata"),
   126  				Target("/var/lib/postgresql/data"),
   127  				Volume,
   128  			),
   129  		),
   130  	), loadBalancerServiceStrategy{}, stackresources.EmptyStackState)
   131  	assert.NoError(t, err)
   132  	assert.Contains(t, s.Statefulsets, "nginx")
   133  }
   134  
   135  func TestStatefulSetWithReplicas(t *testing.T) {
   136  	s, err := StackToStack(*Stack("demo",
   137  		WithService("redis",
   138  			Image("redis:alpine"),
   139  			WithVolume(Source("data"), Volume),
   140  			Deploy(Replicas(6)),
   141  		),
   142  	), loadBalancerServiceStrategy{}, stackresources.EmptyStackState)
   143  	assert.NoError(t, err)
   144  	assert.Contains(t, s.Statefulsets, "redis")
   145  	replicas := int32(6)
   146  	revisionHistoryLimit := int32(3)
   147  
   148  	expectedLabels := map[string]string{
   149  		"com.docker.stack.namespace": "demo",
   150  		"com.docker.service.name":    "redis",
   151  		"com.docker.service.id":      "demo-redis",
   152  	}
   153  
   154  	expectedStatefulSetSpec := appsv1.StatefulSetSpec{
   155  		Selector: &metav1.LabelSelector{
   156  			MatchLabels: expectedLabels,
   157  		},
   158  		Replicas:             &replicas,
   159  		RevisionHistoryLimit: &revisionHistoryLimit,
   160  		Template: apiv1.PodTemplateSpec{
   161  			ObjectMeta: metav1.ObjectMeta{
   162  				Labels: expectedLabels,
   163  			},
   164  			Spec: apiv1.PodSpec{
   165  				Containers: []apiv1.Container{
   166  					{
   167  						Name:            "redis",
   168  						Image:           "redis:alpine",
   169  						ImagePullPolicy: apiv1.PullIfNotPresent,
   170  						VolumeMounts: []apiv1.VolumeMount{
   171  							{
   172  								Name: "data",
   173  							},
   174  						},
   175  					},
   176  				},
   177  				Affinity: makeExpectedAffinity(
   178  					kv(kubernetesOs, "linux"),
   179  					kv(kubernetesArch, "amd64"),
   180  				),
   181  			},
   182  		},
   183  		VolumeClaimTemplates: []apiv1.PersistentVolumeClaim{
   184  			{
   185  				ObjectMeta: metav1.ObjectMeta{
   186  					Name: "data",
   187  				},
   188  				Spec: apiv1.PersistentVolumeClaimSpec{
   189  					AccessModes: []apiv1.PersistentVolumeAccessMode{
   190  						apiv1.ReadWriteOnce,
   191  					},
   192  					Resources: apiv1.ResourceRequirements{
   193  						Requests: apiv1.ResourceList{
   194  							apiv1.ResourceStorage: resource.MustParse("100Mi"),
   195  						},
   196  					},
   197  				},
   198  			},
   199  		},
   200  	}
   201  
   202  	assert.Equal(t, expectedStatefulSetSpec, s.Statefulsets["redis"].Spec)
   203  }
   204  
   205  func TestStatefulSetWithUpdateConfig(t *testing.T) {
   206  	s, err := StackToStack(*Stack("demo",
   207  		WithService("nginx",
   208  			Image("nginx"),
   209  			WithVolume(Source("data"), Volume),
   210  			Deploy(Update(Parallelism(2))),
   211  		),
   212  	), loadBalancerServiceStrategy{}, stackresources.EmptyStackState)
   213  	assert.NoError(t, err)
   214  	assert.Contains(t, s.Statefulsets, "nginx")
   215  
   216  	assert.Equal(t, "RollingUpdate", string(s.Statefulsets["nginx"].Spec.UpdateStrategy.Type))
   217  	assert.Equal(t, int32(2), *s.Statefulsets["nginx"].Spec.UpdateStrategy.RollingUpdate.Partition)
   218  }