Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from _pytest.runner import CallInfo
from kubernetes.dynamic.exceptions import ConflictError
from ocp_resources.network_config_openshift_io import Network
from packaging.version import Version

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Execution Plan

Run smoke tests: False
No smoke-marked test file is in the affected set. Modified EUS/upgrade symbols are isolated to upgrade-lane fixtures and utilities.

Run gating tests: True

Dependency paths:

  • tests/virt/upgrade/test_upgrade_virt.py (gating)unupdated_vmi_pods_names fixture (tests/virt/upgrade/conftest.py:179) → wait_for_automatic_vm_migrations(vm_list=…) in tests/virt/upgrade/utils.py (signature changed: admin_client param removed)
  • tests/virt/upgrade/test_upgrade_virt.py (gating)csv_after_upgrade fixture (tests/virt/upgrade/conftest.py:381) → eus_hco_target_csv_name dependency removed; now relies solely on hco_target_csv_name

Affected tests to run

Path Marker Reason
tests/install_upgrade_operators/product_upgrade/test_eus_upgrade.py eus_upgrade Core EUS test; eus_cnv_upgrade_path fixture fully reworked, eus_created_target_hco_csv replaced with created_target_hco_csv
tests/install_upgrade_operators/product_upgrade/test_upgrade_iuo.py eus_upgrade Uses reworked EUS conftest fixtures
tests/virt/upgrade/test_upgrade_virt.py gating csv_after_upgrade + unupdated_vmi_pods_names fixture signatures changed
tests/install_upgrade_operators/product_upgrade/test_upgrade.py gating wait_for_mcp_update_completion now accepts timeout; EUS conftest in same session scope

Real tests (cluster required)

Root conftest.py pytest_cmdline_main now enforces even-minor-version validation and mandatory --cnv-version/--cnv-image for EUS at session startup.

Error path (odd minor version guard):

pytest tests/install_upgrade_operators/product_upgrade/test_eus_upgrade.py \
  --upgrade=eus --cnv-version=4.21.0 --cnv-image=NA --eus-ocp-images=NA,NA --collect-only

Expected: ValueError: EUS target version 4.21.0 must have an even minor version

Happy path (even minor — regression):

pytest tests/install_upgrade_operators/product_upgrade/test_eus_upgrade.py \
  --upgrade=eus --cnv-version=4.22.0 --cnv-image=NA --eus-ocp-images=NA,NA --collect-only

Expected: collection completes without error

Virt upgrade fixture regression (admin_client removal):

pytest tests/virt/upgrade/test_upgrade_virt.py -m eus_upgrade \
  --upgrade=eus --cnv-version=<target> --cnv-image=<image> --eus-ocp-images=<img1>,<img2> --collect-only

Expected: fixtures resolve without unexpected admin_client argument errors

