Allow Bazel in JUnit black box tests to fail.
This is needed to verify the failure in case we do not know the expected error code exactly.
Closes #7616.
PiperOrigin-RevId: 236831845
diff --git a/src/test/java/com/google/devtools/build/lib/blackbox/framework/BuilderRunner.java b/src/test/java/com/google/devtools/build/lib/blackbox/framework/BuilderRunner.java
index 6927658..1d69d92 100644
--- a/src/test/java/com/google/devtools/build/lib/blackbox/framework/BuilderRunner.java
+++ b/src/test/java/com/google/devtools/build/lib/blackbox/framework/BuilderRunner.java
@@ -50,6 +50,7 @@
private boolean useDefaultRc = true;
private int errorCode = 0;
private List<String> flags;
+ private boolean shouldFail;
/**
* Creates the BuilderRunner
@@ -106,6 +107,16 @@
}
/**
+ * Expect Bazel to fail. This method is needed when the exact error code can not be specified.
+ *
+ * @return this BuildRunner instance
+ */
+ public BuilderRunner shouldFail() {
+ this.shouldFail = true;
+ return this;
+ }
+
+ /**
* Sets timeout value for the Bazel process invocation. If not called, default value is used,
* which is calculated from the test parameters. See {@link
* BlackBoxTestContext#getTestTimeoutMillis()}. If the invocation time exceeds timeout, {@link
@@ -271,6 +282,7 @@
// we need to allow the error output stream be not empty
.setExpectedEmptyError(false)
.setExpectedExitCode(errorCode)
+ .setExpectedToFail(shouldFail)
.build();
return new ProcessRunner(parameters, executorService).runSynchronously();
}
diff --git a/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessParameters.java b/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessParameters.java
index cef17f4..0113b30 100644
--- a/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessParameters.java
+++ b/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessParameters.java
@@ -34,6 +34,8 @@
abstract int expectedExitCode();
+ abstract boolean expectedToFail();
+
abstract boolean expectedEmptyError();
abstract Optional<ImmutableMap<String, String>> environment();
@@ -48,6 +50,7 @@
return new AutoValue_ProcessParameters.Builder()
.setExpectedExitCode(0)
.setExpectedEmptyError(true)
+ .setExpectedToFail(false)
.setTimeoutMillis(30 * 1000)
.setArguments();
}
@@ -70,6 +73,8 @@
public abstract Builder setExpectedExitCode(int value);
+ public abstract Builder setExpectedToFail(boolean value);
+
public abstract Builder setExpectedEmptyError(boolean value);
public abstract Builder setEnvironment(ImmutableMap<String, String> map);
diff --git a/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessRunner.java b/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessRunner.java
index 2436c8f..bfff4d4 100644
--- a/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessRunner.java
+++ b/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessRunner.java
@@ -34,7 +34,6 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@@ -70,7 +69,7 @@
commandParts.add(parameters.name());
commandParts.addAll(args);
- logger.info("Running: " + commandParts.stream().collect(Collectors.joining(" ")));
+ logger.info("Running: " + String.join(" ", commandParts));
ProcessBuilder processBuilder = new ProcessBuilder(commandParts);
processBuilder.directory(parameters.workingDirectory());
@@ -107,12 +106,25 @@
? outReader.get()
: Files.readAllLines(parameters.redirectOutput().get());
- if (parameters.expectedExitCode() != process.exitValue()) {
+ int exitValue = process.exitValue();
+ boolean processFailed = exitValue != 0;
+ boolean expectedToFail = parameters.expectedToFail() || parameters.expectedExitCode() != 0;
+ if (processFailed != expectedToFail) {
+ // We want to check the exact exit code if it was explicitly set to something;
+ if (parameters.expectedExitCode() != 0 && parameters.expectedExitCode() != exitValue) {
+ throw new ProcessRunnerException(
+ String.format(
+ "Expected exit code %d, but found %d.\nError: %s\nOutput: %s",
+ parameters.expectedExitCode(),
+ exitValue,
+ StringUtilities.joinLines(err),
+ StringUtilities.joinLines(out)));
+ }
throw new ProcessRunnerException(
String.format(
- "Expected exit code %d, but found %d.\nError: %s\nOutput: %s",
- parameters.expectedExitCode(),
- process.exitValue(),
+ "Expected to %s, but %s.\nError: %s\nOutput: %s",
+ expectedToFail ? "fail" : "succeed",
+ processFailed ? "failed" : "succeeded",
StringUtilities.joinLines(err),
StringUtilities.joinLines(out)));
}
@@ -123,7 +135,7 @@
"Expected empty error stream, but found: " + StringUtilities.joinLines(err));
}
}
- return ProcessResult.create(parameters.expectedExitCode(), out, err);
+ return ProcessResult.create(exitValue, out, err);
} finally {
process.destroy();
}
diff --git a/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessRunnerTest.java b/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessRunnerTest.java
index ed4cb78..c1355ec 100644
--- a/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessRunnerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/blackbox/framework/ProcessRunnerTest.java
@@ -80,7 +80,7 @@
}
@Test
- public void testFailure() throws Exception {
+ public void testFailureWithCode() throws Exception {
Files.write(
path, createScriptText(/* exit code */ 124, /* output */ null, /* error */ "Failure"));
@@ -94,6 +94,20 @@
}
@Test
+ public void testFailure() throws Exception {
+ Files.write(
+ path, createScriptText(/* exit code */ 124, /* output */ null, /* error */ "Failure"));
+
+ ProcessParameters parameters =
+ createBuilder().setExpectedToFail(true).setExpectedEmptyError(false).build();
+ ProcessResult result = new ProcessRunner(parameters, executorService).runSynchronously();
+
+ assertThat(result.exitCode()).isEqualTo(124);
+ assertThat(result.outString()).isEmpty();
+ assertThat(result.errString()).isEqualTo("Failure");
+ }
+
+ @Test
public void testTimeout() throws Exception {
// Windows script to sleep 5 seconds, so that we can test timeout.
// This script finds PowerShell using %systemroot% variable, which we assume is always