From a962d80b9999b7ad8e1720bbcd5197c15b231eac Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Thu, 2 Apr 2020 10:53:22 +1300 Subject: [PATCH 1/9] Update and improve ReplicationController resource lifecycle test --- test/e2e/apps/rc.go | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index f9a7c7e2d1a..c3ad5e96139 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -32,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" + watch "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/pkg/controller/replication" @@ -139,6 +140,12 @@ var _ = SIGDescribe("ReplicationController", func() { rcWatchChan := rcWatch.ResultChan() + ginkgo.By("waiting for RC to be added") + for watchEvent := range rcWatchChan { + if watchEvent.Type == watch.Added { + break + } + } ginkgo.By("waiting for available Replicas") for watchEvent := range rcWatchChan { rc, ok := watchEvent.Object.(*v1.ReplicationController) @@ -158,6 +165,12 @@ var _ = SIGDescribe("ReplicationController", func() { ginkgo.By("patching ReplicationController") _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcLabelPatchPayload), metav1.PatchOptions{}) framework.ExpectNoError(err, "Failed to patch ReplicationController") + ginkgo.By("waiting for RC to be modified") + for watchEvent := range rcWatchChan { + if watchEvent.Type == watch.Modified { + break + } + } rcStatusPatchPayload, err := json.Marshal(map[string]interface{}{ "status": map[string]interface{}{ @@ -172,6 +185,12 @@ var _ = SIGDescribe("ReplicationController", func() { rcStatus, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcStatusPatchPayload), metav1.PatchOptions{}, "status") framework.ExpectNoError(err, "Failed to patch ReplicationControllerStatus") framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(0), "ReplicationControllerStatus's readyReplicas does not equal 0") + ginkgo.By("waiting for RC to be modified") + for watchEvent := range rcWatchChan { + if watchEvent.Type == watch.Modified { + break + } + } ginkgo.By("fetching ReplicationController status") rcStatusUnstructured, err := dc.Resource(rcResource).Namespace(testRcNamespace).Get(context.TODO(), testRcName, metav1.GetOptions{}, "status") @@ -193,6 +212,12 @@ var _ = SIGDescribe("ReplicationController", func() { ginkgo.By("patching ReplicationController scale") _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcScalePatchPayload), metav1.PatchOptions{}, "scale") framework.ExpectNoError(err, "Failed to patch ReplicationControllerScale") + ginkgo.By("waiting for RC to be modified") + for watchEvent := range rcWatchChan { + if watchEvent.Type == watch.Modified { + break + } + } var rcFromWatch *v1.ReplicationController ginkgo.By("waiting for ReplicationController's scale to be the max amount") @@ -224,12 +249,9 @@ var _ = SIGDescribe("ReplicationController", func() { rcStatus, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).UpdateStatus(context.TODO(), rcStatusUpdatePayload, metav1.UpdateOptions{}) framework.ExpectNoError(err, "failed to update ReplicationControllerStatus") framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(1), "ReplicationControllerStatus readyReplicas does not equal 1") - - ginkgo.By(fmt.Sprintf("waiting for ReplicationController readyReplicas to be equal to %v", testRcMaxReplicaCount)) + ginkgo.By("waiting for RC to be modified") for watchEvent := range rcWatchChan { - rc, ok := watchEvent.Object.(*v1.ReplicationController) - framework.ExpectEqual(ok, true, "unable to convert type of ReplicationController watch watchEvent") - if rc.Status.Replicas == testRcMaxReplicaCount && rc.Status.ReadyReplicas == testRcMaxReplicaCount { + if watchEvent.Type == watch.Modified { break } } @@ -245,9 +267,7 @@ var _ = SIGDescribe("ReplicationController", func() { if rcItem.ObjectMeta.Name == testRcName && rcItem.ObjectMeta.Namespace == testRcNamespace && rcItem.ObjectMeta.Labels["test-rc-static"] == "true" && - rcItem.ObjectMeta.Labels["test-rc"] == "patched" && - rcItem.Status.Replicas == testRcMaxReplicaCount && - rcItem.Status.ReadyReplicas == testRcMaxReplicaCount { + rcItem.ObjectMeta.Labels["test-rc"] == "patched" { foundRc = true } } @@ -260,7 +280,7 @@ var _ = SIGDescribe("ReplicationController", func() { ginkgo.By("waiting for ReplicationController to have a DELETED watchEvent") for watchEvent := range rcWatchChan { - if watchEvent.Type == "DELETED" { + if watchEvent.Type == watch.Deleted { break } } From 54c744f033600645b7cf5f52bac05b1c67ae52c5 Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Mon, 20 Apr 2020 13:57:09 +1200 Subject: [PATCH 2/9] Update patch checks, scale patch type --- test/e2e/apps/rc.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index c3ad5e96139..7a15f956812 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -22,7 +22,6 @@ import ( "fmt" "time" - autoscalingv1 "k8s.io/api/autoscaling/v1" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" @@ -163,8 +162,9 @@ var _ = SIGDescribe("ReplicationController", func() { framework.ExpectNoError(err, "failed to marshal json of replicationcontroller label patch") // Patch the ReplicationController ginkgo.By("patching ReplicationController") - _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcLabelPatchPayload), metav1.PatchOptions{}) + testRcPatched, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcLabelPatchPayload), metav1.PatchOptions{}) framework.ExpectNoError(err, "Failed to patch ReplicationController") + framework.ExpectEqual(testRcPatched.ObjectMeta.Labels["test-rc"], "patched", "failed to patch RC") ginkgo.By("waiting for RC to be modified") for watchEvent := range rcWatchChan { if watchEvent.Type == watch.Modified { @@ -192,6 +192,15 @@ var _ = SIGDescribe("ReplicationController", func() { } } + for watchEvent := range rcWatchChan { + rc, ok := watchEvent.Object.(*v1.ReplicationController) + framework.ExpectEqual(ok, true, "Unable to convert type of ReplicationController watch watchEvent") + + if rc.Status.Replicas == testRcInitialReplicaCount { + break + } + } + ginkgo.By("fetching ReplicationController status") rcStatusUnstructured, err := dc.Resource(rcResource).Namespace(testRcNamespace).Get(context.TODO(), testRcName, metav1.GetOptions{}, "status") framework.ExpectNoError(err, "Failed to fetch ReplicationControllerStatus") @@ -201,9 +210,9 @@ var _ = SIGDescribe("ReplicationController", func() { json.Unmarshal(rcStatusUjson, &rcStatus) framework.ExpectEqual(rcStatus.Status.Replicas, testRcInitialReplicaCount, "ReplicationController ReplicaSet cound does not match initial Replica count") - rcScalePatchPayload, err := json.Marshal(autoscalingv1.Scale{ - Spec: autoscalingv1.ScaleSpec{ - Replicas: testRcMaxReplicaCount, + rcScalePatchPayload, err := json.Marshal(v1.ReplicationController{ + Spec: v1.ReplicationControllerSpec{ + Replicas: &testRcMaxReplicaCount, }, }) framework.ExpectNoError(err, "Failed to marshal json of replicationcontroller label patch") From 29c85b7265cabc77b6878afa98e17084b7e9a40c Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Mon, 20 Apr 2020 15:10:28 +1200 Subject: [PATCH 3/9] Update BUILD --- test/e2e/apps/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/test/e2e/apps/BUILD b/test/e2e/apps/BUILD index 957e001ca62..039a5aac3ce 100644 --- a/test/e2e/apps/BUILD +++ b/test/e2e/apps/BUILD @@ -34,7 +34,6 @@ go_library( "//pkg/master/ports:go_default_library", "//pkg/scheduler/apis/config:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", - "//staging/src/k8s.io/api/autoscaling/v1:go_default_library", "//staging/src/k8s.io/api/batch/v1:go_default_library", "//staging/src/k8s.io/api/batch/v1beta1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", From 1c010beb248213ac6a965a808386b59df89c0b70 Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Wed, 22 Apr 2020 10:01:13 +1200 Subject: [PATCH 4/9] Revert scale patch payload types --- test/e2e/apps/BUILD | 1 + test/e2e/apps/rc.go | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/e2e/apps/BUILD b/test/e2e/apps/BUILD index 039a5aac3ce..957e001ca62 100644 --- a/test/e2e/apps/BUILD +++ b/test/e2e/apps/BUILD @@ -34,6 +34,7 @@ go_library( "//pkg/master/ports:go_default_library", "//pkg/scheduler/apis/config:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", + "//staging/src/k8s.io/api/autoscaling/v1:go_default_library", "//staging/src/k8s.io/api/batch/v1:go_default_library", "//staging/src/k8s.io/api/batch/v1beta1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index 7a15f956812..afe3de89f0e 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -22,6 +22,7 @@ import ( "fmt" "time" + autoscalingv1 "k8s.io/api/autoscaling/v1" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" @@ -210,9 +211,9 @@ var _ = SIGDescribe("ReplicationController", func() { json.Unmarshal(rcStatusUjson, &rcStatus) framework.ExpectEqual(rcStatus.Status.Replicas, testRcInitialReplicaCount, "ReplicationController ReplicaSet cound does not match initial Replica count") - rcScalePatchPayload, err := json.Marshal(v1.ReplicationController{ - Spec: v1.ReplicationControllerSpec{ - Replicas: &testRcMaxReplicaCount, + rcScalePatchPayload, err := json.Marshal(autoscalingv1.Scale{ + Spec: autoscalingv1.ScaleSpec{ + Replicas: testRcMaxReplicaCount, }, }) framework.ExpectNoError(err, "Failed to marshal json of replicationcontroller label patch") From d7d9ebf4820adb4045c0fd16ef72bb2ac5a82f00 Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Wed, 22 Apr 2020 14:34:43 +1200 Subject: [PATCH 5/9] Add checks to each watch loops --- test/e2e/apps/rc.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index afe3de89f0e..776887b96de 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -141,19 +141,26 @@ var _ = SIGDescribe("ReplicationController", func() { rcWatchChan := rcWatch.ResultChan() ginkgo.By("waiting for RC to be added") + eventFound := false for watchEvent := range rcWatchChan { if watchEvent.Type == watch.Added { + eventFound = true break } } + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) + ginkgo.By("waiting for available Replicas") + eventFound = false for watchEvent := range rcWatchChan { rc, ok := watchEvent.Object.(*v1.ReplicationController) framework.ExpectEqual(ok, true, "Unable to convert type of ReplicationController watch watchEvent") if rc.Status.Replicas == testRcInitialReplicaCount && rc.Status.ReadyReplicas == testRcInitialReplicaCount { + eventFound = true break } } + framework.ExpectEqual(eventFound, true, "failed to find event with initial replica count") rcLabelPatchPayload, err := json.Marshal(v1.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ @@ -167,11 +174,14 @@ var _ = SIGDescribe("ReplicationController", func() { framework.ExpectNoError(err, "Failed to patch ReplicationController") framework.ExpectEqual(testRcPatched.ObjectMeta.Labels["test-rc"], "patched", "failed to patch RC") ginkgo.By("waiting for RC to be modified") + eventFound = false for watchEvent := range rcWatchChan { if watchEvent.Type == watch.Modified { + eventFound = true break } } + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Modified) rcStatusPatchPayload, err := json.Marshal(map[string]interface{}{ "status": map[string]interface{}{ @@ -187,20 +197,26 @@ var _ = SIGDescribe("ReplicationController", func() { framework.ExpectNoError(err, "Failed to patch ReplicationControllerStatus") framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(0), "ReplicationControllerStatus's readyReplicas does not equal 0") ginkgo.By("waiting for RC to be modified") + eventFound = false for watchEvent := range rcWatchChan { if watchEvent.Type == watch.Modified { + eventFound = true break } } + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Modified) + eventFound = false for watchEvent := range rcWatchChan { rc, ok := watchEvent.Object.(*v1.ReplicationController) framework.ExpectEqual(ok, true, "Unable to convert type of ReplicationController watch watchEvent") if rc.Status.Replicas == testRcInitialReplicaCount { + eventFound = true break } } + framework.ExpectEqual(eventFound, true, "RC does not have initial replica count") ginkgo.By("fetching ReplicationController status") rcStatusUnstructured, err := dc.Resource(rcResource).Namespace(testRcNamespace).Get(context.TODO(), testRcName, metav1.GetOptions{}, "status") @@ -223,11 +239,15 @@ var _ = SIGDescribe("ReplicationController", func() { _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcScalePatchPayload), metav1.PatchOptions{}, "scale") framework.ExpectNoError(err, "Failed to patch ReplicationControllerScale") ginkgo.By("waiting for RC to be modified") + + eventFound = false for watchEvent := range rcWatchChan { if watchEvent.Type == watch.Modified { + eventFound = true break } } + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Modified) var rcFromWatch *v1.ReplicationController ginkgo.By("waiting for ReplicationController's scale to be the max amount") @@ -260,11 +280,15 @@ var _ = SIGDescribe("ReplicationController", func() { framework.ExpectNoError(err, "failed to update ReplicationControllerStatus") framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(1), "ReplicationControllerStatus readyReplicas does not equal 1") ginkgo.By("waiting for RC to be modified") + + eventFound = false for watchEvent := range rcWatchChan { if watchEvent.Type == watch.Modified { + eventFound = true break } } + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Modified) ginkgo.By("listing all ReplicationControllers") rcs, err := f.ClientSet.CoreV1().ReplicationControllers("").List(context.TODO(), metav1.ListOptions{LabelSelector: "test-rc-static=true"}) @@ -289,11 +313,14 @@ var _ = SIGDescribe("ReplicationController", func() { framework.ExpectNoError(err, "Failed to delete ReplicationControllers") ginkgo.By("waiting for ReplicationController to have a DELETED watchEvent") + eventFound = false for watchEvent := range rcWatchChan { if watchEvent.Type == watch.Deleted { + eventFound = true break } } + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Deleted) }) }) From 209c05546a4761a6fc01dea4bf91333ac50a6f81 Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Thu, 28 May 2020 08:56:38 +1200 Subject: [PATCH 6/9] Update to include watch tooling --- test/e2e/apps/rc.go | 433 +++++++++++++++++++++++++------------------- 1 file changed, 245 insertions(+), 188 deletions(-) diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index 776887b96de..04b81617094 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -32,9 +32,10 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" - watch "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" clientset "k8s.io/client-go/kubernetes" + watchtools "k8s.io/client-go/tools/watch" + watch "k8s.io/apimachinery/pkg/watch" "k8s.io/kubernetes/pkg/controller/replication" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" @@ -104,6 +105,14 @@ var _ = SIGDescribe("ReplicationController", func() { testRcInitialReplicaCount := int32(1) testRcMaxReplicaCount := int32(2) rcResource := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "replicationcontrollers"} + expectedWatchEvents := []watch.Event{ + {Type: watch.Added}, + {Type: watch.Modified}, + {Type: watch.Modified}, + {Type: watch.Modified}, + {Type: watch.Modified}, + {Type: watch.Deleted}, + } rcTest := v1.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ @@ -128,199 +137,247 @@ var _ = SIGDescribe("ReplicationController", func() { }, } - ginkgo.By("creating a ReplicationController") - // Create a ReplicationController - _, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Create(context.TODO(), &rcTest, metav1.CreateOptions{}) - framework.ExpectNoError(err, "Failed to create ReplicationController") + framework.WatchEventSequenceVerifier(context.TODO(), dc, rcResource, testRcNamespace, testRcName, metav1.ListOptions{LabelSelector: "test-rc-static=true"}, expectedWatchEvents, func(retryWatcher *watchtools.RetryWatcher) (actualWatchEvents []watch.Event) { + ginkgo.By("creating a ReplicationController") + // Create a ReplicationController + _, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Create(context.TODO(), &rcTest, metav1.CreateOptions{}) + framework.ExpectNoError(err, "Failed to create ReplicationController") - // setup a watch for the RC - rcWatchTimeoutSeconds := int64(180) - rcWatch, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Watch(context.TODO(), metav1.ListOptions{LabelSelector: "test-rc-static=true", TimeoutSeconds: &rcWatchTimeoutSeconds}) - framework.ExpectNoError(err, "Failed to setup watch on newly created ReplicationController") - - rcWatchChan := rcWatch.ResultChan() - - ginkgo.By("waiting for RC to be added") - eventFound := false - for watchEvent := range rcWatchChan { - if watchEvent.Type == watch.Added { + ginkgo.By("waiting for RC to be added") + eventFound := false + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + if watchEvent.Type != watch.Added { + return false, nil + } + actualWatchEvents = append(actualWatchEvents, watchEvent) eventFound = true - break - } - } - framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) + return true, nil + }) + framework.ExpectNoError(err, "Wait until condition with watch events should not return an error") + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) - ginkgo.By("waiting for available Replicas") - eventFound = false - for watchEvent := range rcWatchChan { - rc, ok := watchEvent.Object.(*v1.ReplicationController) - framework.ExpectEqual(ok, true, "Unable to convert type of ReplicationController watch watchEvent") - if rc.Status.Replicas == testRcInitialReplicaCount && rc.Status.ReadyReplicas == testRcInitialReplicaCount { + ginkgo.By("waiting for available Replicas") + eventFound = false + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + var rc *v1.ReplicationController + rcBytes, err := json.Marshal(watchEvent.Object) + if err != nil { + return false, err + } + err = json.Unmarshal(rcBytes, &rc) + if err != nil { + return false, err + } + if rc.Status.Replicas != testRcInitialReplicaCount || rc.Status.ReadyReplicas != testRcInitialReplicaCount { + return false, nil + } eventFound = true - break - } - } - framework.ExpectEqual(eventFound, true, "failed to find event with initial replica count") + return true, nil + }) + framework.ExpectNoError(err, "Wait for condition with watch events should not return an error") + framework.ExpectEqual(eventFound, true, "RC has not reached ReadyReplicas count of %v", testRcInitialReplicaCount) - rcLabelPatchPayload, err := json.Marshal(v1.ReplicationController{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"test-rc": "patched"}, - }, + rcLabelPatchPayload, err := json.Marshal(v1.ReplicationController{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"test-rc": "patched"}, + }, + }) + framework.ExpectNoError(err, "failed to marshal json of replicationcontroller label patch") + // Patch the ReplicationController + ginkgo.By("patching ReplicationController") + testRcPatched, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcLabelPatchPayload), metav1.PatchOptions{}) + framework.ExpectNoError(err, "Failed to patch ReplicationController") + framework.ExpectEqual(testRcPatched.ObjectMeta.Labels["test-rc"], "patched", "failed to patch RC") + ginkgo.By("waiting for RC to be modified") + eventFound = false + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + if watchEvent.Type != watch.Modified { + return false, nil + } + actualWatchEvents = append(actualWatchEvents, watchEvent) + eventFound = true + return true, nil + }) + framework.ExpectNoError(err, "Wait until condition with watch events should not return an error") + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) + + rcStatusPatchPayload, err := json.Marshal(map[string]interface{}{ + "status": map[string]interface{}{ + "readyReplicas": 0, + "availableReplicas": 0, + }, + }) + framework.ExpectNoError(err, "Failed to marshal JSON of ReplicationController label patch") + + // Patch the ReplicationController's status + ginkgo.By("patching ReplicationController status") + rcStatus, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcStatusPatchPayload), metav1.PatchOptions{}, "status") + framework.ExpectNoError(err, "Failed to patch ReplicationControllerStatus") + framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(0), "ReplicationControllerStatus's readyReplicas does not equal 0") + ginkgo.By("waiting for RC to be modified") + eventFound = false + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + if watchEvent.Type != watch.Modified { + return false, nil + } + actualWatchEvents = append(actualWatchEvents, watchEvent) + eventFound = true + return true, nil + }) + framework.ExpectNoError(err, "Wait until condition with watch events should not return an error") + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) + + ginkgo.By("waiting for available Replicas") + _, err = framework.WatchUntilWithoutRetry(context.TODO(), retryWatcher, func(watchEvent watch.Event) (bool, error) { + var rc *v1.ReplicationController + rcBytes, err := json.Marshal(watchEvent.Object) + if err != nil { + return false, err + } + err = json.Unmarshal(rcBytes, &rc) + if err != nil { + return false, err + } + if rc.Status.Replicas != testRcInitialReplicaCount { + return false, nil + } + return true, nil + }) + framework.ExpectEqual(eventFound, true, "Failed to find updated ready replica count") + + ginkgo.By("fetching ReplicationController status") + rcStatusUnstructured, err := dc.Resource(rcResource).Namespace(testRcNamespace).Get(context.TODO(), testRcName, metav1.GetOptions{}, "status") + framework.ExpectNoError(err, "Failed to fetch ReplicationControllerStatus") + + rcStatusUjson, err := json.Marshal(rcStatusUnstructured) + framework.ExpectNoError(err, "Failed to marshal json of replicationcontroller label patch") + json.Unmarshal(rcStatusUjson, &rcStatus) + framework.ExpectEqual(rcStatus.Status.Replicas, testRcInitialReplicaCount, "ReplicationController ReplicaSet cound does not match initial Replica count") + + rcScalePatchPayload, err := json.Marshal(autoscalingv1.Scale{ + Spec: autoscalingv1.ScaleSpec{ + Replicas: testRcMaxReplicaCount, + }, + }) + framework.ExpectNoError(err, "Failed to marshal json of replicationcontroller label patch") + + // Patch the ReplicationController's scale + ginkgo.By("patching ReplicationController scale") + _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcScalePatchPayload), metav1.PatchOptions{}, "scale") + framework.ExpectNoError(err, "Failed to patch ReplicationControllerScale") + ginkgo.By("waiting for RC to be modified") + eventFound = false + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + if watchEvent.Type != watch.Modified { + return false, nil + } + actualWatchEvents = append(actualWatchEvents, watchEvent) + eventFound = true + return true, nil + }) + framework.ExpectNoError(err, "Wait until condition with watch events should not return an error") + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) + + ginkgo.By("waiting for ReplicationController's scale to be the max amount") + eventFound = false + _, err = framework.WatchUntilWithoutRetry(context.TODO(), retryWatcher, func(watchEvent watch.Event) (bool, error) { + var rc *v1.ReplicationController + rcBytes, err := json.Marshal(watchEvent.Object) + if err != nil { + return false, err + } + err = json.Unmarshal(rcBytes, &rc) + if err != nil { + return false, err + } + if rc.ObjectMeta.Name != testRcName || rc.ObjectMeta.Namespace != testRcNamespace || rc.Status.Replicas != testRcMaxReplicaCount || rc.Status.ReadyReplicas != testRcMaxReplicaCount { + return false, nil + } + eventFound = true + return true, nil + }) + framework.ExpectNoError(err, "Wait until condition with watch events should not return an error") + framework.ExpectEqual(eventFound, true, "Failed to find updated ready replica count") + + // Get the ReplicationController + ginkgo.By("fetching ReplicationController; ensuring that it's patched") + rc, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Get(context.TODO(), testRcName, metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to fetch ReplicationController") + framework.ExpectEqual(rc.ObjectMeta.Labels["test-rc"], "patched", "ReplicationController is missing a label from earlier patch") + + rcStatusUpdatePayload := rc + rcStatusUpdatePayload.Status.AvailableReplicas = 1 + rcStatusUpdatePayload.Status.ReadyReplicas = 1 + + // Replace the ReplicationController's status + ginkgo.By("updating ReplicationController status") + _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).UpdateStatus(context.TODO(), rcStatusUpdatePayload, metav1.UpdateOptions{}) + framework.ExpectNoError(err, "failed to update ReplicationControllerStatus") + + ginkgo.By("waiting for RC to be modified") + eventFound = false + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + if watchEvent.Type != watch.Modified { + return false, nil + } + actualWatchEvents = append(actualWatchEvents, watchEvent) + eventFound = true + return true, nil + }) + framework.ExpectNoError(err, "Wait until condition with watch events should not return an error") + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) + + ginkgo.By("listing all ReplicationControllers") + rcs, err := f.ClientSet.CoreV1().ReplicationControllers("").List(context.TODO(), metav1.ListOptions{LabelSelector: "test-rc-static=true"}) + framework.ExpectNoError(err, "failed to list ReplicationController") + framework.ExpectEqual(len(rcs.Items) > 0, true) + + ginkgo.By("checking that ReplicationController has expected values") + foundRc := false + for _, rcItem := range rcs.Items { + if rcItem.ObjectMeta.Name == testRcName && + rcItem.ObjectMeta.Namespace == testRcNamespace && + rcItem.ObjectMeta.Labels["test-rc-static"] == "true" && + rcItem.ObjectMeta.Labels["test-rc"] == "patched" { + foundRc = true + } + } + framework.ExpectEqual(foundRc, true) + + // Delete ReplicationController + ginkgo.By("deleting ReplicationControllers by collection") + err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "test-rc-static=true"}) + framework.ExpectNoError(err, "Failed to delete ReplicationControllers") + + ginkgo.By("waiting for ReplicationController to have a DELETED watchEvent") + eventFound = false + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + if watchEvent.Type != watch.Deleted { + return false, nil + } + actualWatchEvents = append(actualWatchEvents, watchEvent) + eventFound = true + return true, nil + }) + framework.ExpectNoError(err, "Wait until condition with watch events should not return an error") + framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) + + return actualWatchEvents }) - framework.ExpectNoError(err, "failed to marshal json of replicationcontroller label patch") - // Patch the ReplicationController - ginkgo.By("patching ReplicationController") - testRcPatched, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcLabelPatchPayload), metav1.PatchOptions{}) - framework.ExpectNoError(err, "Failed to patch ReplicationController") - framework.ExpectEqual(testRcPatched.ObjectMeta.Labels["test-rc"], "patched", "failed to patch RC") - ginkgo.By("waiting for RC to be modified") - eventFound = false - for watchEvent := range rcWatchChan { - if watchEvent.Type == watch.Modified { - eventFound = true - break - } - } - framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Modified) - - rcStatusPatchPayload, err := json.Marshal(map[string]interface{}{ - "status": map[string]interface{}{ - "readyReplicas": 0, - "availableReplicas": 0, - }, - }) - framework.ExpectNoError(err, "Failed to marshal JSON of ReplicationController label patch") - - // Patch the ReplicationController's status - ginkgo.By("patching ReplicationController status") - rcStatus, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcStatusPatchPayload), metav1.PatchOptions{}, "status") - framework.ExpectNoError(err, "Failed to patch ReplicationControllerStatus") - framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(0), "ReplicationControllerStatus's readyReplicas does not equal 0") - ginkgo.By("waiting for RC to be modified") - eventFound = false - for watchEvent := range rcWatchChan { - if watchEvent.Type == watch.Modified { - eventFound = true - break - } - } - framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Modified) - - eventFound = false - for watchEvent := range rcWatchChan { - rc, ok := watchEvent.Object.(*v1.ReplicationController) - framework.ExpectEqual(ok, true, "Unable to convert type of ReplicationController watch watchEvent") - - if rc.Status.Replicas == testRcInitialReplicaCount { - eventFound = true - break - } - } - framework.ExpectEqual(eventFound, true, "RC does not have initial replica count") - - ginkgo.By("fetching ReplicationController status") - rcStatusUnstructured, err := dc.Resource(rcResource).Namespace(testRcNamespace).Get(context.TODO(), testRcName, metav1.GetOptions{}, "status") - framework.ExpectNoError(err, "Failed to fetch ReplicationControllerStatus") - - rcStatusUjson, err := json.Marshal(rcStatusUnstructured) - framework.ExpectNoError(err, "Failed to marshal json of replicationcontroller label patch") - json.Unmarshal(rcStatusUjson, &rcStatus) - framework.ExpectEqual(rcStatus.Status.Replicas, testRcInitialReplicaCount, "ReplicationController ReplicaSet cound does not match initial Replica count") - - rcScalePatchPayload, err := json.Marshal(autoscalingv1.Scale{ - Spec: autoscalingv1.ScaleSpec{ - Replicas: testRcMaxReplicaCount, - }, - }) - framework.ExpectNoError(err, "Failed to marshal json of replicationcontroller label patch") - - // Patch the ReplicationController's scale - ginkgo.By("patching ReplicationController scale") - _, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Patch(context.TODO(), testRcName, types.StrategicMergePatchType, []byte(rcScalePatchPayload), metav1.PatchOptions{}, "scale") - framework.ExpectNoError(err, "Failed to patch ReplicationControllerScale") - ginkgo.By("waiting for RC to be modified") - - eventFound = false - for watchEvent := range rcWatchChan { - if watchEvent.Type == watch.Modified { - eventFound = true - break - } - } - framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Modified) - - var rcFromWatch *v1.ReplicationController - ginkgo.By("waiting for ReplicationController's scale to be the max amount") - foundRcWithMaxScale := false - for watchEvent := range rcWatchChan { - rc, ok := watchEvent.Object.(*v1.ReplicationController) - framework.ExpectEqual(ok, true, "Unable to convert type of ReplicationController watch watchEvent") - if rc.ObjectMeta.Name == testRcName && rc.ObjectMeta.Namespace == testRcNamespace && rc.Status.Replicas == testRcMaxReplicaCount && rc.Status.ReadyReplicas == testRcMaxReplicaCount { - foundRcWithMaxScale = true - rcFromWatch = rc - break - } - } - framework.ExpectEqual(foundRcWithMaxScale, true, "failed to locate a ReplicationController with max scale") - framework.ExpectEqual(rcFromWatch.Status.Replicas, testRcMaxReplicaCount, "ReplicationController ReplicasSet Scale does not match the expected scale") - - // Get the ReplicationController - ginkgo.By("fetching ReplicationController; ensuring that it's patched") - rc, err := f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).Get(context.TODO(), testRcName, metav1.GetOptions{}) - framework.ExpectNoError(err, "failed to fetch ReplicationController") - framework.ExpectEqual(rc.ObjectMeta.Labels["test-rc"], "patched", "ReplicationController is missing a label from earlier patch") - - rcStatusUpdatePayload := rc - rcStatusUpdatePayload.Status.AvailableReplicas = 1 - rcStatusUpdatePayload.Status.ReadyReplicas = 1 - - // Replace the ReplicationController's status - ginkgo.By("updating ReplicationController status") - rcStatus, err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).UpdateStatus(context.TODO(), rcStatusUpdatePayload, metav1.UpdateOptions{}) - framework.ExpectNoError(err, "failed to update ReplicationControllerStatus") - framework.ExpectEqual(rcStatus.Status.ReadyReplicas, int32(1), "ReplicationControllerStatus readyReplicas does not equal 1") - ginkgo.By("waiting for RC to be modified") - - eventFound = false - for watchEvent := range rcWatchChan { - if watchEvent.Type == watch.Modified { - eventFound = true - break - } - } - framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Modified) - - ginkgo.By("listing all ReplicationControllers") - rcs, err := f.ClientSet.CoreV1().ReplicationControllers("").List(context.TODO(), metav1.ListOptions{LabelSelector: "test-rc-static=true"}) - framework.ExpectNoError(err, "failed to list ReplicationController") - framework.ExpectEqual(len(rcs.Items) > 0, true) - - ginkgo.By("checking that ReplicationController has expected values") - foundRc := false - for _, rcItem := range rcs.Items { - if rcItem.ObjectMeta.Name == testRcName && - rcItem.ObjectMeta.Namespace == testRcNamespace && - rcItem.ObjectMeta.Labels["test-rc-static"] == "true" && - rcItem.ObjectMeta.Labels["test-rc"] == "patched" { - foundRc = true - } - } - framework.ExpectEqual(foundRc, true) - - // Delete ReplicationController - ginkgo.By("deleting ReplicationControllers by collection") - err = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "test-rc-static=true"}) - framework.ExpectNoError(err, "Failed to delete ReplicationControllers") - - ginkgo.By("waiting for ReplicationController to have a DELETED watchEvent") - eventFound = false - for watchEvent := range rcWatchChan { - if watchEvent.Type == watch.Deleted { - eventFound = true - break - } - } - framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Deleted) }) }) From 782bb43c4c78656a9f9894b2ded4cbbacabadc03 Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Thu, 28 May 2020 09:52:02 +1200 Subject: [PATCH 7/9] Fix formatting --- test/e2e/apps/rc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index 04b81617094..822443e1fb5 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -32,10 +32,10 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" + watch "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" clientset "k8s.io/client-go/kubernetes" watchtools "k8s.io/client-go/tools/watch" - watch "k8s.io/apimachinery/pkg/watch" "k8s.io/kubernetes/pkg/controller/replication" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" From 076d96236ef4abb495d984805bb074b13ad4118d Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Thu, 4 Jun 2020 09:58:15 +1200 Subject: [PATCH 8/9] Add cleanup function --- test/e2e/apps/rc.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index 822443e1fb5..2fbf96e47de 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -377,6 +377,9 @@ var _ = SIGDescribe("ReplicationController", func() { framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) return actualWatchEvents + }, func () (err error) { + _ = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "test-rc-static=true"}) + return err }) }) }) From e3b9d7891510d3e7ccaf50ea4706229842e437a5 Mon Sep 17 00:00:00 2001 From: Caleb Woodbine Date: Thu, 4 Jun 2020 13:46:21 +1200 Subject: [PATCH 9/9] Fix formatting --- test/e2e/apps/rc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/apps/rc.go b/test/e2e/apps/rc.go index 2fbf96e47de..ae433f8e1f0 100644 --- a/test/e2e/apps/rc.go +++ b/test/e2e/apps/rc.go @@ -377,7 +377,7 @@ var _ = SIGDescribe("ReplicationController", func() { framework.ExpectEqual(eventFound, true, "failed to find RC %v event", watch.Added) return actualWatchEvents - }, func () (err error) { + }, func() (err error) { _ = f.ClientSet.CoreV1().ReplicationControllers(testRcNamespace).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "test-rc-static=true"}) return err })