Skip to content

Commit d940463

Browse files
committed
Use a separate namespace for each e2e test
Fixes #1307 Create and use a new namespace for every e2e test. This means that extension resources are placed in their own namespace. The tests deletes the namespace, and then waits until completion. This ensures that _most_ of an extension's resources are deleted. It does not guarantee that global resources (e.g. CRDs, CRs, CRBs) are deleted, but it improves the tests, and would eventually allow the tests to be run in parallel (assuming the installed extensions allow for that). Signed-off-by: Todd Short <[email protected]>
1 parent 6bda277 commit d940463

File tree

2 files changed

+99
-33
lines changed

2 files changed

+99
-33
lines changed

test/e2e/cluster_extension_install_test.go

Lines changed: 97 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ import (
1717
appsv1 "k8s.io/api/apps/v1"
1818
corev1 "k8s.io/api/core/v1"
1919
rbacv1 "k8s.io/api/rbac/v1"
20+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2021
"k8s.io/apimachinery/pkg/api/errors"
2122
apimeta "k8s.io/apimachinery/pkg/api/meta"
2223
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24+
"k8s.io/apimachinery/pkg/labels"
2325
"k8s.io/apimachinery/pkg/types"
2426
"k8s.io/apimachinery/pkg/util/rand"
2527
kubeclient "k8s.io/client-go/kubernetes"
@@ -38,6 +40,20 @@ const (
3840
var pollDuration = time.Minute
3941
var pollInterval = time.Second
4042

43+
func createNamespace(ctx context.Context) (*corev1.Namespace, error) {
44+
namespaceName := fmt.Sprintf("namespace-%s", rand.String(8))
45+
ns := &corev1.Namespace{
46+
ObjectMeta: metav1.ObjectMeta{
47+
Name: namespaceName,
48+
},
49+
}
50+
err := c.Create(ctx, ns)
51+
if err != nil {
52+
return nil, err
53+
}
54+
return ns, nil
55+
}
56+
4157
func createServiceAccount(ctx context.Context, name types.NamespacedName, clusterExtensionName string) (*corev1.ServiceAccount, error) {
4258
sa := &corev1.ServiceAccount{
4359
ObjectMeta: metav1.ObjectMeta{
@@ -177,8 +193,12 @@ func createClusterRoleAndBindingForSA(ctx context.Context, name string, sa *core
177193
return nil
178194
}
179195

180-
func testInit(t *testing.T) (*ocv1alpha1.ClusterExtension, *catalogd.ClusterCatalog, *corev1.ServiceAccount) {
196+
func testInit(t *testing.T) (*ocv1alpha1.ClusterExtension, *catalogd.ClusterCatalog, *corev1.ServiceAccount, *corev1.Namespace) {
181197
var err error
198+
199+
ns, err := createNamespace(context.Background())
200+
require.NoError(t, err)
201+
182202
extensionCatalog, err := createTestCatalog(context.Background(), testCatalogName, os.Getenv(testCatalogRefEnvVar))
183203
require.NoError(t, err)
184204

@@ -191,30 +211,72 @@ func testInit(t *testing.T) (*ocv1alpha1.ClusterExtension, *catalogd.ClusterCata
191211

192212
defaultNamespace := types.NamespacedName{
193213
Name: clusterExtensionName,
194-
Namespace: "default",
214+
Namespace: ns.GetName(),
195215
}
196216

197217
sa, err := createServiceAccount(context.Background(), defaultNamespace, clusterExtensionName)
198218
require.NoError(t, err)
199-
return clusterExtension, extensionCatalog, sa
219+
return clusterExtension, extensionCatalog, sa, ns
200220
}
201221

202-
func testCleanup(t *testing.T, cat *catalogd.ClusterCatalog, clusterExtension *ocv1alpha1.ClusterExtension, sa *corev1.ServiceAccount) {
222+
func ensureNoExtensionResources(t *testing.T, clusterExtensionName string) {
223+
ls := labels.Set{"olm.operatorframework.io/owner-name": clusterExtensionName}
224+
225+
t.Logf("By waiting for CustomResourceDefinitions of %q to be deleted", clusterExtensionName)
226+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
227+
list := &apiextensionsv1.CustomResourceDefinitionList{}
228+
err := c.List(context.Background(), list, client.MatchingLabelsSelector{Selector: ls.AsSelector()})
229+
assert.NoError(ct, err)
230+
assert.Len(ct, list.Items, 0)
231+
}, 2*pollDuration, pollInterval)
232+
233+
t.Logf("By waiting for ClusterRoleBindings of %q to be deleted", clusterExtensionName)
234+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
235+
list := &rbacv1.ClusterRoleBindingList{}
236+
err := c.List(context.Background(), list, client.MatchingLabelsSelector{Selector: ls.AsSelector()})
237+
assert.NoError(ct, err)
238+
assert.Len(ct, list.Items, 0)
239+
}, 2*pollDuration, pollInterval)
240+
241+
t.Logf("By waiting for ClusterRoles of %q to be deleted", clusterExtensionName)
242+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
243+
list := &rbacv1.ClusterRoleList{}
244+
err := c.List(context.Background(), list, client.MatchingLabelsSelector{Selector: ls.AsSelector()})
245+
assert.NoError(ct, err)
246+
assert.Len(ct, list.Items, 0)
247+
}, 2*pollDuration, pollInterval)
248+
}
249+
250+
func testCleanup(t *testing.T, cat *catalogd.ClusterCatalog, clusterExtension *ocv1alpha1.ClusterExtension, sa *corev1.ServiceAccount, ns *corev1.Namespace) {
251+
t.Logf("By deleting ClusterCatalog %q", cat.Name)
203252
require.NoError(t, c.Delete(context.Background(), cat))
204253
require.Eventually(t, func() bool {
205254
err := c.Get(context.Background(), types.NamespacedName{Name: cat.Name}, &catalogd.ClusterCatalog{})
206255
return errors.IsNotFound(err)
207256
}, pollDuration, pollInterval)
257+
258+
t.Logf("By deleting ClusterExtension %q", clusterExtension.Name)
208259
require.NoError(t, c.Delete(context.Background(), clusterExtension))
209260
require.Eventually(t, func() bool {
210261
err := c.Get(context.Background(), types.NamespacedName{Name: clusterExtension.Name}, &ocv1alpha1.ClusterExtension{})
211262
return errors.IsNotFound(err)
212263
}, pollDuration, pollInterval)
264+
265+
t.Logf("By deleting ServiceAccount %q", sa.Name)
213266
require.NoError(t, c.Delete(context.Background(), sa))
214267
require.Eventually(t, func() bool {
215268
err := c.Get(context.Background(), types.NamespacedName{Name: sa.Name, Namespace: sa.Namespace}, &corev1.ServiceAccount{})
216269
return errors.IsNotFound(err)
217270
}, pollDuration, pollInterval)
271+
272+
t.Logf("By deleting Namespace %q", ns.Name)
273+
require.NoError(t, c.Delete(context.Background(), ns))
274+
require.Eventually(t, func() bool {
275+
err := c.Get(context.Background(), types.NamespacedName{Name: ns.Name}, &corev1.Namespace{})
276+
return errors.IsNotFound(err)
277+
}, pollDuration, pollInterval)
278+
279+
ensureNoExtensionResources(t, clusterExtension.Name)
218280
}
219281

220282
func TestClusterExtensionInstallRegistry(t *testing.T) {
@@ -240,8 +302,8 @@ func TestClusterExtensionInstallRegistry(t *testing.T) {
240302
t.Log("When a cluster extension is installed from a catalog")
241303
t.Log("When the extension bundle format is registry+v1")
242304

243-
clusterExtension, extensionCatalog, sa := testInit(t)
244-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
305+
clusterExtension, extensionCatalog, sa, ns := testInit(t)
306+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
245307
defer getArtifactsOutput(t)
246308

247309
clusterExtension.Spec = ocv1alpha1.ClusterExtensionSpec{
@@ -255,7 +317,7 @@ func TestClusterExtensionInstallRegistry(t *testing.T) {
255317
},
256318
},
257319
Install: ocv1alpha1.ClusterExtensionInstallConfig{
258-
Namespace: "default",
320+
Namespace: ns.Name,
259321
ServiceAccount: ocv1alpha1.ServiceAccountReference{
260322
Name: sa.Name,
261323
},
@@ -298,8 +360,8 @@ func TestClusterExtensionInstallRegistry(t *testing.T) {
298360
func TestClusterExtensionInstallRegistryMultipleBundles(t *testing.T) {
299361
t.Log("When a cluster extension is installed from a catalog")
300362

301-
clusterExtension, extensionCatalog, sa := testInit(t)
302-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
363+
clusterExtension, extensionCatalog, sa, ns := testInit(t)
364+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
303365
defer getArtifactsOutput(t)
304366

305367
clusterExtension.Spec = ocv1alpha1.ClusterExtensionSpec{
@@ -310,7 +372,7 @@ func TestClusterExtensionInstallRegistryMultipleBundles(t *testing.T) {
310372
},
311373
},
312374
Install: ocv1alpha1.ClusterExtensionInstallConfig{
313-
Namespace: "default",
375+
Namespace: ns.Name,
314376
ServiceAccount: ocv1alpha1.ServiceAccountReference{
315377
Name: sa.Name,
316378
},
@@ -341,8 +403,8 @@ func TestClusterExtensionBlockInstallNonSuccessorVersion(t *testing.T) {
341403
t.Log("When a cluster extension is installed from a catalog")
342404
t.Log("When resolving upgrade edges")
343405

344-
clusterExtension, extensionCatalog, sa := testInit(t)
345-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
406+
clusterExtension, extensionCatalog, sa, ns := testInit(t)
407+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
346408
defer getArtifactsOutput(t)
347409

348410
t.Log("By creating an ClusterExtension at a specified version")
@@ -356,7 +418,7 @@ func TestClusterExtensionBlockInstallNonSuccessorVersion(t *testing.T) {
356418
},
357419
},
358420
Install: ocv1alpha1.ClusterExtensionInstallConfig{
359-
Namespace: "default",
421+
Namespace: ns.Name,
360422
ServiceAccount: ocv1alpha1.ServiceAccountReference{
361423
Name: sa.Name,
362424
},
@@ -406,8 +468,8 @@ func TestClusterExtensionForceInstallNonSuccessorVersion(t *testing.T) {
406468
t.Log("When a cluster extension is installed from a catalog")
407469
t.Log("When resolving upgrade edges")
408470

409-
clusterExtension, extensionCatalog, sa := testInit(t)
410-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
471+
clusterExtension, extensionCatalog, sa, ns := testInit(t)
472+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
411473
defer getArtifactsOutput(t)
412474

413475
t.Log("By creating an ClusterExtension at a specified version")
@@ -420,7 +482,7 @@ func TestClusterExtensionForceInstallNonSuccessorVersion(t *testing.T) {
420482
},
421483
},
422484
Install: ocv1alpha1.ClusterExtensionInstallConfig{
423-
Namespace: "default",
485+
Namespace: ns.Name,
424486
ServiceAccount: ocv1alpha1.ServiceAccountReference{
425487
Name: sa.Name,
426488
},
@@ -457,8 +519,8 @@ func TestClusterExtensionForceInstallNonSuccessorVersion(t *testing.T) {
457519
func TestClusterExtensionInstallSuccessorVersion(t *testing.T) {
458520
t.Log("When a cluster extension is installed from a catalog")
459521
t.Log("When resolving upgrade edges")
460-
clusterExtension, extensionCatalog, sa := testInit(t)
461-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
522+
clusterExtension, extensionCatalog, sa, ns := testInit(t)
523+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
462524
defer getArtifactsOutput(t)
463525

464526
t.Log("By creating an ClusterExtension at a specified version")
@@ -471,7 +533,7 @@ func TestClusterExtensionInstallSuccessorVersion(t *testing.T) {
471533
},
472534
},
473535
Install: ocv1alpha1.ClusterExtensionInstallConfig{
474-
Namespace: "default",
536+
Namespace: ns.Name,
475537
ServiceAccount: ocv1alpha1.ServiceAccountReference{
476538
Name: sa.Name,
477539
},
@@ -507,8 +569,8 @@ func TestClusterExtensionInstallSuccessorVersion(t *testing.T) {
507569
func TestClusterExtensionInstallReResolvesWhenCatalogIsPatched(t *testing.T) {
508570
t.Log("When a cluster extension is installed from a catalog")
509571
t.Log("It resolves again when a catalog is patched with new ImageRef")
510-
clusterExtension, extensionCatalog, sa := testInit(t)
511-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
572+
clusterExtension, extensionCatalog, sa, ns := testInit(t)
573+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
512574
defer getArtifactsOutput(t)
513575

514576
clusterExtension.Spec = ocv1alpha1.ClusterExtensionSpec{
@@ -528,7 +590,7 @@ func TestClusterExtensionInstallReResolvesWhenCatalogIsPatched(t *testing.T) {
528590
},
529591
},
530592
Install: ocv1alpha1.ClusterExtensionInstallConfig{
531-
Namespace: "default",
593+
Namespace: ns.Name,
532594
ServiceAccount: ocv1alpha1.ServiceAccountReference{
533595
Name: sa.Name,
534596
},
@@ -593,9 +655,11 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) {
593655
Name: clusterExtensionName,
594656
},
595657
}
596-
sa, err := createServiceAccount(context.Background(), types.NamespacedName{Name: clusterExtensionName, Namespace: "default"}, clusterExtensionName)
658+
ns, err := createNamespace(context.Background())
597659
require.NoError(t, err)
598-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
660+
sa, err := createServiceAccount(context.Background(), types.NamespacedName{Name: clusterExtensionName, Namespace: ns.Name}, clusterExtensionName)
661+
require.NoError(t, err)
662+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
599663
defer getArtifactsOutput(t)
600664

601665
clusterExtension.Spec = ocv1alpha1.ClusterExtensionSpec{
@@ -609,7 +673,7 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) {
609673
},
610674
},
611675
Install: ocv1alpha1.ClusterExtensionInstallConfig{
612-
Namespace: "default",
676+
Namespace: ns.Name,
613677
ServiceAccount: ocv1alpha1.ServiceAccountReference{
614678
Name: sa.Name,
615679
},
@@ -657,8 +721,8 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) {
657721
func TestClusterExtensionInstallReResolvesWhenManagedContentChanged(t *testing.T) {
658722
t.Log("When a cluster extension is installed from a catalog")
659723
t.Log("It resolves again when managed content is changed")
660-
clusterExtension, extensionCatalog, sa := testInit(t)
661-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
724+
clusterExtension, extensionCatalog, sa, ns := testInit(t)
725+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
662726
defer getArtifactsOutput(t)
663727

664728
clusterExtension.Spec = ocv1alpha1.ClusterExtensionSpec{
@@ -672,7 +736,7 @@ func TestClusterExtensionInstallReResolvesWhenManagedContentChanged(t *testing.T
672736
},
673737
},
674738
Install: ocv1alpha1.ClusterExtensionInstallConfig{
675-
Namespace: "default",
739+
Namespace: ns.Name,
676740
ServiceAccount: ocv1alpha1.ServiceAccountReference{
677741
Name: sa.Name,
678742
},
@@ -712,18 +776,18 @@ func TestClusterExtensionRecoversFromInitialInstallFailedWhenFailureFixed(t *tes
712776
t.Log("When a cluster extension is installed from a catalog")
713777
t.Log("When the extension bundle format is registry+v1")
714778

715-
clusterExtension, extensionCatalog, _ := testInit(t)
779+
clusterExtension, extensionCatalog, _, ns := testInit(t)
780+
716781
name := rand.String(10)
717782
sa := &corev1.ServiceAccount{
718783
ObjectMeta: metav1.ObjectMeta{
719784
Name: name,
720-
Namespace: "default",
785+
Namespace: ns.Name,
721786
},
722787
}
723788
err := c.Create(context.Background(), sa)
724789
require.NoError(t, err)
725-
726-
defer testCleanup(t, extensionCatalog, clusterExtension, sa)
790+
defer testCleanup(t, extensionCatalog, clusterExtension, sa, ns)
727791
defer getArtifactsOutput(t)
728792

729793
clusterExtension.Spec = ocv1alpha1.ClusterExtensionSpec{
@@ -737,7 +801,7 @@ func TestClusterExtensionRecoversFromInitialInstallFailedWhenFailureFixed(t *tes
737801
},
738802
},
739803
Install: ocv1alpha1.ClusterExtensionInstallConfig{
740-
Namespace: "default",
804+
Namespace: ns.Name,
741805
ServiceAccount: ocv1alpha1.ServiceAccountReference{
742806
Name: sa.Name,
743807
},

test/e2e/e2e_suite_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing"
77
"time"
88

9+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
910
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1011
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1112
"k8s.io/client-go/rest"
@@ -32,6 +33,7 @@ func TestMain(m *testing.M) {
3233
cfg = ctrl.GetConfigOrDie()
3334

3435
var err error
36+
utilruntime.Must(apiextensionsv1.AddToScheme(scheme.Scheme))
3537
c, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
3638
utilruntime.Must(err)
3739

0 commit comments

Comments
 (0)