blob: e3a4d432a20888914b2f4e9d7addbe85a05a3402 [file] [log] [blame]
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# 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", encoding="utf-8") 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", encoding="utf-8") 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