From 558607bfd5a391ca4fe181b9e70c6756402426cc Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Wed, 5 Nov 2025 13:34:18 -0800 Subject: [PATCH 01/10] update stagedUpdateRun to use latest resource snapshot if resourceIndex is unset Signed-off-by: Britania Rodriguez Reyes --- apis/placement/v1beta1/stageupdate_types.go | 2 +- ...etes-fleet.io_clusterstagedupdateruns.yaml | 2 +- ...leet.io_clusterstagedupdatestrategies.yaml | 2 +- ....kubernetes-fleet.io_stagedupdateruns.yaml | 2 +- ...netes-fleet.io_stagedupdatestrategies.yaml | 2 +- pkg/controllers/updaterun/initialization.go | 42 ++++++++++++------- .../initialization_integration_test.go | 25 ++++++++++- 7 files changed, 56 insertions(+), 21 deletions(-) diff --git a/apis/placement/v1beta1/stageupdate_types.go b/apis/placement/v1beta1/stageupdate_types.go index db72de9d5..7e3866a87 100644 --- a/apis/placement/v1beta1/stageupdate_types.go +++ b/apis/placement/v1beta1/stageupdate_types.go @@ -159,7 +159,7 @@ type UpdateRunSpec struct { // The resource snapshot index of the selected resources to be updated across clusters. // The index represents a group of resource snapshots that includes all the resources a ResourcePlacement selected. - // +kubebuilder:validation:Required + // +kubebuilder:validation:optional ResourceSnapshotIndex string `json:"resourceSnapshotIndex"` // The name of the update strategy that specifies the stages and the sequence diff --git a/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml b/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml index 3102c7f53..1d7518e28 100644 --- a/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml +++ b/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml @@ -1998,7 +1998,7 @@ spec: description: |- MaxConcurrency specifies the maximum number of clusters that can be updated concurrently within this stage. Value can be an absolute number (ex: 5) or a percentage of the total clusters in the stage (ex: 50%). - Absolute number is calculated from percentage by rounding up. + Fractional results are rounded down. A minimum of 1 update is enforced. If not specified, all clusters in the stage are updated sequentially (effectively maxConcurrency = 1). Defaults to 1. pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ diff --git a/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdatestrategies.yaml b/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdatestrategies.yaml index 8791e4ce9..4d088a0ce 100644 --- a/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdatestrategies.yaml +++ b/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdatestrategies.yaml @@ -312,7 +312,7 @@ spec: description: |- MaxConcurrency specifies the maximum number of clusters that can be updated concurrently within this stage. Value can be an absolute number (ex: 5) or a percentage of the total clusters in the stage (ex: 50%). - Absolute number is calculated from percentage by rounding up. + Fractional results are rounded down. A minimum of 1 update is enforced. If not specified, all clusters in the stage are updated sequentially (effectively maxConcurrency = 1). Defaults to 1. pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ diff --git a/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml b/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml index ec319411f..f7bbb44bf 100644 --- a/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml +++ b/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml @@ -917,7 +917,7 @@ spec: description: |- MaxConcurrency specifies the maximum number of clusters that can be updated concurrently within this stage. Value can be an absolute number (ex: 5) or a percentage of the total clusters in the stage (ex: 50%). - Absolute number is calculated from percentage by rounding up. + Fractional results are rounded down. A minimum of 1 update is enforced. If not specified, all clusters in the stage are updated sequentially (effectively maxConcurrency = 1). Defaults to 1. pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ diff --git a/config/crd/bases/placement.kubernetes-fleet.io_stagedupdatestrategies.yaml b/config/crd/bases/placement.kubernetes-fleet.io_stagedupdatestrategies.yaml index fe0dfc567..898f92a88 100644 --- a/config/crd/bases/placement.kubernetes-fleet.io_stagedupdatestrategies.yaml +++ b/config/crd/bases/placement.kubernetes-fleet.io_stagedupdatestrategies.yaml @@ -174,7 +174,7 @@ spec: description: |- MaxConcurrency specifies the maximum number of clusters that can be updated concurrently within this stage. Value can be an absolute number (ex: 5) or a percentage of the total clusters in the stage (ex: 50%). - Absolute number is calculated from percentage by rounding up. + Fractional results are rounded down. A minimum of 1 update is enforced. If not specified, all clusters in the stage are updated sequentially (effectively maxConcurrency = 1). Defaults to 1. pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ diff --git a/pkg/controllers/updaterun/initialization.go b/pkg/controllers/updaterun/initialization.go index 45a4ba48a..36443e511 100644 --- a/pkg/controllers/updaterun/initialization.go +++ b/pkg/controllers/updaterun/initialization.go @@ -469,27 +469,39 @@ func validateAfterStageTask(tasks []placementv1beta1.StageTask) error { // recordOverrideSnapshots finds all the override snapshots that are associated with each cluster and record them in the UpdateRun status. func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey types.NamespacedName, updateRun placementv1beta1.UpdateRunObj) error { + var resourceSnapshotObjs []placementv1beta1.ResourceSnapshotObj + var snapshotIndex int updateRunRef := klog.KObj(updateRun) updateRunSpec := updateRun.GetUpdateRunSpec() placementName := placementKey.Name + if updateRunSpec.ResourceSnapshotIndex != "" { + snapshotIndex, err := strconv.Atoi(updateRunSpec.ResourceSnapshotIndex) + if err != nil || snapshotIndex < 0 { + err := controller.NewUserError(fmt.Errorf("invalid resource snapshot index `%s` provided, expected an integer >= 0", updateRunSpec.ResourceSnapshotIndex)) + klog.ErrorS(err, "Failed to parse the resource snapshot index", "updateRun", updateRunRef) + // no more retries here. + return fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) + } - snapshotIndex, err := strconv.Atoi(updateRunSpec.ResourceSnapshotIndex) - if err != nil || snapshotIndex < 0 { - err := controller.NewUserError(fmt.Errorf("invalid resource snapshot index `%s` provided, expected an integer >= 0", updateRunSpec.ResourceSnapshotIndex)) - klog.ErrorS(err, "Failed to parse the resource snapshot index", "updateRun", updateRunRef) - // no more retries here. - return fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) - } - - resourceSnapshotList, err := controller.ListAllResourceSnapshotWithAnIndex(ctx, r.Client, updateRunSpec.ResourceSnapshotIndex, placementName, placementKey.Namespace) - if err != nil { - klog.ErrorS(err, "Failed to list the resourceSnapshots associated with the placement", - "placement", placementKey, "resourceSnapshotIndex", snapshotIndex, "updateRun", updateRunRef) - // err can be retried. - return controller.NewAPIServerError(true, err) + resourceSnapshotList, err := controller.ListAllResourceSnapshotWithAnIndex(ctx, r.Client, updateRunSpec.ResourceSnapshotIndex, placementName, placementKey.Namespace) + if err != nil { + klog.ErrorS(err, "Failed to list the resourceSnapshots associated with the placement", + "placement", placementKey, "resourceSnapshotIndex", snapshotIndex, "updateRun", updateRunRef) + // err can be retried. + return controller.NewAPIServerError(true, err) + } + resourceSnapshotObjs = resourceSnapshotList.GetResourceSnapshotObjs() + } else { + latestResourceSnapshot, err := controller.ListLatestResourceSnapshots(ctx, r.Client, placementKey) + if err != nil { + klog.ErrorS(err, "Failed to list the latest resourceSnapshots associated with the placement", + "placement", placementKey, "updateRun", updateRunRef) + // err can be retried. + return controller.NewAPIServerError(true, err) + } + resourceSnapshotObjs = latestResourceSnapshot.GetResourceSnapshotObjs() } - resourceSnapshotObjs := resourceSnapshotList.GetResourceSnapshotObjs() if len(resourceSnapshotObjs) == 0 { err := controller.NewUserError(fmt.Errorf("no resourceSnapshots with index `%d` found for placement `%s`", snapshotIndex, placementKey)) klog.ErrorS(err, "No specified resourceSnapshots found", "updateRun", updateRunRef) diff --git a/pkg/controllers/updaterun/initialization_integration_test.go b/pkg/controllers/updaterun/initialization_integration_test.go index 8bfab157a..2406393de 100644 --- a/pkg/controllers/updaterun/initialization_integration_test.go +++ b/pkg/controllers/updaterun/initialization_integration_test.go @@ -748,7 +748,7 @@ var _ = Describe("Updaterun initialization tests", func() { Expect(k8sClient.Create(ctx, updateStrategy)).To(Succeed()) }) - It("Should fail to initialize if the specified resource snapshot index is invalid - not integer", func() { + FIt("Should fail to initialize if the specified resource snapshot index is invalid - not integer", func() { By("Creating a new clusterStagedUpdateRun with invalid resource snapshot index") updateRun.Spec.ResourceSnapshotIndex = "invalid-index" Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) @@ -828,6 +828,29 @@ var _ = Describe("Updaterun initialization tests", func() { validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) }) + It("Should put related ClusterResourceOverrides in the status with no resource index defined", func() { + By("Creating a new resource snapshot") + Expect(k8sClient.Create(ctx, resourceSnapshot)).To(Succeed()) + + By("Creating a new cluster resource override") + Expect(k8sClient.Create(ctx, clusterResourceOverride)).To(Succeed()) + + By("Creating a new clusterStagedUpdateRun") + updateRun.Spec.ResourceSnapshotIndex = "" + Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) + + By("Validating the clusterStagedUpdateRun stats") + initialized := generateSucceededInitializationStatus(crp, updateRun, policySnapshot, updateStrategy, clusterResourceOverride) + want := generateExecutionStartedStatus(updateRun, initialized) + validateClusterStagedUpdateRunStatus(ctx, updateRun, want, "") + + By("Validating the clusterStagedUpdateRun initialized consistently") + validateClusterStagedUpdateRunStatusConsistently(ctx, updateRun, want, "") + + By("Checking update run status metrics are emitted") + validateUpdateRunMetricsEmitted(generateProgressingMetric(updateRun)) + }) + It("Should put related ClusterResourceOverrides in the status", func() { By("Creating a new resource snapshot") Expect(k8sClient.Create(ctx, resourceSnapshot)).To(Succeed()) From bff950842f01cab0eb0041401ed4ef7134581848 Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Wed, 5 Nov 2025 15:37:49 -0800 Subject: [PATCH 02/10] fix UT Signed-off-by: Britania Rodriguez Reyes --- pkg/controllers/updaterun/initialization_integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/controllers/updaterun/initialization_integration_test.go b/pkg/controllers/updaterun/initialization_integration_test.go index 2406393de..0aec57df9 100644 --- a/pkg/controllers/updaterun/initialization_integration_test.go +++ b/pkg/controllers/updaterun/initialization_integration_test.go @@ -748,7 +748,7 @@ var _ = Describe("Updaterun initialization tests", func() { Expect(k8sClient.Create(ctx, updateStrategy)).To(Succeed()) }) - FIt("Should fail to initialize if the specified resource snapshot index is invalid - not integer", func() { + It("Should fail to initialize if the specified resource snapshot index is invalid - not integer", func() { By("Creating a new clusterStagedUpdateRun with invalid resource snapshot index") updateRun.Spec.ResourceSnapshotIndex = "invalid-index" Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) From 1c44de92827a1f6972679b5509952b4f7e6a4701 Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Thu, 6 Nov 2025 17:00:24 -0800 Subject: [PATCH 03/10] address comments Signed-off-by: Britania Rodriguez Reyes --- apis/placement/v1beta1/stageupdate_types.go | 6 +- ...etes-fleet.io_clusterstagedupdateruns.yaml | 5 +- ....kubernetes-fleet.io_stagedupdateruns.yaml | 5 +- pkg/controllers/updaterun/execution.go | 6 +- pkg/controllers/updaterun/initialization.go | 76 +++++++++++-------- .../initialization_integration_test.go | 12 ++- 6 files changed, 67 insertions(+), 43 deletions(-) diff --git a/apis/placement/v1beta1/stageupdate_types.go b/apis/placement/v1beta1/stageupdate_types.go index 7e3866a87..80d5e91ab 100644 --- a/apis/placement/v1beta1/stageupdate_types.go +++ b/apis/placement/v1beta1/stageupdate_types.go @@ -159,7 +159,7 @@ type UpdateRunSpec struct { // The resource snapshot index of the selected resources to be updated across clusters. // The index represents a group of resource snapshots that includes all the resources a ResourcePlacement selected. - // +kubebuilder:validation:optional + // +kubebuilder:validation:Optional ResourceSnapshotIndex string `json:"resourceSnapshotIndex"` // The name of the update strategy that specifies the stages and the sequence @@ -335,6 +335,10 @@ type UpdateRunStatus struct { // +kubebuilder:validation:Optional PolicyObservedClusterCount int `json:"policyObservedClusterCount,omitempty"` + // ResourceSnapshotName records the name of the resource snapshot that the update run is based on. + // +kubebuilder:validation:Optional + ResourceSnapshotName string `json:"resourceSnapshotName,omitempty"` + // ApplyStrategy is the apply strategy that the stagedUpdateRun is using. // It is the same as the apply strategy in the CRP when the staged update run starts. // The apply strategy is not updated during the update run even if it changes in the CRP. diff --git a/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml b/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml index 1d7518e28..7c7f62985 100644 --- a/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml +++ b/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml @@ -1175,7 +1175,6 @@ spec: type: string required: - placementName - - resourceSnapshotIndex - stagedRolloutStrategyName type: object x-kubernetes-validations: @@ -1856,6 +1855,10 @@ spec: All clusters involved in the update run are selected from the list of clusters scheduled by the CRP according to the current policy. type: string + resourceSnapshotName: + description: ResourceSnapshotName records the name of the resource + snapshot that the update run is based on. + type: string stagedUpdateStrategySnapshot: description: |- UpdateStrategySnapshot is the snapshot of the UpdateStrategy used for the update run. diff --git a/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml b/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml index f7bbb44bf..7f72254c5 100644 --- a/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml +++ b/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml @@ -94,7 +94,6 @@ spec: type: string required: - placementName - - resourceSnapshotIndex - stagedRolloutStrategyName type: object x-kubernetes-validations: @@ -775,6 +774,10 @@ spec: All clusters involved in the update run are selected from the list of clusters scheduled by the CRP according to the current policy. type: string + resourceSnapshotName: + description: ResourceSnapshotName records the name of the resource + snapshot that the update run is based on. + type: string stagedUpdateStrategySnapshot: description: |- UpdateStrategySnapshot is the snapshot of the UpdateStrategy used for the update run. diff --git a/pkg/controllers/updaterun/execution.go b/pkg/controllers/updaterun/execution.go index c69e34f11..948f93654 100644 --- a/pkg/controllers/updaterun/execution.go +++ b/pkg/controllers/updaterun/execution.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "reflect" - "strconv" "time" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -93,11 +92,8 @@ func (r *Reconciler) executeUpdatingStage( toBeUpdatedBindings []placementv1beta1.BindingObj, ) (time.Duration, error) { updateRunStatus := updateRun.GetUpdateRunStatus() - updateRunSpec := updateRun.GetUpdateRunSpec() updatingStageStatus := &updateRunStatus.StagesStatus[updatingStageIndex] - // The parse error is ignored because the initialization should have caught it. - resourceIndex, _ := strconv.Atoi(updateRunSpec.ResourceSnapshotIndex) - resourceSnapshotName := fmt.Sprintf(placementv1beta1.ResourceSnapshotNameFmt, updateRunSpec.PlacementName, resourceIndex) + resourceSnapshotName := updateRunStatus.ResourceSnapshotName updateRunRef := klog.KObj(updateRun) // Create the map of the toBeUpdatedBindings. toBeUpdatedBindingsMap := make(map[string]placementv1beta1.BindingObj, len(toBeUpdatedBindings)) diff --git a/pkg/controllers/updaterun/initialization.go b/pkg/controllers/updaterun/initialization.go index 36443e511..756dc27ab 100644 --- a/pkg/controllers/updaterun/initialization.go +++ b/pkg/controllers/updaterun/initialization.go @@ -469,42 +469,18 @@ func validateAfterStageTask(tasks []placementv1beta1.StageTask) error { // recordOverrideSnapshots finds all the override snapshots that are associated with each cluster and record them in the UpdateRun status. func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey types.NamespacedName, updateRun placementv1beta1.UpdateRunObj) error { - var resourceSnapshotObjs []placementv1beta1.ResourceSnapshotObj - var snapshotIndex int updateRunRef := klog.KObj(updateRun) updateRunSpec := updateRun.GetUpdateRunSpec() placementName := placementKey.Name - if updateRunSpec.ResourceSnapshotIndex != "" { - snapshotIndex, err := strconv.Atoi(updateRunSpec.ResourceSnapshotIndex) - if err != nil || snapshotIndex < 0 { - err := controller.NewUserError(fmt.Errorf("invalid resource snapshot index `%s` provided, expected an integer >= 0", updateRunSpec.ResourceSnapshotIndex)) - klog.ErrorS(err, "Failed to parse the resource snapshot index", "updateRun", updateRunRef) - // no more retries here. - return fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) - } - resourceSnapshotList, err := controller.ListAllResourceSnapshotWithAnIndex(ctx, r.Client, updateRunSpec.ResourceSnapshotIndex, placementName, placementKey.Namespace) - if err != nil { - klog.ErrorS(err, "Failed to list the resourceSnapshots associated with the placement", - "placement", placementKey, "resourceSnapshotIndex", snapshotIndex, "updateRun", updateRunRef) - // err can be retried. - return controller.NewAPIServerError(true, err) - } - resourceSnapshotObjs = resourceSnapshotList.GetResourceSnapshotObjs() - } else { - latestResourceSnapshot, err := controller.ListLatestResourceSnapshots(ctx, r.Client, placementKey) - if err != nil { - klog.ErrorS(err, "Failed to list the latest resourceSnapshots associated with the placement", - "placement", placementKey, "updateRun", updateRunRef) - // err can be retried. - return controller.NewAPIServerError(true, err) - } - resourceSnapshotObjs = latestResourceSnapshot.GetResourceSnapshotObjs() + resourceSnapshotObjs, err := r.getResourceSnapshotObjs(ctx, updateRunSpec, placementName, placementKey, updateRunRef) + if err != nil { + return err } if len(resourceSnapshotObjs) == 0 { - err := controller.NewUserError(fmt.Errorf("no resourceSnapshots with index `%d` found for placement `%s`", snapshotIndex, placementKey)) - klog.ErrorS(err, "No specified resourceSnapshots found", "updateRun", updateRunRef) + err := controller.NewUserError(fmt.Errorf("no resourceSnapshots found for placement `%s`", placementKey)) + klog.ErrorS(err, "No resourceSnapshots found", "updateRun", updateRunRef) // no more retries here. return fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) } @@ -518,15 +494,23 @@ func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey t break } } - // No masterResourceSnapshot found. if masterResourceSnapshot == nil { - err := controller.NewUnexpectedBehaviorError(fmt.Errorf("no master resourceSnapshot found for placement `%s` with index `%d`", placementKey, snapshotIndex)) + err := controller.NewUnexpectedBehaviorError(fmt.Errorf("no master resourceSnapshot found for placement %s", placementKey)) klog.ErrorS(err, "Failed to find master resourceSnapshot", "updateRun", updateRunRef) // no more retries here. return fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) } - klog.V(2).InfoS("Found master resourceSnapshot", "placement", placementKey, "index", snapshotIndex, "updateRun", updateRunRef) + + klog.InfoS("Found master resourceSnapshot", "placement", placementKey, "index", updateRun.GetUpdateRunSpec().ResourceSnapshotIndex, "updateRun", updateRunRef) + + // Update the resource snapshot name in the UpdateRun status. + updateRun.GetUpdateRunStatus().ResourceSnapshotName = masterResourceSnapshot.GetName() + if updateErr := r.Client.Status().Update(ctx, updateRun); updateErr != nil { + klog.ErrorS(updateErr, "Failed to update the UpdateRun status with resource snapshot name", "updateRun", klog.KObj(updateRun), "resourceSnapshot", klog.KObj(masterResourceSnapshot)) + // updateErr can be retried. + return controller.NewUpdateIgnoreConflictError(updateErr) + } resourceSnapshotRef := klog.KObj(masterResourceSnapshot) // Fetch all the matching overrides. @@ -555,6 +539,34 @@ func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey t return nil } +// getResourceSnapshotObjs retrieves the resource snapshot objects either by index or latest snapshots. +func (r *Reconciler) getResourceSnapshotObjs(ctx context.Context, updateRunSpec *placementv1beta1.UpdateRunSpec, placementName string, placementKey types.NamespacedName, updateRunRef klog.ObjectRef) ([]placementv1beta1.ResourceSnapshotObj, error) { + if updateRunSpec.ResourceSnapshotIndex != "" { + snapshotIndex, err := strconv.Atoi(updateRunSpec.ResourceSnapshotIndex) + if err != nil || snapshotIndex < 0 { + err := controller.NewUserError(fmt.Errorf("invalid resource snapshot index `%s` provided, expected an integer >= 0", updateRunSpec.ResourceSnapshotIndex)) + klog.ErrorS(err, "Failed to parse the resource snapshot index", "updateRun", updateRunRef) + return nil, fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) + } + + resourceSnapshotList, err := controller.ListAllResourceSnapshotWithAnIndex(ctx, r.Client, updateRunSpec.ResourceSnapshotIndex, placementName, placementKey.Namespace) + if err != nil { + klog.ErrorS(err, "Failed to list the resourceSnapshots associated with the placement", + "placement", placementKey, "resourceSnapshotIndex", snapshotIndex, "updateRun", updateRunRef) + return nil, controller.NewAPIServerError(true, err) + } + return resourceSnapshotList.GetResourceSnapshotObjs(), nil + } + + latestResourceSnapshots, err := controller.ListLatestResourceSnapshots(ctx, r.Client, placementKey) + if err != nil { + klog.ErrorS(err, "Failed to list the latest resourceSnapshots associated with the placement", + "placement", placementKey, "updateRun", updateRunRef) + return nil, controller.NewAPIServerError(true, err) + } + return latestResourceSnapshots.GetResourceSnapshotObjs(), nil +} + // recordInitializationSucceeded records the successful initialization condition in the UpdateRun status. func (r *Reconciler) recordInitializationSucceeded(ctx context.Context, updateRun placementv1beta1.UpdateRunObj) error { updateRunStatus := updateRun.GetUpdateRunStatus() diff --git a/pkg/controllers/updaterun/initialization_integration_test.go b/pkg/controllers/updaterun/initialization_integration_test.go index 0aec57df9..b38a80443 100644 --- a/pkg/controllers/updaterun/initialization_integration_test.go +++ b/pkg/controllers/updaterun/initialization_integration_test.go @@ -655,6 +655,7 @@ var _ = Describe("Updaterun initialization tests", func() { } want := generateSucceededInitializationStatus(crp, updateRun, policySnapshot, updateStrategy, clusterResourceOverride) + want.ResourceSnapshotName = "" // resourceSnapshot not created in this test // No clusters should be selected in the first stage. want.StagesStatus[0].Clusters = []placementv1beta1.ClusterUpdatingStatus{} // All clusters should be selected in the second stage and sorted by name. @@ -697,6 +698,7 @@ var _ = Describe("Updaterun initialization tests", func() { } want := generateSucceededInitializationStatus(crp, updateRun, policySnapshot, updateStrategy, clusterResourceOverride) + want.ResourceSnapshotName = "" // resourceSnapshot not created in this test for i := range want.StagesStatus[0].Clusters { // Remove the CROs, as they are not added in this test. want.StagesStatus[0].Clusters[i].ClusterResourceOverrideSnapshots = nil @@ -777,7 +779,7 @@ var _ = Describe("Updaterun initialization tests", func() { Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) By("Validating the initialization failed") - validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots with index `0` found") + validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots found for placement") By("Checking update run status metrics are emitted") validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) @@ -792,7 +794,7 @@ var _ = Describe("Updaterun initialization tests", func() { Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) By("Validating the initialization failed") - validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots with index `0` found") + validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots found for placement") By("Checking update run status metrics are emitted") validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) @@ -807,7 +809,7 @@ var _ = Describe("Updaterun initialization tests", func() { Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) By("Validating the initialization failed") - validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots with index `0` found") + validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots found for placement") By("Checking update run status metrics are emitted") validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) @@ -841,6 +843,7 @@ var _ = Describe("Updaterun initialization tests", func() { By("Validating the clusterStagedUpdateRun stats") initialized := generateSucceededInitializationStatus(crp, updateRun, policySnapshot, updateStrategy, clusterResourceOverride) + initialized.ResourceSnapshotName = testResourceSnapshotName want := generateExecutionStartedStatus(updateRun, initialized) validateClusterStagedUpdateRunStatus(ctx, updateRun, want, "") @@ -863,6 +866,7 @@ var _ = Describe("Updaterun initialization tests", func() { By("Validating the clusterStagedUpdateRun stats") initialized := generateSucceededInitializationStatus(crp, updateRun, policySnapshot, updateStrategy, clusterResourceOverride) + initialized.ResourceSnapshotName = testResourceSnapshotName want := generateExecutionStartedStatus(updateRun, initialized) validateClusterStagedUpdateRunStatus(ctx, updateRun, want, "") @@ -902,6 +906,7 @@ func generateSucceededInitializationStatus( status := &placementv1beta1.UpdateRunStatus{ PolicySnapshotIndexUsed: policySnapshot.Labels[placementv1beta1.PolicyIndexLabel], PolicyObservedClusterCount: 10, + ResourceSnapshotName: testResourceSnapshotName, ApplyStrategy: crp.Spec.Strategy.ApplyStrategy.DeepCopy(), UpdateStrategySnapshot: &updateStrategy.Spec, StagesStatus: []placementv1beta1.StageUpdatingStatus{ @@ -962,6 +967,7 @@ func generateSucceededInitializationStatusForSmallClusters( status := &placementv1beta1.UpdateRunStatus{ PolicySnapshotIndexUsed: policySnapshot.Labels[placementv1beta1.PolicyIndexLabel], PolicyObservedClusterCount: 3, + ResourceSnapshotName: testResourceSnapshotName, ApplyStrategy: crp.Spec.Strategy.ApplyStrategy.DeepCopy(), UpdateStrategySnapshot: &updateStrategy.Spec, StagesStatus: []placementv1beta1.StageUpdatingStatus{ From 9176f1d4e4df7cedef8c210044b9e8ca7e9b8aa4 Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Mon, 10 Nov 2025 12:18:51 -0800 Subject: [PATCH 04/10] fix some e2es Signed-off-by: Britania Rodriguez Reyes --- .../v1beta1/zz_generated.deepcopy.go | 2 +- test/e2e/actuals_test.go | 5 ++- test/e2e/cluster_staged_updaterun_test.go | 40 ++++++++++--------- test/e2e/staged_updaterun_test.go | 26 ++++++------ 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/apis/placement/v1beta1/zz_generated.deepcopy.go b/apis/placement/v1beta1/zz_generated.deepcopy.go index 73d66c8fa..b9ff2e710 100644 --- a/apis/placement/v1beta1/zz_generated.deepcopy.go +++ b/apis/placement/v1beta1/zz_generated.deepcopy.go @@ -21,7 +21,7 @@ limitations under the License. package v1beta1 import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) diff --git a/test/e2e/actuals_test.go b/test/e2e/actuals_test.go index 889f1abe3..51ee76a9e 100644 --- a/test/e2e/actuals_test.go +++ b/test/e2e/actuals_test.go @@ -2092,6 +2092,7 @@ func updateRunSucceedConditions(generation int64) []metav1.Condition { func clusterStagedUpdateRunStatusSucceededActual( updateRunName string, + wantResourceSnapshotName string, wantPolicyIndex string, wantClusterCount int, wantApplyStrategy *placementv1beta1.ApplyStrategy, @@ -2109,6 +2110,7 @@ func clusterStagedUpdateRunStatusSucceededActual( wantStatus := placementv1beta1.UpdateRunStatus{ PolicySnapshotIndexUsed: wantPolicyIndex, + ResourceSnapshotName: wantResourceSnapshotName, PolicyObservedClusterCount: wantClusterCount, ApplyStrategy: wantApplyStrategy.DeepCopy(), UpdateStrategySnapshot: wantStrategySpec, @@ -2125,7 +2127,7 @@ func clusterStagedUpdateRunStatusSucceededActual( } func stagedUpdateRunStatusSucceededActual( - updateRunName, namespace string, + updateRunName, namespace, wantResourceSnapshotName string, wantPolicyIndex string, wantClusterCount int, wantApplyStrategy *placementv1beta1.ApplyStrategy, @@ -2143,6 +2145,7 @@ func stagedUpdateRunStatusSucceededActual( wantStatus := placementv1beta1.UpdateRunStatus{ PolicySnapshotIndexUsed: wantPolicyIndex, + ResourceSnapshotName: wantResourceSnapshotName, PolicyObservedClusterCount: wantClusterCount, ApplyStrategy: wantApplyStrategy.DeepCopy(), UpdateStrategySnapshot: wantStrategySpec, diff --git a/test/e2e/cluster_staged_updaterun_test.go b/test/e2e/cluster_staged_updaterun_test.go index 9880c2eef..da1c05001 100644 --- a/test/e2e/cluster_staged_updaterun_test.go +++ b/test/e2e/cluster_staged_updaterun_test.go @@ -46,6 +46,8 @@ const ( policySnapshotIndex3rd = "2" testConfigMapDataValue = "new" + + testResourceSnapshotNameTmpl = "%s-%s-snapshot" ) var ( @@ -149,7 +151,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to all the members and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[0], policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[0], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -214,7 +216,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-1 and member-cluster-3 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) By("Verify that new the configmap is updated on all member clusters") for idx := range allMemberClusters { @@ -252,7 +254,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollback resources to member-cluster-1 and member-cluster-3 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], "", policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) for idx := range allMemberClusters { configMapActual := configMapPlacedOnClusterActual(allMemberClusters[idx], &oldConfigMap) @@ -348,7 +350,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-1 too but not member-cluster-3 and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[0], policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[0], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) checkIfRemovedWorkResourcesFromMemberClustersConsistently([]*framework.Cluster{allMemberClusters[2]}) @@ -398,7 +400,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-3 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], policySnapshotIndex2nd, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex2nd, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -445,7 +447,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { It("Should remove resources on member-cluster-1 and member-cluster-2 and complete the cluster staged update run successfully", func() { // need to go through two stages - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], policySnapshotIndex3rd, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0], allMemberClusterNames[1]}, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], "", policySnapshotIndex3rd, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0], allMemberClusterNames[1]}, nil, nil) Eventually(csurSucceededActual, 2*updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[2]) checkIfRemovedWorkResourcesFromMemberClusters([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) checkIfPlacedWorkResourcesOnMemberClustersConsistently([]*framework.Cluster{allMemberClusters[2]}) @@ -537,7 +539,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-3 and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[0], policySnapshotIndex1st, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[0], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[2]}) checkIfRemovedWorkResourcesFromMemberClustersConsistently([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) @@ -586,7 +588,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-1 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -632,7 +634,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should remove resources on member-cluster-1 and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], "", policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) Eventually(csurSucceededActual, 2*updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[2]) checkIfRemovedWorkResourcesFromMemberClusters([]*framework.Cluster{allMemberClusters[0]}) checkIfPlacedWorkResourcesOnMemberClustersConsistently([]*framework.Cluster{allMemberClusters[1], allMemberClusters[2]}) @@ -804,7 +806,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-1 and member-cluster-3 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, wantCROs, wantROs) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, wantCROs, wantROs) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunName) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -904,7 +906,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should report diff for member-cluster-1 and member-cluster-3 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, policySnapshotIndex1st, len(allMemberClusters), applyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), applyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunName) }) @@ -1015,7 +1017,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { validateAndApproveClusterApprovalRequests(updateRunName, envCanary) // Verify complete rollout - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex2nd), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunName) // Verify new configmap is on all member clusters @@ -1141,7 +1143,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should complete the staged update run after approval", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunName) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -1214,7 +1216,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { validateAndApproveClusterApprovalRequests(updateRunName, envCanary) - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunName, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunName) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) @@ -1340,7 +1342,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label createClusterStagedUpdateRunSucceed(updateRunNames[0], crpName, resourceSnapshotIndex1st, strategyName) By("Validating staged update run has succeeded") - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[0], policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[0], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[0]) By("Validating CRP status as completed") @@ -1392,7 +1394,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label }) It("Should complete the second staged update run and complete the CRP", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1], allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1], allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) crpStatusUpdatedActual := crpStatusWithExternalStrategyActual(workResourceIdentifiers(), resourceSnapshotIndex1st, true, allMemberClusterNames[1:], @@ -1440,7 +1442,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label }) It("Should complete the staged update run, complete CRP, and rollout resources to all member clusters", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[0]) crpStatusUpdatedActual := crpStatusWithExternalStrategyActual(workResourceIdentifiers(), resourceSnapshotIndex1st, true, allMemberClusterNames, @@ -1483,7 +1485,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label }) It("Should complete the staged update run, complete CRP, and rollout updated resources to all member clusters", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) crpStatusUpdatedActual := crpStatusWithExternalStrategyActual(workResourceIdentifiers(), resourceSnapshotIndex2nd, true, allMemberClusterNames, @@ -1522,7 +1524,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label }) It("Should complete the staged update run, complete CRP, and re-place resources to all member clusters", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) crpStatusUpdatedActual := crpStatusWithExternalStrategyActual(workResourceIdentifiers(), resourceSnapshotIndex1st, true, allMemberClusterNames, diff --git a/test/e2e/staged_updaterun_test.go b/test/e2e/staged_updaterun_test.go index b5a5428b1..8d0a17d98 100644 --- a/test/e2e/staged_updaterun_test.go +++ b/test/e2e/staged_updaterun_test.go @@ -142,7 +142,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to all the members and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -207,7 +207,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-1 and member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[1]) By("Verify that new the configmap is updated on all member clusters") for idx := range allMemberClusters { @@ -245,7 +245,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollback resources to member-cluster-1 and member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, "", policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) for idx := range allMemberClusters { configMapActual := configMapPlacedOnClusterActual(allMemberClusters[idx], &oldConfigMap) @@ -339,7 +339,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-1 too but not member-cluster-3 and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) checkIfRemovedConfigMapFromMemberClustersConsistently([]*framework.Cluster{allMemberClusters[2]}) @@ -389,7 +389,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, policySnapshotIndex2nd, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, "", policySnapshotIndex2nd, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[1]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -436,7 +436,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem It("Should remove resources on member-cluster-1 and member-cluster-2 and complete the staged update run successfully", func() { // need to go through two stages - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, policySnapshotIndex3rd, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0], allMemberClusterNames[1]}, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, "", policySnapshotIndex3rd, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0], allMemberClusterNames[1]}, nil, nil) Eventually(surSucceededActual, 2*updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[2]) checkIfRemovedConfigMapFromMemberClusters([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) checkIfPlacedWorkResourcesOnMemberClustersConsistently([]*framework.Cluster{allMemberClusters[2]}) @@ -526,7 +526,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-3 and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, policySnapshotIndex1st, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[2]}) checkIfRemovedConfigMapFromMemberClustersConsistently([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) @@ -575,7 +575,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-1 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[1]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -621,7 +621,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should remove resources on member-cluster-1 and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, "", policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) Eventually(surSucceededActual, 2*updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[2]) checkIfRemovedConfigMapFromMemberClusters([]*framework.Cluster{allMemberClusters[0]}) checkIfPlacedWorkResourcesOnMemberClustersConsistently([]*framework.Cluster{allMemberClusters[1], allMemberClusters[2]}) @@ -766,7 +766,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-1 and member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, wantROs) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, "", policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, wantROs) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunName) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -860,7 +860,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should report diff for member-cluster-1 and member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, policySnapshotIndex1st, len(allMemberClusters), applyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), applyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunName) }) @@ -969,7 +969,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem validateAndApproveNamespacedApprovalRequests(updateRunName, testNamespace, envCanary) // Verify complete rollout. - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex2nd), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunName) // Verify new configmap is on all member clusters. @@ -1045,7 +1045,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem validateAndApproveNamespacedApprovalRequests(updateRunName, testNamespace, envCanary) - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunName) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) From aca848c582c86a00d2d7cf0504210945dd15d92a Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Mon, 10 Nov 2025 15:06:38 -0800 Subject: [PATCH 05/10] fix the rest of the e2es Signed-off-by: Britania Rodriguez Reyes --- test/e2e/cluster_staged_updaterun_test.go | 16 +++++++------- test/e2e/staged_updaterun_test.go | 26 +++++++++++------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/e2e/cluster_staged_updaterun_test.go b/test/e2e/cluster_staged_updaterun_test.go index da1c05001..c6b529c49 100644 --- a/test/e2e/cluster_staged_updaterun_test.go +++ b/test/e2e/cluster_staged_updaterun_test.go @@ -216,7 +216,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-1 and member-cluster-3 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex2nd), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) By("Verify that new the configmap is updated on all member clusters") for idx := range allMemberClusters { @@ -254,7 +254,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollback resources to member-cluster-1 and member-cluster-3 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], "", policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) for idx := range allMemberClusters { configMapActual := configMapPlacedOnClusterActual(allMemberClusters[idx], &oldConfigMap) @@ -400,7 +400,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-3 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex2nd, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex2nd, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -447,7 +447,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { It("Should remove resources on member-cluster-1 and member-cluster-2 and complete the cluster staged update run successfully", func() { // need to go through two stages - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], "", policySnapshotIndex3rd, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0], allMemberClusterNames[1]}, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex3rd, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0], allMemberClusterNames[1]}, nil, nil) Eventually(csurSucceededActual, 2*updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[2]) checkIfRemovedWorkResourcesFromMemberClusters([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) checkIfPlacedWorkResourcesOnMemberClustersConsistently([]*framework.Cluster{allMemberClusters[2]}) @@ -588,7 +588,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should rollout resources to member-cluster-1 too and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -634,7 +634,7 @@ var _ = Describe("test CRP rollout with staged update run", func() { }) It("Should remove resources on member-cluster-1 and complete the cluster staged update run successfully", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], "", policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[2], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) Eventually(csurSucceededActual, 2*updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[2]) checkIfRemovedWorkResourcesFromMemberClusters([]*framework.Cluster{allMemberClusters[0]}) checkIfPlacedWorkResourcesOnMemberClustersConsistently([]*framework.Cluster{allMemberClusters[1], allMemberClusters[2]}) @@ -1394,7 +1394,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label }) It("Should complete the second staged update run and complete the CRP", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1], allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1], allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) crpStatusUpdatedActual := crpStatusWithExternalStrategyActual(workResourceIdentifiers(), resourceSnapshotIndex1st, true, allMemberClusterNames[1:], @@ -1442,7 +1442,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label }) It("Should complete the staged update run, complete CRP, and rollout resources to all member clusters", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[0]) crpStatusUpdatedActual := crpStatusWithExternalStrategyActual(workResourceIdentifiers(), resourceSnapshotIndex1st, true, allMemberClusterNames, diff --git a/test/e2e/staged_updaterun_test.go b/test/e2e/staged_updaterun_test.go index 8d0a17d98..8a0227cd3 100644 --- a/test/e2e/staged_updaterun_test.go +++ b/test/e2e/staged_updaterun_test.go @@ -142,7 +142,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to all the members and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -207,7 +207,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-1 and member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex2nd), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[1]) By("Verify that new the configmap is updated on all member clusters") for idx := range allMemberClusters { @@ -245,7 +245,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollback resources to member-cluster-1 and member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, "", policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) for idx := range allMemberClusters { configMapActual := configMapPlacedOnClusterActual(allMemberClusters[idx], &oldConfigMap) @@ -339,7 +339,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-1 too but not member-cluster-3 and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) checkIfRemovedConfigMapFromMemberClustersConsistently([]*framework.Cluster{allMemberClusters[2]}) @@ -389,7 +389,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, "", policySnapshotIndex2nd, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex2nd, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[1]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -436,7 +436,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem It("Should remove resources on member-cluster-1 and member-cluster-2 and complete the staged update run successfully", func() { // need to go through two stages - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, "", policySnapshotIndex3rd, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0], allMemberClusterNames[1]}, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex3rd, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0], allMemberClusterNames[1]}, nil, nil) Eventually(surSucceededActual, 2*updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[2]) checkIfRemovedConfigMapFromMemberClusters([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) checkIfPlacedWorkResourcesOnMemberClustersConsistently([]*framework.Cluster{allMemberClusters[2]}) @@ -526,7 +526,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-3 and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 1, defaultApplyStrategy, &strategy.Spec, [][]string{{}, {allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[0]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[2]}) checkIfRemovedConfigMapFromMemberClustersConsistently([]*framework.Cluster{allMemberClusters[0], allMemberClusters[1]}) @@ -575,7 +575,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-1 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[1], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[1]) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -621,7 +621,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should remove resources on member-cluster-1 and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, "", policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[2], testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 2, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[2]}}, []string{allMemberClusterNames[0]}, nil, nil) Eventually(surSucceededActual, 2*updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[2]) checkIfRemovedConfigMapFromMemberClusters([]*framework.Cluster{allMemberClusters[0]}) checkIfPlacedWorkResourcesOnMemberClustersConsistently([]*framework.Cluster{allMemberClusters[1], allMemberClusters[2]}) @@ -766,7 +766,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should rollout resources to member-cluster-1 and member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, "", policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, wantROs) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, wantROs) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunName) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) }) @@ -860,7 +860,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem }) It("Should report diff for member-cluster-1 and member-cluster-3 too and complete the staged update run successfully", func() { - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), applyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), applyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunName) }) @@ -969,7 +969,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem validateAndApproveNamespacedApprovalRequests(updateRunName, testNamespace, envCanary) // Verify complete rollout. - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex2nd), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex2nd), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunName) // Verify new configmap is on all member clusters. @@ -1045,7 +1045,7 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem validateAndApproveNamespacedApprovalRequests(updateRunName, testNamespace, envCanary) - surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) + surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunName, testNamespace, fmt.Sprintf(testResourceSnapshotNameTmpl, rpName, resourceSnapshotIndex1st), policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunName) checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters) From 13bfaf66c1ee0c51038f2fabf81e84a93aa584a1 Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Mon, 10 Nov 2025 15:25:34 -0800 Subject: [PATCH 06/10] minor fix Signed-off-by: Britania Rodriguez Reyes --- test/e2e/cluster_staged_updaterun_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/e2e/cluster_staged_updaterun_test.go b/test/e2e/cluster_staged_updaterun_test.go index c6b529c49..c1a7ae7c4 100644 --- a/test/e2e/cluster_staged_updaterun_test.go +++ b/test/e2e/cluster_staged_updaterun_test.go @@ -1485,7 +1485,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label }) It("Should complete the staged update run, complete CRP, and rollout updated resources to all member clusters", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex2nd), policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) crpStatusUpdatedActual := crpStatusWithExternalStrategyActual(workResourceIdentifiers(), resourceSnapshotIndex2nd, true, allMemberClusterNames, @@ -1524,7 +1524,7 @@ var _ = Describe("Test member cluster join and leave flow with updateRun", Label }) It("Should complete the staged update run, complete CRP, and re-place resources to all member clusters", func() { - csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], "", policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) + csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], fmt.Sprintf(testResourceSnapshotNameTmpl, crpName, resourceSnapshotIndex1st), policySnapshotIndex1st, 3, defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[0], allMemberClusterNames[1], allMemberClusterNames[2]}}, nil, nil, nil) Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1]) crpStatusUpdatedActual := crpStatusWithExternalStrategyActual(workResourceIdentifiers(), resourceSnapshotIndex1st, true, allMemberClusterNames, From b65b259b1d36050ac99c1e8f5c9d66dbbc897733 Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Mon, 10 Nov 2025 20:46:50 -0800 Subject: [PATCH 07/10] address comments Signed-off-by: Britania Rodriguez Reyes --- apis/placement/v1beta1/stageupdate_types.go | 2 +- .../v1beta1/zz_generated.deepcopy.go | 2 +- ...etes-fleet.io_clusterstagedupdateruns.yaml | 2 +- ....kubernetes-fleet.io_stagedupdateruns.yaml | 2 +- pkg/controllers/updaterun/initialization.go | 39 ++++++---- .../initialization_integration_test.go | 74 +++++++++++++++++++ 6 files changed, 104 insertions(+), 17 deletions(-) diff --git a/apis/placement/v1beta1/stageupdate_types.go b/apis/placement/v1beta1/stageupdate_types.go index 80d5e91ab..41947e59f 100644 --- a/apis/placement/v1beta1/stageupdate_types.go +++ b/apis/placement/v1beta1/stageupdate_types.go @@ -335,7 +335,7 @@ type UpdateRunStatus struct { // +kubebuilder:validation:Optional PolicyObservedClusterCount int `json:"policyObservedClusterCount,omitempty"` - // ResourceSnapshotName records the name of the resource snapshot that the update run is based on. + // ResourceSnapshotName records the name of the master resource snapshot that the update run is based on. // +kubebuilder:validation:Optional ResourceSnapshotName string `json:"resourceSnapshotName,omitempty"` diff --git a/apis/placement/v1beta1/zz_generated.deepcopy.go b/apis/placement/v1beta1/zz_generated.deepcopy.go index b9ff2e710..73d66c8fa 100644 --- a/apis/placement/v1beta1/zz_generated.deepcopy.go +++ b/apis/placement/v1beta1/zz_generated.deepcopy.go @@ -21,7 +21,7 @@ limitations under the License. package v1beta1 import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) diff --git a/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml b/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml index 7c7f62985..a6e220141 100644 --- a/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml +++ b/config/crd/bases/placement.kubernetes-fleet.io_clusterstagedupdateruns.yaml @@ -1856,7 +1856,7 @@ spec: to the current policy. type: string resourceSnapshotName: - description: ResourceSnapshotName records the name of the resource + description: ResourceSnapshotName records the name of the master resource snapshot that the update run is based on. type: string stagedUpdateStrategySnapshot: diff --git a/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml b/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml index 7f72254c5..3728e6c55 100644 --- a/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml +++ b/config/crd/bases/placement.kubernetes-fleet.io_stagedupdateruns.yaml @@ -775,7 +775,7 @@ spec: to the current policy. type: string resourceSnapshotName: - description: ResourceSnapshotName records the name of the resource + description: ResourceSnapshotName records the name of the master resource snapshot that the update run is based on. type: string stagedUpdateStrategySnapshot: diff --git a/pkg/controllers/updaterun/initialization.go b/pkg/controllers/updaterun/initialization.go index 756dc27ab..29ba03ef0 100644 --- a/pkg/controllers/updaterun/initialization.go +++ b/pkg/controllers/updaterun/initialization.go @@ -478,19 +478,13 @@ func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey t return err } - if len(resourceSnapshotObjs) == 0 { - err := controller.NewUserError(fmt.Errorf("no resourceSnapshots found for placement `%s`", placementKey)) - klog.ErrorS(err, "No resourceSnapshots found", "updateRun", updateRunRef) - // no more retries here. - return fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) - } - // Look for the master resourceSnapshot. var masterResourceSnapshot placementv1beta1.ResourceSnapshotObj for _, resourceSnapshot := range resourceSnapshotObjs { // only master has this annotation. if len(resourceSnapshot.GetAnnotations()[placementv1beta1.ResourceGroupHashAnnotation]) != 0 { masterResourceSnapshot = resourceSnapshot + break } } @@ -502,10 +496,12 @@ func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey t return fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) } - klog.InfoS("Found master resourceSnapshot", "placement", placementKey, "index", updateRun.GetUpdateRunSpec().ResourceSnapshotIndex, "updateRun", updateRunRef) + klog.InfoS("Found master resourceSnapshot", "placement", placementKey, "masterResourceSnapshot", masterResourceSnapshot.GetName(), "updateRun", updateRunRef) // Update the resource snapshot name in the UpdateRun status. - updateRun.GetUpdateRunStatus().ResourceSnapshotName = masterResourceSnapshot.GetName() + updateRunStatus := updateRun.GetUpdateRunStatus() + updateRunStatus.ResourceSnapshotName = masterResourceSnapshot.GetName() + updateRun.SetUpdateRunStatus(*updateRunStatus) if updateErr := r.Client.Status().Update(ctx, updateRun); updateErr != nil { klog.ErrorS(updateErr, "Failed to update the UpdateRun status with resource snapshot name", "updateRun", klog.KObj(updateRun), "resourceSnapshot", klog.KObj(masterResourceSnapshot)) // updateErr can be retried. @@ -522,7 +518,6 @@ func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey t } // Pick the overrides associated with each target cluster. - updateRunStatus := updateRun.GetUpdateRunStatus() for _, stageStatus := range updateRunStatus.StagesStatus { for i := range stageStatus.Clusters { clusterStatus := &stageStatus.Clusters[i] @@ -539,8 +534,10 @@ func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey t return nil } -// getResourceSnapshotObjs retrieves the resource snapshot objects either by index or latest snapshots. +// getResourceSnapshotObjs retrieves the list of resource snapshot objects from the specified ResourceSnapshotIndex. +// If ResourceSnapshotIndex is unspecified, it returns the list of latest resource snapshots. func (r *Reconciler) getResourceSnapshotObjs(ctx context.Context, updateRunSpec *placementv1beta1.UpdateRunSpec, placementName string, placementKey types.NamespacedName, updateRunRef klog.ObjectRef) ([]placementv1beta1.ResourceSnapshotObj, error) { + var resourceSnapshotObjs []placementv1beta1.ResourceSnapshotObj if updateRunSpec.ResourceSnapshotIndex != "" { snapshotIndex, err := strconv.Atoi(updateRunSpec.ResourceSnapshotIndex) if err != nil || snapshotIndex < 0 { @@ -555,7 +552,15 @@ func (r *Reconciler) getResourceSnapshotObjs(ctx context.Context, updateRunSpec "placement", placementKey, "resourceSnapshotIndex", snapshotIndex, "updateRun", updateRunRef) return nil, controller.NewAPIServerError(true, err) } - return resourceSnapshotList.GetResourceSnapshotObjs(), nil + + resourceSnapshotObjs = resourceSnapshotList.GetResourceSnapshotObjs() + if len(resourceSnapshotObjs) == 0 { + err := controller.NewUserError(fmt.Errorf("no resourceSnapshots with index `%d` found for placement `%s`", snapshotIndex, placementKey)) + klog.ErrorS(err, "No specified resourceSnapshots found", "updateRun", updateRunRef) + // no more retries here. + return resourceSnapshotObjs, fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) + } + return resourceSnapshotObjs, nil } latestResourceSnapshots, err := controller.ListLatestResourceSnapshots(ctx, r.Client, placementKey) @@ -564,7 +569,15 @@ func (r *Reconciler) getResourceSnapshotObjs(ctx context.Context, updateRunSpec "placement", placementKey, "updateRun", updateRunRef) return nil, controller.NewAPIServerError(true, err) } - return latestResourceSnapshots.GetResourceSnapshotObjs(), nil + + resourceSnapshotObjs = latestResourceSnapshots.GetResourceSnapshotObjs() + if len(resourceSnapshotObjs) == 0 { + err := controller.NewUserError(fmt.Errorf("no resourceSnapshots found for placement `%s`", placementKey)) + klog.ErrorS(err, "No resourceSnapshots found", "updateRun", updateRunRef) + // no more retries here. + return resourceSnapshotObjs, fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) + } + return resourceSnapshotObjs, nil } // recordInitializationSucceeded records the successful initialization condition in the UpdateRun status. diff --git a/pkg/controllers/updaterun/initialization_integration_test.go b/pkg/controllers/updaterun/initialization_integration_test.go index b38a80443..c2d9a6095 100644 --- a/pkg/controllers/updaterun/initialization_integration_test.go +++ b/pkg/controllers/updaterun/initialization_integration_test.go @@ -877,6 +877,80 @@ var _ = Describe("Updaterun initialization tests", func() { validateUpdateRunMetricsEmitted(generateProgressingMetric(updateRun)) }) }) + + Context("Test multiple resource snapshots", func() { + var resourceSnapshot2, resourceSnapshot3 *placementv1beta1.ClusterResourceSnapshot + BeforeEach(func() { + By("Creating a new clusterResourcePlacement") + Expect(k8sClient.Create(ctx, crp)).To(Succeed()) + + By("Creating scheduling policy snapshot") + Expect(k8sClient.Create(ctx, policySnapshot)).To(Succeed()) + + By("Setting the latest policy snapshot condition as fully scheduled") + meta.SetStatusCondition(&policySnapshot.Status.Conditions, metav1.Condition{ + Type: string(placementv1beta1.PolicySnapshotScheduled), + Status: metav1.ConditionTrue, + ObservedGeneration: policySnapshot.Generation, + Reason: "scheduled", + }) + Expect(k8sClient.Status().Update(ctx, policySnapshot)).Should(Succeed(), "failed to update the policy snapshot condition") + + By("Creating a new resource snapshot") + resourceSnapshot.Labels[placementv1beta1.IsLatestSnapshotLabel] = "false" + Expect(k8sClient.Create(ctx, resourceSnapshot)).To(Succeed()) + + By("Creating a another new resource snapshot") + resourceSnapshot2 = generateTestClusterResourceSnapshot() + resourceSnapshot2.Name = testCRPName + "-1-snapshot" + resourceSnapshot2.Labels[placementv1beta1.IsLatestSnapshotLabel] = "false" + resourceSnapshot2.Labels[placementv1beta1.ResourceIndexLabel] = "1" + Expect(k8sClient.Create(ctx, resourceSnapshot2)).To(Succeed()) + + By("Creating a latest master resource snapshot") + resourceSnapshot3 = generateTestClusterResourceSnapshot() + resourceSnapshot3.Name = testCRPName + "-2-snapshot" + resourceSnapshot3.Labels[placementv1beta1.ResourceIndexLabel] = "2" + Expect(k8sClient.Create(ctx, resourceSnapshot3)).To(Succeed()) + + By("Creating the member clusters") + for _, cluster := range targetClusters { + Expect(k8sClient.Create(ctx, cluster)).To(Succeed()) + } + for _, cluster := range unscheduledClusters { + Expect(k8sClient.Create(ctx, cluster)).To(Succeed()) + } + + By("Creating a bunch of ClusterResourceBindings") + for _, binding := range resourceBindings { + Expect(k8sClient.Create(ctx, binding)).To(Succeed()) + } + + By("Creating a clusterStagedUpdateStrategy") + Expect(k8sClient.Create(ctx, updateStrategy)).To(Succeed()) + }) + + It("Should pick latest master resource snapshot", func() { + By("Creating a new cluster resource override") + Expect(k8sClient.Create(ctx, clusterResourceOverride)).To(Succeed()) + + By("Creating a new clusterStagedUpdateRun") + updateRun.Spec.ResourceSnapshotIndex = "" + Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) + + By("Validating the clusterStagedUpdateRun stats") + initialized := generateSucceededInitializationStatus(crp, updateRun, policySnapshot, updateStrategy, clusterResourceOverride) + initialized.ResourceSnapshotName = resourceSnapshot3.Name + want := generateExecutionStartedStatus(updateRun, initialized) + validateClusterStagedUpdateRunStatus(ctx, updateRun, want, "") + + By("Validating the clusterStagedUpdateRun initialized consistently") + validateClusterStagedUpdateRunStatusConsistently(ctx, updateRun, want, "") + + By("Checking update run status metrics are emitted") + validateUpdateRunMetricsEmitted(generateProgressingMetric(updateRun)) + }) + }) }) func validateFailedInitCondition(ctx context.Context, updateRun *placementv1beta1.ClusterStagedUpdateRun, message string) { From 7bd599d657131bdf16d5a3b504364052038b3bb3 Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Tue, 11 Nov 2025 10:22:15 -0800 Subject: [PATCH 08/10] fix UT Signed-off-by: Britania Rodriguez Reyes --- pkg/controllers/updaterun/initialization.go | 1 - .../updaterun/initialization_integration_test.go | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pkg/controllers/updaterun/initialization.go b/pkg/controllers/updaterun/initialization.go index 29ba03ef0..c6e5460a8 100644 --- a/pkg/controllers/updaterun/initialization.go +++ b/pkg/controllers/updaterun/initialization.go @@ -484,7 +484,6 @@ func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey t // only master has this annotation. if len(resourceSnapshot.GetAnnotations()[placementv1beta1.ResourceGroupHashAnnotation]) != 0 { masterResourceSnapshot = resourceSnapshot - break } } diff --git a/pkg/controllers/updaterun/initialization_integration_test.go b/pkg/controllers/updaterun/initialization_integration_test.go index c2d9a6095..581feba16 100644 --- a/pkg/controllers/updaterun/initialization_integration_test.go +++ b/pkg/controllers/updaterun/initialization_integration_test.go @@ -774,18 +774,18 @@ var _ = Describe("Updaterun initialization tests", func() { validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) }) - It("Should fail to initialize if the specified resource snapshot is not found - no resourceSnapshots at all", func() { + FIt("Should fail to initialize if the specified resource snapshot is not found - no resourceSnapshots at all", func() { By("Creating a new clusterStagedUpdateRun") Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) By("Validating the initialization failed") - validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots found for placement") + validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots with index `0` found") By("Checking update run status metrics are emitted") validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) }) - It("Should fail to initialize if the specified resource snapshot is not found - no CRP label found", func() { + FIt("Should fail to initialize if the specified resource snapshot is not found - no CRP label found", func() { By("Creating a new resource snapshot associated with another CRP") resourceSnapshot.Labels[placementv1beta1.PlacementTrackingLabel] = "not-exist-crp" Expect(k8sClient.Create(ctx, resourceSnapshot)).To(Succeed()) @@ -794,13 +794,13 @@ var _ = Describe("Updaterun initialization tests", func() { Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) By("Validating the initialization failed") - validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots found for placement") + validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots with index `0` found") By("Checking update run status metrics are emitted") validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) }) - It("Should fail to initialize if the specified resource snapshot is not found - no resource index label found", func() { + FIt("Should fail to initialize if the specified resource snapshot is not found - no resource index label found", func() { By("Creating a new resource snapshot with a different index label") resourceSnapshot.Labels[placementv1beta1.ResourceIndexLabel] = testResourceSnapshotIndex + "1" Expect(k8sClient.Create(ctx, resourceSnapshot)).To(Succeed()) @@ -809,7 +809,7 @@ var _ = Describe("Updaterun initialization tests", func() { Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) By("Validating the initialization failed") - validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots found for placement") + validateFailedInitCondition(ctx, updateRun, "no resourceSnapshots with index `0` found") By("Checking update run status metrics are emitted") validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) From 3567909a81569adf7a12b1e6ee240d1ba0290641 Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Tue, 11 Nov 2025 10:35:12 -0800 Subject: [PATCH 09/10] fix Signed-off-by: Britania Rodriguez Reyes --- .../updaterun/initialization_integration_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/controllers/updaterun/initialization_integration_test.go b/pkg/controllers/updaterun/initialization_integration_test.go index 581feba16..95ffdfcac 100644 --- a/pkg/controllers/updaterun/initialization_integration_test.go +++ b/pkg/controllers/updaterun/initialization_integration_test.go @@ -774,7 +774,7 @@ var _ = Describe("Updaterun initialization tests", func() { validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) }) - FIt("Should fail to initialize if the specified resource snapshot is not found - no resourceSnapshots at all", func() { + It("Should fail to initialize if the specified resource snapshot is not found - no resourceSnapshots at all", func() { By("Creating a new clusterStagedUpdateRun") Expect(k8sClient.Create(ctx, updateRun)).To(Succeed()) @@ -785,7 +785,7 @@ var _ = Describe("Updaterun initialization tests", func() { validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) }) - FIt("Should fail to initialize if the specified resource snapshot is not found - no CRP label found", func() { + It("Should fail to initialize if the specified resource snapshot is not found - no CRP label found", func() { By("Creating a new resource snapshot associated with another CRP") resourceSnapshot.Labels[placementv1beta1.PlacementTrackingLabel] = "not-exist-crp" Expect(k8sClient.Create(ctx, resourceSnapshot)).To(Succeed()) @@ -800,7 +800,7 @@ var _ = Describe("Updaterun initialization tests", func() { validateUpdateRunMetricsEmitted(generateInitializationFailedMetric(updateRun)) }) - FIt("Should fail to initialize if the specified resource snapshot is not found - no resource index label found", func() { + It("Should fail to initialize if the specified resource snapshot is not found - no resource index label found", func() { By("Creating a new resource snapshot with a different index label") resourceSnapshot.Labels[placementv1beta1.ResourceIndexLabel] = testResourceSnapshotIndex + "1" Expect(k8sClient.Create(ctx, resourceSnapshot)).To(Succeed()) From 8e4673eebc3ccf03e8da4f75028a10969d5e7521 Mon Sep 17 00:00:00 2001 From: Britania Rodriguez Reyes Date: Tue, 11 Nov 2025 14:50:57 -0800 Subject: [PATCH 10/10] address comments Signed-off-by: Britania Rodriguez Reyes --- pkg/controllers/updaterun/initialization.go | 3 +- .../initialization_integration_test.go | 10 + .../updaterun/initialization_test.go | 194 +++++++++++++++++- 3 files changed, 204 insertions(+), 3 deletions(-) diff --git a/pkg/controllers/updaterun/initialization.go b/pkg/controllers/updaterun/initialization.go index c6e5460a8..c770185bb 100644 --- a/pkg/controllers/updaterun/initialization.go +++ b/pkg/controllers/updaterun/initialization.go @@ -495,12 +495,11 @@ func (r *Reconciler) recordOverrideSnapshots(ctx context.Context, placementKey t return fmt.Errorf("%w: %s", errInitializedFailed, err.Error()) } - klog.InfoS("Found master resourceSnapshot", "placement", placementKey, "masterResourceSnapshot", masterResourceSnapshot.GetName(), "updateRun", updateRunRef) + klog.V(2).InfoS("Found master resourceSnapshot", "placement", placementKey, "masterResourceSnapshot", masterResourceSnapshot.GetName(), "updateRun", updateRunRef) // Update the resource snapshot name in the UpdateRun status. updateRunStatus := updateRun.GetUpdateRunStatus() updateRunStatus.ResourceSnapshotName = masterResourceSnapshot.GetName() - updateRun.SetUpdateRunStatus(*updateRunStatus) if updateErr := r.Client.Status().Update(ctx, updateRun); updateErr != nil { klog.ErrorS(updateErr, "Failed to update the UpdateRun status with resource snapshot name", "updateRun", klog.KObj(updateRun), "resourceSnapshot", klog.KObj(masterResourceSnapshot)) // updateErr can be retried. diff --git a/pkg/controllers/updaterun/initialization_integration_test.go b/pkg/controllers/updaterun/initialization_integration_test.go index 95ffdfcac..039893b30 100644 --- a/pkg/controllers/updaterun/initialization_integration_test.go +++ b/pkg/controllers/updaterun/initialization_integration_test.go @@ -930,6 +930,16 @@ var _ = Describe("Updaterun initialization tests", func() { Expect(k8sClient.Create(ctx, updateStrategy)).To(Succeed()) }) + AfterEach(func() { + By("Deleting the second clusterResourceSnapshot") + Expect(k8sClient.Delete(ctx, resourceSnapshot2)).To(Succeed()) + + By("Deleting the third clusterResourceSnapshot") + Expect(k8sClient.Delete(ctx, resourceSnapshot3)).To(Succeed()) + + // Everything else should be deleted by the outer AfterEach + }) + It("Should pick latest master resource snapshot", func() { By("Creating a new cluster resource override") Expect(k8sClient.Create(ctx, clusterResourceOverride)).To(Succeed()) diff --git a/pkg/controllers/updaterun/initialization_test.go b/pkg/controllers/updaterun/initialization_test.go index 0c470d38e..3e5515a71 100644 --- a/pkg/controllers/updaterun/initialization_test.go +++ b/pkg/controllers/updaterun/initialization_test.go @@ -1,13 +1,22 @@ package updaterun import ( + "context" + "fmt" + "strings" "testing" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/klog/v2" "k8s.io/utils/ptr" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/kubefleet-dev/kubefleet/apis/placement/v1beta1" + v1beta1 "github.com/kubefleet-dev/kubefleet/apis/placement/v1beta1" ) func TestValidateAfterStageTask(t *testing.T) { @@ -85,3 +94,186 @@ func TestValidateAfterStageTask(t *testing.T) { }) } } + +func TestGetResourceSnapshotObjs(t *testing.T) { + ctx := context.Background() + placementName := "test-placement" + placementKey := types.NamespacedName{Name: placementName, Namespace: "test-namespace"} + updateRunRef := klog.ObjectRef{ + Name: "test-updaterun", + Namespace: "test-namespace", + } + + // Create test resource snapshots + masterResourceSnapshot := &v1beta1.ClusterResourceSnapshot{ + ObjectMeta: metav1.ObjectMeta{ + Name: placementName + "-1-snapshot", + Namespace: placementKey.Namespace, + Labels: map[string]string{ + v1beta1.PlacementTrackingLabel: placementName, + v1beta1.ResourceIndexLabel: "1", + v1beta1.IsLatestSnapshotLabel: "false", + v1beta1.ResourceGroupHashAnnotation: "hash123", + }, + Annotations: map[string]string{ + v1beta1.ResourceGroupHashAnnotation: "hash123", + }, + }, + } + + tests := []struct { + name string + updateRunSpec *v1beta1.UpdateRunSpec + resourceSnapshots []runtime.Object + wantSnapshotCount int + wantErr bool + wantErrMsg string + }{ + // negative cases only + { + name: "invalid resource snapshot index - non-numeric", + updateRunSpec: &v1beta1.UpdateRunSpec{ + ResourceSnapshotIndex: "invalid", + }, + resourceSnapshots: []runtime.Object{}, + wantSnapshotCount: 0, + wantErr: true, + wantErrMsg: "invalid resource snapshot index `invalid` provided, expected an integer >= 0", + }, + { + name: "invalid resource snapshot index - negative", + updateRunSpec: &v1beta1.UpdateRunSpec{ + ResourceSnapshotIndex: "-1", + }, + resourceSnapshots: []runtime.Object{}, + wantSnapshotCount: 0, + wantErr: true, + wantErrMsg: "invalid resource snapshot index `-1` provided, expected an integer >= 0", + }, + { + name: "no resource snapshots found for specific index", + updateRunSpec: &v1beta1.UpdateRunSpec{ + ResourceSnapshotIndex: "999", + }, + resourceSnapshots: []runtime.Object{ + masterResourceSnapshot, // has index "1", not "999" + }, + wantSnapshotCount: 0, + wantErr: true, + wantErrMsg: fmt.Sprintf("no resourceSnapshots with index `999` found for placement `%s`", placementKey), + }, + { + name: "no latest resource snapshots found", + updateRunSpec: &v1beta1.UpdateRunSpec{ + ResourceSnapshotIndex: "", + }, + resourceSnapshots: []runtime.Object{}, // no snapshots + wantSnapshotCount: 0, + wantErr: true, + wantErrMsg: fmt.Sprintf("no resourceSnapshots found for placement `%s`", placementKey), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a fake client with the test objects + s := runtime.NewScheme() + _ = v1beta1.AddToScheme(s) + _ = scheme.AddToScheme(s) + + fakeClient := fake.NewClientBuilder(). + WithScheme(s). + WithRuntimeObjects(tt.resourceSnapshots...). + Build() + + // Create reconciler with fake client + r := &Reconciler{ + Client: fakeClient, + } + + // Call the function + result, err := r.getResourceSnapshotObjs(ctx, tt.updateRunSpec, placementName, placementKey, updateRunRef) + + // Verify error expectations + if tt.wantErr { + if err == nil { + t.Errorf("getResourceSnapshotObjs() error = nil, wantErr %v", tt.wantErr) + return + } + // Check if the error message contains the expected substring + if !strings.Contains(err.Error(), tt.wantErrMsg) { + t.Errorf("getResourceSnapshotObjs() error = %v, want error containing %v", err, tt.wantErrMsg) + } + return + } + + // Verify no error when not expected + if err != nil { + t.Errorf("getResourceSnapshotObjs() unexpected error = %v", err) + return + } + + // Verify result count + if len(result) != tt.wantSnapshotCount { + t.Errorf("getResourceSnapshotObjs() returned %d snapshots, want %d", len(result), tt.wantSnapshotCount) + return + } + }) + } +} + +// fakeListErrorClient wraps a client and always returns an error on List. +type fakeListErrorClient struct { + client.Client +} + +func (f *fakeListErrorClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { + return fmt.Errorf("simulated list error") +} + +func TestGetResourceSnapshotObjs_ListError(t *testing.T) { + tests := []struct { + name string + spec *v1beta1.UpdateRunSpec + wantErrMsg string + }{ + { + name: "list error simulation with resource index", + spec: &v1beta1.UpdateRunSpec{ + ResourceSnapshotIndex: "1", + }, + wantErrMsg: "Failed to list the resourceSnapshots associated with the placement for the given index", + }, + { + name: "list error simulation without resource index", + spec: &v1beta1.UpdateRunSpec{ + ResourceSnapshotIndex: "", + }, + wantErrMsg: "Failed to list the resourceSnapshots associated with the placement", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + placementName := "test-placement" + placementKey := types.NamespacedName{Name: placementName, Namespace: "test-namespace"} + updateRunRef := klog.ObjectRef{ + Name: "test-updaterun", + Namespace: "test-namespace", + } + + s := runtime.NewScheme() + _ = v1beta1.AddToScheme(s) + _ = scheme.AddToScheme(s) + + fakeClient := &fakeListErrorClient{Client: fake.NewClientBuilder().WithScheme(s).Build()} + r := &Reconciler{Client: fakeClient} + + _, err := r.getResourceSnapshotObjs(ctx, tt.spec, placementName, placementKey, updateRunRef) + if err == nil || !strings.Contains(err.Error(), "simulated list error") { + t.Errorf("expected simulated list error, got: %v", err) + } + }) + } +}