diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index a2b81f69..9fefa287 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -84,6 +84,11 @@ def repo(scenario, test_env): @pytest.fixture(scope="session") def koji(test_env): - """Koji session for the instance MBS is configured to work with - """ + """Koji session for the instance MBS is configured to work with.""" return utils.Koji(**test_env["koji"]) + + +@pytest.fixture(scope="session") +def mbs(test_env): + """MBS instance session.""" + return utils.MBS(test_env["mbs_api"]) diff --git a/tests/integration/example.test.env.yaml b/tests/integration/example.test.env.yaml index d9733361..b54ec051 100644 --- a/tests/integration/example.test.env.yaml +++ b/tests/integration/example.test.env.yaml @@ -42,6 +42,15 @@ testdata: buildorder: [{"module-build-macros"}, {"attr"}, {"acl"}] # True if buildrequire a Platform stream representing a GA RHEL release platform_is_ga: true + normal_build_conflict: + build_id: 1944 + # Name of the package that will cause a conflict in a buildroot. + conflicting_package: logrotate + module: testmodule2 + branch: test-conflicting-component + buildrequires: + module: testmodule + branch: test-stream-with-logrotate resume_cancelled_build: # This scenario doesn't support reusing past builds. "build_id" is not used. module: testmodule diff --git a/tests/integration/test_normal_build_conflict.py b/tests/integration/test_normal_build_conflict.py new file mode 100644 index 00000000..e4f967f5 --- /dev/null +++ b/tests/integration/test_normal_build_conflict.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# SPDX-License-Identifier: MIT + + +def test_normal_build_conflict(pkg_util, scenario, repo, koji, mbs): + """Build module which contains conflict component in buildroot. + + Checks: + * Verify that component contains conflict package + * Verify that build.log contains info about conflict. + """ + conflicting_build = mbs.get_builds(module=scenario["buildrequires"]["module"], + stream=scenario["buildrequires"]["branch"], + order_desc_by='version') + components = conflicting_build[0].component_names() + error_msg = "Stream does not contain expected package." + assert scenario["conflicting_package"] in \ + components, error_msg + + repo.bump() + builds = pkg_util.run( + "--optional", + "rebuild_strategy=all", + reuse=scenario.get("build_id"), + ) + pkg_util.watch(builds) + build = builds[0] + buildlog = koji.get_build_log(build.components()[0], "build.log") + error_msg = "Conflict package was not found in build.log" + assert f"Conflicts: {scenario['conflicting_package']}" in buildlog, error_msg diff --git a/tests/integration/utils.py b/tests/integration/utils.py index fd81956c..96860adb 100644 --- a/tests/integration/utils.py +++ b/tests/integration/utils.py @@ -53,6 +53,27 @@ class Koji: r.raise_for_status() return yaml.safe_load(r.content) + def get_build_log(self, component, log_name): + """Log file related to a build. + + :param dict component: Item produced with build.components() + :param str log_name: Filename of log e.g 'build.log' + :return Content of a log file + :rtype str + """ + nvr = component['nvr'] + build_logs = self._session.getBuildLogs(nvr) + + for log in build_logs: + if log['name'] == log_name: + log_path = log['path'] + break + + url = self._topurl + '/' + log_path + r = requests.get(url) + r.raise_for_status() + return r.text + class Repo: """Wrapper class to work with module git repositories @@ -389,3 +410,30 @@ class Component: with pushd(self._clone_dir.name): git("commit", *args) git("push") + + +class MBS: + """Wrapper class to work with MBS requests. + + :attribute string _mbs_api: URL of the MBS API (including trailing '/') + """ + + def __init__(self, mbs_api): + self._mbs_api = mbs_api + + def get_builds(self, module, stream, order_desc_by=None): + """Get list of Builds objects via mbs api. + + :attribute string module: Module name + :attribute string stream: Stream name + :attribute string order_desc_by: Optional sorting parameter e.g. "version" + :return: list of Build objects + :rtype: list + """ + url = f"{self._mbs_api}module-builds/" + payload = {'name': module, "stream": stream} + if order_desc_by: + payload.update({"order_desc_by": order_desc_by}) + r = requests.get(url, params=payload) + r.raise_for_status() + return [Build(self._mbs_api, build["id"]) for build in r.json()["items"]]