Skip to content

Commit

Permalink
[RHELC-1715, RHELC-1134] conftest.py refactor - remove unnecessary co…
Browse files Browse the repository at this point in the history
…de (#1361)

* Remove unnecesary code from conftest.py

Ref: https://issues.redhat.com/browse/RHELC-1715
Improve the env_var fixture

* Refactor pre-registered fixture

* Remove kernel reinstall on centos-8 for the custom_kernel integration test
  • Loading branch information
kokesak authored Sep 11, 2024
1 parent f3f7db2 commit 6722626
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 212 deletions.
164 changes: 23 additions & 141 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

from collections import namedtuple
from contextlib import contextmanager
from fileinput import FileInput
from typing import ContextManager, Optional
from typing import ContextManager

import click
import pexpect
Expand Down Expand Up @@ -229,6 +228,12 @@ def fixture_subman():

yield

# The "pre_registered system" test requires to remain registered even after the conversion is completed,
# so the check "enabled repositories" after the conversion can be executed.
if "C2R_TESTS_SUBMAN_REMAIN_REGISTERED" not in os.environ:
subman.unregister()

# We do not need to spend time on performing the cleanup for some test cases (destructive)
if "C2R_TESTS_NONDESTRUCTIVE" in os.environ:
subman.clean_up()

Expand Down Expand Up @@ -376,97 +381,6 @@ def factory(
return factory


@dataclasses.dataclass
class OsRelease:
"""Dataclass representing the content of /etc/os-release."""

name: str
version: str
id: str
id_like: str
version_id: str
pretty_name: str
home_url: str
bug_report_url: str
ansi_color: Optional[str] = None
cpe_name: Optional[str] = None
platform_id: Optional[str] = None

@classmethod
def create_from_file(cls, file: Path):
assert file.exists(), f"File doesn't exist: {str(file)}"
res = {}
with open(file) as os_release_f:
for line in os_release_f:
try:
param, value = line.strip().split("=")
except ValueError:
# we're skipping lines which can't be split based on =
pass
else:
if param.lower() in cls.__annotations__:
res[param.lower()] = value.strip('"')
return cls(**res)


@pytest.fixture()
def os_release():
return OsRelease.create_from_file(Path("/etc/os-release"))


class ConfigUtils:
"""Convenient features to work with configs (or any other text files).
Created specifically to simplify writing integration tests, which requires
adjusting some configs.
"""

def __init__(self, config_path: Path):
self.config_path = config_path

@contextmanager
def replace_line(self, pattern: str, repl: str):
"""Iterates over config file lines and do re.sub for each line.
Parameters are the same as in re.sub
(https://docs.python.org/3/library/re.html#re.sub)
Example:
>>> with c2r_config.replace_line(pattern="releasever=.*", repl=f"releasever=9"):
>>> # do something here (the config is changed)
>>> pass
>>> # config is restored at this point
"""
logger.info(f"Scanning {str(self.config_path)} for {repr(pattern)} and replace with {repr(repl)}")
search = re.compile(pattern)
backup_suffix = ".bak"
try:
with FileInput(files=[str(self.config_path)], inplace=True, backup=backup_suffix) as f:
for line in f:
new_line = search.sub(repl, line)
if line != new_line:
logger.debug(f"{repr(line.strip())} replaced with\n{repr(new_line.strip())}")
# need to write to stdout to write the line to the file
print(new_line, end="")
yield
finally:
backup_config = self.config_path.with_suffix(self.config_path.suffix + backup_suffix)
backup_config.replace(self.config_path)
logger.debug("ConfigUtils file was restored to the origin state")


@pytest.fixture()
def c2r_config(os_release):
"""ConfigUtils object with already loaded convert2rhel config."""
release_id2conf = {"centos": "centos", "ol": "oracle", "almalinux": "almalinux", "rocky": "rocky"}
config_path = (
Path("/usr/share/convert2rhel/configs/")
/ f"{release_id2conf[os_release.id]}-{os_release.version[0]}-x86_64.cfg"
)
assert config_path.exists(), f"Can't find Convert2RHEL config file.\n{str(config_path)} - does not exist."
return ConfigUtils(config_path)


class SystemInformationRelease:
"""
Helper class.
Expand Down Expand Up @@ -503,25 +417,6 @@ class SystemInformationRelease:
system_release = "{}-{}.{}".format(distribution, version.major, version.minor)


@pytest.fixture()
def config_at():
"""Factory of the ConfigUtils object.
Created for simplicity injecting it into your testing unit (no need to import).
Example:
>>> with config_at(Path("/etc/system-release")).replace_line(
>>> "release .+",
>>> f"release {os_release.version[0]}.1.1111",
>>> ):
"""

def factory(path: Path) -> ConfigUtils:
return ConfigUtils(path)

return factory


@pytest.fixture()
def log_file_data():
"""
Expand Down Expand Up @@ -559,7 +454,7 @@ def remove_repositories(shell, backup_directory):


@pytest.fixture
def pre_registered(shell, request):
def pre_registered(shell, request, fixture_subman):
"""
A fixture to install subscription manager and pre-register the system prior to the convert2rhel run.
We're using the client-tools-for-rhel-<version>-rpms repository to install the subscription-manager package from.
Expand All @@ -568,8 +463,6 @@ def pre_registered(shell, request):
Can be parametrized by requesting a different KEY from the TEST_VARS file.
@pytest.mark.parametrize("pre_registered", [("DIFFERENT_USERNAME", "DIFFERENT_PASSWORD")], indirect=True)
"""
subman = SubscriptionManager()

username = TEST_VARS["RHSM_SCA_USERNAME"]
password = TEST_VARS["RHSM_SCA_PASSWORD"]
# Use custom keys when the fixture is parametrized
Expand All @@ -579,18 +472,16 @@ def pre_registered(shell, request):
password = TEST_VARS[password_key]
print(">>> Using parametrized username and password requested in the fixture.")

subman.set_up_requirements()

# Register the system
assert (
shell(
"subscription-manager register --serverurl {} --username {} --password {}".format(
"subscription-manager register --serverurl {0} --username {1} --password {2}".format(
TEST_VARS["RHSM_SERVER_URL"], username, password
),
hide_command=True,
).returncode
== 0
)
), f"Failed to pre-register the system. The subscription manager call has failed."

rhsm_uuid_command = "subscription-manager identity | grep identity"

Expand All @@ -612,15 +503,6 @@ def pre_registered(shell, request):
# Validate it matches with UUID prior to the conversion
assert original_registration_uuid == post_c2r_registration_uuid

# The "pre_registered system" test requires to remain registered even after the conversion is completed,
# so the check "enabled repositories" after the conversion can be executed.
if "C2R_TESTS_SUBMAN_REMAIN_REGISTERED" not in os.environ:
subman.unregister()

# We do not need to spend time on performing the cleanup for some test cases (destructive)
if "C2R_TESTS_NONDESTRUCTIVE" in os.environ:
subman.clean_up()


@pytest.fixture()
def hybrid_rocky_image(shell):
Expand All @@ -644,25 +526,25 @@ def hybrid_rocky_image(shell):
def environment_variables(request):
"""
Fixture.
Sets and unsets required environment variables.
Environment variable(s) needs to be passed as a list(s) to pytest parametrize.
Set and unset required environment variables.
Usage:
@pytest.mark.parametrize("envars", [["LIST", "OF"], ["ENVIRONMENT", "VARIABLES"]])
@pytest.mark.parametrize("environment_variables", ["CONVERT2RHEL_UNSUPPORTED"], indirect=True)
@pytest.mark.parametrize("environment_variables", [["FIRST", "TEST", "EXECUTION"], ["SECOND", "TEST", "EXECUTION"]], indirect=True)
"""

def _set_env_var(envars):
for envar in envars:
os.environ[envar] = "1"
if hasattr(request, "param"):
env_vars = request.param
if not isinstance(env_vars, list):
env_vars = [env_vars]

yield _set_env_var
for e in env_vars:
os.environ[e] = "1"

def _unset_env_var(envars):
for envar in envars:
if envar in os.environ:
del os.environ[envar]
assert envar not in os.environ
yield

return _unset_env_var
for e in env_vars:
os.environ.pop(e, None)
assert e not in os.environ, f"The removal of the environment variable - '{e}' failed"


@pytest.fixture(scope="function")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ order: 49
description: |
Verify that Convert2RHEL is working properly when ELS repositories are used during the conversion.
Verify that the correct repositories are enabled after the conversion (in one of the check-after-conversion tests).
environment+:
C2R_TESTS_SUBMAN_REMAIN_REGISTERED: 1
tag+:
- rhsm-els-conversion
test: pytest -m test_rhsm_with_els_system_conversion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,15 @@ def test_inhibitor_with_unavailable_kmod_loaded(kmod_in_different_directory, con
assert c2r.exitstatus == 2


@pytest.mark.parametrize("envars", [["CONVERT2RHEL_ALLOW_UNAVAILABLE_KMODS"]])
@pytest.mark.parametrize("environment_variables", ["CONVERT2RHEL_ALLOW_UNAVAILABLE_KMODS"], indirect=True)
def test_override_inhibitor_with_unavailable_kmod_loaded(
kmod_in_different_directory, convert2rhel, environment_variables, envars
kmod_in_different_directory, convert2rhel, environment_variables
):
"""
This test verifies that setting the environment variable "CONVERT2RHEL_ALLOW_UNAVAILABLE_KMODS"
will override the check error when there is an kernel module unavailable in RHEL detected.
The environment variable is set through the test metadata.
"""
environment_variables(envars)
with convert2rhel(
"--serverurl {} --username {} --password {} --debug".format(
TEST_VARS["RHSM_SERVER_URL"],
Expand Down Expand Up @@ -108,16 +107,15 @@ def test_inhibitor_with_force_loaded_tainted_kmod(shell, convert2rhel, forced_km
assert c2r.exitstatus == 1


@pytest.mark.parametrize("envars", [["CONVERT2RHEL_TAINTED_KERNEL_MODULE_CHECK_SKIP"]])
def test_override_inhibitor_with_tainted_kmod(shell, convert2rhel, forced_kmods, environment_variables, envars):
@pytest.mark.parametrize("environment_variables", ["CONVERT2RHEL_TAINTED_KERNEL_MODULE_CHECK_SKIP"], indirect=True)
def test_override_inhibitor_with_tainted_kmod(shell, convert2rhel, forced_kmods, environment_variables):
"""
In this test case we force load kmod and verify that the TAINTED_KMODS.TAINTED_KMODS_DETECTED
is overridable by setting the environment variable 'CONVERT2RHEL_TAINTED_KERNEL_MODULE_CHECK_SKIP'
to '1'
Force loaded kmods are denoted (FE) where F = module was force loaded E = unsigned module was loaded.
Convert2RHEL sees force loaded kmod as tainted.
"""
environment_variables(envars)
with convert2rhel(
"--serverurl {} --username {} --password {} --debug".format(
TEST_VARS["RHSM_SERVER_URL"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ def custom_kernel(shell, hybrid_rocky_image, backup_directory):
custom_kernel_installed = None
# Create a temporary file to store the original kernel NVRA
kernel_info_storage = os.path.join(backup_directory, "original-kernel")
# Store the current running kernel NVRA in a file
shell("echo $(uname -r) >> %s" % kernel_info_storage)
if os.environ["TMT_REBOOT_COUNT"] == "0":
# Store the current running kernel NVRA in a file
shell("echo $(uname -r) > %s" % kernel_info_storage)

# The version of yum on el7 like systems does not allow the --repofrompath option.
# Therefore, we need to install the rpm directly
if SystemInformationRelease.version.major == 7:
Expand Down Expand Up @@ -101,9 +102,6 @@ def custom_kernel(shell, hybrid_rocky_image, backup_directory):
with open(kernel_info_storage, "r") as f:
original_kernel = f.readline().rstrip()
original_kernel_title = get_full_kernel_title(shell, kernel=original_kernel)
# Install back the CentOS 8.5 original kernel
if "centos-8-latest" in SYSTEM_RELEASE_ENV:
assert shell(f"yum reinstall -y kernel").returncode == 0

workaround_grub_setup(shell)
assert shell(f"grub2-set-default '{original_kernel_title}'").returncode == 0
Expand Down
Loading

0 comments on commit 6722626

Please sign in to comment.