aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar Benjamin Peterson <bp@benjamin.pe>2017-08-21 18:41:45 +0200
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2017-08-22 09:13:25 +0200
commit3ff87f79c6a579272532bc676acdf924db1e8b59 (patch)
treecb108e0dddea1a592d16f123bdc49c1d5edea245 /src/test/java/com/google/devtools/build/lib
parent523a01c3f0db0d028c3cebd52065e52f56cb4967 (diff)
remote: don't fail build if upload fails
If the upload of local build artifacts fails, the build no longer fails but instead a warning is printed once. If --verbose_failures is specified, a detailed warning is printed for every failure. This helps fixing #2964, however it doesn't fully fix it due to timeouts and retries slowing the build significantly. Also, add some other tests related to fallback behavior. Change-Id: Ief49941f9bc7e0123b5d93456d77428686dd5268 PiperOrigin-RevId: 165938874
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib')
-rw-r--r--src/test/java/com/google/devtools/build/lib/BUILD1
-rw-r--r--src/test/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutionClientTest.java3
-rw-r--r--src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnCacheTest.java40
-rw-r--r--src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnRunnerTest.java145
4 files changed, 183 insertions, 6 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index 033da62bf1..cd0ea1419f 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -1081,6 +1081,7 @@ java_test(
":testutil",
"//src/main/java/com/google/devtools/build/lib:auth_and_tls_options",
"//src/main/java/com/google/devtools/build/lib:build-base",
+ "//src/main/java/com/google/devtools/build/lib:events",
"//src/main/java/com/google/devtools/build/lib:inmemoryfs",
"//src/main/java/com/google/devtools/build/lib:io",
"//src/main/java/com/google/devtools/build/lib:preconditions",
diff --git a/src/test/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutionClientTest.java b/src/test/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutionClientTest.java
index daed01ac5a..1db31cc372 100644
--- a/src/test/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutionClientTest.java
+++ b/src/test/java/com/google/devtools/build/lib/remote/GrpcRemoteExecutionClientTest.java
@@ -228,7 +228,8 @@ public class GrpcRemoteExecutionClientTest {
GrpcUtils.newCallCredentials(Options.getDefaults(AuthAndTLSOptions.class));
GrpcRemoteCache remoteCache =
new GrpcRemoteCache(channel, creds, options, retrier);
- client = new RemoteSpawnRunner(execRoot, options, null, true, remoteCache, executor);
+ client = new RemoteSpawnRunner(execRoot, options, null, true, /*cmdlineReporter=*/null,
+ remoteCache, executor);
inputDigest = fakeFileCache.createScratchInput(simpleSpawn.getInputFiles().get(0), "xyz");
}
diff --git a/src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnCacheTest.java b/src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnCacheTest.java
index 930815bcf5..43e4de4f54 100644
--- a/src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnCacheTest.java
+++ b/src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnCacheTest.java
@@ -16,12 +16,14 @@ package com.google.devtools.build.lib.remote;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.ActionInputFileCache;
import com.google.devtools.build.lib.actions.ActionInputHelper;
@@ -29,6 +31,10 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.actions.SimpleSpawn;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventKind;
+import com.google.devtools.build.lib.events.Reporter;
+import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.exec.SpawnCache.CacheHandle;
import com.google.devtools.build.lib.exec.SpawnInputExpander;
import com.google.devtools.build.lib.exec.SpawnResult;
@@ -77,6 +83,8 @@ public class RemoteSpawnCacheTest {
private RemoteSpawnCache cache;
private FileOutErr outErr;
+ private StoredEventHandler eventHandler = new StoredEventHandler();
+
private final SpawnExecutionPolicy simplePolicy =
new SpawnExecutionPolicy() {
@Override
@@ -155,7 +163,10 @@ public class RemoteSpawnCacheTest {
FileSystemUtils.createDirectoryAndParents(stderr.getParentDirectory());
outErr = new FileOutErr(stdout, stderr);
RemoteOptions options = Options.getDefaults(RemoteOptions.class);
- cache = new RemoteSpawnCache(execRoot, options, remoteCache);
+ Reporter reporter = new Reporter(new EventBus());
+ eventHandler = new StoredEventHandler();
+ reporter.addHandler(eventHandler);
+ cache = new RemoteSpawnCache(execRoot, options, remoteCache, false, reporter);
fakeFileCache.createScratchInput(simpleSpawn.getInputFiles().get(0), "xyz");
}
@@ -200,4 +211,31 @@ public class RemoteSpawnCacheTest {
eq(outputFiles),
eq(outErr));
}
+
+ @Test
+ public void printWarningIfUploadFails() throws Exception {
+ CacheHandle entry = cache.lookup(simpleSpawn, simplePolicy);
+ assertThat(entry.hasResult()).isFalse();
+ SpawnResult result = new SpawnResult.Builder().setExitCode(0).setStatus(Status.SUCCESS).build();
+ ImmutableList<Path> outputFiles = ImmutableList.of(fs.getPath("/random/file"));
+
+ doThrow(new IOException("cache down")).when(remoteCache).upload(any(ActionKey.class),
+ any(Path.class),
+ eq(outputFiles),
+ eq(outErr));
+
+ entry.store(result, outputFiles);
+ verify(remoteCache)
+ .upload(
+ any(ActionKey.class),
+ any(Path.class),
+ eq(outputFiles),
+ eq(outErr));
+
+ assertThat(eventHandler.getEvents()).hasSize(1);
+ Event evt = eventHandler.getEvents().get(0);
+ assertThat(evt.getKind()).isEqualTo(EventKind.WARNING);
+ assertThat(evt.getMessage()).contains("fail");
+ assertThat(evt.getMessage()).contains("upload");
+ }
}
diff --git a/src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnRunnerTest.java b/src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnRunnerTest.java
index 180a0dfcf1..b8e4f21ec0 100644
--- a/src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnRunnerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/remote/RemoteSpawnRunnerTest.java
@@ -17,6 +17,8 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -25,6 +27,7 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.ActionInputFileCache;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
@@ -33,6 +36,10 @@ import com.google.devtools.build.lib.actions.ExecutionRequirements;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.actions.SimpleSpawn;
import com.google.devtools.build.lib.actions.Spawn;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventKind;
+import com.google.devtools.build.lib.events.Reporter;
+import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.exec.SpawnInputExpander;
import com.google.devtools.build.lib.exec.SpawnResult;
import com.google.devtools.build.lib.exec.SpawnResult.Status;
@@ -112,7 +119,8 @@ public class RemoteSpawnRunnerTest {
options.remoteUploadLocalResults = true;
RemoteSpawnRunner runner =
- new RemoteSpawnRunner(execRoot, options, localRunner, true, cache, executor);
+ new RemoteSpawnRunner(execRoot, options, localRunner, true, /*cmdlineReporter=*/null,
+ cache, executor);
ExecuteResponse succeeded = ExecuteResponse.newBuilder().setResult(
ActionResult.newBuilder().setExitCode(0).build()).build();
@@ -154,7 +162,8 @@ public class RemoteSpawnRunnerTest {
options.remoteUploadLocalResults = true;
RemoteSpawnRunner runner =
- new RemoteSpawnRunner(execRoot, options, localRunner, true, cache, null);
+ new RemoteSpawnRunner(execRoot, options, localRunner, true, /*cmdlineReporter=*/null,
+ cache, null);
// Throw an IOException to trigger the local fallback.
when(executor.executeRemotely(any(ExecuteRequest.class))).thenThrow(IOException.class);
@@ -190,7 +199,8 @@ public class RemoteSpawnRunnerTest {
options.remoteUploadLocalResults = true;
RemoteSpawnRunner runner =
- spy(new RemoteSpawnRunner(execRoot, options, localRunner, true, cache, null));
+ spy(new RemoteSpawnRunner(execRoot, options, localRunner, true, /*cmdlineReporter=*/null,
+ cache, null));
Spawn spawn = new SimpleSpawn(
new FakeOwner("foo", "bar"),
@@ -236,7 +246,8 @@ public class RemoteSpawnRunnerTest {
SpawnExecutionPolicy policy = new FakeSpawnExecutionPolicy(spawn);
RemoteSpawnRunner runner =
- spy(new RemoteSpawnRunner(execRoot, options, localRunner, true, cache, null));
+ spy(new RemoteSpawnRunner(execRoot, options, localRunner, true, /*cmdlineReporter=*/null,
+ cache, null));
try {
runner.exec(spawn, policy);
@@ -246,6 +257,132 @@ public class RemoteSpawnRunnerTest {
}
}
+ @Test
+ @SuppressWarnings("unchecked")
+ public void printWarningIfCacheIsDown() throws Exception {
+ // If we try to upload to a local cache, that is down a warning should be printed.
+
+ RemoteOptions options = Options.getDefaults(RemoteOptions.class);
+ options.remoteUploadLocalResults = true;
+ options.remoteLocalFallback = true;
+
+ Reporter reporter = new Reporter(new EventBus());
+ StoredEventHandler eventHandler = new StoredEventHandler();
+ reporter.addHandler(eventHandler);
+
+ RemoteSpawnRunner runner =
+ new RemoteSpawnRunner(execRoot, options, localRunner, false, reporter, cache, null);
+
+ Spawn spawn =
+ new SimpleSpawn(
+ new FakeOwner("foo", "bar"),
+ /*arguments=*/ ImmutableList.of(),
+ /*environment=*/ ImmutableMap.of(),
+ /*executionInfo=*/ ImmutableMap.of(),
+ /*inputs=*/ ImmutableList.of(),
+ /*outputs=*/ ImmutableList.<ActionInput>of(),
+ ResourceSet.ZERO);
+ SpawnExecutionPolicy policy = new FakeSpawnExecutionPolicy(spawn);
+
+ when(cache.getCachedActionResult(any(ActionKey.class)))
+ .thenThrow(new IOException("cache down"));
+
+ doThrow(new IOException("cache down")).when(cache)
+ .upload(any(ActionKey.class), any(Path.class), any(Collection.class),
+ any(FileOutErr.class));
+
+ SpawnResult res = new SpawnResult.Builder().setStatus(Status.SUCCESS).setExitCode(0).build();
+ when(localRunner.exec(eq(spawn), eq(policy))).thenReturn(res);
+
+ assertThat(runner.exec(spawn, policy)).isEqualTo(res);
+
+ verify(localRunner).exec(eq(spawn), eq(policy));
+
+ assertThat(eventHandler.getEvents()).hasSize(1);
+
+ Event evt = eventHandler.getEvents().get(0);
+ assertThat(evt.getKind()).isEqualTo(EventKind.WARNING);
+ assertThat(evt.getMessage()).contains("fail");
+ assertThat(evt.getMessage()).contains("upload");
+ }
+
+ @Test
+ public void fallbackFails() throws Exception {
+ // Errors from the fallback runner should be propogated out of the remote runner.
+
+ RemoteOptions options = Options.getDefaults(RemoteOptions.class);
+ options.remoteUploadLocalResults = true;
+ options.remoteLocalFallback = true;
+
+ RemoteSpawnRunner runner =
+ new RemoteSpawnRunner(execRoot, options, localRunner, true, /*cmdlineReporter=*/null,
+ cache, null);
+
+ Spawn spawn =
+ new SimpleSpawn(
+ new FakeOwner("foo", "bar"),
+ /*arguments=*/ ImmutableList.of(),
+ /*environment=*/ ImmutableMap.of(),
+ /*executionInfo=*/ ImmutableMap.of(),
+ /*inputs=*/ ImmutableList.of(),
+ /*outputs=*/ ImmutableList.<ActionInput>of(),
+ ResourceSet.ZERO);
+ SpawnExecutionPolicy policy = new FakeSpawnExecutionPolicy(spawn);
+
+ when(cache.getCachedActionResult(any(ActionKey.class))).thenReturn(null);
+
+ IOException err = new IOException("local execution error");
+ when(localRunner.exec(eq(spawn), eq(policy))).thenThrow(err);
+
+ try {
+ runner.exec(spawn, policy);
+ fail("expected IOException to be raised");
+ } catch (IOException e) {
+ assertThat(e).isSameAs(err);
+ }
+
+ verify(localRunner).exec(eq(spawn), eq(policy));
+ }
+
+ @Test
+ public void cacheDownloadFailureTriggersRemoteExecution() throws Exception {
+ // If downloading a cached action fails, remote execution should be tried.
+
+ RemoteOptions options = Options.getDefaults(RemoteOptions.class);
+
+ RemoteSpawnRunner runner =
+ new RemoteSpawnRunner(execRoot, options, localRunner, true, /*cmdlineReporter=*/null,
+ cache, executor);
+
+ ActionResult cachedResult = ActionResult.newBuilder().setExitCode(0).build();
+ when(cache.getCachedActionResult(any(ActionKey.class))).thenReturn(cachedResult);
+ doThrow(CacheNotFoundException.class)
+ .when(cache)
+ .download(eq(cachedResult), any(Path.class), any(FileOutErr.class));
+ ActionResult execResult = ActionResult.newBuilder().setExitCode(31).build();
+ ExecuteResponse succeeded = ExecuteResponse.newBuilder().setResult(execResult).build();
+ when(executor.executeRemotely(any(ExecuteRequest.class))).thenReturn(succeeded);
+ doNothing().when(cache).download(eq(execResult), any(Path.class), any(FileOutErr.class));
+
+ Spawn spawn =
+ new SimpleSpawn(
+ new FakeOwner("foo", "bar"),
+ /*arguments=*/ ImmutableList.of(),
+ /*environment=*/ ImmutableMap.of(),
+ /*executionInfo=*/ ImmutableMap.of(),
+ /*inputs=*/ ImmutableList.of(),
+ /*outputs=*/ ImmutableList.<ActionInput>of(),
+ ResourceSet.ZERO);
+
+ SpawnExecutionPolicy policy = new FakeSpawnExecutionPolicy(spawn);
+
+ SpawnResult res = runner.exec(spawn, policy);
+ assertThat(res.status()).isEqualTo(Status.SUCCESS);
+ assertThat(res.exitCode()).isEqualTo(31);
+
+ verify(executor).executeRemotely(any(ExecuteRequest.class));
+ }
+
// TODO(buchgr): Extract a common class to be used for testing.
class FakeSpawnExecutionPolicy implements SpawnExecutionPolicy {