From 7cddac0ccefb3d947b15c2da50833a11d9289ce0 Mon Sep 17 00:00:00 2001 From: Kui Wang Date: Thu, 30 Oct 2025 12:17:55 +0800 Subject: [PATCH] continue to migrate cases --- .../openshift_payload_olmv0.json | 651 ++++- tests-extension/cmd/main.go | 6 +- tests-extension/pkg/bindata/qe/bindata.go | 43 + tests-extension/test/qe/README.md | 1 - tests-extension/test/qe/specs/olmv0_allns.go | 406 +++ tests-extension/test/qe/specs/olmv0_common.go | 539 ++++ .../test/qe/specs/olmv0_microshift.go | 4 +- .../test/qe/specs/olmv0_multins.go | 153 + .../test/qe/specs/olmv0_nonallns.go | 2585 +++++++++++++++++ .../test/qe/testdata/olm/apiservice.yaml | 23 + .../test/qe/util/olmv0util/catalog_source.go | 7 +- 11 files changed, 4366 insertions(+), 52 deletions(-) create mode 100644 tests-extension/test/qe/testdata/olm/apiservice.yaml diff --git a/tests-extension/.openshift-tests-extension/openshift_payload_olmv0.json b/tests-extension/.openshift-tests-extension/openshift_payload_olmv0.json index ef9b9b54e6..5d84dedf90 100644 --- a/tests-extension/.openshift-tests-extension/openshift_payload_olmv0.json +++ b/tests-extension/.openshift-tests-extension/openshift_payload_olmv0.json @@ -9,16 +9,363 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:25783-[Skipped:Disconnected]Subscriptions are not getting processed taking very long to get processed[Serial]", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:21484-PolarionID:21532-[Skipped:Disconnected]watch special or all namespace by operator group", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:24906-[Skipped:Disconnected]Operators requesting cluster-scoped permission can trigger kube GC bug[Serial]", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:33241-[Skipped:Disconnected]Enable generated operator component adoption for operators with all ns mode[Serial]", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within all namespace PolarionID:22226-[Skipped:Disconnected]the csv without support AllNamespaces fails for og with allnamespace", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should pass a trivial sanity check", + "labels": { + "Extended": {}, + "ReleaseGate": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:22259-[Skipped:Disconnected]marketplace operator CR status on a running cluster[Serial]", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:73695-[Skipped:Disconnected]PO is disable", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:24076-check the version of olm operator is appropriate in ClusterOperator", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:29775-PolarionID:29786-[Skipped:Disconnected]as oc user on linux to mirror catalog image[Slow][Timeout:30m]", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:33452-[Skipped:Disconnected]oc adm catalog mirror does not mirror the index image itself", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:21825-[Skipped:Disconnected]Certs for packageserver can be rotated successfully [Serial]", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:83105-[Skipped:Disconnected]olmv0 static networkpolicy on ocp", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {}, + "ReleaseGate": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:83583-[Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {}, + "ReleaseGate": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 optional should PolarionID:68679-[Skipped:Disconnected]catalogsource with invalid name is created", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45381-[Skipped:Disconnected]Support custom catalogs in hypershift", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45408-[Skipped:Disconnected]Eliminate use of imagestreams in catalog management", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 on microshift PolarionID:69867-[Skipped:Disconnected]deployed in microshift and install one operator with single mode.", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 on microshift PolarionID:69868-[Skipped:Disconnected]olm microshift install operator with all mode, muilt og error and delete one og to get it installed.", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 on microshift PolarionID:83581-[Skipped:Disconnected]olmv0 networkpolicy on microshift.", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 with multi ns PolarionID:22226-[Skipped:Disconnected]the csv without support MultiNamespace fails for og with MultiNamespace", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 with multi ns PolarionID:71119-[Skipped:Disconnected]pod does not start for installing operator of multi-ns mode when og is in one of the ns[Serial]", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 with multi ns PolarionID:29275-[Skipped:Disconnected]label to target namespace of operator group with multi namespace", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:24870-[Skipped:Disconnected]can not create csv without operator group", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:22200-[Skipped:Disconnected]add minimum kube version to CSV [Slow]", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } }, { - "name": "[sig-operator][Jira:OLM] OLMv0 should pass a trivial sanity check", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:23473-[Skipped:Disconnected]permit z-stream releases skipping during operator updates", "labels": { - "Extended": {}, - "ReleaseGate": {} + "Extended": {} }, "resources": { "isolation": {} @@ -28,7 +375,31 @@ "environmentSelector": {} }, { - "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:22259-[Skipped:Disconnected]marketplace operator CR status on a running cluster[Serial]", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:37263-[Skipped:Disconnected][Skipped:Proxy]Subscription stays in UpgradePending but InstallPlan not installing [Slow]", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:29231-PolarionID:29277-label to target namespace of group", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:25855-[Skipped:Disconnected][Serial]Add the channel field to subscription_sync_count", "labels": { "Extended": {}, "NonHyperShiftHOST": {} @@ -37,13 +408,13 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } }, { - "name": "[sig-operator][Jira:OLM] OLMv0 should PolarionID:73695-[Skipped:Disconnected]PO is disable", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:23170-[Skipped:Disconnected]API labels should be hash", "labels": { "Extended": {} }, @@ -51,11 +422,11 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": {} }, { - "name": "[sig-operator][Jira:OLM] OLMv0 optional should PolarionID:68679-[Skipped:Disconnected]catalogsource with invalid name is created", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:20979-[Skipped:Disconnected]only one IP is generated", "labels": { "Extended": {}, "NonHyperShiftHOST": {} @@ -64,13 +435,13 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } }, { - "name": "[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45381-[Skipped:Disconnected]Support custom catalogs in hypershift", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:25757-PolarionID:22656-[Skipped:Disconnected]manual approval strategy apply to subsequent releases", "labels": { "Extended": {}, "NonHyperShiftHOST": {} @@ -79,13 +450,13 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } }, { - "name": "[sig-operator][Jira:OLM] OLMv0 on hypershift mgmt PolarionID:45408-[Skipped:Disconnected]Eliminate use of imagestreams in catalog management", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:24438-[Skipped:Disconnected]check subscription CatalogSource Status", "labels": { "Extended": {}, "NonHyperShiftHOST": {} @@ -94,13 +465,37 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } }, { - "name": "[sig-operator][Jira:OLM] OLMv0 on microshift PolarionID:69867-[Skipped:Disconnected]deployed in microshift and install one operator with single mode.", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:24027-[Skipped:Disconnected]can create and delete catalogsource and sub repeatedly", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:21404-[Skipped:Disconnected]csv will be RequirementsNotMet after sa is delete", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:29723-[Skipped:Disconnected]As cluster admin find abnormal status condition via components of operator resource", "labels": { "Extended": {}, "NonHyperShiftHOST": {} @@ -109,13 +504,85 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } }, { - "name": "[sig-operator][Jira:OLM] OLMv0 on microshift PolarionID:69868-[Skipped:Disconnected]olm microshift install operator with all mode, muilt og error and delete one og to get it installed.", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:30762-[Skipped:Disconnected]installs bundles with v1 CRDs", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:27683-[Skipped:Disconnected]InstallPlans can install from extracted bundles", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:24513-[Skipped:Disconnected]Operator config support env only", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:24382-[Skipped:Disconnected]Should restrict CRD update if schema changes[Serial]", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:25760-[Skipped:Disconnected]Operator upgrades does not fail after change the channel", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:35895-[Skipped:Disconnected]can't install a CSV with duplicate roles", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:32863-[Skipped:Disconnected]Support resources required for SAP Gardener Control Plane Operator[Serial][Disruptive]", "labels": { "Extended": {}, "NonHyperShiftHOST": {} @@ -124,13 +591,25 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } }, { - "name": "[sig-operator][Jira:OLM] OLMv0 on microshift PolarionID:83581-[Skipped:Disconnected]olmv0 networkpolicy on microshift.", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:34472-[Skipped:Disconnected]olm label dependency", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:33176-[Skipped:Disconnected]Enable generated operator component adoption for operators with single ns mode[Slow][Serial]", "labels": { "Extended": {}, "NonHyperShiftHOST": {} @@ -139,13 +618,13 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } }, { - "name": "[sig-operator][Jira:OLM] OLMv0 with multi ns PolarionID:22226-[Skipped:Disconnected]the csv without support MultiNamespace fails for og with MultiNamespace", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:39897-[Skipped:Disconnected]operator objects should not be recreated after all other associated resources have been deleted[Serial]", "labels": { "Extended": {} }, @@ -153,11 +632,11 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": {} }, { - "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:24870-[Skipped:Disconnected]can not create csv without operator group", + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:50135-[Skipped:Disconnected]automatic upgrade for failed operator installation og created correctly", "labels": { "Extended": {} }, @@ -165,11 +644,50 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": {} }, { - "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:37263-[Skipped:Disconnected][Skipped:Proxy]Subscription stays in UpgradePending but InstallPlan not installing [Slow]", + "name": "[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": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:50138-[Skipped:Disconnected]automatic upgrade for failed operator installation ip fails", + "labels": { + "Extended": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": {} + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:40958-[Skipped:Disconnected]Indicate invalid OperatorGroup on InstallPlan status", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:60114-[Skipped:Disconnected]olm serves an api to discover all versions of an operator[Slow]", "labels": { "Extended": {} }, @@ -177,9 +695,54 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": {} }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:62974-olm sets invalid scc label on its namespaces", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:62973-[Skipped:Disconnected]dedicated way collect profiles cronjob pod missing target.workload.openshift.io management annotation[Serial][Disruptive][Slow]", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, + { + "name": "[sig-operator][Jira:OLM] OLMv0 within a namespace PolarionID:62973-general way collect profiles cronjob pod missing target.workload.openshift.io management annotation", + "labels": { + "Extended": {}, + "NonHyperShiftHOST": {} + }, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:olmv0", + "lifecycle": "blocking", + "environmentSelector": { + "exclude": "topology==\"External\"" + } + }, { "name": "[sig-operator][Jira:OLM] OLMv0 opm should PolarionID:43185-DC based opm subcommands out of alpha", "labels": { @@ -191,7 +754,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -207,7 +770,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -223,7 +786,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -239,7 +802,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -255,7 +818,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -271,7 +834,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -287,7 +850,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -303,7 +866,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -319,7 +882,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -335,7 +898,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -351,7 +914,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -367,7 +930,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -383,7 +946,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -399,7 +962,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -415,7 +978,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -431,7 +994,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -447,7 +1010,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } @@ -463,7 +1026,7 @@ "isolation": {} }, "source": "openshift:payload:olmv0", - "lifecycle": "informing", + "lifecycle": "blocking", "environmentSelector": { "exclude": "topology==\"External\"" } diff --git a/tests-extension/cmd/main.go b/tests-extension/cmd/main.go index 6ba22dc783..9da53ae216 100644 --- a/tests-extension/cmd/main.go +++ b/tests-extension/cmd/main.go @@ -215,9 +215,9 @@ func main() { specs = specs.Walk(func(spec *et.ExtensionTestSpec) { if spec.Labels.Has("Extended") { // Change blocking tests to informing unless marked as ReleaseGate - if !spec.Labels.Has("ReleaseGate") && spec.Lifecycle == "blocking" { - spec.Lifecycle = "informing" - } + // if !spec.Labels.Has("ReleaseGate") && spec.Lifecycle == "blocking" { + // spec.Lifecycle = "informing" + // } // Exclude External topology for NonHyperShiftHOST tests if spec.Labels.Has("NonHyperShiftHOST") { spec.Exclude(et.TopologyEquals("External")) diff --git a/tests-extension/pkg/bindata/qe/bindata.go b/tests-extension/pkg/bindata/qe/bindata.go index 0e1f80f68a..c4d9ccfee0 100644 --- a/tests-extension/pkg/bindata/qe/bindata.go +++ b/tests-extension/pkg/bindata/qe/bindata.go @@ -1,5 +1,6 @@ // Code generated for package testdata by go-bindata DO NOT EDIT. (@generated) // sources: +// test/qe/testdata/olm/apiservice.yaml // test/qe/testdata/olm/catalogsource-address.yaml // test/qe/testdata/olm/catalogsource-configmap.yaml // test/qe/testdata/olm/catalogsource-image-cacheless.yaml @@ -191,6 +192,46 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } +var _testQeTestdataOlmApiserviceYaml = []byte(`apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: apiservice-template +objects: +- kind: APIService + apiVersion: apiregistration.k8s.io/v1 + metadata: + name: "${NAME}" + spec: + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJaekNDQVE2Z0F3SUJBZ0lJTjRRUFRuVnJWK2t3Q2dZSUtvWkl6ajBFQXdJd0dERVdNQlFHQTFVRUNoTU4KVW1Wa0lFaGhkQ3dnU1c1akxqQWVGdzB5TURBMk1qSXhOREE1TWpSYUZ3MHlNakEyTWpJeE5EQTVNalJhTUJneApGakFVQmdOVkJBb1REVkpsWkNCSVlYUXNJRWx1WXk0d1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DCkFBUmVkUlVESkhGb2gzTThYcEYxTzN1RXRCWU9ZeW1vMEdPTjN6WC91dHNpRlM3YnZ1Tmk2UEE0NC9teGZlT3oKUENrdDBRWitWUWp0MnE3UHhHdzZ4YkZwbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZdwpGQVlJS3dZQkJRVUhBd0lHQ0NzR0FRVUZCd01CTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3Q2dZSUtvWkl6ajBFCkF3SURSd0F3UkFJZ0NxY2tjdE1Tc1hYQi9PQ0hwQjlkSmZSRmZMYmJNOFQ1Q3J3dGlBNTlRYW9DSUdRSlh1TnkKUVlBUnczUmNLUXI1ZnNQM1JhMElRaUNORzNveUZXaVg1Y3RSCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + group: foos.bar.com + groupPriorityMinimum: 2000 + service: + name: foo + namespace: bar + port: 5443 + version: "${VERSION}" + versionPriority: 15 +parameters: +- name: NAME +- name: VERSION + +`) + +func testQeTestdataOlmApiserviceYamlBytes() ([]byte, error) { + return _testQeTestdataOlmApiserviceYaml, nil +} + +func testQeTestdataOlmApiserviceYaml() (*asset, error) { + bytes, err := testQeTestdataOlmApiserviceYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "test/qe/testdata/olm/apiservice.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _testQeTestdataOlmCatalogsourceAddressYaml = []byte(`apiVersion: template.openshift.io/v1 kind: Template metadata: @@ -17876,6 +17917,7 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ + "test/qe/testdata/olm/apiservice.yaml": testQeTestdataOlmApiserviceYaml, "test/qe/testdata/olm/catalogsource-address.yaml": testQeTestdataOlmCatalogsourceAddressYaml, "test/qe/testdata/olm/catalogsource-configmap.yaml": testQeTestdataOlmCatalogsourceConfigmapYaml, "test/qe/testdata/olm/catalogsource-image-cacheless.yaml": testQeTestdataOlmCatalogsourceImageCachelessYaml, @@ -18063,6 +18105,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "qe": {nil, map[string]*bintree{ "testdata": {nil, map[string]*bintree{ "olm": {nil, map[string]*bintree{ + "apiservice.yaml": {testQeTestdataOlmApiserviceYaml, map[string]*bintree{}}, "catalogsource-address.yaml": {testQeTestdataOlmCatalogsourceAddressYaml, map[string]*bintree{}}, "catalogsource-configmap.yaml": {testQeTestdataOlmCatalogsourceConfigmapYaml, map[string]*bintree{}}, "catalogsource-image-cacheless.yaml": {testQeTestdataOlmCatalogsourceImageCachelessYaml, map[string]*bintree{}}, diff --git a/tests-extension/test/qe/README.md b/tests-extension/test/qe/README.md index 94e798e72b..156234edfb 100644 --- a/tests-extension/test/qe/README.md +++ b/tests-extension/test/qe/README.md @@ -36,7 +36,6 @@ We need to identify all cases from tests-private among all cases, then mark whic g.It("xxxxxx", g.Label("ReleaseGate"), func() { ``` - This makes the case equivalent to origin cases for openshift-tests - - Test framework automatically sets these cases without `ReleaseGate` as `Informing` - For the cases with `ReleaseGate` that need `Informing`, add: ```go import oteg "github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo" diff --git a/tests-extension/test/qe/specs/olmv0_allns.go b/tests-extension/test/qe/specs/olmv0_allns.go index 303a323528..94c9490896 100644 --- a/tests-extension/test/qe/specs/olmv0_allns.go +++ b/tests-extension/test/qe/specs/olmv0_allns.go @@ -1,6 +1,7 @@ package specs import ( + "context" "fmt" "os" "path/filepath" @@ -152,4 +153,409 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within all namespace", func() }) + g.It("PolarionID:25783-[Skipped:Disconnected]Subscriptions are not getting processed taking very long to get processed[Serial]", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipArchitectures(oc, architecture.PPC64LE, architecture.S390X, architecture.MULTI) + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipNoCapabilities(oc, "marketplace") + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + node, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + err = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(err).NotTo(o.HaveOccurred()) + efips, errFips := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errFips != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogAllTemplate = filepath.Join(buildPruningBaseDir, "og-allns.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + ogAll = olmv0util.OperatorGroupDescription{ + Name: "og-all", + Namespace: "", + Template: ogAllTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-25783-operator", + Namespace: "", + DisplayName: "Test Catsrc 25783 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv25783", + Template: catsrcImageTemplate, + } + subCockroachdb = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v25783", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v25783", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: false, + } + + csvCockroachdb = olmv0util.CsvDescription{ + Name: "", + Namespace: "", + } + ) + + exutil.SkipForSNOCluster(oc) + platform := exutil.CheckPlatform(oc) + proxy, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + + g.By("Create og") + ns := oc.Namespace() + ogAll.Namespace = ns + ogAll.Create(oc, itName, dr) + + g.By("create catsrc") + catsrc.Namespace = ns + catsrc.Create(oc, itName, dr) + defer catsrc.Delete(itName, dr) + + g.By("create operator nginx-ok") + subCockroachdb.CatalogSourceNamespace = catsrc.Namespace + subCockroachdb.Namespace = catsrc.Namespace + defer subCockroachdb.Delete(itName, dr) + subCockroachdb.Create(oc, itName, dr) + csvCockroachdb.Name = subCockroachdb.InstalledCSV + csvCockroachdb.Namespace = subCockroachdb.Namespace + defer csvCockroachdb.Delete(itName, dr) + 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-[Skipped:Disconnected]watch special or all namespace by operator group", func() { + architecture.SkipArchitectures(oc, architecture.PPC64LE, architecture.S390X, architecture.MULTI) + exutil.SkipNoCapabilities(oc, "marketplace") + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogAllTemplate = filepath.Join(buildPruningBaseDir, "og-allns.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + ogAll = olmv0util.OperatorGroupDescription{ + Name: "og-all", + Namespace: "", + Template: ogAllTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "olm-21532-catalog", + Namespace: "", + DisplayName: "OLM 21532 Catalog", + Publisher: "QE", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv21532", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v21532", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v21532", + CatalogSourceName: "olm-21532-catalog", + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: false, + } + + project = olmv0util.ProjectDescription{ + Name: "olm-enduser-specific-21484", + TargetNamespace: oc.Namespace(), + } + cl = olmv0util.CheckList{} + ) + + // OCP-21532 + g.By("Check the global operator global-operators support all namesapces") + cl.Add(olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "[]", exutil.Ok, []string{"og", "global-operators", "-n", "openshift-operators", "-o=jsonpath={.status.namespaces}"})) + + g.By("Create og") + ns := oc.Namespace() + ogAll.Namespace = ns + ogAll.Create(oc, itName, dr) + + g.By("create catsrc") + catsrc.Namespace = ns + catsrc.CreateWithCheck(oc, itName, dr) + defer catsrc.Delete(itName, dr) + + // OCP-21484, OCP-21532 + g.By("Create operator targeted at all namespace") + sub.Namespace = ns + sub.CatalogSourceNamespace = ns + sub.Create(oc, itName, dr) + + g.By("Create new namespace") + project.Create(oc, itName, dr) + + // OCP-21532 + g.By("New annotations is added to copied CSV in current namespace") + cl.Add(olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithNamespace, exutil.Contain, "alm-examples", exutil.Ok, []string{"csv", sub.InstalledCSV, "-o=jsonpath={.metadata.annotations}"})) + + // OCP-21484, OCP-21532 + g.By("Check the csv within new namespace is copied. note: the step is slow because it wait to copy csv to new namespace") + cl.Add(olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Copied", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", project.Name, "-o=jsonpath={.status.reason}"})) + + cl.Check(oc) + + }) + + g.It("PolarionID:24906-[Skipped:Disconnected]Operators requesting cluster-scoped permission can trigger kube GC bug[Serial]", func() { + architecture.SkipArchitectures(oc, architecture.PPC64LE, architecture.S390X, architecture.MULTI) + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipNoCapabilities(oc, "marketplace") + exutil.SkipIfDisableDefaultCatalogsource(oc) + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + exutil.SkipBaselineCaps(oc, "None") + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogAllTemplate = filepath.Join(buildPruningBaseDir, "og-allns.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + ogAll = olmv0util.OperatorGroupDescription{ + Name: "og-all", + Namespace: "", + Template: ogAllTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-operator", + Namespace: "", + DisplayName: "Test Catsrc Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv24906", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v24906", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v24906", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: false, + } + cl = olmv0util.CheckList{} + ) + + g.By("Create og") + ns := oc.Namespace() + ogAll.Namespace = ns + ogAll.Create(oc, itName, dr) + + g.By("create catalog source") + catsrc.Namespace = ns + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create operator targeted at all namespace") + sub.Namespace = ns + sub.CatalogSourceNamespace = catsrc.Namespace + sub.Create(oc, itName, dr) + sub.Update(oc, itName, dr) + + g.By("Check clusterrolebinding has no OwnerReferences") + cl.Add(olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "", exutil.Ok, []string{"clusterrolebinding", fmt.Sprintf("--selector=olm.owner=%s", sub.InstalledCSV), "-n", sub.Namespace, "-o=jsonpath={..OwnerReferences}"})) + + g.By("Check clusterrole has no OwnerReferences") + cl.Add(olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "", exutil.Ok, []string{"clusterrole", fmt.Sprintf("--selector=olm.owner=%s", sub.InstalledCSV), "-n", sub.Namespace, "-o=jsonpath={..OwnerReferences}"})) + //do check parallelly + cl.Check(oc) + }) + + g.It("PolarionID:33241-[Skipped:Disconnected]Enable generated operator component adoption for operators with all ns mode[Serial]", func() { + if isAKS, _ := exutil.IsAKSCluster(context.TODO(), oc); isAKS { + g.Skip("skip for aks cluster") + } + architecture.SkipArchitectures(oc, architecture.PPC64LE, architecture.S390X, architecture.MULTI) + exutil.SkipNoCapabilities(oc, "marketplace") + node, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + err = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(err).NotTo(o.HaveOccurred()) + efips, err := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if err != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-33241-operator", + Namespace: "openshift-marketplace", + DisplayName: "Test Catsrc 33241 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv33241", + Template: catsrcImageTemplate, + } + subCockroachdb = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v33241", + Namespace: "openshift-operators", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v33241", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: catsrc.Namespace, + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: false, + } + ) + + g.By("check if cockroachdb is already installed with all ns.") + csvList := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "csv", "-n", subCockroachdb.Namespace, "-o=jsonpath={.items[*].metadata.name}") + if !strings.Contains(csvList, subCockroachdb.OperatorPackage) { + g.By("create catsrc") + catsrc.CreateWithCheck(oc, itName, dr) + defer catsrc.Delete(itName, dr) + + g.By("Create operator targeted at all namespace") + subCockroachdb.Create(oc, itName, dr) + csvCockroachdb := olmv0util.CsvDescription{ + Name: subCockroachdb.InstalledCSV, + Namespace: subCockroachdb.Namespace, + } + defer subCockroachdb.Delete(itName, dr) + defer csvCockroachdb.Delete(itName, dr) + crdName := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subCockroachdb.OperatorPackage+"."+subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[?(.kind=='CustomResourceDefinition')].name}") + o.Expect(crdName).NotTo(o.BeEmpty()) + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "crd", crdName) + }() + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subCockroachdb.OperatorPackage+"."+subCockroachdb.Namespace) + }() + + g.By("Check all resources via operators") + resourceKind := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subCockroachdb.OperatorPackage+"."+subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}") + o.Expect(resourceKind).To(o.ContainSubstring("Deployment")) + o.Expect(resourceKind).To(o.ContainSubstring("Role")) + o.Expect(resourceKind).To(o.ContainSubstring("RoleBinding")) + o.Expect(resourceKind).To(o.ContainSubstring("ClusterRole")) + o.Expect(resourceKind).To(o.ContainSubstring("ClusterRoleBinding")) + o.Expect(resourceKind).To(o.ContainSubstring("CustomResourceDefinition")) + o.Expect(resourceKind).To(o.ContainSubstring("Subscription")) + o.Expect(resourceKind).To(o.ContainSubstring("InstallPlan")) + o.Expect(resourceKind).To(o.ContainSubstring("ClusterServiceVersion")) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, subCockroachdb.Namespace, exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[?(.kind=='ClusterServiceVersion')].namespace}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "InstallSucceeded", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[?(.kind=='ClusterServiceVersion')].conditions[*].reason}"}).Check(oc) + } + }) + + g.It("PolarionID:22226-[Skipped:Disconnected]the csv without support AllNamespaces fails for og with allnamespace", func() { + var ( + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + cmNcTemplate = filepath.Join(buildPruningBaseDir, "cm-namespaceconfig.yaml") + catsrcCmTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-configmap.yaml") + ogAllTemplate = filepath.Join(buildPruningBaseDir, "og-allns.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + itName = g.CurrentSpecReport().FullText() + og = olmv0util.OperatorGroupDescription{ + Name: "og-allnamespace", + Namespace: "", + Template: ogAllTemplate, + } + cm = olmv0util.ConfigMapDescription{ + Name: "cm-community-namespaceconfig-operators", + Namespace: "", //must be set in iT + Template: cmNcTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-community-namespaceconfig-operators", + Namespace: "", //must be set in iT + DisplayName: "Community namespaceconfig Operators", + Publisher: "Community", + SourceType: "configmap", + Address: "cm-community-namespaceconfig-operators", + Template: catsrcCmTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "namespace-configuration-operator", + Namespace: "", //must be set in iT + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "namespace-configuration-operator", + CatalogSourceName: "catsrc-community-namespaceconfig-operators", + CatalogSourceNamespace: "", //must be set in iT + StartingCSV: "", + CurrentCSV: "namespace-configuration-operator.v0.1.0", //it matches to that in cm, so set it. + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + + cm.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + og.Namespace = oc.Namespace() + g.By("Create cm") + cm.Create(oc, itName, dr) + + g.By("Create catalog source") + catsrc.Create(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("Create sub") + sub.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "AllNamespaces InstallModeType not supported", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.message}"}).Check(oc) + }) + }) diff --git a/tests-extension/test/qe/specs/olmv0_common.go b/tests-extension/test/qe/specs/olmv0_common.go index 4ecdbff63f..ca16b7473a 100644 --- a/tests-extension/test/qe/specs/olmv0_common.go +++ b/tests-extension/test/qe/specs/olmv0_common.go @@ -2,10 +2,16 @@ package specs import ( "context" + "fmt" "os/exec" + "strings" + "time" 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" exutil "github.com/openshift/operator-framework-olm/tests-extension/test/qe/util" "github.com/openshift/operator-framework-olm/tests-extension/test/qe/util/olmv0util" @@ -69,4 +75,537 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 should", func() { o.Expect(err).To(o.HaveOccurred(), "PO is not disable") }) + g.It("PolarionID:24076-check the version of olm operator is appropriate in ClusterOperator", g.Label("NonHyperShiftHOST"), func() { + var ( + olmClusterOperatorName = "operator-lifecycle-manager" + ) + + g.By("get the version of olm operator") + olmVersion := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "clusteroperator", olmClusterOperatorName, "-o=jsonpath={.status.versions[?(@.name==\"operator\")].version}") + o.Expect(olmVersion).NotTo(o.BeEmpty()) + + g.By("Check if it is appropriate in ClusterOperator") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, olmVersion, exutil.Ok, []string{"clusteroperator", "-o=jsonpath={.items[?(@.metadata.name==\"" + olmClusterOperatorName + "\")].status.versions[?(@.name==\"operator\")].version}"}).Check(oc) + }) + + g.It("PolarionID:29775-PolarionID:29786-[Skipped:Disconnected]as oc user on linux to mirror catalog image[Slow][Timeout:30m]", func() { + var ( + bundleIndex1 = "quay.io/kuiwang/operators-all:v1" + bundleIndex2 = "quay.io/kuiwang/operators-dockerio:v1" + operatorAllPath = "operators-all-manifests-" + exutil.GetRandomString() + operatorDockerioPath = "operators-dockerio-manifests-" + exutil.GetRandomString() + ) + defer func() { _, _ = exec.Command("bash", "-c", "rm -fr ./"+operatorAllPath).Output() }() + defer func() { _, _ = exec.Command("bash", "-c", "rm -fr ./"+operatorDockerioPath).Output() }() + + g.By("mirror to quay.io/kuiwang") + var output string + var err error + // Add timeout and retry mechanism for network resilience + // Timeout: 6 minutes (360s), Retry interval: 60s, Max retries: 2 + err = wait.PollUntilContextTimeout(context.TODO(), 60*time.Second, 6*time.Minute, false, func(ctx context.Context) (bool, error) { + e2e.Logf("Executing 'oc adm catalog mirror' for %s (may take several minutes)...", bundleIndex1) + output, err = oc.AsAdmin().WithoutNamespace().Run("adm", "catalog", "mirror").Args("--manifests-only", "--to-manifests="+operatorAllPath, bundleIndex1, "quay.io/kuiwang").Output() + if err != nil { + e2e.Logf("Warning: catalog mirror command failed (will retry): %v", err) + return false, nil // Retry on failure + } + if !strings.Contains(output, "operators-all-manifests") { + e2e.Logf("Warning: expected output not found (will retry)") + return false, nil // Retry if output is unexpected + } + e2e.Logf("Successfully completed catalog mirror for %s", bundleIndex1) + return true, nil // Success + }) + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(output).To(o.ContainSubstring("operators-all-manifests")) + + g.By("check mapping.txt") + result, err := exec.Command("bash", "-c", "cat ./"+operatorAllPath+"/mapping.txt|grep -E \"atlasmap-atlasmap-operator:0.1.0|quay.io/kuiwang/jmckind-argocd-operator:[a-z0-9][a-z0-9]|redhat-cop-cert-utils-operator:latest\"").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(result).To(o.ContainSubstring("atlasmap-atlasmap-operator:0.1.0")) + o.Expect(result).To(o.ContainSubstring("redhat-cop-cert-utils-operator:latest")) + o.Expect(result).To(o.ContainSubstring("quay.io/kuiwang/jmckind-argocd-operator")) + + g.By("check icsp yaml") + result, err = exec.Command("bash", "-c", "cat ./"+operatorAllPath+"/imageContentSourcePolicy.yaml | grep -E \"quay.io/kuiwang/strimzi-operator|docker.io/strimzi/operator$\"").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(result).To(o.ContainSubstring("- quay.io/kuiwang/strimzi-operator")) + o.Expect(result).To(o.ContainSubstring("source: docker.io/strimzi/operator")) + + g.By("mirror to localhost:5000") + // Add timeout and retry mechanism for network resilience + // Timeout: 6 minutes (360s), Retry interval: 60s, Max retries: 2 + err = wait.PollUntilContextTimeout(context.TODO(), 60*time.Second, 6*time.Minute, false, func(ctx context.Context) (bool, error) { + e2e.Logf("Executing 'oc adm catalog mirror' for %s (may take several minutes)...", bundleIndex2) + output, err = oc.AsAdmin().WithoutNamespace().Run("adm", "catalog", "mirror").Args("--manifests-only", "--to-manifests="+operatorDockerioPath, bundleIndex2, "localhost:5000").Output() + if err != nil { + e2e.Logf("Warning: catalog mirror command failed (will retry): %v", err) + return false, nil // Retry on failure + } + if !strings.Contains(output, "operators-dockerio-manifests") { + e2e.Logf("Warning: expected output not found (will retry)") + return false, nil // Retry if output is unexpected + } + e2e.Logf("Successfully completed catalog mirror for %s", bundleIndex2) + return true, nil // Success + }) + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(output).To(o.ContainSubstring("operators-dockerio-manifests")) + + g.By("check mapping.txt to localhost:5000") + result, err = exec.Command("bash", "-c", "cat ./"+operatorDockerioPath+"/mapping.txt|grep -E \"localhost:5000/atlasmap/atlasmap-operator:0.1.0|localhost:5000/strimzi/operator:[a-z0-9][a-z0-9]\"").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(result).To(o.ContainSubstring("localhost:5000/atlasmap/atlasmap-operator:0.1.0")) + o.Expect(result).To(o.ContainSubstring("localhost:5000/strimzi/operator")) + + g.By("check icsp yaml to localhost:5000") + result, err = exec.Command("bash", "-c", "cat ./"+operatorDockerioPath+"/imageContentSourcePolicy.yaml | grep -E \"localhost:5000/strimzi/operator|docker.io/strimzi/operator$\"").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(result).To(o.ContainSubstring("- localhost:5000/strimzi/operator")) + o.Expect(result).To(o.ContainSubstring("source: docker.io/strimzi/operator")) + o.Expect(result).NotTo(o.ContainSubstring("docker.io/atlasmap/atlasmap-operator")) + }) + + g.It("PolarionID:33452-[Skipped:Disconnected]oc adm catalog mirror does not mirror the index image itself", func() { + var ( + bundleIndex1 = "quay.io/olmqe/olm-api@sha256:71cfd4deaa493d31cd1d8255b1dce0fb670ae574f4839c778f2cfb1bf1f96995" + manifestPath = "manifests-olm-api-" + exutil.GetRandomString() + ) + defer func() { _, _ = exec.Command("bash", "-c", "rm -fr ./"+manifestPath).Output() }() + + g.By("mirror to localhost:5000/test") + output, err := oc.AsAdmin().WithoutNamespace().Run("adm", "catalog", "mirror").Args("--manifests-only", "--to-manifests="+manifestPath, bundleIndex1, "localhost:5000/test").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(output).To(o.ContainSubstring("manifests-olm-api")) + + g.By("check mapping.txt to localhost:5000") + result, err := exec.Command("bash", "-c", "cat ./"+manifestPath+"/mapping.txt|grep -E \"quay.io/olmqe/olm-api\"").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(result).To(o.ContainSubstring("quay.io/olmqe/olm-api")) + + g.By("check icsp yaml to localhost:5000") + result, err = exec.Command("bash", "-c", "cat ./"+manifestPath+"/imageContentSourcePolicy.yaml | grep -E \"quay.io/olmqe/olm-api\"").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(result).To(o.ContainSubstring("quay.io/olmqe/olm-api")) + }) + + g.It("PolarionID:21825-[Skipped:Disconnected]Certs for packageserver can be rotated successfully [Serial]", g.Label("NonHyperShiftHOST"), func() { + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipIfDisableDefaultCatalogsource(oc) + var ( + packageserverName = "packageserver" + ) + + g.By("Get certsRotateAt and APIService name") + resources := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "csv", packageserverName, "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.status.certsRotateAt}{\" \"}{.status.requirementStatus[?(@.kind==\"APIService\")].name}") + o.Expect(resources).NotTo(o.BeEmpty()) + resourceFields := strings.Fields(resources) + o.Expect(len(resourceFields)).To(o.BeNumerically(">=", 2)) + apiServiceName := resourceFields[1] + certsRotateAt, err := time.Parse(time.RFC3339, resourceFields[0]) + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("Get caBundle") + caBundle := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "apiservices", apiServiceName, "-o=jsonpath={.spec.caBundle}") + o.Expect(caBundle).NotTo(o.BeEmpty()) + + g.By("Change caBundle") + exutil.PatchResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "apiservices", apiServiceName, "-p", "{\"spec\":{\"caBundle\":\"test"+caBundle+"\"}}") + + g.By("Check updated certsRotataAt") + err = wait.PollUntilContextTimeout(context.TODO(), 3*time.Second, 150*time.Second, false, func(ctx context.Context) (bool, error) { + updatedCertsRotateAtStr := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "csv", packageserverName, "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.status.certsRotateAt}") + updatedCertsRotateAt, err := time.Parse(time.RFC3339, updatedCertsRotateAtStr) + if err != nil { + e2e.Logf("the get error is %v, and try next", err) + return false, nil + } + if !updatedCertsRotateAt.Equal(certsRotateAt) { + e2e.Logf("wait update, and try next") + return false, nil + } + return true, nil + }) + exutil.AssertWaitPollNoErr(err, "csv "+packageserverName+" cert is not updated") + + 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-[Skipped:Disconnected]olmv0 static networkpolicy on ocp", g.Label("NonHyperShiftHOST", "ReleaseGate"), 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-[Skipped:Disconnected]olmv0 networkpolicy on hosted hypershift", g.Label("NonHyperShiftHOST", "ReleaseGate"), 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_microshift.go b/tests-extension/test/qe/specs/olmv0_microshift.go index 5b452b411b..ea53dd7c45 100644 --- a/tests-extension/test/qe/specs/olmv0_microshift.go +++ b/tests-extension/test/qe/specs/olmv0_microshift.go @@ -43,7 +43,6 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 on microshift", g.Label("NonH }) - // author: kuiwang@redhat.com g.It("PolarionID:69867-[Skipped:Disconnected]deployed in microshift and install one operator with single mode.", func() { var ( @@ -147,7 +146,7 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 on microshift", g.Label("NonH ), "some resources do not exist") }) - // author: kuiwang@redhat.com + g.It("PolarionID:69868-[Skipped:Disconnected]olm microshift install operator with all mode, muilt og error and delete one og to get it installed.", func() { var ( @@ -220,7 +219,6 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 on microshift", g.Label("NonH }) - // author: kuiwang@redhat.com g.It("PolarionID:83581-[Skipped:Disconnected]olmv0 networkpolicy on microshift.", func() { policies := []olmv0util.NpExpecter{ diff --git a/tests-extension/test/qe/specs/olmv0_multins.go b/tests-extension/test/qe/specs/olmv0_multins.go index ccf2ee4538..23d00e4469 100644 --- a/tests-extension/test/qe/specs/olmv0_multins.go +++ b/tests-extension/test/qe/specs/olmv0_multins.go @@ -1,9 +1,14 @@ package specs import ( + "os" "path/filepath" + "strconv" + "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" "github.com/openshift/operator-framework-olm/tests-extension/test/qe/util/olmv0util" @@ -110,4 +115,152 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 with multi ns", func() { olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "MultiNamespace InstallModeType not supported", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.message}"}).Check(oc) }) + g.It("PolarionID:71119-[Skipped:Disconnected]pod does not start for installing operator of multi-ns mode when og is in one of the ns[Serial]", g.Label("NonHyperShiftHOST"), func() { + exutil.SkipForSNOCluster(oc) + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipNoCapabilities(oc, "marketplace") + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || + strings.Contains(platform, "ibmcloud") || strings.Contains(platform, "nutanix") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogMultiTemplate = filepath.Join(buildPruningBaseDir, "og-multins.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + catsrc = olmv0util.CatalogSourceDescription{ + Name: "olm-71119-catalog", + Namespace: "", + DisplayName: "OLM 71119 Catalog", + Publisher: "QE", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv71119", + Template: catsrcImageTemplate, + } + og = olmv0util.OperatorGroupDescription{ + Name: "og-71119", + Namespace: "test-ns71119-1", + Multinslabel: "label-71119", + Template: ogMultiTemplate, + } + p1 = olmv0util.ProjectDescription{ + Name: "test-ns71119-1", + TargetNamespace: "test-ns71119-1", + } + p2 = olmv0util.ProjectDescription{ + Name: "test-ns71119-2", + TargetNamespace: "test-ns71119-1", + } + subSample = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v71119", + Namespace: "test-ns71119-1", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: p1.Name, + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v71119", + Template: subTemplate, + } + ) + + g.By("create two ns and og") + defer p1.Delete(oc) + p1.Create(oc, itName, dr) + p1.Label(oc, "label-71119") + defer p2.Delete(oc) + p2.Create(oc, itName, dr) + p2.Label(oc, "label-71119") + og.Create(oc, itName, dr) + catsrc.Namespace = p1.Name + catsrc.Create(oc, itName, dr) + + g.By("subscribe to operator with multinamespaces mode") + defer subSample.Delete(itName, dr) + subSample.Create(oc, itName, dr) + defer subSample.GetCSV().Delete(itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", subSample.InstalledCSV, "-n", subSample.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + podName, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("pod", "-n", subSample.Namespace, "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(podName).NotTo(o.BeEmpty()) + + o.Consistently(func() int { + restartCount, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("pod", podName, "-n", subSample.Namespace, "-o=jsonpath={.status..restartCount}").Output() + if strings.Contains(restartCount, "NotFound") { + return 0 + } + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(restartCount).NotTo(o.BeEmpty()) + count, err := strconv.Atoi(strings.Fields(restartCount)[0]) + o.Expect(err).NotTo(o.HaveOccurred()) + return count + }, 150*time.Second, 10*time.Second).Should(o.Equal(0), "the pod restart") + }) + + g.It("PolarionID:29275-[Skipped:Disconnected]label to target namespace of operator group with multi namespace", g.Label("NonHyperShiftHOST"), func() { + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogMultiTemplate = filepath.Join(buildPruningBaseDir, "og-multins.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-1651-1", + Namespace: "", + Multinslabel: "test-og-label-1651", + Template: ogMultiTemplate, + } + p1 = olmv0util.ProjectDescription{ + Name: "test-ns1651-1", + TargetNamespace: "", + } + p2 = olmv0util.ProjectDescription{ + Name: "test-ns1651-2", + TargetNamespace: "", + } + ) + + p1.TargetNamespace = oc.Namespace() + p2.TargetNamespace = oc.Namespace() + og.Namespace = oc.Namespace() + g.By("Create new projects and label them") + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "ns", p1.Name, "--ignore-not-found") + }() + err := oc.AsAdmin().WithoutNamespace().Run("create").Args("ns", p1.Name).Execute() + o.Expect(err).NotTo(o.HaveOccurred()) + p1.Label(oc, "test-og-label-1651") + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "ns", p2.Name, "--ignore-not-found") + }() + err = oc.AsAdmin().WithoutNamespace().Run("create").Args("ns", p2.Name).Execute() + o.Expect(err).NotTo(o.HaveOccurred()) + p2.Label(oc, "test-og-label-1651") + + g.By("Create og and check the label") + og.Create(oc, itName, dr) + ogUID := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithNamespace, "og", og.Name, "-o=jsonpath={.metadata.uid}") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+ogUID, exutil.Ok, []string{"ns", p1.Name, "-o=jsonpath={.metadata.labels}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+ogUID, exutil.Ok, []string{"ns", p2.Name, "-o=jsonpath={.metadata.labels}"}).Check(oc) + + g.By("delete og and check there is no label") + og.Delete(itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+ogUID, exutil.Nok, []string{"ns", p1.Name, "-o=jsonpath={.metadata.labels}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+ogUID, exutil.Nok, []string{"ns", p2.Name, "-o=jsonpath={.metadata.labels}"}).Check(oc) + + g.By("create another og to check the label") + og.Name = "og-1651-2" + og.Create(oc, itName, dr) + ogUID = olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithNamespace, "og", og.Name, "-o=jsonpath={.metadata.uid}") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+ogUID, exutil.Ok, []string{"ns", p1.Name, "-o=jsonpath={.metadata.labels}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+ogUID, exutil.Ok, []string{"ns", p2.Name, "-o=jsonpath={.metadata.labels}"}).Check(oc) + }) + }) diff --git a/tests-extension/test/qe/specs/olmv0_nonallns.go b/tests-extension/test/qe/specs/olmv0_nonallns.go index 869f8d65eb..abd90cbe6a 100644 --- a/tests-extension/test/qe/specs/olmv0_nonallns.go +++ b/tests-extension/test/qe/specs/olmv0_nonallns.go @@ -1,11 +1,20 @@ package specs import ( + "context" + "fmt" + "os" + "os/exec" "path/filepath" + "regexp" "strings" + "time" 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" exutil "github.com/openshift/operator-framework-olm/tests-extension/test/qe/util" "github.com/openshift/operator-framework-olm/tests-extension/test/qe/util/architecture" @@ -93,6 +102,211 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within a namespace", func() { 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) }) + g.It("PolarionID:22200-[Skipped:Disconnected]add minimum kube version to CSV [Slow]", g.Label("NonHyperShiftHOST"), func() { + checkArch := architecture.ClusterArchitecture(oc) + e2e.Logf("the curent arch is %v", checkArch.String()) + architecture.SkipNonAmd64SingleArch(oc) + e2e.Logf("done for SkipNonAmd64SingleArch and try the following method which is same to SkipNonAmd64SingleArch") + architecture.SkipArchitectures(oc, architecture.PPC64LE, architecture.S390X, architecture.MULTI, architecture.ARM64, architecture.UNKNOWN) + if isAks, _ := exutil.IsAKSCluster(context.TODO(), oc); isAks { + g.Skip("skip for ask cluster") + } + exutil.SkipNoCapabilities(oc, "marketplace") + node, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + errGet = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errGet).NotTo(o.HaveOccurred()) + efips, errGet := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errGet != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + infra, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "none") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + cmNcTemplate = filepath.Join(buildPruningBaseDir, "cm-namespaceconfig.yaml") + catsrcCmTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-configmap.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogTemplate, + } + cmNc = olmv0util.ConfigMapDescription{ + Name: "cm-community-namespaceconfig-operators", + Namespace: "", //must be set in iT + Template: cmNcTemplate, + } + catsrcNc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-community-namespaceconfig-operators", + Namespace: "", //must be set in iT + DisplayName: "Community namespaceconfig Operators", + Publisher: "Community", + SourceType: "configmap", + Address: "cm-community-namespaceconfig-operators", + Template: catsrcCmTemplate, + } + subNc = olmv0util.SubscriptionDescription{ + SubName: "namespace-configuration-operator", + Namespace: "", //must be set in iT + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "namespace-configuration-operator", + CatalogSourceName: "catsrc-community-namespaceconfig-operators", + CatalogSourceNamespace: "", //must be set in iT + StartingCSV: "", + CurrentCSV: "namespace-configuration-operator.v0.1.0", //it matches to that in cm, so set it. + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + cm = cmNc + catsrc = catsrcNc + sub = subNc + ) + + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need derfer or AfterEach + cm.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + og.Namespace = oc.Namespace() + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("Create configmap of csv") + cm.Create(oc, itName, dr) + + g.By("Get minKubeVersionRequired and kubeVersionUpdated") + output := olmv0util.GetResource(oc, exutil.AsUser, exutil.WithoutNamespace, "cm", cm.Name, "-n", cm.Namespace, "-o=json") + csvDesc := strings.TrimSuffix(strings.TrimSpace(strings.SplitN(strings.SplitN(output, "\"clusterServiceVersions\": ", 2)[1], "\"customResourceDefinitions\":", 2)[0]), ",") + o.Expect(strings.Contains(csvDesc, "minKubeVersion:")).To(o.BeTrue()) + minKubeVersionRequired := strings.TrimSpace(strings.SplitN(strings.SplitN(csvDesc, "minKubeVersion:", 2)[1], "\\n", 2)[0]) + kubeVersionUpdated := olmv0util.GenerateUpdatedKubernatesVersion(oc) + e2e.Logf("the kubeVersionUpdated version is %s, and minKubeVersionRequired is %s", kubeVersionUpdated, minKubeVersionRequired) + + g.By("Create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Update the minKubeVersion greater than the cluster KubeVersion") + cm.Patch(oc, fmt.Sprintf("{\"data\": {\"clusterServiceVersions\": %s}}", strings.ReplaceAll(csvDesc, "minKubeVersion: "+minKubeVersionRequired, "minKubeVersion: "+kubeVersionUpdated))) + + g.By("Create sub with greater KubeVersion") + sub.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "not met+2+less than", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.requirementStatus[?(@.kind==\"ClusterServiceVersion\")].message}"}).Check(oc) + + g.By("Remove sub and csv and update the minKubeVersion to orignl") + sub.Delete(itName, dr) + sub.GetCSV().Delete(itName, dr) + cm.Patch(oc, fmt.Sprintf("{\"data\": {\"clusterServiceVersions\": %s}}", csvDesc)) + + g.By("Create sub with orignal KubeVersion") + sub.Create(oc, itName, dr) + err := wait.PollUntilContextTimeout(context.TODO(), 15*time.Second, 360*time.Second, false, func(ctx context.Context) (bool, error) { + csvPhase := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}") + if strings.Contains(csvPhase, "Succeeded") { + e2e.Logf("sub is installed") + return true, nil + } + return false, nil + }) + if err != nil { + msg := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.requirementStatus[?(@.kind==\"ClusterServiceVersion\")].message}") + if strings.Contains(msg, "CSV version requirement not met") && !strings.Contains(msg, kubeVersionUpdated) { + e2e.Failf("the csv can not be installed with correct kube version") + } + } + }) + + g.It("PolarionID:23473-[Skipped:Disconnected]permit z-stream releases skipping during operator updates", func() { + architecture.SkipNonAmd64SingleArch(oc) + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + cmNcTemplate = filepath.Join(buildPruningBaseDir, "cm-namespaceconfig.yaml") + catsrcCmTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-configmap.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogTemplate, + } + skippedVersion = "namespace-configuration-operator.v0.0.2" + cmNc = olmv0util.ConfigMapDescription{ + Name: "cm-community-namespaceconfig-operators", + Namespace: "", //must be set in iT + Template: cmNcTemplate, + } + catsrcNc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-community-namespaceconfig-operators", + Namespace: "", //must be set in iT + DisplayName: "Community namespaceconfig Operators", + Publisher: "Community", + SourceType: "configmap", + Address: "cm-community-namespaceconfig-operators", + Template: catsrcCmTemplate, + } + subNc = olmv0util.SubscriptionDescription{ + SubName: "namespace-configuration-operator", + Namespace: "", //must be set in iT + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "namespace-configuration-operator", + CatalogSourceName: "catsrc-community-namespaceconfig-operators", + CatalogSourceNamespace: "", //must be set in iT + StartingCSV: "", + CurrentCSV: "namespace-configuration-operator.v0.1.0", //it matches to that in cm, so set it. + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + cm = cmNc + catsrc = catsrcNc + sub = subNc + ) + + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need derfer or AfterEach + cm.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + og.Namespace = oc.Namespace() + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("Create configmap of csv") + cm.Create(oc, itName, dr) + + g.By("Create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create sub") + sub.IpApproval = "Manual" + sub.StartingCSV = "namespace-configuration-operator.v0.0.1" + sub.Create(oc, itName, dr) + + g.By("manually approve sub") + sub.Approve(oc, itName, dr) + + g.By(fmt.Sprintf("there is skipped csv version %s", skippedVersion)) + o.Expect(strings.Contains(sub.IpCsv, skippedVersion)).To(o.BeFalse()) + }) + g.It("PolarionID:37263-[Skipped:Disconnected][Skipped:Proxy]Subscription stays in UpgradePending but InstallPlan not installing [Slow]", func() { architecture.SkipNonAmd64SingleArch(oc) exutil.SkipBaselineCaps(oc, "None") @@ -244,4 +458,2375 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 within a namespace", func() { }) + // It will cover test case: OCP-29231 and OCP-29277 + g.It("PolarionID:29231-PolarionID:29277-label to target namespace of group", func() { + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + og1 = olmv0util.OperatorGroupDescription{ + Name: "og1-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + og2 = olmv0util.OperatorGroupDescription{ + Name: "og2-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + ) + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need derfer or AfterEach + og1.Namespace = oc.Namespace() + og2.Namespace = oc.Namespace() + + g.By("Create og1 and check the label of target namespace of og1 is created") + og1.Create(oc, itName, dr) + og1Uid := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithNamespace, "og", og1.Name, "-o=jsonpath={.metadata.uid}") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+og1Uid, exutil.Ok, + []string{"ns", og1.Namespace, "-o=jsonpath={.metadata.labels}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+og1Uid, exutil.Nok, + []string{"ns", "openshift-operators", "-o=jsonpath={.metadata.labels}"}).Check(oc) + + g.By("Delete og1 and check the label of target namespace of og1 is removed") + og1.Delete(itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+og1Uid, exutil.Nok, + []string{"ns", og1.Namespace, "-o=jsonpath={.metadata.labels}"}).Check(oc) + + g.By("Create og2 and recreate og1 and check the label") + og2.Create(oc, itName, dr) + og2Uid := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithNamespace, "og", og2.Name, "-o=jsonpath={.metadata.uid}") + og1.Create(oc, itName, dr) + og1Uid = olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithNamespace, "og", og1.Name, "-o=jsonpath={.metadata.uid}") + labelNs := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "ns", og1.Namespace, "-o=jsonpath={.metadata.labels}") + o.Expect(labelNs).To(o.ContainSubstring(og2Uid)) + o.Expect(labelNs).To(o.ContainSubstring(og1Uid)) + + // OCP-29277 + g.By("Check no label of global operator group ") + globalOgUID := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "og", "global-operators", "-n", "openshift-operators", "-o=jsonpath={.metadata.uid}") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "olm.operatorgroup.uid/"+globalOgUID, exutil.Nok, + []string{"ns", "default", "-o=jsonpath={.metadata.labels}"}).Check(oc) + + }) + + // Group 2: OCP-25855 + g.It("PolarionID:25855-[Skipped:Disconnected][Serial]Add the channel field to subscription_sync_count", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipNonAmd64SingleArch(oc) + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipForSNOCluster(oc) + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-operator", + Namespace: "", + DisplayName: "Test Catsrc Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-index:OLM-2378-Oadp-GoodOne-withCache", + Template: catsrcImageTemplate, + } + + sub = olmv0util.SubscriptionDescription{ + SubName: "oadp-operator", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "oadp-operator", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + og.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("Create operator") + sub.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("get information of catalog operator pod") + output := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "pods", "-l", "app=catalog-operator", "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.items[0].metadata.name}{\" \"}{.items[0].status.podIP}{\":\"}{.items[0].spec.containers[0].ports[?(@.name==\"metrics\")].containerPort}") + o.Expect(output).NotTo(o.BeEmpty()) + infoCatalogOperator := strings.Fields(output) + + g.By("check the subscription_sync_total") + var subscriptionSyncTotal []byte + var errExec error + err = wait.PollUntilContextTimeout(context.TODO(), 20*time.Second, 120*time.Second, false, func(ctx context.Context) (bool, error) { + // Get prometheus service account token + token, errToken := exutil.GetPrometheusSAToken(oc) + if errToken != nil { + e2e.Logf("failed to get prometheus token: %v", errToken) + return false, nil + } + token = strings.TrimSpace(token) + + // Use the token in curl command + curlCmd := fmt.Sprintf("oc exec -c catalog-operator %s -n openshift-operator-lifecycle-manager -- curl -s -k -H 'Authorization: Bearer %s' https://%s/metrics", infoCatalogOperator[0], token, infoCatalogOperator[1]) + subscriptionSyncTotal, errExec = exec.Command("bash", "-c", curlCmd).Output() + if !strings.Contains(string(subscriptionSyncTotal), sub.InstalledCSV) { + e2e.Logf("the metric is not counted and try next round") + return false, nil + } + return true, nil + }) + if err != nil { + e2e.Logf("the output: %v \n the err: %v", string(subscriptionSyncTotal), errExec) + } + exutil.AssertWaitPollNoErr(err, fmt.Sprintf("csv %s is not included in metric", sub.InstalledCSV)) + }) + + // Group 2: OCP-23170 + g.It("PolarionID:23170-[Skipped:Disconnected]API labels should be hash", func() { + architecture.SkipNonAmd64SingleArch(oc) + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + ogD = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-operator", + Namespace: "", + DisplayName: "Test Catsrc Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv23170", + Template: catsrcImageTemplate, + } + subD = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v23170", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v23170", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + + og = ogD + sub = subD + ) + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need defer or AfterEach + og.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("Create operator") + sub.Create(oc, itName, dr) + + g.By("Check the API labels should be hash") + apiLabels := olmv0util.GetResource(oc, exutil.AsUser, exutil.WithNamespace, "csv", sub.InstalledCSV, "-o=jsonpath={.metadata.labels}") + o.Expect(len(apiLabels)).NotTo(o.BeZero()) + pattern, err := regexp.Compile(`^[a-fA-F0-9]{16}$|^[a-fA-F0-9]{15}$`) + o.Expect(err).NotTo(o.HaveOccurred()) + for _, v := range strings.Split(strings.Trim(apiLabels, "{}"), ",") { + if strings.Contains(v, "olm.api") { + hash := strings.Trim(strings.Split(strings.Split(v, ":")[0], ".")[2], "\"") + // calling regexp.MatchString in a loop has poor performance, consider using regexp.Compile (SA6000) + // match, err := regexp.MatchString(`^[a-fA-F0-9]{16}$|^[a-fA-F0-9]{15}$`, hash) + // o.Expect(err).NotTo(o.HaveOccurred()) + // o.Expect(match).To(o.BeTrue()) + res := pattern.Find([]byte(hash)) + o.Expect(string(res)).NotTo(o.BeEmpty()) + } + } + }) + + // Group 3: OCP-20979 + g.It("PolarionID:20979-[Skipped:Disconnected]only one IP is generated", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipNonAmd64SingleArch(oc) + if isAks, _ := exutil.IsAKSCluster(context.TODO(), oc); isAks { + g.Skip("skip for aks cluster") + } + exutil.SkipNoCapabilities(oc, "marketplace") + node, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + errGet = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errGet).NotTo(o.HaveOccurred()) + efips, errGet := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errGet != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "none") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + ogD = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-operator", + Namespace: "", + DisplayName: "Test Catsrc Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv20979", + Template: catsrcImageTemplate, + } + subD = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v20979", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v20979", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + og = ogD + sub = subD + ) + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need defer or AfterEach + og.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.Create(oc, itName, dr) + err := wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 180*time.Second, false, func(ctx context.Context) (bool, error) { + status, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("catsrc", catsrc.Name, "-n", catsrc.Namespace, "-o=jsonpath={.status..lastObservedState}").Output() + if strings.Compare(status, "READY") != 0 { + e2e.Logf("catsrc %s lastObservedState is %s, not READY", catsrc.Name, status) + return false, nil + } + return true, nil + }) + if err != nil { + output, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("catsrc", catsrc.Name, "-n", catsrc.Namespace, "-o=jsonpath={.status}").Output() + e2e.Logf("catsrc status: %s", output) + pods, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("pods", "-n", catsrc.Namespace).Output() + e2e.Logf("Pods in namespace %s: %s", catsrc.Namespace, pods) + events, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("events", "-n", catsrc.Namespace).Output() + e2e.Logf("Events in namespace %s: %s", catsrc.Namespace, events) + g.Skip("catsrc is not ready, so skip") + } + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("Create operator") + sub.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("Check there is only one ip") + ips := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "installplan", "-n", sub.Namespace, "--no-headers") + ipList := strings.Split(ips, "\n") + for _, ip := range ipList { + name := strings.Fields(ip)[0] + olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "installplan", name, "-n", sub.Namespace, "-o=json") + } + o.Expect(strings.Count(ips, sub.InstalledCSV)).To(o.Equal(1)) + }) + + // Group 3: OCP-25757/22656 + g.It("PolarionID:25757-PolarionID:22656-[Skipped:Disconnected]manual approval strategy apply to subsequent releases", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipNonAmd64SingleArch(oc) + if isAks, _ := exutil.IsAKSCluster(context.TODO(), oc); isAks { + g.Skip("skip for aks cluster") + } + exutil.SkipNoCapabilities(oc, "marketplace") + node, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + errGet = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errGet).NotTo(o.HaveOccurred()) + efips, errGet := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errGet != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + infra, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "none") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + ogD = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-operator", + Namespace: "", + DisplayName: "Test Catsrc Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-index:OLM-2378-Oadp-Good", + Template: catsrcImageTemplate, + } + subD = olmv0util.SubscriptionDescription{ + SubName: "oadp-operator", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "oadp-operator", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + + og = ogD + sub = subD + ) + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need defer or AfterEach + og.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("prepare for manual approval") + sub.IpApproval = "Manual" + sub.StartingCSV = "oadp-operator.v0.5.5" + + g.By("Create Sub which apply manual approve install plan") + sub.Create(oc, itName, dr) + + g.By("the install plan is RequiresApproval") + installPlan := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.installplan.name}") + o.Expect(installPlan).NotTo(o.BeEmpty()) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "RequiresApproval", exutil.Ok, []string{"installplan", installPlan, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("manually approve sub") + sub.Approve(oc, itName, dr) + + g.By("the target CSV is created with upgrade") + err := wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 150*time.Second, false, func(ctx context.Context) (bool, error) { + currentCSV := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.currentCSV}") + if strings.Compare(currentCSV, sub.StartingCSV) != 0 { + return true, nil + } + return false, nil + }) + exutil.AssertWaitPollNoErr(err, fmt.Sprintf("the installedCSV %v is not expected", sub.InstalledCSV)) + }) + + // Group 4 - OCP-24438 + OCP-24027 + g.It("PolarionID:24438-[Skipped:Disconnected]check subscription CatalogSource Status", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipNonAmd64SingleArch(oc) + platform := exutil.CheckPlatform(oc) + if strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || strings.Contains(platform, "none") || exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + ogD = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-test-operator", + Namespace: "", + DisplayName: "Test Catsrc Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "", + Template: catsrcImageTemplate, + } + subD = olmv0util.SubscriptionDescription{ + SubName: "oadp-operator", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "oadp-operator", + CatalogSourceName: "test", + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + + og = ogD + sub = subD + ) + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need derfer or AfterEach + og.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + + catsrc.Namespace = oc.Namespace() + sub.CatalogSourceName = catsrc.Name + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("create sub with the above catalogsource") + sub.CreateWithoutCheck(oc, itName, dr) + + g.By("check its condition is UnhealthyCatalogSourceFound") + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithoutNamespace, exutil.Contain, "UnhealthyCatalogSourceFound", exutil.Ok, []string{"sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.conditions[*].reason}"}).Check(oc) + + g.By("create catalogsource") + catsrc.Address = "quay.io/olmqe/olm-index:OLM-2378-Oadp-GoodOne-withCache" + catsrc.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "READY", exutil.Ok, []string{"catsrc", catsrc.Name, "-n", catsrc.Namespace, "-o=jsonpath={.status..lastObservedState}"}).Check(oc) + }) + + g.It("PolarionID:24027-[Skipped:Disconnected]can create and delete catalogsource and sub repeatedly", func() { + architecture.SkipNonAmd64SingleArch(oc) + platform := exutil.CheckPlatform(oc) + if strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || strings.Contains(platform, "none") || exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + ogD = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + subD = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v24027", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v24027", + CatalogSourceName: "", + CatalogSourceNamespace: "", + StartingCSV: "nginx-ok-v24027.v0.0.1", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-test-operator", + Namespace: "", + DisplayName: "Test Catsrc Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv24027", + Template: catsrcImageTemplate, + } + repeatedCount = 2 + og = ogD + sub = subD + ) + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need derfer or AfterEach + og.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + + catsrc.Namespace = oc.Namespace() + sub.CatalogSourceName = catsrc.Name + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("Create og") + og.Create(oc, itName, dr) + + for i := 0; i < repeatedCount; i++ { + g.By("Create Catalogsource") + catsrc.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithoutNamespace, exutil.Compare, "READY", exutil.Ok, []string{"catsrc", catsrc.Name, "-n", catsrc.Namespace, "-o=jsonpath={.status..lastObservedState}"}).Check(oc) + + g.By("Create sub with the above catalogsource") + sub.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("Remove catalog and sub") + sub.Delete(itName, dr) + sub.DeleteCSV(itName, dr) + catsrc.Delete(itName, dr) + if i < repeatedCount-1 { + time.Sleep(20 * time.Second) + } + } + }) + + // OCP-21404 - CSV will be RequirementsNotMet after SA is deleted + g.It("PolarionID:21404-[Skipped:Disconnected]csv will be RequirementsNotMet after sa is delete", func() { + if isAks, _ := exutil.IsAKSCluster(context.TODO(), oc); isAks { + g.Skip("skip for ask cluster") + } + architecture.SkipNonAmd64SingleArch(oc) + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipForSNOCluster(oc) + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || strings.Contains(platform, "none") || exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + ogD = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-operator", + Namespace: "", + DisplayName: "Test Catsrc Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-index:OLM-2378-Oadp-GoodOne-withCache", + Template: catsrcImageTemplate, + } + + subD = olmv0util.SubscriptionDescription{ + SubName: "oadp-operator", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "oadp-operator", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + og = ogD + sub = subD + ) + oc.SetupProject() + og.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("Create operator") + sub.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("Get SA of csv") + olmv0util.GetResource(oc, exutil.AsUser, exutil.WithNamespace, "csv", sub.InstalledCSV, "-o=json") + sa := olmv0util.NewSa(strings.Fields(olmv0util.GetResource(oc, exutil.AsUser, exutil.WithNamespace, "csv", sub.InstalledCSV, "-o=jsonpath={.status.requirementStatus[?(@.kind==\"ServiceAccount\")].name}"))[0], sub.Namespace) + + g.By("Delete sa of csv") + sa.GetDefinition(oc) + sa.Delete(oc) + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithNamespace, exutil.Compare, "RequirementsNotMet", exutil.Ok, []string{"csv", sub.InstalledCSV, "-o=jsonpath={.status.reason}"}).Check(oc) + + g.By("Recovery sa of csv") + sa.Reapply(oc) + olmv0util.NewCheck("expect", exutil.AsUser, exutil.WithNamespace, exutil.Compare, "Succeeded+2+Installing", exutil.Ok, []string{"csv", sub.InstalledCSV, "-o=jsonpath={.status.phase}"}).Check(oc) + }) + + // OCP-29723 - As cluster admin find abnormal status condition via components of operator resource + g.It("PolarionID:29723-[Skipped:Disconnected]As cluster admin find abnormal status condition via components of operator resource", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipNonAmd64SingleArch(oc) + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image-extract.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-29723-operator", + Namespace: "", + DisplayName: "Test Catsrc 29723 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:v1399-fbc-multi", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok1-1399", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok1-1399", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "nginx-ok1-1399.v0.0.4", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install perator") + sub.Create(oc, itName, dr) + + g.By("delete catalog source") + catsrc.Delete(itName, dr) + g.By("delete sa") + _, err := exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "sa", "nginx-ok1-1399-controller-manager", "-n", sub.Namespace) + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("check abnormal status") + output := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", sub.OperatorPackage+"."+sub.Namespace, "-o=json") + o.Expect(output).NotTo(o.BeEmpty()) + + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "CatalogSourcesUnhealthy", exutil.Ok, []string{"operator.operators.coreos.com", sub.OperatorPackage + "." + sub.Namespace, + fmt.Sprintf("-o=jsonpath={.status.components.refs[?(@.name==\"%s\")].conditions[*].type}", sub.SubName)}).Check(oc) + + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "RequirementsNotMet+2+InstallWaiting", exutil.Ok, []string{"operator.operators.coreos.com", sub.OperatorPackage + "." + sub.Namespace, + fmt.Sprintf("-o=jsonpath={.status.components.refs[?(@.name==\"%s\")].conditions[*].reason}", sub.InstalledCSV)}).Check(oc) + }) + + // OCP-30762 - installs bundles with v1 CRDs + g.It("PolarionID:30762-[Skipped:Disconnected]installs bundles with v1 CRDs", func() { + architecture.SkipNonAmd64SingleArch(oc) + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + e2e.Logf("platform: %v", platform) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "none") || + strings.Contains(platform, "vsphere") || strings.Contains(platform, "osp") || strings.Contains(platform, "ibmcloud") || strings.Contains(platform, "nutanix") || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" || + exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-30762-operator", + Namespace: "", + DisplayName: "Test Catsrc 30762 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv30762", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v30762", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v30762", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "nginx-ok-v30762.v0.0.1", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install perator") + sub.Create(oc, itName, dr) + + g.By("check csv") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + }) + + // OCP-27683 - InstallPlans can install from extracted bundles + g.It("PolarionID:27683-[Skipped:Disconnected]InstallPlans can install from extracted bundles", func() { + architecture.SkipNonAmd64SingleArch(oc) + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-27683-operator", + Namespace: "", + DisplayName: "Test Catsrc 27683 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv27683", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v27683", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v27683", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "nginx-ok-v27683.v0.0.1", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install perator") + sub.Create(oc, itName, dr) + + g.By("check csv") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("get bundle package from ip") + installPlan := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.installplan.name}") + o.Expect(installPlan).NotTo(o.BeEmpty()) + ipBundle := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "installplan", installPlan, "-n", sub.Namespace, "-o=jsonpath={.status.bundleLookups[0].path}") + o.Expect(ipBundle).NotTo(o.BeEmpty()) + + g.By("get bundle package from job") + jobName := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "job", "-n", catsrc.Namespace, "-o=jsonpath={.items[0].metadata.name}") + o.Expect(jobName).NotTo(o.BeEmpty()) + jobBundle := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "pod", "-l", "job-name="+jobName, "-n", catsrc.Namespace, "-o=jsonpath={.items[0].status.initContainerStatuses[*].image}") + o.Expect(jobName).NotTo(o.BeEmpty()) + o.Expect(jobBundle).To(o.ContainSubstring(ipBundle)) + }) + + g.It("PolarionID:24513-[Skipped:Disconnected]Operator config support env only", func() { + architecture.SkipNonAmd64SingleArch(oc) + platform := exutil.CheckPlatform(oc) + if strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || strings.Contains(platform, "none") || exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image-extract.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-24513-operator", + Namespace: "", + DisplayName: "Test Catsrc 24513 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:v1399-1-arg", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok1-1399", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok1-1399", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "nginx-ok1-1399.v0.0.5", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install operator") + sub.Create(oc, itName, dr) + + g.By("check csv") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("get parameter of deployment") + olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "deployment", "-n", sub.Namespace, "-o=yaml") + + g.By("patch env for sub") + sub.Patch(oc, "{\"spec\": {\"config\": {\"env\": [{\"name\": \"EMPTY_ENV\"},{\"name\": \"ARGS1\",\"value\": \"-v=4\"}]}}}") + + g.By("check the empty env") + }) + + g.It("PolarionID:24382-[Skipped:Disconnected]Should restrict CRD update if schema changes[Serial]", func() { + if isAks, _ := exutil.IsAKSCluster(context.TODO(), oc); isAks { + g.Skip("skip for aks cluster") + } + architecture.SkipNonAmd64SingleArch(oc) + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipForSNOCluster(oc) + node, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + err = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(err).NotTo(o.HaveOccurred()) + efips, err := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if err != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + e2e.Logf("platform: %v", platform) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-legacy.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + etcdCluster = filepath.Join(buildPruningBaseDir, "etcd-cluster.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-24382-operator", + Namespace: "", + DisplayName: "Test Catsrc 24382 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-dep:vschema-crdv3", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "etcd", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "etcd", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "etcdoperator.v0.9.2", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + etcdCr = olmv0util.CustomResourceDescription{ + Name: "example-24382", + Namespace: "", + TypeName: "EtcdCluster", + Template: etcdCluster, + } + ) + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + etcdCr.Namespace = oc.Namespace() + defer func() { _ = exutil.RecoverNamespaceRestricted(oc, oc.Namespace()) }() + err = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install operator") + sub.Create(oc, itName, dr) + + g.By("check csv") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + errCRD := wait.PollUntilContextTimeout(context.TODO(), 30*time.Second, 60*time.Second, false, func(ctx context.Context) (bool, error) { + output, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("crd", "etcdclusters.etcd.database.coreos.com", "-o=jsonpath={.status.storedVersions}").Output() + if err != nil { + return false, err + } + if strings.Contains(output, "v1beta2") { + return true, nil + } + return false, nil + }) + exutil.AssertWaitPollNoErr(errCRD, "crd etcdcluster does not exist") + + g.By("create cr") + etcdCr.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Running", exutil.Ok, []string{etcdCr.TypeName, etcdCr.Name, "-n", etcdCr.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("update operator") + sub.Patch(oc, "{\"spec\": {\"channel\": \"beta\"}}") + sub.FindInstalledCSV(oc, itName, dr) + + errIP := wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 120*time.Second, false, func(ctx context.Context) (bool, error) { + output, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.currentCSV}").Output() + if err != nil { + return false, err + } + if strings.Contains(output, "etcdoperator.v0.9.4") { + return true, nil + } + return false, nil + }) + exutil.AssertWaitPollNoErr(errIP, "operator does not change to etcdoperator.v0.9.4") + + g.By("check schema does not work") + installPlan := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.installplan.name}") + o.Expect(installPlan).NotTo(o.BeEmpty()) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "error validating existing CRs", exutil.Ok, []string{"installplan", installPlan, "-n", sub.Namespace, "-o=jsonpath={.status.conditions[*].message}"}).Check(oc) + }) + + // Group 8: OCP-25760 + OCP-35895 + g.It("PolarionID:25760-[Skipped:Disconnected]Operator upgrades does not fail after change the channel", func() { + architecture.SkipNonAmd64SingleArch(oc) + exutil.SkipForSNOCluster(oc) + platform := exutil.CheckPlatform(oc) + if strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || strings.Contains(platform, "none") || exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + node, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + err = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(err).NotTo(o.HaveOccurred()) + efips, errFips := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errFips != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image-extract.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-25760-operator", + Namespace: "", + DisplayName: "Test Catsrc 25760 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv25760", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v25760", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v25760", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "nginx-ok-v25760.v0.0.1", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.Create(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install operator") + sub.Create(oc, itName, dr) + + g.By("check csv") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("switch channel") + sub.Patch(oc, "{\"spec\": {\"channel\": \"beta\"}}") + sub.FindInstalledCSV(oc, itName, dr) + + g.By("check csv of new channel") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + }) + + g.It("PolarionID:35895-[Skipped:Disconnected]can't install a CSV with duplicate roles", func() { + architecture.SkipNonAmd64SingleArch(oc) + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + exutil.SkipForSNOCluster(oc) + platform := exutil.CheckPlatform(oc) + e2e.Logf("platform: %v", platform) + proxy, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "none") || + strings.Contains(platform, "vsphere") || strings.Contains(platform, "osp") || strings.Contains(platform, "ibmcloud") || strings.Contains(platform, "nutanix") || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" || + exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-35895-operator", + Namespace: "", + DisplayName: "Test Catsrc 35895 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-dep:vmtaduprol2-withCache", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "mta-operator", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "mta-operator", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "windup-operator.0.0.5", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.Create(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install operator") + sub.Create(oc, itName, dr) + + g.By("check csv") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("check sa") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "windup-operator-haproxy", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={..serviceAccountName}"}).Check(oc) + }) + + // Group 9: OCP-32863 + g.It("PolarionID:32863-[Skipped:Disconnected]Support resources required for SAP Gardener Control Plane Operator[Disruptive]", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipNonAmd64SingleArch(oc) + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipForSNOCluster(oc) + platform := exutil.CheckPlatform(oc) + e2e.Logf("platform: %v", platform) + node, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + errGet = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errGet).NotTo(o.HaveOccurred()) + efips, errGet := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errGet != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + proxy, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "none") || + strings.Contains(platform, "vsphere") || strings.Contains(platform, "external") || strings.Contains(platform, "osp") || exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + vpaTemplate = filepath.Join(buildPruningBaseDir, "vpa-crd.yaml") + crdVpa = olmv0util.CrdDescription{ + Name: "verticalpodautoscalers.autoscaling.k8s.io", + Template: vpaTemplate, + } + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-32863-operator", + Namespace: "", + DisplayName: "Test Catsrc 32863 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/single-bundle-index:pdb3", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "busybox", + Namespace: "", + Channel: "candidate-v2", + IpApproval: "Automatic", + OperatorPackage: "busybox", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "busybox.v2.0.0", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + + // defer crdVpa.Delete(oc) //it is not needed in case it already exist + if olmv0util.IsPresentResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, exutil.NotPresent, "crd", crdVpa.Name) { + + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need derfer or AfterEach + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create vpa crd") + crdVpa.Create(oc, itName, dr) + defer crdVpa.Delete(oc) + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install operator") + sub.Create(oc, itName, dr) + + g.By("check csv") + err := wait.PollUntilContextTimeout(context.TODO(), 15*time.Second, 5*time.Minute, false, func(ctx context.Context) (bool, error) { + status := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}") + if strings.Compare(status, "Succeeded") == 0 { + return true, nil + } + return false, nil + }) + exutil.AssertWaitPollNoErr(err, "csv busybox.v2.0.0 is not installed as expected") + + g.By("check additional resources") + olmv0util.NewCheck("present", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Present, "", exutil.Ok, []string{"VerticalPodAutoscaler", "busybox-vpa", "-n", sub.Namespace}).Check(oc) + olmv0util.NewCheck("present", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Present, "", exutil.Ok, []string{"PriorityClass", "super-priority", "-n", sub.Namespace}).Check(oc) + olmv0util.NewCheck("present", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Present, "", exutil.Ok, []string{"PodDisruptionBudget", "busybox-pdb", "-n", sub.Namespace}).Check(oc) + } + }) + + // Group 10 - OCP-34472 + g.It("PolarionID:34472-[Skipped:Disconnected]olm label dependency", func() { + architecture.SkipNonAmd64SingleArch(oc) + platform := exutil.CheckPlatform(oc) + if strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || strings.Contains(platform, "none") || exutil.Is3MasterNoDedicatedWorkerNode(oc) { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image-extract.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "olm-1933-v8-catalog", + Namespace: "", + DisplayName: "OLM 1933 v8 Operator Catalog", + Publisher: "QE", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-dep:v12", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "mta-operator", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "mta-operator", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "windup-operator.0.0.5", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + dependentOperator = "nginx-ok1-1399.v0.0.5" + ) + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.Create(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install operator") + sub.Create(oc, itName, dr) + + g.By("check if dependent operator is installed") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", sub.InstalledCSV, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", dependentOperator, "-n", sub.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + }) + + // Group 10 - OCP-33176 + g.It("PolarionID:33176-[Skipped:Disconnected]Enable generated operator component adoption for operators with single ns mode[Slow][Serial]", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipNonAmd64SingleArch(oc) + if isAks, _ := exutil.IsAKSCluster(context.TODO(), oc); isAks { + g.Skip("skip for ask cluster") + } + exutil.SkipNoCapabilities(oc, "marketplace") + node, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + errGet = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errGet).NotTo(o.HaveOccurred()) + efips, errGet := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errGet != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + infra, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "none") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + apiserviceImageTemplate = filepath.Join(buildPruningBaseDir, "apiservice.yaml") + apiserviceVersion = "v33176" + apiserviceName = apiserviceVersion + ".foos.bar.com" + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-33176-operator", + Namespace: "", + DisplayName: "Test Catsrc 33176 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-api:v5", + Template: catsrcImageTemplate, + } + subEtcd = olmv0util.SubscriptionDescription{ + SubName: "etcd33176", + Namespace: "", + Channel: "singlenamespace-alpha", + IpApproval: "Automatic", + OperatorPackage: "etcd", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "etcdoperator.v0.9.4", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: false, + } + subCockroachdb = olmv0util.SubscriptionDescription{ + SubName: "cockroachdb33176", + Namespace: "", + Channel: "stable-5.x", + IpApproval: "Automatic", + OperatorPackage: "cockroachdb", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "cockroachdb.v5.0.4", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: false, + } + ) + + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + subEtcd.Namespace = oc.Namespace() + subEtcd.CatalogSourceNamespace = catsrc.Namespace + subCockroachdb.Namespace = oc.Namespace() + subCockroachdb.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.Create(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install Etcd") + subEtcd.Create(oc, itName, dr) + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subEtcd.OperatorPackage+"."+subEtcd.Namespace) + }() + + g.By("Check all resources via operators") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "ServiceAccount", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "Role", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "RoleBinding", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "CustomResourceDefinition", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "Subscription", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "InstallPlan", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "ClusterServiceVersion", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "Deployment", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, subEtcd.Namespace, exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[?(.kind=='ClusterServiceVersion')].namespace}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "InstallSucceeded", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[?(.kind=='ClusterServiceVersion')].conditions[*].reason}"}).Check(oc) + + g.By("delete operator and Operator still exists because of crd") + subEtcd.Delete(itName, dr) + _, err := exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "csv", subEtcd.InstalledCSV, "-n", subEtcd.Namespace) + o.Expect(err).NotTo(o.HaveOccurred()) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "CustomResourceDefinition", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + + g.By("reinstall etcd and check Operator") + subEtcd.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "InstallSucceeded", exutil.Ok, []string{"operator.operators.coreos.com", subEtcd.OperatorPackage + "." + subEtcd.Namespace, "-o=jsonpath={.status.components.refs[?(.kind=='ClusterServiceVersion')].conditions[*].reason}"}).Check(oc) + + g.By("delete etcd and the Operator again and Operator should recreated because of crd") + _, err = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "sub", subEtcd.SubName, "-n", subEtcd.Namespace) + o.Expect(err).NotTo(o.HaveOccurred()) + _, err = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "csv", subEtcd.InstalledCSV, "-n", subEtcd.Namespace) + o.Expect(err).NotTo(o.HaveOccurred()) + _, err = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subEtcd.OperatorPackage+"."+subEtcd.Namespace) + o.Expect(err).NotTo(o.HaveOccurred()) + // here there is issue and take WA + _, err = exutil.OcAction(oc, "label", exutil.AsAdmin, exutil.WithoutNamespace, "crd", "etcdbackups.etcd.database.coreos.com", "operators.coreos.com/"+subEtcd.OperatorPackage+"."+subEtcd.Namespace+"-") + o.Expect(err).NotTo(o.HaveOccurred()) + _, err = exutil.OcAction(oc, "label", exutil.AsAdmin, exutil.WithoutNamespace, "crd", "etcdbackups.etcd.database.coreos.com", "operators.coreos.com/"+subEtcd.OperatorPackage+"."+subEtcd.Namespace+"=") + o.Expect(err).NotTo(o.HaveOccurred()) + //done for WA + var componentKind string + err = wait.PollUntilContextTimeout(context.TODO(), 15*time.Second, 240*time.Second, false, func(ctx context.Context) (bool, error) { + componentKind = olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subEtcd.OperatorPackage+"."+subEtcd.Namespace, "-o=jsonpath={.status.components.refs[*].kind}") + if strings.Contains(componentKind, "CustomResourceDefinition") { + return true, nil + } + e2e.Logf("the got kind is %v", componentKind) + return false, nil + }) + if err != nil && strings.Compare(componentKind, "") != 0 { + e2e.Failf("the operator has wrong component") + // after the official is supported, will change it again. + } + + g.By("install Cockroachdb") + subCockroachdb.Create(oc, itName, dr) + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subCockroachdb.OperatorPackage+"."+subCockroachdb.Namespace) + }() + + g.By("Check all resources of Cockroachdb via operators") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "Role", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "RoleBinding", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "CustomResourceDefinition", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "Subscription", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "InstallPlan", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "ClusterServiceVersion", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "Deployment", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, subCockroachdb.Namespace, exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[?(.kind=='ClusterServiceVersion')].namespace}"}).Check(oc) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "InstallSucceeded", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[?(.kind=='ClusterServiceVersion')].conditions[*].reason}"}).Check(oc) + + g.By("create ns test-33176 and label it") + _, err = exutil.OcAction(oc, "create", exutil.AsAdmin, exutil.WithoutNamespace, "ns", "test-33176") + o.Expect(err).NotTo(o.HaveOccurred()) + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "ns", "test-33176", "--force", "--grace-period=0", "--wait=false") + }() + _, err = exutil.OcAction(oc, "label", exutil.AsAdmin, exutil.WithoutNamespace, "ns", "test-33176", "operators.coreos.com/"+subCockroachdb.OperatorPackage+"."+subCockroachdb.Namespace+"=") + o.Expect(err).NotTo(o.HaveOccurred()) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "Namespace", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + + g.By("create apiservice and label it") + err = olmv0util.ApplyResourceFromTemplate(oc, "--ignore-unknown-parameters=true", "-f", apiserviceImageTemplate, "-p", "NAME="+apiserviceName, "VERSION="+apiserviceVersion) + o.Expect(err).NotTo(o.HaveOccurred()) + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "apiservice", apiserviceName) + }() + _, err = exutil.OcAction(oc, "label", exutil.AsAdmin, exutil.WithoutNamespace, "apiservice", apiserviceName, + "operators.coreos.com/"+subCockroachdb.OperatorPackage+"."+subCockroachdb.Namespace+"=") + o.Expect(err).NotTo(o.HaveOccurred()) + _, err = exutil.OcAction(oc, "label", exutil.AsAdmin, exutil.WithoutNamespace, "apiservice", apiserviceName, + "olm.managed="+`true`) + o.Expect(err).NotTo(o.HaveOccurred()) + _, err = exutil.OcAction(oc, "label", exutil.AsAdmin, exutil.WithoutNamespace, "apiservice", apiserviceName, + "olm.owner"+"="+subCockroachdb.InstalledCSV) + o.Expect(err).NotTo(o.HaveOccurred()) + _, err = exutil.OcAction(oc, "label", exutil.AsAdmin, exutil.WithoutNamespace, "apiservice", apiserviceName, + "olm.owner.kind"+"="+"ClusterServiceVersion") + o.Expect(err).NotTo(o.HaveOccurred()) + _, err = exutil.OcAction(oc, "label", exutil.AsAdmin, exutil.WithoutNamespace, "apiservice", apiserviceName, + "olm.owner.namespace"+"="+subCockroachdb.Namespace) + o.Expect(err).NotTo(o.HaveOccurred()) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "APIService", exutil.Ok, []string{"operator.operators.coreos.com", subCockroachdb.OperatorPackage + "." + subCockroachdb.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + }) + + // Group 11 - OCP-39897 + g.It("PolarionID:39897-[Skipped:Disconnected]operator objects should not be recreated after all other associated resources have been deleted[Serial]", func() { + architecture.SkipNonAmd64SingleArch(oc) + if isAks, _ := exutil.IsAKSCluster(context.TODO(), oc); isAks { + g.Skip("skip for ask cluster") + } + exutil.SkipNoCapabilities(oc, "marketplace") + node, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + errGet = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errGet).NotTo(o.HaveOccurred()) + efips, errGet := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errGet != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + infra, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-39897-operator", + Namespace: "", + DisplayName: "Test Catsrc 39897 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/nginx-ok-index:vokv39897", + Template: catsrcImageTemplate, + } + subMta = olmv0util.SubscriptionDescription{ + SubName: "nginx-ok-v39897", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "nginx-ok-v39897", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "nginx-ok-v39897.v0.0.1", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: false, + } + crd = olmv0util.CrdDescription{ + Name: "okv39897s.cache.example.com", + } + ) + + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + subMta.Namespace = oc.Namespace() + subMta.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install Teiid") + subMta.Create(oc, itName, dr) + defer func() { + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subMta.OperatorPackage+"."+subMta.Namespace) + }() + + g.By("Check the resources via operators") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "CustomResourceDefinition", exutil.Ok, []string{"operator.operators.coreos.com", subMta.OperatorPackage + "." + subMta.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + + g.By("delete operator and Operator still exists because of crd") + subMta.Delete(itName, dr) + _, err := exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "csv", subMta.InstalledCSV, "-n", subMta.Namespace) + o.Expect(err).NotTo(o.HaveOccurred()) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Contain, "CustomResourceDefinition", exutil.Ok, []string{"operator.operators.coreos.com", subMta.OperatorPackage + "." + subMta.Namespace, "-o=jsonpath={.status.components.refs[*].kind}"}).Check(oc) + + g.By("delete crd") + crd.Delete(oc) + + g.By("delete Operator resource to check if it is recreated") + _, _ = exutil.OcAction(oc, "delete", exutil.AsAdmin, exutil.WithoutNamespace, "operator.operators.coreos.com", subMta.OperatorPackage+"."+subMta.Namespace) + olmv0util.NewCheck("present", exutil.AsAdmin, exutil.WithoutNamespace, exutil.NotPresent, "", exutil.Ok, []string{"operator.operators.coreos.com", subMta.OperatorPackage + "." + subMta.Namespace}).Check(oc) + }) + + // Group 12 - OCP-50135 + g.It("PolarionID:50135-[Skipped:Disconnected]automatic upgrade for failed operator installation og created correctly", func() { + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + ogAllTemplate = filepath.Join(buildPruningBaseDir, "og-allns.yaml") + ogUpgradeStrategyTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup-upgradestrategy.yaml") + + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + ogAll = olmv0util.OperatorGroupDescription{ + Name: "og-all", + Namespace: "", + Template: ogAllTemplate, + } + ogDefault = olmv0util.OperatorGroupDescription{ + Name: "og-default", + Namespace: "", + UpgradeStrategy: "Default", + Template: ogUpgradeStrategyTemplate, + } + ogFailForward = olmv0util.OperatorGroupDescription{ + Name: "og-failforwad", + Namespace: "", + UpgradeStrategy: "TechPreviewUnsafeFailForward", + Template: ogUpgradeStrategyTemplate, + } + ogFoo = olmv0util.OperatorGroupDescription{ + Name: "og-foo", + Namespace: "", + UpgradeStrategy: "foo", + Template: ogUpgradeStrategyTemplate, + } + ) + + oc.SetupProject() + ns := oc.Namespace() + og.Namespace = ns + ogAll.Namespace = ns + ogDefault.Namespace = ns + ogFailForward.Namespace = ns + ogFoo.Namespace = ns + + g.By("Create og") + og.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Default", exutil.Ok, []string{"og", og.Name, "-n", og.Namespace, "-o=jsonpath={.spec.upgradeStrategy}"}).Check(oc) + og.Delete(itName, dr) + + g.By("Create og all") + ogAll.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Default", exutil.Ok, []string{"og", ogAll.Name, "-n", ogAll.Namespace, "-o=jsonpath={.spec.upgradeStrategy}"}).Check(oc) + ogAll.Delete(itName, dr) + + g.By("Create og Default") + ogDefault.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Default", exutil.Ok, []string{"og", ogDefault.Name, "-n", ogDefault.Namespace, "-o=jsonpath={.spec.upgradeStrategy}"}).Check(oc) + ogDefault.Delete(itName, dr) + + g.By("Create og failforward") + ogFailForward.Create(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "TechPreviewUnsafeFailForward", exutil.Ok, []string{"og", ogFailForward.Name, "-n", ogFailForward.Namespace, "-o=jsonpath={.spec.upgradeStrategy}"}).Check(oc) + ogFailForward.Delete(itName, dr) + + g.By("Create og with invalid upgradeStrategy") + err := olmv0util.ApplyResourceFromTemplate(oc, "--ignore-unknown-parameters=true", "-f", ogFoo.Template, "-p", "NAME="+ogFoo.Name, "NAMESPACE="+ogFoo.Namespace, "UPGRADESTRATEGY="+ogFoo.UpgradeStrategy) + o.Expect(err).To(o.HaveOccurred()) + o.Expect(err.Error()).To(o.ContainSubstring("exit status 1")) + }) + + // Group 12 - OCP-50136 + g.It("PolarionID:50136-[Skipped:Disconnected]automatic upgrade for failed operator installation csv fails[Slow][Timeout:30m]", func() { + architecture.SkipNonAmd64SingleArch(oc) + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-2378-operator", + Namespace: "", + DisplayName: "Test Catsrc 2378 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-index:OLM-2378-Oadp-GoodOne-multi", + Template: catsrcImageTemplate, + } + subOadp = olmv0util.SubscriptionDescription{ + SubName: "oadp-operator", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "oadp-operator", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "oadp-operator.v0.5.3", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + subOadp.Namespace = oc.Namespace() + subOadp.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.CreateWithCheck(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install OADP") + subOadp.Create(oc, itName, dr) + + g.By("Check the oadp-operator.v0.5.3 is installed successfully") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", subOadp.InstalledCSV, "-n", subOadp.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("patch to index image with wrong bundle csv fails") + err := oc.AsAdmin().WithoutNamespace().Run("patch").Args("catsrc", catsrc.Name, "-n", catsrc.Namespace, "--type=merge", "-p", "{\"spec\":{\"image\":\"quay.io/olmqe/olm-index:OLM-2378-Oadp-csvfail-multi\"}}").Execute() + o.Expect(err).NotTo(o.HaveOccurred()) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "oadp-operator.v0.5.4", exutil.Ok, []string{"sub", subOadp.SubName, "-n", subOadp.Namespace, "-o=jsonpath={.status.currentCSV}"}).Check(oc) + + g.By("check the csv fails") + var status string + // it fails after 10m which we can not control it. so, have to check it in 11m + err = wait.PollUntilContextTimeout(context.TODO(), 30*time.Second, 15*time.Minute, false, func(ctx context.Context) (bool, error) { + status = olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "csv", "oadp-operator.v0.5.4", "-n", subOadp.Namespace, "-o=jsonpath={.status.phase}") + if strings.Compare(status, "Failed") == 0 { + e2e.Logf("csv oadp-operator.v0.5.4 fails expected") + return true, nil + } + return false, nil + }) + if strings.Contains(status, "nstalling") { + return + } + exutil.AssertWaitPollNoErr(err, "csv oadp-operator.v0.5.4 is not failing as expected") + + g.By("change upgrade strategy to TechPreviewUnsafeFailForward") + 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("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) { + 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) + return true, nil + } + return false, nil + }) + 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) { + 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") + return true, nil + } + return false, nil + }) + exutil.AssertWaitPollNoErr(err, "csv oadp-operator.v0.5.6 is not successful") + + }) + + g.It("PolarionID:50138-[Skipped:Disconnected]automatic upgrade for failed operator installation ip fails", func() { + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + exutil.SkipBaselineCaps(oc, "None") + exutil.SkipForSNOCluster(oc) + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + og = olmv0util.OperatorGroupDescription{ + Name: "og-singlenamespace", + Namespace: "", + Template: ogSingleTemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-2378-operator", + Namespace: "", + DisplayName: "Test Catsrc 2378 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-index:OLM-2378-Oadp-GoodOne-multi", + Template: catsrcImageTemplate, + } + subOadp = olmv0util.SubscriptionDescription{ + SubName: "oadp-operator", + Namespace: "", + Channel: "alpha", + IpApproval: "Automatic", + OperatorPackage: "oadp-operator", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "oadp-operator.v0.5.3", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + + oc.SetupProject() + og.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + subOadp.Namespace = oc.Namespace() + subOadp.CatalogSourceNamespace = catsrc.Namespace + + g.By("create catalog source") + catsrc.Create(oc, itName, dr) + + g.By("Create og") + og.Create(oc, itName, dr) + + g.By("install OADP") + subOadp.Create(oc, itName, dr) + + g.By("Check the oadp-operator.v0.5.3 is installed successfully") + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", subOadp.InstalledCSV, "-n", subOadp.Namespace, "-o=jsonpath={.status.phase}"}).Check(oc) + + g.By("patch to index image with wrong bundle ip fails") + err = oc.AsAdmin().WithoutNamespace().Run("patch").Args("catsrc", catsrc.Name, "-n", catsrc.Namespace, "--type=merge", "-p", "{\"spec\":{\"image\":\"quay.io/olmqe/olm-index:OLM-2378-Oadp-ipfailTwo-multi\"}}").Execute() + o.Expect(err).NotTo(o.HaveOccurred()) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "oadp-operator.v0.5.5", exutil.Ok, []string{"sub", subOadp.SubName, "-n", subOadp.Namespace, "-o=jsonpath={.status.currentCSV}"}).Check(oc) + + g.By("check the ip fails") + ips := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "sub", subOadp.SubName, "-n", subOadp.Namespace, "-o=jsonpath={.status.installplan.name}") + o.Expect(ips).NotTo(o.BeEmpty()) + err = wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 300*time.Second, false, func(ctx context.Context) (bool, error) { + status := olmv0util.GetResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "installplan", ips, "-n", subOadp.Namespace, "-o=jsonpath={.status.phase}") + if strings.Compare(status, "Failed") == 0 { + e2e.Logf("ip %v fails expected", ips) + return true, nil + } + return false, nil + }) + exutil.AssertWaitPollNoErr(err, fmt.Sprintf("ip %v not failing as expected", ips)) + + g.By("change upgrade strategy to TechPreviewUnsafeFailForward") + 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("patch to index image again with fixed bundle") + err = oc.AsAdmin().WithoutNamespace().Run("patch").Args("catsrc", catsrc.Name, "-n", catsrc.Namespace, "--type=merge", "-p", "{\"spec\":{\"image\":\"quay.io/olmqe/olm-index:OLM-2378-Oadp-ipfailskip-multi\"}}").Execute() + o.Expect(err).NotTo(o.HaveOccurred()) + err = wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 300*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) + return true, nil + } + return false, nil + }) + 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) { + 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") + return true, nil + } + return false, nil + }) + exutil.AssertWaitPollNoErr(err, "csv oadp-operator.v0.5.6 is not successful") + + }) + + g.It("PolarionID:40958-[Skipped:Disconnected]Indicate invalid OperatorGroup on InstallPlan status", g.Label("NonHyperShiftHOST"), func() { + architecture.SkipNonAmd64SingleArch(oc) + if isAks, _ := exutil.IsAKSCluster(context.TODO(), oc); isAks { + g.Skip("skip for ask cluster") + } + exutil.SkipNoCapabilities(oc, "marketplace") + node, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata.name}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + errGet = exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errGet).NotTo(o.HaveOccurred()) + efips, errGet := oc.AsAdmin().WithoutNamespace().Run("debug").Args("node/"+node, "--to-namespace="+oc.Namespace(), "--", "chroot", "/host", "fips-mode-setup", "--check").Output() + if errGet != nil || strings.Contains(efips, "FIPS mode is enabled") { + g.Skip("skip it without impacting function") + } + infra, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() + o.Expect(errGet).NotTo(o.HaveOccurred()) + if infra == "SingleReplica" { + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "none") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + ogSingleTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") + ogSAtemplate = filepath.Join(buildPruningBaseDir, "operatorgroup-serviceaccount.yaml") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-legacy.yaml") + subTemplate = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") + saName = "scopedv40958" + og1 = olmv0util.OperatorGroupDescription{ + Name: "og1-40958", + Namespace: "", + Template: ogSingleTemplate, + } + og2 = olmv0util.OperatorGroupDescription{ + Name: "og2-40958", + Namespace: "", + Template: ogSingleTemplate, + } + ogSa = olmv0util.OperatorGroupDescription{ + Name: "ogsa-40958", + Namespace: "", + ServiceAccountName: saName, + Template: ogSAtemplate, + } + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-40958-operator", + Namespace: "", + DisplayName: "Test Catsrc 40958 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "quay.io/olmqe/olm-dep:v40958", + Template: catsrcImageTemplate, + } + sub = olmv0util.SubscriptionDescription{ + SubName: "teiid", + Namespace: "", + Channel: "beta", + IpApproval: "Automatic", + OperatorPackage: "teiid", + CatalogSourceName: catsrc.Name, + CatalogSourceNamespace: "", + StartingCSV: "teiid.v0.4.0", + CurrentCSV: "", + InstalledCSV: "", + Template: subTemplate, + SingleNamespace: true, + } + ) + oc.SetupProject() // project and its resource are deleted automatically when out of It, so no need derfer or AfterEach + og1.Namespace = oc.Namespace() + og2.Namespace = oc.Namespace() + ogSa.Namespace = oc.Namespace() + catsrc.Namespace = oc.Namespace() + sub.Namespace = oc.Namespace() + sub.CatalogSourceNamespace = catsrc.Namespace + defer func() { _ = exutil.RecoverNamespaceRestricted(oc, oc.Namespace()) }() + errSet := exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errSet).NotTo(o.HaveOccurred()) + + g.By("create catalog source") + catsrc.Create(oc, itName, dr) + + g.By("install operator without og") + sub.CreateWithoutCheck(oc, itName, dr) + + g.By("no Installplan is generated, without og") + // by https://issues.redhat.com/browse/OCPBUGS-9259 + waitErr := wait.PollUntilContextTimeout(context.TODO(), 3*time.Second, 10*time.Second, false, func(ctx context.Context) (bool, error) { + var err error + installPlan, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.installPlanRef.name}").Output() + if strings.Compare(installPlan, "") == 0 || err != nil { + return false, nil + } + return true, nil + }) + exutil.AssertWaitPollWithErr(waitErr, fmt.Sprintf("sub %s has installplan", sub.SubName)) + + g.By("delete operator") + sub.Delete(itName, dr) + + g.By("Create og1") + og1.Create(oc, itName, dr) + + g.By("Create og2") + og2.Create(oc, itName, dr) + + g.By("install operator with multiple og") + sub.CreateWithoutCheck(oc, itName, dr) + + g.By("no Installplan is generated, multiple og") + waitErr = wait.PollUntilContextTimeout(context.TODO(), 3*time.Second, 10*time.Second, false, func(ctx context.Context) (bool, error) { + var err error + installPlan, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.installPlanRef.name}").Output() + if strings.Compare(installPlan, "") == 0 || err != nil { + return false, nil + } + return true, nil + }) + exutil.AssertWaitPollWithErr(waitErr, fmt.Sprintf("sub %s has installplan", sub.SubName)) + + g.By("delete resource for next step") + sub.Delete(itName, dr) + og1.Delete(itName, dr) + og2.Delete(itName, dr) + + g.By("create sa") + _, err := oc.WithoutNamespace().AsAdmin().Run("create").Args("sa", saName, "-n", sub.Namespace).Output() + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("Create ogSa") + ogSa.CreateWithCheck(oc, itName, dr) + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, saName, exutil.Ok, []string{"og", ogSa.Name, "-n", ogSa.Namespace, "-o=jsonpath={.status.serviceAccountRef.name}"}).Check(oc) + + g.By("delete the service account") + _, err = oc.WithoutNamespace().AsAdmin().Run("delete").Args("sa", saName, "-n", sub.Namespace).Output() + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("install operator without sa for og") + sub.CreateWithoutCheck(oc, itName, dr) + + g.By("no Installplan is generated, without sa for og") + installPlan, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("sub", sub.SubName, "-n", sub.Namespace, "-o=jsonpath={.status.installPlanRef.name}").Output() + if strings.Compare(installPlan, "") != 0 && err == nil { + subContent, _ := oc.WithoutNamespace().AsAdmin().Run("get").Args("sub", sub.SubName, "-n", sub.Namespace, "-oyaml").Output() + e2e.Logf("subContent: %v", subContent) + e2e.Failf("should no ip") + } + }) + + g.It("PolarionID:60114-[Skipped:Disconnected]olm serves an api to discover all versions of an operator[Slow]", func() { + architecture.SkipArchitectures(oc, architecture.PPC64LE, architecture.S390X, architecture.MULTI) + _ = oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-o=jsonpath={.items[0].metadata}").Execute() + nodes, errGet := oc.AsAdmin().WithoutNamespace().Run("get").Args("node", "-l", "node.kubernetes.io/instance-type=Standard_EC4es_v6").Output() + if errGet != nil || len(nodes) == 0 { + e2e.Logf("nodes: %v", nodes) + g.Skip("it is not supported") + } + platform := exutil.CheckPlatform(oc) + proxy, errProxy := oc.AsAdmin().WithoutNamespace().Run("get").Args("proxy", "cluster", "-o=jsonpath={.status.httpProxy}{.status.httpsProxy}").Output() + o.Expect(errProxy).NotTo(o.HaveOccurred()) + if proxy != "" || strings.Contains(platform, "openstack") || strings.Contains(platform, "baremetal") || strings.Contains(platform, "vsphere") || + strings.Contains(platform, "ibmcloud") || strings.Contains(platform, "nutanix") || exutil.Is3MasterNoDedicatedWorkerNode(oc) || + os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" || os.Getenv("http_proxy") != "" || os.Getenv("https_proxy") != "" { + g.Skip("it is not supported") + } + var ( + itName = g.CurrentSpecReport().FullText() + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + catsrcImageTemplate = filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") + catsrc = olmv0util.CatalogSourceDescription{ + Name: "catsrc-run1399-operator", + Namespace: "", + DisplayName: "Test Catsrc RUN1399 Operators", + Publisher: "Red Hat", + SourceType: "grpc", + Address: "", + Template: catsrcImageTemplate, + } + ) + + catsrc.Namespace = oc.Namespace() + + ok1AlphaAssertion := func(entries string) { + o.Expect(entries).To(o.ContainSubstring("nginx-ok1-1399.v0.0.4")) + o.Expect(entries).To(o.ContainSubstring("nginx-ok1-1399.v0.0.2")) + o.Expect(entries).To(o.ContainSubstring("nginx-ok1-1399.v0.0.1")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok1-1399.v0.0.5")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok1-1399.v0.0.3")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.4\"")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.2\"")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.1\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.5\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.3\"")) + } + ok1BetaAssertion := func(entries string) { + o.Expect(entries).To(o.ContainSubstring("nginx-ok1-1399.v0.0.5")) + o.Expect(entries).To(o.ContainSubstring("nginx-ok1-1399.v0.0.3")) + o.Expect(entries).To(o.ContainSubstring("nginx-ok1-1399.v0.0.1")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok1-1399.v0.0.4")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok1-1399.v0.0.2")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.5\"")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.3\"")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.1\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.4\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.2\"")) + } + ok2AlphaNoDepAssertion := func(entries string) { + o.Expect(entries).To(o.ContainSubstring("nginx-ok2-1399.v0.0.4")) + o.Expect(entries).To(o.ContainSubstring("nginx-ok2-1399.v0.0.2")) + o.Expect(entries).To(o.ContainSubstring("nginx-ok2-1399.v0.0.1")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.5")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.3")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.4\"")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.2\"")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.1\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.5\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.3\"")) + } + ok2BetaAssertion := func(entries string) { + o.Expect(entries).To(o.ContainSubstring("nginx-ok2-1399.v0.0.5")) + o.Expect(entries).To(o.ContainSubstring("nginx-ok2-1399.v0.0.3")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.4")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.2")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.1")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.5\"")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.3\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.4\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.2\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.1\"")) + } + + g.By("fbc based image without deprecated bundle") + catsrc.Address = "quay.io/olmqe/nginx-ok-index:v1399-fbc-multi" + catsrc.CreateWithCheck(oc, itName, dr) + entries := olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok1-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"alpha\")].entries}") + ok1AlphaAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok1-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"beta\")].entries}") + ok1BetaAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok2-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"alpha\")].entries}") + ok2AlphaNoDepAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok2-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"beta\")].entries}") + ok2BetaAssertion(entries) + + catsrc.Delete(itName, dr) + + g.By("ffbc based image with deprecated bundle made by properties.yaml") + catsrc.Address = "quay.io/olmqe/nginx-ok-index:v1399-fbc-deprecate-nomigrate-multi" + catsrc.CreateWithCheck(oc, itName, dr) + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok1-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"alpha\")].entries}") + ok1AlphaAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok1-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"beta\")].entries}") + ok1BetaAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok2-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"alpha\")].entries}") + o.Expect(entries).To(o.ContainSubstring("nginx-ok2-1399.v0.0.4")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.2")) + o.Expect(entries).To(o.ContainSubstring("nginx-ok2-1399.v0.0.1")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.5")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.3")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.4\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.2\"")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.1\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.5\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.3\"")) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok2-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"beta\")].entries}") + ok2BetaAssertion(entries) + + catsrc.Delete(itName, dr) + + g.By("sqlite based image without deprecated bundle") + catsrc.Address = "quay.io/olmqe/nginx-ok-index:v1399-sql" + defer func() { + errRecover := exutil.RecoverNamespaceRestricted(oc, oc.Namespace()) + if errRecover != nil { + e2e.Logf("RecoverNamespaceRestricted error: %v", errRecover) + } + }() + errPriv := exutil.SetNamespacePrivileged(oc, oc.Namespace()) + o.Expect(errPriv).NotTo(o.HaveOccurred()) + catsrc.CreateWithCheck(oc, itName, dr) + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok1-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"alpha\")].entries}") + ok1AlphaAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok1-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"beta\")].entries}") + ok1BetaAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok2-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"alpha\")].entries}") + ok2AlphaNoDepAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok2-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"beta\")].entries}") + ok2BetaAssertion(entries) + + catsrc.Delete(itName, dr) + + g.By("sqlite based image with deprecated bundle made by deprecatetruncate") + catsrc.Address = "quay.io/olmqe/nginx-ok-index:v1399-sql-deprecate" + catsrc.CreateWithCheck(oc, itName, dr) + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok1-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"alpha\")].entries}") + ok1AlphaAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok1-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"beta\")].entries}") + ok1BetaAssertion(entries) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok2-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"alpha\")].entries}") + o.Expect(entries).To(o.ContainSubstring("nginx-ok2-1399.v0.0.4")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.2")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.1")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.5")) + o.Expect(entries).NotTo(o.ContainSubstring("nginx-ok2-1399.v0.0.3")) + o.Expect(entries).To(o.ContainSubstring("\"version\":\"0.0.4\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.2\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.1\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.5\"")) + o.Expect(entries).NotTo(o.ContainSubstring("\"version\":\"0.0.3\"")) + + entries = olmv0util.GetResourceNoEmpty(oc, exutil.AsAdmin, exutil.WithoutNamespace, "packagemanifest", "nginx-ok2-1399", "-n", catsrc.Namespace, "-o=jsonpath={.status.channels[?(@.name==\"beta\")].entries}") + ok2BetaAssertion(entries) + + }) + + g.It("PolarionID:62974-olm sets invalid scc label on its namespaces", g.Label("NonHyperShiftHOST"), func() { + labelKey := "openshift\\.io\\/scc" + + for _, ns := range []string{"openshift-operators", "openshift-operator-lifecycle-manager"} { + g.By("check label openshift.io/scc is empty on " + ns) + sccLabel, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("namespace", ns, "-o=jsonpath={.metadata.labels}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + o.Expect(sccLabel).NotTo(o.BeEmpty()) + e2e.Logf("the lables: %v", sccLabel) + gResult := gjson.Get(sccLabel, labelKey) + if gResult.Exists() && gResult.String() != "" { + o.Expect("the value of label openshift.io/scc").To(o.BeEmpty(), fmt.Sprintf("there is label openshift.io/scc on %v and is not empty on", ns)) + } + } + }) + + g.It("PolarionID:62973-[Skipped:Disconnected]dedicated way collect profiles cronjob pod missing target.workload.openshift.io management annotation[Disruptive][Slow]", g.Label("NonHyperShiftHOST"), func() { + if !exutil.IsSNOCluster(oc) { + g.Skip("it is not sno cluster, so skip it") + } + g.By("check if the current mcp is ready, or else skip") + olmv0util.AssertOrCheckMCP(oc, "master", 10, 1, true) + + g.By("check if it is aleady in workload partition") + wordLoadPartition, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("pods", "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.items[*].metadata.annotations}").Output() + o.Expect(err).NotTo(o.HaveOccurred()) + if strings.Contains(wordLoadPartition, "resources.workload.openshift.io/collect-profiles") { + e2e.Logf("it already works") + return + } + + var ( + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") + mcWordloadPartiation = filepath.Join(buildPruningBaseDir, "mc-workload-partition.yaml") + ) + + g.By("apply MchineConfig to set workload partition") + defer func() { + g.By("wait mcp recovered") + olmv0util.AssertOrCheckMCP(oc, "master", 240, 30, false) + }() + defer func() { + _ = oc.AsAdmin().WithoutNamespace().Run("delete").Args("-f", mcWordloadPartiation).Execute() + }() + err = oc.AsAdmin().WithoutNamespace().Run("apply").Args("-f", mcWordloadPartiation).Execute() + o.Expect(err).NotTo(o.HaveOccurred()) + + g.By("check mcp updated successfully") + olmv0util.AssertOrCheckMCP(oc, "master", 180, 30, false) + + g.By("check resources.workload.openshift.io/collect-profiles") + o.Eventually(func() string { + annotation, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("pods", "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.items[*].metadata.annotations}").Output() + return annotation + }, 20*time.Minute, 1*time.Minute).Should(o.ContainSubstring("resources.workload.openshift.io/collect-profiles")) + }) + + g.It("PolarionID:62973-general way collect profiles cronjob pod missing target.workload.openshift.io management annotation", g.Label("NonHyperShiftHOST"), func() { + g.By("https://issues.redhat.com/browse/OCPBUGS-1088 automated") + + g.By("check target.workload.openshift.io/management") + o.Eventually(func() string { + annotation, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("CronJob", "collect-profiles", "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.spec.jobTemplate.spec.template.metadata.annotations}").Output() + return annotation + }, 20*time.Second, 2*time.Second).Should(o.ContainSubstring("target.workload.openshift.io/management")) + }) + }) diff --git a/tests-extension/test/qe/testdata/olm/apiservice.yaml b/tests-extension/test/qe/testdata/olm/apiservice.yaml new file mode 100644 index 0000000000..497084ef2f --- /dev/null +++ b/tests-extension/test/qe/testdata/olm/apiservice.yaml @@ -0,0 +1,23 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: apiservice-template +objects: +- kind: APIService + apiVersion: apiregistration.k8s.io/v1 + metadata: + name: "${NAME}" + spec: + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJaekNDQVE2Z0F3SUJBZ0lJTjRRUFRuVnJWK2t3Q2dZSUtvWkl6ajBFQXdJd0dERVdNQlFHQTFVRUNoTU4KVW1Wa0lFaGhkQ3dnU1c1akxqQWVGdzB5TURBMk1qSXhOREE1TWpSYUZ3MHlNakEyTWpJeE5EQTVNalJhTUJneApGakFVQmdOVkJBb1REVkpsWkNCSVlYUXNJRWx1WXk0d1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DCkFBUmVkUlVESkhGb2gzTThYcEYxTzN1RXRCWU9ZeW1vMEdPTjN6WC91dHNpRlM3YnZ1Tmk2UEE0NC9teGZlT3oKUENrdDBRWitWUWp0MnE3UHhHdzZ4YkZwbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZdwpGQVlJS3dZQkJRVUhBd0lHQ0NzR0FRVUZCd01CTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3Q2dZSUtvWkl6ajBFCkF3SURSd0F3UkFJZ0NxY2tjdE1Tc1hYQi9PQ0hwQjlkSmZSRmZMYmJNOFQ1Q3J3dGlBNTlRYW9DSUdRSlh1TnkKUVlBUnczUmNLUXI1ZnNQM1JhMElRaUNORzNveUZXaVg1Y3RSCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + group: foos.bar.com + groupPriorityMinimum: 2000 + service: + name: foo + namespace: bar + port: 5443 + version: "${VERSION}" + versionPriority: 15 +parameters: +- name: NAME +- name: VERSION + diff --git a/tests-extension/test/qe/util/olmv0util/catalog_source.go b/tests-extension/test/qe/util/olmv0util/catalog_source.go index ae4fb9a5dc..38a9c9ff6f 100644 --- a/tests-extension/test/qe/util/olmv0util/catalog_source.go +++ b/tests-extension/test/qe/util/olmv0util/catalog_source.go @@ -54,10 +54,15 @@ func (catsrc *CatalogSourceDescription) Create(oc *exutil.CLI, itName string, dr applyFn = ApplyResourceFromTemplateOnMicroshift } // Apply the catalog source template with all configured parameters + // Quote empty values to prevent shell parsing errors + imageTemplate := catsrc.ImageTemplate + if imageTemplate == "" { + imageTemplate = `""` + } err := applyFn(oc, "--ignore-unknown-parameters=true", "-f", catsrc.Template, "-p", "NAME="+catsrc.Name, "NAMESPACE="+catsrc.Namespace, "ADDRESS="+catsrc.Address, "SECRET="+catsrc.Secret, "DISPLAYNAME="+"\""+catsrc.DisplayName+"\"", "PUBLISHER="+"\""+catsrc.Publisher+"\"", "SOURCETYPE="+catsrc.SourceType, - "INTERVAL="+catsrc.Interval, "IMAGETEMPLATE="+catsrc.ImageTemplate) + "INTERVAL="+catsrc.Interval, "IMAGETEMPLATE="+imageTemplate) o.Expect(err).NotTo(o.HaveOccurred()) // Configure security context constraints for non-microshift clusters if strings.Compare(catsrc.ClusterType, "microshift") != 0 {