Skip to content

Commit 25f73b2

Browse files
committed
test: add ResourceGroup assertions to WatchForSync
This adds validation for the ResourceGroup status in the WatchForSync function, which is used extensively in the test framework to validate RSyncs and wait for them to finish syncing. This will cause WatchForSync to now also wait for all synced objects to reconcile and for the ResourceGroup to be current. This is intended to provide test coverage for the resource-group-controller when integrated with Config Sync.
1 parent 9eae3e6 commit 25f73b2

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

e2e/nomostest/sync.go

+52
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import (
2121
"kpt.dev/configsync/e2e/nomostest/testpredicates"
2222
"kpt.dev/configsync/pkg/api/configsync"
2323
"kpt.dev/configsync/pkg/api/configsync/v1beta1"
24+
"kpt.dev/configsync/pkg/api/kpt.dev/v1alpha1"
2425
"kpt.dev/configsync/pkg/parse"
2526
"kpt.dev/configsync/pkg/reposync"
27+
"kpt.dev/configsync/pkg/resourcegroup/controllers/status"
2628
"kpt.dev/configsync/pkg/rootsync"
2729
"kpt.dev/configsync/pkg/util/log"
2830
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -263,3 +265,53 @@ func statusHasSyncDirAndNoErrors(status v1beta1.Status, sourceType configsync.So
263265
}
264266
return nil
265267
}
268+
269+
func resourceGroupHasReconciled(sourceHash string) testpredicates.Predicate {
270+
return func(o client.Object) error {
271+
if o == nil {
272+
return testpredicates.ErrObjectNotFound
273+
}
274+
rg, ok := o.(*v1alpha1.ResourceGroup)
275+
if !ok {
276+
return testpredicates.WrongTypeErr(o, &v1alpha1.ResourceGroup{})
277+
}
278+
279+
if len(rg.Spec.Resources) != len(rg.Status.ResourceStatuses) {
280+
return fmt.Errorf("length of spec.resources (%d) does not equal length of status.resourceStatuses (%d)",
281+
len(rg.Spec.Resources), len(rg.Status.ResourceStatuses))
282+
}
283+
284+
resourceCount := make(map[v1alpha1.ObjMetadata]int)
285+
for _, s := range rg.Status.ResourceStatuses {
286+
if err := resourceStatusIsCurrent(s, sourceHash); err != nil {
287+
return fmt.Errorf("object %s is not current: %w", s.ObjMetadata, err)
288+
}
289+
resourceCount[s.ObjMetadata]++
290+
}
291+
292+
for _, o := range rg.Spec.Resources {
293+
if count, ok := resourceCount[o]; ok && count > 0 {
294+
resourceCount[o]--
295+
} else {
296+
return fmt.Errorf("spec.resources does not equal status.resourceStatuses")
297+
}
298+
}
299+
return nil
300+
}
301+
}
302+
303+
func resourceStatusIsCurrent(rs v1alpha1.ResourceStatus, sourceHash string) error {
304+
if rs.Status != v1alpha1.Current {
305+
return fmt.Errorf("resourceStatus.status is not %s. Got %s", v1alpha1.Current, rs.Status)
306+
}
307+
if rs.Reconcile != v1alpha1.ReconcileSucceeded {
308+
return fmt.Errorf("resourceStatus.reconcile is not %s. Got %s", v1alpha1.ReconcileSucceeded, rs.Reconcile)
309+
}
310+
if rs.Actuation != v1alpha1.ActuationSucceeded {
311+
return fmt.Errorf("resourceStatus.actuation is not %s. Got %s", v1alpha1.ActuationSucceeded, rs.Actuation)
312+
}
313+
if rs.SourceHash != status.TruncateSourceHash(sourceHash) {
314+
return fmt.Errorf("resourceStatus.sourceHash is not %s. Got %s", sourceHash, rs.SourceHash)
315+
}
316+
return nil
317+
}

e2e/nomostest/wait_for_sync.go

+11
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,17 @@ func (nt *NT) WatchForSync(
229229
return fmt.Errorf("waiting for sync: %w", err)
230230
}
231231
nt.T.Logf("%s %s/%s is synced", gvk.Kind, namespace, name)
232+
rgPredicates := []testpredicates.Predicate{
233+
// Wait until status.observedGeneration matches metadata.generation
234+
testpredicates.HasObservedLatestGeneration(nt.Scheme),
235+
// Wait until metadata.deletionTimestamp is missing, and conditions do not iniclude Reconciling=True or Stalled=True
236+
testpredicates.StatusEquals(nt.Scheme, kstatus.CurrentStatus),
237+
// Wait until all resourceStatuses are consistent with spec and current/reconciled
238+
resourceGroupHasReconciled(expectedCommit),
239+
}
240+
if err := nt.Watcher.WatchObject(kinds.ResourceGroup(), name, namespace, testwatcher.WatchPredicates(rgPredicates...)); err != nil {
241+
return fmt.Errorf("waiting for ResourceGroup: %w", err)
242+
}
232243
return nil
233244
}
234245

pkg/resourcegroup/controllers/status/status.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ func GetSourceHash(annotations map[string]string) string {
133133
if len(annotations) == 0 {
134134
return ""
135135
}
136-
sourceHash := annotations[SourceHashAnnotationKey]
136+
return TruncateSourceHash(annotations[SourceHashAnnotationKey])
137+
}
138+
139+
// TruncateSourceHash truncates the provided source hash after the first 7 characters.
140+
func TruncateSourceHash(sourceHash string) string {
137141
if len(sourceHash) > 7 {
138142
return sourceHash[0:7]
139143
}

0 commit comments

Comments
 (0)