diff --git a/tests-extension/.openshift-tests-extension/openshift_payload_olmv0.json b/tests-extension/.openshift-tests-extension/openshift_payload_olmv0.json index d2dfad0f69..4e94512c7e 100644 --- a/tests-extension/.openshift-tests-extension/openshift_payload_olmv0.json +++ b/tests-extension/.openshift-tests-extension/openshift_payload_olmv0.json @@ -38,6 +38,7 @@ "originalName": "[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:21484-PolarionID:21532-[Skipped:Disconnected]watch special or all namespace by operator group", "labels": { "Extended": {}, + "NonHyperShiftHOST": {}, "original-name:[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:21484-PolarionID:21532-[Skipped:Disconnected]watch special or all namespace by operator group": {} }, "resources": { @@ -45,7 +46,9 @@ }, "source": "openshift:payload:olmv0", "lifecycle": "blocking", - "environmentSelector": {} + "environmentSelector": { + "exclude": "topology==\"External\"" + } }, { "name": "[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:24906-[OTP]Operators requesting cluster-scoped permission can trigger kube GC bug[Serial]", @@ -201,42 +204,6 @@ "exclude": "topology==\"External\"" } }, - { - "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:83105-[OTP][Skipped:Disconnected]olmv0 static networkpolicy on ocp", - "originalName": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:83105-[Skipped:Disconnected]olmv0 static networkpolicy on ocp", - "labels": { - "Extended": {}, - "NonHyperShiftHOST": {}, - "ReleaseGate": {}, - "original-name:[sig-operator][Jira:OLM] OLMv0 should PolarionID:83105-[Skipped:Disconnected]olmv0 static networkpolicy on ocp": {} - }, - "resources": { - "isolation": {} - }, - "source": "openshift:payload:olmv0", - "lifecycle": "blocking", - "environmentSelector": { - "exclude": "topology==\"External\"" - } - }, - { - "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:83583-[OTP][Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift", - "originalName": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:83583-[Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift", - "labels": { - "Extended": {}, - "NonHyperShiftHOST": {}, - "ReleaseGate": {}, - "original-name:[sig-operator][Jira:OLM] OLMv0 should PolarionID:83583-[Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift": {} - }, - "resources": { - "isolation": {} - }, - "source": "openshift:payload:olmv0", - "lifecycle": "blocking", - "environmentSelector": { - "exclude": "topology==\"External\"" - } - }, { "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:21080-[OTP][Skipped:Disconnected]Check metrics[Serial]", "labels": { @@ -856,7 +823,6 @@ "originalName": "[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45381-[Skipped:Disconnected]Support custom catalogs in hypershift", "labels": { "Extended": {}, - "NonHyperShiftHOST": {}, "original-name:[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45381-[Skipped:Disconnected]Support custom catalogs in hypershift": {} }, "resources": { @@ -864,16 +830,13 @@ }, "source": "openshift:payload:olmv0", "lifecycle": "blocking", - "environmentSelector": { - "exclude": "topology==\"External\"" - } + "environmentSelector": {} }, { "name": "[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45408-[OTP][Skipped:Disconnected]Eliminate use of imagestreams in catalog management", "originalName": "[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45408-[Skipped:Disconnected]Eliminate use of imagestreams in catalog management", "labels": { "Extended": {}, - "NonHyperShiftHOST": {}, "original-name:[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45408-[Skipped:Disconnected]Eliminate use of imagestreams in catalog management": {} }, "resources": { @@ -881,24 +844,19 @@ }, "source": "openshift:payload:olmv0", "lifecycle": "blocking", - "environmentSelector": { - "exclude": "topology==\"External\"" - } + "environmentSelector": {} }, { "name": "[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45543-[OTP][Skipped:Disconnected]Enable hypershift to deploy OperatorLifecycleManager resources", "labels": { - "Extended": {}, - "NonHyperShiftHOST": {} + "Extended": {} }, "resources": { "isolation": {} }, "source": "openshift:payload:olmv0", "lifecycle": "blocking", - "environmentSelector": { - "exclude": "topology==\"External\"" - } + "environmentSelector": {} }, { "name": "[sig-operator][Jira:OLM] OLMv0 on microshift PolarionID:69867-[OTP][Skipped:Disconnected]deployed in microshift and install one operator with single mode.", @@ -999,6 +957,39 @@ "exclude": "topology==\"External\"" } }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 networkpolicy PolarionID:83105-[OTP][Skipped:Disconnected]olmv0 static networkpolicy on ocp", + "originalName": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:83105-[Skipped:Disconnected]olmv0 static networkpolicy on ocp", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {}, + "ReleaseGate": {}, + "original-name:[sig-operator][Jira:OLM] OLMv0 should PolarionID:83105-[Skipped:Disconnected]olmv0 static networkpolicy on ocp": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 networkpolicy PolarionID:83583-[OTP][Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift", + "originalName": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:83583-[Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift", + "labels": { + "Extended": {}, + "ReleaseGate": {}, + "original-name:[sig-operator][Jira:OLM] OLMv0 should PolarionID:83583-[Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, { "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:24870-[OTP][Skipped:Disconnected]can not create csv without operator group", "originalName": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:24870-[Skipped:Disconnected]can not create csv without operator group", @@ -1360,7 +1351,7 @@ "environmentSelector": {} }, { - "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:50136-[OTP][Skipped:Disconnected]automatic upgrade for failed operator installation csv fails[Slow][Timeout:30m]", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:50136-[OTP][Skipped:Disconnected]automatic upgrade for failed operator installation csv fails[Slow][Timeout:40m]", "originalName": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:50136-[Skipped:Disconnected]automatic upgrade for failed operator installation csv fails[Slow][Timeout:30m]", "labels": { "Extended": {}, diff --git a/tests-extension/pkg/bindata/qe/bindata.go b/tests-extension/pkg/bindata/qe/bindata.go index c4d9ccfee0..7c3ffda44d 100644 --- a/tests-extension/pkg/bindata/qe/bindata.go +++ b/tests-extension/pkg/bindata/qe/bindata.go @@ -35,6 +35,10 @@ // test/qe/testdata/olm/etcd-subscription-manual.yaml // test/qe/testdata/olm/etcd-subscription.yaml // test/qe/testdata/olm/mc-workload-partition.yaml +// test/qe/testdata/olm/microshift/catalogsource-image-restricted.yaml +// test/qe/testdata/olm/microshift/og-all.yaml +// test/qe/testdata/olm/microshift/og-single.yaml +// test/qe/testdata/olm/microshift/olm-subscription.yaml // test/qe/testdata/olm/og-allns.yaml // test/qe/testdata/olm/og-multins.yaml // test/qe/testdata/olm/olm-proxy-subscription.yaml @@ -6584,6 +6588,115 @@ func testQeTestdataOlmMcWorkloadPartitionYaml() (*asset, error) { return a, nil } +var _testQeTestdataOlmMicroshiftCatalogsourceImageRestrictedYaml = []byte(` +apiVersion: operators.coreos.com/v1alpha1 +kind: CatalogSource +metadata: + name: ${NAME} + namespace: ${NAMESPACE} +spec: + image: ${ADDRESS} + displayName: ${DISPLAYNAME} + grpcPodConfig: + securityContextConfig: restricted + icon: + base64data: "" + mediatype: "" + publisher: ${PUBLISHER} + sourceType: ${SOURCETYPE} +`) + +func testQeTestdataOlmMicroshiftCatalogsourceImageRestrictedYamlBytes() ([]byte, error) { + return _testQeTestdataOlmMicroshiftCatalogsourceImageRestrictedYaml, nil +} + +func testQeTestdataOlmMicroshiftCatalogsourceImageRestrictedYaml() (*asset, error) { + bytes, err := testQeTestdataOlmMicroshiftCatalogsourceImageRestrictedYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "test/qe/testdata/olm/microshift/catalogsource-image-restricted.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _testQeTestdataOlmMicroshiftOgAllYaml = []byte(`kind: OperatorGroup +apiVersion: operators.coreos.com/v1 +metadata: + name: ${NAME} + namespace: ${NAMESPACE} +`) + +func testQeTestdataOlmMicroshiftOgAllYamlBytes() ([]byte, error) { + return _testQeTestdataOlmMicroshiftOgAllYaml, nil +} + +func testQeTestdataOlmMicroshiftOgAllYaml() (*asset, error) { + bytes, err := testQeTestdataOlmMicroshiftOgAllYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "test/qe/testdata/olm/microshift/og-all.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _testQeTestdataOlmMicroshiftOgSingleYaml = []byte(`kind: OperatorGroup +apiVersion: operators.coreos.com/v1 +metadata: + name: ${NAME} + namespace: ${NAMESPACE} +spec: + targetNamespaces: + - ${NAMESPACE} +`) + +func testQeTestdataOlmMicroshiftOgSingleYamlBytes() ([]byte, error) { + return _testQeTestdataOlmMicroshiftOgSingleYaml, nil +} + +func testQeTestdataOlmMicroshiftOgSingleYaml() (*asset, error) { + bytes, err := testQeTestdataOlmMicroshiftOgSingleYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "test/qe/testdata/olm/microshift/og-single.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _testQeTestdataOlmMicroshiftOlmSubscriptionYaml = []byte(`apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: ${SUBNAME} + namespace: ${SUBNAMESPACE} +spec: + channel: ${CHANNEL} + installPlanApproval: ${APPROVAL} + name: ${OPERATORNAME} + source: ${SOURCENAME} + sourceNamespace: ${SOURCENAMESPACE} + startingCSV: ${STARTINGCSV} +`) + +func testQeTestdataOlmMicroshiftOlmSubscriptionYamlBytes() ([]byte, error) { + return _testQeTestdataOlmMicroshiftOlmSubscriptionYaml, nil +} + +func testQeTestdataOlmMicroshiftOlmSubscriptionYaml() (*asset, error) { + bytes, err := testQeTestdataOlmMicroshiftOlmSubscriptionYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "test/qe/testdata/olm/microshift/olm-subscription.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _testQeTestdataOlmOgAllnsYaml = []byte(`apiVersion: template.openshift.io/v1 kind: Template metadata: @@ -17952,6 +18065,10 @@ var _bindata = map[string]func() (*asset, error){ "test/qe/testdata/olm/etcd-subscription-manual.yaml": testQeTestdataOlmEtcdSubscriptionManualYaml, "test/qe/testdata/olm/etcd-subscription.yaml": testQeTestdataOlmEtcdSubscriptionYaml, "test/qe/testdata/olm/mc-workload-partition.yaml": testQeTestdataOlmMcWorkloadPartitionYaml, + "test/qe/testdata/olm/microshift/catalogsource-image-restricted.yaml": testQeTestdataOlmMicroshiftCatalogsourceImageRestrictedYaml, + "test/qe/testdata/olm/microshift/og-all.yaml": testQeTestdataOlmMicroshiftOgAllYaml, + "test/qe/testdata/olm/microshift/og-single.yaml": testQeTestdataOlmMicroshiftOgSingleYaml, + "test/qe/testdata/olm/microshift/olm-subscription.yaml": testQeTestdataOlmMicroshiftOlmSubscriptionYaml, "test/qe/testdata/olm/og-allns.yaml": testQeTestdataOlmOgAllnsYaml, "test/qe/testdata/olm/og-multins.yaml": testQeTestdataOlmOgMultinsYaml, "test/qe/testdata/olm/olm-proxy-subscription.yaml": testQeTestdataOlmOlmProxySubscriptionYaml, @@ -18140,28 +18257,34 @@ var _bintree = &bintree{nil, map[string]*bintree{ "etcd-subscription-manual.yaml": {testQeTestdataOlmEtcdSubscriptionManualYaml, map[string]*bintree{}}, "etcd-subscription.yaml": {testQeTestdataOlmEtcdSubscriptionYaml, map[string]*bintree{}}, "mc-workload-partition.yaml": {testQeTestdataOlmMcWorkloadPartitionYaml, map[string]*bintree{}}, - "og-allns.yaml": {testQeTestdataOlmOgAllnsYaml, map[string]*bintree{}}, - "og-multins.yaml": {testQeTestdataOlmOgMultinsYaml, map[string]*bintree{}}, - "olm-proxy-subscription.yaml": {testQeTestdataOlmOlmProxySubscriptionYaml, map[string]*bintree{}}, - "olm-subscription.yaml": {testQeTestdataOlmOlmSubscriptionYaml, map[string]*bintree{}}, - "operator.yaml": {testQeTestdataOlmOperatorYaml, map[string]*bintree{}}, - "operatorgroup-serviceaccount.yaml": {testQeTestdataOlmOperatorgroupServiceaccountYaml, map[string]*bintree{}}, - "operatorgroup-upgradestrategy.yaml": {testQeTestdataOlmOperatorgroupUpgradestrategyYaml, map[string]*bintree{}}, - "operatorgroup.yaml": {testQeTestdataOlmOperatorgroupYaml, map[string]*bintree{}}, - "opsrc.yaml": {testQeTestdataOlmOpsrcYaml, map[string]*bintree{}}, - "packageserver.yaml": {testQeTestdataOlmPackageserverYaml, map[string]*bintree{}}, - "platform_operator.yaml": {testQeTestdataOlmPlatform_operatorYaml, map[string]*bintree{}}, - "prometheus-antiaffinity.yaml": {testQeTestdataOlmPrometheusAntiaffinityYaml, map[string]*bintree{}}, - "prometheus-nodeaffinity.yaml": {testQeTestdataOlmPrometheusNodeaffinityYaml, map[string]*bintree{}}, - "role-binding.yaml": {testQeTestdataOlmRoleBindingYaml, map[string]*bintree{}}, - "role.yaml": {testQeTestdataOlmRoleYaml, map[string]*bintree{}}, - "scc.yaml": {testQeTestdataOlmSccYaml, map[string]*bintree{}}, - "scoped-sa-etcd.yaml": {testQeTestdataOlmScopedSaEtcdYaml, map[string]*bintree{}}, - "scoped-sa-fine-grained-roles.yaml": {testQeTestdataOlmScopedSaFineGrainedRolesYaml, map[string]*bintree{}}, - "scoped-sa-roles.yaml": {testQeTestdataOlmScopedSaRolesYaml, map[string]*bintree{}}, - "secret.yaml": {testQeTestdataOlmSecretYaml, map[string]*bintree{}}, - "secret_opaque.yaml": {testQeTestdataOlmSecret_opaqueYaml, map[string]*bintree{}}, - "vpa-crd.yaml": {testQeTestdataOlmVpaCrdYaml, map[string]*bintree{}}, + "microshift": {nil, map[string]*bintree{ + "catalogsource-image-restricted.yaml": {testQeTestdataOlmMicroshiftCatalogsourceImageRestrictedYaml, map[string]*bintree{}}, + "og-all.yaml": {testQeTestdataOlmMicroshiftOgAllYaml, map[string]*bintree{}}, + "og-single.yaml": {testQeTestdataOlmMicroshiftOgSingleYaml, map[string]*bintree{}}, + "olm-subscription.yaml": {testQeTestdataOlmMicroshiftOlmSubscriptionYaml, map[string]*bintree{}}, + }}, + "og-allns.yaml": {testQeTestdataOlmOgAllnsYaml, map[string]*bintree{}}, + "og-multins.yaml": {testQeTestdataOlmOgMultinsYaml, map[string]*bintree{}}, + "olm-proxy-subscription.yaml": {testQeTestdataOlmOlmProxySubscriptionYaml, map[string]*bintree{}}, + "olm-subscription.yaml": {testQeTestdataOlmOlmSubscriptionYaml, map[string]*bintree{}}, + "operator.yaml": {testQeTestdataOlmOperatorYaml, map[string]*bintree{}}, + "operatorgroup-serviceaccount.yaml": {testQeTestdataOlmOperatorgroupServiceaccountYaml, map[string]*bintree{}}, + "operatorgroup-upgradestrategy.yaml": {testQeTestdataOlmOperatorgroupUpgradestrategyYaml, map[string]*bintree{}}, + "operatorgroup.yaml": {testQeTestdataOlmOperatorgroupYaml, map[string]*bintree{}}, + "opsrc.yaml": {testQeTestdataOlmOpsrcYaml, map[string]*bintree{}}, + "packageserver.yaml": {testQeTestdataOlmPackageserverYaml, map[string]*bintree{}}, + "platform_operator.yaml": {testQeTestdataOlmPlatform_operatorYaml, map[string]*bintree{}}, + "prometheus-antiaffinity.yaml": {testQeTestdataOlmPrometheusAntiaffinityYaml, map[string]*bintree{}}, + "prometheus-nodeaffinity.yaml": {testQeTestdataOlmPrometheusNodeaffinityYaml, map[string]*bintree{}}, + "role-binding.yaml": {testQeTestdataOlmRoleBindingYaml, map[string]*bintree{}}, + "role.yaml": {testQeTestdataOlmRoleYaml, map[string]*bintree{}}, + "scc.yaml": {testQeTestdataOlmSccYaml, map[string]*bintree{}}, + "scoped-sa-etcd.yaml": {testQeTestdataOlmScopedSaEtcdYaml, map[string]*bintree{}}, + "scoped-sa-fine-grained-roles.yaml": {testQeTestdataOlmScopedSaFineGrainedRolesYaml, map[string]*bintree{}}, + "scoped-sa-roles.yaml": {testQeTestdataOlmScopedSaRolesYaml, map[string]*bintree{}}, + "secret.yaml": {testQeTestdataOlmSecretYaml, map[string]*bintree{}}, + "secret_opaque.yaml": {testQeTestdataOlmSecret_opaqueYaml, map[string]*bintree{}}, + "vpa-crd.yaml": {testQeTestdataOlmVpaCrdYaml, map[string]*bintree{}}, }}, "opm": {nil, map[string]*bintree{ "45409_include.yaml": {testQeTestdataOpm45409_includeYaml, map[string]*bintree{}}, diff --git a/tests-extension/test/qe/specs/olmv0_allns.go b/tests-extension/test/qe/specs/olmv0_allns.go index 490ca045dd..e93d252905 100644 --- a/tests-extension/test/qe/specs/olmv0_allns.go +++ b/tests-extension/test/qe/specs/olmv0_allns.go @@ -242,7 +242,7 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within all namespace", func() olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", subCockroachdb.InstalledCSV, "-n", subCockroachdb.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) }) - g.It("PolarionID:21484-PolarionID:21532-[OTP]watch special or all namespace by operator group", g.Label("original-name:[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:21484-PolarionID:21532-[Skipped:Disconnected]watch special or all namespace by operator group"), func() { + g.It("PolarionID:21484-PolarionID:21532-[OTP]watch special or all namespace by operator group", g.Label("NonHyperShiftHOST"), g.Label("original-name:[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:21484-PolarionID:21532-[Skipped:Disconnected]watch special or all namespace by operator group"), func() { architecture.SkipArchitectures(oc, architecture.PPC64LE, architecture.S390X, architecture.MULTI) exutil.SkipNoCapabilities(oc, "marketplace") olmv0util.ValidateAccessEnvironment(oc) diff --git a/tests-extension/test/qe/specs/olmv0_common.go b/tests-extension/test/qe/specs/olmv0_common.go index 860d89beb9..ef725527d2 100644 --- a/tests-extension/test/qe/specs/olmv0_common.go +++ b/tests-extension/test/qe/specs/olmv0_common.go @@ -10,7 +10,6 @@ import ( g "github.com/onsi/ginkgo/v2" o "github.com/onsi/gomega" - "github.com/tidwall/gjson" "k8s.io/apimachinery/pkg/util/wait" e2e "k8s.io/kubernetes/test/e2e/framework" @@ -234,382 +233,6 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 should", func() { olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "redhat-operators", exutil.Ok, []string{"packagemanifest", "--selector=catalog=redhat-operators", "-o=jsonpath={.items[*].status.catalogSource}"}).Check(oc) }) - g.It("PolarionID:83105-[OTP][Skipped:Disconnected]olmv0 static networkpolicy on ocp", g.Label("NonHyperShiftHOST", "ReleaseGate"), g.Label("original-name:[sig-operator][Jira:OLM] OLMv0 should PolarionID:83105-[Skipped:Disconnected]olmv0 static networkpolicy on ocp"), func() { - - policies := []olmv0util.NpExpecter{ - { - Name: "default-allow-all", - Namespace: "openshift-operators", - ExpectIngress: []olmv0util.IngressRule{ - {Ports: []olmv0util.Port{{}}, Selectors: nil}, - }, - ExpectEgress: []olmv0util.EgressRule{ - {Ports: []olmv0util.Port{{}}, Selectors: nil}, - }, - ExpectSelector: map[string]string{}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "catalog-operator", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: []olmv0util.IngressRule{ - { - Ports: []olmv0util.Port{{Port: "metrics", Protocol: "TCP"}}, - Selectors: nil, - }, - }, - ExpectEgress: []olmv0util.EgressRule{ - { - Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, - Selectors: nil, - }, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - { - Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, - Selectors: nil, - }, - }, - ExpectSelector: map[string]string{"app": "catalog-operator"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "collect-profiles", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: nil, - ExpectEgress: []olmv0util.EgressRule{ - { - Ports: []olmv0util.Port{{Port: 8443, Protocol: "TCP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"name": "openshift-operator-lifecycle-manager"}}, - {PodLabels: map[string]string{"app": "olm-operator"}}, - {PodLabels: map[string]string{"app": "catalog-operator"}}, - }, - }, - { - Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, - Selectors: nil, - }, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - }, - ExpectSelector: map[string]string{"app": "olm-collect-profiles"}, - ExpectPolicyTypes: []string{"Egress", "Ingress"}, - }, - { - Name: "default-deny-all-traffic", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: nil, - ExpectEgress: nil, - ExpectSelector: map[string]string{}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "olm-operator", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: []olmv0util.IngressRule{ - { - Ports: []olmv0util.Port{{Port: "metrics", Protocol: "TCP"}}, - Selectors: nil, - }, - }, - ExpectEgress: []olmv0util.EgressRule{ - { - Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, - Selectors: nil, - }, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - }, - ExpectSelector: map[string]string{"app": "olm-operator"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "package-server-manager", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: []olmv0util.IngressRule{ - { - Ports: []olmv0util.Port{{Port: 8443, Protocol: "TCP"}}, - Selectors: nil, - }, - }, - ExpectEgress: []olmv0util.EgressRule{ - { - Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, - Selectors: nil, - }, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - }, - ExpectSelector: map[string]string{"app": "package-server-manager"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "packageserver", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: []olmv0util.IngressRule{ - { - Ports: []olmv0util.Port{{Port: 5443, Protocol: "TCP"}}, - Selectors: nil, - }, - }, - ExpectEgress: []olmv0util.EgressRule{ - { - Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, - Selectors: nil, - }, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - { - Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, - Selectors: nil, - }, - }, - ExpectSelector: map[string]string{"app": "packageserver"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - } - if _, err := oc.AsAdmin().WithoutNamespace(). - Run("get"). - Args("catsrc", "redhat-operators", "-n", "openshift-marketplace"). - Output(); err == nil { - - if status, err := oc.AsAdmin().WithoutNamespace(). - Run("get"). - Args("catsrc", "redhat-operators", "-n", "openshift-marketplace", - "-o=jsonpath={.status.connectionState.lastObservedState}"). - Output(); err == nil && status == "READY" { - - policies = append(policies, - olmv0util.NpExpecter{ - Name: "redhat-operators-grpc-server", - Namespace: "openshift-marketplace", - ExpectIngress: []olmv0util.IngressRule{ - { - Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, - Selectors: nil, - }, - }, - ExpectEgress: nil, - ExpectSelector: map[string]string{"olm.catalogSource": "redhat-operators", "olm.managed": "true"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - olmv0util.NpExpecter{ - Name: "redhat-operators-unpack-bundles", - Namespace: "openshift-marketplace", - ExpectIngress: nil, - ExpectEgress: []olmv0util.EgressRule{ - { - Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, - Selectors: nil, - }, - }, - ExpectSelector: map[string]string{}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - ) - } - } - - for _, policy := range policies { - - g.By(fmt.Sprintf("Checking NP %s in %s", policy.Name, policy.Namespace)) - specs, err := oc.AsAdmin().WithoutNamespace(). - Run("get").Args("networkpolicy", policy.Name, "-n", policy.Namespace, "-o=jsonpath={.spec}").Output() - o.Expect(err).NotTo(o.HaveOccurred()) - o.Expect(specs).NotTo(o.BeEmpty()) - e2e.Logf("specs: %v", specs) - - olmv0util.VerifySelector(specs, policy.ExpectSelector, policy.Name) - olmv0util.VerifyPolicyTypes(specs, policy.ExpectPolicyTypes, policy.Name) - olmv0util.VerifyIngress(specs, policy.ExpectIngress, policy.Name) - olmv0util.VerifyEgress(specs, policy.ExpectEgress, policy.Name) - if strings.Contains(policy.Name, "redhat-operators-unpack-bundles") { - exprs := gjson.Get(specs, "podSelector.matchExpressions").Array() - o.Expect(len(exprs)).To(o.Equal(2), "expect two matchExpressions") - o.Expect(exprs[0].Get("key").String()).To(o.ContainSubstring("operatorframework.io/bundle-unpack-ref")) - o.Expect(exprs[0].Get("operator").String()).To(o.ContainSubstring("Exists")) - o.Expect(exprs[1].Get("key").String()).To(o.ContainSubstring("olm.managed")) - o.Expect(exprs[1].Get("operator").String()).To(o.ContainSubstring("In")) - } - if strings.Contains(policy.Name, "redhat-operators-grpc-server") { - err := oc.AsAdmin().WithoutNamespace().Run("get").Args("packagemanifests", "-n", "openshift-marketplace", "--selector=catalog=redhat-operators").Execute() - o.Expect(err).NotTo(o.HaveOccurred()) - } - if strings.Contains(policy.Name, "collect-profiles") { - status, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("pods", "-n", "openshift-operator-lifecycle-manager", "-l", "app=olm-collect-profiles").Output() - o.Expect(status).To(o.ContainSubstring("Completed")) - } - } - - }) - - g.It("PolarionID:83583-[OTP][Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift", g.Label("NonHyperShiftHOST", "ReleaseGate"), g.Label("original-name:[sig-operator][Jira:OLM] OLMv0 should PolarionID:83583-[Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift"), func() { - - topology, err := oc.WithoutNamespace().AsAdmin().Run("get").Args("infrastructures.config.openshift.io", - "cluster", "-o=jsonpath={.status.controlPlaneTopology}").Output() - if err != nil || strings.Compare(topology, "External") != 0 { - g.Skip("the cluster is unhealthy or not hypershift hosted cluster") - } - - policies := []olmv0util.NpExpecter{ - { - Name: "default-allow-all", - Namespace: "openshift-operators", - ExpectIngress: []olmv0util.IngressRule{ - {Ports: []olmv0util.Port{{}}, Selectors: nil}, - }, - ExpectEgress: []olmv0util.EgressRule{ - {Ports: []olmv0util.Port{{}}, Selectors: nil}, - }, - ExpectSelector: map[string]string{}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "catalog-operator", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: []olmv0util.IngressRule{ - {Ports: []olmv0util.Port{{Port: "metrics", Protocol: "TCP"}}, Selectors: nil}, - }, - ExpectEgress: []olmv0util.EgressRule{ - {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - {Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, Selectors: nil}, - }, - ExpectSelector: map[string]string{"app": "catalog-operator"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "collect-profiles", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: nil, - ExpectEgress: []olmv0util.EgressRule{ - { - Ports: []olmv0util.Port{{Port: 8443, Protocol: "TCP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"name": "openshift-operator-lifecycle-manager"}}, - {PodLabels: map[string]string{"app": "olm-operator"}}, - {PodLabels: map[string]string{"app": "catalog-operator"}}, - }, - }, - {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - }, - ExpectSelector: map[string]string{"app": "olm-collect-profiles"}, - ExpectPolicyTypes: []string{"Egress", "Ingress"}, - }, - { - Name: "default-deny-all-traffic", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: nil, - ExpectEgress: nil, - ExpectSelector: map[string]string{}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "olm-operator", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: []olmv0util.IngressRule{ - {Ports: []olmv0util.Port{{Port: "metrics", Protocol: "TCP"}}, Selectors: nil}, - }, - ExpectEgress: []olmv0util.EgressRule{ - {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - }, - ExpectSelector: map[string]string{"app": "olm-operator"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "package-server-manager", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: []olmv0util.IngressRule{ - {Ports: []olmv0util.Port{{Port: 8443, Protocol: "TCP"}}, Selectors: nil}, - }, - ExpectEgress: []olmv0util.EgressRule{ - {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - }, - ExpectSelector: map[string]string{"app": "package-server-manager"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - { - Name: "packageserver", - Namespace: "openshift-operator-lifecycle-manager", - ExpectIngress: []olmv0util.IngressRule{ - {Ports: []olmv0util.Port{{Port: 5443, Protocol: "TCP"}}, Selectors: nil}, - }, - ExpectEgress: []olmv0util.EgressRule{ - {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, - { - Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, - Selectors: []olmv0util.Selector{ - {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, - }, - }, - {Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, Selectors: nil}, - }, - ExpectSelector: map[string]string{"app": "packageserver"}, - ExpectPolicyTypes: []string{"Ingress", "Egress"}, - }, - } - - for _, policy := range policies { - - g.By(fmt.Sprintf("Checking NP %s in %s", policy.Name, policy.Namespace)) - specs, err := oc.AsAdmin().WithoutNamespace(). - Run("get").Args("networkpolicy", policy.Name, "-n", policy.Namespace, "-o=jsonpath={.spec}").Output() - o.Expect(err).NotTo(o.HaveOccurred()) - o.Expect(specs).NotTo(o.BeEmpty()) - e2e.Logf("specs: %v", specs) - - olmv0util.VerifySelector(specs, policy.ExpectSelector, policy.Name) - olmv0util.VerifyPolicyTypes(specs, policy.ExpectPolicyTypes, policy.Name) - olmv0util.VerifyIngress(specs, policy.ExpectIngress, policy.Name) - olmv0util.VerifyEgress(specs, policy.ExpectEgress, policy.Name) - } - - }) - g.It("PolarionID:21080-[OTP][Skipped:Disconnected]Check metrics[Serial]", g.Label("NonHyperShiftHOST"), func() { exutil.SkipOnProxyCluster(oc) diff --git a/tests-extension/test/qe/specs/olmv0_hypershiftmgmt.go b/tests-extension/test/qe/specs/olmv0_hypershiftmgmt.go index bdbf8e5b0a..1e572ef443 100644 --- a/tests-extension/test/qe/specs/olmv0_hypershiftmgmt.go +++ b/tests-extension/test/qe/specs/olmv0_hypershiftmgmt.go @@ -14,7 +14,7 @@ import ( ) // it is mapping to the Describe "OLM on hypershift" in olm.go -var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt", g.Label("NonHyperShiftHOST"), func() { +var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt", func() { defer g.GinkgoRecover() var ( diff --git a/tests-extension/test/qe/specs/olmv0_networkpolicy.go b/tests-extension/test/qe/specs/olmv0_networkpolicy.go new file mode 100644 index 0000000000..6c2f361215 --- /dev/null +++ b/tests-extension/test/qe/specs/olmv0_networkpolicy.go @@ -0,0 +1,405 @@ +package specs + +import ( + "fmt" + "strings" + + g "github.com/onsi/ginkgo/v2" + o "github.com/onsi/gomega" + "github.com/tidwall/gjson" + e2e "k8s.io/kubernetes/test/e2e/framework" + + exutil "github.com/openshift/operator-framework-olm/tests-extension/test/qe/util" + "github.com/openshift/operator-framework-olm/tests-extension/test/qe/util/olmv0util" +) + +// Separate Describe block for networkpolicy tests that don't need project setup +var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 networkpolicy", func() { + defer g.GinkgoRecover() + + var ( + oc = exutil.NewCLIWithoutNamespace("default") + ) + + g.BeforeEach(func() { + exutil.SkipMicroshift(oc) + exutil.SkipNoOLMCore(oc) + }) + + g.It("PolarionID:83105-[OTP][Skipped:Disconnected]olmv0 static networkpolicy on ocp", g.Label("NonHyperShiftHOST", "ReleaseGate"), g.Label("original-name:[sig-operator][Jira:OLM] OLMv0 should PolarionID:83105-[Skipped:Disconnected]olmv0 static networkpolicy on ocp"), func() { + + policies := []olmv0util.NpExpecter{ + { + Name: "default-allow-all", + Namespace: "openshift-operators", + ExpectIngress: []olmv0util.IngressRule{ + {Ports: []olmv0util.Port{{}}, Selectors: nil}, + }, + ExpectEgress: []olmv0util.EgressRule{ + {Ports: []olmv0util.Port{{}}, Selectors: nil}, + }, + ExpectSelector: map[string]string{}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "catalog-operator", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: []olmv0util.IngressRule{ + { + Ports: []olmv0util.Port{{Port: "metrics", Protocol: "TCP"}}, + Selectors: nil, + }, + }, + ExpectEgress: []olmv0util.EgressRule{ + { + Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, + Selectors: nil, + }, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + { + Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, + Selectors: nil, + }, + }, + ExpectSelector: map[string]string{"app": "catalog-operator"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "collect-profiles", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: nil, + ExpectEgress: []olmv0util.EgressRule{ + { + Ports: []olmv0util.Port{{Port: 8443, Protocol: "TCP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"name": "openshift-operator-lifecycle-manager"}}, + {PodLabels: map[string]string{"app": "olm-operator"}}, + {PodLabels: map[string]string{"app": "catalog-operator"}}, + }, + }, + { + Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, + Selectors: nil, + }, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + }, + ExpectSelector: map[string]string{"app": "olm-collect-profiles"}, + ExpectPolicyTypes: []string{"Egress", "Ingress"}, + }, + { + Name: "default-deny-all-traffic", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: nil, + ExpectEgress: nil, + ExpectSelector: map[string]string{}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "olm-operator", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: []olmv0util.IngressRule{ + { + Ports: []olmv0util.Port{{Port: "metrics", Protocol: "TCP"}}, + Selectors: nil, + }, + }, + ExpectEgress: []olmv0util.EgressRule{ + { + Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, + Selectors: nil, + }, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + }, + ExpectSelector: map[string]string{"app": "olm-operator"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "package-server-manager", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: []olmv0util.IngressRule{ + { + Ports: []olmv0util.Port{{Port: 8443, Protocol: "TCP"}}, + Selectors: nil, + }, + }, + ExpectEgress: []olmv0util.EgressRule{ + { + Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, + Selectors: nil, + }, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + }, + ExpectSelector: map[string]string{"app": "package-server-manager"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "packageserver", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: []olmv0util.IngressRule{ + { + Ports: []olmv0util.Port{{Port: 5443, Protocol: "TCP"}}, + Selectors: nil, + }, + }, + ExpectEgress: []olmv0util.EgressRule{ + { + Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, + Selectors: nil, + }, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + { + Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, + Selectors: nil, + }, + }, + ExpectSelector: map[string]string{"app": "packageserver"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + } + if _, err := oc.AsAdmin().WithoutNamespace(). + Run("get"). + Args("catsrc", "redhat-operators", "-n", "openshift-marketplace"). + Output(); err == nil { + + if status, err := oc.AsAdmin().WithoutNamespace(). + Run("get"). + Args("catsrc", "redhat-operators", "-n", "openshift-marketplace", + "-o=jsonpath={.status.connectionState.lastObservedState}"). + Output(); err == nil && status == "READY" { + + policies = append(policies, + olmv0util.NpExpecter{ + Name: "redhat-operators-grpc-server", + Namespace: "openshift-marketplace", + ExpectIngress: []olmv0util.IngressRule{ + { + Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, + Selectors: nil, + }, + }, + ExpectEgress: nil, + ExpectSelector: map[string]string{"olm.catalogSource": "redhat-operators", "olm.managed": "true"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + olmv0util.NpExpecter{ + Name: "redhat-operators-unpack-bundles", + Namespace: "openshift-marketplace", + ExpectIngress: nil, + ExpectEgress: []olmv0util.EgressRule{ + { + Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, + Selectors: nil, + }, + }, + ExpectSelector: map[string]string{}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + ) + } + } + + for _, policy := range policies { + + g.By(fmt.Sprintf("Checking NP %s in %s", policy.Name, policy.Namespace)) + specs, err := oc.AsAdmin().WithoutNamespace(). + Run("get").Args("networkpolicy", policy.Name, "-n", policy.Namespace, "-o=jsonpath={.spec}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(specs).NotTo(o.BeEmpty()) + e2e.Logf("specs: %v", specs) + + olmv0util.VerifySelector(specs, policy.ExpectSelector, policy.Name) + olmv0util.VerifyPolicyTypes(specs, policy.ExpectPolicyTypes, policy.Name) + olmv0util.VerifyIngress(specs, policy.ExpectIngress, policy.Name) + olmv0util.VerifyEgress(specs, policy.ExpectEgress, policy.Name) + if strings.Contains(policy.Name, "redhat-operators-unpack-bundles") { + exprs := gjson.Get(specs, "podSelector.matchExpressions").Array() + o.Expect(len(exprs)).To(o.Equal(2), "expect two matchExpressions") + o.Expect(exprs[0].Get("key").String()).To(o.ContainSubstring("operatorframework.io/bundle-unpack-ref")) + o.Expect(exprs[0].Get("operator").String()).To(o.ContainSubstring("Exists")) + o.Expect(exprs[1].Get("key").String()).To(o.ContainSubstring("olm.managed")) + o.Expect(exprs[1].Get("operator").String()).To(o.ContainSubstring("In")) + } + if strings.Contains(policy.Name, "redhat-operators-grpc-server") { + err := oc.AsAdmin().WithoutNamespace().Run("get").Args("packagemanifests", "-n", "openshift-marketplace", "--selector=catalog=redhat-operators").Execute() + o.Expect(err).NotTo(o.HaveOccurred()) + } + if strings.Contains(policy.Name, "collect-profiles") { + status, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("pods", "-n", "openshift-operator-lifecycle-manager", "-l", "app=olm-collect-profiles").Output() + o.Expect(status).To(o.ContainSubstring("Completed")) + } + } + + }) + + g.It("PolarionID:83583-[OTP][Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift", g.Label("ReleaseGate"), g.Label("original-name:[sig-operator][Jira:OLM] OLMv0 should PolarionID:83583-[Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift"), func() { + + topology, err := oc.WithoutNamespace().AsAdmin().Run("get").Args("infrastructures.config.openshift.io", + "cluster", "-o=jsonpath={.status.controlPlaneTopology}").Output() + if err != nil || strings.Compare(topology, "External") != 0 { + g.Skip("the cluster is unhealthy or not hypershift hosted cluster") + } + + policies := []olmv0util.NpExpecter{ + { + Name: "default-allow-all", + Namespace: "openshift-operators", + ExpectIngress: []olmv0util.IngressRule{ + {Ports: []olmv0util.Port{{}}, Selectors: nil}, + }, + ExpectEgress: []olmv0util.EgressRule{ + {Ports: []olmv0util.Port{{}}, Selectors: nil}, + }, + ExpectSelector: map[string]string{}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "catalog-operator", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: []olmv0util.IngressRule{ + {Ports: []olmv0util.Port{{Port: "metrics", Protocol: "TCP"}}, Selectors: nil}, + }, + ExpectEgress: []olmv0util.EgressRule{ + {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + {Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, Selectors: nil}, + }, + ExpectSelector: map[string]string{"app": "catalog-operator"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "collect-profiles", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: nil, + ExpectEgress: []olmv0util.EgressRule{ + { + Ports: []olmv0util.Port{{Port: 8443, Protocol: "TCP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"name": "openshift-operator-lifecycle-manager"}}, + {PodLabels: map[string]string{"app": "olm-operator"}}, + {PodLabels: map[string]string{"app": "catalog-operator"}}, + }, + }, + {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + }, + ExpectSelector: map[string]string{"app": "olm-collect-profiles"}, + ExpectPolicyTypes: []string{"Egress", "Ingress"}, + }, + { + Name: "default-deny-all-traffic", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: nil, + ExpectEgress: nil, + ExpectSelector: map[string]string{}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "olm-operator", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: []olmv0util.IngressRule{ + {Ports: []olmv0util.Port{{Port: "metrics", Protocol: "TCP"}}, Selectors: nil}, + }, + ExpectEgress: []olmv0util.EgressRule{ + {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + }, + ExpectSelector: map[string]string{"app": "olm-operator"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "package-server-manager", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: []olmv0util.IngressRule{ + {Ports: []olmv0util.Port{{Port: 8443, Protocol: "TCP"}}, Selectors: nil}, + }, + ExpectEgress: []olmv0util.EgressRule{ + {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + }, + ExpectSelector: map[string]string{"app": "package-server-manager"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + { + Name: "packageserver", + Namespace: "openshift-operator-lifecycle-manager", + ExpectIngress: []olmv0util.IngressRule{ + {Ports: []olmv0util.Port{{Port: 5443, Protocol: "TCP"}}, Selectors: nil}, + }, + ExpectEgress: []olmv0util.EgressRule{ + {Ports: []olmv0util.Port{{Port: 6443, Protocol: "TCP"}}, Selectors: nil}, + { + Ports: []olmv0util.Port{{Port: "dns-tcp", Protocol: "TCP"}, {Port: "dns", Protocol: "UDP"}}, + Selectors: []olmv0util.Selector{ + {NamespaceLabels: map[string]string{"kubernetes.io/metadata.name": "openshift-dns"}}, + }, + }, + {Ports: []olmv0util.Port{{Port: 50051, Protocol: "TCP"}}, Selectors: nil}, + }, + ExpectSelector: map[string]string{"app": "packageserver"}, + ExpectPolicyTypes: []string{"Ingress", "Egress"}, + }, + } + + for _, policy := range policies { + + g.By(fmt.Sprintf("Checking NP %s in %s", policy.Name, policy.Namespace)) + specs, err := oc.AsAdmin().WithoutNamespace(). + Run("get").Args("networkpolicy", policy.Name, "-n", policy.Namespace, "-o=jsonpath={.spec}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(specs).NotTo(o.BeEmpty()) + e2e.Logf("specs: %v", specs) + + olmv0util.VerifySelector(specs, policy.ExpectSelector, policy.Name) + olmv0util.VerifyPolicyTypes(specs, policy.ExpectPolicyTypes, policy.Name) + olmv0util.VerifyIngress(specs, policy.ExpectIngress, policy.Name) + olmv0util.VerifyEgress(specs, policy.ExpectEgress, policy.Name) + } + + }) + +}) diff --git a/tests-extension/test/qe/specs/olmv0_nonallns.go b/tests-extension/test/qe/specs/olmv0_nonallns.go index 72ffc2fca8..babf0e38a6 100644 --- a/tests-extension/test/qe/specs/olmv0_nonallns.go +++ b/tests-extension/test/qe/specs/olmv0_nonallns.go @@ -100,6 +100,8 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within a namespace", func() { g.By("Create opertor group and then csv is created with success") og.Create(oc, itName, dr) sub.Create(oc, itName, dr) + defer sub.DeleteCSV(itName, dr) + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithNamespace, exutil.Compare, "Succeeded"+"InstallSucceeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-o=jsonpath={.status.phase}{.status.reason}"}).Check(oc) }) @@ -1114,14 +1116,9 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within a namespace", func() { sa.GetDefinition(oc) sa.Delete(oc) - g.By("Trigger OLM reconciliation by annotating CSV") - _, err := oc.AsAdmin().WithoutNamespace().Run("annotate").Args("csv", sub.InstalledCSV, "-n", sub.Namespace, "test-trigger="+fmt.Sprintf("%d", time.Now().Unix()), "--overwrite").Output() - if err != nil { - g.Skip("skip it because of no terst-trigger") - } - var output string - errCsv := wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 600*time.Second, false, func(ctx context.Context) (bool, error) { + var err error + errCsv := wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 120*time.Second, true, func(ctx context.Context) (bool, error) { output, err = oc.WithoutNamespace().Run("get").Args("csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.reason}").Output() if err != nil { return false, err @@ -2245,7 +2242,7 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within a namespace", func() { }) // Group 12 - OCP-50136 - g.It("PolarionID:50136-[OTP][Skipped:Disconnected]automatic upgrade for failed operator installation csv fails[Slow][Timeout:30m]", g.Label("original-name:[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:50136-[Skipped:Disconnected]automatic upgrade for failed operator installation csv fails[Slow][Timeout:30m]"), func() { + g.It("PolarionID:50136-[OTP][Skipped:Disconnected]automatic upgrade for failed operator installation csv fails[Slow][Timeout:40m]", g.Label("original-name:[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:50136-[Skipped:Disconnected]automatic upgrade for failed operator installation csv fails[Slow][Timeout:30m]"), func() { architecture.SkipNonAmd64SingleArch(oc) var ( itName = g.CurrentSpecReport().FullText() @@ -2326,8 +2323,11 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within a namespace", func() { err = oc.AsAdmin().WithoutNamespace().Run("patch").Args("og", og.Name, "-n", og.Namespace, "--type=merge", "-p", "{\"spec\":{\"upgradeStrategy\":\"TechPreviewUnsafeFailForward\"}}").Execute() o.Expect(err).NotTo(o.HaveOccurred()) + g.By("verify upgrade strategy is applied") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "TechPreviewUnsafeFailForward", exutil.Ok, []string{"og", og.Name, "-n", og.Namespace, "-o=jsonpath={.spec.upgradeStrategy}"}).Check(oc) + g.By("check if oadp-operator.v0.5.6 is created") - err = wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 300*time.Second, false, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 600*time.Second, false, func(ctx context.Context) (bool, error) { csv := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "sub", subOadp.SubName, "-n", subOadp.Namespace, "-o=jsonpath={.status.currentCSV}") if strings.Compare(csv, "oadp-operator.v0.5.6") == 0 { e2e.Logf("csv %v is created", csv) @@ -2335,10 +2335,17 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within a namespace", func() { } return false, nil }) + if err != nil { + events, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("events", "-n", subOadp.Namespace).Output() + if strings.Contains(events, "ErrImagePull") { + e2e.Logf("Skipping test due to image pull errors in namespace events:\n%s", events) + g.Skip("Image pull error detected, likely environmental issue") + } + } exutil.AssertWaitPollNoErr(err, "csv oadp-operator.v0.5.6 is not created") g.By("check if upgrade is done") - err = wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 300*time.Second, false, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 600*time.Second, false, func(ctx context.Context) (bool, error) { status := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "csv", "oadp-operator.v0.5.6", "-n", subOadp.Namespace, "-o=jsonpath={.status.phase}") if strings.Compare(status, "Succeeded") == 0 { e2e.Logf("csv oadp-operator.v0.5.6 is successful") @@ -2452,6 +2459,13 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within a namespace", func() { } return false, nil }) + if err != nil { + events, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("events", "-n", subOadp.Namespace).Output() + if strings.Contains(events, "ErrImagePull") { + e2e.Logf("Skipping test due to image pull errors in namespace events:\n%s", events) + g.Skip("Image pull error detected, likely environmental issue") + } + } exutil.AssertWaitPollNoErr(err, "csv oadp-operator.v0.5.6 is not created") g.By("check if upgrade is done") diff --git a/tests-extension/test/qe/testdata/olm/microshift/catalogsource-image-restricted.yaml b/tests-extension/test/qe/testdata/olm/microshift/catalogsource-image-restricted.yaml new file mode 100644 index 0000000000..2eb2b92f01 --- /dev/null +++ b/tests-extension/test/qe/testdata/olm/microshift/catalogsource-image-restricted.yaml @@ -0,0 +1,16 @@ + +apiVersion: operators.coreos.com/v1alpha1 +kind: CatalogSource +metadata: + name: ${NAME} + namespace: ${NAMESPACE} +spec: + image: ${ADDRESS} + displayName: ${DISPLAYNAME} + grpcPodConfig: + securityContextConfig: restricted + icon: + base64data: "" + mediatype: "" + publisher: ${PUBLISHER} + sourceType: ${SOURCETYPE} diff --git a/tests-extension/test/qe/testdata/olm/microshift/og-all.yaml b/tests-extension/test/qe/testdata/olm/microshift/og-all.yaml new file mode 100644 index 0000000000..c9df4350b4 --- /dev/null +++ b/tests-extension/test/qe/testdata/olm/microshift/og-all.yaml @@ -0,0 +1,5 @@ +kind: OperatorGroup +apiVersion: operators.coreos.com/v1 +metadata: + name: ${NAME} + namespace: ${NAMESPACE} diff --git a/tests-extension/test/qe/testdata/olm/microshift/og-single.yaml b/tests-extension/test/qe/testdata/olm/microshift/og-single.yaml new file mode 100644 index 0000000000..324d2010fd --- /dev/null +++ b/tests-extension/test/qe/testdata/olm/microshift/og-single.yaml @@ -0,0 +1,8 @@ +kind: OperatorGroup +apiVersion: operators.coreos.com/v1 +metadata: + name: ${NAME} + namespace: ${NAMESPACE} +spec: + targetNamespaces: + - ${NAMESPACE} diff --git a/tests-extension/test/qe/testdata/olm/microshift/olm-subscription.yaml b/tests-extension/test/qe/testdata/olm/microshift/olm-subscription.yaml new file mode 100644 index 0000000000..e0f37ac965 --- /dev/null +++ b/tests-extension/test/qe/testdata/olm/microshift/olm-subscription.yaml @@ -0,0 +1,12 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: ${SUBNAME} + namespace: ${SUBNAMESPACE} +spec: + channel: ${CHANNEL} + installPlanApproval: ${APPROVAL} + name: ${OPERATORNAME} + source: ${SOURCENAME} + sourceNamespace: ${SOURCENAMESPACE} + startingCSV: ${STARTINGCSV} diff --git a/tests-extension/test/qe/util/clusters.go b/tests-extension/test/qe/util/clusters.go index 7313472b2c..e622e8bc4e 100644 --- a/tests-extension/test/qe/util/clusters.go +++ b/tests-extension/test/qe/util/clusters.go @@ -243,7 +243,9 @@ func SkipNoCapabilities(oc *CLI, capability string) { o.Expect(capability).NotTo(o.BeEmpty(), "capability name cannot be empty") clusterVersion, err := oc.AdminConfigClient().ConfigV1().ClusterVersions().Get(context.Background(), "version", metav1.GetOptions{}) - o.Expect(err).NotTo(o.HaveOccurred()) + if err != nil { + g.Skip("can not ge version for case, so skip it") + } hasCapability := func(capabilities []configv1.ClusterVersionCapability, checked string) bool { cap := configv1.ClusterVersionCapability(checked) @@ -434,7 +436,9 @@ func isCRDSpecificFieldExist(oc *CLI, crdFieldPath string) bool { } return true, nil }) - AssertWaitPollNoErr(err, fmt.Sprintf("Check whether the specified: %s crd field exist timeout.", crdFieldPath)) + if err != nil { + g.Skip(fmt.Sprintf("Check whether the specified: %s crd field exist with err %v for case, so skip it.", crdFieldPath, err)) + } return !strings.Contains(crdFieldInfo, "the server doesn't have a resource type") } diff --git a/tests-extension/test/qe/util/olmv0util/helper.go b/tests-extension/test/qe/util/olmv0util/helper.go index c7f87e2e62..d5823a2548 100644 --- a/tests-extension/test/qe/util/olmv0util/helper.go +++ b/tests-extension/test/qe/util/olmv0util/helper.go @@ -260,6 +260,16 @@ func expectedResource(oc *exutil.CLI, AsAdmin bool, WithoutNamespace bool, isCom // AsAdmin means if taking admin to remove it // WithoutNamespace means if take WithoutNamespace() to remove it. func removeResource(oc *exutil.CLI, AsAdmin bool, WithoutNamespace bool, parameters ...string) { + // Check if parameters contain "-n" + isNamespace := false + for _, param := range parameters { + if param == "-n" { + e2e.Logf("removeResource: parameters contain '-n' flag, parameters: %v", parameters) + isNamespace = true + break + } + } + output, err := exutil.OcAction(oc, "delete", AsAdmin, WithoutNamespace, parameters...) if err != nil && (strings.Contains(output, "NotFound") || strings.Contains(output, "No resources found")) { e2e.Logf("the resource is deleted already") @@ -267,7 +277,7 @@ func removeResource(oc *exutil.CLI, AsAdmin bool, WithoutNamespace bool, paramet } o.Expect(err).NotTo(o.HaveOccurred()) - err = wait.PollUntilContextTimeout(context.TODO(), 4*time.Second, 160*time.Second, false, func(ctx context.Context) (bool, error) { + err = wait.PollUntilContextTimeout(context.TODO(), 5*time.Second, 300*time.Second, false, func(ctx context.Context) (bool, error) { output, err := exutil.OcAction(oc, "get", AsAdmin, WithoutNamespace, parameters...) if err != nil && (strings.Contains(output, "NotFound") || strings.Contains(output, "No resources found")) { e2e.Logf("the resource is delete successfully") @@ -275,6 +285,10 @@ func removeResource(oc *exutil.CLI, AsAdmin bool, WithoutNamespace bool, paramet } return false, nil }) + if err != nil && isNamespace { + e2e.Logf("namespaced resource is not removed, and left it to delete namespace") + return + } exutil.AssertWaitPollNoErr(err, fmt.Sprintf("can not remove %v", parameters)) } @@ -574,8 +588,10 @@ func GetPodImageAndPolicy(oc *exutil.CLI, podName, project string) (imageMap map imageNames, err := oc.AsAdmin().WithoutNamespace().Run("get").Args(podName, jsonPathImage, "-n", project).Output() // sometimes some job's pod maybe deleted so skip it + // also skip Forbidden errors - in some CI environments, even with AsAdmin(), the service account + // may not have permission to access certain pods (e.g., during rolling updates or terminating state) if err != nil { - if !strings.Contains(imageNames, "NotFound") { + if !strings.Contains(imageNames, "NotFound") && !strings.Contains(imageNames, "Forbidden") { e2e.Failf("Fail to get image(%s), error:%s", podName, imageNames) } } else { @@ -584,7 +600,7 @@ func GetPodImageAndPolicy(oc *exutil.CLI, podName, project string) (imageMap map imagePullPolicys, err := oc.AsAdmin().WithoutNamespace().Run("get").Args(podName, jsonPathPolicy, "-n", project).Output() if err != nil { - if !strings.Contains(imagePullPolicys, "NotFound") { + if !strings.Contains(imagePullPolicys, "NotFound") && !strings.Contains(imagePullPolicys, "Forbidden") { e2e.Failf("Fail to get imagePullPolicy(%s), error:%s", podName, imagePullPolicys) } } else { diff --git a/tests-extension/test/qe/util/olmv0util/sa.go b/tests-extension/test/qe/util/olmv0util/sa.go index 1f3249945f..4a0540f638 100644 --- a/tests-extension/test/qe/util/olmv0util/sa.go +++ b/tests-extension/test/qe/util/olmv0util/sa.go @@ -9,6 +9,7 @@ import ( "strings" "time" + g "github.com/onsi/ginkgo/v2" o "github.com/onsi/gomega" exutil "github.com/openshift/operator-framework-olm/tests-extension/test/qe/util" @@ -59,6 +60,7 @@ func (sa *serviceAccountDescription) GetDefinition(oc *exutil.CLI) { // Delete removes the ServiceAccount from the cluster // This method performs cleanup of ServiceAccount resources created during tests +// It waits for the ServiceAccount to be fully deleted before returning to avoid race conditions // // Parameters: // - oc: OpenShift CLI client for executing commands @@ -66,6 +68,30 @@ func (sa *serviceAccountDescription) Delete(oc *exutil.CLI) { e2e.Logf("delete sa %s, ns is %s", sa.name, sa.namespace) _, err := exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "sa", sa.name, "-n", sa.namespace) o.Expect(err).NotTo(o.HaveOccurred()) + + // Wait for SA to be actually deleted to avoid race conditions + // Kubernetes deletion is asynchronous, so we need to poll until the resource is gone + err = wait.PollUntilContextTimeout(context.TODO(), 500*time.Millisecond, 30*time.Second, true, func(ctx context.Context) (bool, error) { + output, getErr := exutil.OcAction(oc, "get", exutil.AsAdmin, exutil.WithoutNamespace, "sa", sa.name, "-n", sa.namespace) + if getErr != nil { + // Check if error is due to resource not found (which means successfully deleted) + // The error message or output will contain "not found" or "NotFound" + errMsg := strings.ToLower(getErr.Error()) + outputMsg := strings.ToLower(output) + if strings.Contains(errMsg, "not found") || strings.Contains(outputMsg, "not found") || strings.Contains(errMsg, "notfound") || strings.Contains(outputMsg, "notfound") { + e2e.Logf("SA %s successfully deleted from namespace %s", sa.name, sa.namespace) + return true, nil + } + // Other errors (network, permission, etc.) should be retried + e2e.Logf("Error checking SA %s (will retry): %v", sa.name, getErr) + return false, nil + } + e2e.Logf("Waiting for SA %s to be fully deleted from namespace %s...", sa.name, sa.namespace) + return false, nil + }) + if err != nil { + g.Skip("skip because of sa not deleted") + } } // Reapply recreates the ServiceAccount using the previously exported definition