Skip to content

Commit 320d48b

Browse files
committed
[4.19] Change method of testing latest rhel versions used in data source
##### Short description: Change method of testing latest rhel versions used in data source ##### More details: Manual cherry pick for #2737 - Added the `subtests` dependency needed on older version of python packages ##### What this PR does / why we need it: Remove use of osdb-info on tests Signed-off-by: rkishner <rkishner@redhat.com>
1 parent 98c0540 commit 320d48b

4 files changed

Lines changed: 124 additions & 93 deletions

File tree

tests/infrastructure/golden_images/update_boot_source/conftest.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from tests.infrastructure.golden_images.update_boot_source.utils import (
1414
generate_data_import_cron_dict,
15+
get_all_release_versions_from_docs,
1516
)
1617
from utilities.constants import TIMEOUT_2MIN
1718
from utilities.hco import (
@@ -125,3 +126,25 @@ def custom_data_source_scope_function(admin_client, custom_data_import_cron_scop
125126
f"{custom_data_import_cron_scope_function.namespace} namespace."
126127
)
127128
raise
129+
130+
131+
@pytest.fixture(scope="module")
132+
def latest_rhel_release_versions_dict():
133+
"""
134+
Parse RHEL documentation pages to find the latest released versions.
135+
136+
Returns:
137+
Dictionary mapping major versions to their latest minor versions
138+
e.g., {rhel8: "8.10", rhel9: "9.7", rhel10: "10.1"}
139+
"""
140+
latest_versions = {}
141+
not_found_versions = []
142+
143+
for major_ver_num in [8, 9, 10]:
144+
all_versions = get_all_release_versions_from_docs(major_ver_num=major_ver_num)
145+
if not all_versions:
146+
not_found_versions.append(major_ver_num)
147+
latest_versions[major_ver_num] = max(all_versions)
148+
149+
assert not not_found_versions, f"Failed to find RHEL {major_ver_num} versions from documentation"
150+
return {f"rhel{major}": f"{major}.{minor}" for major, minor in latest_versions.items()}

tests/infrastructure/golden_images/update_boot_source/test_latest_rhel_image.py

Lines changed: 0 additions & 92 deletions
This file was deleted.

tests/infrastructure/golden_images/update_boot_source/test_ssp_data_import_crons.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
CUSTOM_DATA_SOURCE_NAME,
1717
DEFAULT_FEDORA_REGISTRY_URL,
1818
)
19+
from tests.infrastructure.golden_images.update_boot_source.utils import get_image_version
1920
from utilities.constants import (
2021
BIND_IMMEDIATE_ANNOTATION,
2122
TIMEOUT_1MIN,
@@ -500,3 +501,33 @@ def test_data_source_instancetype_preference_label(
500501
assert not failed_data_source_list, (
501502
f"Could not create VMs with the following data sources: {failed_data_source_list}"
502503
)
504+
505+
506+
@pytest.mark.parametrize(
507+
"rhel_version",
508+
[
509+
pytest.param("rhel8", id="rhel8"),
510+
pytest.param("rhel9", id="rhel9"),
511+
pytest.param("rhel10", id="rhel10"),
512+
],
513+
)
514+
@pytest.mark.polarion("CNV-12414")
515+
def test_updated_rhel_image(
516+
admin_client,
517+
golden_images_namespace,
518+
latest_rhel_release_versions_dict,
519+
rhel_version,
520+
):
521+
rhel_dic = DataImportCron(
522+
client=admin_client,
523+
name=f"{rhel_version}-image-cron",
524+
namespace=golden_images_namespace.name,
525+
ensure_exists=True,
526+
)
527+
rhel_instance_dict = rhel_dic.instance
528+
image_reference_version = get_image_version(
529+
image=rhel_instance_dict.metadata.annotations.get("cdi.kubevirt.io/storage.import.imageStreamDockerRef")
530+
)
531+
managed_data_source = rhel_instance_dict.spec.managedDataSource
532+
assert managed_data_source, "spec.managedDataSource doesn't exists"
533+
assert latest_rhel_release_versions_dict[managed_data_source] == image_reference_version

tests/infrastructure/golden_images/update_boot_source/utils.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import logging
2+
import re
23

4+
import requests
5+
from bs4 import BeautifulSoup
36
from ocp_resources.template import Template
7+
from packaging.version import Version
48

59
from tests.infrastructure.golden_images.constants import (
610
DEFAULT_FEDORA_REGISTRY_URL,
711
)
8-
from utilities.constants import WILDCARD_CRON_EXPRESSION
12+
from utilities.constants import TIMEOUT_30SEC, WILDCARD_CRON_EXPRESSION
13+
from utilities.infra import generate_openshift_pull_secret_file
14+
from utilities.virt import get_oc_image_info
915

1016
LOGGER = logging.getLogger(__name__)
1117

@@ -45,3 +51,66 @@ def template_labels(os):
4551
workload=Template.Workload.SERVER,
4652
flavor=Template.Flavor.SMALL,
4753
)
54+
55+
56+
def get_all_release_versions_from_docs(major_ver_num: int) -> list[int]:
57+
"""
58+
Parse the documentation index page to get all release notes versions.
59+
60+
Fetches the Red Hat Enterprise Linux documentation index page for the specified
61+
major version and extracts all available minor release version numbers from
62+
the release notes links.
63+
64+
Args:
65+
major_ver_num: Major version number (e.g., 8, 9, 10).
66+
67+
Returns:
68+
Sorted list of minor version numbers (e.g., [0, 1, 2, 3, 4, 5, 6, 7]).
69+
70+
Raises:
71+
requests.RequestException: If the HTTP request to the documentation page fails.
72+
"""
73+
url = f"https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/{major_ver_num}/"
74+
response = requests.get(url=url, timeout=TIMEOUT_30SEC)
75+
response.raise_for_status()
76+
77+
soup = BeautifulSoup(response.text, "html.parser")
78+
versions = []
79+
pattern = re.compile(
80+
rf"/en/documentation/red_hat_enterprise_linux/{major_ver_num}/html/{major_ver_num}\.(\d+)_release_notes"
81+
)
82+
83+
for link in soup.find_all("a", href=True):
84+
match = pattern.search(string=link.get("href", ""))
85+
if match:
86+
versions.append(int(match.group(1)))
87+
versions = sorted(set(versions))
88+
return versions
89+
90+
91+
def get_image_version(image: str) -> str | None:
92+
"""
93+
Extract the major.minor version from an image's version label.
94+
95+
Retrieves image information and extracts the version label, returning
96+
only the major and minor version components (e.g., "8.9" from "8.9.0").
97+
98+
Args:
99+
image: Image reference string.
100+
101+
Returns:
102+
Version string in "major.minor" format (e.g., "8.9"), or None if:
103+
- The image information cannot be retrieved
104+
- The version label is not present in the image metadata
105+
"""
106+
image_info = get_oc_image_info(
107+
image=image,
108+
pull_secret=generate_openshift_pull_secret_file(),
109+
)
110+
full_version = image_info.get("config", {}).get("config", {}).get("Labels", {}).get("version")
111+
try:
112+
version = Version(version=full_version)
113+
return f"{version.major}.{version.minor}"
114+
except (ValueError, AttributeError, TypeError):
115+
LOGGER.warning(f"No RHEL version was found from: {image}")
116+
return None

0 commit comments

Comments
 (0)