# -*- coding: utf-8 -*- # SPDX-License-Identifier: MIT import os import sys import tempfile import pytest import sh import yaml import utils our_sh = sh(_out=sys.stdout, _err=sys.stderr, _tee=True) from our_sh import pushd, Command # noqa @pytest.fixture(scope="session") def test_env(): """Load test environment configuration :return: Test environment configuration. :rtype: dict """ config_file = os.getenv("MBS_TEST_CONFIG", "test.env.yaml") with open(config_file) as f: env = yaml.safe_load(f) return env @pytest.fixture(scope="session") def pkg_util(test_env): """Fixture to interact with the packaging utility :return: Packaging utility configured for the tests :rtype: utils.PackagingUtility """ return utils.PackagingUtility(test_env["packaging_utility"], test_env["mbs_api"]) @pytest.fixture(scope="function") def scenario(request, test_env): """Configuration data for the scenario Find out the name of the scenario (anything that follows "test_"), and return the corresponding configuration. This is a convenience fixture to serve as a shortcut to access scenario configuration. """ scenario_name = request.function.__name__.split("test_", 1)[1] scenario = test_env["testdata"].get(scenario_name) if not scenario: pytest.skip("No test scenario in 'test.env' for: {}".format(request.function.__name__)) return scenario @pytest.fixture(scope="function") def repo(scenario, test_env): """Clone the module repo to be used by the scenario 1) Get the module repo from the scenario configuration. 2) Clone the repo in a temporary location and switch the current working directory into it. :param pytest.fixture scenario: test scenario fixture :param pytest.fixture test_env: test environment fixture :return: repository object the tests can work with :rtype: utils.Repo """ module = scenario["module"] branch = scenario["branch"] with tempfile.TemporaryDirectory() as tempdir: pkg_util = utils.PackagingUtility(test_env["packaging_utility"], None) # no need for MBS pkg_util.clone("--branch", branch, f"modules/{module}", tempdir) with pushd(tempdir): yield utils.Repo(module, branch) @pytest.fixture(scope="function") def koji(test_env): """Koji session for the instance MBS is configured to work with.""" return utils.Koji(**test_env["koji"]) @pytest.fixture(scope="function") def mbs(test_env): """MBS instance session.""" return utils.MBS(test_env["mbs_api"]) @pytest.fixture(scope="function") def clone_and_start_build(repo, pkg_util): """Shortcut for tests that need a running build/s. Auto clean-up. :return: repo and list of submitted builds :rtype utils.Repo, list: """ repo.bump() _builds = [] _cancel = True def _build(*args, cancel=True, **kwargs): nonlocal _builds, _cancel options = [str(i) for i in args] builds = pkg_util.run(*options, **kwargs) if not builds: raise AssertionError(f"Packaging utility args={options} did not produce any builds") _builds, _cancel = (builds, cancel) return repo, builds yield _build if _cancel: for build in _builds: pkg_util.cancel(build, ignore_errors=True) @pytest.fixture(scope="function") def require_koji_resolver(repo, scenario, test_env, mbs): """Check that koji resolver is present.""" stream = repo.modulemd['data']['dependencies'][0]['buildrequires']['platform'] platform_build = mbs.get_module_builds(name="platform", stream=stream)[0] resolver = platform_build.get_modulemd()['data']['xmd']['mbs']\ .get('koji_tag_with_modules') if not resolver: pytest.skip('koji resolver is not configured.')