diff options
author | 2016-05-13 11:06:33 +0000 | |
---|---|---|
committer | 2016-05-13 11:10:05 +0000 | |
commit | 49b3f8d687ae4ee26fd70393c86b2910572e4e45 (patch) | |
tree | cdcae0e46c8198177906b311e2de956a6ae07dde /src | |
parent | e0bfbca4a186969d6c3c4590ab963db7565d2b12 (diff) |
Improve pass-through during build
If tests are run with --test_output=streamed, output has to be passed through
before the end of the (overall) build. In this situation, enforcing a line-end
to redraw the status bar messes up the output that is streamed through. Therefore,
buffer stdout/stderr to full lines and pass them through without extra newlines
added.
--
Change-Id: I52d5dfbd1cb30a6ce2d7d2fd34658a606abcc277
Reviewed-on: https://bazel-review.googlesource.com/#/c/3620
MOS_MIGRATED_REVID=122248012
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java | 54 | ||||
-rwxr-xr-x | src/test/shell/integration/experimental_ui_test.sh | 18 |
2 files changed, 59 insertions, 13 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java b/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java index b6fc87d9c8..cf4795f683 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/ExperimentalEventHandler.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.runtime; import com.google.common.eventbus.Subscribe; +import com.google.common.primitives.Bytes; import com.google.devtools.build.lib.actions.ActionCompletionEvent; import com.google.devtools.build.lib.actions.ActionStartedEvent; import com.google.devtools.build.lib.analysis.AnalysisPhaseCompleteEvent; @@ -38,6 +39,7 @@ import com.google.devtools.build.lib.view.test.TestStatus.BlazeTestStatus; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.logging.Logger; /** @@ -64,6 +66,8 @@ public class ExperimentalEventHandler extends BlazeCommandEventHandler { private boolean buildComplete; private boolean progressBarNeedsRefresh; private Thread updateThread; + private byte[] stdoutBuffer; + private byte[] stderrBuffer; public final int terminalWidth; @@ -88,6 +92,8 @@ public class ExperimentalEventHandler extends BlazeCommandEventHandler { this.numLinesProgressBar = 0; this.minimalDelayMillis = Math.round(options.showProgressRateLimit * 1000); this.minimalUpdateInterval = Math.max(this.minimalDelayMillis, MAXIMAL_UPDATE_DELAY_MILLIS); + this.stdoutBuffer = new byte[] {}; + this.stderrBuffer = new byte[] {}; // The progress bar has not been updated yet. ignoreRefreshLimitOnce(); } @@ -107,24 +113,39 @@ public class ExperimentalEventHandler extends BlazeCommandEventHandler { switch (event.getKind()) { case STDOUT: case STDERR: - if (!buildComplete) { - clearProgressBar(); - terminal.flush(); - } OutputStream stream = event.getKind() == EventKind.STDOUT ? outErr.getOutputStream() : outErr.getErrorStream(); - stream.write(event.getMessageBytes()); - if (!buildComplete) { - stream.write(new byte[] {10, 13}); - } - stream.flush(); - if (!buildComplete) { - if (cursorControl) { - addProgressBar(); + if (buildComplete) { + stream.write(event.getMessageBytes()); + stream.flush(); + } else { + byte[] message = event.getMessageBytes(); + int eolIndex = Bytes.lastIndexOf(message, (byte) '\n'); + if (eolIndex >= 0) { + clearProgressBar(); + terminal.flush(); + stream.write(event.getKind() == EventKind.STDOUT ? stdoutBuffer : stderrBuffer); + stream.write(Arrays.copyOf(message, eolIndex + 1)); + byte[] restMessage = Arrays.copyOfRange(message, eolIndex + 1, message.length + 1); + if (event.getKind() == EventKind.STDOUT) { + stdoutBuffer = restMessage; + } else { + stderrBuffer = restMessage; + } + stream.flush(); + if (cursorControl) { + addProgressBar(); + } + terminal.flush(); + } else { + if (event.getKind() == EventKind.STDOUT) { + stdoutBuffer = Bytes.concat(stdoutBuffer, message); + } else { + stderrBuffer = Bytes.concat(stderrBuffer, message); + } } - terminal.flush(); } break; case ERROR: @@ -134,6 +155,13 @@ public class ExperimentalEventHandler extends BlazeCommandEventHandler { if (!buildComplete) { clearProgressBar(); } + outErr.getOutputStream().write(stdoutBuffer); + outErr.getOutputStream().flush(); + stdoutBuffer = new byte[] {}; + outErr.getErrorStream().write(stderrBuffer); + outErr.getErrorStream().flush(); + stderrBuffer = new byte[] {}; + crlf(); setEventKindColor(event.getKind()); terminal.writeString(event.getKind() + ": "); terminal.resetTerminal(); diff --git a/src/test/shell/integration/experimental_ui_test.sh b/src/test/shell/integration/experimental_ui_test.sh index cfcb76f638..490d0fe747 100755 --- a/src/test/shell/integration/experimental_ui_test.sh +++ b/src/test/shell/integration/experimental_ui_test.sh @@ -46,6 +46,14 @@ EOF exit 1 EOF chmod 755 pkg/false.sh + cat > pkg/output.sh <<EOF +#!/bin/sh +`which echo` -n foo +sleep 1 +`which echo` -n bar +exit 0 +EOF + chmod 755 pkg/output.sh cat > pkg/BUILD <<EOF sh_test( name = "true", @@ -59,6 +67,10 @@ sh_test( name = "false", srcs = ["false.sh"], ) +sh_test( + name = "output", + srcs = ["output.sh"], +) genrule( name = "gentext", outs = ["gentext.txt"], @@ -208,5 +220,11 @@ function test_failure_scrollback_buffer { expect_log '^'$'\x1b\[31m\x1b\[1mFAIL:' } +function test_streamed { + bazel test --experimental_ui --curses=yes --color=yes \ + --nocache_test_results --test_output=streamed pkg:output >$TEST_log \ + || fail "expected success" + expect_log 'foobar' +} run_suite "Integration tests for bazel's experimental UI" |