enhance: Add comprehensive .gitignore for deb-mock project
- Add mock-specific build artifacts (chroot/, mock-*, mockroot/) - Include package build files (*.deb, *.changes, *.buildinfo) - Add development tools (.coverage, .pytest_cache, .tox) - Include system files (.DS_Store, Thumbs.db, ._*) - Add temporary and backup files (*.tmp, *.bak, *.backup) - Include local configuration overrides (config.local.yaml, .env.local) - Add test artifacts and documentation builds - Comprehensive coverage for Python build system project This ensures build artifacts, chroot environments, and development tools are properly ignored in version control.
This commit is contained in:
parent
1a559245ea
commit
4c0dcb2522
329 changed files with 27394 additions and 965 deletions
0
mock/tests/__init__.py
Normal file
0
mock/tests/__init__.py
Normal file
14
mock/tests/conftest.py
Normal file
14
mock/tests/conftest.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
"""Common pytest fixtures."""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
pytest_version_tuple = tuple(int(piece) for piece in pytest.__version__.split("."))
|
||||
if pytest_version_tuple < (3, 9):
|
||||
# Old versions of pytest don’t have the tmp_path fixture, fill it in here.
|
||||
from pathlib import Path
|
||||
|
||||
@pytest.fixture
|
||||
def tmp_path(tmpdir):
|
||||
"""Return temporary directory path object."""
|
||||
return Path(tmpdir)
|
||||
7
mock/tests/data/config-001/fedora-rawhide-x86_64.cfg
Normal file
7
mock/tests/data/config-001/fedora-rawhide-x86_64.cfg
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
include("templates/fedora-rawhide.tpl")
|
||||
|
||||
config_opts["target_arch"] = "x86_64"
|
||||
|
||||
config_opts["override_wins_conf"] = "conf"
|
||||
config_opts["override_wins_home_site"] = "conf"
|
||||
config_opts["override_wins_home_conf"] = "conf"
|
||||
7
mock/tests/data/config-001/site-defaults.cfg
Normal file
7
mock/tests/data/config-001/site-defaults.cfg
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
config_opts["default"] = True
|
||||
|
||||
config_opts["override_wins_site"] = "site"
|
||||
config_opts["override_wins_conf"] = "site"
|
||||
config_opts["override_wins_home_site"] = "site"
|
||||
config_opts["override_wins_home_conf"] = "site"
|
||||
config_opts["override_wins_template"] = "site"
|
||||
6
mock/tests/data/config-001/templates/fedora-rawhide.tpl
Normal file
6
mock/tests/data/config-001/templates/fedora-rawhide.tpl
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
config_opts["template"] = "templated_value"
|
||||
|
||||
config_opts["override_wins_conf"] = "template"
|
||||
config_opts["override_wins_home_site"] = "template"
|
||||
config_opts["override_wins_home_conf"] = "template"
|
||||
config_opts["override_wins_template"] = "template"
|
||||
8
mock/tests/data/home-001/.config/mock.cfg
Normal file
8
mock/tests/data/home-001/.config/mock.cfg
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
config_opts["home_default"] = (1, 2)
|
||||
|
||||
# A bit tricky. The order of evaluation is:
|
||||
# 1. site-defaults.cfg
|
||||
# 2. configuration file => fedora-rawhide-x86_64.cfg in HOME!
|
||||
# 3. configuration file included
|
||||
# 4. home mock.cfg
|
||||
config_opts["override_wins_home_site"] = "home_site"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
include("fedora-rawhide-x86_64.cfg")
|
||||
config_opts["home_override"] = "10"
|
||||
|
||||
config_opts["override_wins_home_conf"] = "home_conf"
|
||||
config_opts["override_wins_home_site"] = "home_conf"
|
||||
0
mock/tests/plugins/__init__.py
Normal file
0
mock/tests/plugins/__init__.py
Normal file
192
mock/tests/plugins/test_rpmautospec.py
Normal file
192
mock/tests/plugins/test_rpmautospec.py
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
"""Test the rpmautospec plugin."""
|
||||
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
from mockbuild.exception import ConfigError, PkgError
|
||||
from mockbuild.plugins import rpmautospec
|
||||
from mockbuild.util import nullcontext
|
||||
|
||||
UNSET = object()
|
||||
|
||||
|
||||
@mock.patch("mockbuild.plugins.rpmautospec.RpmautospecPlugin")
|
||||
def test_init(RpmautospecPlugin): # pylint: disable=invalid-name
|
||||
"""Test the function which registers the plugin."""
|
||||
plugins = object()
|
||||
conf = object()
|
||||
buildroot = object()
|
||||
|
||||
rpmautospec.init(plugins, conf, buildroot)
|
||||
|
||||
RpmautospecPlugin.assert_called_once_with(plugins, conf, buildroot)
|
||||
|
||||
|
||||
class TestRpmautospecPlugin:
|
||||
"""Test the RpmautospecPlugin class."""
|
||||
|
||||
DEFAULT_OPTS = {
|
||||
"requires": ["rpmautospec"],
|
||||
"cmd_base": ["rpmautospec", "process-distgit"],
|
||||
}
|
||||
|
||||
def create_plugin(self, plugins=UNSET, conf=UNSET, buildroot=UNSET):
|
||||
"""Create a plugin object and prepare it for testing."""
|
||||
if plugins is UNSET:
|
||||
plugins = mock.Mock()
|
||||
if conf is UNSET:
|
||||
conf = deepcopy(self.DEFAULT_OPTS)
|
||||
if buildroot is UNSET:
|
||||
buildroot = mock.Mock()
|
||||
|
||||
return rpmautospec.RpmautospecPlugin(plugins, conf, buildroot)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"with_cmd_base", (True, False), ids=("with-cmd_base", "without-cmd_base")
|
||||
)
|
||||
@mock.patch("mockbuild.plugins.rpmautospec.getLog")
|
||||
def test___init__(self, getLog, with_cmd_base):
|
||||
"""Test the constructor."""
|
||||
plugins = mock.Mock()
|
||||
|
||||
conf = deepcopy(self.DEFAULT_OPTS)
|
||||
if with_cmd_base:
|
||||
expectation = nullcontext()
|
||||
else:
|
||||
expectation = pytest.raises(ConfigError)
|
||||
del conf["cmd_base"]
|
||||
|
||||
buildroot = mock.Mock()
|
||||
|
||||
with expectation as exc_info:
|
||||
logger = getLog.return_value
|
||||
plugin = self.create_plugin(plugins=plugins, conf=conf, buildroot=buildroot)
|
||||
|
||||
if with_cmd_base:
|
||||
assert plugin.buildroot is buildroot
|
||||
assert plugin.config is buildroot.config
|
||||
assert plugin.opts is conf
|
||||
assert plugin.log is logger
|
||||
plugins.add_hook.assert_called_once_with("pre_srpm_build", plugin.attempt_process_distgit)
|
||||
logger.info.assert_called_once_with("rpmautospec: initialized")
|
||||
else:
|
||||
assert "rpmautospec_opts.cmd_base" in str(exc_info.value)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"testcase",
|
||||
(
|
||||
"happy-path",
|
||||
"happy-path-no-requires",
|
||||
"without-sources",
|
||||
"sources-not-dir",
|
||||
"sources-not-repo",
|
||||
"sources-no-specfile",
|
||||
"spec-files-different",
|
||||
"specfile-no-rpmautospec",
|
||||
"broken-requires",
|
||||
),
|
||||
)
|
||||
def test_attempt_process_distgit(
|
||||
self, testcase, tmp_path
|
||||
): # pylint: disable=too-many-branches disable=too-many-statements disable=too-many-locals
|
||||
"""Test the attempt_process_distgit() method."""
|
||||
# Set the stage
|
||||
plugin = self.create_plugin()
|
||||
plugin.log = log = mock.Mock()
|
||||
plugin.buildroot.make_chroot_path.return_value = str(tmp_path)
|
||||
if "no-requires" in testcase:
|
||||
plugin.opts["requires"] = []
|
||||
|
||||
spec_dir = tmp_path / "SPECS"
|
||||
spec_dir.mkdir()
|
||||
sources_dir = tmp_path / "SOURCES"
|
||||
sources_dir.mkdir()
|
||||
|
||||
host_chroot_spec = spec_dir / "pkg.spec"
|
||||
host_chroot_sources = sources_dir / "pkg"
|
||||
host_chroot_sources.mkdir()
|
||||
host_chroot_sources_git = host_chroot_sources / ".git"
|
||||
host_chroot_sources_spec = host_chroot_sources / "pkg.spec"
|
||||
|
||||
if "no-rpmautospec" not in testcase:
|
||||
spec_contents = (
|
||||
"Release: %autorelease",
|
||||
"%changelog",
|
||||
"%autochangelog",
|
||||
)
|
||||
else:
|
||||
spec_contents = (
|
||||
"Release: 1",
|
||||
"%changelog",
|
||||
)
|
||||
|
||||
with host_chroot_spec.open("w") as fp:
|
||||
for line in spec_contents:
|
||||
print(line, file=fp)
|
||||
|
||||
if "without-sources" in testcase:
|
||||
host_chroot_sources = None
|
||||
elif "sources-not-dir" not in testcase:
|
||||
if "sources-no-specfile" not in testcase:
|
||||
with host_chroot_sources_spec.open("w") as fp:
|
||||
if "spec-files-different" in testcase:
|
||||
print("# BOO", file=fp)
|
||||
for line in spec_contents:
|
||||
print(line, file=fp)
|
||||
if "sources-not-repo" not in testcase:
|
||||
host_chroot_sources_git.mkdir()
|
||||
else:
|
||||
host_chroot_sources = tmp_path / "pkg.tar"
|
||||
host_chroot_sources.touch()
|
||||
|
||||
if "broken-requires" in testcase:
|
||||
plugin.buildroot.install_as_root.side_effect = RuntimeError("FAIL")
|
||||
expect_exception = pytest.raises(PkgError)
|
||||
else:
|
||||
expect_exception = nullcontext()
|
||||
|
||||
with expect_exception as excinfo:
|
||||
plugin.attempt_process_distgit(host_chroot_spec, host_chroot_sources)
|
||||
|
||||
if "happy-path" in testcase:
|
||||
chroot_spec = Path("/") / host_chroot_spec.relative_to(tmp_path)
|
||||
chroot_sources = Path("/") / host_chroot_sources.relative_to(tmp_path)
|
||||
chroot_sources_spec = Path("/") / host_chroot_sources_spec.relative_to(tmp_path)
|
||||
|
||||
expected_command = plugin.opts["cmd_base"] + [chroot_sources_spec, chroot_spec]
|
||||
|
||||
plugin.buildroot.doChrootPlugin.assert_called_once_with(
|
||||
expected_command,
|
||||
cwd=chroot_sources,
|
||||
)
|
||||
else:
|
||||
plugin.buildroot.doChrootPlugin.assert_not_called()
|
||||
if "broken-requires" not in testcase:
|
||||
if "spec-files-different" in testcase:
|
||||
log_method = log.warning
|
||||
else:
|
||||
log_method = log.debug
|
||||
log_method.assert_called_once()
|
||||
log_string = log_method.call_args[0][0]
|
||||
assert "skipping rpmautospec preprocessing" in log_string
|
||||
|
||||
if "without-sources" in testcase:
|
||||
assert "Sources not specified" in log_string
|
||||
elif "sources-not-dir" in testcase:
|
||||
assert "Sources not a directory" in log_string
|
||||
elif "sources-not-repo" in testcase:
|
||||
assert "Sources is not a git repository" in log_string
|
||||
elif "sources-no-specfile" in testcase:
|
||||
assert "Sources doesn’t contain spec file" in log_string
|
||||
elif "spec-files-different" in testcase:
|
||||
assert "Spec file inside and outside sources are different" in log_string
|
||||
elif "specfile-no-rpmautospec" in testcase:
|
||||
assert "Spec file doesn’t use rpmautospec" in log_string
|
||||
else:
|
||||
assert str(excinfo.value) == (
|
||||
"Can’t install rpmautospec dependencies into chroot: "
|
||||
+ ", ".join(self.DEFAULT_OPTS["requires"])
|
||||
)
|
||||
24
mock/tests/test_buildroot.py
Normal file
24
mock/tests/test_buildroot.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
""" Tests for buildroot.py """
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
from mockbuild import util, buildroot
|
||||
|
||||
|
||||
def test_module_config():
|
||||
""" test _module_commands_from_config method """
|
||||
def _check(config, output):
|
||||
assert buildroot.Buildroot._module_commands_from_config(config) \
|
||||
== output
|
||||
_check([("enable", "module:stream")],
|
||||
[["module", "enable", "module:stream"]])
|
||||
_check([("enable", "module:stream, module2:stream2")],
|
||||
[["module", "enable", "module:stream", "module2:stream2"]])
|
||||
_check([("disable", "module:*,module2:*"),
|
||||
("enable", "module:stream, module2:stream2"),
|
||||
("install", "pg:12")],
|
||||
[["module", "disable", "module:*", "module2:*"],
|
||||
["module", "enable", "module:stream", "module2:stream2"],
|
||||
["module", "install", "pg:12"]])
|
||||
|
||||
_check([("info", "")], [["module", "info"]])
|
||||
_check([("info", None)], [["module", "info"]])
|
||||
162
mock/tests/test_buildroot_lock.py
Normal file
162
mock/tests/test_buildroot_lock.py
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
"""
|
||||
Test the methods that generate buildroot_lock.json
|
||||
"""
|
||||
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
import jsonschema
|
||||
|
||||
from mockbuild.plugins.buildroot_lock import init
|
||||
import mockbuild.exception
|
||||
|
||||
# gpg-pubkey packages stay ignored
|
||||
# fedora-release is normal package with simple license
|
||||
RPM_OUTPUT = """\
|
||||
gpg-pubkey|/@(none)|/@pubkey|/@105ef944|/@65ca83d1|/@(none)|/@(none)|/@(none)
|
||||
gpg-pubkey|/@(none)|/@pubkey|/@e99d6ad1|/@64d2612c|/@(none)|/@(none)|/@(none)
|
||||
fedora-release|/@noarch|/@MIT|/@42|/@0.3|/@(none)|/@cf31d87e5e3eac97ff32a98e7e073f37|/@(none)
|
||||
bash|/@x86_64|/@GPLv3+|/@5.1.8|/@9.el9|/@(none)|/@57e93b1739cc3512f9f29dcaa8a38055|/@RSA/SHA256, Sun Mar 31 12:41:20 2024, Key ID 199e2f91fd431d51
|
||||
""" # noqa: E501
|
||||
|
||||
# cyrus-sasl-lib is not present in the REPOQUERY_OUTPUT
|
||||
RPM_ONLY_RPM = """\
|
||||
cyrus-sasl-lib|/@x86_64|/@BSD with advertising|/@2.1.27|/@21.el9|/@(none)|/@9e1caba09fac94568419b9dfd14fb4c5|/@RSA/SHA256, Mon Sep 12 23:24:22 2022, Key ID 199e2f91fd431d51
|
||||
""" # noqa: E501
|
||||
|
||||
REPOQUERY_OUTPUT = """\
|
||||
http://ftp.fi.muni.cz/pub/linux/fedora/linux/development/rawhide/Everything/x86_64/os/Packages/f/fedora-release-42-0.3.noarch.rpm
|
||||
https://cdn.redhat.com/content/dist/rhel9/9/x86_64/baseos/os/Packages/b/bash-5.1.8-9.el9.x86_64.rpm
|
||||
"""
|
||||
|
||||
EXPECTED_OUTPUT = {
|
||||
'version': '1.1.0',
|
||||
'buildroot': {
|
||||
'rpms': [{
|
||||
'arch': 'x86_64',
|
||||
'epoch': None,
|
||||
'license': 'GPLv3+',
|
||||
'name': 'bash',
|
||||
'release': '9.el9',
|
||||
'sigmd5': '57e93b1739cc3512f9f29dcaa8a38055',
|
||||
'signature': 'fd431d51',
|
||||
'url': 'https://cdn.redhat.com/content/dist/rhel9/9/x86_64'
|
||||
'/baseos/os/Packages/b/bash-5.1.8-9.el9.x86_64.rpm',
|
||||
'version': '5.1.8'
|
||||
}, {
|
||||
'arch': 'noarch',
|
||||
'epoch': None,
|
||||
'license': 'MIT',
|
||||
'name': 'fedora-release',
|
||||
'release': '0.3',
|
||||
'sigmd5': 'cf31d87e5e3eac97ff32a98e7e073f37',
|
||||
'signature': None,
|
||||
'url': 'http://ftp.fi.muni.cz/pub/linux/fedora/linux'
|
||||
'/development/rawhide/Everything/x86_64/os'
|
||||
'/Packages/f/fedora-release-42-0.3.noarch.rpm',
|
||||
'version': '42',
|
||||
}]
|
||||
},
|
||||
"bootstrap": {
|
||||
"image_digest": "sha256:ba1067bef190fbe88f085bd019464a8c0803b7cd1e3f",
|
||||
"pull_digest": "sha256:1d9f0eaec60b59a669b285d1e775d970061b9694d4998b5bdb9626c9f33685cd",
|
||||
"id": "b222730c2ba32385173fe3351026c316c9a294fa8d8c3c0f80d8afdb1b1aeef7",
|
||||
"architecture": "amd64",
|
||||
},
|
||||
'config': {
|
||||
'bootstrap_image': 'foo',
|
||||
'bootstrap_image_ready': True,
|
||||
"legal_host_arches": ["x86_64"],
|
||||
"target_arch": "x86_64",
|
||||
"dist": ".f42",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _exp_output_bootstrap(exp_data):
|
||||
data = copy.deepcopy(exp_data["bootstrap"])
|
||||
del data["image_digest"]
|
||||
return data
|
||||
|
||||
|
||||
def _mock_vars(rpm_out, repoquery_out):
|
||||
tc = TestCase()
|
||||
tc.maxDiff = None
|
||||
buildroot = MagicMock()
|
||||
buildroot.state = MagicMock()
|
||||
buildroot.uid_manager = MagicMock()
|
||||
buildroot.doOutChroot = MagicMock(
|
||||
side_effect=iter([
|
||||
(rpm_out, None),
|
||||
(repoquery_out, None),
|
||||
])
|
||||
)
|
||||
buildroot.config = EXPECTED_OUTPUT['config']
|
||||
buildroot.resultdir = tempfile.mkdtemp(prefix="mock-test-buildroot-lock")
|
||||
plugins = MagicMock()
|
||||
plugins.add_hook = MagicMock()
|
||||
return tc, buildroot, plugins
|
||||
|
||||
|
||||
def _call_method(plugins, buildroot):
|
||||
# initialize the plugin
|
||||
init(plugins, {}, buildroot)
|
||||
# obtain the hook method, and call it
|
||||
plugins.add_hook.assert_called_once()
|
||||
_, method = plugins.add_hook.call_args[0]
|
||||
|
||||
podman_obj = MagicMock()
|
||||
podman_obj.get_oci_digest.return_value = EXPECTED_OUTPUT["bootstrap"]["image_digest"]
|
||||
podman_obj.inspect_hermetic_metadata.return_value = _exp_output_bootstrap(EXPECTED_OUTPUT)
|
||||
podman_cls = MagicMock(return_value=podman_obj)
|
||||
with patch("mockbuild.plugins.buildroot_lock.Podman", side_effect=podman_cls):
|
||||
method()
|
||||
|
||||
|
||||
def test_nonexisting_file_in_repo():
|
||||
"""
|
||||
Test the situation when RPM is installed, and no longer available in
|
||||
repository.
|
||||
"""
|
||||
_, buildroot, plugins = _mock_vars(
|
||||
RPM_OUTPUT + RPM_ONLY_RPM,
|
||||
REPOQUERY_OUTPUT,
|
||||
)
|
||||
raised = False
|
||||
try:
|
||||
_call_method(plugins, buildroot)
|
||||
except mockbuild.exception.Error as e:
|
||||
assert e.msg == "Can't get location for cyrus-sasl-lib-2.1.27-21.el9.x86_64"
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
|
||||
def _get_json_schema():
|
||||
testdir = os.path.dirname(__file__)
|
||||
basename = "buildroot-lock-schema-" + EXPECTED_OUTPUT["version"] + ".json"
|
||||
with open(os.path.join(testdir, "..", "docs", basename),
|
||||
"r", encoding="utf-8") as fd:
|
||||
return json.load(fd)
|
||||
|
||||
|
||||
def test_buildroot_lock_output():
|
||||
""" test the buildroot_lock.json file format """
|
||||
tc, buildroot, plugins = _mock_vars(RPM_OUTPUT, REPOQUERY_OUTPUT)
|
||||
_call_method(plugins, buildroot)
|
||||
with open(os.path.join(buildroot.resultdir, "buildroot_lock.json"), "r",
|
||||
encoding="utf-8") as fd:
|
||||
data = json.load(fd)
|
||||
tc.assertDictEqual(data, EXPECTED_OUTPUT)
|
||||
schema = _get_json_schema()
|
||||
jsonschema.validate(EXPECTED_OUTPUT, schema)
|
||||
|
||||
|
||||
def test_json_schema_metadata():
|
||||
""" Test basic format of the json schema """
|
||||
schema = _get_json_schema()
|
||||
version = EXPECTED_OUTPUT["version"]
|
||||
assert "Version " + version + ";" in schema["description"]
|
||||
assert "schema-" + version + ".json" in schema["$id"]
|
||||
52
mock/tests/test_config_loader.py
Normal file
52
mock/tests/test_config_loader.py
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
"""
|
||||
Tests for mockbuild.config
|
||||
"""
|
||||
|
||||
# pylint: disable=missing-class-docstring
|
||||
# pylint: disable=missing-function-docstring
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
|
||||
import pwd
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from unittest import mock
|
||||
from mockbuild.config import simple_load_config
|
||||
|
||||
|
||||
class TestConfigLoader:
|
||||
def setup_method(self):
|
||||
testdir = os.path.dirname(os.path.realpath(__file__))
|
||||
self.configdir = os.path.join(testdir, "data", "config-001")
|
||||
self.homedir = tempfile.mkdtemp(prefix='mock-test-home')
|
||||
homedata = os.path.join(testdir, "data", "home-001")
|
||||
self.username = pwd.getpwuid(os.getuid())[0]
|
||||
userdir = os.path.join(self.homedir, self.username)
|
||||
shutil.copytree(homedata, userdir)
|
||||
|
||||
def test_config_paths(self):
|
||||
with mock.patch("mockbuild.config.os.path.expanduser") as patch:
|
||||
patch.side_effect = lambda x: x.replace("~", self.homedir + "/")
|
||||
config = simple_load_config('fedora-rawhide-x86_64', self.configdir)
|
||||
assert set(config["config_paths"]) == {
|
||||
os.path.join(self.configdir, "site-defaults.cfg"),
|
||||
os.path.join(self.configdir, "fedora-rawhide-x86_64.cfg"),
|
||||
os.path.join(self.configdir, "templates", "fedora-rawhide.tpl"),
|
||||
os.path.join(self.homedir, self.username, ".config", "mock.cfg"),
|
||||
os.path.join(self.homedir, self.username, ".config", "mock", "fedora-rawhide-x86_64.cfg"),
|
||||
}
|
||||
|
||||
assert config["default"] is True
|
||||
assert config["target_arch"] == 'x86_64'
|
||||
assert config["template"] == "templated_value"
|
||||
assert config["home_default"] == (1, 2)
|
||||
|
||||
assert config["override_wins_site"] == "site"
|
||||
assert config["override_wins_conf"] == "conf"
|
||||
assert config["override_wins_home_site"] == "home_site"
|
||||
assert config["override_wins_home_conf"] == "home_conf"
|
||||
assert config["override_wins_template"] == "template"
|
||||
|
||||
def teardown_method(self):
|
||||
shutil.rmtree(self.homedir)
|
||||
127
mock/tests/test_config_templates.py
Normal file
127
mock/tests/test_config_templates.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import pytest
|
||||
from templated_dictionary import TemplatedDictionary
|
||||
|
||||
|
||||
def test_transitive_expand():
|
||||
config = TemplatedDictionary()
|
||||
config['a'] = 'test'
|
||||
config['b'] = '{{ a }} {{ a }}'
|
||||
config['c'] = '{{ b + " " + b }}'
|
||||
assert config['c'] == '{{ b + " " + b }}'
|
||||
config['__jinja_expand'] = True
|
||||
assert config['c'] == 'test test test test'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('setup', [
|
||||
# host target bootstrap expected_repo
|
||||
('x86_64', 'arm7hl', True, 'x86_64'),
|
||||
('x86_64', 'arm7hl', False, 'armhfp'),
|
||||
('ppc64le', 'arm7hl', True, 'ppc64le'),
|
||||
('ppc64le', 'arm7hl', False, 'armhfp'),
|
||||
])
|
||||
def test_nested_access(setup):
|
||||
"""
|
||||
Check that we can access config_opts["foo"]["bar"] items in jinja.
|
||||
"""
|
||||
host, target, bootstrap, result = setup
|
||||
config = TemplatedDictionary()
|
||||
config["archmap"] = {"i386": "i686", "arm7hl": "armhfp", "x86_64": "x86_64"}
|
||||
config["host_arch"] = host
|
||||
config["target_arch"] = target
|
||||
config["root"] = "foo-bootstrap" if bootstrap else "foo"
|
||||
config["repo_arch"] = (
|
||||
"{% set desired = host_arch if root.endswith('bootstrap') else target_arch %}"
|
||||
"{{ archmap[desired] if desired in archmap else desired }}"
|
||||
)
|
||||
config['__jinja_expand'] = True
|
||||
assert config['repo_arch'] == result
|
||||
|
||||
|
||||
def test_aliases():
|
||||
config = TemplatedDictionary(
|
||||
alias_spec={
|
||||
'dnf.conf': ['yum.conf', 'package_manager.conf'],
|
||||
},
|
||||
)
|
||||
|
||||
config['dnf.conf'] = "initial"
|
||||
config['yum.conf'] += " appended"
|
||||
|
||||
config['__jinja_expand'] = True
|
||||
assert config['package_manager.conf'] == "initial appended"
|
||||
config['__jinja_expand'] = False
|
||||
|
||||
config['package_manager.conf'] = "replaced"
|
||||
|
||||
config['__jinja_expand'] = True
|
||||
assert config['dnf.conf'] == config['yum.conf'] == 'replaced'
|
||||
|
||||
config['variable'] = "content"
|
||||
config['package_manager.conf'] += " {{ variable }}"
|
||||
|
||||
assert config['dnf.conf'] == config['yum.conf'] == 'replaced content'
|
||||
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_that_access_doesnt_affect_value():
|
||||
config = TemplatedDictionary()
|
||||
config['a'] = {}
|
||||
config['a']['b'] = '{{ b }}'
|
||||
config['__jinja_expand'] = True
|
||||
|
||||
# access it, and and destroy 'a' (shouldn't happen)
|
||||
assert '' == config['a']['b']
|
||||
|
||||
# we set b, but it is not propagated to a.b because a.b was already
|
||||
# accessed - and that rewrote a.b to ''. So even after setting b properly,
|
||||
# a.b stays empty.
|
||||
config['b'] = 'b'
|
||||
assert 'b' == config['a']['b']
|
||||
|
||||
|
||||
def test_not_detected_recursion():
|
||||
config = TemplatedDictionary()
|
||||
config['a'] = '{{ a }}'
|
||||
config['b'] = '{{ a }}'
|
||||
config['__jinja_expand'] = True
|
||||
|
||||
# TODO: should this throw exception? We might hypotetically use this
|
||||
# "problem" to assure that some values are unexpanded.
|
||||
assert config['a'] == '{{ a }}'
|
||||
assert config['b'] == '{{ a }}'
|
||||
|
||||
|
||||
def test_too_deep_recursion():
|
||||
config = TemplatedDictionary()
|
||||
config['a'] = '{{ b }}'
|
||||
config['b'] = '[ {{ a }} ]'
|
||||
config['__jinja_expand'] = True
|
||||
with pytest.raises(ValueError):
|
||||
# infinite recursion
|
||||
config['a']
|
||||
|
||||
config = TemplatedDictionary()
|
||||
config['a'] = '{{ b }}'
|
||||
config['b'] = '{{ c }}'
|
||||
config['c'] = '{{ d }}'
|
||||
config['d'] = '{{ e }}'
|
||||
config['e'] = '{{ f }}'
|
||||
config['f'] = 'f'
|
||||
config['g'] = 11
|
||||
config['__jinja_expand'] = True
|
||||
|
||||
# this is not yet too deep
|
||||
assert config['b'] == 'f'
|
||||
|
||||
# but this is too deep
|
||||
with pytest.raises(ValueError):
|
||||
config['a']
|
||||
|
||||
|
||||
def test_many_newlines():
|
||||
# rhbz#1806482
|
||||
config = TemplatedDictionary()
|
||||
string = "\n\n\n\n\n\na\n\n\n\n\n\n"
|
||||
config['a'] = string
|
||||
config['__jinja_expand'] = True
|
||||
assert config['a'] == string
|
||||
14
mock/tests/test_installed_packages.py
Normal file
14
mock/tests/test_installed_packages.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
"""
|
||||
Test the "installed_packages.py" file
|
||||
"""
|
||||
|
||||
from mockbuild.installed_packages import _subprocess_executor
|
||||
|
||||
|
||||
def test_the_default_executor():
|
||||
"""
|
||||
The expected executor output is just stderr
|
||||
"""
|
||||
assert "stdout\n" == _subprocess_executor([
|
||||
"/bin/sh", "-c", "echo stdout ; echo >&2 stderr"
|
||||
])
|
||||
192
mock/tests/test_package_manager.py
Normal file
192
mock/tests/test_package_manager.py
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
import pytest
|
||||
from unittest import mock
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from templated_dictionary import TemplatedDictionary
|
||||
from mockbuild.config import setup_default_config_opts
|
||||
from mockbuild.constants import PKGPYTHONDIR
|
||||
from mockbuild.buildroot import Buildroot
|
||||
from mockbuild.package_manager import _PackageManager
|
||||
|
||||
|
||||
class TestPackageManager:
|
||||
|
||||
def setup_method(self, method):
|
||||
self.workdir = tempfile.mkdtemp(prefix='mock-test')
|
||||
|
||||
testdir = os.path.dirname(os.path.realpath(__file__))
|
||||
plugindir = os.path.join(testdir, '..', 'py', 'mockbuild')
|
||||
plugindir = os.path.realpath(plugindir)
|
||||
PKGPYTHONDIR = plugindir
|
||||
|
||||
self.config_opts = setup_default_config_opts()
|
||||
self.config_opts['root'] = 'distro-version-arch'
|
||||
self.config_opts['basedir'] = self.workdir
|
||||
self.config_opts["resultdir"] = "{{basedir}}/{{root}}/result"
|
||||
self.config_opts['chroothome'] = '/builddir'
|
||||
self.config_opts['chrootgid'] = '135'
|
||||
self.config_opts['package_manager'] = 'dnf'
|
||||
self.config_opts['releasever'] = '1'
|
||||
self.config_opts['target_arch'] = 'fakearch'
|
||||
self.config_opts['dnf_vars'] = {'test': 'testval'}
|
||||
|
||||
with mock.patch('mockbuild.buildroot.package_manager'):
|
||||
with mock.patch('mockbuild.util.cmpKernelVer') as kv:
|
||||
kv.return_value = True
|
||||
self.bootstrap_buildroot = Buildroot(
|
||||
self.config_opts.copy(),
|
||||
None, # state
|
||||
MagicMock(), # state
|
||||
MagicMock(), # plugins
|
||||
None, # bootstrap_buildroot
|
||||
True, # is_bootstrap
|
||||
)
|
||||
|
||||
self.buildroot = Buildroot(
|
||||
self.config_opts,
|
||||
None, # uidManager
|
||||
MagicMock(), # state
|
||||
MagicMock(), # plugins
|
||||
self.bootstrap_buildroot,
|
||||
False, # is_bootstrap
|
||||
)
|
||||
|
||||
self.package_manager = _PackageManager(
|
||||
self.buildroot.config,
|
||||
self.buildroot,
|
||||
self.buildroot.plugins,
|
||||
self.bootstrap_buildroot,
|
||||
)
|
||||
|
||||
self.package_manager_bootstrap = _PackageManager(
|
||||
self.bootstrap_buildroot.config,
|
||||
self.bootstrap_buildroot,
|
||||
self.bootstrap_buildroot.plugins,
|
||||
self.buildroot.plugins,
|
||||
)
|
||||
|
||||
def teardown_method(self, method):
|
||||
shutil.rmtree(self.workdir)
|
||||
|
||||
def get_user_bind_mounts_from_config(self, config):
|
||||
pm = self.package_manager_bootstrap
|
||||
pm.pkg_manager_config = config
|
||||
pm.initialize_config()
|
||||
pm._bind_mount_repos_to_bootstrap()
|
||||
return self.bootstrap_buildroot.mounts.managed_mounts
|
||||
|
||||
def test_absolute_path_name_in_baseurl(self):
|
||||
repo_directory = os.path.join(self.workdir, 'repo')
|
||||
os.mkdir(repo_directory)
|
||||
config = """
|
||||
[main]
|
||||
something = 1
|
||||
|
||||
[external]
|
||||
baseurl = http://exmaple.com/test/
|
||||
|
||||
[external-urlencoded]
|
||||
baseurl = http://example.com/results/%40fedora-llvm-team/
|
||||
|
||||
[fedora]
|
||||
baseurl = {}
|
||||
""".format(repo_directory)
|
||||
mounts = self.get_user_bind_mounts_from_config(config)
|
||||
assert len(mounts) == 1
|
||||
assert mounts[0].srcpath == repo_directory
|
||||
assert mounts[0].bindpath.startswith(self.workdir)
|
||||
assert mounts[0].bindpath.endswith(repo_directory)
|
||||
|
||||
def test_file_colon_slash_path_name_in_baseurl(self):
|
||||
repo_directory = os.path.join(self.workdir, 'repo')
|
||||
os.mkdir(repo_directory)
|
||||
config = """
|
||||
[main]
|
||||
something = 1
|
||||
|
||||
[fedora]
|
||||
baseurl = file://{}
|
||||
""".format(repo_directory)
|
||||
mounts = self.get_user_bind_mounts_from_config(config)
|
||||
assert len(mounts) == 1
|
||||
assert mounts[0].srcpath == repo_directory
|
||||
assert mounts[0].bindpath.startswith(self.workdir)
|
||||
assert mounts[0].bindpath.endswith(repo_directory)
|
||||
|
||||
def test_dir_doesnt_exist(self):
|
||||
repo_directory = os.path.join(self.workdir, 'repo')
|
||||
config = """
|
||||
[main]
|
||||
something = 1
|
||||
|
||||
[fedora]
|
||||
baseurl = file://{}
|
||||
""".format(repo_directory)
|
||||
mounts = self.get_user_bind_mounts_from_config(config)
|
||||
assert len(mounts) == 0
|
||||
|
||||
@pytest.mark.parametrize('option', ['metalink', 'mirrorlist'])
|
||||
@pytest.mark.parametrize('exists', [True, False])
|
||||
def test_local_metalink_mirrorlist(self, option, exists):
|
||||
repo_directory = os.path.join(self.workdir, 'repo')
|
||||
os.mkdir(repo_directory)
|
||||
path = os.path.join(repo_directory, 'testfile')
|
||||
|
||||
if exists:
|
||||
with open(path, 'w') as f:
|
||||
f.write("line\n")
|
||||
|
||||
config = """
|
||||
[main]
|
||||
metalink = file://{}
|
||||
""".format(path)
|
||||
mounts = self.get_user_bind_mounts_from_config(config)
|
||||
|
||||
if not exists:
|
||||
assert len(mounts) == 0
|
||||
return
|
||||
|
||||
assert len(mounts) == 1
|
||||
assert mounts[0].srcpath == path
|
||||
assert mounts[0].bindpath.startswith(self.workdir)
|
||||
assert mounts[0].bindpath.endswith(path)
|
||||
|
||||
def test_bindmount_baseurl_list_with_dupes(self):
|
||||
for repo in ['alt1', 'alt2', 'alt3']:
|
||||
repo_directory = os.path.join(self.workdir, repo)
|
||||
os.mkdir(repo_directory)
|
||||
|
||||
config = (
|
||||
"[main]\n"
|
||||
"baseurl = file://{0}/alt2, {0}/alt1\n"
|
||||
" file://{0}/alt3\n"
|
||||
" file://{0}/alt2\n" # 2nd time
|
||||
).format(self.workdir)
|
||||
|
||||
mounts = self.get_user_bind_mounts_from_config(config)
|
||||
assert len(mounts) == 3
|
||||
assert {x.srcpath for x in mounts} == set([
|
||||
os.path.join(self.workdir, 'alt1'),
|
||||
os.path.join(self.workdir, 'alt2'),
|
||||
os.path.join(self.workdir, 'alt3'),
|
||||
])
|
||||
|
||||
def test_bindmount_expand_vars(self):
|
||||
repo_directory = os.path.join(self.workdir,
|
||||
self.config_opts['target_arch'],
|
||||
self.config_opts['releasever'],
|
||||
self.config_opts['dnf_vars']['test'])
|
||||
os.makedirs(repo_directory)
|
||||
config = (
|
||||
"[main]\n"
|
||||
"baseurl = file://{0}/$basearch/${{releasever}}/$test\n"
|
||||
).format(self.workdir)
|
||||
|
||||
mounts = self.get_user_bind_mounts_from_config(config)
|
||||
assert len(mounts) == 1
|
||||
mount = mounts[0]
|
||||
assert mount.srcpath == repo_directory
|
||||
Loading…
Add table
Add a link
Reference in a new issue