From c57bc292de21db94eb1501e4bcdd810b7a103e9b Mon Sep 17 00:00:00 2001 From: Peter Schuurman Date: Wed, 1 Feb 2023 21:45:31 -0800 Subject: [PATCH] Add e2e tests for StatefulSetStartOrdinal feature --- test/e2e/apps/statefulset.go | 163 +++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/test/e2e/apps/statefulset.go b/test/e2e/apps/statefulset.go index de5c4649094..f133203b8a2 100644 --- a/test/e2e/apps/statefulset.go +++ b/test/e2e/apps/statefulset.go @@ -1460,6 +1460,162 @@ var _ = SIGDescribe("StatefulSet", func() { framework.ExpectEqual(pod.Spec.NodeName, readyNode.Name) // confirm the pod was scheduled back to the original node }) }) + + ginkgo.Describe("Scaling StatefulSetStartOrdinal [Feature:StatefulSetStartOrdinal]", func() { + ssName := "ss" + labels := map[string]string{ + "foo": "bar", + "baz": "blah", + } + headlessSvcName := "test" + var ss *appsv1.StatefulSet + + ginkgo.BeforeEach(func(ctx context.Context) { + ss = e2estatefulset.NewStatefulSet(ssName, ns, headlessSvcName, 2, nil, nil, labels) + + ginkgo.By("Creating service " + headlessSvcName + " in namespace " + ns) + headlessService := e2eservice.CreateServiceSpec(headlessSvcName, "", true, labels) + _, err := c.CoreV1().Services(ns).Create(ctx, headlessService, metav1.CreateOptions{}) + framework.ExpectNoError(err) + }) + + ginkgo.AfterEach(func(ctx context.Context) { + if ginkgo.CurrentSpecReport().Failed() { + e2eoutput.DumpDebugInfo(ctx, c, ns) + } + framework.Logf("Deleting all statefulset in ns %v", ns) + e2estatefulset.DeleteAllStatefulSets(ctx, c, ns) + }) + + ginkgo.It("Setting .start.ordinal", func(ctx context.Context) { + ginkgo.By("Creating statefulset " + ssName + " in namespace " + ns) + *(ss.Spec.Replicas) = 2 + _, err := c.AppsV1().StatefulSets(ns).Create(ctx, ss, metav1.CreateOptions{}) + framework.ExpectNoError(err) + waitForStatus(ctx, c, ss) + e2estatefulset.WaitForStatusReplicas(ctx, c, ss, 2) + e2estatefulset.WaitForStatusReadyReplicas(ctx, c, ss, 2) + + ginkgo.By("Confirming 2 replicas, with start ordinal 0") + pods := e2estatefulset.GetPodList(ctx, c, ss) + e2estatefulset.SortStatefulPods(pods) + expectPodNames(pods, []string{"ss-0", "ss-1"}) + + ginkgo.By("Setting .spec.replicas = 3 .spec.ordinals.start = 2") + ss, err = updateStatefulSetWithRetries(ctx, c, ns, ss.Name, func(update *appsv1.StatefulSet) { + update.Spec.Ordinals = &appsv1.StatefulSetOrdinals{ + Start: 2, + } + *(update.Spec.Replicas) = 3 + }) + framework.ExpectNoError(err) + e2estatefulset.WaitForStatusReplicas(ctx, c, ss, 3) + e2estatefulset.WaitForStatusReadyReplicas(ctx, c, ss, 3) + + ginkgo.By("Confirming 3 replicas, with start ordinal 2") + pods = e2estatefulset.GetPodList(ctx, c, ss) + e2estatefulset.SortStatefulPods(pods) + expectPodNames(pods, []string{"ss-2", "ss-3", "ss-4"}) + }) + + ginkgo.It("Increasing .start.ordinal", func(ctx context.Context) { + ginkgo.By("Creating statefulset " + ssName + " in namespace " + ns) + *(ss.Spec.Replicas) = 2 + ss.Spec.Ordinals = &appsv1.StatefulSetOrdinals{ + Start: 2, + } + _, err := c.AppsV1().StatefulSets(ns).Create(ctx, ss, metav1.CreateOptions{}) + framework.ExpectNoError(err) + waitForStatus(ctx, c, ss) + e2estatefulset.WaitForStatusReplicas(ctx, c, ss, 2) + e2estatefulset.WaitForStatusReadyReplicas(ctx, c, ss, 2) + + ginkgo.By("Confirming 2 replicas, with start ordinal 2") + pods := e2estatefulset.GetPodList(ctx, c, ss) + e2estatefulset.SortStatefulPods(pods) + expectPodNames(pods, []string{"ss-2", "ss-3"}) + + ginkgo.By("Increasing .spec.ordinals.start = 4") + ss, err = updateStatefulSetWithRetries(ctx, c, ns, ss.Name, func(update *appsv1.StatefulSet) { + update.Spec.Ordinals = &appsv1.StatefulSetOrdinals{ + Start: 4, + } + }) + framework.ExpectNoError(err) + waitForStatus(ctx, c, ss) + e2estatefulset.WaitForStatusReplicas(ctx, c, ss, 2) + e2estatefulset.WaitForStatusReadyReplicas(ctx, c, ss, 2) + + ginkgo.By("Confirming 2 replicas, with start ordinal 4") + pods = e2estatefulset.GetPodList(ctx, c, ss) + e2estatefulset.SortStatefulPods(pods) + expectPodNames(pods, []string{"ss-4", "ss-5"}) + }) + + ginkgo.It("Decreasing .start.ordinal", func(ctx context.Context) { + ginkgo.By("Creating statefulset " + ssName + " in namespace " + ns) + *(ss.Spec.Replicas) = 2 + ss.Spec.Ordinals = &appsv1.StatefulSetOrdinals{ + Start: 3, + } + _, err := c.AppsV1().StatefulSets(ns).Create(ctx, ss, metav1.CreateOptions{}) + framework.ExpectNoError(err) + waitForStatus(ctx, c, ss) + e2estatefulset.WaitForStatusReplicas(ctx, c, ss, 2) + e2estatefulset.WaitForStatusReadyReplicas(ctx, c, ss, 2) + + ginkgo.By("Confirming 2 replicas, with start ordinal 3") + pods := e2estatefulset.GetPodList(ctx, c, ss) + e2estatefulset.SortStatefulPods(pods) + expectPodNames(pods, []string{"ss-3", "ss-4"}) + + ginkgo.By("Decreasing .spec.ordinals.start = 2") + ss, err = updateStatefulSetWithRetries(ctx, c, ns, ss.Name, func(update *appsv1.StatefulSet) { + update.Spec.Ordinals = &appsv1.StatefulSetOrdinals{ + Start: 2, + } + }) + framework.ExpectNoError(err) + waitForStatus(ctx, c, ss) + e2estatefulset.WaitForStatusReplicas(ctx, c, ss, 2) + e2estatefulset.WaitForStatusReadyReplicas(ctx, c, ss, 2) + + ginkgo.By("Confirming 2 replicas, with start ordinal 2") + pods = e2estatefulset.GetPodList(ctx, c, ss) + e2estatefulset.SortStatefulPods(pods) + expectPodNames(pods, []string{"ss-2", "ss-3"}) + }) + + ginkgo.It("Removing .start.ordinal", func(ctx context.Context) { + ginkgo.By("Creating statefulset " + ssName + " in namespace " + ns) + *(ss.Spec.Replicas) = 2 + ss.Spec.Ordinals = &appsv1.StatefulSetOrdinals{ + Start: 3, + } + _, err := c.AppsV1().StatefulSets(ns).Create(ctx, ss, metav1.CreateOptions{}) + framework.ExpectNoError(err) + e2estatefulset.WaitForStatusReplicas(ctx, c, ss, 2) + e2estatefulset.WaitForStatusReadyReplicas(ctx, c, ss, 2) + + ginkgo.By("Confirming 2 replicas, with start ordinal 3") + pods := e2estatefulset.GetPodList(ctx, c, ss) + e2estatefulset.SortStatefulPods(pods) + expectPodNames(pods, []string{"ss-3", "ss-4"}) + + ginkgo.By("Removing .spec.ordinals") + ss, err = updateStatefulSetWithRetries(ctx, c, ns, ss.Name, func(update *appsv1.StatefulSet) { + update.Spec.Ordinals = nil + }) + framework.ExpectNoError(err) + e2estatefulset.WaitForStatusReplicas(ctx, c, ss, 2) + e2estatefulset.WaitForStatusReadyReplicas(ctx, c, ss, 2) + + ginkgo.By("Confirming 2 replicas, with start ordinal 0") + pods = e2estatefulset.GetPodList(ctx, c, ss) + e2estatefulset.SortStatefulPods(pods) + expectPodNames(pods, []string{"ss-0", "ss-1"}) + }) + }) }) func uncordonNode(ctx context.Context, c clientset.Interface, oldData, newData []byte, nodeName string) { @@ -2020,3 +2176,10 @@ func verifyStatefulSetPVCsExistWithOwnerRefs(ctx context.Context, c clientset.In return true, nil }) } + +func expectPodNames(pods *v1.PodList, expectedPodNames []string) { + framework.ExpectEqual(len(pods.Items), len(expectedPodNames), "unexpected number of pods") + for i, pod := range pods.Items { + framework.ExpectEqual(pod.Name, expectedPodNames[i], "unexpected pod name") + } +}