Skip to content

Commit

Permalink
Remote: Always download outputs and outErr even if declared outputs a…
Browse files Browse the repository at this point in the history
…re missing.

So that if the unusual case described by bazelbuild#14543 happens, we can still see the error message of the spawn (if any).

Closes bazelbuild#15724.

PiperOrigin-RevId: 470673113
Change-Id: I54a17a555bf1e88bd8ec8bd8a980e5914cfd2261
  • Loading branch information
coeuvre authored and aiuto committed Oct 12, 2022
1 parent c22b086 commit 49fcb1e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1031,43 +1031,6 @@ public InMemoryOutput downloadOutputs(RemoteAction action, RemoteActionResult re
metadata = parseActionResultMetadata(context, result);
}

if (result.success()) {
// Check that all mandatory outputs are created.
for (ActionInput output : action.getSpawn().getOutputFiles()) {
if (action.getSpawn().isMandatoryOutput(output)) {
// In the past, remote execution did not create output directories if the action didn't do
// this explicitly. This check only remains so that old remote cache entries that do not
// include empty output directories remain valid.
if (output instanceof Artifact && ((Artifact) output).isTreeArtifact()) {
continue;
}

Path localPath = execRoot.getRelative(output.getExecPath());
if (!metadata.files.containsKey(localPath)
&& !metadata.directories.containsKey(localPath)
&& !metadata.symlinks.containsKey(localPath)) {
throw new IOException(
"Invalid action cache entry "
+ action.getActionKey().getDigest().getHash()
+ ": expected output "
+ prettyPrint(output)
+ " does not exist.");
}
}
}

// When downloading outputs from just remotely executed action, the action result comes from
// Execution response which means, if disk cache is enabled, action result hasn't been
// uploaded to it. Upload action result to disk cache here so next build could hit it.
if (useDiskCache(remoteOptions) && result.executeResponse != null) {
getFromFuture(
remoteCache.uploadActionResult(
context.withWriteCachePolicy(CachePolicy.DISK_CACHE_ONLY),
action.getActionKey(),
result.actionResult));
}
}

FileOutErr outErr = action.getSpawnExecutionContext().getFileOutErr();

ImmutableList.Builder<ListenableFuture<FileMetadata>> downloadsBuilder =
Expand Down Expand Up @@ -1195,6 +1158,43 @@ public InMemoryOutput downloadOutputs(RemoteAction action, RemoteActionResult re
}
}

if (result.success()) {
// Check that all mandatory outputs are created.
for (ActionInput output : action.getSpawn().getOutputFiles()) {
if (action.getSpawn().isMandatoryOutput(output)) {
// In the past, remote execution did not create output directories if the action didn't do
// this explicitly. This check only remains so that old remote cache entries that do not
// include empty output directories remain valid.
if (output instanceof Artifact && ((Artifact) output).isTreeArtifact()) {
continue;
}

Path localPath = execRoot.getRelative(output.getExecPath());
if (!metadata.files.containsKey(localPath)
&& !metadata.directories.containsKey(localPath)
&& !metadata.symlinks.containsKey(localPath)) {
throw new IOException(
"Invalid action cache entry "
+ action.getActionKey().getDigest().getHash()
+ ": expected output "
+ prettyPrint(output)
+ " does not exist.");
}
}
}

// When downloading outputs from just remotely executed action, the action result comes from
// Execution response which means, if disk cache is enabled, action result hasn't been
// uploaded to it. Upload action result to disk cache here so next build could hit it.
if (useDiskCache(remoteOptions) && result.executeResponse != null) {
getFromFuture(
remoteCache.uploadActionResult(
context.withWriteCachePolicy(CachePolicy.DISK_CACHE_ONLY),
action.getActionKey(),
result.actionResult));
}
}

return null;
}

Expand Down
3 changes: 2 additions & 1 deletion src/test/shell/bazel/remote/remote_execution_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2699,14 +2699,15 @@ function test_missing_outputs_dont_upload_action_result() {
genrule(
name = 'foo',
outs = ["foo.txt"],
cmd = "echo foo",
cmd = "echo foo-generation-error",
)
EOF

bazel build \
--remote_cache=grpc://localhost:${worker_port} \
//a:foo >& $TEST_log && fail "Should failed to build"

expect_log "foo-generation-error"
remote_cas_files="$(count_remote_cas_files)"
[[ "$remote_cas_files" == 0 ]] || fail "Expected 0 remote cas entries, not $remote_cas_files"
remote_ac_files="$(count_remote_ac_files)"
Expand Down

0 comments on commit 49fcb1e

Please sign in to comment.