diff --git a/tests/integration/example.test.env.yaml b/tests/integration/example.test.env.yaml index 0c2b720a..6d450f2f 100644 --- a/tests/integration/example.test.env.yaml +++ b/tests/integration/example.test.env.yaml @@ -51,3 +51,13 @@ testdata: build_id_reused: 1235 module: testmodule branch: reuse-all-components-branch + reuse_components: + # Build id to be reused for this test, it will be used to set a baseline. + baseline_build_id: 1234 + build_id: 1235 + module: testmodule + branch: reuse-components-build-branch + # Name of package that will be changed and will be rebuild in the build. + package: acl + # Name of the branch which is going to be built for the specified package. + component_branch: private-test-reuse-components diff --git a/tests/integration/test_reuse_components.py b/tests/integration/test_reuse_components.py new file mode 100644 index 00000000..72ec7473 --- /dev/null +++ b/tests/integration/test_reuse_components.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# SPDX-License-Identifier: MIT + +import utils + + +def test_reuse_components(test_env, repo, koji): + """ + Bump the commit of one of the components that MBS uses. + Bump the commit of the same testmodule that was mentioned in the preconditions. + Submit a testmodule build again with `fedpkg module-build -w --optional + rebuild_strategy=only-changed` (this is the default rebuild strategy). + + Checks: + * Verify all the components were reused except for the component that had their commit change. + * Verify that the component with the changed commit was rebuilt. + """ + repo.bump() + baseline_build = utils.Build(test_env["packaging_utility"], test_env["mbs_api"]) + baseline_build.run( + "--watch", + "--optional", + "rebuild_strategy=all", + reuse=test_env["testdata"]["reuse_components"].get("baseline_build_id"), + ) + + package = test_env["testdata"]["reuse_components"].get("package") + component = utils.Component( + package, + test_env["testdata"]["reuse_components"].get("component_branch") + ) + component.clone(test_env["packaging_utility"]) + component.bump() + + repo.bump() + build = utils.Build(test_env["packaging_utility"], test_env["mbs_api"]) + build.run( + "--watch", + "--optional", + "rebuild_strategy=only-changed", + reuse=test_env["testdata"]["reuse_components"].get("build_id"), + ) + + comp_task_ids_base = baseline_build.component_task_ids() + comp_task_ids = build.component_task_ids() + comp_task_ids_base.pop('module-build-macros') + comp_task_ids.pop('module-build-macros') + changed_package_base_task_id = comp_task_ids_base.pop(package) + changed_package_task_id = comp_task_ids.pop(package) + assert changed_package_base_task_id != changed_package_task_id + assert comp_task_ids == comp_task_ids_base + + assert build.components(package=package)[0]['state_name'] == 'COMPLETE' + state_reason = build.components(package=package)[0]['state_reason'] + assert state_reason != "Reused component from previous module build" diff --git a/tests/integration/utils.py b/tests/integration/utils.py index 2f05deb3..a59d6368 100644 --- a/tests/integration/utils.py +++ b/tests/integration/utils.py @@ -9,10 +9,11 @@ from kobo import rpmlib import koji import yaml import requests +import tempfile import sh our_sh = sh(_out=sys.stdout, _err=sys.stderr, _tee=True) -from our_sh import Command, git # noqa +from our_sh import Command, git, pushd # noqa class Koji: @@ -244,13 +245,21 @@ class Build: :param string state: Koji build state the components should be in :param int batch: the number of the batch the components should be in - :param string: name of component (package): + :param string package: name of component (package): :return: List of components packages :rtype: list of strings """ components = self.components(state, batch, package) return [item["package"] for item in components] + def component_task_ids(self): + """Dictionary containing all names of packages from build and appropriate task ids + + :return: Dictionary containing name of packages and their task id + :rtype: dict + """ + return {comp["package"]: comp["task_id"] for comp in self.components()} + def batches(self): """ Components of the module build separated in sets according to batches @@ -268,18 +277,10 @@ class Build: return batches - def component_task_ids(self): - """Dictionary containing all names of packages from build and appropriate task ids - - :return: Dictionary containing name of packages and their task id - :rtype: dict - """ - return {comp["package"]: comp["task_id"] for comp in self.components()} - def wait_for_koji_task_id(self, package, batch, timeout=300, sleep=10): """Wait until the component is submitted to Koji (has a task_id) - :param string: name of component (package) + :param string package: name of component (package) :param int batch: the number of the batch the components should be in :param int timeout: time in seconds :param int sleep: time in seconds @@ -325,3 +326,47 @@ class Build: ): return True return False + + +class Component: + """Wrapper class to work with git repositories of components + + :attribute string module_name: name of the module stored in this repo + :attribute string branch: branch of the git repo that will be used + :attribute TemporaryDirectory _clone_dir: directory where is the clone of the repo + """ + def __init__(self, module_name, branch): + self._module_name = module_name + self._branch = branch + self._clone_dir = None + + def __del__(self): + self._clone_dir.cleanup() + + def clone(self, packaging_utility): + """Clone the git repo of the component to be used by the test in a temporary location + + Directory of the clone is stored in self._clone_dir. + :param string packaging_utility: packaging utility as defined in test.env.yaml + """ + tempdir = tempfile.TemporaryDirectory() + args = [ + "--branch", + self._branch, + f'rpms/{self._module_name}', + tempdir.name + ] + packaging_util = Command(packaging_utility) + packaging_util("clone", *args) + self._clone_dir = tempdir + + def bump(self): + """Create a "bump" commit and push it in git""" + args = [ + "--allow-empty", + "-m", + "Bump" + ] + with pushd(self._clone_dir.name): + git("commit", *args) + git("push")