From bbae477a9c4027cbde0b68af577a0c319bcad607 Mon Sep 17 00:00:00 2001 From: Preston Watson Date: Tue, 20 Feb 2024 14:46:22 -0500 Subject: [PATCH] [RHELC-1070] Duplicate package check for preconversion analysis (#987) * [RHELC-1070] Duplicate package check for preconversion analysis * Update convert2rhel/actions/system_checks/duplicate_packages.py Co-authored-by: Rodolfo Olivieri --------- Co-authored-by: Freya Gustavsson Co-authored-by: Rodolfo Olivieri --- .../system_checks/duplicate_packages.py | 49 +++++++++++++ .../system_checks/duplicate_packages_test.py | 71 +++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 convert2rhel/actions/system_checks/duplicate_packages.py create mode 100644 convert2rhel/unit_tests/actions/system_checks/duplicate_packages_test.py diff --git a/convert2rhel/actions/system_checks/duplicate_packages.py b/convert2rhel/actions/system_checks/duplicate_packages.py new file mode 100644 index 0000000000..377c82bb1c --- /dev/null +++ b/convert2rhel/actions/system_checks/duplicate_packages.py @@ -0,0 +1,49 @@ +# Copyright(C) 2023 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +__metaclass__ = type + +import logging + +from convert2rhel import actions, utils + + +logger = logging.getLogger(__name__) + + +class DuplicatePackages(actions.Action): + id = "DUPLICATE_PACKAGES" + + def run(self): + """Ensure that there are no duplicate system packages installed.""" + super(DuplicatePackages, self).run() + + logger.task("Prepare: Check if there are any duplicate installed packages on the system") + output, _ = utils.run_subprocess(["/usr/bin/package-cleanup", "--dupes", "--quiet"], print_output=False) + if not output: + return + + duplicate_packages = filter(None, output.split("\n")) + if duplicate_packages: + self.set_result( + level="ERROR", + id="DUPLICATE_PACKAGES_FOUND", + title="Duplicate packages found on the system", + description="The system contains one or more packages with multiple versions.", + diagnosis="The following packages have multiple versions: %s." % ", ".join(duplicate_packages), + remediations="This error can be resolved by removing duplicate versions of the listed packages." + " The command 'package-cleanup' can be used to automatically remove duplicate packages" + " on the system.", + ) diff --git a/convert2rhel/unit_tests/actions/system_checks/duplicate_packages_test.py b/convert2rhel/unit_tests/actions/system_checks/duplicate_packages_test.py new file mode 100644 index 0000000000..2da04d1eb8 --- /dev/null +++ b/convert2rhel/unit_tests/actions/system_checks/duplicate_packages_test.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# +# Copyright(C) 2023 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +__metaclass__ = type + + +import pytest + +from convert2rhel import unit_tests, utils +from convert2rhel.actions.system_checks import duplicate_packages +from convert2rhel.unit_tests import RunSubprocessMocked + + +@pytest.fixture +def duplicate_packages_action(): + return duplicate_packages.DuplicatePackages() + + +@pytest.mark.parametrize( + ("output", "expected"), + ( + ( + "package1.x86_64\npackage1.s390x\npackage2.x86_64\npackage2.ppc64le\n", + ["package1.x86_64", "package1.s390x", "package2.x86_64", "package2.ppc64le"], + ), + ( + "package1.x86_64\npackage1.i686\npackage1.s390x\npackage2.x86_64\npackage2.ppc64le\n", + ["package1.x86_64", "package1.i686", "package1.s390x", "package2.x86_64", "package2.ppc64le"], + ), + ), +) +def test_duplicate_packages_error(monkeypatch, output, expected, duplicate_packages_action): + + monkeypatch.setattr(utils, "run_subprocess", RunSubprocessMocked(return_value=(output, 0))) + duplicate_packages_action.run() + + unit_tests.assert_actions_result( + duplicate_packages_action, + level="ERROR", + id="DUPLICATE_PACKAGES_FOUND", + title="Duplicate packages found on the system", + description="The system contains one or more packages with multiple versions.", + diagnosis="The following packages have multiple versions: %s." % ", ".join(expected), + remediations="This error can be resolved by removing duplicate versions of the listed packages." + " The command 'package-cleanup' can be used to automatically remove duplicate packages" + " on the system.", + ) + + +def test_duplicate_packages_success(monkeypatch, duplicate_packages_action): + + monkeypatch.setattr(utils, "run_subprocess", RunSubprocessMocked(return_value=("", 0))) + duplicate_packages_action.run() + unit_tests.assert_actions_result( + duplicate_packages_action, + level="SUCCESS", + )