mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-04-09 13:49:24 +08:00
Add test 'reuse components if added'
This commit is contained in:
@@ -49,7 +49,10 @@ def scenario(request, test_env):
|
||||
scenario configuration.
|
||||
"""
|
||||
scenario_name = request.function.__name__.split("test_", 1)[1]
|
||||
return test_env["testdata"][scenario_name]
|
||||
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")
|
||||
|
||||
@@ -115,3 +115,21 @@ testdata:
|
||||
build_id: 3345
|
||||
module: testmodule
|
||||
branch: test-scratch-final-mmd
|
||||
reuse_components_if_removed_1:
|
||||
#...
|
||||
reuse_components_if_removed_n:
|
||||
#...
|
||||
reuse_components_if_added_1:
|
||||
#...
|
||||
reuse_components_if_added_n:
|
||||
# reuse_components_if_added_n or reuse_components_if_removed_n, where n = {1, 2, ...}
|
||||
# Same test case divided into different test functions to enable parallel execution.
|
||||
# If any of these scenarios is missing, the appropriate test will simply be skipped.
|
||||
module: testmodule
|
||||
branch: test-reuse-components-if-added-2
|
||||
# indexes of RPMs found in the test branch modulemd
|
||||
first_build: [0, 2]
|
||||
second_build: [0, 1, 2]
|
||||
expected_reused: [0]
|
||||
expected_rebuilt: [1, 2]
|
||||
rebuild_strategy: "changed-and-after"
|
||||
|
||||
96
tests/integration/test_reuse_components_if_added.py
Normal file
96
tests/integration/test_reuse_components_if_added.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import copy
|
||||
|
||||
|
||||
def extracted_test_function(repo, pkg_util, scenario):
|
||||
"""Test if previous components are reused properly, after components are added/removed.
|
||||
|
||||
Prerequisites:
|
||||
EMPTY (no components/RPMs) module MD file
|
||||
Steps:
|
||||
1) Make changes to the modulemd according to test scenario (first build)
|
||||
2) Make a clean build (rebuild strategy : all).
|
||||
3) Add/remove RPMs according to test scenario (second build)
|
||||
4) Rebuild, rebuild strategy according to test scenario
|
||||
5) Revert to the initial state.
|
||||
|
||||
:param utils.Repo repo: repo fixture
|
||||
:param utils.PackagingUtility pkg_util: pkg_util fixture
|
||||
:param dict scenario: see example.test.env
|
||||
"""
|
||||
test_rpms = repo.components
|
||||
|
||||
# Prepare test data from test.env scenario
|
||||
first_build_rpms = {test_rpms[i] for i in scenario["first_build"]}
|
||||
second_build_rpms = {test_rpms[i] for i in scenario["second_build"]}
|
||||
expected_reused = {test_rpms[i] for i in scenario["expected_reused"]}
|
||||
expected_rebuilt = {test_rpms[i] for i in scenario["expected_rebuilt"]}
|
||||
rebuild_strategy = scenario["rebuild_strategy"]
|
||||
|
||||
# Save initial state
|
||||
original_metadata = repo.modulemd
|
||||
original_rpms = repo.modulemd["data"]["components"]["rpms"]
|
||||
|
||||
# Prepare initial build metadata & push
|
||||
tmp_metadata = copy.deepcopy(original_metadata)
|
||||
tmp_metadata["data"]["components"]["rpms"] = {}
|
||||
for rpm in first_build_rpms:
|
||||
tmp_metadata["data"]["components"]["rpms"][rpm] = original_rpms[rpm]
|
||||
|
||||
repo.write_to_modulemd(tmp_metadata)
|
||||
repo.add_all_commit_and_push(f'1st build: "{first_build_rpms}"')
|
||||
|
||||
try:
|
||||
# Make an initial build (to be later reused)
|
||||
builds = pkg_util.run("--watch", "--optional", "rebuild_strategy=all")
|
||||
assert len(builds) == 1, "Initial build failed!"
|
||||
|
||||
# Prepare 2nd build metadata & push
|
||||
tmp_metadata["data"]["components"]["rpms"] = {}
|
||||
for rpm in second_build_rpms:
|
||||
tmp_metadata["data"]["components"]["rpms"][rpm] = original_rpms[rpm]
|
||||
repo.write_to_modulemd(tmp_metadata)
|
||||
repo.add_all_commit_and_push(f'2nd build: "{second_build_rpms}"')
|
||||
|
||||
# Make a new build
|
||||
builds = pkg_util.run("--watch", "--optional", f"rebuild_strategy={rebuild_strategy}")
|
||||
assert len(builds) == 1, "Second (re)build failed!"
|
||||
|
||||
build = builds[0]
|
||||
# we don"t care about module-build-macros
|
||||
build_components = [c for c in build.components() if c["package"] != "module-build-macros"]
|
||||
|
||||
# Partition components by "reused" state - package name only
|
||||
reused_msg = "Reused component from previous module build"
|
||||
actually_reused = {
|
||||
c["package"] for c in build_components if c["state_reason"] == reused_msg
|
||||
}
|
||||
actually_rebuilt = {
|
||||
c["package"] for c in build_components if c["state_reason"] != reused_msg
|
||||
}
|
||||
|
||||
assert actually_reused == expected_reused
|
||||
assert actually_rebuilt == expected_rebuilt
|
||||
|
||||
finally: # Revert the change
|
||||
repo.write_to_modulemd(original_metadata)
|
||||
repo.add_all_commit_and_push("Revert")
|
||||
|
||||
|
||||
# Each function needs its own test branch due to parallel execution.
|
||||
# Module branch provides data - i.e. RPM components - and test.env provides
|
||||
# scenario to be executed, i.e. which RPMs go to the 1st and 2nd build
|
||||
# as well as expected result - see test.env example.
|
||||
def test_reuse_components_if_added_1(repo, pkg_util, scenario):
|
||||
extracted_test_function(repo, pkg_util, scenario)
|
||||
|
||||
|
||||
def test_reuse_components_if_added_2(repo, pkg_util, scenario):
|
||||
extracted_test_function(repo, pkg_util, scenario)
|
||||
|
||||
|
||||
def test_reuse_components_if_removed_1(repo, pkg_util, scenario):
|
||||
extracted_test_function(repo, pkg_util, scenario)
|
||||
|
||||
|
||||
def test_reuse_components_if_removed_2(repo, pkg_util, scenario):
|
||||
extracted_test_function(repo, pkg_util, scenario)
|
||||
@@ -124,6 +124,11 @@ class Repo:
|
||||
self._modulemd = None
|
||||
self._version = None
|
||||
|
||||
@property
|
||||
def modulemd_path(self):
|
||||
"""Modulemd file absolute path"""
|
||||
return os.path.join(os.path.abspath(os.curdir), self.module_name + ".yaml")
|
||||
|
||||
@property
|
||||
def modulemd(self):
|
||||
"""Modulemd file as read from the repo
|
||||
@@ -160,6 +165,20 @@ class Repo:
|
||||
elif self._version == 2:
|
||||
return self._modulemd["data"]["dependencies"][0]["buildrequires"].get("platform")
|
||||
|
||||
def write_to_modulemd(self, content_yaml):
|
||||
"""Write new content (replace) to the modulemd file
|
||||
|
||||
:param dict content_yaml: module metadata dictionary
|
||||
"""
|
||||
with open(self.modulemd_path, 'w') as md_file:
|
||||
yaml.dump(content_yaml, md_file, sort_keys=False)
|
||||
|
||||
def add_all_commit_and_push(self, message="Bump"):
|
||||
"""Add all current changes and commit with a custom message"""
|
||||
git("add", "--all")
|
||||
git("commit", "--allow-empty", "-m", message)
|
||||
git("push")
|
||||
|
||||
def bump(self):
|
||||
"""Create a "bump" commit"""
|
||||
args = [
|
||||
|
||||
Reference in New Issue
Block a user