Repository: red-hat-storage/ocs-ci
Pull request #11864: run_on_all_clients marker
Author: login: fbalak
Labels: name: Verified
description: Mark when PR was verified and log provided
name: size/M
description: PR that changes 30-99 lines
name: lgtm
name: provider-client
description: Provider-client solution
Created: 2025-04-07T12:15:16Z | Merged: 2025-04-28T08:58:37Z



Diff:
diff --git a/ocs_ci/framework/__init__.py b/ocs_ci/framework/__init__.py
index daf10cafa93..7a24c2a7a4f 100644
--- a/ocs_ci/framework/__init__.py
+++ b/ocs_ci/framework/__init__.py
@@ -540,7 +540,10 @@ def get_client_contexts_if_available(self):
         If there are no client contexts available then use simple nullcontext to not break
         functionality and still execute the code on current cluster.
         """
-        indexes = config.get_consumer_indexes_list()
+        try:
+            indexes = config.get_consumer_indexes_list()
+        except ClusterNotFoundException:
+            indexes = None
         if indexes:
             return [self.RunWithConfigContext(index) for index in indexes]
         else:
diff --git a/ocs_ci/framework/pytest_customization/marks.py b/ocs_ci/framework/pytest_customization/marks.py
index 2b6856e7cc4..17af688cece 100644
--- a/ocs_ci/framework/pytest_customization/marks.py
+++ b/ocs_ci/framework/pytest_customization/marks.py
@@ -8,6 +8,7 @@
 import pytest
 from funcy import compose
 
+from ocs_ci.ocs.exceptions import ClusterNotFoundException
 from ocs_ci.framework import config
 from ocs_ci.ocs.constants import (
     ORDER_BEFORE_OCS_UPGRADE,
@@ -392,6 +393,18 @@
     ),
     reason="Test runs ONLY on Fusion HCI provider and client clusters",
 )
+# when run_on_all_clients marker is used, there needs to be added cluster_index
+# parameter to the test to prevent any issues with the test parametrization
+run_on_all_clients = pytest.mark.run_on_all_clients
+try:
+    client_indexes = [
+        pytest.param(*[idx]) for idx in config.get_consumer_indexes_list()
+    ]
+    run_on_all_clients = pytest.mark.parametrize(
+        argnames=["cluster_index"], argvalues=client_indexes, indirect=True
+    )
+except ClusterNotFoundException:
+    pass
 kms_config_required = pytest.mark.skipif(
     (
         config.ENV_DATA["KMS_PROVIDER"].lower() != HPCS_KMS_PROVIDER
diff --git a/tests/conftest.py b/tests/conftest.py
index 5640073571e..e873261539e 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -563,13 +563,26 @@ def pytest_runtest_setup(item):
     if ocsci_config.multicluster and ocsci_config.UPGRADE.get("upgrade", False):
         for mark in item.iter_markers():
             if mark.name == "config_index":
-                log.info("Switching the test context to index: {mark.args[0]}")
+                log.info(f"Switching the test context to index: {mark.args[0]}")
                 ocsci_config.switch_ctx(mark.args[0])
+    if ocsci_config.multicluster:
+        for mark in item.iter_markers():
+            if mark.name == "parametrize":
+                if item.callspec.params.get("cluster_index"):
+                    context = item.callspec.params.get("cluster_index")
+                    log.info(f"Switching the test context to index: {context}")
+                    original_idx = ocsci_config.cur_index
+                    ocsci_config.switch_ctx(context)
+                    yield
+                    log.info(
+                        f"Switching the test context back to index: {original_idx}"
+                    )
+                    ocsci_config.switch_ctx(original_idx)
 
 
 def pytest_fixture_setup(fixturedef, request):
     """
-    In case of multicluster upgrade scenarios, we want to make sure that before running
+    In case of multicluster scenarios, we want to make sure that before running
     any fixture related to the testcase we need to switch the cluster context
 
     """
@@ -580,6 +593,25 @@ def pytest_fixture_setup(fixturedef, request):
             for mark in request.node.iter_markers():
                 if mark.name == "config_index":
                     ocsci_config.switch_ctx(mark.args[0])
+    if ocsci_config.multicluster:
+        for mark in request.node.iter_markers():
+            if mark.name == "parametrize":
+                if request.node.callspec.params.get("cluster_index"):
+                    context = request.node.callspec.params.get("cluster_index")
+                    log.info(f"Switching the fixture context to index: {context}")
+                    ocsci_config.switch_ctx(context)
+
+
+def pytest_fixture_post_finalizer(fixturedef, request):
+    """
+    In case of multicluster scenarios, we want to make sure that context is restored
+    after fixture is finished.
+    """
+    if ocsci_config.multicluster:
+        for mark in request.node.iter_markers():
+            if mark.name == "parametrize":
+                if request.node.callspec.params.get("cluster_index"):
+                    ocsci_config.reset_ctx()
 
 
 @pytest.fixture()
diff --git a/tests/functional/object/mcg/test_provider_client.py b/tests/functional/object/mcg/test_provider_client.py
index 53bbde4dcf3..16be2f45846 100644
--- a/tests/functional/object/mcg/test_provider_client.py
+++ b/tests/functional/object/mcg/test_provider_client.py
@@ -5,6 +5,7 @@
 from ocs_ci.framework.pytest_customization.marks import (
     tier1,
     red_squad,
+    run_on_all_clients,
     runs_on_provider,
     mcg,
     provider_client_ms_platform_required,
@@ -58,11 +59,15 @@ def test_verify_backingstore_uses_rgw(mcg_obj_session):
 @mcg
 @red_squad
 @tier1
-@runs_on_provider
 @provider_client_ms_platform_required
+@run_on_all_clients
 @pytest.mark.polarion_id("OCS-5214")
 def test_write_file_to_bucket_on_client(
-    bucket_factory, mcg_obj, awscli_pod_client_session, return_to_original_context
+    bucket_factory,
+    mcg_obj,
+    awscli_pod_client_session,
+    return_to_original_context,
+    cluster_index,
 ):
     """
     Test object IO using the S3 SDK on bucket created on provider and used on client.
