use of com.google.copybara.shell.KillableObserver in project copybara by google.
the class CommandRunner method execute.
/**
* Executes a {@link Command} with the given input and writes to the console and the log depending
* on the exit code of the command and the verbose flag.
*/
public CommandOutputWithStatus execute() throws CommandException {
Stopwatch stopwatch = Stopwatch.createStarted();
String startMsg = ShellUtils.prettyPrintArgv(Arrays.asList(cmd.getCommandLineElements()));
startMsg = startMsg.length() > MAX_COMMAND_LENGTH ? startMsg.substring(0, MAX_COMMAND_LENGTH) + "..." : startMsg;
String validStartMsg = "Executing [" + startMsg + "]";
logger.atInfo().log("%s", validStartMsg);
if (verbose) {
System.err.println(validStartMsg);
}
TerminationStatus exitStatus = null;
CombinedKillableObserver cmdMonitor = new CombinedKillableObserver(timeout, additionalObservers.toArray(new KillableObserver[0]));
ByteArrayOutputStream stdoutCollector = new ByteArrayOutputStream();
ByteArrayOutputStream stderrCollector = new ByteArrayOutputStream();
try {
if (asyncStdoutStream.isPresent()) {
stdoutCollector.write("stdOut redirected to external observer.".getBytes(UTF_8));
}
if (asyncErrStream.isPresent()) {
stderrCollector.write("stdErr redirected to external observer.".getBytes(UTF_8));
}
} catch (IOException e) {
logger.atSevere().withCause(e).log("Error writing output.");
}
OutputStream stdoutStream = commandOutputStream(asyncStdoutStream.orElse(stdoutCollector));
OutputStream stderrStream = commandOutputStream(asyncErrStream.orElse(stderrCollector));
try {
CommandExecutor runner = executor.orElse(new DefaultExecutor());
TerminationStatus status = runner.getCommandOutputWithStatus(cmd, input, cmdMonitor, stdoutStream, stderrStream);
exitStatus = status;
return new CommandOutputWithStatus(status, stdoutCollector.toByteArray(), stderrCollector.toByteArray());
} catch (BadExitStatusException e) {
exitStatus = e.getResult().getTerminationStatus();
maybeTreatTimeout(stdoutCollector, stderrCollector, cmdMonitor, e);
throw new BadExitStatusWithOutputException(e.getCommand(), e.getResult(), e.getMessage(), stdoutCollector.toByteArray(), stderrCollector.toByteArray());
} catch (AbnormalTerminationException e) {
maybeTreatTimeout(stdoutCollector, stderrCollector, cmdMonitor, e);
throw e;
} finally {
String commandName = cmd.getCommandLineElements()[0];
if (maxOutLogLines != 0) {
logOutput(Level.INFO, String.format("'%s' STDOUT: ", commandName), stdoutCollector, maxOutLogLines);
logOutput(Level.INFO, String.format("'%s' STDERR: ", commandName), stderrCollector, maxOutLogLines);
}
String finishMsg;
if (cmdMonitor.hasTimedOut()) {
finishMsg = String.format("Command '%s' was killed after timeout. Execution time %s. %s", commandName, formatDuration(stopwatch.elapsed()), exitStatus != null ? exitStatus.toString() : "(No exit status)");
logger.atSevere().log("%s", finishMsg);
} else {
finishMsg = String.format("Command '%s' finished in %s. %s", commandName, formatDuration(stopwatch.elapsed()), exitStatus != null ? exitStatus.toString() : "(No exit status)");
logger.atInfo().log("%s", finishMsg);
}
if (verbose) {
System.err.println(finishMsg);
}
}
}
use of com.google.copybara.shell.KillableObserver in project copybara by google.
the class CommandRunnerTest method testObserverCanTerminate.
@Test
public void testObserverCanTerminate() throws Exception {
KillableObserver tester = new KillableObserver() {
@Override
public void startObserving(Killable killable) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
// ignored
}
killable.kill();
}
@Override
public void stopObserving(Killable killable) {
}
};
Command command = bashCommand("" + "echo stdout msg\n" + ">&2 echo stderr msg\n" + "sleep 10\n");
AbnormalTerminationException e = assertThrows(AbnormalTerminationException.class, () -> runCommand(new CommandRunner(command, Duration.ofSeconds(90)).withObserver(tester)));
assertThat(e).hasMessageThat().containsMatch("Process terminated by signal 15");
assertThat(e).hasMessageThat().doesNotContainMatch("Command '.*' killed by Copybara after timeout \\(1s\\)");
}
use of com.google.copybara.shell.KillableObserver in project copybara by google.
the class CommandRunnerTest method testCommandWithCustomRunner.
@Test
public void testCommandWithCustomRunner() throws Exception {
Command command = bashCommand("");
CommandException e = assertThrows(CommandException.class, () -> runCommand(new CommandRunner(command).withCommandExecutor(new CommandExecutor() {
@Override
public TerminationStatus getCommandOutputWithStatus(Command cmd, byte[] input, KillableObserver cmdMonitor, OutputStream stdoutStream, OutputStream stderrStream) throws CommandException {
throw new CommandException(cmd, "OH NOES!");
}
})));
assertThat(e).hasMessageThat().contains("OH NOES!");
}
Aggregations