Skip to content

Commit 602a302

Browse files
committed
RemoteExecutionService: support output_symlinks in ActionResult
Since Remote API v2.1, both - output_file_symlinks - output_directory_symlinks were marked as deprecated in favor of output_symlinks. However, Bazel downloadOutputs has only support the 2 deprecated fields and not output_symlinks. Add support for output_symlinks.
1 parent 0dd106e commit 602a302

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

src/main/java/com/google/devtools/build/lib/remote/RemoteExecutionService.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,10 @@ public List<OutputSymlink> getOutputDirectorySymlinks() {
644644
return actionResult.getOutputDirectorySymlinksList();
645645
}
646646

647+
public List<OutputSymlink> getOutputSymlinks() {
648+
return actionResult.getOutputSymlinksList();
649+
}
650+
647651
/**
648652
* Returns the freeform informational message with details on the execution of the action that
649653
* may be displayed to the user upon failure or when requested explicitly.
@@ -1089,8 +1093,11 @@ ActionResultMetadata parseActionResultMetadata(
10891093
}
10901094

10911095
ImmutableMap.Builder<Path, SymlinkMetadata> symlinks = ImmutableMap.builder();
1092-
Iterable<OutputSymlink> outputSymlinks =
1093-
Iterables.concat(result.getOutputFileSymlinks(), result.getOutputDirectorySymlinks());
1096+
var outputSymlinks = ImmutableSet.<OutputSymlink>builder()
1097+
.addAll(result.getOutputFileSymlinks())
1098+
.addAll(result.getOutputDirectorySymlinks())
1099+
.addAll(result.getOutputSymlinks())
1100+
.build();
10941101
for (OutputSymlink symlink : outputSymlinks) {
10951102
Path localPath =
10961103
remotePathResolver.outputPathToLocalPath(encodeBytestringUtf8(symlink.getPath()));

src/test/java/com/google/devtools/build/lib/remote/RemoteExecutionServiceTest.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,54 @@ public void downloadOutputs_relativeDirectorySymlink_success() throws Exception
590590
assertThat(context.isLockOutputFilesCalled()).isTrue();
591591
}
592592

593+
@Test
594+
public void downloadOutputs_relativeOutputSymlinks_success() throws Exception {
595+
// Test that download outputs works when the action result only contains output_symlinks
596+
// and not output_file_symlinks or output_directory_symlinks, which are deprecated.
597+
ActionResult.Builder builder = ActionResult.newBuilder();
598+
builder.addOutputSymlinksBuilder().setPath("outputs/a/b/link").setTarget("../../foo");
599+
RemoteActionResult result =
600+
RemoteActionResult.createFromCache(CachedActionResult.remote(builder.build()));
601+
Spawn spawn = newSpawnFromResult(result);
602+
FakeSpawnExecutionContext context = newSpawnExecutionContext(spawn);
603+
RemoteExecutionService service = newRemoteExecutionService();
604+
RemoteAction action = service.buildRemoteAction(spawn, context);
605+
606+
// Doesn't check for dangling links, hence download succeeds.
607+
service.downloadOutputs(action, result);
608+
609+
Path path = execRoot.getRelative("outputs/a/b/link");
610+
assertThat(path.isSymbolicLink()).isTrue();
611+
assertThat(path.readSymbolicLink()).isEqualTo(PathFragment.create("../../foo"));
612+
assertThat(context.isLockOutputFilesCalled()).isTrue();
613+
}
614+
615+
@Test
616+
public void downloadOutputs_outputSymlinksCompatibility_success() throws Exception {
617+
// Test that download outputs works when the action result contains both output_symlinks
618+
// and output_file_symlinks (or output_directory_symlinks).
619+
//
620+
// Remote Execution Server may set both fields to ensure backward compatibility with
621+
// clients that don't support output_symlinks.
622+
ActionResult.Builder builder = ActionResult.newBuilder();
623+
builder.addOutputFileSymlinksBuilder().setPath("outputs/a/b/link").setTarget("foo");
624+
builder.addOutputSymlinksBuilder().setPath("outputs/a/b/link").setTarget("foo");
625+
RemoteActionResult result =
626+
RemoteActionResult.createFromCache(CachedActionResult.remote(builder.build()));
627+
Spawn spawn = newSpawnFromResult(result);
628+
FakeSpawnExecutionContext context = newSpawnExecutionContext(spawn);
629+
RemoteExecutionService service = newRemoteExecutionService();
630+
RemoteAction action = service.buildRemoteAction(spawn, context);
631+
632+
// Doesn't check for dangling links, hence download succeeds.
633+
service.downloadOutputs(action, result);
634+
635+
Path path = execRoot.getRelative("outputs/a/b/link");
636+
assertThat(path.isSymbolicLink()).isTrue();
637+
assertThat(path.readSymbolicLink()).isEqualTo(PathFragment.create("foo"));
638+
assertThat(context.isLockOutputFilesCalled()).isTrue();
639+
}
640+
593641
@Test
594642
public void downloadOutputs_relativeSymlinkInDirectory_success() throws Exception {
595643
Tree tree =
@@ -2014,6 +2062,12 @@ private Spawn newSpawnFromResult(
20142062
outputs.add(output);
20152063
}
20162064

2065+
for (OutputSymlink symlink : result.getOutputSymlinks()) {
2066+
Path path = remotePathResolver.outputPathToLocalPath(symlink.getPath());
2067+
Artifact output = ActionsTestUtil.createArtifact(artifactRoot, path);
2068+
outputs.add(output);
2069+
}
2070+
20172071
return newSpawn(executionInfo, outputs.build());
20182072
}
20192073

0 commit comments

Comments
 (0)