Skip to content

Commit a9b7520

Browse files
committed
rebase and address comments
Signed-off-by: Britania Rodriguez Reyes <[email protected]>
1 parent e1e3554 commit a9b7520

File tree

9 files changed

+205
-227
lines changed

9 files changed

+205
-227
lines changed

pkg/controllers/updaterun/controller_integration_test.go

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -812,26 +812,17 @@ func generateFalseProgressingCondition(obj client.Object, condType any, succeede
812812

813813
func generateTrueStageTaskCondition(obj client.Object, condType any, isBeforeStage bool) metav1.Condition {
814814
reason, typeStr := "", ""
815-
switch cond := condType.(type) {
816-
case placementv1beta1.StageTaskConditionType:
817-
switch cond {
818-
case placementv1beta1.StageTaskConditionWaitTimeElapsed:
819-
reason = condition.AfterStageTaskWaitTimeElapsedReason
820-
case placementv1beta1.StageTaskConditionApprovalRequestCreated:
821-
if isBeforeStage {
822-
reason = condition.BeforeStageTaskApprovalRequestCreatedReason
823-
} else {
824-
reason = condition.AfterStageTaskApprovalRequestCreatedReason
825-
}
826-
case placementv1beta1.StageTaskConditionApprovalRequestApproved:
827-
if isBeforeStage {
828-
reason = condition.BeforeStageTaskApprovalRequestApprovedReason
829-
} else {
830-
reason = condition.AfterStageTaskApprovalRequestApprovedReason
831-
}
832-
}
833-
typeStr = string(cond)
815+
cond := condType.(placementv1beta1.StageTaskConditionType)
816+
switch cond {
817+
case placementv1beta1.StageTaskConditionWaitTimeElapsed:
818+
reason = condition.AfterStageTaskWaitTimeElapsedReason
819+
case placementv1beta1.StageTaskConditionApprovalRequestCreated:
820+
reason = condition.StageTaskApprovalRequestCreatedReason
821+
case placementv1beta1.StageTaskConditionApprovalRequestApproved:
822+
reason = condition.StageTaskApprovalRequestApprovedReason
834823
}
824+
typeStr = string(cond)
825+
835826
return metav1.Condition{
836827
Status: metav1.ConditionTrue,
837828
Type: typeStr,

pkg/controllers/updaterun/execution.go

Lines changed: 93 additions & 162 deletions
Large diffs are not rendered by default.

pkg/controllers/updaterun/execution_integration_test.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,6 @@ var _ = Describe("UpdateRun execution tests - double stages", func() {
167167
Context("Cluster staged update run should update clusters one by one", Ordered, func() {
168168
var wantApprovalRequest *placementv1beta1.ClusterApprovalRequest
169169
BeforeAll(func() {
170-
By("Update the strategy with an approval before stage task and after stage tasks")
171-
Expect(k8sClient.Update(ctx, updateStrategy)).To(Succeed())
172-
173170
By("Creating a new clusterStagedUpdateRun")
174171
Expect(k8sClient.Create(ctx, updateRun)).To(Succeed())
175172

@@ -180,7 +177,7 @@ var _ = Describe("UpdateRun execution tests - double stages", func() {
180177
wantStatus = generateExecutionNotStartedStatus(updateRun, initialized)
181178
validateClusterStagedUpdateRunStatus(ctx, updateRun, wantStatus, "")
182179

183-
By("Validating the first approvalRequest has been created")
180+
By("Validating the first beforeStage approvalRequest has been created")
184181
wantApprovalRequest = &placementv1beta1.ClusterApprovalRequest{
185182
ObjectMeta: metav1.ObjectMeta{
186183
Name: updateRun.Status.StagesStatus[0].BeforeStageTaskStatus[0].ApprovalRequestName,
@@ -319,7 +316,7 @@ var _ = Describe("UpdateRun execution tests - double stages", func() {
319316
meta.SetStatusCondition(&binding.Status.Conditions, generateTrueCondition(binding, placementv1beta1.ResourceBindingAvailable))
320317
Expect(k8sClient.Status().Update(ctx, binding)).Should(Succeed(), "failed to update the binding status")
321318

322-
By("Validating the 5th cluster has succeeded and 1st has completed and is waiting for next after stage tasks")
319+
By("Validating the 5th cluster has succeeded and 1st stage has completed and is waiting for AfterStageTasks")
323320
// 5th cluster succeeded.
324321
wantStatus.StagesStatus[0].Clusters[4].Conditions = append(wantStatus.StagesStatus[0].Clusters[4].Conditions, generateTrueCondition(updateRun, placementv1beta1.ClusterUpdatingConditionSucceeded))
325322
// Now waiting for after stage tasks of 1st stage.
@@ -355,9 +352,6 @@ var _ = Describe("UpdateRun execution tests - double stages", func() {
355352
approveClusterApprovalRequest(ctx, wantApprovalRequest.Name)
356353

357354
By("Validating both after stage tasks have completed and 2nd stage has started")
358-
// Timedwait afterStageTask completed.
359-
wantStatus.StagesStatus[0].AfterStageTaskStatus[0].Conditions = append(wantStatus.StagesStatus[0].AfterStageTaskStatus[0].Conditions,
360-
generateTrueCondition(updateRun, placementv1beta1.StageTaskConditionWaitTimeElapsed))
361355
// Approval afterStageTask completed.
362356
wantStatus.StagesStatus[0].AfterStageTaskStatus[1].Conditions = append(wantStatus.StagesStatus[0].AfterStageTaskStatus[1].Conditions,
363357
generateTrueCondition(updateRun, placementv1beta1.StageTaskConditionApprovalRequestApproved))
@@ -926,7 +920,7 @@ var _ = Describe("UpdateRun execution tests - single stage", func() {
926920
wantStatus = generateExecutionNotStartedStatus(updateRun, initialized)
927921
validateClusterStagedUpdateRunStatus(ctx, updateRun, wantStatus, "")
928922

929-
By("Validating the approvalRequest has been created")
923+
By("Validating the first beforeStage approvalRequest has been created")
930924
wantApprovalRequest = &placementv1beta1.ClusterApprovalRequest{
931925
ObjectMeta: metav1.ObjectMeta{
932926
Name: updateRun.Status.StagesStatus[0].BeforeStageTaskStatus[0].ApprovalRequestName,
@@ -1617,7 +1611,7 @@ var _ = Describe("UpdateRun execution tests - single stage", func() {
16171611
Expect(k8sClient.Create(ctx, updateRun)).To(Succeed())
16181612

16191613
By("Validating the initialization succeeded and the execution started")
1620-
initialized := generateSucceededInitializationStatusForSmallClusters(crp, updateRun, policySnapshot, updateStrategy)
1614+
initialized := generateSucceededInitializationStatusForSmallClusters(crp, updateRun, testResourceSnapshotIndex, policySnapshot, updateStrategy)
16211615
initialized.StagesStatus[0].BeforeStageTaskStatus[0].Conditions = append(initialized.StagesStatus[0].BeforeStageTaskStatus[0].Conditions,
16221616
generateTrueStageTaskCondition(updateRun, placementv1beta1.StageTaskConditionApprovalRequestCreated, true))
16231617
wantStatus = generateExecutionNotStartedStatus(updateRun, initialized)

pkg/controllers/updaterun/execution_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ limitations under the License.
1717
package updaterun
1818

1919
import (
20+
"context"
2021
"testing"
2122

2223
"github.com/google/go-cmp/cmp"
2324
"k8s.io/apimachinery/pkg/api/meta"
2425
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/apimachinery/pkg/runtime"
2527
"k8s.io/apimachinery/pkg/types"
28+
"sigs.k8s.io/controller-runtime/pkg/client"
29+
"sigs.k8s.io/controller-runtime/pkg/client/fake"
2630

2731
placementv1beta1 "github.com/kubefleet-dev/kubefleet/apis/placement/v1beta1"
2832
"github.com/kubefleet-dev/kubefleet/pkg/utils/condition"
@@ -398,3 +402,63 @@ func TestBuildApprovalRequestObject(t *testing.T) {
398402
})
399403
}
400404
}
405+
406+
func TestCheckBeforeStageTasksStatus_NegativeCases(t *testing.T) {
407+
tests := []struct {
408+
name string
409+
stageIndex int
410+
updateRun *placementv1beta1.ClusterStagedUpdateRun
411+
}{
412+
// Negative test cases only
413+
{
414+
name: "should return err if before stage task is TimedWait",
415+
stageIndex: 0,
416+
updateRun: &placementv1beta1.ClusterStagedUpdateRun{
417+
Status: placementv1beta1.UpdateRunStatus{
418+
UpdateStrategySnapshot: &placementv1beta1.UpdateStrategySpec{
419+
Stages: []placementv1beta1.StageConfig{
420+
{
421+
Name: "stage-0",
422+
BeforeStageTasks: []placementv1beta1.StageTask{
423+
{
424+
Type: placementv1beta1.StageTaskTypeTimedWait,
425+
},
426+
},
427+
},
428+
},
429+
},
430+
StagesStatus: []placementv1beta1.StageUpdatingStatus{
431+
{
432+
StageName: "stage-0",
433+
BeforeStageTaskStatus: []placementv1beta1.StageTaskStatus{
434+
{
435+
Type: placementv1beta1.StageTaskTypeTimedWait,
436+
},
437+
},
438+
},
439+
},
440+
},
441+
},
442+
},
443+
}
444+
for _, tt := range tests {
445+
t.Run(tt.name, func(t *testing.T) {
446+
objects := []client.Object{tt.updateRun}
447+
scheme := runtime.NewScheme()
448+
_ = placementv1beta1.AddToScheme(scheme)
449+
fakeClient := fake.NewClientBuilder().
450+
WithScheme(scheme).
451+
WithObjects(objects...).
452+
WithStatusSubresource(objects...).
453+
Build()
454+
r := Reconciler{
455+
Client: fakeClient,
456+
}
457+
ctx := context.Background()
458+
_, err := r.checkBeforeStageTasksStatus(ctx, tt.stageIndex, tt.updateRun)
459+
if err == nil {
460+
t.Fatalf("checkBeforeStageTasksStatus() expected error but got nil")
461+
}
462+
})
463+
}
464+
}

pkg/controllers/updaterun/initialization_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ var _ = Describe("Updaterun initialization tests", func() {
587587
Expect(k8sClient.Create(ctx, updateRun)).To(Succeed())
588588

589589
By("Validating the initialization succeeded")
590-
generateSucceededInitializationStatus(crp, updateRun, policySnapshot, updateStrategy, clusterResourceOverride)
590+
generateSucceededInitializationStatus(crp, updateRun, testResourceSnapshotIndex, policySnapshot, updateStrategy, clusterResourceOverride)
591591
})
592592
})
593593

pkg/utils/condition/reason.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -194,23 +194,20 @@ const (
194194
// ClusterUpdatingSucceededReason is the reason string of condition if the cluster updating succeeded.
195195
ClusterUpdatingSucceededReason = "ClusterUpdatingSucceeded"
196196

197-
// BeforeStageTaskApprovalRequestApprovedReason is the reason string of condition if the approval request for before stage task has been approved.
198-
BeforeStageTaskApprovalRequestApprovedReason = "BeforeStageTaskApprovalRequestApproved"
197+
// StageTaskApprovalRequestApprovedReason is the reason string of condition if the approval request for before or after stage task has been approved.
198+
StageTaskApprovalRequestApprovedReason = "StageTaskApprovalRequestApproved"
199199

200-
// BeforeStageTaskApprovalRequestCreatedReason is the reason string of condition if the approval request for before stage task has been created.
201-
BeforeStageTaskApprovalRequestCreatedReason = "BeforeStageTaskApprovalRequestCreated"
202-
203-
// AfterStageTaskApprovalRequestApprovedReason is the reason string of condition if the approval request for after stage task has been approved.
204-
AfterStageTaskApprovalRequestApprovedReason = "AfterStageTaskApprovalRequestApproved"
205-
206-
// AfterStageTaskApprovalRequestCreatedReason is the reason string of condition if the approval request for after stage task has been created.
207-
AfterStageTaskApprovalRequestCreatedReason = "AfterStageTaskApprovalRequestCreated"
200+
// StageTaskApprovalRequestCreatedReason is the reason string of condition if the approval request for beofre or after stage task has been created.
201+
StageTaskApprovalRequestCreatedReason = "StageTaskApprovalRequestCreated"
208202

209203
// AfterStageTaskWaitTimeElapsedReason is the reason string of condition if the wait time for after stage task has elapsed.
210204
AfterStageTaskWaitTimeElapsedReason = "AfterStageTaskWaitTimeElapsed"
211205

212206
// ApprovalRequestApprovalAcceptedReason is the reason string of condition if the approval of the approval request has been accepted.
213207
ApprovalRequestApprovalAcceptedReason = "ApprovalRequestApprovalAccepted"
208+
209+
// UpdateRunWaitingMessageFmt is the message format string of condition if the staged update run is waiting for stage tasks in a stage to complete.
210+
UpdateRunWaitingMessageFmt = "The updateRun is waiting for %s tasks in stage %s to complete"
214211
)
215212

216213
// A group of condition reason & message string which is used to populate the ClusterResourcePlacementEviction condition.

test/e2e/actuals_test.go

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2040,35 +2040,19 @@ func updateRunStageRolloutSucceedConditions(generation int64) []metav1.Condition
20402040
}
20412041
}
20422042

2043-
func updateRunStageTaskSucceedConditions(generation int64, taskType placementv1beta1.StageTaskType, isBeforeStage bool) []metav1.Condition {
2043+
func updateRunStageTaskSucceedConditions(generation int64, taskType placementv1beta1.StageTaskType) []metav1.Condition {
20442044
if taskType == placementv1beta1.StageTaskTypeApproval {
2045-
if isBeforeStage {
2046-
return []metav1.Condition{
2047-
{
2048-
Type: string(placementv1beta1.StageTaskConditionApprovalRequestCreated),
2049-
Status: metav1.ConditionTrue,
2050-
Reason: condition.BeforeStageTaskApprovalRequestCreatedReason,
2051-
ObservedGeneration: generation,
2052-
},
2053-
{
2054-
Type: string(placementv1beta1.StageTaskConditionApprovalRequestApproved),
2055-
Status: metav1.ConditionTrue,
2056-
Reason: condition.BeforeStageTaskApprovalRequestApprovedReason,
2057-
ObservedGeneration: generation,
2058-
},
2059-
}
2060-
}
20612045
return []metav1.Condition{
20622046
{
20632047
Type: string(placementv1beta1.StageTaskConditionApprovalRequestCreated),
20642048
Status: metav1.ConditionTrue,
2065-
Reason: condition.AfterStageTaskApprovalRequestCreatedReason,
2049+
Reason: condition.StageTaskApprovalRequestCreatedReason,
20662050
ObservedGeneration: generation,
20672051
},
20682052
{
20692053
Type: string(placementv1beta1.StageTaskConditionApprovalRequestApproved),
20702054
Status: metav1.ConditionTrue,
2071-
Reason: condition.AfterStageTaskApprovalRequestApprovedReason,
2055+
Reason: condition.StageTaskApprovalRequestApprovedReason,
20722056
ObservedGeneration: generation,
20732057
},
20742058
}
@@ -2200,15 +2184,15 @@ func buildStageUpdatingStatuses(
22002184
if task.Type == placementv1beta1.StageTaskTypeApproval {
22012185
stagesStatus[i].AfterStageTaskStatus[j].ApprovalRequestName = fmt.Sprintf(placementv1beta1.AfterStageApprovalTaskNameFmt, updateRun.GetName(), stage.Name)
22022186
}
2203-
stagesStatus[i].AfterStageTaskStatus[j].Conditions = updateRunStageTaskSucceedConditions(updateRun.GetGeneration(), task.Type, false)
2187+
stagesStatus[i].AfterStageTaskStatus[j].Conditions = updateRunStageTaskSucceedConditions(updateRun.GetGeneration(), task.Type)
22042188
}
22052189
stagesStatus[i].BeforeStageTaskStatus = make([]placementv1beta1.StageTaskStatus, len(stage.BeforeStageTasks))
22062190
for j, task := range stage.BeforeStageTasks {
22072191
stagesStatus[i].BeforeStageTaskStatus[j].Type = task.Type
22082192
if task.Type == placementv1beta1.StageTaskTypeApproval {
22092193
stagesStatus[i].BeforeStageTaskStatus[j].ApprovalRequestName = fmt.Sprintf(placementv1beta1.BeforeStageApprovalTaskNameFmt, updateRun.GetName(), stage.Name)
22102194
}
2211-
stagesStatus[i].BeforeStageTaskStatus[j].Conditions = updateRunStageTaskSucceedConditions(updateRun.GetGeneration(), task.Type, true)
2195+
stagesStatus[i].BeforeStageTaskStatus[j].Conditions = updateRunStageTaskSucceedConditions(updateRun.GetGeneration(), task.Type)
22122196
}
22132197
stagesStatus[i].Conditions = updateRunStageRolloutSucceedConditions(updateRun.GetGeneration())
22142198
}

test/e2e/cluster_staged_updaterun_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,16 @@ var _ = Describe("test CRP rollout with staged update run", func() {
215215
validateAndApproveClusterApprovalRequests(updateRunNames[1], envCanary)
216216
})
217217

218-
It("Should rollout resources to member-cluster-1 and member-cluster-3 too and complete the cluster staged update run successfully", func() {
218+
It("Should not rollout resources to prod stage until approved", func() {
219+
checkIfRemovedWorkResourcesFromMemberClustersConsistently([]*framework.Cluster{allMemberClusters[0], allMemberClusters[2]})
220+
})
221+
222+
It("Should rollout resources to all the members after approval and complete the cluster staged update run successfully", func() {
223+
validateAndApproveClusterApprovalRequests(updateRunNames[0], envProd)
224+
225+
By("Should rollout resources to member-cluster-1 first because of its name")
226+
checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[0]})
227+
219228
csurSucceededActual := clusterStagedUpdateRunStatusSucceededActual(updateRunNames[1], resourceSnapshotIndex2nd, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil)
220229
Eventually(csurSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s succeeded", updateRunNames[1])
221230
By("Verify that new the configmap is updated on all member clusters")

test/e2e/staged_updaterun_test.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,16 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem
137137
validateAndApproveNamespacedApprovalRequests(updateRunNames[0], testNamespace, envCanary)
138138
})
139139

140-
It("Should rollout resources to member-cluster-1 first because of its name", func() {
141-
checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[0]})
140+
It("Should not rollout resources to prod stage until approved", func() {
141+
checkIfRemovedConfigMapFromMemberClustersConsistently([]*framework.Cluster{allMemberClusters[0], allMemberClusters[2]})
142142
})
143143

144-
It("Should rollout resources to all the members and complete the staged update run successfully", func() {
144+
It("Should rollout resources to all the members after approval and complete the staged update run successfully", func() {
145+
validateAndApproveNamespacedApprovalRequests(updateRunNames[0], testNamespace, envProd)
146+
147+
By("Should rollout resources to member-cluster-1 first because of its name")
148+
checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[0]})
149+
145150
surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, resourceSnapshotIndex1st, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil)
146151
Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[0])
147152
checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters)
@@ -309,6 +314,9 @@ var _ = Describe("test RP rollout with staged update run", Label("resourceplacem
309314
It("Should rollout resources to all the members after approval and complete the staged update run successfully", func() {
310315
validateAndApproveNamespacedApprovalRequests(updateRunNames[0], testNamespace, envProd)
311316

317+
By("Should rollout resources to member-cluster-1 first because of its name")
318+
checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun([]*framework.Cluster{allMemberClusters[0]})
319+
312320
surSucceededActual := stagedUpdateRunStatusSucceededActual(updateRunNames[0], testNamespace, resourceSnapshotIndex1st, policySnapshotIndex1st, len(allMemberClusters), defaultApplyStrategy, &strategy.Spec, [][]string{{allMemberClusterNames[1]}, {allMemberClusterNames[0], allMemberClusterNames[2]}}, nil, nil, nil)
313321
Eventually(surSucceededActual, updateRunEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to validate updateRun %s/%s succeeded", testNamespace, updateRunNames[0])
314322
checkIfPlacedWorkResourcesOnMemberClustersInUpdateRun(allMemberClusters)

0 commit comments

Comments
 (0)