diff --git a/convert2rhel/actions/system_checks/convert2rhel_latest.py b/convert2rhel/actions/system_checks/convert2rhel_latest.py index a6a2478e6b..23bc929a0f 100644 --- a/convert2rhel/actions/system_checks/convert2rhel_latest.py +++ b/convert2rhel/actions/system_checks/convert2rhel_latest.py @@ -22,7 +22,8 @@ import rpm -from convert2rhel import __version__ as installed_convert2rhel_version +from convert2rhel import __file__ as convert2rhel_file +from convert2rhel import __version__ as running_convert2rhel_version from convert2rhel import actions, utils from convert2rhel.pkghandler import parse_pkg_string from convert2rhel.systeminfo import system_info @@ -108,26 +109,7 @@ def run(self): ) return - # convert the raw output of convert2rhel version strings into a list - raw_output_convert2rhel_versions = raw_output_convert2rhel_versions.splitlines() - - temp_raw_output = [] - - # We are expecting an repoquery output to be similar to this: - # C2R convert2rhel-0:0.17-1.el7.noarch - # We need the `C2R` identifier to be present on the line so we can know for - # sure that the line we are working with is the a line that contains - # relevant repoquery information to our check, otherwise, we just log the - # information as debug and do nothing with it. - for raw_version in raw_output_convert2rhel_versions: - if "C2R" in raw_version: - temp_raw_output.append(raw_version.lstrip("C2R ")) - else: - # Mainly for debugging purposes to see what is happening if we got - # anything else that does not have the C2R identifier at the start - # of the line. - logger.debug("Got a line without the C2R identifier: %s" % raw_version) - raw_output_convert2rhel_versions = temp_raw_output + raw_output_convert2rhel_versions = _extract_convert2rhel_versions(raw_output_convert2rhel_versions) latest_available_version = ("0", "0.00", "0") convert2rhel_versions = [] @@ -161,14 +143,67 @@ def run(self): latest_available_version = (package_version[1], package_version[2], package_version[3]) logger.debug("Found %s to be latest available version" % (latest_available_version[1])) - # After the for loop, the latest_available_version variable will gain the epoch, version, and release - # (e.g. ("0" "0.26" "1.el7")) information from the convert2rhel yum repo - # when the versions are the same the latest_available_version's release field will cause it to evaluate as a later version. - # Therefore we need to hardcode "0" for both the epoch and release below for installed_convert2rhel_version - # and latest_available_version respectively, to compare **just** the version field. - ver_compare = rpm.labelCompare( - ("0", installed_convert2rhel_version, "0"), ("0", latest_available_version[1], "0") + precise_available_version = ("0", latest_available_version[1], "0") + precise_convert2rhel_version = ("0", running_convert2rhel_version, "0") + # Get source files that we're running with import convert2rhel ; convert2rhel.__file__ + running_convert2rhel_init_file = convert2rhel_file + + # Run `rpm -qf ` to get the installed convert2rhel package NEVRA + running_convert2rhel_NEVRA, return_code = utils.run_subprocess( + ( + "rpm", + "-qf", + running_convert2rhel_init_file, + "--qf", + "C2R %{NAME}-%|EPOCH?{%{EPOCH}}:{0}|:%{VERSION}-%{RELEASE}.%{ARCH}\n", + ), + print_output=False, ) + + running_convert2rhel_NEVRA = _extract_convert2rhel_versions(running_convert2rhel_NEVRA) + + # If we couldn't get a NEVRA above, then print a warning that we could not determine the rpm release and use convert2rhel.__version__ to compare with the latest packaged version + if return_code != 0 or len(running_convert2rhel_NEVRA) != 1: + logger.warning( + "Couldn't determine the rpm release; We will check that the version of convert2rhel (%s) is the latest but ignore the rpm release." + % running_convert2rhel_version + ) + + else: + running_convert2rhel_NEVRA = running_convert2rhel_NEVRA[0] + # Run `rpm -V ` to make sure the user hasn't installed a different convert2rhel version on top of a previously installed rpm package through other means than rpm (e.g. pip install from GitHub) + rpm_convert2rhel_verify, return_code = utils.run_subprocess( + ["rpm", "-V", running_convert2rhel_NEVRA], + print_output=False, + ) + + # If the files aren't what shipped in the rpm, we print a warning that we could not determine the rpm release and use convert2rhel.__version__ to compare with the latest packaged version + if return_code != 0: + logger.warning( + "Some files in the convert2rhel package have changed so the installed convert2rhel is not what was packaged." + " We will check that the version of convert2rhel (%s) is the latest but ignore the rpm release." + % running_convert2rhel_version + ) + + # Otherwise use the NEVRA from above to compare with the latest packaged version + else: + parsed_convert2rhel_version = parse_pkg_string(running_convert2rhel_NEVRA) + + precise_convert2rhel_version = ( + parsed_convert2rhel_version[1], + parsed_convert2rhel_version[2], + parsed_convert2rhel_version[3], + ) + + precise_available_version = latest_available_version + + ver_compare = rpm.labelCompare(precise_convert2rhel_version, precise_available_version) + + formatted_convert2rhel_version = _format_EVR(*precise_convert2rhel_version) + formatted_available_version = _format_EVR(*precise_available_version) + print("Formatted convert2rhel version: %s" % formatted_convert2rhel_version) + print("Formatted avaliable version: %s" % formatted_available_version) + if ver_compare < 0: # Current and deprecated env var names allow_older_envvar_names = ("CONVERT2RHEL_ALLOW_OLDER_VERSION", "CONVERT2RHEL_UNSUPPORTED_VERSION") @@ -191,7 +226,7 @@ def run(self): diagnosis = ( "You are currently running %s and the latest version of convert2rhel is %s.\n" "'CONVERT2RHEL_ALLOW_OLDER_VERSION' environment variable detected, continuing conversion" - % (installed_convert2rhel_version, latest_available_version[1]) + % (formatted_convert2rhel_version, formatted_available_version) ) logger.warning(diagnosis) self.add_message( @@ -206,7 +241,7 @@ def run(self): logger.warning( "You are currently running %s and the latest version of convert2rhel is %s.\n" "We encourage you to update to the latest version." - % (installed_convert2rhel_version, latest_available_version[1]) + % (formatted_convert2rhel_version, formatted_available_version) ) self.add_message( level="WARNING", @@ -216,7 +251,7 @@ def run(self): diagnosis=( "You are currently running %s and the latest version of convert2rhel is %s.\n" "We encourage you to update to the latest version." - % (installed_convert2rhel_version, latest_available_version[1]) + % (formatted_convert2rhel_version, formatted_available_version) ), ) @@ -229,10 +264,39 @@ def run(self): diagnosis=( "You are currently running %s and the latest version of convert2rhel is %s.\n" "Only the latest version is supported for conversion." - % (installed_convert2rhel_version, latest_available_version[1]) + % (formatted_convert2rhel_version, formatted_available_version) ), remediation="If you want to ignore this check, then set the environment variable 'CONVERT2RHEL_ALLOW_OLDER_VERSION=1' to continue.", ) return logger.info("Latest available convert2rhel version is installed.") + + +def _format_EVR(epoch, version, release): + return "%s" % (version) + + +def _extract_convert2rhel_versions(raw_versions): + parsed_versions = [] + + # convert the raw output of convert2rhel version strings into a list + precise_raw_version = raw_versions.splitlines() + + # We are expecting an repoquery output to be similar to this: + # C2R convert2rhel-0:0.17-1.el7.noarch + # We need the `C2R` identifier to be present on the line so we can know for + # sure that the line we are working with is the a line that contains + # relevant repoquery information to our check, otherwise, we just log the + # information as debug and do nothing with it. + for raw_version in precise_raw_version: + if "C2R" in raw_version: + parsed_versions.append(raw_version.lstrip("C2R ")) + else: + # Mainly for debugging purposes to see what is happening if we got + # anything else that does not have the C2R identifier at the start + # of the line. + logger.debug("Got a line without the C2R identifier: %s" % raw_version) + precise_raw_version = parsed_versions + + return precise_raw_version diff --git a/convert2rhel/unit_tests/actions/system_checks/convert2rhel_latest_test.py b/convert2rhel/unit_tests/actions/system_checks/convert2rhel_latest_test.py index 145faf9513..05223c4f26 100644 --- a/convert2rhel/unit_tests/actions/system_checks/convert2rhel_latest_test.py +++ b/convert2rhel/unit_tests/actions/system_checks/convert2rhel_latest_test.py @@ -20,6 +20,11 @@ import os import pytest +import six + + +six.add_move(six.MovedModule("mock", "mock", "unittest.mock")) +from six.moves import mock from convert2rhel import actions, systeminfo, unit_tests, utils from convert2rhel.actions.system_checks import convert2rhel_latest @@ -36,15 +41,24 @@ def convert2rhel_latest_version_test(monkeypatch, tmpdir, request, global_system global_system_info.has_internet_access = True marker = request.param - monkeypatch.setattr(convert2rhel_latest, "installed_convert2rhel_version", marker["local_version"]) + monkeypatch.setattr(convert2rhel_latest, "running_convert2rhel_version", marker["local_version"]) - run_subprocess_mocked = unit_tests.RunSubprocessMocked(return_string=marker["package_version"]) + # Mocking run_subprocess for different command outputs + command_outputs = [ + (marker["package_version_repoquery"], 0), # Output for repoquery + (marker["package_version_qf"], 0), # Output for rpm -qf + (marker["package_version_V"], 0), # Output for rpm -V + ] + run_subprocess_mocked = mock.Mock(spec=utils.run_subprocess, side_effect=command_outputs) monkeypatch.setattr(utils, "run_subprocess", run_subprocess_mocked) monkeypatch.setattr(global_system_info, "version", systeminfo.Version(marker["pmajor"], 0)) monkeypatch.setattr(utils, "TMP_DIR", str(tmpdir)) - return marker["local_version"], marker["package_version"] + return ( + marker["running_version"], + marker["latest_version"], + ) @pytest.fixture @@ -56,9 +70,42 @@ class TestCheckConvert2rhelLatest: @pytest.mark.parametrize( ("convert2rhel_latest_version_test",), ( - [{"local_version": "0.20", "package_version": "C2R convert2rhel-0:0.22-1.el7.noarch", "pmajor": "7"}], - [{"local_version": "0.20", "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", "pmajor": "7"}], - [{"local_version": "0.20.0", "package_version": "C2R convert2rhel-0:0.22-1.el7.noarch", "pmajor": "7"}], + [ + { + "local_version": "0.20", + "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.20-1.el7.noarch", + "package_version_V": " ", + "pmajor": "7", + "running_version": "0:0.20-1.el7", + "latest_version": "0:0.18-1.el7", + } + ], + [ + { + "local_version": "0.20", + "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.20-1.el7.noarch", + "package_version_V": " ", + "pmajor": "7", + "running_version": "0.20", + "latest_version": "0.22.0", + } + ], + [ + { + "local_version": "0.20.0", + "package_version": "C2R convert2rhel-0:0.22.1-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.20.0-1.el7.noarch", + "package_version_V": " ", + "pmajor": "7", + "running_version": "0:0.20.0", + "latest_version": "0:0.18-1.el7", + } + ], ), indirect=True, ) @@ -89,23 +136,73 @@ def test_convert2rhel_latest_offline( @pytest.mark.parametrize( ("convert2rhel_latest_version_test",), ( - [{"local_version": "0.21", "package_version": "C2R convert2rhel-0:0.22-1.el7.noarch", "pmajor": "7"}], - [{"local_version": "0.21", "package_version": "C2R convert2rhel-0:1.10-1.el7.noarch", "pmajor": "7"}], - [{"local_version": "1.21.0", "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", "pmajor": "7"}], - [{"local_version": "1.21", "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", "pmajor": "7"}], - [{"local_version": "1.21.1", "package_version": "C2R convert2rhel-0:1.22-1.el7.noarch", "pmajor": "7"}], + [ + { + "local_version": "0.21", + "package_version": "C2R convert2rhel-0:0.22-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.22-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.21-1.el7.noarch", + "package_version_V": 0, + "pmajor": "7", + "running_version": "0.21", + "latest_version": "0.22", + } + ], + [ + { + "local_version": "0.21", + "package_version": "C2R convert2rhel-0:1.10-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.10-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.21-1.el7.noarch", + "package_version_V": 0, + "pmajor": "7", + "running_version": "0.21", + "latest_version": "1.10", + } + ], + [ + { + "local_version": "1.21.0", + "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.21.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "7", + "running_version": "1.21.0", + "latest_version": "1.21.1", + } + ], + [ + { + "local_version": "1.21", + "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.21-1.el7.noarch", + "package_version_V": 0, + "pmajor": "7", + "running_version": "1.21", + "latest_version": "1.21.1", + } + ], + [ + { + "local_version": "1.21.1", + "package_version": "C2R convert2rhel-0:1.22-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.22-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_V": 0, + "pmajor": "7", + "running_version": "1.21.1", + "latest_version": "1.22", + } + ], ), indirect=True, ) def test_convert2rhel_latest_action_error(self, convert2rhel_latest_action, convert2rhel_latest_version_test): convert2rhel_latest_action.run() - local_version, package_version = convert2rhel_latest_version_test - if len(package_version) > 36: - - package_version = package_version[19:25] - else: - package_version = package_version[19:23] + running_version, latest_version = convert2rhel_latest_version_test unit_tests.assert_actions_result( convert2rhel_latest_action, @@ -115,7 +212,7 @@ def test_convert2rhel_latest_action_error(self, convert2rhel_latest_action, conv description="An outdated convert2rhel version has been detected", diagnosis=( "You are currently running %s and the latest version of convert2rhel is %s.\n" - "Only the latest version is supported for conversion." % (local_version, package_version) + "Only the latest version is supported for conversion." % (running_version, latest_version) ), remediation="If you want to ignore this check, then set the environment variable 'CONVERT2RHEL_ALLOW_OLDER_VERSION=1' to continue.", ) @@ -123,52 +220,66 @@ def test_convert2rhel_latest_action_error(self, convert2rhel_latest_action, conv @pytest.mark.parametrize( ("convert2rhel_latest_version_test",), ( - [{"local_version": "0.21", "package_version": "C2R convert2rhel-0:0.22-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "0.21", "package_version": "C2R convert2rhel-0:1.10-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "1.21.0", "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "1.21", "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "1.21.1", "package_version": "C2R convert2rhel-0:1.22-1.el7.noarch", "pmajor": "6"}], - ), - indirect=True, - ) - def test_convert2rhel_latest_action_outdated_version( - self, convert2rhel_latest_action, convert2rhel_latest_version_test - ): - convert2rhel_latest_action.run() - - local_version, package_version = convert2rhel_latest_version_test - if len(package_version) > 36: - - package_version = package_version[19:25] - else: - package_version = package_version[19:23] - - expected = set( - ( - actions.ActionMessage( - level="WARNING", - id="OUTDATED_CONVERT2RHEL_VERSION", - title="Outdated convert2rhel version detected", - description="An outdated convert2rhel version has been detected", - diagnosis=( - "You are currently running %s and the latest version of convert2rhel is %s.\n" - "We encourage you to update to the latest version." % (local_version, package_version) - ), - remediation=None, - ), - ) - ) - assert expected.issuperset(convert2rhel_latest_action.messages) - assert expected.issubset(convert2rhel_latest_action.messages) - - @pytest.mark.parametrize( - ("convert2rhel_latest_version_test",), - ( - [{"local_version": "0.21", "package_version": "C2R convert2rhel-0:0.22-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "0.21", "package_version": "C2R convert2rhel-0:1.10-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "1.21.0", "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "1.21", "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "1.21.1", "package_version": "C2R convert2rhel-0:1.22-1.el7.noarch", "pmajor": "6"}], + [ + { + "local_version": "0.21", + "package_version": "C2R convert2rhel-0:0.22-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.22-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.21-1.el7.noarch", + "package_version_V": " ", + "pmajor": "6", + "running_version": "0.21", + "latest_version": "0.22", + } + ], + [ + { + "local_version": "0.21", + "package_version": "C2R convert2rhel-0:1.10-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.10-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.21-1.el7.noarch", + "package_version_V": " ", + "pmajor": "6", + "running_version": "0.21", + "latest_version": "1.10", + } + ], + [ + { + "local_version": "1.21.0", + "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.21.0-1.el7.noarch", + "package_version_V": " ", + "pmajor": "6", + "running_version": "1.21.0", + "latest_version": "1.21.1", + } + ], + [ + { + "local_version": "1.21", + "package_version": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.21-1.el7.noarch", + "package_version_V": 0, + "pmajor": "6", + "running_version": "1.21", + "latest_version": "1.21.1", + } + ], + [ + { + "local_version": "1.21.1", + "package_version": "C2R convert2rhel-0:0.22-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.22-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.21.1-1.el7.noarch", + "package_version_V": 0, + "pmajor": "6", + "running_version": "1.21.1", + "latest_version": "1.22", + } + ], ), indirect=True, ) @@ -177,12 +288,7 @@ def test_convert2rhel_latest_action_outdated_version( ): convert2rhel_latest_action.run() - local_version, package_version = convert2rhel_latest_version_test - if len(package_version) > 36: - - package_version = package_version[19:25] - else: - package_version = package_version[19:23] + running_version, latest_version = convert2rhel_latest_version_test expected = set( ( @@ -193,10 +299,9 @@ def test_convert2rhel_latest_action_outdated_version( description="An outdated convert2rhel version has been detected", diagnosis=( "You are currently running %s and the latest version of convert2rhel is %s.\n" - "We encourage you to update to the latest version." % (local_version, package_version) + "We encourage you to update to the latest version." % (running_version, latest_version) ), remediation=None, - variables={}, ), ) ) @@ -210,40 +315,65 @@ def test_convert2rhel_latest_action_outdated_version( { "local_version": "0.18.0", "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_V": 0, "pmajor": "6", "enset": "1", + "running_version": "0.18.0", + "latest_version": "0.22.0", } ], [ { "local_version": "0.18.1", "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.18.1-1.el7.noarch", + "package_version_V": 0, "pmajor": "7", "enset": "1", + "running_version": "0.18.1", + "latest_version": "0.22.0", } ], [ { "local_version": "0.18.3", "package_version": "C2R convert2rhel-0:0.22.1-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.22.1-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.18.3-1.el7.noarch", + "package_version_V": 0, "pmajor": "8", "enset": "1", + "running_version": "0.18.3", + "latest_version": "0.22.1", } ], [ { "local_version": "0.18", "package_version": "C2R convert2rhel-0:1.10.2-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.10.2-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.18-1.el7.noarch", + "package_version_V": 0, "pmajor": "8", "enset": "1", + "running_version": "0.18", + "latest_version": "1.10.2", } ], [ { "local_version": "0.18.0", "package_version": "C2R convert2rhel-0:1.10-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.10-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_V": 0, "pmajor": "8", "enset": "1", + "running_version": "0.18.0", + "latest_version": "1.10", } ], ), @@ -255,15 +385,12 @@ def test_convert2rhel_latest_log_check_env( monkeypatch.setattr(os, "environ", {"CONVERT2RHEL_ALLOW_OLDER_VERSION": "1"}) convert2rhel_latest_action.run() - local_version, package_version = convert2rhel_latest_version_test - if len(package_version) > 36: - package_version = package_version[19:25] - else: - package_version = package_version[19:23] + running_version, latest_version = convert2rhel_latest_version_test + log_msg = ( "You are currently running %s and the latest version of convert2rhel is %s.\n" "'CONVERT2RHEL_ALLOW_OLDER_VERSION' environment variable detected, continuing conversion" - % (local_version, package_version) + % (running_version, latest_version) ) assert log_msg in caplog.text @@ -273,14 +400,102 @@ def test_convert2rhel_latest_log_check_env( @pytest.mark.parametrize( ("convert2rhel_latest_version_test",), ( - [{"local_version": "0.17.0", "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "0.17.0", "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", "pmajor": "7"}], - [{"local_version": "0.17.0", "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", "pmajor": "8"}], - [{"local_version": "0.25.0", "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", "pmajor": "6"}], - [{"local_version": "0.25.0", "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", "pmajor": "7"}], - [{"local_version": "0.25.0", "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", "pmajor": "8"}], - [{"local_version": "1.10.0", "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch", "pmajor": "8"}], - [{"local_version": "1.10.1", "package_version": "C2R convert2rhel-0:1.10.0-1.el7.noarch", "pmajor": "8"}], + [ + { + "local_version": "0.17.0", + "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "6", + "running_version": "0:0.17.1-1.el7", + "latest_version": "0:0.17.0-1.el7", + } + ], + [ + { + "local_version": "0.17.0", + "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "7", + "running_version": "0.17.0", + "latest_version": "0.17.1", + } + ], + [ + { + "local_version": "0.17.0", + "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "0.17.0", + "latest_version": "0.17.0", + } + ], + [ + { + "local_version": "0.25.0", + "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.25.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "6", + "running_version": "0.25.0", + "latest_version": "0.17.0", + } + ], + [ + { + "local_version": "0.25.0", + "package_version": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.25.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "7", + "running_version": "0.25.0", + "latest_version": "0.17.0", + } + ], + [ + { + "local_version": "0.25.0", + "package_version": "C2R convert2rhel-:0.18.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.25.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "0.25.0", + "latest_version": "0.18.0", + } + ], + [ + { + "local_version": "1.10.0", + "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.10.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "1.10.0", + "latest_version": "0.18.0", + } + ], + [ + { + "local_version": "1.10.1", + "package_version": "C2R convert2rhel-0:1.10.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:1.10.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.10.1-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "1.10.1", + "latest_version": "1.10.0", + } + ], ), indirect=True, ) @@ -293,9 +508,42 @@ def test_c2r_up_to_date(self, caplog, monkeypatch, convert2rhel_latest_action, c @pytest.mark.parametrize( ("convert2rhel_latest_version_test",), ( - [{"local_version": "1.10.0", "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch", "pmajor": "8"}], - [{"local_version": "1.10", "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch", "pmajor": "8"}], - [{"local_version": "1.10.0", "package_version": "C2R convert2rhel-0:0.18-1.el7.noarch", "pmajor": "8"}], + [ + { + "local_version": "1.10.0", + "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.10.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "1.10.0", + "latest_version": "0.18.0", + } + ], + [ + { + "local_version": "1.10", + "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.10-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "1.10", + "latest_version": "0.18.0", + } + ], + [ + { + "local_version": "1.10.0", + "package_version": "C2R convert2rhel-:0.18-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:1.10.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "1.10.0", + "latest_version": "0.18", + } + ], ), indirect=True, ) @@ -337,21 +585,36 @@ def test_c2r_up_to_date_repoquery_error( { "local_version": "0.19.0", "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.19.0-1.el7.noarch", + "package_version_V": 0, "pmajor": "8", + "running_version": "0.19.0", + "latest_version": "0.20.0", } ], [ { "local_version": "0.19", "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.19-1.el7.noarch", + "package_version_V": 0, "pmajor": "8", + "running_version": "0.19", + "latest_version": "0.20.0", } ], [ { "local_version": "0.19.0", "package_version": "C2R convert2rhel-0:0.18-1.el7.noarch\nC2R convert2rhel-0:0.17-1.el7.noarch\nC2R convert2rhel-0:0.20-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.19.0-1.el7.noarch", + "package_version_V": 0, "pmajor": "8", + "running_version": "0.19.0", + "latest_version": "0.20", } ], ), @@ -360,12 +623,7 @@ def test_c2r_up_to_date_repoquery_error( def test_c2r_up_to_date_multiple_packages(self, convert2rhel_latest_action, convert2rhel_latest_version_test): convert2rhel_latest_action.run() - local_version, package_version = convert2rhel_latest_version_test - - if len(package_version) > 110: - package_version = package_version[97:103] - else: - package_version = package_version[93:97] + running_version, latest_version = convert2rhel_latest_version_test unit_tests.assert_actions_result( convert2rhel_latest_action, @@ -375,35 +633,57 @@ def test_c2r_up_to_date_multiple_packages(self, convert2rhel_latest_action, conv description="An outdated convert2rhel version has been detected", diagnosis=( "You are currently running %s and the latest version of convert2rhel is %s.\n" - "Only the latest version is supported for conversion." % (local_version, package_version) + "Only the latest version is supported for conversion." % (running_version, latest_version) ), remediation="If you want to ignore this check, then set the environment variable 'CONVERT2RHEL_ALLOW_OLDER_VERSION=1' to continue.", ) @pytest.mark.parametrize( - ( - "convert2rhel_latest_version_test", - "current_version", - ), + ("convert2rhel_latest_version_test",), ( [ - {"local_version": "0.17.0", "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch", "pmajor": "8"}, - "0.18.0", + { + "local_version": "0.17.0", + "package_version": "C2R convert2rhel-0.18.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "0.17.0", + "latest_version": "0.18.0", + } ], [ - {"local_version": "0.17", "package_version": "C2R convert2rhel-0:0.18.0-1.el7.noarch", "pmajor": "8"}, - "0.18.0", + { + "local_version": "0.17", + "package_version": "C2R convert2rhel-0.18.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.17-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "0.17", + "latest_version": "0.18.0", + } ], [ - {"local_version": "0.17.0", "package_version": "C2R convert2rhel-0:0.18-1.el7.noarch", "pmajor": "8"}, - "0.18", + { + "local_version": "0.17.0", + "package_version": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0:0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.17.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "0.17.0", + "latest_version": "0.18", + } ], ), indirect=True, ) def test_c2r_up_to_date_deprecated_env_var( - self, caplog, monkeypatch, convert2rhel_latest_action, convert2rhel_latest_version_test, current_version + self, caplog, monkeypatch, convert2rhel_latest_action, convert2rhel_latest_version_test ): + running_version, latest_version = convert2rhel_latest_version_test env = {"CONVERT2RHEL_UNSUPPORTED_VERSION": 1} monkeypatch.setattr(os, "environ", env) expected = set( @@ -423,7 +703,7 @@ def test_c2r_up_to_date_deprecated_env_var( description="An outdated convert2rhel version has been detected", diagnosis="You are currently running %s and the latest version of convert2rhel is %s.\n" "'CONVERT2RHEL_ALLOW_OLDER_VERSION' environment variable detected, continuing conversion" - % (convert2rhel_latest_version_test[0], current_version), + % (running_version, latest_version), remediation=None, ), ) @@ -440,3 +720,276 @@ def test_c2r_up_to_date_deprecated_env_var( assert expected.issuperset(convert2rhel_latest_action.messages) assert expected.issubset(convert2rhel_latest_action.messages) assert log_msg in caplog.text + + @pytest.mark.parametrize( + ("convert2rhel_latest_version_test",), + ( + [ + { + "local_version": "0.18.0", + "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_V": 1, + "pmajor": "6", + "running_version": "0.18.0", + "latest_version": "0.18.1", + } + ], + [ + { + "local_version": "0.18.1", + "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_V": 1, + "pmajor": "7", + "running_version": "0.18.1", + "latest_version": "0.18.1", + } + ], + [ + { + "local_version": "0.18.3", + "package_version": "C2R convert2rhel-0:0.22.1-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_V": 1, + "pmajor": "8", + "running_version": "0.18.3", + "latest_version": "0.18.1", + } + ], + ), + indirect=True, + ) + def test_convert2rhel_latest_rpm_V_check( + self, caplog, monkeypatch, convert2rhel_latest_action, convert2rhel_latest_version_test + ): + def mock_run_subprocess(cmd, print_output=False): + if "--qf" in cmd: + return ("C2R convert2rhel-0:0.18.0-1.el7.noarch", 0) + elif "-V" in cmd: + return ("", 1) + return ("", 0) + + monkeypatch.setattr( + utils, + "run_subprocess", + mock_run_subprocess, + ) + + running_version, latest_version = convert2rhel_latest_version_test + convert2rhel_latest_action.run() + + log_msg = ( + "Some files in the convert2rhel package have changed so the installed convert2rhel is not what was packaged." + " We will check that the version of convert2rhel (%s) is the latest but ignore the rpm release." + % running_version + ) + + assert log_msg in caplog.text + + @pytest.mark.parametrize( + ("convert2rhel_latest_version_test",), + ( + [ + { + "local_version": "0.18.0", + "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_V": " ", + "pmajor": "6", + "running_version": "0.18.0", + "latest_version": "0.18.1", + } + ], + [ + { + "local_version": "0.18.1", + "package_version": "C2R convert2rhel-0:0.22.0-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_V": 0, + "pmajor": "7", + "running_version": "0.18.1", + "latest_version": "0.18.1", + } + ], + [ + { + "local_version": "0.18.3", + "package_version": "C2R convert2rhel-0:0.22.1-1.el7.noarch", + "package_version_repoquery": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0.18-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "0.18.3", + "latest_version": "0.18.1", + } + ], + ), + indirect=True, + ) + def test_convert2rhel_latest_rpm_qf_check( + self, caplog, monkeypatch, convert2rhel_latest_action, convert2rhel_latest_version_test + ): + def mock_run_subprocess(cmd, print_output=False): + if "repoquery" in cmd: + return ("C2R convert2rhel-0:0.18.0-1.el7.noarch", 0) + elif "--qf" in cmd: + return ("", 1) + return ("", 0) + + monkeypatch.setattr( + utils, + "run_subprocess", + mock_run_subprocess, + ) + + running_version, latest_version = convert2rhel_latest_version_test + convert2rhel_latest_action.run() + + log_msg = ( + "Couldn't determine the rpm release; We will check that the version of convert2rhel (%s) is the latest but ignore the rpm release." + % running_version + ) + + assert log_msg in caplog.text + + @pytest.mark.parametrize( + ("convert2rhel_latest_version_test",), + ( + [ + { + "local_version": "0.19.0", + "package_version_repoquery": "C2R convert2rhel-0:0.18.0-1.el7.noarch\nNot a NEVRA that we was not filtered due to a bug\nC2R convert2rhel-0:0.20.0-1.el7.noarch", + "package_version_qf": "C2R convert2rhel-0:0.19.0-1.el7.noarch", + "package_version_V": 0, + "pmajor": "8", + "running_version": "0.19.0", + "latest_version": "0.20.0", + } + ], + ), + indirect=True, + ) + def test_bad_NEVRA_to_parse_pkg_string( + self, + convert2rhel_latest_action, + convert2rhel_latest_version_test, + monkeypatch, + ): + generator = extract_convert2rhel_versions_generator() + + # Use mock.patch with side_effect set to the generator + mock.patch( + "convert2rhel_latest._extract_convert2rhel_versions", + side_effect=generator, + ) + + convert2rhel_latest_action.run() + + running_version, latest_version = convert2rhel_latest_version_test + + unit_tests.assert_actions_result( + convert2rhel_latest_action, + level="ERROR", + id="OUT_OF_DATE", + title="Outdated convert2rhel version detected", + description="An outdated convert2rhel version has been detected", + diagnosis=( + "You are currently running %s and the latest version of convert2rhel is %s.\n" + "Only the latest version is supported for conversion." % (running_version, latest_version) + ), + remediation="If you want to ignore this check, then set the environment variable 'CONVERT2RHEL_ALLOW_OLDER_VERSION=1' to continue.", + ) + + +def extract_convert2rhel_versions_generator(): + # Yield bad output + yield [ + "convert2rhel-0:0.18.0-1.el7.noarch", + "Not a NEVRA that we was not filtered due to a bug", + "convert2rhel-0:0.20.0-1.el7.noarch", + ] + + # Yield good output + yield [ + "convert2rhel-0:0.18.0-1.el7.noarch", + "convert2rhel-0:0.19.0-1.el7.noarch", + "convert2rhel-0:0.20.0-1.el7.noarch", + ] + + +class Test_ExtractConvert2rhelVersions: + @pytest.mark.parametrize( + ("raw_versions", "expected_versions"), + ( + ( + "C2R convert2rhel-0:0.18.0-1.el7.noarch\n", + [ + "convert2rhel-0:0.18.0-1.el7.noarch", + ], + ), + ( + "C2R convert2rhel-1:1.0-99.el8.noarch\n", + [ + "convert2rhel-1:1.0-99.el8.noarch", + ], + ), + ( + "C2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch", + [ + "convert2rhel-0:0.18.0-1.el7.noarch", + "convert2rhel-0:0.17.0-1.el7.noarch", + "convert2rhel-0:0.20.0-1.el7.noarch", + ], + ), + ( + "C2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch\nconvert2rhel-0:0.21-1.el7.noarch", + [ + "convert2rhel-0:0.18.0-1.el7.noarch", + "convert2rhel-0:0.17.0-1.el7.noarch", + "convert2rhel-0:0.20.0-1.el7.noarch", + ], + ), + ( + "C2R convert2rhel-0:0.18.0-1.el7.noarch\nconvert2rhel-0:0.21-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch\n", + [ + "convert2rhel-0:0.18.0-1.el7.noarch", + "convert2rhel-0:0.17.0-1.el7.noarch", + "convert2rhel-0:0.20.0-1.el7.noarch", + ], + ), + ( + "convert2rhel-0:0.21-1.el7.noarch\nC2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch\n", + [ + "convert2rhel-0:0.18.0-1.el7.noarch", + "convert2rhel-0:0.17.0-1.el7.noarch", + "convert2rhel-0:0.20.0-1.el7.noarch", + ], + ), + ( + "convert2rhel-0:0.21-1.el7.noarch\nC2R convert2rhel-0:0.18.0-1.el7.noarch\nC2R convert2rhel-0:0.17.0-1.el7.noarch\nconvert2rhel-1:2.27-9.el8.noarch\nC2R convert2rhel-0:0.20.0-1.el7.noarch\n", + [ + "convert2rhel-0:0.18.0-1.el7.noarch", + "convert2rhel-0:0.17.0-1.el7.noarch", + "convert2rhel-0:0.20.0-1.el7.noarch", + ], + ), + ( + "", + [], + ), + ( + "Output\nfrom repoquery where\nno strings were for\npackages", + [], + ), + ), + ) + def test_extract_convert2rhel_version(self, raw_versions, expected_versions): + list_of_versions = convert2rhel_latest._extract_convert2rhel_versions(raw_versions) + + assert list_of_versions == expected_versions