diff options
15 files changed, 157 insertions, 101 deletions
diff --git a/scripts/bootstrap/compile.sh b/scripts/bootstrap/compile.sh index 09bb32cff1..2cb8e58710 100755 --- a/scripts/bootstrap/compile.sh +++ b/scripts/bootstrap/compile.sh @@ -227,6 +227,31 @@ cat <<'EOF' >${ARCHIVE_DIR}/_embedded_binaries/process-wrapper${EXE_EXT} #!/bin/sh # Dummy process wrapper, does not support timeout shift 2 +stdout="$1" +stderr="$2" +shift 2 + +if [ "$stdout" = "-" ] +then + if [ "$stderr" = "-" ] + then + "$@" + exit $? + else + "$@" 2>"$stderr" + exit $? + fi +else + if [ "$stderr" = "-" ] + then + "$@" >"$stdout" + exit $? + else + "$@" 2>"$stderr" >"$stdout" + exit $? + fi +fi + "$@" exit $? diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java index 0a85494d99..729bace0ef 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java @@ -254,6 +254,8 @@ public class RunCommand implements BlazeCommand { cmdLine.add(env.getExecRoot().getRelative(processWrapperPath).getPathString()); cmdLine.add("-1"); cmdLine.add("15"); + cmdLine.add("-"); + cmdLine.add("-"); } List<String> prettyCmdLine = new ArrayList<>(); // Insert the command prefix specified by the "--run_under=<command-prefix>" option diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java index b60f47dbfd..9516fe2753 100644 --- a/src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java +++ b/src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java @@ -190,8 +190,8 @@ public class NamespaceSandboxRunner { cmd.execute( /* stdin */ new byte[] {}, Command.NO_OBSERVER, - outErr.getOutputFile(), - outErr.getErrorFile(), + outErr.getOutputStream(), + outErr.getErrorStream(), /* killSubprocessOnInterrupt */ true); } catch (CommandException e) { boolean timedOut = false; diff --git a/src/main/java/com/google/devtools/build/lib/shell/Command.java b/src/main/java/com/google/devtools/build/lib/shell/Command.java index 8d40c15e24..84f78d2ae3 100644 --- a/src/main/java/com/google/devtools/build/lib/shell/Command.java +++ b/src/main/java/com/google/devtools/build/lib/shell/Command.java @@ -410,10 +410,12 @@ public final class Command { } /** - * Like {@link #execute(byte[], KillableObserver, OutputStream, OutputStream, boolean)} but allows - * using files to redirect stdOut and stdErr. This gives better performance as the data doesn't - * flow through the JVM but instead is written directly to the corresponding file descriptors by - * the process. + * Execute this command with given input to stdin; this stream is closed when the process + * terminates, and exceptions raised when closing this stream are ignored. This call blocks until + * the process completes or an error occurs. The caller provides {@link OutputStream} instances + * into which the process writes its stdout/stderr output; these streams are <em>not</em> closed + * when the process terminates. The given {@link KillableObserver} may also terminate the process + * early while running. * * <p>If stdOut or stdErr is {@code null}, it will be redirected to /dev/null. */ @@ -680,12 +682,10 @@ public final class Command { final Subprocess process = startProcess(); - if (outErrConsumers != null) { - outErrConsumers.logConsumptionStrategy(); + outErrConsumers.logConsumptionStrategy(); - outErrConsumers.registerInputs( - process.getInputStream(), process.getErrorStream(), closeOutputStreams); - } + outErrConsumers.registerInputs( + process.getInputStream(), process.getErrorStream(), closeOutputStreams); processInput(stdinInput, process); @@ -826,12 +826,10 @@ public final class Command { log.finer(status.toString()); try { - if (outErr != null) { - if (Thread.currentThread().isInterrupted()) { - outErr.cancel(); - } else { - outErr.waitForCompletion(); - } + if (Thread.currentThread().isInterrupted()) { + outErr.cancel(); + } else { + outErr.waitForCompletion(); } } catch (IOException ioe) { CommandResult noOutputResult = @@ -854,10 +852,7 @@ public final class Command { } CommandResult result = - new CommandResult( - outErr != null ? outErr.getAccumulatedOut() : CommandResult.NO_OUTPUT_COLLECTED, - outErr != null ? outErr.getAccumulatedErr() : CommandResult.NO_OUTPUT_COLLECTED, - status); + new CommandResult(outErr.getAccumulatedOut(), outErr.getAccumulatedErr(), status); result.logThis(); if (status.success()) { return result; diff --git a/src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java b/src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java index 4a666832e1..6c5df1b864 100644 --- a/src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java +++ b/src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java @@ -99,6 +99,11 @@ public class StandaloneSpawnStrategy implements SpawnActionContext { args.add(processWrapper.getPathString()); args.add(Integer.toString(timeout)); args.add("5"); /* kill delay: give some time to print stacktraces and whatnot. */ + + // TODO(bazel-team): use process-wrapper redirection so we don't have to + // pass test logs through the Java heap. + args.add("-"); /* stdout. */ + args.add("-"); /* stderr. */ } args.addAll(spawn.getArguments()); @@ -111,8 +116,8 @@ public class StandaloneSpawnStrategy implements SpawnActionContext { cmd.execute( /* stdin */ new byte[] {}, Command.NO_OBSERVER, - outErr.getOutputFile(), - outErr.getErrorFile(), + outErr.getOutputStream(), + outErr.getErrorStream(), /*killSubprocessOnInterrupt*/ true); } catch (AbnormalTerminationException e) { TerminationStatus status = e.getResult().getTerminationStatus(); diff --git a/src/main/java/com/google/devtools/build/lib/util/io/FileOutErr.java b/src/main/java/com/google/devtools/build/lib/util/io/FileOutErr.java index add8a0f792..b1e0faa68e 100644 --- a/src/main/java/com/google/devtools/build/lib/util/io/FileOutErr.java +++ b/src/main/java/com/google/devtools/build/lib/util/io/FileOutErr.java @@ -19,7 +19,6 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -52,6 +51,18 @@ public class FileOutErr extends OutErr { this(new FileRecordingOutputStream(stdout), new FileRecordingOutputStream(stderr)); } + /** + * Creates a new FileOutErr that writes its input to the file specified by output. Both + * stdout/stderr will be copied into the single file. + * + * @param output The file for the both stdout and stderr of this outErr. + */ + public FileOutErr(Path output) { + // We don't need to create a synchronized funnel here, like in the OutErr -- The + // respective functions in the FileRecordingOutputStream take care of locking. + this(new FileRecordingOutputStream(output)); + } + protected FileOutErr(AbstractFileRecordingOutputStream out, AbstractFileRecordingOutputStream err) { super(out, err); @@ -113,32 +124,6 @@ public class FileOutErr extends OutErr { return getFileErrorStream().getFile(); } - /** - * Returns the {@link File} this OutErr uses to buffer stdout - * - * <p>The user must ensure that no other process is writing to the files at time of creation. - * - * @return the file object with the contents of stdout - */ - public File getOutputFile() { - if (getFileOutputStream().getFile() != null) { - return getFileOutputStream().getFile().getPathFile(); - } - return null; - } - - /** - * Returns the {@link File} this OutErr uses to buffer stderr. - * - * @return the file object with the contents of stderr - */ - public File getErrorFile() { - if (getFileErrorStream().getFile() != null) { - return getFileErrorStream().getFile().getPathFile(); - } - return null; - } - /** Interprets the captured out content as an {@code ISO-8859-1} encoded string. */ public String outAsLatin1() { return getFileOutputStream().getRecordedOutput(); diff --git a/src/main/tools/namespace-sandbox.c b/src/main/tools/namespace-sandbox.c index dfae81a9d8..580225da91 100644 --- a/src/main/tools/namespace-sandbox.c +++ b/src/main/tools/namespace-sandbox.c @@ -67,6 +67,8 @@ struct Options { int create_netns; // If 1, create a new network namespace (-n) int fake_root; // Pretend to be root inside the namespace (-r) bool debug; // Whether to print debugging messages (-D) + const char *stdout_path; // Where to redirect stdout (-l) + const char *stderr_path; // Where to redirect stderr (-L) char *const *args; // Command to run (--) }; @@ -145,6 +147,8 @@ static void Usage(int argc, char *const *argv, const char *fmt, ...) { " -n if set, a new network namespace will be created\n" " -r if set, make the uid/gid be root, otherwise use nobody\n" " -D if set, debug info will be printed\n" + " -l <file> redirect stdout to a file\n" + " -L <file> redirect stderr to a file\n" " @FILE read newline-separated arguments from FILE\n"); exit(EXIT_FAILURE); } @@ -260,7 +264,7 @@ static void ParseCommandLine(int argc, char *const *argv) { extern int optind, optopt; int c; - while ((c = getopt(argc, argv, ":CS:W:T:t:d:M:m:nrD")) != -1) { + while ((c = getopt(argc, argv, ":CS:W:T:t:d:M:m:nrDl:L:")) != -1) { switch (c) { case 'C': // Shortcut for the "does this system support sandboxing" check. @@ -336,6 +340,22 @@ static void ParseCommandLine(int argc, char *const *argv) { case 'D': opt.debug = true; break; + case 'l': + if (opt.stdout_path == NULL) { + opt.stdout_path = optarg; + } else { + Usage(argc, argv, + "Cannot redirect stdout to more than one destination."); + } + break; + case 'L': + if (opt.stderr_path == NULL) { + opt.stderr_path = optarg; + } else { + Usage(argc, argv, + "Cannot redirect stderr to more than one destination."); + } + break; case '?': Usage(argc, argv, "Unrecognized argument: -%c (%d)", optopt, optind); break; @@ -756,6 +776,9 @@ int main(int argc, char *const argv[]) { int uid = SwitchToEuid(); int gid = SwitchToEgid(); + RedirectStdout(opt.stdout_path); + RedirectStderr(opt.stderr_path); + PRINT_DEBUG("sandbox root is %s\n", opt.sandbox_root); PRINT_DEBUG("working dir is %s\n", (opt.working_dir != NULL) ? opt.working_dir : "/ (default)"); diff --git a/src/main/tools/process-tools.c b/src/main/tools/process-tools.c index 88343c96c8..9dddfee5f5 100644 --- a/src/main/tools/process-tools.c +++ b/src/main/tools/process-tools.c @@ -47,6 +47,24 @@ int SwitchToEgid() { return egid; } +void Redirect(const char *target_path, int fd, const char *name) { + if (target_path != NULL && strcmp(target_path, "-") != 0) { + int fd_out; + const int flags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND; + CHECK_CALL(fd_out = open(target_path, flags, 0666)); + CHECK_CALL(dup2(fd_out, fd)); + CHECK_CALL(close(fd_out)); + } +} + +void RedirectStdout(const char *stdout_path) { + Redirect(stdout_path, STDOUT_FILENO, "stdout"); +} + +void RedirectStderr(const char *stderr_path) { + Redirect(stderr_path, STDERR_FILENO, "stderr"); +} + void KillEverything(int pgrp, bool gracefully, double graceful_kill_delay) { if (gracefully) { kill(-pgrp, SIGTERM); diff --git a/src/main/tools/process-tools.h b/src/main/tools/process-tools.h index 873aeaf377..a0ba38816d 100644 --- a/src/main/tools/process-tools.h +++ b/src/main/tools/process-tools.h @@ -52,6 +52,12 @@ int SwitchToEuid(); // Switch completely to the effective gid. int SwitchToEgid(); +// Redirect stdout to the file stdout_path (but not if stdout_path is "-"). +void RedirectStdout(const char *stdout_path); + +// Redirect stderr to the file stdout_path (but not if stderr_path is "-"). +void RedirectStderr(const char *stderr_path); + // Make sure the process group "pgrp" and all its subprocesses are killed. // If "gracefully" is true, sends SIGTERM first and after a timeout of // "graceful_kill_delay" seconds, sends SIGKILL. diff --git a/src/main/tools/process-wrapper.c b/src/main/tools/process-wrapper.c index bee74739d5..07ae840a52 100644 --- a/src/main/tools/process-wrapper.c +++ b/src/main/tools/process-wrapper.c @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -// process-wrapper runs a subprocess with a given timeout (optional). Upon exit, -// whether from normal termination or timeout, the subprocess (and any of its -// children) is killed. +// process-wrapper runs a subprocess with a given timeout (optional), +// redirecting stdout and stderr to given files. Upon exit, whether +// from normal termination or timeout, the subprocess (and any of its children) +// is killed. // // The exit status of this program is whatever the child process returned, // unless process-wrapper receives a signal. ie, on SIGTERM this program will @@ -48,6 +49,8 @@ static volatile sig_atomic_t global_signal; struct Options { double timeout_secs; double kill_delay_secs; + const char *stdout_path; + const char *stderr_path; char *const *args; }; @@ -56,7 +59,8 @@ struct Options { // string for the error message to print. static void Usage(char *const *argv) { fprintf(stderr, - "Usage: %s <timeout-secs> <kill-delay-secs> <command> [args] ...\n", + "Usage: %s <timeout-secs> <kill-delay-secs> <stdout-redirect> " + "<stderr-redirect> <command> [args] ...\n", argv[0]); exit(EXIT_FAILURE); } @@ -64,7 +68,7 @@ static void Usage(char *const *argv) { // Parse the command line flags and return the result in an Options structure // passed as argument. static void ParseCommandLine(int argc, char *const *argv, struct Options *opt) { - if (argc <= 3) { + if (argc <= 5) { Usage(argv); } @@ -75,6 +79,8 @@ static void ParseCommandLine(int argc, char *const *argv, struct Options *opt) { if (sscanf(*argv++, "%lf", &opt->kill_delay_secs) != 1) { DIE("kill_delay_secs is not a real number.\n"); } + opt->stdout_path = *argv++; + opt->stderr_path = *argv++; opt->args = argv; } @@ -154,6 +160,9 @@ int main(int argc, char *argv[]) { SwitchToEuid(); SwitchToEgid(); + RedirectStdout(opt.stdout_path); + RedirectStderr(opt.stderr_path); + SpawnCommand(opt.args, opt.timeout_secs); return 0; diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index 7e7575d84f..af217e0961 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -964,7 +964,6 @@ java_test( "//src/main/java/com/google/devtools/build/lib:build-base", "//src/main/java/com/google/devtools/build/lib:clock", "//src/main/java/com/google/devtools/build/lib:events", - "//src/main/java/com/google/devtools/build/lib:io", "//src/main/java/com/google/devtools/build/lib:os_util", "//src/main/java/com/google/devtools/build/lib:shell", "//src/main/java/com/google/devtools/build/lib:util", @@ -992,7 +991,6 @@ java_test( "//src/main/java/com/google/devtools/build/lib:build-base", "//src/main/java/com/google/devtools/build/lib:clock", "//src/main/java/com/google/devtools/build/lib:events", - "//src/main/java/com/google/devtools/build/lib:io", "//src/main/java/com/google/devtools/build/lib:os_util", "//src/main/java/com/google/devtools/build/lib:shell", "//src/main/java/com/google/devtools/build/lib:util", diff --git a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java index 492425caa6..771162fe0e 100644 --- a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java @@ -29,9 +29,9 @@ import com.google.devtools.build.lib.events.Reporter; import com.google.devtools.build.lib.exec.ExecutionOptions; import com.google.devtools.build.lib.testutil.BlazeTestUtils; import com.google.devtools.build.lib.testutil.TestConstants; +import com.google.devtools.build.lib.testutil.TestFileOutErr; import com.google.devtools.build.lib.testutil.TestUtils; import com.google.devtools.build.lib.util.BlazeClock; -import com.google.devtools.build.lib.util.io.FileOutErr; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; @@ -56,7 +56,7 @@ public class LinuxSandboxedStrategyTestCase { protected BlazeExecutor executor; protected BlazeDirectories blazeDirs; - protected FileOutErr outErr; + protected TestFileOutErr outErr = new TestFileOutErr(); protected String out() { return outErr.outAsLatin1(); @@ -70,9 +70,6 @@ public class LinuxSandboxedStrategyTestCase { public final void createDirectoriesAndExecutor() throws Exception { Path testRoot = createTestRoot(); - outErr = - new FileOutErr(testRoot.getRelative("test_out.log"), testRoot.getRelative("test_err.log")); - workspaceDir = testRoot.getRelative("workspace"); workspaceDir.createDirectory(); diff --git a/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java b/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java index 6d20ba7118..580bff9ba5 100644 --- a/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java +++ b/src/test/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategyTest.java @@ -39,10 +39,10 @@ import com.google.devtools.build.lib.exec.SingleBuildFileCache; import com.google.devtools.build.lib.rules.apple.AppleConfiguration; import com.google.devtools.build.lib.testutil.BlazeTestUtils; import com.google.devtools.build.lib.testutil.TestConstants; +import com.google.devtools.build.lib.testutil.TestFileOutErr; import com.google.devtools.build.lib.testutil.TestUtils; import com.google.devtools.build.lib.util.BlazeClock; import com.google.devtools.build.lib.util.OS; -import com.google.devtools.build.lib.util.io.FileOutErr; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; @@ -66,7 +66,6 @@ public class StandaloneSpawnStrategyTest { private Reporter reporter = new Reporter(PrintingEventHandler.ERRORS_AND_WARNINGS_TO_STDERR); private BlazeExecutor executor; private FileSystem fileSystem; - private FileOutErr outErr; private Path createTestRoot() throws IOException { fileSystem = FileSystems.getNativeFileSystem(); @@ -86,9 +85,6 @@ public class StandaloneSpawnStrategyTest { Path workspaceDir = testRoot.getRelative(TestConstants.WORKSPACE_NAME); workspaceDir.createDirectory(); - outErr = - new FileOutErr(testRoot.getRelative("test_out.log"), testRoot.getRelative("test_err.log")); - // setup output base & directories Path outputBase = testRoot.getRelative("outputBase"); outputBase.createDirectory(); @@ -123,6 +119,8 @@ public class StandaloneSpawnStrategyTest { new ActionsTestUtil.NullAction()); } + private TestFileOutErr outErr = new TestFileOutErr(); + private String out() { return outErr.outAsLatin1(); } @@ -142,7 +140,6 @@ public class StandaloneSpawnStrategyTest { private void run(Spawn spawn) throws Exception { executor.getSpawnActionContext(spawn.getMnemonic()).exec(spawn, createContext()); } - private ActionExecutionContext createContext() { Path execRoot = executor.getExecRoot(); return new ActionExecutionContext( diff --git a/src/test/shell/bazel/namespace-runner_test.sh b/src/test/shell/bazel/namespace-runner_test.sh index 5c05f98beb..da6857bda1 100755 --- a/src/test/shell/bazel/namespace-runner_test.sh +++ b/src/test/shell/bazel/namespace-runner_test.sh @@ -49,78 +49,74 @@ function assert_output() { } function test_basic_functionality() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -- /bin/echo hi there >$OUT 2>$ERR || fail + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -l $OUT -L $ERR -- /bin/echo hi there || fail assert_output "hi there" "" } function test_default_user_is_nobody() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -- /usr/bin/id >$OUT 2>$ERR || fail + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -l $OUT -L $ERR -- /usr/bin/id || fail assert_output "uid=65534 gid=65534 groups=65534" "" } function test_user_switched_to_root() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -r -- /usr/bin/id >$OUT 2>$ERR || fail + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -r -l $OUT -L $ERR -- /usr/bin/id || fail assert_contains "uid=0 gid=0" "$OUT" } function test_network_namespace() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -n -- /bin/ip link ls >$OUT 2>$ERR || fail + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -n -l $OUT -L $ERR -- /bin/ip link ls || fail assert_contains "LOOPBACK,UP" "$OUT" } function test_ping_loopback() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -n -r -- /bin/ping -c 1 127.0.0.1 >$OUT 2>$ERR || fail + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -n -r -l $OUT -L $ERR -- /bin/ping -c 1 127.0.0.1 || fail assert_contains "1 received" "$OUT" } function test_to_stderr() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -- /bin/bash -c "/bin/echo hi there >&2" >$OUT 2>$ERR || fail + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -l $OUT -L $ERR -- /bin/bash -c "/bin/echo hi there >&2" || fail assert_output "" "hi there" } function test_exit_code() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -- /bin/bash -c "exit 71" >$OUT 2>$ERR || code=$? + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -l $OUT -L $ERR -- /bin/bash -c "exit 71" || code=$? assert_equals 71 "$code" } function test_signal_death() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -- /bin/bash -c 'kill -ABRT $$' >$OUT 2>$ERR || code=$? + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -l $OUT -L $ERR -- /bin/bash -c 'kill -ABRT $$' || code=$? assert_equals 134 "$code" # SIGNAL_BASE + SIGABRT = 128 + 6 } function test_signal_catcher() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -T 2 -t 3 -- /bin/bash -c \ - 'trap "echo later; exit 0" SIGINT SIGTERM SIGALRM; sleep 1000' >$OUT 2>$ERR || code=$? + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -T 2 -t 3 -l $OUT -L $ERR -- /bin/bash -c \ + 'trap "echo later; exit 0" SIGINT SIGTERM SIGALRM; sleep 1000' || code=$? assert_equals 142 "$code" # SIGNAL_BASE + SIGALRM = 128 + 14 assert_stdout "later" } function test_basic_timeout() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -T 3 -t 3 -- /bin/bash -c \ - "echo before; sleep 1000; echo after" >$OUT 2>$ERR && fail + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -T 3 -t 3 -l $OUT -L $ERR -- /bin/bash -c "echo before; sleep 1000; echo after" && fail assert_output "before" "" } function test_timeout_grace() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -T 2 -t 3 -- /bin/bash -c \ - 'trap "echo -n before; sleep 1; echo -n after; exit 0" SIGINT SIGTERM SIGALRM; sleep 1000' \ - >$OUT 2>$ERR || code=$? + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -T 2 -t 3 -l $OUT -L $ERR -- /bin/bash -c \ + 'trap "echo -n before; sleep 1; echo -n after; exit 0" SIGINT SIGTERM SIGALRM; sleep 1000' || code=$? assert_equals 142 "$code" # SIGNAL_BASE + SIGALRM = 128 + 14 assert_stdout "beforeafter" } function test_timeout_kill() { - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -T 2 -t 3 -- /bin/bash -c \ - 'trap "echo before; sleep 1000; echo after; exit 0" SIGINT SIGTERM SIGALRM; sleep 1000' \ - >$OUT 2>$ERR || code=$? + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -T 2 -t 3 -l $OUT -L $ERR -- /bin/bash -c \ + 'trap "echo before; sleep 1000; echo after; exit 0" SIGINT SIGTERM SIGALRM; sleep 1000' || code=$? assert_equals 142 "$code" # SIGNAL_BASE + SIGALRM = 128 + 14 assert_stdout "before" } function test_debug_logging() { touch ${TEST_TMPDIR}/testfile - $namespace_sandbox $SANDBOX_DEFAULT_OPTS -D -M ${TEST_TMPDIR}/testfile -m /tmp/sandboxed_testfile \ - -- /bin/true >$OUT 2>$ERR || code=$? + $namespace_sandbox $SANDBOX_DEFAULT_OPTS -D -M ${TEST_TMPDIR}/testfile -m /tmp/sandboxed_testfile -l $OUT -L $ERR -- /bin/true || code=$? assert_contains "mount: /usr/bin\$" "$ERR" assert_contains "mount: ${TEST_TMPDIR}/testfile -> <sandbox>/tmp/sandboxed_testfile\$" "$ERR" } diff --git a/src/test/shell/bazel/process-wrapper_test.sh b/src/test/shell/bazel/process-wrapper_test.sh index 93bf4d5d3a..a46b4500aa 100755 --- a/src/test/shell/bazel/process-wrapper_test.sh +++ b/src/test/shell/bazel/process-wrapper_test.sh @@ -41,37 +41,37 @@ function assert_output() { } function test_basic_functionality() { - $process_wrapper -1 0 /bin/echo hi there >$OUT 2>$ERR || fail + $process_wrapper -1 0 $OUT $ERR /bin/echo hi there &> $TEST_log || fail assert_output "hi there" "" } function test_to_stderr() { - $process_wrapper -1 0 /bin/bash -c "/bin/echo hi there >&2" >$OUT 2>$ERR || fail + $process_wrapper -1 0 $OUT $ERR /bin/bash -c "/bin/echo hi there >&2" &> $TEST_log || fail assert_output "" "hi there" } function test_exit_code() { local code=0 - $process_wrapper -1 0 /bin/bash -c "exit 71" >$OUT 2>$ERR || code=$? + $process_wrapper -1 0 $OUT $ERR /bin/bash -c "exit 71" &> $TEST_log || code=$? assert_equals 71 "$code" } function test_signal_death() { local code=0 - $process_wrapper -1 0 /bin/bash -c 'kill -ABRT $$' >$OUT 2>$ERR || code=$? + $process_wrapper -1 0 $OUT $ERR /bin/bash -c 'kill -ABRT $$' &> $TEST_log || code=$? assert_equals 134 "$code" # SIGNAL_BASE + SIGABRT = 128 + 6 } function test_signal_catcher() { local code=0 - $process_wrapper 1 2 /bin/bash -c \ - 'trap "echo later; exit 0" SIGINT SIGTERM SIGALRM; sleep 10' >$OUT 2>$ERR || code=$? + $process_wrapper 1 2 $OUT $ERR /bin/bash -c \ + 'trap "echo later; exit 0" SIGINT SIGTERM SIGALRM; sleep 10' &> $TEST_log || code=$? assert_equals 142 "$code" # SIGNAL_BASE + SIGALRM = 128 + 14 assert_stdout "later" } function test_basic_timeout() { - $process_wrapper 1 2 /bin/bash -c "echo before; sleep 10; echo after" >$OUT 2>$ERR && fail + $process_wrapper 1 2 $OUT $ERR /bin/bash -c "echo before; sleep 10; echo after" &> $TEST_log && fail assert_stdout "before" } @@ -81,9 +81,9 @@ function test_basic_timeout() { # grace period, thus printing "beforeafter". function test_timeout_grace() { local code=0 - $process_wrapper 1 10 /bin/bash -c \ + $process_wrapper 1 10 $OUT $ERR /bin/bash -c \ 'trap "echo -n before; sleep 1; echo after; exit 0" SIGINT SIGTERM SIGALRM; sleep 10' \ - >$OUT 2>$ERR || code=$? + &> $TEST_log || code=$? assert_equals 142 "$code" # SIGNAL_BASE + SIGALRM = 128 + 14 assert_stdout "beforeafter" } @@ -94,16 +94,16 @@ function test_timeout_grace() { # trap takes longer than the grace period, thus only printing "before". function test_timeout_kill() { local code=0 - $process_wrapper 1 2 /bin/bash -c \ + $process_wrapper 1 2 $OUT $ERR /bin/bash -c \ 'trap "echo before; sleep 10; echo after; exit 0" SIGINT SIGTERM SIGALRM; sleep 10' \ - >$OUT 2>$ERR || code=$? + &> $TEST_log || code=$? assert_equals 142 "$code" # SIGNAL_BASE + SIGALRM = 128 + 14 assert_stdout "before" } function test_execvp_error_message() { local code=0 - $process_wrapper -1 0 /bin/notexisting >$OUT 2>$ERR || code=$? + $process_wrapper -1 0 $OUT $ERR /bin/notexisting &> $TEST_log || code=$? assert_equals 1 "$code" assert_contains "execvp(\"/bin/notexisting\", ...): No such file or directory" "$ERR" } |