Skip to content

Commit e455804

Browse files
authored
Use watch after deleting objects in tests (GoogleContainerTools#583)
1 parent fc90b80 commit e455804

File tree

11 files changed

+72
-117
lines changed

11 files changed

+72
-117
lines changed

e2e/nomostest/clean.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func deleteTestObjectsAndWait(nt *NT) error {
160160
}
161161
}
162162
// Delete all objects in serial and wait for not found in parallel.
163-
return deleteObjectsAndWait(nt, objs...)
163+
return DeleteObjectsAndWait(nt, objs...)
164164
}
165165

166166
// deleteManagedNamespacesAndWait deletes all the namespaces managed by Config Sync.
@@ -229,7 +229,7 @@ func deleteNamespacesAndWait(nt *NT, nsList []corev1.Namespace) error {
229229
for i := range nsList {
230230
objs = append(objs, &nsList[i])
231231
}
232-
return deleteObjectsAndWait(nt, objs...)
232+
return DeleteObjectsAndWait(nt, objs...)
233233
}
234234

235235
func filterMutableListTypes(nt *NT) map[schema.GroupVersionKind]reflect.Type {
@@ -395,7 +395,7 @@ func deleteKubevirt(nt *NT) error {
395395
objs = append(objs, obj)
396396

397397
// Delete specified KubeVirt objects in parallel and wait for NotFound
398-
if err := deleteObjectsAndWait(nt, objs...); err != nil {
398+
if err := DeleteObjectsAndWait(nt, objs...); err != nil {
399399
return err
400400
}
401401

@@ -490,9 +490,9 @@ func deleteObject(nt *NT, obj client.Object) error {
490490
return nil
491491
}
492492

493-
// deleteObjectsAndWait deletes zero or more objects in serial and waits for not found in parallel.
493+
// DeleteObjectsAndWait deletes zero or more objects in serial and waits for not found in parallel.
494494
// NOTE: Deleting in parallel might be faster, but the log would be harder to debug.
495-
func deleteObjectsAndWait(nt *NT, objs ...client.Object) error {
495+
func DeleteObjectsAndWait(nt *NT, objs ...client.Object) error {
496496
tg := taskgroup.New()
497497
for _, obj := range objs {
498498
nn := client.ObjectKeyFromObject(obj)

e2e/nomostest/config_sync.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
corev1 "k8s.io/api/core/v1"
3131
rbacv1 "k8s.io/api/rbac/v1"
3232
apierrors "k8s.io/apimachinery/pkg/api/errors"
33-
"k8s.io/apimachinery/pkg/api/meta"
3433
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3534
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3635
"k8s.io/apimachinery/pkg/types"
@@ -178,14 +177,7 @@ func uninstallConfigSync(nt *NT) error {
178177
if err != nil {
179178
return err
180179
}
181-
for _, o := range objs {
182-
if err := nt.KubeClient.Delete(o); err != nil {
183-
if !apierrors.IsNotFound(err) && !meta.IsNoMatchError(err) {
184-
return err
185-
}
186-
}
187-
}
188-
return nil
180+
return DeleteObjectsAndWait(nt, objs...)
189181
}
190182

191183
func isPSPCluster() bool {

e2e/nomostest/reset.go

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ func ResetRepoSyncs(nt *NT, rsList []v1beta1.RepoSync) error {
298298
if err != nil {
299299
return err
300300
}
301-
if err := batchDeleteAndWait(nt, rbs...); err != nil {
301+
if err := DeleteObjectsAndWait(nt, rbs...); err != nil {
302302
return err
303303
}
304304

@@ -316,7 +316,7 @@ func ResetRepoSyncs(nt *NT, rsList []v1beta1.RepoSync) error {
316316
if err != nil {
317317
return err
318318
}
319-
if err := batchDeleteAndWait(nt, crbs...); err != nil {
319+
if err := DeleteObjectsAndWait(nt, crbs...); err != nil {
320320
return err
321321
}
322322

@@ -361,7 +361,7 @@ func ResetNamespaces(nt *NT, nsList []corev1.Namespace) error {
361361
// reconcilers, if it exists.
362362
func deleteRepoSyncClusterRole(nt *NT) error {
363363
nt.T.Log("[RESET] Deleting RepoSync ClusterRole")
364-
return batchDeleteAndWait(nt, nt.RepoSyncClusterRole())
364+
return DeleteObjectsAndWait(nt, nt.RepoSyncClusterRole())
365365
}
366366

367367
func findUnmanaged(nt *NT, objs ...client.Object) ([]client.Object, error) {
@@ -378,28 +378,6 @@ func findUnmanaged(nt *NT, objs ...client.Object) ([]client.Object, error) {
378378
return unmanaged, nil
379379
}
380380

381-
func batchDeleteAndWait(nt *NT, objs ...client.Object) error {
382-
for _, obj := range objs {
383-
if err := nt.KubeClient.Delete(obj); err != nil {
384-
if !apierrors.IsNotFound(err) {
385-
return err
386-
}
387-
}
388-
}
389-
tg := taskgroup.New()
390-
for _, obj := range objs {
391-
gvk, err := kinds.Lookup(obj, nt.Scheme)
392-
if err != nil {
393-
return err
394-
}
395-
nn := client.ObjectKeyFromObject(obj)
396-
tg.Go(func() error {
397-
return nt.Watcher.WatchForNotFound(gvk, nn.Name, nn.Namespace)
398-
})
399-
}
400-
return tg.Wait()
401-
}
402-
403381
func listRootSyncs(nt *NT, opts ...client.ListOption) (*v1beta1.RootSyncList, error) {
404382
rsList := &v1beta1.RootSyncList{}
405383
opts = append(opts, withLabelListOption(testkubeclient.TestLabel, testkubeclient.TestLabelValue))

e2e/nomostest/wait_for_sync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func syncDirectory(syncDirectoryMap map[types.NamespacedName]string, nn types.Na
106106
// WatchForAllSyncs calls WatchForSync on all Syncs in nt.RootRepos & nt.NonRootRepos.
107107
//
108108
// If you want to validate specific fields of a Sync object, use
109-
// nomostest.WatchObject() instead.
109+
// nt.Watcher.WatchObject() instead.
110110
func (nt *NT) WatchForAllSyncs(options ...WatchForAllSyncsOptions) error {
111111
waitForRepoSyncsOptions := watchForAllSyncsOptions{
112112
timeout: nt.DefaultWaitTimeout,

e2e/testcases/basic_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ func manageNamespace(nt *nomostest.NT, namespace string) {
178178
}
179179

180180
nt.T.Cleanup(func() {
181-
if err := nt.KubeClient.Delete(fake.ServiceObject(core.Name("some-other-service"), core.Namespace(namespace))); err != nil {
181+
svcObj := fake.ServiceObject(core.Name("some-other-service"), core.Namespace(namespace))
182+
if err := nomostest.DeleteObjectsAndWait(nt, svcObj); err != nil {
182183
nt.T.Fatal(err)
183184
}
184185
})

e2e/testcases/kcc_test.go

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,14 @@ import (
1818
"fmt"
1919
"testing"
2020

21-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2221
"k8s.io/apimachinery/pkg/runtime/schema"
2322
"k8s.io/apimachinery/pkg/types"
2423
"kpt.dev/configsync/e2e/nomostest"
2524
"kpt.dev/configsync/e2e/nomostest/ntopts"
25+
"kpt.dev/configsync/e2e/nomostest/taskgroup"
2626
nomostesting "kpt.dev/configsync/e2e/nomostest/testing"
27-
"kpt.dev/configsync/e2e/nomostest/testpredicates"
2827
"kpt.dev/configsync/pkg/api/configsync"
2928
"kpt.dev/configsync/pkg/testing/fake"
30-
"sigs.k8s.io/controller-runtime/pkg/client"
3129
)
3230

3331
// This file includes tests for KCC resources from a cloud source repository.
@@ -72,10 +70,24 @@ func TestKCCResourcesOnCSR(t *testing.T) {
7270
Version: "v1beta1",
7371
Kind: "IAMPolicyMember",
7472
}
75-
validateKCCResourceReady(nt, gvkPubSubTopic, "test-cs", "foo")
76-
validateKCCResourceReady(nt, gvkPubSubSubscription, "test-cs-read", "foo")
77-
validateKCCResourceReady(nt, gvkServiceAccount, "pubsub-app", "foo")
78-
validateKCCResourceReady(nt, gvkPolicyMember, "policy-member-binding", "foo")
73+
74+
// Wait until all objects are reconciled
75+
tg := taskgroup.New()
76+
tg.Go(func() error {
77+
return nt.Watcher.WatchForCurrentStatus(gvkPubSubTopic, "test-cs", "foo")
78+
})
79+
tg.Go(func() error {
80+
return nt.Watcher.WatchForCurrentStatus(gvkPubSubSubscription, "test-cs-read", "foo")
81+
})
82+
tg.Go(func() error {
83+
return nt.Watcher.WatchForCurrentStatus(gvkServiceAccount, "pubsub-app", "foo")
84+
})
85+
tg.Go(func() error {
86+
return nt.Watcher.WatchForCurrentStatus(gvkPolicyMember, "policy-member-binding", "foo")
87+
})
88+
if err := tg.Wait(); err != nil {
89+
nt.T.Fatal(err)
90+
}
7991

8092
// Remove the kcc resources
8193
nt.T.Log("sync to an empty directory from a CSR repo")
@@ -89,43 +101,21 @@ func TestKCCResourcesOnCSR(t *testing.T) {
89101
nt.T.Fatal(err)
90102
}
91103

92-
// Verify that the GCP resources are removed.
93-
validateKCCResourceNotFound(nt, gvkPubSubTopic, "test-cs", "foo")
94-
validateKCCResourceNotFound(nt, gvkPubSubSubscription, "test-cs-read", "foo")
95-
validateKCCResourceNotFound(nt, gvkServiceAccount, "pubsub-app", "foo")
96-
validateKCCResourceNotFound(nt, gvkPolicyMember, "policy-member-binding", "foo")
97-
}
98-
99-
func validateKCCResourceReady(nt *nomostest.NT, gvk schema.GroupVersionKind, name, namespace string) {
100-
nomostest.Wait(nt.T, fmt.Sprintf("wait for kcc resources %q %v to be ready", name, gvk),
101-
nt.DefaultWaitTimeout, func() error {
102-
u := &unstructured.Unstructured{}
103-
u.SetGroupVersionKind(gvk)
104-
return nt.Validate(name, namespace, u, kccResourceReady)
105-
})
106-
}
107-
108-
func kccResourceReady(o client.Object) error {
109-
if o == nil {
110-
return testpredicates.ErrObjectNotFound
111-
}
112-
u := o.(*unstructured.Unstructured)
113-
conditions, found, err := unstructured.NestedSlice(u.Object, "status", "conditions")
114-
if err != nil || !found || len(conditions) == 0 {
115-
return fmt.Errorf(".status.conditions not found %v", err)
116-
}
117-
condition := (conditions[0]).(map[string]interface{})
118-
if condition["type"] != "Ready" || condition["status"] != "True" {
119-
return fmt.Errorf("resource is not ready %v", condition)
104+
// Wait until all objects are not found
105+
tg = taskgroup.New()
106+
tg.Go(func() error {
107+
return nt.Watcher.WatchForNotFound(gvkPubSubTopic, "test-cs", "foo")
108+
})
109+
tg.Go(func() error {
110+
return nt.Watcher.WatchForNotFound(gvkPubSubSubscription, "test-cs-read", "foo")
111+
})
112+
tg.Go(func() error {
113+
return nt.Watcher.WatchForNotFound(gvkServiceAccount, "pubsub-app", "foo")
114+
})
115+
tg.Go(func() error {
116+
return nt.Watcher.WatchForNotFound(gvkPolicyMember, "policy-member-binding", "foo")
117+
})
118+
if err := tg.Wait(); err != nil {
119+
nt.T.Fatal(err)
120120
}
121-
return nil
122-
}
123-
124-
func validateKCCResourceNotFound(nt *nomostest.NT, gvk schema.GroupVersionKind, name, namespace string) {
125-
nomostest.Wait(nt.T, fmt.Sprintf("wait for %q %v to terminate", name, gvk),
126-
nt.DefaultWaitTimeout, func() error {
127-
u := &unstructured.Unstructured{}
128-
u.SetGroupVersionKind(gvk)
129-
return nt.ValidateNotFound(name, namespace, u)
130-
})
131121
}

e2e/testcases/multi_sync_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ func TestControllerValidationErrors(t *testing.T) {
773773
nt.T.Fatal(err)
774774
}
775775
t.Cleanup(func() {
776-
if err := nt.KubeClient.Delete(testNamespace); err != nil {
776+
if err := nomostest.DeleteObjectsAndWait(nt, testNamespace); err != nil {
777777
nt.T.Fatal(err)
778778
}
779779
})
@@ -794,7 +794,7 @@ func TestControllerValidationErrors(t *testing.T) {
794794
}
795795
nt.WaitForRootSyncStalledError(rootSync.Namespace, rootSync.Name, "Validation", "RootSync objects are only allowed in the config-management-system namespace, not in test-ns")
796796
t.Cleanup(func() {
797-
if err := nt.KubeClient.Delete(rootSync); err != nil {
797+
if err := nomostest.DeleteObjectsAndWait(nt, rootSync); err != nil {
798798
nt.T.Fatal(err)
799799
}
800800
})
@@ -805,7 +805,7 @@ func TestControllerValidationErrors(t *testing.T) {
805805
nt.T.Fatal(err)
806806
}
807807
nt.WaitForRepoSyncStalledError(rs.Namespace, rs.Name, "Validation", "RepoSync objects are not allowed in the config-management-system namespace")
808-
if err := nt.KubeClient.Delete(rs); err != nil {
808+
if err := nomostest.DeleteObjectsAndWait(nt, rs); err != nil {
809809
nt.T.Fatal(err)
810810
}
811811

@@ -823,7 +823,7 @@ func TestControllerValidationErrors(t *testing.T) {
823823
fmt.Sprintf(`Invalid reconciler name "ns-reconciler-%s-%s-%d": must be no more than %d characters.`,
824824
testNs, veryLongName, len(veryLongName), validation.DNS1123SubdomainMaxLength))
825825
t.Cleanup(func() {
826-
if err := nt.KubeClient.Delete(rs); err != nil {
826+
if err := nomostest.DeleteObjectsAndWait(nt, rs); err != nil {
827827
nt.T.Fatal(err)
828828
}
829829
})
@@ -838,7 +838,7 @@ func TestControllerValidationErrors(t *testing.T) {
838838
fmt.Sprintf(`The managed secret name "ns-reconciler-%s-%s-%d-%s" is invalid: must be no more than %d characters. To fix it, update '.spec.git.secretRef.name'`,
839839
testNs, rsInvalidSecretRef.Name, len(rsInvalidSecretRef.Name), v1beta1.GetSecretName(rsInvalidSecretRef.Spec.SecretRef), validation.DNS1123SubdomainMaxLength))
840840
t.Cleanup(func() {
841-
if err := nt.KubeClient.Delete(rsInvalidSecretRef); err != nil {
841+
if err := nomostest.DeleteObjectsAndWait(nt, rsInvalidSecretRef); err != nil {
842842
nt.T.Fatal(err)
843843
}
844844
})

e2e/testcases/namespace_repo_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,8 @@ func TestDeleteRepoSync_Delegated_AndRepoSyncV1Alpha1(t *testing.T) {
193193
}
194194
secretNames := getNsReconcilerSecrets(nt, bsNamespace)
195195

196-
// Delete RepoSync custom resource from the cluster.
197-
err := nt.KubeClient.Delete(&rs)
198-
if err != nil {
199-
nt.T.Fatalf("RepoSync delete failed: %v", err)
196+
if err := nomostest.DeleteObjectsAndWait(nt, &rs); err != nil {
197+
nt.T.Fatal(err)
200198
}
201199

202200
checkRepoSyncResourcesNotPresent(nt, bsNamespace, secretNames)

e2e/testcases/namespaces_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -820,10 +820,8 @@ func checkpointProtectedNamespace(nt *nomostest.NT, namespace string) {
820820
if apierrors.IsNotFound(err) {
821821
nt.T.Cleanup(func() {
822822
// Revert to initial state (not found).
823-
if err := nt.KubeClient.Delete(nsObj); err != nil {
824-
if !apierrors.IsNotFound(err) {
825-
nt.T.Errorf("Failed to revert %q namespace: %v", namespace, err)
826-
}
823+
if err := nomostest.DeleteObjectsAndWait(nt, nsObj); err != nil {
824+
nt.T.Fatal(err)
827825
}
828826
})
829827
return

e2e/testcases/oci_sync_test.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,19 @@ func TestSwitchFromGitToOci(t *testing.T) {
325325
nt.T.Fatal(err)
326326
}
327327

328+
// To facilitate cleanup, add the implicit namespace explicitly.
329+
// Otherwise, the reconciler finalizer will skip deleting the implicit
330+
// namespace, because it has the PreventDeletion annotation.
331+
t.Cleanup(func() {
332+
implictNs := &corev1.Namespace{}
333+
implictNs.Name = namespace
334+
nt.Must(nt.RootRepos[configsync.RootSyncName].Add(repoResourcePath, implictNs))
335+
nt.Must(nt.RootRepos[configsync.RootSyncName].CommitAndPush("add implicit namespace explicitly"))
336+
if err := nt.WatchForAllSyncs(); err != nil {
337+
nt.T.Fatal(err)
338+
}
339+
})
340+
328341
// Verify the central controlled configuration: switch from Git to OCI
329342
// Backward compatibility check. Previously managed RepoSync objects without sourceType should still work.
330343
nt.T.Log("Add the RepoSync object to the Root Repo")
@@ -457,14 +470,6 @@ func TestSwitchFromGitToOci(t *testing.T) {
457470
nt.T.Log("Manually patch RepoSync object to miss OCI spec when sourceType is oci")
458471
nt.MustMergePatch(rs, `{"spec":{"sourceType":"oci"}}`)
459472
nt.WaitForRepoSyncStalledError(namespace, configsync.RepoSyncName, "Validation", `KNV1061: RepoSyncs must specify spec.oci when spec.sourceType is "oci"`)
460-
461-
// Stop the Config Sync webhook to delete the implicit namespace manually
462-
nomostest.StopWebhook(nt)
463-
if err := nt.KubeClient.Delete(implictNs); err != nil {
464-
{
465-
nt.T.Error(err)
466-
}
467-
}
468473
}
469474

470475
func parseObjectFromFile(nt *nomostest.NT, absPath string) (client.Object, error) {

e2e/testcases/root_sync_test.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,13 @@ import (
4848
func TestDeleteRootSyncAndRootSyncV1Alpha1(t *testing.T) {
4949
nt := nomostest.New(t, nomostesting.ACMController)
5050

51-
var rs v1beta1.RootSync
52-
err := nt.Validate(configsync.RootSyncName, v1.NSConfigManagementSystem, &rs)
51+
rs := &v1beta1.RootSync{}
52+
err := nt.Validate(configsync.RootSyncName, v1.NSConfigManagementSystem, rs)
5353
if err != nil {
5454
nt.T.Fatal(err)
5555
}
5656

57-
// Delete RootSync custom resource from the cluster.
58-
err = nt.KubeClient.Delete(&rs)
59-
if err != nil {
60-
nt.T.Fatalf("deleting RootSync: %v", err)
61-
}
62-
63-
// Verify RootSync no longer present.
64-
if err := nt.Watcher.WatchForNotFound(kinds.RootSyncV1Beta1(), rs.GetName(), rs.GetNamespace()); err != nil {
57+
if err := nomostest.DeleteObjectsAndWait(nt, rs); err != nil {
6558
nt.T.Fatal(err)
6659
}
6760

0 commit comments

Comments
 (0)