# Pylint doesn't play well with fixtures and dependency injection from pytest # pylint: disable=redefined-outer-name import os import pytest from buildstream.testing import cli # pylint: disable=unused-import # Project directory DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project",) def strict_args(args, strict): if strict != "strict": return ["--no-strict", *args] return args @pytest.mark.datafiles(DATA_DIR) @pytest.mark.parametrize("strict", ["strict", "non-strict"]) def test_rebuild(datafiles, cli, strict): project = str(datafiles) # First build intermediate target.bst result = cli.run(project=project, args=strict_args(["build", "target.bst"], strict)) result.assert_success() # Modify base import with open(os.path.join(project, "files", "dev-files", "usr", "include", "new.h"), "w") as f: f.write("#define NEW") # Rebuild base import and build top-level rebuild-target.bst # In non-strict mode, this does not rebuild intermediate target.bst, # which means that a weakly cached target.bst will be staged as dependency. result = cli.run(project=project, args=strict_args(["build", "rebuild-target.bst"], strict)) result.assert_success() built_elements = result.get_built_elements() assert "rebuild-target.bst" in built_elements if strict == "strict": assert "target.bst" in built_elements else: assert "target.bst" not in built_elements # Test that a cached artifact matching the strict cache key is preferred # to a more recent artifact matching only the weak cache key. @pytest.mark.datafiles(DATA_DIR) @pytest.mark.parametrize("strict", ["strict", "non-strict"]) def test_modify_and_revert(datafiles, cli, strict): project = str(datafiles) # First build target and dependencies result = cli.run(project=project, args=["build", "target.bst"]) result.assert_success() # Remember cache key of first build target_cache_key = cli.get_element_key(project, "target.bst") # Modify dependency new_header_path = os.path.join(project, "files", "dev-files", "usr", "include", "new.h") with open(new_header_path, "w") as f: f.write("#define NEW") # Trigger rebuild. This will also rebuild the unmodified target as this # follows a strict build plan. result = cli.run(project=project, args=["build", "target.bst"]) result.assert_success() assert "target.bst" in result.get_built_elements() assert cli.get_element_key(project, "target.bst") != target_cache_key # Revert previous modification in dependency os.unlink(new_header_path) # Rebuild again, everything should be cached. result = cli.run(project=project, args=["build", "target.bst"]) result.assert_success() assert len(result.get_built_elements()) == 0 # Verify that cache key now again matches the first build in both # strict and non-strict mode. cli.configure({"projects": {"test": {"strict": strict == "strict"}}}) assert cli.get_element_key(project, "target.bst") == target_cache_key