@@ -70,11 +75,10 @@ def test_write_file_to_bucket_on_client(
     awscli_pod, client_cluster = awscli_pod_client_session
     # Retrieve a list of all objects on the test-objects bucket and
     # downloads them to the pod
-    bucketname = bucket_factory(1, interface="OC")[0].name
+    with config.RunWithProviderConfigContextIfAvailable():
+        bucketname = bucket_factory(1, interface="OC")[0].name
     full_object_path = f"s3://{bucketname}"
 
-    config.switch_ctx(client_cluster)
-    log.info(f"Switched to client cluster with index {client_cluster}")
     downloaded_files = awscli_pod.exec_cmd_on_pod(
         f"ls -A1 {constants.AWSCLI_TEST_OBJ_DIR}"
     ).split(" ")
diff --git a/tests/functional/pod_and_daemons/test_ephemeral_pod.py b/tests/functional/pod_and_daemons/test_ephemeral_pod.py
index 1dc4db5743e..5b007da5247 100644
--- a/tests/functional/pod_and_daemons/test_ephemeral_pod.py
+++ b/tests/functional/pod_and_daemons/test_ephemeral_pod.py
@@ -9,7 +9,12 @@
     RBD_INTERFACE,
 )
 from ocs_ci.framework import config
-from ocs_ci.framework.pytest_customization.marks import tier1, brown_squad, polarion_id
+from ocs_ci.framework.pytest_customization.marks import (
+    tier1,
+    brown_squad,
+    polarion_id,
+    run_on_all_clients,
+)
 
 log = getLogger(__name__)
 
@@ -21,7 +26,8 @@ class TestEphemeralPod:
     @pytest.mark.parametrize(
         argnames=["interface"], argvalues=[[CEPHFS_INTERFACE], [RBD_INTERFACE]]
     )
-    def test_ephemeral_pod_creation(self, interface) -> None:
+    @run_on_all_clients
+    def test_ephemeral_pod_creation(self, interface, cluster_index) -> None:
         pod_name = None
         storage_type = interface
         ephemeral_pod = EphemeralPodFactory.create_ephemeral_pod(pod_name, storage_type)


Reviews:
user: login: DanielOsypenko
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T08:21:43Z
user: login: suchita-g
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T15:32:02Z
user: login: DanielOsypenko
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T08:23:36Z
user: login: keesturam
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-28T08:32:56Z
user: login: keesturam
body: LGTM
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-28T08:35:10Z
user: login: shylesh
body: lgtm
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T08:57:20Z

Review comments:
diff_hunk: @@ -392,6 +393,18 @@
     ),
     reason="Test runs ONLY on Fusion HCI provider and client clusters",
 )
+# when run_on_all_clients marker is used, there needs to be added cluster_index
+# parameter to the test to prevent any issues with the test parametrization
+run_on_all_clients = pytest.mark.run_on_all_clients
+try:
+    client_indexes = [
+        pytest.param(*[idx]) for idx in config.get_consumer_indexes_list()
+    ]
+    run_on_all_clients = pytest.mark.parametrize(
+        argnames=["cluster_index"], argvalues=client_indexes, indirect=True
+    )
+except ClusterNotFoundException:
path: ocs_ci/framework/pytest_customization/marks.py
user: login: keesturam
body: just curious - on what conditions would we end up in this exception in a test flow?
created_at: 2025-04-28T08:32:56Z
author_association: MEMBER

PR comments:
user: login: fbalak
created_at: 2025-04-28T08:18:34Z
body: Verified: https://jenkins-csb-odf-qe-ocs4.dno.corp.redhat.com/view/all/job/qe-odf-provider-client-multicluster/236/
Switching of clusters works but tests that are currently marked with runs_on_all_clients are not fully adjusted. This will be handled in future pr.
author_association: CONTRIBUTOR
user: login: openshift-ci[bot]
created_at: 2025-04-28T08:57:25Z
body: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/red-hat-storage/ocs-ci/pull/11864#pullrequestreview-2798442483" title="Approved">DanielOsypenko</a>*, *<a href="https://github.com/red-hat-storage/ocs-ci/pull/11864#" title="Author self-approved">fbalak</a>*, *<a href="https://github.com/red-hat-storage/ocs-ci/pull/11864#pullrequestreview-2798492464" title="Approved">keesturam</a>*, *<a href="https://github.com/red-hat-storage/ocs-ci/pull/11864#pullrequestreview-2798566782" title="Approved">shylesh</a>*


The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=red-hat-storage%2Focs-ci).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/red-hat-storage/ocs-ci/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: NONE