Пример #1
0
  @Override
  public StepExecutionResult execute(ExecutionContext context) throws InterruptedException {
    // Build the process, redirecting output to the provided output file.  In general,
    // it's undesirable that both stdout and stderr are being redirected to the same
    // input stream.  However, due to the nature of OS pipe buffering, we can't really
    // maintain the natural interleaving of multiple output streams in a way that we
    // can correctly associate both stdout/stderr streams to the one correct test out
    // of the many that ran.  So, our best bet is to just combine them all into stdout,
    // so they get properly interleaved with the test start and end messages that we
    // use when we parse the test output.
    ProcessBuilder builder = new ProcessBuilder();
    builder.command(command);
    builder.redirectOutput(filesystem.resolve(output).toFile());
    builder.redirectErrorStream(true);

    Process process;
    try {
      process = BgProcessKiller.startProcess(builder);
    } catch (IOException e) {
      context.logError(e, "Error starting command %s", command);
      return StepExecutionResult.ERROR;
    }

    // Run the test process, saving the exit code.
    ProcessExecutor executor = context.getProcessExecutor();
    ImmutableSet<ProcessExecutor.Option> options =
        ImmutableSet.of(ProcessExecutor.Option.EXPECTING_STD_OUT);
    ProcessExecutor.Result result =
        executor.execute(
            process,
            options,
            /* stdin */ Optional.<String>absent(),
            /* timeOutMs */ testRuleTimeoutMs,
            /* timeOutHandler */ Optional.<Function<Process, Void>>absent());

    if (result.isTimedOut()) {
      throw new HumanReadableException(
          "Timed out after %d ms running test command %s", testRuleTimeoutMs.or(-1L), command);
    }

    // Since test binaries return a non-zero exit code when unittests fail, save the exit code
    // to a file rather than signalling a step failure.
    try (FileOutputStream stream = new FileOutputStream(filesystem.resolve(exitCode).toFile())) {
      stream.write((Integer.toString(result.getExitCode())).getBytes());
    } catch (IOException e) {
      context.logError(e, "Error saving exit code to %s", exitCode);
      return StepExecutionResult.ERROR;
    }

    return StepExecutionResult.SUCCESS;
  }