diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java index 93ec205cc9b7eb..6191f65903a1c0 100644 --- a/src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java +++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java @@ -28,6 +28,7 @@ import com.google.devtools.build.lib.actions.FileArtifactValue; import com.google.devtools.build.lib.actions.MetadataProvider; import com.google.devtools.build.lib.actions.cache.VirtualActionInput; +import com.google.devtools.build.lib.actions.cache.VirtualActionInput.EmptyActionInput; import com.google.devtools.build.lib.profiler.Profiler; import com.google.devtools.build.lib.profiler.ProfilerTask; import com.google.devtools.build.lib.profiler.SilentCloseable; @@ -94,9 +95,11 @@ public void prefetchFiles( Map> downloadsToWaitFor = new HashMap<>(); for (ActionInput input : inputs) { if (input instanceof VirtualActionInput) { - VirtualActionInput virtualActionInput = (VirtualActionInput) input; - Path outputPath = execRoot.getRelative(virtualActionInput.getExecPath()); - SandboxHelpers.atomicallyWriteVirtualInput(virtualActionInput, outputPath, ".remote"); + if (!(input instanceof EmptyActionInput)) { + VirtualActionInput virtualActionInput = (VirtualActionInput) input; + Path outputPath = execRoot.getRelative(virtualActionInput.getExecPath()); + SandboxHelpers.atomicallyWriteVirtualInput(virtualActionInput, outputPath, ".remote"); + } } else { FileArtifactValue metadata = metadataProvider.getMetadata(input); if (metadata == null || !metadata.isRemote()) { diff --git a/src/test/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcherTest.java b/src/test/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcherTest.java index 4dded5281afcc0..591f4de356a440 100644 --- a/src/test/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcherTest.java +++ b/src/test/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcherTest.java @@ -36,6 +36,7 @@ import com.google.devtools.build.lib.actions.cache.VirtualActionInput; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; import com.google.devtools.build.lib.clock.JavaClock; +import com.google.devtools.build.lib.exec.SpawnInputExpander; import com.google.devtools.build.lib.remote.options.RemoteOptions; import com.google.devtools.build.lib.remote.util.DigestUtil; import com.google.devtools.build.lib.remote.util.InMemoryCacheClient; @@ -74,6 +75,9 @@ public void setUp() throws IOException { FileSystem fs = new InMemoryFileSystem(new JavaClock(), HASH_FUNCTION); execRoot = fs.getPath("/exec"); execRoot.createDirectoryAndParents(); + Path dev = fs.getPath("/dev"); + dev.createDirectory(); + dev.setWritable(false); artifactRoot = ArtifactRoot.asDerivedRoot(execRoot, "root"); artifactRoot.getRoot().asPath().createDirectoryAndParents(); options = Options.getDefaults(RemoteOptions.class); @@ -127,6 +131,23 @@ public void testStagingVirtualActionInput() throws Exception { assertThat(actionInputFetcher.downloadsInProgress).isEmpty(); } + @Test + public void testStagingEmptyVirtualActionInput() throws Exception { + // arrange + MetadataProvider metadataProvider = new StaticMetadataProvider(new HashMap<>()); + RemoteCache remoteCache = newCache(options, digestUtil, new HashMap<>()); + RemoteActionInputFetcher actionInputFetcher = + new RemoteActionInputFetcher(remoteCache, execRoot, RequestMetadata.getDefaultInstance()); + + // act + actionInputFetcher.prefetchFiles( + ImmutableList.of(SpawnInputExpander.EMPTY_FILE), metadataProvider); + + // assert that nothing happened + assertThat(actionInputFetcher.downloadedFiles()).isEmpty(); + assertThat(actionInputFetcher.downloadsInProgress).isEmpty(); + } + @Test public void testFileNotFound() throws Exception { // Test that we get an exception if an input file is missing