Skip to content

Commit ed602f3

Browse files
committed
Add and fix unit tests
Assisted by GitHub Copilot
1 parent 9ab9652 commit ed602f3

File tree

5 files changed

+180
-104
lines changed

5 files changed

+180
-104
lines changed

convert2rhel/actions/pre_ponr_changes/yum_variables.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from convert2rhel import backup
2323
from convert2rhel.backup.files import InstalledFile, RestorableFile
2424
from convert2rhel.logger import root_logger
25-
from convert2rhel.pkghandler import get_files_owned_by_package, get_packages_to_remove
25+
from convert2rhel import pkghandler
2626
from convert2rhel.repo import DEFAULT_DNF_VARS_DIR, DEFAULT_YUM_VARS_DIR
2727
from convert2rhel.systeminfo import system_info
2828
from convert2rhel.toolopts.config import loggerinst
@@ -48,18 +48,24 @@ def run(self):
4848
super(BackUpYumVariables, self).run()
4949

5050
logger.debug("Getting a list of files owned by packages affecting variables in .repo files.")
51-
yum_var_affecting_pkgs = get_packages_to_remove(system_info.repofile_pkgs)
52-
yum_var_files_to_back_up = self._get_yum_var_files_owned_by_pkgs(
53-
[pkg_obj.nevra.name for pkg_obj in yum_var_affecting_pkgs]
54-
)
51+
yum_var_affecting_pkgs = []
52+
for pkg in system_info.repofile_pkgs:
53+
# We use get_installed_pkg_objects() to have yum find installed packages even when a glob (*) is useed
54+
yum_var_affecting_pkgs.extend(pkghandler.get_installed_pkg_objects(pkg))
55+
56+
# Get just the names of the packages affecting yum variables
57+
yum_var_affecting_pkg_names = [pkg.name for pkg in yum_var_affecting_pkgs]
58+
logger.debug("Packages affecting yum variables: {0}".format(", ".join(yum_var_affecting_pkg_names)))
59+
60+
yum_var_files_to_back_up = self._get_yum_var_files_owned_by_pkgs(yum_var_affecting_pkg_names)
5561
self._back_up_var_files(yum_var_files_to_back_up)
5662

5763
def _get_yum_var_files_owned_by_pkgs(self, pkg_names):
5864
"""Get paths of yum var files owned by the packages passed to the method."""
5965
pkg_owned_files = set()
6066
for pkg in pkg_names:
6167
# using set() and union() to get unique paths
62-
pkg_owned_files = pkg_owned_files.union(get_files_owned_by_package(pkg))
68+
pkg_owned_files = pkg_owned_files.union(pkghandler.get_files_owned_by_package(pkg))
6369

