@@ -13,6 +13,7 @@ import (
1313 appsv1 "k8s.io/api/apps/v1"
1414 corev1 "k8s.io/api/core/v1"
1515 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
16+ "k8s.io/apimachinery/pkg/api/errors"
1617 "k8s.io/apimachinery/pkg/api/meta"
1718 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1819 "k8s.io/apimachinery/pkg/util/rand"
@@ -277,9 +278,7 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace] OLMv1 ope
277278 var (
278279 k8sClient client.Client
279280 activeNamespaces map [string ]struct {}
280- catalogName string
281- packageName string
282- crdSuffix string
281+ singleownImage string
283282 )
284283
285284 BeforeEach (func (ctx SpecContext ) {
@@ -291,29 +290,8 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace] OLMv1 ope
291290 helpers .RequireImageRegistry (ctx )
292291 k8sClient = env .Get ().K8sClient
293292 activeNamespaces = map [string ]struct {}{}
294-
295- // Generate unique CRD suffix for parallel execution
296- crdSuffix = rand .String (4 )
297-
298- // Build in-cluster bundle and catalog
299- singleownImage := image .LocationFor ("quay.io/olmtest/webhook-operator:v0.0.5" )
300- packageName = fmt .Sprintf ("singleown-operator-both-%s" , crdSuffix )
301- By (fmt .Sprintf ("using singleown operator image: %s, CRD suffix: %s, package: %s" , singleownImage , crdSuffix , packageName ))
302-
303- replacements := map [string ]string {
304- "{{ TEST-BUNDLE }}" : "" ,
305- "{{ NAMESPACE }}" : "" ,
306- "{{ TEST-CONTROLLER }}" : singleownImage ,
307- "{{ CRD-SUFFIX }}" : crdSuffix ,
308- "{{ PACKAGE-NAME }}" : packageName ,
309- }
310-
311- var nsName , opName string
312- _ , nsName , catalogName , opName = helpers .NewCatalogAndClusterBundles (ctx , replacements ,
313- singleownindex .AssetNames , singleownindex .Asset ,
314- singleownbundle .AssetNames , singleownbundle .Asset ,
315- )
316- By (fmt .Sprintf ("singleown bundle %q and catalog %q built successfully in namespace %q" , opName , catalogName , nsName ))
293+ singleownImage = image .LocationFor ("quay.io/olmtest/webhook-operator:v0.0.5" )
294+ By (fmt .Sprintf ("using singleown operator image: %s" , singleownImage ))
317295 })
318296
319297 AfterEach (func (ctx SpecContext ) {
@@ -359,6 +337,29 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace] OLMv1 ope
359337 activeNamespaces [watchNamespace ] = struct {}{}
360338 }
361339
340+ // Ensure unique names per scenario
341+ crdSuffix := rand .String (4 )
342+ packageName := fmt .Sprintf ("singleown-operator-both-%s" , crdSuffix )
343+ By (fmt .Sprintf ("building singleown operator assets for %s scenario: image=%s, CRD suffix=%s, package=%s" , sc .label , singleownImage , crdSuffix , packageName ))
344+
345+ replacements := map [string ]string {
346+ "{{ TEST-BUNDLE }}" : "" ,
347+ "{{ NAMESPACE }}" : "" ,
348+ "{{ TEST-CONTROLLER }}" : singleownImage ,
349+ "{{ CRD-SUFFIX }}" : crdSuffix , // Unique CRD suffix per scenario
350+ "{{ PACKAGE-NAME }}" : packageName ,
351+ "webhook-operator-webhooktest-admin-role" : fmt .Sprintf ("webhook-operator-webhooktest-admin-role-%s" , crdSuffix ),
352+ "webhook-operator-webhooktest-editor-role" : fmt .Sprintf ("webhook-operator-webhooktest-editor-role-%s" , crdSuffix ),
353+ "webhook-operator-webhooktest-viewer-role" : fmt .Sprintf ("webhook-operator-webhooktest-viewer-role-%s" , crdSuffix ),
354+ "webhook-operator-metrics-reader" : fmt .Sprintf ("webhook-operator-metrics-reader-%s" , crdSuffix ),
355+ }
356+
357+ _ , nsName , catalogName , opName := helpers .NewCatalogAndClusterBundles (ctx , replacements ,
358+ singleownindex .AssetNames , singleownindex .Asset ,
359+ singleownbundle .AssetNames , singleownbundle .Asset ,
360+ )
361+ By (fmt .Sprintf ("singleown bundle %q and catalog %q built successfully in namespace %q for %s scenario" , opName , catalogName , nsName , sc .label ))
362+
362363 By (fmt .Sprintf ("ensuring no ClusterExtension for %s before %s scenario" , packageName , sc .label ))
363364 crdName := fmt .Sprintf ("webhooktests-%s.webhook.operators.coreos.io" , crdSuffix )
364365 helpers .EnsureCleanupClusterExtension (context .Background (), packageName , crdName )
@@ -432,6 +433,13 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace] OLMv1 ope
432433 DeferCleanup (func () {
433434 By (fmt .Sprintf ("cleanup: deleting ClusterExtension %s" , ce .Name ))
434435 _ = k8sClient .Delete (context .Background (), ce , client .PropagationPolicy (metav1 .DeletePropagationForeground ))
436+ if crdName != "" {
437+ crd := & apiextensionsv1.CustomResourceDefinition {}
438+ if err := k8sClient .Get (context .Background (), client.ObjectKey {Name : crdName }, crd ); err == nil {
439+ By (fmt .Sprintf ("cleanup: deleting CRD %s" , crdName ))
440+ _ = k8sClient .Delete (context .Background (), crd )
441+ }
442+ }
435443 })
436444
437445 By (fmt .Sprintf ("waiting for the ClusterExtension %s to be installed for %s scenario" , ceName , sc .label ))
@@ -459,6 +467,8 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace] OLMv1 ope
459467 g .Expect (found ).To (BeTrue (), "failed to find deployment with olm.targetNamespaces annotation" )
460468 }).WithTimeout (helpers .DefaultTimeout ).WithPolling (helpers .DefaultPolling ).Should (Succeed ())
461469
470+ // Ginkgo never invokes those deferred cleanups until we exit the whole spec, so the first scenario’s
471+ // cluster resources survive long enough to collide with the second scenario.
462472 By (fmt .Sprintf ("cleaning up resources created for %s scenario to allow next scenario" , sc .label ))
463473 deletePolicy := metav1 .DeletePropagationForeground
464474 Expect (k8sClient .Delete (ctx , ce , client .PropagationPolicy (deletePolicy ))).To (Succeed (), "failed to delete ClusterExtension %q" , ceName )
@@ -471,6 +481,19 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace] OLMv1 ope
471481 Expect (k8sClient .Delete (ctx , watchNSObj , client .PropagationPolicy (deletePolicy ))).To (Succeed (), "failed to delete watch namespace %q" , watchNamespace )
472482 }
473483 Expect (k8sClient .Delete (ctx , installNS , client .PropagationPolicy (deletePolicy ))).To (Succeed (), "failed to delete install namespace %q" , installNamespace )
484+
485+ By (fmt .Sprintf ("waiting for namespace %s to be fully deleted before next scenario" , installNamespace ))
486+ Eventually (func () bool {
487+ err := k8sClient .Get (ctx , client.ObjectKey {Name : installNamespace }, & corev1.Namespace {})
488+ return errors .IsNotFound (err )
489+ }).WithTimeout (helpers .DefaultTimeout ).WithPolling (helpers .DefaultPolling ).Should (BeTrue (), "expected namespace %s to be deleted" , installNamespace )
490+ if watchNSObj != nil {
491+ By (fmt .Sprintf ("waiting for namespace %s to be fully deleted before next scenario" , watchNamespace ))
492+ Eventually (func () bool {
493+ err := k8sClient .Get (ctx , client.ObjectKey {Name : watchNamespace }, & corev1.Namespace {})
494+ return errors .IsNotFound (err )
495+ }).WithTimeout (helpers .DefaultTimeout ).WithPolling (helpers .DefaultPolling ).Should (BeTrue (), "expected namespace %s to be deleted" , watchNamespace )
496+ }
474497 }
475498 })
476499})
0 commit comments