From 99fc9776144c137b6bd464436f910e32bbab0036 Mon Sep 17 00:00:00 2001 From: Hunor Csomortáni Date: Nov 26 2019 15:50:52 +0000 Subject: Merge #1515 `Integration test for normal build` --- diff --git a/tests/integration/example.test.env.yaml b/tests/integration/example.test.env.yaml index 38d53a4..aa11a5c 100644 --- a/tests/integration/example.test.env.yaml +++ b/tests/integration/example.test.env.yaml @@ -8,6 +8,7 @@ git_url: https://src.fedoraproject.org/ koji: server: https://koji.fedoraproject.org/kojihub topurl: https://kojipkgs.fedoraproject.org/ + weburl: https://brewweb.stage.engineering.redhat.com/brewroot # Test data to be used by the tests. # Items in here are mapped by their name to the tests that use them. # For example test_scratch_build will use scratch_build. @@ -32,3 +33,10 @@ failed_build: # List of components expected to complete or canceled in the batch. canceled_components: - comp2 + normal_build: + module: testmodule + branch: normal-build-branch + # List of components in order they should be build in. One set represents one batch. + buildorder: [{"module-build-macros"}, {"attr"}, {"acl"}] + # True if buildrequire a Platform stream representing a GA RHEL release + platform_is_ga: true diff --git a/tests/integration/test_normal_build.py b/tests/integration/test_normal_build.py new file mode 100644 index 0000000..a35eb98 --- /dev/null +++ b/tests/integration/test_normal_build.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# SPDX-License-Identifier: MIT + +import utils + + +def test_normal_build(test_env, repo, koji): + """ + Run build with `rhpkg-stage module-build --optional rebuild_strategy=all` + + Checks: + * Check that MBS will submit all the component builds + * Check that buildorder of components is respected + * Check that MBS will create two content generator builds representing the module: + - [module] + - [module]-devel + * Check that MBS changed the buildrequired platform to have a suffix of “z” + if a Platform stream is representing a GA RHEL release. + """ + build = utils.Build(test_env["packaging_utility"], test_env["mbs_api"]) + build_id = build.run( + "--watch", + "--scratch", + "--optional", + "rebuild_strategy=all", + reuse=test_env["testdata"]["normal_build"].get("build_id"), + ) + assert sorted(build.components()) == sorted(repo.components + ["module-build-macros"]) + + expected_buildorder = test_env["testdata"]["normal_build"]["buildorder"] + expected_buildorder = [set(batch) for batch in expected_buildorder] + actual_buildorder = build.batches() + assert actual_buildorder == expected_buildorder + + cg_build = koji.get_build(build.nvr()) + cg_devel_build = koji.get_build(build.nvr(name_suffix="-devel")) + assert cg_build and cg_devel_build + assert cg_devel_build['extra']['typeinfo']['module']['module_build_service_id'] == int(build_id) + + modulemd = koji.get_modulemd(cg_build) + actual_platforms = modulemd["data"]["dependencies"][0]["buildrequires"]["platform"] + expected_platforms = repo.platform + platform_ga = test_env["testdata"]["normal_build"].get("platform_is_ga") + if platform_ga: + expected_platforms = [f"{pf}.z" for pf in expected_platforms] + assert expected_platforms == actual_platforms diff --git a/tests/integration/utils.py b/tests/integration/utils.py index 14fe341..e53f9b6 100644 --- a/tests/integration/utils.py +++ b/tests/integration/utils.py @@ -15,13 +15,17 @@ class Koji: :attribute string _server: URL of the Koji hub :attribute string _topurl: URL of the top-level Koji download location + :attribute string _weburl: URL of the web interface :attribute koji.ClientSession _session: Koji session + :attribute koji.PathInfo _pathinfo: Koji path """ - def __init__(self, server, topurl): + def __init__(self, server, topurl, weburl): self._server = server self._topurl = topurl + self._weburl = weburl self._session = koji.ClientSession(self._server) + self._pathinfo = koji.PathInfo(self._weburl) def get_build(self, nvr_dict): """Koji build data for NVR @@ -33,6 +37,18 @@ class Koji: nvr_string = rpmlib.make_nvr(nvr_dict) return self._session.getBuild(nvr_string) + def get_modulemd(self, cg_build): + """Modulemd file of the build from koji archive + + :param cg_build: koji build object + :return: Modulemd file + :rtype: dict + """ + url = self._pathinfo.typedir(cg_build, 'module') + r = requests.get(f"{url}/modulemd.txt") + r.raise_for_status() + return yaml.safe_load(r.content) + class Repo: """Wrapper class to work with module git repositories @@ -44,6 +60,7 @@ class Repo: def __init__(self, module_name): self.module_name = module_name self._modulemd = None + self._version = None @property def modulemd(self): @@ -67,6 +84,21 @@ class Repo: """ return list(self.modulemd["data"]["components"]["rpms"]) + @property + def platform(self): + """ + List of platforms in the modulemd file, obtaining values differs on version + + :return: List of platforms in the modulemd file + :rtype: list of strings + """ + if self._version is None: + self._version = self._modulemd["version"] + if self._version == 1: + return [self._modulemd["data"]["dependencies"]["buildrequires"].get("platform")] + elif self._version == 2: + return self._modulemd["data"]["dependencies"][0]["buildrequires"].get("platform") + class Build: """Wrapper class to work with module builds @@ -146,6 +178,23 @@ class Build: return [item["package"] for item in filtered] + def batches(self): + """ + Components of the module build separated in sets according to batches + + :return: list of components according to batches + :rtype: list of sets + """ + comps_data = sorted(self.component_data["items"], key=lambda x: x["batch"]) + batch_count = comps_data[-1]["batch"] + batches = batch_count * [set()] + for data in comps_data: + batch = data["batch"] + package = data["package"] + batches[batch - 1] = batches[batch - 1].union({package}) + + return batches + def nvr(self, name_suffix=""): """NVR dictionary of this module build