Skip to content

Commit

Permalink
tests/integration/cachedfail.py: Test explicit retry of failed builds
Browse files Browse the repository at this point in the history
Test behavior of `--retry-failed` vs not specifying the flag in various
scenarios, added the test adjacent to existing test of retrying of failed
builds in non-strict mode.

The behavior differs slightly for automatic retries of failed
builds in non-strict mode, so the two tests remain separate.
  • Loading branch information
tristanvb committed Jul 10, 2023
1 parent b155a3d commit 7a054a3
Showing 1 changed file with 78 additions and 0 deletions.
78 changes: 78 additions & 0 deletions tests/integration/cachedfail.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,84 @@ def test_host_tools_errors_are_not_cached(cli, datafiles, tmp_path):
assert cli.get_element_state(project, "element.bst") == "cached"


# Tests that failed builds will be retried if --retry-failed is specified
#
@pytest.mark.datafiles(DATA_DIR)
@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox")
@pytest.mark.parametrize("use_share", (False, True), ids=["local-cache", "pull-failed-artifact"])
@pytest.mark.parametrize("retry", (True, False), ids=["retry", "no-retry"])
@pytest.mark.parametrize("strict", (True, False), ids=["strict", "non-strict"])
def test_retry_failed(cli, tmpdir, datafiles, use_share, retry, strict):
project = str(datafiles)
target_path = os.path.join(project, "elements", "target.bst")

# Use separate cache directories for each iteration of this test
# even though we're using cli_integration
#
# Global nonstrict configuration ensures all commands will be non-strict
cli.configure({"cachedir": cli.directory, "projects": {"test": {"strict": strict}}})

def generate_target():
return {
"kind": "manual",
"depends": [
"base.bst",
],
"config": {
"build-commands": [
"test -e /foo",
],
},
}

with ExitStack() as stack:

if use_share:
share = stack.enter_context(create_artifact_share(os.path.join(str(tmpdir), "artifactshare")))
cli.configure({"artifacts": {"servers": [{"url": share.repo, "push": True}]}})

target = generate_target()
_yaml.roundtrip_dump(target, target_path)

# Try to build it, this should result in caching a failure of the target
result = cli.run(project=project, args=["build", "target.bst"])
result.assert_main_error(ErrorDomain.STREAM, None)

# Assert that it's cached in a failed artifact
assert cli.get_element_state(project, "target.bst") == "failed"

if use_share:
# Delete the local cache, provoke pulling of the failed build
cli.remove_artifact_from_cache(project, "target.bst")

# Assert that the failed build has been removed
assert cli.get_element_state(project, "target.bst") == "buildable"

# Even though we are in non-strict mode, the failed build should be retried
if retry:
result = cli.run(project=project, args=["build", "--retry-failed", "target.bst"])
else:
result = cli.run(project=project, args=["build", "target.bst"])

# If we did not modify the cache key, we want to assert that we did not
# in fact attempt to rebuild the failed artifact.
#
# Since the UX is very similar, we'll distinguish this by counting the number of
# build logs which were produced.
#
result.assert_main_error(ErrorDomain.STREAM, None)
if retry:
assert "target.bst" in result.get_built_elements()
else:
assert "target.bst" not in result.get_built_elements()

if use_share:
# Assert that we did indeed go through the motions of downloading the failed
# build, and possibly discarded the failed artifact if the strong key did not match
#
assert "target.bst" in result.get_pulled_elements()


# Tests that failed builds will be retried in strict mode when dependencies have changed.
#
# This test ensures:
Expand Down

0 comments on commit 7a054a3

Please sign in to comment.