diff options
author | bst-marge-bot <marge-bot@buildstream.build> | 2019-10-08 18:53:28 +0000 |
---|---|---|
committer | bst-marge-bot <marge-bot@buildstream.build> | 2019-10-08 18:53:28 +0000 |
commit | 99e0236e2e995efe041b75bfc052ed5596952661 (patch) | |
tree | 1ea1b26462e007a870e8df3f179aca1842f44e14 | |
parent | d390fd62f28db1cb812554d386f2b3560e5e6628 (diff) | |
parent | 78f05bb7d6af99b6716cfee56d1bf382b9243b62 (diff) | |
download | buildstream-99e0236e2e995efe041b75bfc052ed5596952661.tar.gz |
Merge branch 'bschubert/fix-empty-buildtree' into 'master'
_artifactcache.py: Don't push artifact blobs when no files are present
Closes #1145
See merge request BuildStream/buildstream!1630
-rw-r--r-- | src/buildstream/_artifactcache.py | 3 | ||||
-rw-r--r-- | src/buildstream/_cas/casserver.py | 3 | ||||
-rw-r--r-- | tests/integration/cachedfail.py | 43 |
3 files changed, 47 insertions, 2 deletions
diff --git a/src/buildstream/_artifactcache.py b/src/buildstream/_artifactcache.py index f8d856be7..b4d4efe00 100644 --- a/src/buildstream/_artifactcache.py +++ b/src/buildstream/_artifactcache.py @@ -560,7 +560,8 @@ class ArtifactCache(BaseCache): artifact_proto = artifact._get_proto() try: - self.cas._send_directory(remote, artifact_proto.files) + if str(artifact_proto.files): + self.cas._send_directory(remote, artifact_proto.files) if str(artifact_proto.buildtree): try: diff --git a/src/buildstream/_cas/casserver.py b/src/buildstream/_cas/casserver.py index 716178bb4..d4241435a 100644 --- a/src/buildstream/_cas/casserver.py +++ b/src/buildstream/_cas/casserver.py @@ -502,7 +502,8 @@ class _ArtifactServicer(artifact_pb2_grpc.ArtifactServiceServicer): if self.update_cas: # Check that the files specified are in the CAS - self._check_directory("files", artifact.files, context) + if str(artifact.files): + self._check_directory("files", artifact.files, context) # Unset protocol buffers don't evaluated to False but do return empty # strings, hence str() diff --git a/tests/integration/cachedfail.py b/tests/integration/cachedfail.py index 08733ab71..e3c05e691 100644 --- a/tests/integration/cachedfail.py +++ b/tests/integration/cachedfail.py @@ -183,6 +183,49 @@ def test_push_cached_fail(cli, tmpdir, datafiles, on_error): assert share.get_artifact(cli.get_artifact_name(project, 'test', 'element.bst')) +@pytest.mark.skipif(not HAVE_SANDBOX, reason='Only available with a functioning sandbox') +@pytest.mark.datafiles(DATA_DIR) +@pytest.mark.parametrize("on_error", ("continue", "quit")) +def test_push_failed_missing_shell(cli, tmpdir, datafiles, on_error): + """Test that we can upload a built artifact that didn't have a valid shell inside. + + When we don't have a valid shell, the artifact will be empty, not even the root directory. + This ensures we handle the case of an entirely empty artifact correctly. + """ + if on_error == 'quit': + pytest.xfail('https://gitlab.com/BuildStream/buildstream/issues/534') + + project = str(datafiles) + element_path = os.path.join(project, 'elements', 'element.bst') + + # Write out our test target + element = { + 'kind': 'script', + 'config': { + 'commands': [ + 'false', + # Ensure unique cache key for different test variants + 'TEST="{}"'.format(os.environ.get('PYTEST_CURRENT_TEST')), + ], + }, + } + _yaml.roundtrip_dump(element, element_path) + + with create_artifact_share(os.path.join(str(tmpdir), 'remote')) as share: + cli.configure({ + 'artifacts': {'url': share.repo, 'push': True}, + }) + + # Build the element, continuing to finish active jobs on error. + result = cli.run(project=project, args=['--on-error={}'.format(on_error), 'build', 'element.bst']) + result.assert_main_error(ErrorDomain.STREAM, None) + + # This element should have failed + assert cli.get_element_state(project, 'element.bst') == 'failed' + # This element should have been pushed to the remote + assert share.get_artifact(cli.get_artifact_name(project, 'test', 'element.bst')) + + @pytest.mark.skipif(HAVE_SANDBOX != 'bwrap', reason='Only available with bubblewrap on Linux') @pytest.mark.datafiles(DATA_DIR) def test_host_tools_errors_are_not_cached(cli, datafiles, tmp_path): |