Skip to content

Commit 3b52f39

Browse files
committed
cgu: added WaitUntilClusterInState and unit tests
This PR adds a few methods to allow waiting on the batch remediation progress for individual clusters on the CGU. Unit tests for these new methods are included.
1 parent c42686d commit 3b52f39

File tree

2 files changed

+229
-0
lines changed

2 files changed

+229
-0
lines changed

pkg/cgu/cgu.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,71 @@ func (builder *CguBuilder) WaitUntilComplete(timeout time.Duration) (*CguBuilder
396396
return builder.WaitForCondition(conditionComplete, timeout)
397397
}
398398

399+
// WaitUntilClusterInState waits the specified timeout for a cluster in the CGU to be in the specified state.
400+
func (builder *CguBuilder) WaitUntilClusterInState(cluster, state string, timeout time.Duration) (*CguBuilder, error) {
401+
if valid, err := builder.validate(); !valid {
402+
return nil, err
403+
}
404+
405+
if cluster == "" {
406+
glog.V(100).Info("Cluster name cannot be empty")
407+
408+
return nil, fmt.Errorf("cluster name cannot be empty")
409+
}
410+
411+
if state == "" {
412+
glog.V(100).Info("State cannot be empty")
413+
414+
return nil, fmt.Errorf("state cannot be empty")
415+
}
416+
417+
glog.V(100).Infof(
418+
"Waiting until cluster %s on CGU %s in namespace %s is in state %s",
419+
cluster, builder.Definition.Name, builder.Definition.Namespace, state)
420+
421+
if !builder.Exists() {
422+
return nil, fmt.Errorf(
423+
"cgu object %s does not exist in namespace %s", builder.Definition.Name, builder.Definition.Namespace)
424+
}
425+
426+
var err error
427+
err = wait.PollUntilContextTimeout(
428+
context.TODO(), 3*time.Second, timeout, true, func(ctx context.Context) (bool, error) {
429+
builder.Object, err = builder.apiClient.RanV1alpha1().ClusterGroupUpgrades(builder.Definition.Namespace).
430+
Get(context.TODO(), builder.Definition.Name, metav1.GetOptions{})
431+
if err != nil {
432+
return false, nil
433+
}
434+
435+
status, ok := builder.Object.Status.Status.CurrentBatchRemediationProgress[cluster]
436+
if !ok {
437+
glog.V(100).Infof(
438+
"cluster %s not found in batch remediation progress for cgu %s in namespace %s",
439+
cluster, builder.Definition.Name, builder.Definition.Namespace)
440+
441+
return false, nil
442+
}
443+
444+
return status.State == state, nil
445+
})
446+
447+
if err != nil {
448+
return nil, err
449+
}
450+
451+
return builder, nil
452+
}
453+
454+
// WaitUntilClusterComplete waits the specified timeout for a cluster in the CGU to complete remidation.
455+
func (builder *CguBuilder) WaitUntilClusterComplete(cluster string, timeout time.Duration) (*CguBuilder, error) {
456+
return builder.WaitUntilClusterInState(cluster, v1alpha1.Completed, timeout)
457+
}
458+
459+
// WaitUntilClusterInProgress waits the specified timeout for a cluster in the CGU to start remidation.
460+
func (builder *CguBuilder) WaitUntilClusterInProgress(cluster string, timeout time.Duration) (*CguBuilder, error) {
461+
return builder.WaitUntilClusterInState(cluster, v1alpha1.InProgress, timeout)
462+
}
463+
399464
// WaitUntilBackupStarts waits the specified timeout for the backup to start.
400465
func (builder *CguBuilder) WaitUntilBackupStarts(timeout time.Duration) (*CguBuilder, error) {
401466
if valid, err := builder.validate(); !valid {

pkg/cgu/cgu_test.go

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ var (
1717
defaultCguName = "cgu-test"
1818
defaultCguNsName = "test-ns"
1919
defaultCguMaxConcurrency = 1
20+
defaultCguClusterName = "test-cluster"
21+
defaultCguClusterState = v1alpha1.NotStarted
2022
defaultCguCondition = conditionComplete
2123
)
2224

@@ -551,6 +553,168 @@ func TestCguWaitUntilComplete(t *testing.T) {
551553
}
552554
}
553555

556+
func TestCguWaitUntilClusterInState(t *testing.T) {
557+
testCases := []struct {
558+
cluster string
559+
state string
560+
exists bool
561+
inState bool
562+
valid bool
563+
expectedError error
564+
}{
565+
{
566+
cluster: defaultCguClusterName,
567+
state: defaultCguClusterState,
568+
exists: true,
569+
inState: true,
570+
valid: true,
571+
expectedError: nil,
572+
},
573+
{
574+
cluster: "",
575+
state: defaultCguClusterState,
576+
exists: true,
577+
inState: true,
578+
valid: true,
579+
expectedError: fmt.Errorf("cluster name cannot be empty"),
580+
},
581+
{
582+
cluster: defaultCguClusterName,
583+
state: "",
584+
exists: true,
585+
inState: true,
586+
valid: true,
587+
expectedError: fmt.Errorf("state cannot be empty"),
588+
},
589+
{
590+
cluster: defaultCguClusterName,
591+
state: defaultCguClusterState,
592+
exists: false,
593+
inState: true,
594+
valid: true,
595+
expectedError: fmt.Errorf("cgu object %s does not exist in namespace %s", defaultCguName, defaultCguNsName),
596+
},
597+
{
598+
cluster: defaultCguClusterName,
599+
state: defaultCguClusterState,
600+
exists: true,
601+
inState: false,
602+
valid: true,
603+
expectedError: context.DeadlineExceeded,
604+
},
605+
{
606+
cluster: defaultCguClusterName,
607+
state: defaultCguClusterState,
608+
exists: true,
609+
inState: true,
610+
valid: false,
611+
expectedError: fmt.Errorf("CGU 'nsname' cannot be empty"),
612+
},
613+
}
614+
615+
for _, testCase := range testCases {
616+
var (
617+
runtimeObjects []runtime.Object
618+
cguBuilder *CguBuilder
619+
)
620+
621+
if testCase.exists {
622+
cgu := buildDummyCgu(defaultCguName, defaultCguNsName, defaultCguMaxConcurrency)
623+
624+
if testCase.inState {
625+
cgu.Status.Status.CurrentBatchRemediationProgress = map[string]*v1alpha1.ClusterRemediationProgress{
626+
testCase.cluster: {State: testCase.state},
627+
}
628+
}
629+
630+
runtimeObjects = append(runtimeObjects, cgu)
631+
}
632+
633+
testSettings := clients.GetTestClients(clients.TestClientParams{
634+
K8sMockObjects: runtimeObjects,
635+
})
636+
637+
if testCase.valid {
638+
cguBuilder = buildValidCguTestBuilder(testSettings)
639+
} else {
640+
cguBuilder = buildInvalidCguTestBuilder(testSettings)
641+
}
642+
643+
_, err := cguBuilder.WaitUntilClusterInState(testCase.cluster, testCase.state, time.Second)
644+
assert.Equal(t, testCase.expectedError, err)
645+
}
646+
}
647+
648+
func TestCguWaitUntilClusterComplete(t *testing.T) {
649+
testCases := []struct {
650+
complete bool
651+
expectedError error
652+
}{
653+
{
654+
complete: true,
655+
expectedError: nil,
656+
},
657+
{
658+
complete: false,
659+
expectedError: context.DeadlineExceeded,
660+
},
661+
}
662+
663+
for _, testCase := range testCases {
664+
cgu := buildDummyCgu(defaultCguName, defaultCguNsName, defaultCguMaxConcurrency)
665+
666+
if testCase.complete {
667+
cgu.Status.Status.CurrentBatchRemediationProgress = map[string]*v1alpha1.ClusterRemediationProgress{
668+
defaultCguClusterName: {State: v1alpha1.Completed},
669+
}
670+
}
671+
672+
testSettings := clients.GetTestClients(clients.TestClientParams{
673+
K8sMockObjects: []runtime.Object{cgu},
674+
})
675+
676+
cguBuilder := buildValidCguTestBuilder(testSettings)
677+
_, err := cguBuilder.WaitUntilClusterComplete(defaultCguClusterName, time.Second)
678+
679+
assert.Equal(t, testCase.expectedError, err)
680+
}
681+
}
682+
683+
func TestCguWaitUntilClusterInProgress(t *testing.T) {
684+
testCases := []struct {
685+
inProgress bool
686+
expectedError error
687+
}{
688+
{
689+
inProgress: true,
690+
expectedError: nil,
691+
},
692+
{
693+
inProgress: false,
694+
expectedError: context.DeadlineExceeded,
695+
},
696+
}
697+
698+
for _, testCase := range testCases {
699+
cgu := buildDummyCgu(defaultCguName, defaultCguNsName, defaultCguMaxConcurrency)
700+
701+
if testCase.inProgress {
702+
cgu.Status.Status.CurrentBatchRemediationProgress = map[string]*v1alpha1.ClusterRemediationProgress{
703+
defaultCguClusterName: {State: v1alpha1.InProgress},
704+
}
705+
}
706+
707+
testSettings := clients.GetTestClients(clients.TestClientParams{
708+
K8sMockObjects: []runtime.Object{cgu},
709+
})
710+
711+
cguBuilder := buildValidCguTestBuilder(testSettings)
712+
_, err := cguBuilder.WaitUntilClusterInProgress(defaultCguClusterName, time.Second)
713+
714+
assert.Equal(t, testCase.expectedError, err)
715+
}
716+
}
717+
554718
func TestWaitUntilBackupStarts(t *testing.T) {
555719
cguObject := buildDummyCgu(defaultCguName, defaultCguNsName, defaultCguMaxConcurrency)
556720
cguObject.Status.Backup = &v1alpha1.BackupStatus{}

0 commit comments

Comments
 (0)