6470
# Out of all the files owned by the packages get just those in yum/dnf var dirs
6571
yum_var_filepaths = [
@@ -69,18 +75,19 @@ def _get_yum_var_files_owned_by_pkgs(self, pkg_names):
6975
return yum_var_filepaths
7076

7177
def _back_up_var_files(self, paths):
72-
"""Back up yum variable files.
78+
"""Back up yum/dnf variable files.
7379
7480
:param paths: Paths to the variable files to back up
7581
:type paths: list[str]
7682
"""
7783
logger.info(
78-
"Backing up variables files from {} owned by {} packages.".format(
84+
"Backing up yum variable files from {} owned by {} packages.".format(
7985
" and ".join(self.yum_var_dirs), system_info.name
8086
)
8187
)
8288
if not paths:
83-
logger.info("No variables files backed up.")
89+
logger.info("No variable files to back up detected.")
90+
return
8491

8592
for filepath in paths:
8693
restorable_file = RestorableFile(filepath)

convert2rhel/pkghandler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ def get_rpm_header(pkg_obj):
200200

201201

202202
def get_installed_pkg_objects(name=None, version=None, release=None, arch=None):
203-
"""Return list with installed package objects. The packages can be
204-
optionally filtered by name.
203+
"""Return list with installed package objects (yum.rpmsack.RPMInstalledPackage objects in case
204+
of yum and hawkey.Package objects in case of dnf). The packages can be optionally filtered.
205205
"""
206206
if pkgmanager.TYPE == "yum":
207207
return _get_installed_pkg_objects_yum(name, version, release, arch)

convert2rhel/unit_tests/actions/post_conversion/update_grub_test.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,37 @@ def test_update_grub_error(update_grub_instance, monkeypatch, get_partition_erro
247247
description="The block device could not be identified, please look at the diagnosis " "for more information.",
248248
diagnosis=diagnosis,
249249
)
250+
251+
252+
# This function was generated by GitHub Copilot
253+
@pytest.mark.parametrize(
254+
("releasever_major", "file_content", "expected_log"),
255+
[
256+
(2, 'GRUB_TERMINAL="ec2-console"', "Successfully updated /etc/default/grub."),
257+
(
258+
2,
259+
'GRUB_TERMINAL="console"',
260+
'GRUB_TERMINAL="ec2-console" not found in /etc/default/grub. Nothing to do.',
261+
),
262+
(3, 'GRUB_TERMINAL="ec2-console"', "Not running Amazon Linux 2, skipping."),
263+
],
264+
)
265+
def test_fix_grub_settings_on_al2(releasever_major, file_content, expected_log, monkeypatch, caplog):
266+
monkeypatch.setattr(
267+
"convert2rhel.systeminfo.system_info.version",
268+
namedtuple("Version", ["major"])(releasever_major),
269+
)
270+
mock_open = mock.mock_open(read_data=file_content)
271+
monkeypatch.setattr("builtins.open", mock_open)
272+
monkeypatch.setattr("convert2rhel.utils.get_file_content", mock.Mock(return_value=file_content))
273+
274+
action = update_grub.FixGrubSettingsOnAL2()
275+
action.run()
276+
277+
if releasever_major == 2 and "ec2-console" in file_content:
278+
mock_open.assert_called_with("/etc/default/grub", "w")
279+
mock_open().write.assert_called_once_with(file_content.replace("ec2-console", "console"))
280+
else:
281+
mock_open.assert_not_called()
282+
283+
assert expected_log in caplog.text

convert2rhel/unit_tests/actions/pre_ponr_changes/backup_system_test.py

Lines changed: 1 addition & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@
2323
import six
2424

2525
from convert2rhel import toolopts, unit_tests
26-
from convert2rhel.actions.pre_ponr_changes import backup_system, yum_variables
26+
from convert2rhel.actions.pre_ponr_changes import backup_system
2727
from convert2rhel.backup import files
2828
from convert2rhel.backup.files import RestorableFile
2929
from convert2rhel.unit_tests import CriticalErrorCallableObject
30-
from convert2rhel.unit_tests.conftest import all_systems, centos7, centos8
3130
from convert2rhel.utils.rpm import PRE_RPM_VA_LOG_FILENAME
3231

3332

@@ -45,11 +44,6 @@ def backup_repository_action():
4544
return backup_system.BackupRepository()
4645

4746

48-
@pytest.fixture
49-
def backup_variables_action():
50-
return yum_variables.BackUpYumVariables()
51-
52-
5347
class RestorableFileBackupMocked(CriticalErrorCallableObject):
5448
method_spec = RestorableFile.enable
5549

@@ -59,19 +53,6 @@ def backup_package_files_action():
5953
return backup_system.BackupPackageFiles()
6054

6155

62-
@pytest.fixture
63-
def generate_vars(tmpdir):
64-
"""Create yum and dnf vars folders with file for backup."""
65-
tmpdir = tmpdir.mkdir("etc")
66-
67-
yum_vars = tmpdir.mkdir("yum").mkdir("vars").join("yum_test_var")
68-
dnf_vars = tmpdir.mkdir("dnf").mkdir("vars").join("dnf_test_var")
69-
yum_vars.write("yum_test_var")
70-
dnf_vars.write("dnf_test_var")
71-
72-
return str(dnf_vars), str(yum_vars)
73-
74-
7556
def generate_repo(tmpdir, name):
7657
"""Create .repo file for backup."""
7758
yum_repofile = tmpdir.mkdir("etc").mkdir("yum.repos.d").join(name)
@@ -469,76 +450,3 @@ def test_backup_repository_no_repofile_presence(self, tmpdir, monkeypatch, caplo
469450

470451
backup_repository.run()
471452
assert ("Repository folder {} seems to be empty.".format(etc)) in caplog.text
472-
473-
474-
class TestBackupVariables:
475-
@all_systems
476-
def test_backup_variables_nonexisting_path(self, tmpdir, monkeypatch, caplog, backup_variables_action, pretend_os):
477-
"""Test empty paths, nothing for backup."""
478-
etc = tmpdir.mkdir("etc")
479-
480-
monkeypatch.setattr(yum_variables, "DEFAULT_YUM_VARS_DIR", str(etc))
481-
monkeypatch.setattr(yum_variables, "DEFAULT_DNF_VARS_DIR", str(etc))
482-
483-
backup_variables = backup_variables_action
484-
485-
backup_variables.run()
486-
487-
assert "No variables files backed up." in caplog.text
488-
489-
@centos7
490-
def test_backup_variables_for_both_dnf_and_yum(
491-
self, pretend_os, monkeypatch, tmpdir, generate_vars, backup_variables_action
492-
):
493-
"""All dnf and yum var files are to be backed up, not matter the system or package manager installed."""
494-
dnf_vars, yum_vars = generate_vars
495-
496-
backup_dir = str(tmpdir.mkdir("backup"))
497-
498-
monkeypatch.setattr(files, "BACKUP_DIR", backup_dir)
499-
500-
backup_variables = backup_variables_action
501-
502-
backup_variables.run()
503-
504-
# Mapping if the file should be backed up or not
505-
orig_path_dict = {dnf_vars: True, yum_vars: True}
506-
507-
# Get the target path of backed up file and check presence of the file
508-
for path, value in orig_path_dict.items():
509-
filename = os.path.basename(path)
510-
dirname = os.path.dirname(path)
511-
hashed_directory = os.path.join(backup_dir, hashlib.md5(dirname.encode()).hexdigest())
512-
backed_up_path = os.path.join(hashed_directory, filename)
513-
514-
assert os.path.exists(backed_up_path) == value
515-
516-
@centos8
517-
def test_backup_variables_complete(
518-
self, monkeypatch, tmpdir, generate_vars, backup_variables_action, global_backup_control, pretend_os
519-
):
520-
"""Test backup, remove the originals and restore them from backup."""
521-
dnf_vars, yum_vars = generate_vars
522-
523-
backup_dir = str(tmpdir.mkdir("backup"))
524-
525-
monkeypatch.setattr(files, "BACKUP_DIR", backup_dir)
526-
527-
backup_variables = backup_variables_action
528-
529-
backup_variables.run()
530-
531-
orig_path_list = [dnf_vars, yum_vars]
532-
533-
# Remove the original files
534-
for path in orig_path_list:
535-
os.remove(path)
536-
assert not os.path.isfile(path)
537-
538-
global_backup_control.pop_all()
539-
540-
# Check presence of restored files
541-
for path in orig_path_list:
542-
assert os.path.isfile(path)
543-
with open(path, mode="r") as f:
544-
assert f.read() == os.path.basename(path)
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Copyright(C) 2025 Red Hat, Inc.
2+
#
3+
# This program is free software: you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
# GitHub Copilot assisted in writing this file.
17+
18+
import pytest
19+
import six
20+
21+
from convert2rhel import pkghandler
22+
from convert2rhel.actions.pre_ponr_changes import yum_variables
23+
from convert2rhel.backup.files import RestorableFile
24+
25+
six.add_move(six.MovedModule("mock", "mock", "unittest.mock"))
26+
from six.moves import mock
27+
28+
29+
@pytest.mark.parametrize(
30+
"pkg_names, owned_files, expected_files",
31+
[
32+
(["pkg1"], ["/etc/yum/vars/pkg1_var"], ["/etc/yum/vars/pkg1_var"]),
33+
(["pkg1"], ["/etc/yum/vars/pkg1_var", "/other_file"], ["/etc/yum/vars/pkg1_var"]),
34+
(
35+
["pkg1", "pkg2"],
36+
["/etc/yum/vars/pkg1_var", "/etc/yum/vars/pkg2_var"],
37+
["/etc/yum/vars/pkg1_var", "/etc/yum/vars/pkg2_var"],
38+
),
39+
(["pkg1"], [], []),
40+
],
41+
)
42+
def test_get_yum_var_files_owned_by_pkgs(monkeypatch, pkg_names, owned_files, expected_files):
43+
action = yum_variables.BackUpYumVariables()
44+
45+
def mock_get_files_owned_by_package(pkg):
46+
return [file for file in owned_files if "/{}_".format(pkg) in file]
47+
48+
monkeypatch.setattr(
49+
"convert2rhel.actions.pre_ponr_changes.yum_variables.get_files_owned_by_package",
50+
mock_get_files_owned_by_package,
51+
)
52+
53+
result = action._get_yum_var_files_owned_by_pkgs(pkg_names)
54+
55+
assert set(result) == set(expected_files)
56+
57+
58+
@pytest.mark.parametrize(
59+
"paths, expected_push_calls, log_message",
60+
[
61+
([], 0, "No variable files to back up detected."),
62+
(
63+
["/etc/yum/vars/pkg1_var", "/etc/yum/vars/pkg2_var"],
64+
2,
65+
"Yum variables successfully backed up.",
66+
),
67+
],
68+
)
69+
def test_back_up_var_files(
70+
monkeypatch, paths, expected_push_calls, log_message, global_system_info, global_backup_control, caplog
71+
):
72+
action = yum_variables.BackUpYumVariables()
73+
global_system_info.name = "centos"
74+
monkeypatch.setattr(yum_variables, "system_info", global_system_info)
75+
monkeypatch.setattr(global_backup_control, "push", mock.Mock())
76+
77+
action._back_up_var_files(paths)
78+
79+
assert caplog.records[0].levelname == "INFO"
80+
assert caplog.records[0].message == (
81+
"Backing up yum variable files from {} owned by {} packages.".format(
82+
" and ".join(action.yum_var_dirs), "centos"
83+
)
84+
)
85+
86+
assert global_backup_control.push.call_count == expected_push_calls
87+
for path in paths:
88+
global_backup_control.push.assert_any_call(RestorableFile(path))
89+
90+
assert caplog.records[-1].levelname == "INFO"
91+
assert caplog.records[-1].message == log_message
92+
93+
94+
@pytest.mark.parametrize(
95+
"installed_pkgs, owned_files",
96+
[
97+
([], []),
98+
(
99+
["pkg1", "pkg2"],
100+
["/etc/yum/vars/pkg1_var", "/etc/yum/vars/pkg2_var"],
101+
),
102+
],
103+
)
104+
def test_run(monkeypatch, installed_pkgs, owned_files, global_system_info, caplog):
105+
action = yum_variables.BackUpYumVariables()
106+
action._back_up_var_files = mock.Mock()
107+
108+
global_system_info.repofile_pkgs = installed_pkgs
109+
monkeypatch.setattr(yum_variables, "system_info", global_system_info)
110+
111+
class MockObj:
112+
def __init__(self, name):
113+
self.name = name
114+
115+
mock_get_installed_pkg_objects = mock.Mock()
116+
mock_get_installed_pkg_objects.side_effect = lambda arg: [MockObj(pkg) for pkg in installed_pkgs if pkg == arg]
117+
monkeypatch.setattr(pkghandler, "get_installed_pkg_objects", mock_get_installed_pkg_objects)
118+
action._get_yum_var_files_owned_by_pkgs = mock.Mock()
119+
action._get_yum_var_files_owned_by_pkgs.return_value = owned_files
120+
121+
action.run()
122+
123+
assert caplog.records[0].is_task
124+
assert caplog.records[0].message == "Back up yum variables"
125+
assert "Getting a list of files owned by packages affecting variables in .repo files." in caplog.text
126+
assert "Packages affecting yum variables: {0}".format(", ".join(installed_pkgs)) in caplog.text
127+
action._back_up_var_files.assert_called_once_with(owned_files)

0 commit comments

Comments
 (0)