import os import tempfile import textwrap from contextlib import ExitStack from pathlib import Path from unittest.mock import patch import pytest from pkgcheck.addons.git import GitConfig from pkgcheck.cli import Tool from pkgcheck.reporters import StrReporter from pkgcheck.results import Result from pkgcheck.scripts import pkgcheck from pkgcore import const as pkgcore_const from snakeoil.cli.arghparse import ArgumentParser from snakeoil.contexts import os_environ from snakeoil.formatters import PlainTextFormatter from snakeoil.osutils import pjoin pytest_plugins = ["pkgcore"] REPO_ROOT = Path(__file__).parent.parent def pytest_configure(): # export repo root for test modules to use pytest.REPO_ROOT = REPO_ROOT def pytest_assertrepr_compare(op, left, right): """Custom assertion failure output.""" if isinstance(left, Result) and isinstance(right, Result) and op == "==": with tempfile.TemporaryFile() as f: with StrReporter(out=PlainTextFormatter(f)) as reporter: reporter.report(left) reporter.report(right) f.seek(0) left_val, right_val = f.read().decode().splitlines() return ["Result instances !=:", left_val, right_val] @pytest.fixture(scope="session", autouse=True) def default_session_fixture(request): """Fixture run globally for the entire test session.""" stack = ExitStack() # don't load the default system or user config files stack.enter_context(patch("pkgcheck.cli.ConfigFileParser.default_configs", ())) stack.enter_context(os_environ(**(git_config := GitConfig()).config_env)) def unpatch(): stack.close() git_config.close() request.addfinalizer(unpatch) @pytest.fixture(scope="session") def testconfig(tmp_path_factory): """Generate a portage config that sets the default repo to the bundled standalone repo. Also, repo entries for all the bundled test repos. """ config = tmp_path_factory.mktemp("testconfig") repos_conf = config / "repos.conf" stubrepo = pjoin(pkgcore_const.DATA_PATH, "stubrepo") testdir = REPO_ROOT / "testdata/repos" with open(repos_conf, "w") as f: f.write( textwrap.dedent( f"""\ [DEFAULT] main-repo = standalone [stubrepo] location = {stubrepo} """ ) ) for repo in testdir.iterdir(): f.write(f"[{repo.name}]\n") f.write(f"location = {repo}\n") profile_path = pjoin(stubrepo, "profiles", "default") os.symlink(profile_path, str(config / "make.profile")) return str(config) @pytest.fixture(scope="session") def cache_dir(tmp_path_factory): """Generate a cache directory for pkgcheck.""" cache_dir = tmp_path_factory.mktemp("cache") return str(cache_dir) @pytest.fixture def fakerepo(tmp_path_factory): """Generate a stub repo.""" fakerepo = tmp_path_factory.mktemp("fakerepo") (profiles := fakerepo / "profiles").mkdir(parents=True) (profiles / "repo_name").write_text("fakerepo\n") (metadata := fakerepo / "metadata").mkdir(parents=True) (metadata / "layout.conf").write_text("masters =\n") return fakerepo @pytest.fixture(scope="session") def tool(testconfig): """Generate a tool utility for running pkgcheck.""" tool = Tool(pkgcheck.argparser) tool.parser.set_defaults(config_path=testconfig) return tool @pytest.fixture def parser(): """Return a copy of the main pkgcheck argparser.""" return ArgumentParser(suppress=True, parents=(pkgcheck.argparser,))