From 0174327ab92bc56a6f0495d6620a1637e732f0a6 Mon Sep 17 00:00:00 2001 From: Camila Macedo <7708031+camilamacedo86@users.noreply.github.com> Date: Fri, 8 Aug 2025 22:49:25 +0100 Subject: [PATCH] UPSTREAM: : Migrate single/own namespace tests This commit migrates the OLMv1 single and own namespace watch mode tests from openshift/origin/test/extended/olm/olmv1-singleownnamespace.go to this repository. This is part of the effort to move component-specific tests into their respective downstream locations. Assisted-by: Gemini --- .../openshift_payload_olmv1.json | 39 +++ .../test/olmv1-singleownnamespace.go | 303 ++++++++++++++++++ 2 files changed, 342 insertions(+) create mode 100644 openshift/tests-extension/test/olmv1-singleownnamespace.go diff --git a/openshift/tests-extension/.openshift-tests-extension/openshift_payload_olmv1.json b/openshift/tests-extension/.openshift-tests-extension/openshift_payload_olmv1.json index 0321e572a..1c2dc808f 100644 --- a/openshift/tests-extension/.openshift-tests-extension/openshift_payload_olmv1.json +++ b/openshift/tests-extension/.openshift-tests-extension/openshift_payload_olmv1.json @@ -69,6 +69,45 @@ "lifecycle": "blocking", "environmentSelector": {} }, + { + "name": "[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected][Serial] OLMv1 operator installation support for singleNamespace watch mode with quay-operator should install a cluster extension successfully", + "originalName": "[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for singleNamespace watch mode with quay-operator should install a cluster extension successfully", + "labels": { + "original-name:[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for singleNamespace watch mode with quay-operator should install a cluster extension successfully": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv1", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected][Serial] OLMv1 operator installation support for ownNamespace watch mode with quay-operator should install a cluster extension successfully", + "originalName": "[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for ownNamespace watch mode with quay-operator should install a cluster extension successfully", + "labels": { + "original-name:[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for ownNamespace watch mode with quay-operator should install a cluster extension successfully": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv1", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected][Serial] OLMv1 operator installation support for ownNamespace watch mode with an operator that does not support ownNamespace installation mode should fail to install a cluster extension successfully", + "originalName": "[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for ownNamespace watch mode with an operator that does not support ownNamespace installation mode should fail to install a cluster extension successfully", + "labels": { + "original-name:[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for ownNamespace watch mode with an operator that does not support ownNamespace installation mode should fail to install a cluster extension successfully": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv1", + "lifecycle": "blocking", + "environmentSelector": {} + }, { "name": "[sig-olmv1] OLMv1 should pass a trivial sanity check", "labels": {}, diff --git a/openshift/tests-extension/test/olmv1-singleownnamespace.go b/openshift/tests-extension/test/olmv1-singleownnamespace.go new file mode 100644 index 000000000..65289bfb9 --- /dev/null +++ b/openshift/tests-extension/test/olmv1-singleownnamespace.go @@ -0,0 +1,303 @@ +package test + +import ( + "context" + "fmt" + "time" + + //nolint:staticcheck // ST1001: dot-imports for readability + . "github.com/onsi/ginkgo/v2" + //nolint:staticcheck // ST1001: dot-imports for readability + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/rand" + "sigs.k8s.io/controller-runtime/pkg/client" + + olmv1 "github.com/operator-framework/operator-controller/api/v1" + + "github/operator-framework-operator-controller/openshift/tests-extension/pkg/env" + "github/operator-framework-operator-controller/openshift/tests-extension/pkg/helpers" +) + +var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected][Serial] OLMv1 operator installation support for singleNamespace watch mode with quay-operator", Ordered, Serial, func() { + var ( + k8sClient client.Client + namespace string + testPrefix = "quay-singlens" + ) + + var unique, saName, crbName, ceName string + BeforeEach(func() { + By("checking if OpenShift is available for tests") + if !env.Get().IsOpenShift { + Skip("Requires OpenShift for the tests") + } + helpers.RequireOLMv1CapabilityOnOpenshift() + k8sClient = env.Get().K8sClient + + unique = rand.String(4) + namespace = fmt.Sprintf("olmv1-%s-ns-%s", testPrefix, unique) + saName = fmt.Sprintf("install-%s-sa-%s", testPrefix, unique) + crbName = fmt.Sprintf("install-%s-crb-%s", testPrefix, unique) + ceName = fmt.Sprintf("install-%s-ce-%s", testPrefix, unique) + + By("ensuring no ClusterExtension and CRD for quay-operator") + helpers.EnsureCleanupClusterExtension(context.Background(), "quay-operator", "quayregistries.quay.redhat.com") + + By(fmt.Sprintf("creating namespace %s for single-namespace tests", namespace)) + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + } + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed(), "failed to create test namespace %q", namespace) + DeferCleanup(func() { + By(fmt.Sprintf("cleaning up namespace %s", namespace)) + _ = k8sClient.Delete(context.Background(), ns, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + }) + + AfterEach(func(ctx SpecContext) { + if CurrentSpecReport().Failed() { + By("dumping for debugging") + helpers.DescribeAllClusterExtensions(ctx, namespace) + } + }) + + It("should install a cluster extension successfully", + Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for singleNamespace watch mode with quay-operator should install a cluster extension successfully"), + func(ctx SpecContext) { + By("creating ServiceAccount") + sa := helpers.NewServiceAccount(saName, namespace) + Expect(k8sClient.Create(ctx, sa)).To(Succeed(), "failed to create ServiceAccount %q", saName) + By("ensuring ServiceAccount is available before proceeding") + helpers.ExpectServiceAccountExists(ctx, saName, namespace) + By("registering cleanup for ServiceAccount") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ServiceAccount %s in namespace %s", sa.Name, sa.Namespace)) + _ = k8sClient.Delete(context.Background(), sa, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + + By("creating ClusterRoleBinding") + crb := helpers.NewClusterRoleBinding(crbName, "cluster-admin", saName, namespace) + Expect(k8sClient.Create(ctx, crb)).To(Succeed(), "failed to create ClusterRoleBinding %q", crbName) + By("ensuring ClusterRoleBinding is available before proceeding") + helpers.ExpectClusterRoleBindingExists(ctx, crbName) + By("registering cleanup for ClusterRoleBinding") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ClusterRoleBinding %s", crb.Name)) + _ = k8sClient.Delete(context.Background(), crb, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + + By("creating ClusterExtension with the watch-namespace annotation") + ce := helpers.NewClusterExtensionObject("quay-operator", "3.14.2", ceName, saName, namespace) + ce.Annotations = map[string]string{ + "olm.operatorframework.io/watch-namespace": namespace, + } + Expect(k8sClient.Create(ctx, ce)).To(Succeed(), "failed to create ClusterExtension %q", ceName) + By("registering cleanup for ClusterExtension") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ClusterExtension %s", ce.Name)) + _ = k8sClient.Delete(context.Background(), ce, client.PropagationPolicy(metav1.DeletePropagationForeground)) + + By("ensuring ClusterExtension is deleted") + helpers.EnsureCleanupClusterExtension(context.Background(), ceName, namespace) + }) + + By("waiting for the ClusterExtension to be installed") + helpers.ExpectClusterExtensionToBeInstalled(ctx, ceName) + }) +}) + +var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected][Serial] OLMv1 operator installation support for ownNamespace watch mode with quay-operator", Ordered, Serial, func() { + var ( + k8sClient client.Client + namespace string + testPrefix = "quay-ownns" + ) + + var unique, saName, crbName, ceName string + BeforeEach(func() { + By("checking if OpenShift is available for tests") + if !env.Get().IsOpenShift { + Skip("Requires OpenShift for the tests") + } + helpers.RequireOLMv1CapabilityOnOpenshift() + k8sClient = env.Get().K8sClient + unique = rand.String(4) + namespace = fmt.Sprintf("olmv1-%s-ns-%s", testPrefix, unique) + saName = fmt.Sprintf("install-%s-sa-%s", testPrefix, unique) + crbName = fmt.Sprintf("install-%s-crb-%s", testPrefix, unique) + ceName = fmt.Sprintf("install-%s-ce-%s", testPrefix, unique) + + By("ensuring no ClusterExtension and CRD for quay-operator") + helpers.EnsureCleanupClusterExtension(context.Background(), "quay-operator", "quayregistries.quay.redhat.com") + + By(fmt.Sprintf("creating namespace %s for own-namespace tests", namespace)) + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + } + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed(), "failed to create test namespace %q", namespace) + DeferCleanup(func() { + By(fmt.Sprintf("cleaning up namespace %s", namespace)) + _ = k8sClient.Delete(context.Background(), ns, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + }) + + AfterEach(func(ctx SpecContext) { + if CurrentSpecReport().Failed() { + By("dumping for debugging") + helpers.DescribeAllClusterExtensions(ctx, namespace) + } + }) + + It("should install a cluster extension successfully", + Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for ownNamespace watch mode with quay-operator should install a cluster extension successfully"), + func(ctx SpecContext) { + By("creating ServiceAccount") + sa := helpers.NewServiceAccount(saName, namespace) + Expect(k8sClient.Create(ctx, sa)).To(Succeed(), "failed to create ServiceAccount %q", saName) + By("ensuring ServiceAccount is available before proceeding") + helpers.ExpectServiceAccountExists(ctx, saName, namespace) + By("registering cleanup for ServiceAccount") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ServiceAccount %s in namespace %s", sa.Name, sa.Namespace)) + _ = k8sClient.Delete(context.Background(), sa, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + + By("creating ClusterRoleBinding") + crb := helpers.NewClusterRoleBinding(crbName, "cluster-admin", saName, namespace) + Expect(k8sClient.Create(ctx, crb)).To(Succeed(), "failed to create ClusterRoleBinding %q", crbName) + By("ensuring ClusterRoleBinding is available before proceeding") + helpers.ExpectClusterRoleBindingExists(ctx, crbName) + By("registering cleanup for ClusterRoleBinding") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ClusterRoleBinding %s", crb.Name)) + _ = k8sClient.Delete(context.Background(), crb, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + + By("creating ClusterExtension with the watch-namespace annotation") + ce := helpers.NewClusterExtensionObject("quay-operator", "3.14.2", ceName, saName, namespace) + ce.Annotations = map[string]string{ + "olm.operatorframework.io/watch-namespace": namespace, + } + Expect(k8sClient.Create(ctx, ce)).To(Succeed(), "failed to create ClusterExtension %q", ceName) + By("registering cleanup for ClusterExtension") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ClusterExtension %s", ce.Name)) + _ = k8sClient.Delete(context.Background(), ce, client.PropagationPolicy(metav1.DeletePropagationForeground)) + + By("ensuring ClusterExtension is deleted") + helpers.EnsureCleanupClusterExtension(context.Background(), ceName, namespace) + }) + + By("waiting for the ClusterExtension to be installed") + helpers.ExpectClusterExtensionToBeInstalled(ctx, ceName) + }) +}) + +var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected][Serial] OLMv1 operator installation support for ownNamespace watch mode with an operator that does not support ownNamespace installation mode", Ordered, Serial, func() { + var ( + k8sClient client.Client + namespace string + testPrefix = "pipelines" + ) + + var unique, saName, crbName, ceName string + BeforeEach(func() { + By("checking if OpenShift is available for tests") + if !env.Get().IsOpenShift { + Skip("Requires OpenShift for the tests") + } + helpers.RequireOLMv1CapabilityOnOpenshift() + k8sClient = env.Get().K8sClient + unique = rand.String(4) + namespace = fmt.Sprintf("olmv1-%s-ns-%s", testPrefix, unique) + saName = fmt.Sprintf("install-%s-sa-%s", testPrefix, unique) + crbName = fmt.Sprintf("install-%s-crb-%s", testPrefix, unique) + ceName = fmt.Sprintf("install-%s-ce-%s", testPrefix, unique) + + By("ensuring no ClusterExtension and CRD for openshift-pipelines-operator-rh") + helpers.EnsureCleanupClusterExtension(context.Background(), "openshift-pipelines-operator-rh", "clustertasks.tekton.dev") + + By(fmt.Sprintf("creating namespace %s for failing tests", namespace)) + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + } + Expect(k8sClient.Create(context.Background(), ns)).To(Succeed(), "failed to create test namespace %q", namespace) + DeferCleanup(func() { + By(fmt.Sprintf("cleaning up namespace %s", namespace)) + _ = k8sClient.Delete(context.Background(), ns, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + }) + + AfterEach(func(ctx SpecContext) { + if CurrentSpecReport().Failed() { + By("dumping for debugging") + helpers.DescribeAllClusterExtensions(ctx, namespace) + } + }) + + It("should fail to install a cluster extension successfully", + Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLMOwnSingleNamespace][Skipped:Disconnected] OLMv1 operator installation support for ownNamespace watch mode with an operator that does not support ownNamespace installation mode should fail to install a cluster extension successfully"), + func(ctx SpecContext) { + By("creating ServiceAccount") + sa := helpers.NewServiceAccount(saName, namespace) + Expect(k8sClient.Create(ctx, sa)).To(Succeed(), "failed to create ServiceAccount %q", saName) + By("ensuring ServiceAccount is available before proceeding") + helpers.ExpectServiceAccountExists(ctx, saName, namespace) + By("registering cleanup for ServiceAccount") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ServiceAccount %s in namespace %s", sa.Name, sa.Namespace)) + _ = k8sClient.Delete(context.Background(), sa, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + + By("creating ClusterRoleBinding") + crb := helpers.NewClusterRoleBinding(crbName, "cluster-admin", saName, namespace) + Expect(k8sClient.Create(ctx, crb)).To(Succeed(), "failed to create ClusterRoleBinding %q", crbName) + By("ensuring ClusterRoleBinding is available before proceeding") + helpers.ExpectClusterRoleBindingExists(ctx, crbName) + By("registering cleanup for ClusterRoleBinding") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ClusterRoleBinding %s", crb.Name)) + _ = k8sClient.Delete(context.Background(), crb, client.PropagationPolicy(metav1.DeletePropagationForeground)) + }) + + By("creating ClusterExtension with the watch-namespace annotation") + ce := helpers.NewClusterExtensionObject("openshift-pipelines-operator-rh", "1.17.1", ceName, saName, namespace) + ce.Annotations = map[string]string{ + "olm.operatorframework.io/watch-namespace": namespace, + } + Expect(k8sClient.Create(ctx, ce)).To(Succeed(), "failed to create ClusterExtension %q", ceName) + By("registering cleanup for ClusterExtension") + DeferCleanup(func() { + By(fmt.Sprintf("cleanup: deleting ClusterExtension %s", ce.Name)) + _ = k8sClient.Delete(context.Background(), ce, client.PropagationPolicy(metav1.DeletePropagationForeground)) + + By("ensuring ClusterExtension is deleted") + helpers.EnsureCleanupClusterExtension(context.Background(), ceName, namespace) + }) + + By("waiting for the ClusterExtension to fail installation") + Eventually(func(g Gomega) { + var ext olmv1.ClusterExtension + err := k8sClient.Get(ctx, client.ObjectKey{Name: ceName}, &ext) + g.Expect(err).ToNot(HaveOccurred(), "failed to get ClusterExtension %q", ceName) + + conditions := ext.Status.Conditions + g.Expect(conditions).ToNot(BeEmpty(), "ClusterExtension %q has empty status.conditions", ceName) + + installed := meta.FindStatusCondition(conditions, olmv1.TypeInstalled) + g.Expect(installed).ToNot(BeNil(), "Installed condition not found") + g.Expect(installed.Status).To(Equal(metav1.ConditionFalse), "Installed should be False") + g.Expect(installed.Reason).To(Equal("Failed")) + }).WithTimeout(5 * time.Minute).WithPolling(1 * time.Second).Should(Succeed()) + }) +})