From 9fb05616ca966c107ff467c0cdb02efd12fb6d7d Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Thu, 18 Jun 2020 21:55:00 -0700 Subject: [PATCH 1/6] Drop WatchSequenceEventVerifier from configmap lifecycle test Collecting events in a certain order and then verifying the order in which they were collected feels redundant. --- test/e2e/common/configmap.go | 179 +++++++++++++++-------------------- 1 file changed, 78 insertions(+), 101 deletions(-) diff --git a/test/e2e/common/configmap.go b/test/e2e/common/configmap.go index 93311c5ee3d..532f95cce75 100644 --- a/test/e2e/common/configmap.go +++ b/test/e2e/common/configmap.go @@ -24,11 +24,11 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" watch "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" + "k8s.io/client-go/tools/cache" watchtools "k8s.io/client-go/tools/watch" "k8s.io/kubernetes/test/e2e/framework" imageutils "k8s.io/kubernetes/test/utils/image" @@ -172,12 +172,6 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { testNamespaceName := f.Namespace.Name testConfigMapName := "test-configmap" + string(uuid.NewUUID()) - configMapResource := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "configmaps"} - expectedWatchEvents := []watch.Event{ - {Type: watch.Added}, - {Type: watch.Modified}, - {Type: watch.Deleted}, - } testConfigMap := v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: testConfigMapName, @@ -190,103 +184,86 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { }, } - framework.WatchEventSequenceVerifier(context.TODO(), dc, configMapResource, testNamespaceName, testConfigMapName, metav1.ListOptions{LabelSelector: "test-configmap-static=true"}, expectedWatchEvents, func(retryWatcher *watchtools.RetryWatcher) (actualWatchEvents []watch.Event) { - ginkgo.By("creating a ConfigMap") - _, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Create(context.TODO(), &testConfigMap, metav1.CreateOptions{}) - framework.ExpectNoError(err, "failed to create ConfigMap") - 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 - return true, nil - }) - framework.ExpectNoError(err, "Wait until condition with watch events should not return an error") - framework.ExpectEqual(eventFound, true, "failed to find ConfigMap %v event", watch.Added) + w := &cache.ListWatch{ + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + options.LabelSelector = "test-configmap-static=true" + return f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Watch(context.TODO(), options) + }, + } + cml, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).List(context.TODO(), metav1.ListOptions{LabelSelector: "test-configmap-static=true"}) + framework.ExpectNoError(err) + retryWatcher, err := watchtools.NewRetryWatcher(cml.ResourceVersion, w) - configMapPatchPayload, err := json.Marshal(v1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "test-configmap": "patched", - }, - }, - Data: map[string]string{ - "valueName": "value1", - }, - }) - framework.ExpectNoError(err, "failed to marshal patch data") + ginkgo.By("creating a ConfigMap") + _, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Create(context.TODO(), &testConfigMap, metav1.CreateOptions{}) + framework.ExpectNoError(err, "failed to create ConfigMap") - ginkgo.By("patching the ConfigMap") - _, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Patch(context.TODO(), testConfigMapName, types.StrategicMergePatchType, []byte(configMapPatchPayload), metav1.PatchOptions{}) - framework.ExpectNoError(err, "failed to patch ConfigMap") - ginkgo.By("waiting for the ConfigMap 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 ConfigMap %v event", watch.Modified) - - ginkgo.By("fetching the ConfigMap") - configMap, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Get(context.TODO(), testConfigMapName, metav1.GetOptions{}) - framework.ExpectNoError(err, "failed to get ConfigMap") - framework.ExpectEqual(configMap.Data["valueName"], "value1", "failed to patch ConfigMap") - framework.ExpectEqual(configMap.Labels["test-configmap"], "patched", "failed to patch ConfigMap") - - ginkgo.By("listing all ConfigMaps in all namespaces") - configMapList, err := f.ClientSet.CoreV1().ConfigMaps("").List(context.TODO(), metav1.ListOptions{ - LabelSelector: "test-configmap-static=true", - }) - framework.ExpectNoError(err, "failed to list ConfigMaps with LabelSelector") - framework.ExpectNotEqual(len(configMapList.Items), 0, "no ConfigMaps found in ConfigMap list") - testConfigMapFound := false - for _, cm := range configMapList.Items { - if cm.ObjectMeta.Name == testConfigMapName && - cm.ObjectMeta.Namespace == testNamespaceName && - cm.ObjectMeta.Labels["test-configmap-static"] == "true" && - cm.Data["valueName"] == "value1" { - testConfigMapFound = true - break - } - } - framework.ExpectEqual(testConfigMapFound, true, "failed to find ConfigMap in list") - - ginkgo.By("deleting the ConfigMap by a collection") - err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: "test-configmap-static=true", - }) - framework.ExpectNoError(err, "failed to delete ConfigMap collection with LabelSelector") - ginkgo.By("waiting for the ConfigMap to be deleted") - 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 ConfigMap %v event", watch.Deleted) - - return actualWatchEvents - }, func() (err error) { - _ = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{LabelSelector: "test-configmap-static=true"}) - return err + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + return watchEvent.Type == watch.Added, nil }) + framework.ExpectNoError(err, "failed to see a watch.Added event for the configmap we created") + + configMapPatchPayload, err := json.Marshal(v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "test-configmap": "patched", + }, + }, + Data: map[string]string{ + "valueName": "value1", + }, + }) + framework.ExpectNoError(err, "failed to marshal patch data") + + ginkgo.By("patching the ConfigMap") + _, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Patch(context.TODO(), testConfigMapName, types.StrategicMergePatchType, []byte(configMapPatchPayload), metav1.PatchOptions{}) + framework.ExpectNoError(err, "failed to patch ConfigMap") + ginkgo.By("waiting for the ConfigMap to be modified") + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + return watchEvent.Type == watch.Modified, nil + }) + framework.ExpectNoError(err, "failed to see a watch.Modified event for the configmap we patched") + + ginkgo.By("fetching the ConfigMap") + configMap, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Get(context.TODO(), testConfigMapName, metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get ConfigMap") + framework.ExpectEqual(configMap.Data["valueName"], "value1", "failed to patch ConfigMap") + framework.ExpectEqual(configMap.Labels["test-configmap"], "patched", "failed to patch ConfigMap") + + ginkgo.By("listing all ConfigMaps in all namespaces") + configMapList, err := f.ClientSet.CoreV1().ConfigMaps("").List(context.TODO(), metav1.ListOptions{ + LabelSelector: "test-configmap-static=true", + }) + framework.ExpectNoError(err, "failed to list ConfigMaps with LabelSelector") + framework.ExpectNotEqual(len(configMapList.Items), 0, "no ConfigMaps found in ConfigMap list") + testConfigMapFound := false + for _, cm := range configMapList.Items { + if cm.ObjectMeta.Name == testConfigMapName && + cm.ObjectMeta.Namespace == testNamespaceName && + cm.ObjectMeta.Labels["test-configmap-static"] == "true" && + cm.Data["valueName"] == "value1" { + testConfigMapFound = true + break + } + } + framework.ExpectEqual(testConfigMapFound, true, "failed to find ConfigMap in list") + + ginkgo.By("deleting the ConfigMap by a collection") + err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{ + LabelSelector: "test-configmap-static=true", + }) + framework.ExpectNoError(err, "failed to delete ConfigMap collection with LabelSelector") + ginkgo.By("waiting for the ConfigMap to be deleted") + ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { + return watchEvent.Type == watch.Deleted, nil + }) + framework.ExpectNoError(err, "fasiled to observe a watch.Deleted event for the ConfigMap we deleted") }) }) From 1048dddc3689b93d0b7ea85bd202b231ed21a453 Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Thu, 18 Jun 2020 22:08:38 -0700 Subject: [PATCH 2/6] For grins, make the watch checks very detailed So we know we're not just seeing an arbitrary watch event, we're seeing _the_ watch event that describes the results of our actions --- test/e2e/common/configmap.go | 47 +++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/test/e2e/common/configmap.go b/test/e2e/common/configmap.go index 532f95cce75..11f0e706435 100644 --- a/test/e2e/common/configmap.go +++ b/test/e2e/common/configmap.go @@ -200,8 +200,19 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { - return watchEvent.Type == watch.Added, nil + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(event watch.Event) (bool, error) { + switch event.Type { + case watch.Added: + if cm, ok := event.Object.(*v1.ConfigMap); ok { + found := cm.ObjectMeta.Name == testConfigMap.Name && + cm.Labels["test-configmap-static"] == "true" && + cm.Data["valueName"] == "value" + return found, nil + } + default: + framework.Logf("observed event type %v", event.Type) + } + return false, nil }) framework.ExpectNoError(err, "failed to see a watch.Added event for the configmap we created") @@ -223,8 +234,20 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { ginkgo.By("waiting for the ConfigMap to be modified") ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { - return watchEvent.Type == watch.Modified, nil + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(event watch.Event) (bool, error) { + switch event.Type { + case watch.Modified: + if cm, ok := event.Object.(*v1.ConfigMap); ok { + found := cm.ObjectMeta.Name == testConfigMap.Name && + cm.Labels["test-configmap-static"] == "true" && + cm.Labels["test-configmap"] == "patched" && + cm.Data["valueName"] == "value1" + return found, nil + } + default: + framework.Logf("observed event type %v", event.Type) + } + return false, nil }) framework.ExpectNoError(err, "failed to see a watch.Modified event for the configmap we patched") @@ -260,8 +283,20 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { ginkgo.By("waiting for the ConfigMap to be deleted") ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(watchEvent watch.Event) (bool, error) { - return watchEvent.Type == watch.Deleted, nil + _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(event watch.Event) (bool, error) { + switch event.Type { + case watch.Deleted: + if cm, ok := event.Object.(*v1.ConfigMap); ok { + found := cm.ObjectMeta.Name == testConfigMap.Name && + cm.Labels["test-configmap-static"] == "true" && + cm.Labels["test-configmap"] == "patched" && + cm.Data["valueName"] == "value1" + return found, nil + } + default: + framework.Logf("observed event type %v", event.Type) + } + return false, nil }) framework.ExpectNoError(err, "fasiled to observe a watch.Deleted event for the ConfigMap we deleted") }) From 4582e26ae17a80bbda8af6af9bde72f3b220041d Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Thu, 18 Jun 2020 22:26:06 -0700 Subject: [PATCH 3/6] Now use the stock watchtools.Until By passing in the same initial resource version each time, we get all watch events from the beginning each time. --- test/e2e/common/configmap.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/e2e/common/configmap.go b/test/e2e/common/configmap.go index 11f0e706435..e86dbcb1bac 100644 --- a/test/e2e/common/configmap.go +++ b/test/e2e/common/configmap.go @@ -192,7 +192,6 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { } cml, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).List(context.TODO(), metav1.ListOptions{LabelSelector: "test-configmap-static=true"}) framework.ExpectNoError(err) - retryWatcher, err := watchtools.NewRetryWatcher(cml.ResourceVersion, w) ginkgo.By("creating a ConfigMap") _, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Create(context.TODO(), &testConfigMap, metav1.CreateOptions{}) @@ -200,7 +199,7 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(event watch.Event) (bool, error) { + _, err = watchtools.Until(ctx, cml.ResourceVersion, w, func(event watch.Event) (bool, error) { switch event.Type { case watch.Added: if cm, ok := event.Object.(*v1.ConfigMap); ok { @@ -234,7 +233,7 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { ginkgo.By("waiting for the ConfigMap to be modified") ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(event watch.Event) (bool, error) { + _, err = watchtools.Until(ctx, cml.ResourceVersion, w, func(event watch.Event) (bool, error) { switch event.Type { case watch.Modified: if cm, ok := event.Object.(*v1.ConfigMap); ok { @@ -283,7 +282,7 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { ginkgo.By("waiting for the ConfigMap to be deleted") ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - _, err = framework.WatchUntilWithoutRetry(ctx, retryWatcher, func(event watch.Event) (bool, error) { + _, err = watchtools.Until(ctx, cml.ResourceVersion, w, func(event watch.Event) (bool, error) { switch event.Type { case watch.Deleted: if cm, ok := event.Object.(*v1.ConfigMap); ok { From 0a869ac043c37728573f725ba2347c1b491de57e Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Thu, 18 Jun 2020 22:46:59 -0700 Subject: [PATCH 4/6] Use different resource versions each time In this way, we avoid having to skip over "stale" watch events. The downside is having to keep track of the previous resource version. --- test/e2e/common/configmap.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/e2e/common/configmap.go b/test/e2e/common/configmap.go index e86dbcb1bac..e8298953605 100644 --- a/test/e2e/common/configmap.go +++ b/test/e2e/common/configmap.go @@ -194,7 +194,7 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { framework.ExpectNoError(err) ginkgo.By("creating a ConfigMap") - _, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Create(context.TODO(), &testConfigMap, metav1.CreateOptions{}) + cm, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Create(context.TODO(), &testConfigMap, metav1.CreateOptions{}) framework.ExpectNoError(err, "failed to create ConfigMap") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) @@ -228,12 +228,12 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { framework.ExpectNoError(err, "failed to marshal patch data") ginkgo.By("patching the ConfigMap") - _, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Patch(context.TODO(), testConfigMapName, types.StrategicMergePatchType, []byte(configMapPatchPayload), metav1.PatchOptions{}) + cm2, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Patch(context.TODO(), testConfigMapName, types.StrategicMergePatchType, []byte(configMapPatchPayload), metav1.PatchOptions{}) framework.ExpectNoError(err, "failed to patch ConfigMap") ginkgo.By("waiting for the ConfigMap to be modified") ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - _, err = watchtools.Until(ctx, cml.ResourceVersion, w, func(event watch.Event) (bool, error) { + _, err = watchtools.Until(ctx, cm.ResourceVersion, w, func(event watch.Event) (bool, error) { switch event.Type { case watch.Modified: if cm, ok := event.Object.(*v1.ConfigMap); ok { @@ -282,7 +282,7 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { ginkgo.By("waiting for the ConfigMap to be deleted") ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - _, err = watchtools.Until(ctx, cml.ResourceVersion, w, func(event watch.Event) (bool, error) { + _, err = watchtools.Until(ctx, cm2.ResourceVersion, w, func(event watch.Event) (bool, error) { switch event.Type { case watch.Deleted: if cm, ok := event.Object.(*v1.ConfigMap); ok { From 121676e22007f23cddd1b19cce60680269daacfc Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Thu, 18 Jun 2020 23:13:26 -0700 Subject: [PATCH 5/6] Drop the use of watchtools The thing is, for this test at least, I'm pretty sure there's nothing we need to wait on. Instead of waiting for a deleted event, we will relist configmaps and expect 0, to confirm the deletion took effect --- test/e2e/common/BUILD | 2 - test/e2e/common/configmap.go | 83 +++--------------------------------- 2 files changed, 6 insertions(+), 79 deletions(-) diff --git a/test/e2e/common/BUILD b/test/e2e/common/BUILD index 5d8f37709a0..3c642b6e247 100644 --- a/test/e2e/common/BUILD +++ b/test/e2e/common/BUILD @@ -58,7 +58,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library", @@ -67,7 +66,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", - "//staging/src/k8s.io/client-go/dynamic:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library", "//staging/src/k8s.io/client-go/tools/watch:go_default_library", diff --git a/test/e2e/common/configmap.go b/test/e2e/common/configmap.go index e8298953605..8eeb67117da 100644 --- a/test/e2e/common/configmap.go +++ b/test/e2e/common/configmap.go @@ -20,16 +20,11 @@ import ( "context" "encoding/json" "fmt" - "time" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" - watch "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/tools/cache" - watchtools "k8s.io/client-go/tools/watch" "k8s.io/kubernetes/test/e2e/framework" imageutils "k8s.io/kubernetes/test/utils/image" @@ -39,12 +34,6 @@ import ( var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { f := framework.NewDefaultFramework("configmap") - var dc dynamic.Interface - - ginkgo.BeforeEach(func() { - dc = f.DynamicClient - }) - /* Release : v1.9 Testname: ConfigMap, from environment field @@ -184,37 +173,10 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { }, } - w := &cache.ListWatch{ - WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { - options.LabelSelector = "test-configmap-static=true" - return f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Watch(context.TODO(), options) - }, - } - cml, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).List(context.TODO(), metav1.ListOptions{LabelSelector: "test-configmap-static=true"}) - framework.ExpectNoError(err) - ginkgo.By("creating a ConfigMap") - cm, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Create(context.TODO(), &testConfigMap, metav1.CreateOptions{}) + _, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Create(context.TODO(), &testConfigMap, metav1.CreateOptions{}) framework.ExpectNoError(err, "failed to create ConfigMap") - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - _, err = watchtools.Until(ctx, cml.ResourceVersion, w, func(event watch.Event) (bool, error) { - switch event.Type { - case watch.Added: - if cm, ok := event.Object.(*v1.ConfigMap); ok { - found := cm.ObjectMeta.Name == testConfigMap.Name && - cm.Labels["test-configmap-static"] == "true" && - cm.Data["valueName"] == "value" - return found, nil - } - default: - framework.Logf("observed event type %v", event.Type) - } - return false, nil - }) - framework.ExpectNoError(err, "failed to see a watch.Added event for the configmap we created") - configMapPatchPayload, err := json.Marshal(v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -228,27 +190,8 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { framework.ExpectNoError(err, "failed to marshal patch data") ginkgo.By("patching the ConfigMap") - cm2, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Patch(context.TODO(), testConfigMapName, types.StrategicMergePatchType, []byte(configMapPatchPayload), metav1.PatchOptions{}) + _, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Patch(context.TODO(), testConfigMapName, types.StrategicMergePatchType, []byte(configMapPatchPayload), metav1.PatchOptions{}) framework.ExpectNoError(err, "failed to patch ConfigMap") - ginkgo.By("waiting for the ConfigMap to be modified") - ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - _, err = watchtools.Until(ctx, cm.ResourceVersion, w, func(event watch.Event) (bool, error) { - switch event.Type { - case watch.Modified: - if cm, ok := event.Object.(*v1.ConfigMap); ok { - found := cm.ObjectMeta.Name == testConfigMap.Name && - cm.Labels["test-configmap-static"] == "true" && - cm.Labels["test-configmap"] == "patched" && - cm.Data["valueName"] == "value1" - return found, nil - } - default: - framework.Logf("observed event type %v", event.Type) - } - return false, nil - }) - framework.ExpectNoError(err, "failed to see a watch.Modified event for the configmap we patched") ginkgo.By("fetching the ConfigMap") configMap, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Get(context.TODO(), testConfigMapName, metav1.GetOptions{}) @@ -279,25 +222,11 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { LabelSelector: "test-configmap-static=true", }) framework.ExpectNoError(err, "failed to delete ConfigMap collection with LabelSelector") - ginkgo.By("waiting for the ConfigMap to be deleted") - ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - _, err = watchtools.Until(ctx, cm2.ResourceVersion, w, func(event watch.Event) (bool, error) { - switch event.Type { - case watch.Deleted: - if cm, ok := event.Object.(*v1.ConfigMap); ok { - found := cm.ObjectMeta.Name == testConfigMap.Name && - cm.Labels["test-configmap-static"] == "true" && - cm.Labels["test-configmap"] == "patched" && - cm.Data["valueName"] == "value1" - return found, nil - } - default: - framework.Logf("observed event type %v", event.Type) - } - return false, nil + ginkgo.By("listing all ConfigMaps in all namespaces") + configMapList, err = f.ClientSet.CoreV1().ConfigMaps("").List(context.TODO(), metav1.ListOptions{ + LabelSelector: "test-configmap-static=true", }) - framework.ExpectNoError(err, "fasiled to observe a watch.Deleted event for the ConfigMap we deleted") + framework.ExpectEqual(len(configMapList.Items), 0, "ConfigMap is still present after being deleted by collection") }) }) From 225e7c75b56cfbdd69d1420a2b42ecee0eefc8e4 Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Thu, 18 Jun 2020 23:45:30 -0700 Subject: [PATCH 6/6] Reorder checks slightly, add a list-by-namespace call Now the test covers 6 different api calls - verify create with a get - verify patch with a list (all namespaces) - verify delete with a list (single namespace) --- test/e2e/common/configmap.go | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/test/e2e/common/configmap.go b/test/e2e/common/configmap.go index 8eeb67117da..06d8e5e9310 100644 --- a/test/e2e/common/configmap.go +++ b/test/e2e/common/configmap.go @@ -177,6 +177,12 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { _, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Create(context.TODO(), &testConfigMap, metav1.CreateOptions{}) framework.ExpectNoError(err, "failed to create ConfigMap") + ginkgo.By("fetching the ConfigMap") + configMap, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Get(context.TODO(), testConfigMapName, metav1.GetOptions{}) + framework.ExpectNoError(err, "failed to get ConfigMap") + framework.ExpectEqual(configMap.Data["valueName"], testConfigMap.Data["valueName"]) + framework.ExpectEqual(configMap.Labels["test-configmap-static"], testConfigMap.Labels["test-configmap-static"]) + configMapPatchPayload, err := json.Marshal(v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -193,39 +199,35 @@ var _ = ginkgo.Describe("[sig-node] ConfigMap", func() { _, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Patch(context.TODO(), testConfigMapName, types.StrategicMergePatchType, []byte(configMapPatchPayload), metav1.PatchOptions{}) framework.ExpectNoError(err, "failed to patch ConfigMap") - ginkgo.By("fetching the ConfigMap") - configMap, err := f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).Get(context.TODO(), testConfigMapName, metav1.GetOptions{}) - framework.ExpectNoError(err, "failed to get ConfigMap") - framework.ExpectEqual(configMap.Data["valueName"], "value1", "failed to patch ConfigMap") - framework.ExpectEqual(configMap.Labels["test-configmap"], "patched", "failed to patch ConfigMap") - - ginkgo.By("listing all ConfigMaps in all namespaces") + ginkgo.By("listing all ConfigMaps in all namespaces with a label selector") configMapList, err := f.ClientSet.CoreV1().ConfigMaps("").List(context.TODO(), metav1.ListOptions{ - LabelSelector: "test-configmap-static=true", + LabelSelector: "test-configmap=patched", }) framework.ExpectNoError(err, "failed to list ConfigMaps with LabelSelector") - framework.ExpectNotEqual(len(configMapList.Items), 0, "no ConfigMaps found in ConfigMap list") testConfigMapFound := false for _, cm := range configMapList.Items { - if cm.ObjectMeta.Name == testConfigMapName && + if cm.ObjectMeta.Name == testConfigMap.ObjectMeta.Name && cm.ObjectMeta.Namespace == testNamespaceName && - cm.ObjectMeta.Labels["test-configmap-static"] == "true" && + cm.ObjectMeta.Labels["test-configmap-static"] == testConfigMap.ObjectMeta.Labels["test-configmap-static"] && + cm.ObjectMeta.Labels["test-configmap"] == "patched" && cm.Data["valueName"] == "value1" { testConfigMapFound = true break } } - framework.ExpectEqual(testConfigMapFound, true, "failed to find ConfigMap in list") + framework.ExpectEqual(testConfigMapFound, true, "failed to find ConfigMap by label selector") - ginkgo.By("deleting the ConfigMap by a collection") + ginkgo.By("deleting the ConfigMap by collection with a label selector") err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{ LabelSelector: "test-configmap-static=true", }) framework.ExpectNoError(err, "failed to delete ConfigMap collection with LabelSelector") - ginkgo.By("listing all ConfigMaps in all namespaces") - configMapList, err = f.ClientSet.CoreV1().ConfigMaps("").List(context.TODO(), metav1.ListOptions{ + + ginkgo.By("listing all ConfigMaps in test namespace") + configMapList, err = f.ClientSet.CoreV1().ConfigMaps(testNamespaceName).List(context.TODO(), metav1.ListOptions{ LabelSelector: "test-configmap-static=true", }) + framework.ExpectNoError(err, "failed to list ConfigMap by LabelSelector") framework.ExpectEqual(len(configMapList.Items), 0, "ConfigMap is still present after being deleted by collection") }) })