from pyhelper_utils.shell import run_command
from pytest import Item
from pytest_testconfig import config as py_config
Expand Down Expand Up @@ -161,7 +162,6 @@ def pytest_addoption(parser):
"--eus-ocp-images",
help="Comma-separated OCP images to use for EUS-to-EUS upgrade.",
)
install_upgrade_group.addoption("--eus-cnv-target-version", help="target CNV version for eus upgrade")
install_upgrade_group.addoption(
"--upgrade-skip-default-sc-setup",
help="Skip the fixture that changes the default sc in upgrade lane",
Expand Down Expand Up @@ -377,18 +377,21 @@ def pytest_cmdline_main(config):
if upgrade_option == "ocp" and not config.getoption("ocp_image"):
raise ValueError("Running with --upgrade ocp: Missing --ocp-image")

if upgrade_option == "cnv":
if upgrade_option in ("cnv", "eus"):
if not config.getoption("cnv_version"):
raise ValueError("Missing --cnv-version")
if not config.getoption("cnv_image"):
if config.getoption("cnv_source") != "production":
if upgrade_option == "eus" or config.getoption("cnv_source") != "production":
raise ValueError("Missing --cnv-image")

if upgrade_option == "eus":
if upgrade_option == "eus" and not config.option.collectonly:
cnv_version = config.getoption("cnv_version")
if Version(version=cnv_version).minor % 2:
raise ValueError(f"EUS target version {cnv_version} must have an even minor version")
eus_ocp_images = config.getoption("eus_ocp_images")
if not (eus_ocp_images and len(eus_ocp_images.split(",")) == 2):
raise ValueError(
f"Two OCP images are needed to perform EUS-to-EUS upgrade with --eus-ocp-images."
f"Two OCP images are needed for EUS-to-EUS upgrade with --eus-ocp-images."
f" Provided images: {eus_ocp_images}"
)

Expand Down Expand Up @@ -905,7 +908,7 @@ def is_skip_must_gather(node: Node) -> bool:

def get_inspect_command_namespace_string(node: Node, test_name: str) -> str:
namespace_str = ""
components = [key for key in NAMESPACE_COLLECTION.keys() if f"tests/{key}/" in test_name]
components = [key for key in NAMESPACE_COLLECTION if f"tests/{key}/" in test_name]
if not components:
LOGGER.warning(f"{test_name} does not require special data collection on failure")
else:
Expand Down
21 changes: 18 additions & 3 deletions docs/INSTALL_AND_UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,27 @@ To upgrade to cnv 4.Y.z, using the cnv image that has been shipped, following co
```

#### EUS upgrade
You must provide --eus-ocp-images via cli, which is two comma separated ocp images for EUS upgrade.
The default target cnv version will be 4.Y+2.0. Optionally, --eus-csv-target-version can be provided for 4.Y+2.z version.
EUS-to-EUS upgrades are only viable between even-numbered minor versions (e.g., 4.20 -> 4.22).

Parameters:

| Parameter Name | Requirement | Default Value | Possible Value |
|:------------------|:---------------:|:-------------:|:----------------------------:|
| `--cnv-version` | **Required** | - | 4.Y.z |
| `--cnv-image` | **Required** | - | -image path- |
| `--cnv-channel` | **Optional** | stable | stable, candidate, nightly |
| `--eus-ocp-images` | **Required** | - | comma-separated OCP images |

Command to run entire upgrade test suite for EUS upgrade, including pre and post upgrade validation:

```bash
--upgrade eus --eus-ocp-images <ocp_image_version_4.y+1.z>,<ocp_image_version_4.y+2.z> --eus-cnv-target-version <4.Y+2.z|None>
--upgrade eus --cnv-version <target_version> --cnv-image <cnv_image_to_upgrade_to> --eus-ocp-images <ocp_image_4.y+1.z>,<ocp_image_4.y+2.z>
```

Command to run only EUS upgrade test, without any pre/post validation:

```bash
-m eus_upgrade --upgrade eus --cnv-version <target_version> --cnv-image <cnv_image_to_upgrade_to> --eus-ocp-images <ocp_image_4.y+1.z>,<ocp_image_4.y+2.z>
```
#### Custom upgrade lanes

Expand Down
20 changes: 3 additions & 17 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
from ocp_resources.virtual_machine_instancetype import VirtualMachineInstancetype
from ocp_resources.virtual_machine_preference import VirtualMachinePreference
from ocp_utilities.monitoring import Prometheus
from packaging.version import Version, parse
from packaging.version import parse
from pytest_testconfig import config as py_config
from timeout_sampler import TimeoutSampler

Expand Down Expand Up @@ -1751,28 +1751,14 @@ def hco_target_csv_name(cnv_target_version):
return get_hco_csv_name_by_version(cnv_target_version=cnv_target_version) if cnv_target_version else None


@pytest.fixture(scope="session")
def eus_hco_target_csv_name(eus_target_cnv_version):
if eus_target_cnv_version is None:
LOGGER.warning("Cannot determine EUS HCO target CSV name: EUS target version is None (non-EUS version)")
return None
return get_hco_csv_name_by_version(cnv_target_version=eus_target_cnv_version)


@pytest.fixture(scope="session")
def cnv_target_version(pytestconfig):
return pytestconfig.option.cnv_version


@pytest.fixture(scope="session")
def eus_target_cnv_version(pytestconfig, cnv_current_version):
cnv_current_version = Version(version=cnv_current_version)
minor = cnv_current_version.minor
# EUS-to-EUS upgrades are only viable between even-numbered minor versions, return None if non-eus version
if minor % 2:
LOGGER.warning(f"EUS upgrade can not be performed from non-eus version: {cnv_current_version}")
return None
return pytestconfig.option.eus_cnv_target_version or f"{cnv_current_version.major}.{minor + 2}.0"
def cnv_channel(pytestconfig):
return pytestconfig.option.cnv_channel


@pytest.fixture()
Expand Down
97 changes: 52 additions & 45 deletions tests/install_upgrade_operators/product_upgrade/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
)
from tests.install_upgrade_operators.product_upgrade.utils import (
approve_cnv_upgrade_install_plan,
build_eus_upgrade_path_dict,
extract_ocp_version_from_ocp_image,
get_alerts_fired_during_upgrade,
get_all_firing_cnv_alerts,
get_iib_images_of_cnv_versions,
get_nodes_labels,
get_nodes_taints,
get_shortest_upgrade_path,
perform_cnv_upgrade,
run_ocp_upgrade_command,
set_workload_update_methods_hco,
Expand All @@ -42,14 +41,14 @@
from utilities.constants import (
HCO_CATALOG_SOURCE,
TIMEOUT_10MIN,
TIMEOUT_180MIN,
NamespacesNames,
)
from utilities.data_collector import (
get_data_collector_base_directory,
)
from utilities.infra import (
generate_openshift_pull_secret_file,
get_csv_by_name,
get_prometheus_k8s_token,
get_related_images_name_and_version,
get_subscription,
Expand Down Expand Up @@ -324,27 +323,26 @@ def fired_alerts_during_upgrade(


@pytest.fixture(scope="session")
def eus_cnv_upgrade_path(admin_client, eus_target_cnv_version):
if eus_target_cnv_version is None:
def eus_cnv_upgrade_path(
admin_client,
cnv_target_version,
cnv_current_version,
cnv_channel,
cnv_image_url,
):
if Version(version=cnv_current_version).minor % 2:
exit_pytest_execution(
log_message="EUS upgrade can not be performed from non-eus version",
admin_client=admin_client,
log_message=f"EUS upgrade can not be performed from non-eus version: {cnv_current_version}",
return_code=EUS_ERROR_CODE,
filename="eus_upgrade_failure.txt",
admin_client=admin_client,
)
# Get the shortest path to the target (EUS) version
upgrade_path_to_target_version = get_shortest_upgrade_path(target_version=eus_target_cnv_version)
# Get the shortest path to the intermediate (non-EUS) version
upgrade_path_to_intermediate_version = get_shortest_upgrade_path(
target_version=upgrade_path_to_target_version["startVersion"]
return build_eus_upgrade_path_dict(
current_cnv_version=cnv_current_version,
target_cnv_version=cnv_target_version,
target_channel=cnv_channel,
target_cnv_image_url=cnv_image_url,
)
# Return a dictionary with the versions and images for the EUS-to-EUS upgrade
upgrade_path = {
"non-eus": get_iib_images_of_cnv_versions(versions=upgrade_path_to_intermediate_version["versions"]),
EUS: get_iib_images_of_cnv_versions(versions=upgrade_path_to_target_version["versions"], errata_status="false"),
}
LOGGER.info(f"Upgrade path for EUS-to-EUS upgrade: {upgrade_path}")
return upgrade_path


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -376,6 +374,7 @@ def eus_unpaused_worker_mcp(
machine_config_pools_list=worker_machine_config_pools,
initial_mcp_conditions=worker_machine_config_pools_conditions,
nodes=workers,
timeout=TIMEOUT_180MIN,
)


Expand Down Expand Up @@ -493,7 +492,7 @@ def triggered_non_eus_to_target_eus_ocp_upgrade(eus_ocp_image_urls):
@pytest.fixture()
def source_eus_to_non_eus_ocp_upgraded(
admin_client,
masters,
control_plane_nodes,
master_machine_config_pools,
ocp_version_eus_to_non_eus_from_image_url,
triggered_source_eus_to_non_eus_ocp_upgrade,
Expand All @@ -503,14 +502,14 @@ def source_eus_to_non_eus_ocp_upgraded(
machine_config_pools_list=master_machine_config_pools,
target_ocp_version=ocp_version_eus_to_non_eus_from_image_url,
initial_mcp_conditions=get_machine_config_pools_conditions(machine_config_pools=master_machine_config_pools),
nodes=masters,
nodes=control_plane_nodes,
)


@pytest.fixture()
def non_eus_to_target_eus_ocp_upgraded(
admin_client,
masters,
control_plane_nodes,
master_machine_config_pools,
ocp_version_non_eus_to_eus_from_image_url,
triggered_non_eus_to_target_eus_ocp_upgrade,
Expand All @@ -520,7 +519,7 @@ def non_eus_to_target_eus_ocp_upgraded(
machine_config_pools_list=master_machine_config_pools,
target_ocp_version=ocp_version_non_eus_to_eus_from_image_url,
initial_mcp_conditions=get_machine_config_pools_conditions(machine_config_pools=master_machine_config_pools),
nodes=masters,
nodes=control_plane_nodes,
)


Expand All @@ -529,17 +528,25 @@ def source_eus_to_non_eus_cnv_upgraded(
admin_client,
hco_namespace,
eus_cnv_upgrade_path,
cnv_subscription_scope_session,
cnv_registry_source,
hyperconverged_resource_scope_function,
updated_cnv_subscription_source,
):
for version, cnv_image in sorted(eus_cnv_upgrade_path["non-eus"].items()):
for version, build_info in sorted(
eus_cnv_upgrade_path["non-eus"].items(),
key=lambda item: Version(version=item[0]),
):
cnv_image = build_info["cnv_image_url"]
LOGGER.info(f"Cnv upgrade to version {version} using image: {cnv_image}")
perform_cnv_upgrade(
admin_client=admin_client,
cnv_image_url=cnv_image,
cr_name=hyperconverged_resource_scope_function.name,
hco_namespace=hco_namespace,
cnv_target_version=version.lstrip("v"),
cnv_target_version=version,
subscription=cnv_subscription_scope_session,
subscription_source=cnv_registry_source["cnv_subscription_source"],
subscription_channel=build_info["channel"],
)
LOGGER.info("Successfully performed cnv upgrades from source EUS to non-EUS version.")

Expand All @@ -549,27 +556,27 @@ def non_eus_to_target_eus_cnv_upgraded(
admin_client,
hco_namespace,
eus_cnv_upgrade_path,
cnv_subscription_scope_session,
cnv_registry_source,
hyperconverged_resource_scope_function,
updated_cnv_subscription_source,
):
version, cnv_image = next(iter(eus_cnv_upgrade_path[EUS].items()))
LOGGER.info(f"Cnv upgrade to version {version} using image: {cnv_image}")
perform_cnv_upgrade(
admin_client=admin_client,
cnv_image_url=cnv_image,
cr_name=hyperconverged_resource_scope_function.name,
hco_namespace=hco_namespace,
cnv_target_version=version.lstrip("v"),
)


@pytest.fixture()
def eus_created_target_hco_csv(admin_client, hco_namespace, eus_hco_target_csv_name):
return get_csv_by_name(
csv_name=eus_hco_target_csv_name,
admin_client=admin_client,
namespace=hco_namespace.name,
)
for version, build_info in sorted(
eus_cnv_upgrade_path[EUS].items(),
key=lambda item: Version(version=item[0]),
):
cnv_image = build_info["cnv_image_url"]
LOGGER.info(f"Cnv upgrade to version {version} using image: {cnv_image}")
perform_cnv_upgrade(
admin_client=admin_client,
cnv_image_url=cnv_image,
cr_name=hyperconverged_resource_scope_function.name,
hco_namespace=hco_namespace,
cnv_target_version=version,
subscription=cnv_subscription_scope_session,
subscription_source=cnv_registry_source["cnv_subscription_source"],
subscription_channel=build_info["channel"],
)
LOGGER.info("Successfully performed cnv upgrades from non-EUS to target EUS version.")


@pytest.fixture()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

LOGGER = logging.getLogger(__name__)

pytestmark = pytest.mark.usefixtures(
"nodes_taints_before_upgrade",
"nodes_labels_before_upgrade",
)


@pytest.mark.product_upgrade_test
@pytest.mark.upgrade
Expand All @@ -20,7 +25,6 @@ def test_eus_upgrade_process(
self,
admin_client,
hco_namespace,
eus_target_cnv_version,
eus_cnv_upgrade_path,
eus_paused_worker_mcp,
eus_paused_workload_update,
Expand All @@ -29,14 +33,14 @@ def test_eus_upgrade_process(
upgraded_odf,
non_eus_to_target_eus_ocp_upgraded,
non_eus_to_target_eus_cnv_upgraded,
eus_created_target_hco_csv,
created_target_hco_csv,
eus_unpaused_workload_update,
eus_unpaused_worker_mcp,
):
LOGGER.info("Validate EUS to EUS upgrade process")
verify_upgrade_cnv(
client=admin_client,
hco_namespace=hco_namespace,
expected_images=get_related_images_name_and_version(csv=eus_created_target_hco_csv).values(),
expected_images=get_related_images_name_and_version(csv=created_target_hco_csv).values(),
)
LOGGER.info("EUS post upgrade validation completed.")
Loading