From f24a3bb2007d01ca3834b2bdbfd4de5950d210e8 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Mon, 26 Sep 2022 15:29:35 -0700 Subject: [PATCH 01/14] initial commit for update e2e --- test/e2e/utils/helper.go | 21 +++++-- test/e2e/utils/work_api_test_utils.go | 13 ----- test/e2e/work_api_e2e_test.go | 82 ++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 19 deletions(-) diff --git a/test/e2e/utils/helper.go b/test/e2e/utils/helper.go index 0f1e3a52f..c12c89fa8 100644 --- a/test/e2e/utils/helper.go +++ b/test/e2e/utils/helper.go @@ -159,12 +159,23 @@ func CreateWork(ctx context.Context, hubCluster framework.Cluster, workName, wor return work } -// DeleteWork deletes all works used in the current test. -func DeleteWork(ctx context.Context, hubCluster framework.Cluster, works []workapi.Work) { - // Using index instead of work object itself due to lint check "Implicit memory aliasing in for loop." - for i := range works { - gomega.Expect(hubCluster.KubeClient.Delete(ctx, &works[i])).Should(gomega.SatisfyAny(gomega.Succeed(), &utils.NotFoundMatcher{}), "Deletion of work %s failed", works[i].Name) +// UpdateWork updates an existing Work Object by replacing the Spec.Manifest with a new objects given from parameter. +func UpdateWork(ctx context.Context, work *workapi.Work, hubCluster *framework.Cluster, objects []runtime.Object) *workapi.Work { + manifests := make([]workapi.Manifest, len(objects)) + for index, obj := range objects { + rawObj, err := json.Marshal(obj) + gomega.Expect(err).Should(gomega.Succeed(), "Failed to marshal object %+v", obj) + + manifests[index] = workapi.Manifest{ + RawExtension: runtime.RawExtension{Object: obj, Raw: rawObj}, + } } + work.Spec.Workload.Manifests = manifests + + err := hubCluster.KubeClient.Update(ctx, work) + gomega.Expect(err).Should(gomega.Succeed(), "Failed to update work %s in namespace %v", work.Name, work.Namespace) + + return work } // AddManifests adds manifests to be included within a Work. diff --git a/test/e2e/utils/work_api_test_utils.go b/test/e2e/utils/work_api_test_utils.go index e69932faf..2405bee5f 100644 --- a/test/e2e/utils/work_api_test_utils.go +++ b/test/e2e/utils/work_api_test_utils.go @@ -74,16 +74,3 @@ func RetrieveWork(workNamespace string, workName string, hubCluster *framework.C } return &workRetrieved, nil } - -func UpdateWork(work *workapi.Work, hubCluster *framework.Cluster) (*workapi.Work, error) { - err := hubCluster.KubeClient.Update(context.Background(), work) - if err != nil { - return nil, err - } - - updatedWork, err := RetrieveWork(work.Namespace, work.Name, hubCluster) - if err != nil { - return nil, err - } - return updatedWork, err -} diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index d20c39eda..616437aa4 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -80,7 +80,6 @@ var _ = Describe("Work API Controller test", func() { }) AfterEach(func() { - testutils.DeleteWork(ctx, *HubCluster, works) testutils.DeleteNamespace(*MemberCluster, resourceNamespace) }) @@ -553,6 +552,87 @@ var _ = Describe("Work API Controller test", func() { Expect(customResource.GetAnnotations()[specHashAnnotation]).ToNot(BeEmpty(), "There is no spec annotation on the custom resource %s", customResource.GetName()) }) + + Context("Updating Work", func() { + configMapBeforeUpdate := corev1.ConfigMap{} + workBeforeUpdate := workapi.Work{} + namespaceType := types.NamespacedName{} + + BeforeEach(func() { + workName := testutils.RandomWorkName(5) + manifestConfigMapName := "work-update-configmap" + configMapBeforeUpdate = corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: manifestConfigMapName, + Namespace: resourceNamespace.Name, + }, + Data: map[string]string{ + "before-update-key": "before-update-data", + }, + } + + // Creating types.NamespacedName to use in retrieving objects. + namespaceType = types.NamespacedName{Name: workName, Namespace: workNamespace.Name} + + manifests := testutils.AddManifests([]runtime.Object{&configMapBeforeUpdate}, []workapi.Manifest{}) + By(fmt.Sprintf("creating work %s of %s", namespaceType, manifestConfigMapName)) + workBeforeUpdate = testutils.CreateWork(ctx, *HubCluster, workName, workNamespace.Name, manifests) + + Eventually(func() string { + if err := HubCluster.KubeClient.Get(ctx, namespaceType, &workBeforeUpdate); err != nil { + return err.Error() + } + + want := []metav1.Condition{ + { + Type: conditionTypeApplied, + Status: metav1.ConditionTrue, + Reason: "appliedWorkComplete", + }, + } + + return cmp.Diff(want, workBeforeUpdate.Status.Conditions, cmpOptions...) + }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Validate WorkStatus mismatch (-want, +got):") + + }) + + It("Updating Work object on the Hub Cluster should update the resource on the member cluster.", func() { + updatedConfigMap := configMapBeforeUpdate.DeepCopy() + updatedConfigMap.Data = map[string]string{ + "updated-key": "updated-data", + } + testutils.UpdateWork(ctx, &workBeforeUpdate, HubCluster, []runtime.Object{updatedConfigMap}) + + By(fmt.Sprintf("The resource %s should be updated in the member cluster %s", updatedConfigMap.Name, memberClusterName)) + configMapNamespaceType := types.NamespacedName{Name: updatedConfigMap.Name, Namespace: resourceNamespace.Name} + retrievedConfigMap := corev1.ConfigMap{} + + want := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: updatedConfigMap.Name, + Namespace: resourceNamespace.Name, + }, + Data: map[string]string{ + "updated-key": "updated-data", + }, + } + + configMapCmpOptions := append(cmpOptions, + cmpopts.IgnoreFields(metav1.ObjectMeta{}, "UID", "ResourceVersion", "Generation", "CreationTimestamp", "Annotations", "OwnerReferences", "ManagedFields"), + ) + + Eventually(func() string { + if err := MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap); err != nil { + return err.Error() + } + return cmp.Diff(want, retrievedConfigMap, configMapCmpOptions...) + }).Should(BeEmpty(), "Resource %s mismatch (-want, +got):", updatedConfigMap.Name) + }) + }) }) func IsKeyMetadata(p cmp.Path) bool { From da94bb186bef2cfe91ca4c5114abd97baec0ddf9 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Mon, 26 Sep 2022 17:28:05 -0700 Subject: [PATCH 02/14] Adding polltime to Eventually statements --- test/e2e/work_api_e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 616437aa4..01bbd005d 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -630,7 +630,7 @@ var _ = Describe("Work API Controller test", func() { return err.Error() } return cmp.Diff(want, retrievedConfigMap, configMapCmpOptions...) - }).Should(BeEmpty(), "Resource %s mismatch (-want, +got):", updatedConfigMap.Name) + }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Resource %s mismatch (-want, +got):", updatedConfigMap.Name) }) }) }) From 15c84743520ddca05dbb23ac39af0593b6772102 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 27 Sep 2022 10:59:36 -0700 Subject: [PATCH 03/14] added more test for update --- test/e2e/work_api_e2e_test.go | 55 ++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 01bbd005d..73698a71b 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -32,8 +32,6 @@ var _ = Describe("Work API Controller test", func() { var ( ctx context.Context - // Includes all works applied to the hub cluster. Used for garbage collection. - works []workapi.Work // Comparison Options cmpOptions = []cmp.Option{ @@ -74,9 +72,6 @@ var _ = Describe("Work API Controller test", func() { }, } testutils.CreateNamespace(*MemberCluster, resourceNamespace) - - //Empties the works since they were garbage collected earlier. - works = []workapi.Work{} }) AfterEach(func() { @@ -521,8 +516,8 @@ var _ = Describe("Work API Controller test", func() { }, } - filterMetadataFunc := cmp.FilterPath(IsKeyMetadata, cmp.Ignore()) - filterNotNameFunc := cmp.FilterPath(IsKeyNotName, cmp.Ignore()) + filterMetadataFunc := cmp.FilterPath(isKeyMetadata, cmp.Ignore()) + filterNotNameFunc := cmp.FilterPath(isKeyNotName, cmp.Ignore()) Expect(cmp.Diff(wantCRObject, *customResource, append(cmpOptions, filterMetadataFunc)...)).Should(BeEmpty(), "Validate CR Object Metadata mismatch (-want, +got):") @@ -621,26 +616,58 @@ var _ = Describe("Work API Controller test", func() { }, } - configMapCmpOptions := append(cmpOptions, - cmpopts.IgnoreFields(metav1.ObjectMeta{}, "UID", "ResourceVersion", "Generation", "CreationTimestamp", "Annotations", "OwnerReferences", "ManagedFields"), - ) - Eventually(func() string { if err := MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap); err != nil { return err.Error() } - return cmp.Diff(want, retrievedConfigMap, configMapCmpOptions...) + return cmp.Diff(want, retrievedConfigMap, cmpOptions...) }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Resource %s mismatch (-want, +got):", updatedConfigMap.Name) }) + + It("Deleting a manifest from the Work object should delete the corresponding resource in the member cluster", func() { + configMapNamespaceType := types.NamespacedName{Name: configMapBeforeUpdate.Name, Namespace: resourceNamespace.Name} + updatedConfigMap := configMapBeforeUpdate.DeepCopy() + updatedConfigMap.Data = map[string]string{} + testutils.UpdateWork(ctx, &workBeforeUpdate, HubCluster, []runtime.Object{}) + + By(fmt.Sprintf("The resource %s should be deleted in the member cluster %s", configMapBeforeUpdate.Name, memberClusterName)) + Eventually(func() error { + retrievedConfigMap := corev1.ConfigMap{} + if err := MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap); err != nil { + return err + } + return nil + }, testutils.PollTimeout, testutils.PollInterval).ShouldNot(Succeed(), "Resource %s should have been deleted.", configMapBeforeUpdate.Name) + + By(fmt.Sprintf("The AppliedWork Manifest should have been deleted")) + appliedWork := workapi.AppliedWork{} + err := MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork) + Expect(err).Should(Succeed(), "Retrieving AppliedWork Manifest Failed") + want := workapi.AppliedtWorkStatus{ + AppliedResources: []workapi.AppliedResourceMeta{}, + } + Expect(cmp.Diff(want, appliedWork.Status)).Should(BeEmpty(), + "Status should be empty for AppliedWork %s", appliedWork.Name) + + By(fmt.Sprintf("The Work Condition should have been deleted from the Work Object")) + work := workapi.Work{} + err = MemberCluster.KubeClient.Get(ctx, namespaceType, &work) + Expect(err).Should(Succeed(), "Retrieving Work Object failed") + Expect(work.Status.Conditions).Should(BeNil(), + "Work Condition for Work Object %s should be empty", work.Name) + + Expect(work.Status.ManifestConditions).Should(BeNil(), + "Work Manifest Condition for Work Object %s should be empty", work.Name) + }) }) }) -func IsKeyMetadata(p cmp.Path) bool { +func isKeyMetadata(p cmp.Path) bool { step, ok := p[len(p)-1].(cmp.MapIndex) return ok && step.Key().String() == "metadata" } -func IsKeyNotName(p cmp.Path) bool { +func isKeyNotName(p cmp.Path) bool { step, ok := p[len(p)-1].(cmp.MapIndex) return ok && step.Key().String() != "name" } From 8d4ab1067d332b52c147460d01922cc313c7475d Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 27 Sep 2022 13:14:05 -0700 Subject: [PATCH 04/14] lint fix --- test/e2e/work_api_e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 73698a71b..9c68efdfd 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -639,7 +639,7 @@ var _ = Describe("Work API Controller test", func() { return nil }, testutils.PollTimeout, testutils.PollInterval).ShouldNot(Succeed(), "Resource %s should have been deleted.", configMapBeforeUpdate.Name) - By(fmt.Sprintf("The AppliedWork Manifest should have been deleted")) + By(fmt.Sprintf("The AppliedWork Manifest for Work %s should have been deleted", namespaceType)) appliedWork := workapi.AppliedWork{} err := MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork) Expect(err).Should(Succeed(), "Retrieving AppliedWork Manifest Failed") From e1f7a5e0dfaf46a9c09fcede80ec1012cfb3ef64 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 27 Sep 2022 13:32:43 -0700 Subject: [PATCH 05/14] lint fix --- test/e2e/work_api_e2e_test.go | 43 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 9c68efdfd..1a4fae3dc 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -549,14 +549,14 @@ var _ = Describe("Work API Controller test", func() { }) Context("Updating Work", func() { - configMapBeforeUpdate := corev1.ConfigMap{} - workBeforeUpdate := workapi.Work{} + configMap := corev1.ConfigMap{} + work := workapi.Work{} namespaceType := types.NamespacedName{} BeforeEach(func() { workName := testutils.RandomWorkName(5) manifestConfigMapName := "work-update-configmap" - configMapBeforeUpdate = corev1.ConfigMap{ + configMap = corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", Kind: "ConfigMap", @@ -573,12 +573,12 @@ var _ = Describe("Work API Controller test", func() { // Creating types.NamespacedName to use in retrieving objects. namespaceType = types.NamespacedName{Name: workName, Namespace: workNamespace.Name} - manifests := testutils.AddManifests([]runtime.Object{&configMapBeforeUpdate}, []workapi.Manifest{}) + manifests := testutils.AddManifests([]runtime.Object{&configMap}, []workapi.Manifest{}) By(fmt.Sprintf("creating work %s of %s", namespaceType, manifestConfigMapName)) - workBeforeUpdate = testutils.CreateWork(ctx, *HubCluster, workName, workNamespace.Name, manifests) + work = testutils.CreateWork(ctx, *HubCluster, workName, workNamespace.Name, manifests) Eventually(func() string { - if err := HubCluster.KubeClient.Get(ctx, namespaceType, &workBeforeUpdate); err != nil { + if err := HubCluster.KubeClient.Get(ctx, namespaceType, &work); err != nil { return err.Error() } @@ -590,17 +590,17 @@ var _ = Describe("Work API Controller test", func() { }, } - return cmp.Diff(want, workBeforeUpdate.Status.Conditions, cmpOptions...) + return cmp.Diff(want, work.Status.Conditions, cmpOptions...) }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Validate WorkStatus mismatch (-want, +got):") }) It("Updating Work object on the Hub Cluster should update the resource on the member cluster.", func() { - updatedConfigMap := configMapBeforeUpdate.DeepCopy() + updatedConfigMap := configMap.DeepCopy() updatedConfigMap.Data = map[string]string{ "updated-key": "updated-data", } - testutils.UpdateWork(ctx, &workBeforeUpdate, HubCluster, []runtime.Object{updatedConfigMap}) + testutils.UpdateWork(ctx, &work, HubCluster, []runtime.Object{updatedConfigMap}) By(fmt.Sprintf("The resource %s should be updated in the member cluster %s", updatedConfigMap.Name, memberClusterName)) configMapNamespaceType := types.NamespacedName{Name: updatedConfigMap.Name, Namespace: resourceNamespace.Name} @@ -625,19 +625,19 @@ var _ = Describe("Work API Controller test", func() { }) It("Deleting a manifest from the Work object should delete the corresponding resource in the member cluster", func() { - configMapNamespaceType := types.NamespacedName{Name: configMapBeforeUpdate.Name, Namespace: resourceNamespace.Name} - updatedConfigMap := configMapBeforeUpdate.DeepCopy() + configMapNamespaceType := types.NamespacedName{Name: configMap.Name, Namespace: resourceNamespace.Name} + updatedConfigMap := configMap.DeepCopy() updatedConfigMap.Data = map[string]string{} - testutils.UpdateWork(ctx, &workBeforeUpdate, HubCluster, []runtime.Object{}) + testutils.UpdateWork(ctx, &work, HubCluster, []runtime.Object{}) - By(fmt.Sprintf("The resource %s should be deleted in the member cluster %s", configMapBeforeUpdate.Name, memberClusterName)) + By(fmt.Sprintf("The resource %s should be deleted in the member cluster %s", configMap.Name, memberClusterName)) Eventually(func() error { retrievedConfigMap := corev1.ConfigMap{} if err := MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap); err != nil { return err } return nil - }, testutils.PollTimeout, testutils.PollInterval).ShouldNot(Succeed(), "Resource %s should have been deleted.", configMapBeforeUpdate.Name) + }, testutils.PollTimeout, testutils.PollInterval).ShouldNot(Succeed(), "Resource %s should have been deleted.", configMap.Name) By(fmt.Sprintf("The AppliedWork Manifest for Work %s should have been deleted", namespaceType)) appliedWork := workapi.AppliedWork{} @@ -649,15 +649,14 @@ var _ = Describe("Work API Controller test", func() { Expect(cmp.Diff(want, appliedWork.Status)).Should(BeEmpty(), "Status should be empty for AppliedWork %s", appliedWork.Name) - By(fmt.Sprintf("The Work Condition should have been deleted from the Work Object")) - work := workapi.Work{} - err = MemberCluster.KubeClient.Get(ctx, namespaceType, &work) + By(fmt.Sprintf("The Work Condition for Work %s should have been deleted from the Work Object", work.Name)) + updatedWork := workapi.Work{} + err = MemberCluster.KubeClient.Get(ctx, namespaceType, &updatedWork) Expect(err).Should(Succeed(), "Retrieving Work Object failed") - Expect(work.Status.Conditions).Should(BeNil(), - "Work Condition for Work Object %s should be empty", work.Name) - - Expect(work.Status.ManifestConditions).Should(BeNil(), - "Work Manifest Condition for Work Object %s should be empty", work.Name) + Expect(updatedWork.Status.Conditions).Should(BeNil(), + "Work Condition for Work Object %s should be empty", updatedWork.Name) + Expect(updatedWork.Status.ManifestConditions).Should(BeNil(), + "Work Manifest Condition for Work Object %s should be empty", updatedWork.Name) }) }) }) From 246337b7443ad7b3a89613f1b072caa5f86e51a2 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 27 Sep 2022 16:00:27 -0700 Subject: [PATCH 06/14] fixing errors --- test/e2e/work_api_e2e_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 1a4fae3dc..eeb9e709f 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -643,10 +643,7 @@ var _ = Describe("Work API Controller test", func() { appliedWork := workapi.AppliedWork{} err := MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork) Expect(err).Should(Succeed(), "Retrieving AppliedWork Manifest Failed") - want := workapi.AppliedtWorkStatus{ - AppliedResources: []workapi.AppliedResourceMeta{}, - } - Expect(cmp.Diff(want, appliedWork.Status)).Should(BeEmpty(), + Expect(appliedWork.Status.AppliedResources).Should(BeEmpty(), "Status should be empty for AppliedWork %s", appliedWork.Name) By(fmt.Sprintf("The Work Condition for Work %s should have been deleted from the Work Object", work.Name)) From 1f5c5662d9411ea613a2c29144a6286faae34923 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 27 Sep 2022 16:55:57 -0700 Subject: [PATCH 07/14] fixing errors --- test/e2e/work_api_e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index eeb9e709f..5eccb08a2 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -649,7 +649,7 @@ var _ = Describe("Work API Controller test", func() { By(fmt.Sprintf("The Work Condition for Work %s should have been deleted from the Work Object", work.Name)) updatedWork := workapi.Work{} err = MemberCluster.KubeClient.Get(ctx, namespaceType, &updatedWork) - Expect(err).Should(Succeed(), "Retrieving Work Object failed") + Expect(err).ShouldNot(Succeed(), "Retrieving Work Object should fail") Expect(updatedWork.Status.Conditions).Should(BeNil(), "Work Condition for Work Object %s should be empty", updatedWork.Name) Expect(updatedWork.Status.ManifestConditions).Should(BeNil(), From 2d6e40a332950e0acee81a05a4243ae94da53628 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Sat, 1 Oct 2022 15:41:30 +0900 Subject: [PATCH 08/14] Fixes based on comments --- test/e2e/utils/helper.go | 2 +- test/e2e/work_api_e2e_test.go | 777 +++++++++++++++++----------------- 2 files changed, 398 insertions(+), 381 deletions(-) diff --git a/test/e2e/utils/helper.go b/test/e2e/utils/helper.go index c12c89fa8..2912c914e 100644 --- a/test/e2e/utils/helper.go +++ b/test/e2e/utils/helper.go @@ -160,7 +160,7 @@ func CreateWork(ctx context.Context, hubCluster framework.Cluster, workName, wor } // UpdateWork updates an existing Work Object by replacing the Spec.Manifest with a new objects given from parameter. -func UpdateWork(ctx context.Context, work *workapi.Work, hubCluster *framework.Cluster, objects []runtime.Object) *workapi.Work { +func UpdateWork(ctx context.Context, hubCluster *framework.Cluster, work *workapi.Work, objects []runtime.Object) *workapi.Work { manifests := make([]workapi.Manifest, len(objects)) for index, obj := range objects { rawObj, err := json.Marshal(obj) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 5eccb08a2..f50629b2d 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -17,12 +17,10 @@ import ( "k8s.io/apimachinery/pkg/types" workapi "sigs.k8s.io/work-api/pkg/apis/v1alpha1" - workcontroller "go.goms.io/fleet/pkg/controllers/work" "go.goms.io/fleet/pkg/utils" testutils "go.goms.io/fleet/test/e2e/utils" ) -// TODO: enable this when join/leave logic is connected to work-api, join the Hub and Member for this test. var _ = Describe("Work API Controller test", func() { const ( @@ -78,87 +76,68 @@ var _ = Describe("Work API Controller test", func() { testutils.DeleteNamespace(*MemberCluster, resourceNamespace) }) - It("Upon successful work creation of a single resource, work manifest is applied and resource is created", func() { - workName := testutils.RandomWorkName(5) + Context("Work Creation Test", func() { + It("Upon successful work creation of a single resource, work manifest is applied and resource is created", func() { + workName := testutils.RandomWorkName(5) - By(fmt.Sprintf("Here is the work Name %s", workName)) + By(fmt.Sprintf("Here is the work Name %s", workName)) - // Configmap will be included in this work object. - manifestConfigMapName := "work-configmap" - manifestConfigMap := corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "ConfigMap", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: manifestConfigMapName, - Namespace: resourceNamespace.Name, - }, - Data: map[string]string{ - "test-key": "test-data", - }, - } + // Configmap will be included in this work object. + manifestConfigMapName := "work-configmap" + manifestConfigMap := corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: manifestConfigMapName, + Namespace: resourceNamespace.Name, + }, + Data: map[string]string{ + "test-key": "test-data", + }, + } - // Creating types.NamespacedName to use in retrieving objects. - namespaceType := types.NamespacedName{Name: workName, Namespace: workNamespace.Name} + // Creating types.NamespacedName to use in retrieving objects. + namespaceType := types.NamespacedName{Name: workName, Namespace: workNamespace.Name} - //Creating types.NamespacedName for the resource created. - resourceNamespaceType := types.NamespacedName{Name: manifestConfigMapName, Namespace: resourceNamespace.Name} + //Creating types.NamespacedName for the resource created. + resourceNamespaceType := types.NamespacedName{Name: manifestConfigMapName, Namespace: resourceNamespace.Name} - manifests := testutils.AddManifests([]runtime.Object{&manifestConfigMap}, []workapi.Manifest{}) - By(fmt.Sprintf("creating work %s of %s", namespaceType, manifestConfigMapName)) - testutils.CreateWork(ctx, *HubCluster, workName, workNamespace.Name, manifests) + manifests := testutils.AddManifests([]runtime.Object{&manifestConfigMap}, []workapi.Manifest{}) + By(fmt.Sprintf("creating work %s of %s", namespaceType, manifestConfigMapName)) + testutils.CreateWork(ctx, *HubCluster, workName, workNamespace.Name, manifests) - By(fmt.Sprintf("Applied Condition should be set to True for Work %s", namespaceType)) - work := workapi.Work{} + By(fmt.Sprintf("Applied Condition should be set to True for Work %s", namespaceType)) + work := workapi.Work{} - Eventually(func() string { - if err := HubCluster.KubeClient.Get(ctx, namespaceType, &work); err != nil { - return err.Error() - } - want := []metav1.Condition{ - { - Type: conditionTypeApplied, - Status: metav1.ConditionTrue, - Reason: "appliedWorkComplete", - }, - } - return cmp.Diff(want, work.Status.Conditions, cmpOptions...) - }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Validate WorkStatus mismatch (-want, +got):") + Eventually(func() string { + if err := HubCluster.KubeClient.Get(ctx, namespaceType, &work); err != nil { + return err.Error() + } - By(fmt.Sprintf("Manifest Condiitons on Work Objects %s should be applied", namespaceType)) - wantManifestCondition := []workapi.ManifestCondition{ - { - Conditions: []metav1.Condition{ + want := []metav1.Condition{ { Type: conditionTypeApplied, Status: metav1.ConditionTrue, + Reason: "appliedWorkComplete", }, - }, - Identifier: workapi.ResourceIdentifier{ - Group: manifestConfigMap.GroupVersionKind().Group, - Version: manifestConfigMap.GroupVersionKind().Version, - Kind: manifestConfigMap.GroupVersionKind().Kind, - Namespace: manifestConfigMap.Namespace, - Name: manifestConfigMap.Name, - Resource: "configmaps", - }, - }, - } - - Expect(cmp.Diff(wantManifestCondition, work.Status.ManifestConditions, cmpOptions...)).Should(BeEmpty(), - "Manifest Condition not matching for work %s (-want, +got):", namespaceType) - Expect(work.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestCreatedAction)).Should(BeTrue()) + } - By(fmt.Sprintf("AppliedWorkStatus should contain the meta for the resource %s", manifestConfigMapName)) - appliedWork := workapi.AppliedWork{} - Expect(MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork)).Should(Succeed(), - "Retrieving AppliedWork %s failed", workName) + return cmp.Diff(want, work.Status.Conditions, cmpOptions...) + }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Validate WorkStatus mismatch (-want, +got):") - want := workapi.AppliedtWorkStatus{ - AppliedResources: []workapi.AppliedResourceMeta{ + By(fmt.Sprintf("Manifest Condiitons on Work Objects %s should be applied", namespaceType)) + wantManifestCondition := []workapi.ManifestCondition{ { - ResourceIdentifier: workapi.ResourceIdentifier{ + Conditions: []metav1.Condition{ + { + Type: conditionTypeApplied, + Status: metav1.ConditionTrue, + Reason: "appliedManifestUpdated", + }, + }, + Identifier: workapi.ResourceIdentifier{ Group: manifestConfigMap.GroupVersionKind().Group, Version: manifestConfigMap.GroupVersionKind().Version, Kind: manifestConfigMap.GroupVersionKind().Kind, @@ -167,136 +146,137 @@ var _ = Describe("Work API Controller test", func() { Resource: "configmaps", }, }, - }, - } + } - Expect(cmp.Diff(want, appliedWork.Status, appliedWorkCmpOptions...)).Should(BeEmpty(), - "Validate AppliedResourceMeta mismatch (-want, +got):") - - By(fmt.Sprintf("Resource %s should have been created in cluster %s", manifestConfigMapName, MemberCluster.ClusterName)) - retrievedConfigMap := corev1.ConfigMap{} - Expect(MemberCluster.KubeClient.Get(ctx, resourceNamespaceType, &retrievedConfigMap)).Should(Succeed(), - "Retrieving the resource %s failed", manifestConfigMap.Name) - //TODO: Fix this to compare the whole structure instead of just the data - Expect(cmp.Diff(manifestConfigMap.Data, retrievedConfigMap.Data)).Should(BeEmpty(), - "ConfigMap %s was not created in the cluster %s, or configMap data mismatch(-want, +got):", manifestConfigMapName, MemberCluster.ClusterName) - - By(fmt.Sprintf("Validating that the resource %s is owned by the work %s", manifestConfigMapName, namespaceType)) - wantOwner := []metav1.OwnerReference{ - { - APIVersion: workapi.GroupVersion.String(), - Kind: workapi.AppliedWorkKind, - Name: appliedWork.GetName(), - UID: appliedWork.GetUID(), - }, - } + Expect(cmp.Diff(wantManifestCondition, work.Status.ManifestConditions, cmpOptions...)).Should(BeEmpty(), + "Manifest Condition not matching for work %s (-want, +got):", namespaceType) - Expect(cmp.Diff(wantOwner, retrievedConfigMap.OwnerReferences, cmpOptions...)).Should(BeEmpty(), "OwnerReference mismatch (-want, +got):") + Expect(work.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestCreatedAction)).Should(BeTrue()) - By(fmt.Sprintf("Validating that the annotation of resource's spec exists on the resource %s", manifestConfigMapName)) - Expect(retrievedConfigMap.ObjectMeta.Annotations[specHashAnnotation]).ToNot(BeEmpty(), - "SpecHash Annotation does not exist for resource %s", retrievedConfigMap.Name) - }) + By(fmt.Sprintf("AppliedWorkStatus should contain the meta for the resource %s", manifestConfigMapName)) + appliedWork := workapi.AppliedWork{} + Expect(MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork)).Should(Succeed(), + "Retrieving AppliedWork %s failed", workName) - It("Upon successful creation of 2 work resources with same manifest, work manifest is applied, and only 1 resource is created with merged owner references.", func() { - workNameOne := testutils.RandomWorkName(5) - workNameTwo := testutils.RandomWorkName(5) + want := workapi.AppliedtWorkStatus{ + AppliedResources: []workapi.AppliedResourceMeta{ + { + ResourceIdentifier: workapi.ResourceIdentifier{ + Group: manifestConfigMap.GroupVersionKind().Group, + Version: manifestConfigMap.GroupVersionKind().Version, + Kind: manifestConfigMap.GroupVersionKind().Kind, + Namespace: manifestConfigMap.Namespace, + Name: manifestConfigMap.Name, + Resource: "configmaps", + }, + }, + }, + } - manifestSecretName := "test-secret" + Expect(cmp.Diff(want, appliedWork.Status, appliedWorkCmpOptions...)).Should(BeEmpty(), + "Validate AppliedResourceMeta mismatch (-want, +got):") - secret := corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Secret", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: manifestSecretName, - Namespace: resourceNamespace.Name, - }, - Data: map[string][]byte{ - "test-secret": []byte("test-data"), - }, - Type: "Opaque", - } + By(fmt.Sprintf("Resource %s should have been created in cluster %s", manifestConfigMapName, MemberCluster.ClusterName)) + gotConfigMap := corev1.ConfigMap{} + Expect(MemberCluster.KubeClient.Get(ctx, resourceNamespaceType, &gotConfigMap)).Should(Succeed(), + "Retrieving the resource %s failed", manifestConfigMap.Name) + //TODO: Fix this to compare the whole structure instead of just the data + Expect(cmp.Diff(manifestConfigMap.Data, gotConfigMap.Data)).Should(BeEmpty(), + "ConfigMap %s was not created in the cluster %s, or configMap data mismatch(-want, +got):", manifestConfigMapName, MemberCluster.ClusterName) - // Creating types.NamespacedName to use in retrieving objects. - namespaceTypeOne := types.NamespacedName{Name: workNameOne, Namespace: workNamespace.Name} - namespaceTypeTwo := types.NamespacedName{Name: workNameTwo, Namespace: workNamespace.Name} + By(fmt.Sprintf("Validating that the resource %s is owned by the work %s", manifestConfigMapName, namespaceType)) + wantOwner := []metav1.OwnerReference{ + { + APIVersion: workapi.GroupVersion.String(), + Kind: workapi.AppliedWorkKind, + Name: appliedWork.GetName(), + UID: appliedWork.GetUID(), + }, + } - resourceNamespaceType := types.NamespacedName{Name: manifestSecretName, Namespace: resourceNamespace.Name} + Expect(cmp.Diff(wantOwner, gotConfigMap.OwnerReferences, cmpOptions...)).Should(BeEmpty(), "OwnerReference mismatch (-want, +got):") - manifests := testutils.AddManifests([]runtime.Object{&secret}, []workapi.Manifest{}) + By(fmt.Sprintf("Validating that the annotation of resource's spec exists on the resource %s", manifestConfigMapName)) + Expect(gotConfigMap.ObjectMeta.Annotations[specHashAnnotation]).ToNot(BeEmpty(), + "SpecHash Annotation does not exist for resource %s", gotConfigMap.Name) + }) - By(fmt.Sprintf("creating work %s of %s", namespaceTypeOne, manifestSecretName)) - testutils.CreateWork(ctx, *HubCluster, workNameOne, workNamespace.Name, manifests) + It("Upon successful creation of 2 work resources with same manifest, work manifest is applied, and only 1 resource is created with merged owner references.", func() { + workNameOne := testutils.RandomWorkName(5) + workNameTwo := testutils.RandomWorkName(5) - By(fmt.Sprintf("creating work %s of %s", namespaceTypeTwo, manifestSecretName)) - testutils.CreateWork(ctx, *HubCluster, workNameTwo, workNamespace.Name, manifests) + manifestSecretName := "test-secret" - By(fmt.Sprintf("Applied Condition should be set to True for Work %s and %s", namespaceTypeOne, namespaceTypeTwo)) + secret := corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: manifestSecretName, + Namespace: resourceNamespace.Name, + }, + Data: map[string][]byte{ + "test-secret": []byte("test-data"), + }, + Type: "Opaque", + } - want := []metav1.Condition{ - { - Type: conditionTypeApplied, - Status: metav1.ConditionTrue, - Reason: "appliedWorkComplete", - }, - } + // Creating types.NamespacedName to use in retrieving objects. + namespaceTypeOne := types.NamespacedName{Name: workNameOne, Namespace: workNamespace.Name} + namespaceTypeTwo := types.NamespacedName{Name: workNameTwo, Namespace: workNamespace.Name} - workOne := workapi.Work{} - Eventually(func() string { - if err := HubCluster.KubeClient.Get(ctx, namespaceTypeOne, &workOne); err != nil { - return err.Error() - } - return cmp.Diff(want, workOne.Status.Conditions, cmpOptions...) - }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Validate WorkStatus mismatch (-want, +got):") + resourceNamespaceType := types.NamespacedName{Name: manifestSecretName, Namespace: resourceNamespace.Name} - workTwo := workapi.Work{} - Eventually(func() string { - if err := HubCluster.KubeClient.Get(ctx, namespaceTypeTwo, &workTwo); err != nil { - return err.Error() - } - return cmp.Diff(want, workTwo.Status.Conditions, cmpOptions...) - }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Validate WorkStatus mismatch (-want, +got):") + manifests := testutils.AddManifests([]runtime.Object{&secret}, []workapi.Manifest{}) - By(fmt.Sprintf("Manifest Condiitons on Work Objects %s and %s should be applied", namespaceTypeOne, namespaceTypeTwo)) - wantManifestCondition := []workapi.ManifestCondition{ - { - Conditions: []metav1.Condition{ - { - Type: conditionTypeApplied, - Status: metav1.ConditionTrue, - }, - }, - Identifier: workapi.ResourceIdentifier{ - Group: secret.GroupVersionKind().Group, - Version: secret.GroupVersionKind().Version, - Kind: secret.GroupVersionKind().Kind, - Namespace: secret.Namespace, - Name: secret.Name, - Resource: "secrets", + By(fmt.Sprintf("creating work %s of %s", namespaceTypeOne, manifestSecretName)) + testutils.CreateWork(ctx, *HubCluster, workNameOne, workNamespace.Name, manifests) + + By(fmt.Sprintf("creating work %s of %s", namespaceTypeTwo, manifestSecretName)) + testutils.CreateWork(ctx, *HubCluster, workNameTwo, workNamespace.Name, manifests) + + By(fmt.Sprintf("Applied Condition should be set to True for Work %s and %s", namespaceTypeOne, namespaceTypeTwo)) + + want := []metav1.Condition{ + { + Type: conditionTypeApplied, + Status: metav1.ConditionTrue, + Reason: "appliedWorkComplete", }, - }, - } + } + + workOne := workapi.Work{} + + Eventually(func() string { + if err := HubCluster.KubeClient.Get(ctx, namespaceTypeOne, &workOne); err != nil { + return err.Error() + } - Expect(cmp.Diff(wantManifestCondition, workOne.Status.ManifestConditions, cmpOptions...)).Should(BeEmpty(), - "Manifest Condition not matching for work %s (-want, +got):", namespaceTypeOne) + return cmp.Diff(want, workOne.Status.Conditions, cmpOptions...) + }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Validate WorkStatus mismatch (-want, +got):") - Expect(cmp.Diff(wantManifestCondition, workTwo.Status.ManifestConditions, cmpOptions...)).Should(BeEmpty(), - "Manifest Condition not matching for work %s (-want, +got):", namespaceTypeTwo) + workTwo := workapi.Work{} - // One of them should be a ManifestCreatedAction and one of them should be an ManifestUpdatedAction - By(fmt.Sprintf("Verify that either works %s and %s condition reason should be updated", namespaceTypeOne, namespaceTypeTwo)) - Expect(workOne.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestCreatedAction) || - workTwo.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestCreatedAction)).Should(BeTrue()) - Expect(workOne.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestUpdatedAction) || - workTwo.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestUpdatedAction)).Should(BeTrue()) + Eventually(func() string { + if err := HubCluster.KubeClient.Get(ctx, namespaceTypeTwo, &workTwo); err != nil { + return err.Error() + } - By(fmt.Sprintf("AppliedWorkStatus for both works %s and %s should contain the meta for the resource %s", namespaceTypeOne, namespaceTypeTwo, manifestSecretName)) - wantAppliedStatus := workapi.AppliedtWorkStatus{ - AppliedResources: []workapi.AppliedResourceMeta{ + return cmp.Diff(want, workTwo.Status.Conditions, cmpOptions...) + }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Validate WorkStatus mismatch (-want, +got):") + + By(fmt.Sprintf("Manifest Condiitons on Work Objects %s and %s should be applied", namespaceTypeOne, namespaceTypeTwo)) + wantManifestCondition := []workapi.ManifestCondition{ { - ResourceIdentifier: workapi.ResourceIdentifier{ + Conditions: []metav1.Condition{ + { + Type: conditionTypeApplied, + Status: metav1.ConditionTrue, + Reason: "appliedManifestUpdated", + }, + }, + Identifier: workapi.ResourceIdentifier{ Group: secret.GroupVersionKind().Group, Version: secret.GroupVersionKind().Version, Kind: secret.GroupVersionKind().Kind, @@ -305,156 +285,145 @@ var _ = Describe("Work API Controller test", func() { Resource: "secrets", }, }, - }, - } - - appliedWorkOne := workapi.AppliedWork{} - Expect(MemberCluster.KubeClient.Get(ctx, namespaceTypeOne, &appliedWorkOne)).Should(Succeed(), - "Retrieving AppliedWork %s failed", workNameOne) + } - Expect(cmp.Diff(wantAppliedStatus, appliedWorkOne.Status, appliedWorkCmpOptions...)).Should(BeEmpty(), - "Validate AppliedResourceMeta mismatch (-want, +got):") + Expect(cmp.Diff(wantManifestCondition, workOne.Status.ManifestConditions, cmpOptions...)).Should(BeEmpty(), + "Manifest Condition not matching for work %s (-want, +got):", namespaceTypeOne) - appliedWorkTwo := workapi.AppliedWork{} - Expect(MemberCluster.KubeClient.Get(ctx, namespaceTypeTwo, &appliedWorkTwo)).Should(Succeed(), - "Retrieving AppliedWork %s failed", workNameTwo) + Expect(cmp.Diff(wantManifestCondition, workTwo.Status.ManifestConditions, cmpOptions...)).Should(BeEmpty(), + "Manifest Condition not matching for work %s (-want, +got):", namespaceTypeTwo) - Expect(cmp.Diff(wantAppliedStatus, appliedWorkTwo.Status, appliedWorkCmpOptions...)).Should(BeEmpty(), - "Validate AppliedResourceMeta mismatch (-want, +got):") + // One of them should be a ManifestCreatedAction and one of them should be an ManifestUpdatedAction + By(fmt.Sprintf("Verify that either works %s and %s condition reason should be updated", namespaceTypeOne, namespaceTypeTwo)) + Expect(workOne.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestCreatedAction) || + workTwo.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestCreatedAction)).Should(BeTrue()) + Expect(workOne.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestUpdatedAction) || + workTwo.Status.ManifestConditions[0].Conditions[0].Reason == string(workcontroller.ManifestUpdatedAction)).Should(BeTrue()) - By(fmt.Sprintf("Resource %s should have been created in cluster %s", manifestSecretName, MemberCluster.ClusterName)) - retrievedSecret := corev1.Secret{} - err := MemberCluster.KubeClient.Get(ctx, resourceNamespaceType, &retrievedSecret) + By(fmt.Sprintf("AppliedWorkStatus for both works %s and %s should contain the meta for the resource %s", namespaceTypeOne, namespaceTypeTwo, manifestSecretName)) + wantAppliedStatus := workapi.AppliedtWorkStatus{ + AppliedResources: []workapi.AppliedResourceMeta{ + { + ResourceIdentifier: workapi.ResourceIdentifier{ + Group: secret.GroupVersionKind().Group, + Version: secret.GroupVersionKind().Version, + Kind: secret.GroupVersionKind().Kind, + Namespace: secret.Namespace, + Name: secret.Name, + Resource: "secrets", + }, + }, + }, + } - Expect(err).Should(Succeed(), "Secret %s was not created in the cluster %s", manifestSecretName, MemberCluster.ClusterName) + appliedWorkOne := workapi.AppliedWork{} + Expect(MemberCluster.KubeClient.Get(ctx, namespaceTypeOne, &appliedWorkOne)).Should(Succeed(), + "Retrieving AppliedWork %s failed", workNameOne) - Expect(cmp.Diff(secret, retrievedSecret, append(cmpOptions, secretCmpOptions...)...)).Should(BeEmpty(), "Secret %s mismatch (-want, +got):") + Expect(cmp.Diff(wantAppliedStatus, appliedWorkOne.Status, appliedWorkCmpOptions...)).Should(BeEmpty(), + "Validate AppliedResourceMeta mismatch (-want, +got):") - By(fmt.Sprintf("Validating that the resource %s is owned by the both works: %s and %s", manifestSecretName, namespaceTypeOne, namespaceTypeTwo)) - wantOwner := []metav1.OwnerReference{ - { - APIVersion: workapi.GroupVersion.String(), - Kind: workapi.AppliedWorkKind, - Name: appliedWorkOne.GetName(), - UID: appliedWorkOne.GetUID(), - }, - { - APIVersion: workapi.GroupVersion.String(), - Kind: workapi.AppliedWorkKind, - Name: appliedWorkTwo.GetName(), - UID: appliedWorkTwo.GetUID(), - }, - } - // sort using compare function (sort the array to guarantee the sequence) - // then the result will be determined - sortSlicesOption := append(cmpOptions, cmpopts.SortSlices(func(ref1, ref2 metav1.OwnerReference) bool { return ref1.Name < ref2.Name })) - Expect(cmp.Diff(wantOwner, retrievedSecret.OwnerReferences, sortSlicesOption...)).Should(BeEmpty(), "OwnerReference mismatch (-want, +got):") - - By(fmt.Sprintf("Validating that the annotation of resource's spec exists on the resource %s", manifestSecretName)) - Expect(retrievedSecret.ObjectMeta.Annotations[specHashAnnotation]).ToNot(BeEmpty(), - "SpecHash Annotation does not exist for resource %s", secret.Name) - }) + appliedWorkTwo := workapi.AppliedWork{} + Expect(MemberCluster.KubeClient.Get(ctx, namespaceTypeTwo, &appliedWorkTwo)).Should(Succeed(), + "Retrieving AppliedWork %s failed", workNameTwo) - It("Upon successful work creation of a CRD resource, manifest is applied, and resources are created", func() { - workName := testutils.RandomWorkName(5) + Expect(cmp.Diff(wantAppliedStatus, appliedWorkTwo.Status, appliedWorkCmpOptions...)).Should(BeEmpty(), + "Validate AppliedResourceMeta mismatch (-want, +got):") - // Name of the CRD object from the manifest file - crdName := "testcrds.multicluster.x-k8s.io" - crdObjectName := "test-crd-object" + By(fmt.Sprintf("Resource %s should have been created in cluster %s", manifestSecretName, MemberCluster.ClusterName)) + retrievedSecret := corev1.Secret{} + err := MemberCluster.KubeClient.Get(ctx, resourceNamespaceType, &retrievedSecret) - // Creating CRD manifest from test file - manifestCRD, crdGVK, crdGVR := testutils.GenerateCRDObjectFromFile(*MemberCluster, TestManifestFiles, "manifests/test-crd.yaml", genericCodec) + Expect(err).Should(Succeed(), "Secret %s was not created in the cluster %s", manifestSecretName, MemberCluster.ClusterName) - // GVR for the Custom Resource created - crGVR := schema.GroupVersionResource{ - Group: "multicluster.x-k8s.io", - Version: "v1alpha1", - Resource: "testcrds", - } - customResourceManifestString := "{\"apiVersion\":\"multicluster.x-k8s.io/v1alpha1\",\"kind\":\"TestCRD\",\"metadata\":{\"name\":\"test-crd-object\"}}" + Expect(cmp.Diff(secret, retrievedSecret, append(cmpOptions, secretCmpOptions...)...)).Should(BeEmpty(), "Secret %s mismatch (-want, +got):") - // Creating types.NamespacedName to use in retrieving objects. - namespaceType := types.NamespacedName{Name: workName, Namespace: workNamespace.Name} + By(fmt.Sprintf("Validating that the resource %s is owned by the both works: %s and %s", manifestSecretName, namespaceTypeOne, namespaceTypeTwo)) + wantOwner := []metav1.OwnerReference{ + { + APIVersion: workapi.GroupVersion.String(), + Kind: workapi.AppliedWorkKind, + Name: appliedWorkOne.GetName(), + UID: appliedWorkOne.GetUID(), + }, + { + APIVersion: workapi.GroupVersion.String(), + Kind: workapi.AppliedWorkKind, + Name: appliedWorkTwo.GetName(), + UID: appliedWorkTwo.GetUID(), + }, + } + // sort using compare function (sort the array to guarantee the sequence) + // then the result will be determined + sortSlicesOption := append(cmpOptions, cmpopts.SortSlices(func(ref1, ref2 metav1.OwnerReference) bool { return ref1.Name < ref2.Name })) + Expect(cmp.Diff(wantOwner, retrievedSecret.OwnerReferences, sortSlicesOption...)).Should(BeEmpty(), "OwnerReference mismatch (-want, +got):") + + By(fmt.Sprintf("Validating that the annotation of resource's spec exists on the resource %s", manifestSecretName)) + Expect(retrievedSecret.ObjectMeta.Annotations[specHashAnnotation]).ToNot(BeEmpty(), + "SpecHash Annotation does not exist for resource %s", secret.Name) + }) - // Creating NamespacedName to retrieve CRD object created - crdNamespaceType := types.NamespacedName{Name: crdName} + It("Upon successful work creation of a CRD resource, manifest is applied, and resources are created", func() { + workName := testutils.RandomWorkName(5) - By(fmt.Sprintf("creating work %s of %s", namespaceType, crdGVK.Kind)) - manifests := testutils.AddManifests([]runtime.Object{manifestCRD}, []workapi.Manifest{}) - manifests = testutils.AddByteArrayToManifest([]byte(customResourceManifestString), manifests) - testutils.CreateWork(ctx, *HubCluster, workName, workNamespace.Name, manifests) + // Name of the CRD object from the manifest file + crdName := "testcrds.multicluster.x-k8s.io" + crdObjectName := "test-crd-object" - By(fmt.Sprintf("Applied Condition should be set to True for Work %s", namespaceType)) - work := workapi.Work{} + // Creating CRD manifest from test file + manifestCRD, crdGVK, crdGVR := testutils.GenerateCRDObjectFromFile(*MemberCluster, TestManifestFiles, "manifests/test-crd.yaml", genericCodec) - Eventually(func() string { - if err := HubCluster.KubeClient.Get(ctx, namespaceType, &work); err != nil { - return err.Error() + // GVR for the Custom Resource created + crGVR := schema.GroupVersionResource{ + Group: "multicluster.x-k8s.io", + Version: "v1alpha1", + Resource: "testcrds", } + customResourceManifestString := "{\"apiVersion\":\"multicluster.x-k8s.io/v1alpha1\",\"kind\":\"TestCRD\",\"metadata\":{\"name\":\"test-crd-object\"}}" - want := []metav1.Condition{ - { - Type: conditionTypeApplied, - Status: metav1.ConditionTrue, - Reason: "appliedWorkComplete", - }, - } + // Creating types.NamespacedName to use in retrieving objects. + namespaceType := types.NamespacedName{Name: workName, Namespace: workNamespace.Name} - return cmp.Diff(want, work.Status.Conditions, cmpOptions...) - }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), - "Applied Condition mismatch for work %s (-want, +got):", workName) + // Creating NamespacedName to retrieve CRD object created + crdNamespaceType := types.NamespacedName{Name: crdName} - By(fmt.Sprintf("Manifest Condiitons on Work Objects %s should be applied", namespaceType)) - expectedManifestCondition := []workapi.ManifestCondition{ - { - Conditions: []metav1.Condition{ - { - Type: conditionTypeApplied, - Status: metav1.ConditionTrue, - // Will ignore reason for now, there can be 2 different outcomes, Complete and Updated. - //Reason: "appliedManifestComplete", - }, - }, - Identifier: workapi.ResourceIdentifier{ - Group: crdGVK.Group, - Version: crdGVK.Version, - Kind: crdGVK.Kind, - Name: crdName, - Resource: crdGVR.Resource, - }, - }, - { - Conditions: []metav1.Condition{ + By(fmt.Sprintf("creating work %s of %s", namespaceType, crdGVK.Kind)) + manifests := testutils.AddManifests([]runtime.Object{manifestCRD}, []workapi.Manifest{}) + manifests = testutils.AddByteArrayToManifest([]byte(customResourceManifestString), manifests) + testutils.CreateWork(ctx, *HubCluster, workName, workNamespace.Name, manifests) + + By(fmt.Sprintf("Applied Condition should be set to True for Work %s", namespaceType)) + work := workapi.Work{} + + Eventually(func() string { + if err := HubCluster.KubeClient.Get(ctx, namespaceType, &work); err != nil { + return err.Error() + } + + want := []metav1.Condition{ { Type: conditionTypeApplied, Status: metav1.ConditionTrue, - //Reason: "appliedManifestUpdated", + Reason: "appliedWorkComplete", }, - }, - Identifier: workapi.ResourceIdentifier{ - Group: crGVR.Group, - Version: crGVR.Version, - Kind: "TestCRD", - Name: crdObjectName, - Resource: "testcrds", - }, - }, - } - - options := append(cmpOptions, cmpopts.IgnoreFields(metav1.Condition{}, "Reason")) - Expect(cmp.Diff(expectedManifestCondition, work.Status.ManifestConditions, options...)).Should(BeEmpty(), - "Manifest Condition not matching for work %s (-want, +got):", namespaceType) - - By(fmt.Sprintf("AppliedWorkStatus should contain the meta for the resource %s", crdGVK.Kind)) - var appliedWork workapi.AppliedWork + } - Expect(MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork)).Should(Succeed(), - "Retrieving AppliedWork %s failed", workName) + return cmp.Diff(want, work.Status.Conditions, cmpOptions...) + }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), + "Applied Condition mismatch for work %s (-want, +got):", workName) - want := workapi.AppliedtWorkStatus{ - AppliedResources: []workapi.AppliedResourceMeta{ + By(fmt.Sprintf("Manifest Condiitons on Work Objects %s should be applied", namespaceType)) + expectedManifestCondition := []workapi.ManifestCondition{ { - ResourceIdentifier: workapi.ResourceIdentifier{ + Conditions: []metav1.Condition{ + { + Type: conditionTypeApplied, + Status: metav1.ConditionTrue, + // Will ignore reason for now, there can be 2 different outcomes, Complete and Updated. + //Reason: "appliedManifestComplete", + }, + }, + Identifier: workapi.ResourceIdentifier{ Group: crdGVK.Group, Version: crdGVK.Version, Kind: crdGVK.Kind, @@ -463,7 +432,14 @@ var _ = Describe("Work API Controller test", func() { }, }, { - ResourceIdentifier: workapi.ResourceIdentifier{ + Conditions: []metav1.Condition{ + { + Type: conditionTypeApplied, + Status: metav1.ConditionTrue, + //Reason: "appliedManifestUpdated", + }, + }, + Identifier: workapi.ResourceIdentifier{ Group: crGVR.Group, Version: crGVR.Version, Kind: "TestCRD", @@ -471,81 +447,114 @@ var _ = Describe("Work API Controller test", func() { Resource: "testcrds", }, }, - }, - } + } - Expect(cmp.Diff(want, appliedWork.Status, appliedWorkCmpOptions...)).Should(BeEmpty(), "Validate AppliedResourceMeta mismatch (-want, +got):") + options := append(cmpOptions, cmpopts.IgnoreFields(metav1.Condition{}, "Reason")) + Expect(cmp.Diff(expectedManifestCondition, work.Status.ManifestConditions, options...)).Should(BeEmpty(), + "Manifest Condition not matching for work %s (-want, +got):", namespaceType) - By(fmt.Sprintf("CRD %s should have been created in cluster %s", crdName, MemberCluster.ClusterName)) + By(fmt.Sprintf("AppliedWorkStatus should contain the meta for the resource %s", crdGVK.Kind)) + var appliedWork workapi.AppliedWork - crd := apiextensionsv1.CustomResourceDefinition{} - err := MemberCluster.KubeClient.Get(ctx, crdNamespaceType, &crd) - Expect(err).Should(Succeed(), "Resources %s not created in cluster %s", crdName, MemberCluster.ClusterName) + Expect(MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork)).Should(Succeed(), + "Retrieving AppliedWork %s failed", workName) - wantCRD := apiextensionsv1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: "testcrds.multicluster.x-k8s.io", - }, - Spec: apiextensionsv1.CustomResourceDefinitionSpec{ - Group: "multicluster.x-k8s.io", - Names: apiextensionsv1.CustomResourceDefinitionNames{ - Plural: "testcrds", - Singular: "testcrd", - ShortNames: nil, - Kind: "TestCRD", - ListKind: "TestCRDList", - Categories: nil, + wantAppliedWorkStatus := workapi.AppliedtWorkStatus{ + AppliedResources: []workapi.AppliedResourceMeta{ + { + ResourceIdentifier: workapi.ResourceIdentifier{ + Group: crdGVK.Group, + Version: crdGVK.Version, + Kind: crdGVK.Kind, + Name: crdName, + Resource: crdGVR.Resource, + }, + }, + { + ResourceIdentifier: workapi.ResourceIdentifier{ + Group: crGVR.Group, + Version: crGVR.Version, + Kind: "TestCRD", + Name: crdObjectName, + Resource: "testcrds", + }, + }, }, - Scope: "Cluster", - }, - } + } + + Expect(cmp.Diff(wantAppliedWorkStatus, appliedWork.Status, appliedWorkCmpOptions...)).Should(BeEmpty(), "Validate AppliedResourceMeta mismatch (-want, +got):") - Expect(cmp.Diff(wantCRD, crd, crdCmpOptions...)).Should(BeEmpty(), "Valdate CRD object mismatch (-want, got+):") + By(fmt.Sprintf("CRD %s should have been created in cluster %s", crdName, MemberCluster.ClusterName)) - By(fmt.Sprintf("CR %s should have been created in cluster %s", crdObjectName, MemberCluster.ClusterName)) + crd := apiextensionsv1.CustomResourceDefinition{} + err := MemberCluster.KubeClient.Get(ctx, crdNamespaceType, &crd) + Expect(err).Should(Succeed(), "Resources %s not created in cluster %s", crdName, MemberCluster.ClusterName) - customResource, err := MemberCluster.DynamicClient.Resource(crGVR).Get(ctx, crdObjectName, metav1.GetOptions{}) - Expect(err).Should(Succeed(), "retrieving CR %s failed in cluster %s", crdObjectName, MemberCluster.ClusterName) - wantCRObject := unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "multicluster.x-k8s.io/v1alpha1", - "kind": "TestCRD", - "metadata": map[string]interface{}{ - "name": "test-crd-object", + wantCRD := apiextensionsv1.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testcrds.multicluster.x-k8s.io", }, - }, - } + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: "multicluster.x-k8s.io", + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "testcrds", + Singular: "testcrd", + ShortNames: nil, + Kind: "TestCRD", + ListKind: "TestCRDList", + Categories: nil, + }, + Scope: "Cluster", + }, + } - filterMetadataFunc := cmp.FilterPath(isKeyMetadata, cmp.Ignore()) - filterNotNameFunc := cmp.FilterPath(isKeyNotName, cmp.Ignore()) + Expect(cmp.Diff(wantCRD, crd, crdCmpOptions...)).Should(BeEmpty(), "Valdate CRD object mismatch (-want, got+):") - Expect(cmp.Diff(wantCRObject, *customResource, - append(cmpOptions, filterMetadataFunc)...)).Should(BeEmpty(), "Validate CR Object Metadata mismatch (-want, +got):") + By(fmt.Sprintf("CR %s should have been created in cluster %s", crdObjectName, MemberCluster.ClusterName)) - Expect(cmp.Diff(wantCRObject.Object["metadata"], customResource.Object["metadata"], - append(cmpOptions, filterNotNameFunc)...)).Should(BeEmpty(), "Validate CR Object Metadata mismatch (-want, +got):") + customResource, err := MemberCluster.DynamicClient.Resource(crGVR).Get(ctx, crdObjectName, metav1.GetOptions{}) + Expect(err).Should(Succeed(), "retrieving CR %s failed in cluster %s", crdObjectName, MemberCluster.ClusterName) + wantCRObject := unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "multicluster.x-k8s.io/v1alpha1", + "kind": "TestCRD", + "metadata": map[string]interface{}{ + "name": "test-crd-object", + }, + }, + } - By(fmt.Sprintf("Validating that the resource %s is owned by the work %s", crdName, namespaceType)) - wantOwner := []metav1.OwnerReference{ - { - APIVersion: workapi.GroupVersion.String(), - Kind: workapi.AppliedWorkKind, - Name: appliedWork.GetName(), - UID: appliedWork.GetUID(), - }, - } + filterMetadataFunc := cmp.FilterPath(isKeyMetadata, cmp.Ignore()) + filterNotNameFunc := cmp.FilterPath(isKeyNotName, cmp.Ignore()) + + Expect(cmp.Diff(wantCRObject, *customResource, + append(cmpOptions, filterMetadataFunc)...)).Should(BeEmpty(), "Validate CR Object Metadata mismatch (-want, +got):") + + Expect(cmp.Diff(wantCRObject.Object["metadata"], customResource.Object["metadata"], + append(cmpOptions, filterNotNameFunc)...)).Should(BeEmpty(), "Validate CR Object Metadata mismatch (-want, +got):") + + By(fmt.Sprintf("Validating that the resource %s is owned by the work %s", crdName, namespaceType)) + wantOwner := []metav1.OwnerReference{ + { + APIVersion: workapi.GroupVersion.String(), + Kind: workapi.AppliedWorkKind, + Name: appliedWork.GetName(), + UID: appliedWork.GetUID(), + }, + } - Expect(cmp.Diff(wantOwner, crd.OwnerReferences, cmpOptions...)).Should(BeEmpty(), - "OwnerReference for resource %s mismatch (-want, +got):", crd.Name) - Expect(cmp.Diff(wantOwner, customResource.GetOwnerReferences(), cmpOptions...)).Should(BeEmpty(), - "OwnerReference for CR %s mismatch (-want, +got):", customResource.GetName()) + Expect(cmp.Diff(wantOwner, crd.OwnerReferences, cmpOptions...)).Should(BeEmpty(), + "OwnerReference for resource %s mismatch (-want, +got):", crd.Name) + Expect(cmp.Diff(wantOwner, customResource.GetOwnerReferences(), cmpOptions...)).Should(BeEmpty(), + "OwnerReference for CR %s mismatch (-want, +got):", customResource.GetName()) - By(fmt.Sprintf("Validating that the annotation of resource's spec exists on the resource %s", crd.Name)) + By(fmt.Sprintf("Validating that the annotation of resource's spec exists on the resource %s", crd.Name)) - Expect(crd.GetAnnotations()[specHashAnnotation]).ToNot(BeEmpty(), - "There is no spec annotation on the resource %s", crd.Name) - Expect(customResource.GetAnnotations()[specHashAnnotation]).ToNot(BeEmpty(), - "There is no spec annotation on the custom resource %s", customResource.GetName()) + Expect(crd.GetAnnotations()[specHashAnnotation]).ToNot(BeEmpty(), + "There is no spec annotation on the resource %s", crd.Name) + Expect(customResource.GetAnnotations()[specHashAnnotation]).ToNot(BeEmpty(), + "There is no spec annotation on the custom resource %s", customResource.GetName()) + }) }) Context("Updating Work", func() { @@ -600,13 +609,13 @@ var _ = Describe("Work API Controller test", func() { updatedConfigMap.Data = map[string]string{ "updated-key": "updated-data", } - testutils.UpdateWork(ctx, &work, HubCluster, []runtime.Object{updatedConfigMap}) + testutils.UpdateWork(ctx, HubCluster, &work, []runtime.Object{updatedConfigMap}) By(fmt.Sprintf("The resource %s should be updated in the member cluster %s", updatedConfigMap.Name, memberClusterName)) configMapNamespaceType := types.NamespacedName{Name: updatedConfigMap.Name, Namespace: resourceNamespace.Name} - retrievedConfigMap := corev1.ConfigMap{} + gotConfigMap := corev1.ConfigMap{} - want := corev1.ConfigMap{ + wantConfigMap := corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: updatedConfigMap.Name, Namespace: resourceNamespace.Name, @@ -617,43 +626,51 @@ var _ = Describe("Work API Controller test", func() { } Eventually(func() string { - if err := MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap); err != nil { + if err := MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &gotConfigMap); err != nil { return err.Error() } - return cmp.Diff(want, retrievedConfigMap, cmpOptions...) + return cmp.Diff(wantConfigMap, gotConfigMap, cmpOptions...) }, testutils.PollTimeout, testutils.PollInterval).Should(BeEmpty(), "Resource %s mismatch (-want, +got):", updatedConfigMap.Name) }) It("Deleting a manifest from the Work object should delete the corresponding resource in the member cluster", func() { configMapNamespaceType := types.NamespacedName{Name: configMap.Name, Namespace: resourceNamespace.Name} - updatedConfigMap := configMap.DeepCopy() - updatedConfigMap.Data = map[string]string{} - testutils.UpdateWork(ctx, &work, HubCluster, []runtime.Object{}) + testutils.UpdateWork(ctx, HubCluster, &work, []runtime.Object{}) By(fmt.Sprintf("The resource %s should be deleted in the member cluster %s", configMap.Name, memberClusterName)) Eventually(func() error { retrievedConfigMap := corev1.ConfigMap{} - if err := MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap); err != nil { - return err - } - return nil - }, testutils.PollTimeout, testutils.PollInterval).ShouldNot(Succeed(), "Resource %s should have been deleted.", configMap.Name) + return MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap) + }, testutils.PollTimeout, testutils.PollInterval).Should(&utils.NotFoundMatcher{}, "Resource %s should have been deleted.", configMap.Name) By(fmt.Sprintf("The AppliedWork Manifest for Work %s should have been deleted", namespaceType)) appliedWork := workapi.AppliedWork{} err := MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork) Expect(err).Should(Succeed(), "Retrieving AppliedWork Manifest Failed") - Expect(appliedWork.Status.AppliedResources).Should(BeEmpty(), - "Status should be empty for AppliedWork %s", appliedWork.Name) + + wantAppliedWorkStatus := workapi.AppliedtWorkStatus{AppliedResources: nil} + Expect(cmp.Diff(wantAppliedWorkStatus, appliedWork.Status)).Should(BeEmpty(), + "Status should be empty for AppliedWork %s (-want, +got):", appliedWork.Name) By(fmt.Sprintf("The Work Condition for Work %s should have been deleted from the Work Object", work.Name)) updatedWork := workapi.Work{} - err = MemberCluster.KubeClient.Get(ctx, namespaceType, &updatedWork) - Expect(err).ShouldNot(Succeed(), "Retrieving Work Object should fail") - Expect(updatedWork.Status.Conditions).Should(BeNil(), - "Work Condition for Work Object %s should be empty", updatedWork.Name) - Expect(updatedWork.Status.ManifestConditions).Should(BeNil(), - "Work Manifest Condition for Work Object %s should be empty", updatedWork.Name) + err = HubCluster.KubeClient.Get(ctx, namespaceType, &updatedWork) + Expect(err).Should(Succeed(), "Retrieving Work Object should succeed") + + // Since "all" the manifests are applied, the work status is counted as "Applied Correctly". + // There are no more manifests within this work. + wantWorkStatus := workapi.WorkStatus{ + Conditions: []metav1.Condition{ + { + Type: conditionTypeApplied, + Status: metav1.ConditionTrue, + Reason: "appliedManifestUpdated", + }, + }, + ManifestConditions: nil, + } + Expect(cmp.Diff(wantWorkStatus, updatedWork.Status)).Should(BeEmpty(), + "Work Condition for Work Object %s should be empty / mismatch (-want, +got): ") }) }) }) From b00a1198ea576f574414a0d25ac23d199075cdee Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Sat, 1 Oct 2022 15:54:13 +0900 Subject: [PATCH 09/14] rebased --- test/e2e/work_api_e2e_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index f50629b2d..9be3d6e41 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -17,6 +17,7 @@ import ( "k8s.io/apimachinery/pkg/types" workapi "sigs.k8s.io/work-api/pkg/apis/v1alpha1" + workcontroller "go.goms.io/fleet/pkg/controllers/work" "go.goms.io/fleet/pkg/utils" testutils "go.goms.io/fleet/test/e2e/utils" ) From 051ef45a050cc39562d0b485effa547c7a2ccee7 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Sat, 1 Oct 2022 20:01:10 +0900 Subject: [PATCH 10/14] Fixing the error --- test/e2e/work_api_e2e_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 9be3d6e41..2c1d896f4 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -665,12 +665,11 @@ var _ = Describe("Work API Controller test", func() { { Type: conditionTypeApplied, Status: metav1.ConditionTrue, - Reason: "appliedManifestUpdated", }, }, ManifestConditions: nil, } - Expect(cmp.Diff(wantWorkStatus, updatedWork.Status)).Should(BeEmpty(), + Expect(cmp.Diff(wantWorkStatus, updatedWork.Status, cmpOptions...)).Should(BeEmpty(), "Work Condition for Work Object %s should be empty / mismatch (-want, +got): ") }) }) From b1ecf742beef1c1b612d34e0fc62adacae78aeb5 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 11 Oct 2022 01:23:27 +0900 Subject: [PATCH 11/14] fixes based on suggestions. --- test/e2e/work_api_e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 2c1d896f4..87e8c8ed9 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -645,6 +645,7 @@ var _ = Describe("Work API Controller test", func() { }, testutils.PollTimeout, testutils.PollInterval).Should(&utils.NotFoundMatcher{}, "Resource %s should have been deleted.", configMap.Name) By(fmt.Sprintf("The AppliedWork Manifest for Work %s should have been deleted", namespaceType)) + // The AppliedWork should still exist, as the work still exists. appliedWork := workapi.AppliedWork{} err := MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork) Expect(err).Should(Succeed(), "Retrieving AppliedWork Manifest Failed") @@ -667,7 +668,6 @@ var _ = Describe("Work API Controller test", func() { Status: metav1.ConditionTrue, }, }, - ManifestConditions: nil, } Expect(cmp.Diff(wantWorkStatus, updatedWork.Status, cmpOptions...)).Should(BeEmpty(), "Work Condition for Work Object %s should be empty / mismatch (-want, +got): ") From 170f667fbb4046bd671f27d1276d6d8f1e6ca476 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 11 Oct 2022 08:55:45 +0900 Subject: [PATCH 12/14] Removed Comment + changed the expect error statement to be more clear. --- test/e2e/work_api_e2e_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 87e8c8ed9..055cd7193 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -645,10 +645,9 @@ var _ = Describe("Work API Controller test", func() { }, testutils.PollTimeout, testutils.PollInterval).Should(&utils.NotFoundMatcher{}, "Resource %s should have been deleted.", configMap.Name) By(fmt.Sprintf("The AppliedWork Manifest for Work %s should have been deleted", namespaceType)) - // The AppliedWork should still exist, as the work still exists. appliedWork := workapi.AppliedWork{} err := MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork) - Expect(err).Should(Succeed(), "Retrieving AppliedWork Manifest Failed") + Expect(err).Should(Succeed(), "AppliedWork should still exist.") wantAppliedWorkStatus := workapi.AppliedtWorkStatus{AppliedResources: nil} Expect(cmp.Diff(wantAppliedWorkStatus, appliedWork.Status)).Should(BeEmpty(), From 08c47217f166082b54826b593cdcc878b82108f6 Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 11 Oct 2022 11:41:20 +0900 Subject: [PATCH 13/14] Changed some logs to be clear --- test/e2e/work_api_e2e_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 055cd7193..9378a4b0b 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -644,7 +644,7 @@ var _ = Describe("Work API Controller test", func() { return MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap) }, testutils.PollTimeout, testutils.PollInterval).Should(&utils.NotFoundMatcher{}, "Resource %s should have been deleted.", configMap.Name) - By(fmt.Sprintf("The AppliedWork Manifest for Work %s should have been deleted", namespaceType)) + By(fmt.Sprintf("Condition for AppliedWork %s should be empty", namespaceType)) appliedWork := workapi.AppliedWork{} err := MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork) Expect(err).Should(Succeed(), "AppliedWork should still exist.") @@ -653,7 +653,7 @@ var _ = Describe("Work API Controller test", func() { Expect(cmp.Diff(wantAppliedWorkStatus, appliedWork.Status)).Should(BeEmpty(), "Status should be empty for AppliedWork %s (-want, +got):", appliedWork.Name) - By(fmt.Sprintf("The Work Condition for Work %s should have been deleted from the Work Object", work.Name)) + By(fmt.Sprintf("Applied Condition for Work %s should still be true", namespaceType)) updatedWork := workapi.Work{} err = HubCluster.KubeClient.Get(ctx, namespaceType, &updatedWork) Expect(err).Should(Succeed(), "Retrieving Work Object should succeed") @@ -669,7 +669,7 @@ var _ = Describe("Work API Controller test", func() { }, } Expect(cmp.Diff(wantWorkStatus, updatedWork.Status, cmpOptions...)).Should(BeEmpty(), - "Work Condition for Work Object %s should be empty / mismatch (-want, +got): ") + "Work Condition for Work Object %s should still be applied / mismatch (-want, +got): ") }) }) }) From c9db1dad8cf77f53b8a2fcfe944d801b6e87f70b Mon Sep 17 00:00:00 2001 From: Youn Jae Kim Date: Tue, 11 Oct 2022 11:45:22 +0900 Subject: [PATCH 14/14] clearing up logs --- test/e2e/work_api_e2e_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/work_api_e2e_test.go b/test/e2e/work_api_e2e_test.go index 9378a4b0b..258ae7137 100644 --- a/test/e2e/work_api_e2e_test.go +++ b/test/e2e/work_api_e2e_test.go @@ -642,12 +642,12 @@ var _ = Describe("Work API Controller test", func() { Eventually(func() error { retrievedConfigMap := corev1.ConfigMap{} return MemberCluster.KubeClient.Get(ctx, configMapNamespaceType, &retrievedConfigMap) - }, testutils.PollTimeout, testutils.PollInterval).Should(&utils.NotFoundMatcher{}, "Resource %s should have been deleted.", configMap.Name) + }, testutils.PollTimeout, testutils.PollInterval).Should(&utils.NotFoundMatcher{}, "Resource %s should have been deleted", configMap.Name) - By(fmt.Sprintf("Condition for AppliedWork %s should be empty", namespaceType)) + By(fmt.Sprintf("Condition for resource %s should be removed from AppliedWork", configMap.Name)) appliedWork := workapi.AppliedWork{} err := MemberCluster.KubeClient.Get(ctx, namespaceType, &appliedWork) - Expect(err).Should(Succeed(), "AppliedWork should still exist.") + Expect(err).Should(Succeed(), "AppliedWork for Work %s should still exist", namespaceType) wantAppliedWorkStatus := workapi.AppliedtWorkStatus{AppliedResources: nil} Expect(cmp.Diff(wantAppliedWorkStatus, appliedWork.Status)).Should(BeEmpty(),