From 2cb548ead0579539899a929ae1a89c599488dd1f Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Wed, 19 Oct 2022 14:03:30 -0700 Subject: [PATCH 1/4] Workload partial failed apply IT --- test/integration/cluster_placement_test.go | 97 +++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/test/integration/cluster_placement_test.go b/test/integration/cluster_placement_test.go index 669d8645b..55c10f780 100644 --- a/test/integration/cluster_placement_test.go +++ b/test/integration/cluster_placement_test.go @@ -7,6 +7,7 @@ package integration import ( "fmt" + workapi "go.goms.io/fleet/pkg/controllers/work" "reflect" "time" @@ -1318,8 +1319,102 @@ var _ = Describe("Test Cluster Resource Placement Controller", func() { }, timeout, interval).Should(BeTrue()) }) - XIt("Test partial failed apply", func() { + It("Test partial failed apply", func() { + By("create clusterResourcePlacement CR") + crp = &fleetv1alpha1.ClusterResourcePlacement{ + ObjectMeta: metav1.ObjectMeta{ + Name: "resource-test-change", + }, + Spec: fleetv1alpha1.ClusterResourcePlacementSpec{ + ResourceSelectors: []fleetv1alpha1.ClusterResourceSelector{ + { + Group: rbacv1.GroupName, + Version: "v1", + Kind: ClusterRoleKind, + Name: "test-cluster-role", + }, + }, + }, + } + Expect(k8sClient.Create(ctx, crp)).Should(Succeed()) + + By("verify that we have created work objects that contain the resource selected") + verifyWorkObjects(crp, []string{ClusterRoleKind}, []*fleetv1alpha1.MemberCluster{&clusterA, &clusterB}) + var clusterWork workv1alpha1.Work + resourceIdentifier := workv1alpha1.ResourceIdentifier{ + Group: rbacv1.GroupName, + Kind: ClusterRoleKind, + Name: "test-cluster-role", + Ordinal: 0, + Resource: "clusterroles", + Version: "v1", + } + + // update work in clusterA to have applied condition as true for manifest and work + Expect(k8sClient.Get(ctx, types.NamespacedName{ + Name: crp.Name, + Namespace: fmt.Sprintf(utils.NamespaceNameFormat, clusterA.Name), + }, &clusterWork)).Should(Succeed()) + + appliedCondition := metav1.Condition{ + Type: workapi.ConditionTypeApplied, + Status: metav1.ConditionTrue, + Reason: "appliedWorkComplete", + ObservedGeneration: clusterWork.GetGeneration(), + LastTransitionTime: metav1.Now(), + } + + manifestCondition := workv1alpha1.ManifestCondition{ + Identifier: resourceIdentifier, + Conditions: []metav1.Condition{ + { + Type: workapi.ConditionTypeApplied, + Status: metav1.ConditionTrue, + Reason: "ManifestCreated", + LastTransitionTime: metav1.Now(), + }, + }, + } + + clusterWork.Status.Conditions = []metav1.Condition{appliedCondition} + clusterWork.Status.ManifestConditions = []workv1alpha1.ManifestCondition{manifestCondition} + Expect(k8sClient.Status().Update(ctx, &clusterWork)).Should(Succeed()) + + // update work in clusterB to have applied condition as false for manifest and work + Expect(k8sClient.Get(ctx, types.NamespacedName{ + Name: crp.Name, + Namespace: fmt.Sprintf(utils.NamespaceNameFormat, clusterB.Name), + }, &clusterWork)).Should(Succeed()) + + appliedCondition = metav1.Condition{ + Type: workapi.ConditionTypeApplied, + Status: metav1.ConditionFalse, + Reason: "appliedWorkFailed", + ObservedGeneration: clusterWork.GetGeneration(), + LastTransitionTime: metav1.Now(), + } + + manifestCondition = workv1alpha1.ManifestCondition{ + Identifier: resourceIdentifier, + Conditions: []metav1.Condition{ + { + Type: workapi.ConditionTypeApplied, + Status: metav1.ConditionFalse, + Reason: "appliedManifestFailed", + LastTransitionTime: metav1.Now(), + }, + }, + } + + clusterWork.Status.Conditions = []metav1.Condition{appliedCondition} + clusterWork.Status.ManifestConditions = []workv1alpha1.ManifestCondition{manifestCondition} + Expect(k8sClient.Status().Update(ctx, &clusterWork)).Should(Succeed()) + + Eventually(func() bool { + Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crp.Name}, crp)).Should(Succeed()) + return len(crp.Status.FailedResourcePlacements) == 1 + }, timeout, interval).Should(BeTrue()) }) }) }) From 0d0231e642d1fce5bfe6cf047b138180122db881 Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Wed, 19 Oct 2022 14:04:51 -0700 Subject: [PATCH 2/4] Fix import --- test/integration/cluster_placement_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/cluster_placement_test.go b/test/integration/cluster_placement_test.go index 55c10f780..f29a50084 100644 --- a/test/integration/cluster_placement_test.go +++ b/test/integration/cluster_placement_test.go @@ -7,7 +7,6 @@ package integration import ( "fmt" - workapi "go.goms.io/fleet/pkg/controllers/work" "reflect" "time" @@ -29,6 +28,7 @@ import ( fleetv1alpha1 "go.goms.io/fleet/apis/v1alpha1" "go.goms.io/fleet/pkg/controllers/clusterresourceplacement" + workapi "go.goms.io/fleet/pkg/controllers/work" "go.goms.io/fleet/pkg/utils" ) From 81e5fbfae4a75feabb22d67dd9f15cbe6075cdb9 Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Wed, 19 Oct 2022 14:50:25 -0700 Subject: [PATCH 3/4] check CRP status --- test/integration/cluster_placement_test.go | 64 +++++++++++++++++++--- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/test/integration/cluster_placement_test.go b/test/integration/cluster_placement_test.go index f29a50084..114cd41ac 100644 --- a/test/integration/cluster_placement_test.go +++ b/test/integration/cluster_placement_test.go @@ -10,6 +10,8 @@ import ( "reflect" "time" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" adminv1 "k8s.io/api/admissionregistration/v1" @@ -1342,7 +1344,7 @@ var _ = Describe("Test Cluster Resource Placement Controller", func() { verifyWorkObjects(crp, []string{ClusterRoleKind}, []*fleetv1alpha1.MemberCluster{&clusterA, &clusterB}) var clusterWork workv1alpha1.Work - resourceIdentifier := workv1alpha1.ResourceIdentifier{ + workResourceIdentifier := workv1alpha1.ResourceIdentifier{ Group: rbacv1.GroupName, Kind: ClusterRoleKind, Name: "test-cluster-role", @@ -1366,7 +1368,7 @@ var _ = Describe("Test Cluster Resource Placement Controller", func() { } manifestCondition := workv1alpha1.ManifestCondition{ - Identifier: resourceIdentifier, + Identifier: workResourceIdentifier, Conditions: []metav1.Condition{ { Type: workapi.ConditionTypeApplied, @@ -1396,7 +1398,7 @@ var _ = Describe("Test Cluster Resource Placement Controller", func() { } manifestCondition = workv1alpha1.ManifestCondition{ - Identifier: resourceIdentifier, + Identifier: workResourceIdentifier, Conditions: []metav1.Condition{ { Type: workapi.ConditionTypeApplied, @@ -1411,10 +1413,58 @@ var _ = Describe("Test Cluster Resource Placement Controller", func() { clusterWork.Status.ManifestConditions = []workv1alpha1.ManifestCondition{manifestCondition} Expect(k8sClient.Status().Update(ctx, &clusterWork)).Should(Succeed()) - Eventually(func() bool { - Expect(k8sClient.Get(ctx, types.NamespacedName{Name: crp.Name}, crp)).Should(Succeed()) - return len(crp.Status.FailedResourcePlacements) == 1 - }, timeout, interval).Should(BeTrue()) + fleetResourceIdentifier := fleetv1alpha1.ResourceIdentifier{ + Group: rbacv1.GroupName, + Version: "v1", + Kind: ClusterRoleKind, + Name: "test-cluster-role", + } + wantCRPStatus := fleetv1alpha1.ClusterResourcePlacementStatus{ + Conditions: []metav1.Condition{ + { + Type: string(fleetv1alpha1.ResourcePlacementConditionTypeScheduled), + Status: metav1.ConditionTrue, + ObservedGeneration: 1, + Reason: "ScheduleSucceeded", + }, + { + Type: string(fleetv1alpha1.ResourcePlacementStatusConditionTypeApplied), + Status: metav1.ConditionFalse, + ObservedGeneration: 1, + Reason: "ApplyFailed", + }, + }, + SelectedResources: []fleetv1alpha1.ResourceIdentifier{fleetResourceIdentifier}, + TargetClusters: []string{clusterA.Name, clusterB.Name}, + FailedResourcePlacements: []fleetv1alpha1.FailedResourcePlacement{ + { + ResourceIdentifier: fleetResourceIdentifier, + ClusterName: clusterB.Name, + Condition: metav1.Condition{ + Type: string(fleetv1alpha1.ResourcePlacementStatusConditionTypeApplied), + Status: metav1.ConditionFalse, + ObservedGeneration: 0, + Reason: "appliedManifestFailed", + }, + }, + }, + } + + crpStatusCmpOptions := []cmp.Option{ + cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime", "Message"), + cmpopts.SortSlices(func(ref1, ref2 metav1.Condition) bool { return ref1.Type < ref2.Type }), + cmpopts.SortSlices(func(ref1, ref2 string) bool { return ref1 < ref2 }), + } + + Eventually(func() error { + if err := k8sClient.Get(ctx, types.NamespacedName{Name: crp.Name}, crp); err != nil { + return err + } + if diff := cmp.Diff(wantCRPStatus, crp.Status, crpStatusCmpOptions...); diff != "" { + return fmt.Errorf("CRP status(%s) mismatch (-want +got):\n%s", crp.Name, diff) + } + return nil + }, timeout, interval).Should(Succeed(), "Failed to compare actual and expected CRP status in %s cluster", clusterB.Name) }) }) }) From efbb470808ce19b796c4618752f1fe7f6be3e6ee Mon Sep 17 00:00:00 2001 From: Arvind Thirumurugan Date: Wed, 19 Oct 2022 14:58:21 -0700 Subject: [PATCH 4/4] make reviewable --- go.mod | 2 +- go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 2421935e4..d45b406cb 100644 --- a/go.mod +++ b/go.mod @@ -76,7 +76,7 @@ require ( golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/text v0.4.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.0 // indirect diff --git a/go.sum b/go.sum index 6e7c3cfdb..04a920b29 100644 --- a/go.sum +++ b/go.sum @@ -728,8 +728,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=