Skip to content

Commit c9f9b0b

Browse files
meisterTcopybara-github
authored andcommitted
Fix spitting out multiple "Build completed" messages.
Also make these a proper event, so that `--ui_event_filters` is applied properly. Fixes bazelbuild#16085 RELNOTES[INC]: This has the side effect of changing the message on unsuccessful builds from ``` FAILED: Build did NOT complete successfully (0 packages loaded) ``` to ``` ERROR: Build did NOT complete successfully ``` PiperOrigin-RevId: 484175656 Change-Id: I080ada6756734e5cdf236854101595949a57c083
1 parent 7c0bdc2 commit c9f9b0b

File tree

9 files changed

+89
-82
lines changed

9 files changed

+89
-82
lines changed

src/main/java/com/google/devtools/build/lib/runtime/SkymeldUiStateTracker.java

+3-24
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.google.devtools.build.lib.buildtool.buildevent.BuildCompleteEvent;
1919
import com.google.devtools.build.lib.buildtool.buildevent.ExecutionProgressReceiverAvailableEvent;
2020
import com.google.devtools.build.lib.clock.Clock;
21+
import com.google.devtools.build.lib.events.Event;
2122
import com.google.devtools.build.lib.pkgcache.LoadingPhaseCompleteEvent;
2223
import com.google.devtools.build.lib.skyframe.ConfigurationPhaseStartedEvent;
2324
import com.google.devtools.build.lib.skyframe.LoadingPhaseStartedEvent;
@@ -26,7 +27,6 @@
2627
import com.google.devtools.build.lib.util.io.PositionAwareAnsiTerminalWriter;
2728
import com.google.errorprone.annotations.CanIgnoreReturnValue;
2829
import java.io.IOException;
29-
import java.time.Instant;
3030

3131
/** Tracks the state of Skymeld builds and determines what to display at each state in the UI. */
3232
final class SkymeldUiStateTracker extends UiStateTracker {
@@ -219,30 +219,9 @@ synchronized void progressReceiverAvailable(ExecutionProgressReceiverAvailableEv
219219
}
220220

221221
@Override
222-
void buildComplete(BuildCompleteEvent event) {
222+
Event buildComplete(BuildCompleteEvent event) {
223223
buildStatus = BuildStatus.BUILD_COMPLETED;
224-
buildCompleteAt = Instant.ofEpochMilli(clock.currentTimeMillis());
225-
226-
if (event.getResult().getSuccess()) {
227-
int actionsCompleted = this.actionsCompleted.get();
228-
if (failedTests == 0) {
229-
additionalMessage =
230-
"Build completed successfully, "
231-
+ actionsCompleted
232-
+ pluralize(" total action", actionsCompleted);
233-
} else {
234-
additionalMessage =
235-
"Build completed, "
236-
+ failedTests
237-
+ pluralize(" test", failedTests)
238-
+ " FAILED, "
239-
+ actionsCompleted
240-
+ pluralize(" total action", actionsCompleted);
241-
}
242-
} else {
243-
ok = false;
244-
additionalMessage = "Build did NOT complete successfully";
245-
}
224+
return super.buildComplete(event);
246225
}
247226

248227
@Override

src/main/java/com/google/devtools/build/lib/runtime/UiEventHandler.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -582,15 +582,17 @@ public void buildComplete(BuildCompleteEvent event) {
582582
// it as an event and add a timestamp, if events are supposed to have a timestamp.
583583
boolean done = false;
584584
synchronized (this) {
585-
stateTracker.buildComplete(event);
585+
handleInternal(stateTracker.buildComplete(event));
586586
ignoreRefreshLimitOnce();
587-
refresh();
588587

589588
// After a build has completed, only stop updating the UI if there is no more activities.
590589
if (!stateTracker.hasActivities()) {
591590
buildRunning = false;
592591
done = true;
593592
}
593+
594+
// Only refresh after we have determined whether we need to keep the progress bar up.
595+
refresh();
594596
}
595597
if (done) {
596598
stopUpdateThread();
@@ -1001,8 +1003,10 @@ private synchronized void addProgressBar() throws IOException {
10011003
TIMESTAMP_FORMAT.format(
10021004
Instant.ofEpochMilli(clock.currentTimeMillis()).atZone(ZoneId.systemDefault()));
10031005
}
1004-
stateTracker.writeProgressBar(terminalWriter, /*shortVersion=*/ !cursorControl, timestamp);
1005-
terminalWriter.newline();
1006+
if (stateTracker.hasActivities()) {
1007+
stateTracker.writeProgressBar(terminalWriter, /*shortVersion=*/ !cursorControl, timestamp);
1008+
terminalWriter.newline();
1009+
}
10061010
numLinesProgressBar = countingTerminalWriter.getWrittenLines();
10071011
if (progressInTermTitle) {
10081012
LoggingTerminalWriter stringWriter = new LoggingTerminalWriter(true);

src/main/java/com/google/devtools/build/lib/runtime/UiStateTracker.java

+13-10
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.google.devtools.build.lib.buildtool.buildevent.TestFilteringCompleteEvent;
4343
import com.google.devtools.build.lib.clock.Clock;
4444
import com.google.devtools.build.lib.cmdline.Label;
45+
import com.google.devtools.build.lib.events.Event;
4546
import com.google.devtools.build.lib.events.ExtendedEventHandler.FetchProgress;
4647
import com.google.devtools.build.lib.pkgcache.LoadingPhaseCompleteEvent;
4748
import com.google.devtools.build.lib.skyframe.ConfigurationPhaseStartedEvent;
@@ -87,7 +88,7 @@ class UiStateTracker {
8788

8889
private int sampleSize = 3;
8990

90-
private String status;
91+
protected String status;
9192
protected String additionalMessage;
9293

9394
protected final Clock clock;
@@ -454,31 +455,31 @@ synchronized void progressReceiverAvailable(ExecutionProgressReceiverAvailableEv
454455
executionProgressReceiver = event.getExecutionProgressReceiver();
455456
}
456457

457-
void buildComplete(BuildCompleteEvent event) {
458+
Event buildComplete(BuildCompleteEvent event) {
458459
buildComplete = true;
459460
buildCompleteAt = Instant.ofEpochMilli(clock.currentTimeMillis());
460461

462+
status = null;
463+
additionalMessage = "";
461464
if (event.getResult().getSuccess()) {
462-
status = "INFO";
463465
int actionsCompleted = this.actionsCompleted.get();
464466
if (failedTests == 0) {
465-
additionalMessage =
467+
return Event.info(
466468
"Build completed successfully, "
467469
+ actionsCompleted
468-
+ pluralize(" total action", actionsCompleted);
470+
+ pluralize(" total action", actionsCompleted));
469471
} else {
470-
additionalMessage =
472+
return Event.info(
471473
"Build completed, "
472474
+ failedTests
473475
+ pluralize(" test", failedTests)
474476
+ " FAILED, "
475477
+ actionsCompleted
476-
+ pluralize(" total action", actionsCompleted);
478+
+ pluralize(" total action", actionsCompleted));
477479
}
478480
} else {
479481
ok = false;
480-
status = "FAILED";
481-
additionalMessage = "Build did NOT complete successfully";
482+
return Event.error("Build did NOT complete successfully");
482483
}
483484
}
484485

@@ -1324,7 +1325,9 @@ synchronized void writeProgressBar(
13241325
return;
13251326
}
13261327

1327-
writeExecutionProgress(terminalWriter, shortVersion);
1328+
if (!buildComplete) {
1329+
writeExecutionProgress(terminalWriter, shortVersion);
1330+
}
13281331

13291332
if (!shortVersion) {
13301333
reportOnDownloads(terminalWriter);

src/test/java/com/google/devtools/build/lib/runtime/SkymeldUiStateTrackerTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public void buildCompleted_stateChanges() {
149149
buildResult.setDetailedExitCode(DetailedExitCode.success());
150150
clock.advanceMillis(SECONDS.toMillis(1));
151151
buildResult.setStopTime(clock.currentTimeMillis());
152-
uiStateTracker.buildComplete(new BuildCompleteEvent(buildResult));
152+
var unused = uiStateTracker.buildComplete(new BuildCompleteEvent(buildResult));
153153

154154
assertThat(uiStateTracker.buildStatus).isEqualTo(BuildStatus.BUILD_COMPLETED);
155155
}

src/test/java/com/google/devtools/build/lib/runtime/UiEventHandlerStdOutAndStdErrTest.java

+42-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.google.devtools.build.lib.events.Event;
2727
import com.google.devtools.build.lib.events.EventKind;
2828
import com.google.devtools.build.lib.testutil.ManualClock;
29+
import com.google.devtools.build.lib.util.DetailedExitCode;
2930
import com.google.devtools.build.lib.util.io.OutErr;
3031
import com.google.testing.junit.testparameterinjector.TestParameter;
3132
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
@@ -45,6 +46,8 @@ public final class UiEventHandlerStdOutAndStdErrTest {
4546

4647
private static final BuildCompleteEvent BUILD_COMPLETE_EVENT =
4748
new BuildCompleteEvent(new BuildResult(/*startTimeMillis=*/ 0));
49+
private static final String BUILD_DID_NOT_COMPLETE_MESSAGE =
50+
"\033[31m\033[1mERROR: \033[0mBuild did NOT complete successfully" + System.lineSeparator();
4851

4952
@TestParameter private TestedOutput testedOutput;
5053

@@ -91,25 +94,54 @@ private void createUiEventHandler(UiOptions uiOptions) {
9194
}
9295

9396
@Test
94-
public void buildComplete_outputsNothing() {
97+
public void buildComplete_outputsBuildFailedOnStderr() {
9598
uiEventHandler.buildComplete(BUILD_COMPLETE_EVENT);
96-
output.assertFlushed();
99+
100+
if (testedOutput == TestedOutput.STDOUT) {
101+
output.assertFlushed();
102+
} else {
103+
output.assertFlushed(BUILD_DID_NOT_COMPLETE_MESSAGE);
104+
}
97105
}
98106

99107
@Test
100108
public void buildComplete_flushesBufferedMessage() {
101109
uiEventHandler.handle(output("hello"));
102110
uiEventHandler.buildComplete(BUILD_COMPLETE_EVENT);
103111

104-
output.assertFlushed("hello");
112+
if (testedOutput == TestedOutput.STDOUT) {
113+
output.assertFlushed("hello");
114+
} else {
115+
output.assertFlushed("hello", System.lineSeparator() + BUILD_DID_NOT_COMPLETE_MESSAGE);
116+
}
117+
}
118+
119+
@Test
120+
public void buildComplete_successfulBuild() {
121+
uiEventHandler.handle(output(""));
122+
var buildSuccessResult = new BuildResult(/*startTimeMillis=*/ 0);
123+
buildSuccessResult.setDetailedExitCode(DetailedExitCode.success());
124+
uiEventHandler.buildComplete(new BuildCompleteEvent(buildSuccessResult));
125+
126+
if (testedOutput == TestedOutput.STDOUT) {
127+
output.assertFlushed();
128+
} else {
129+
output.assertFlushed(
130+
"\033[32mINFO: \033[0mBuild completed successfully, 0 total actions"
131+
+ System.lineSeparator());
132+
}
105133
}
106134

107135
@Test
108-
public void buildComplete_emptyBuffer_outputsNothing() {
136+
public void buildComplete_emptyBuffer_outputsBuildFailedOnStderr() {
109137
uiEventHandler.handle(output(""));
110138
uiEventHandler.buildComplete(BUILD_COMPLETE_EVENT);
111139

112-
output.assertFlushed();
140+
if (testedOutput == TestedOutput.STDOUT) {
141+
output.assertFlushed();
142+
} else {
143+
output.assertFlushed(BUILD_DID_NOT_COMPLETE_MESSAGE);
144+
}
113145
}
114146

115147
@Test
@@ -124,7 +156,11 @@ public void handleOutputEvent_concatenatesInBuffer() {
124156
uiEventHandler.handle(output("there"));
125157
uiEventHandler.buildComplete(BUILD_COMPLETE_EVENT);
126158

127-
output.assertFlushed("hello there");
159+
if (testedOutput == TestedOutput.STDOUT) {
160+
output.assertFlushed("hello there");
161+
} else {
162+
output.assertFlushed("hello there", System.lineSeparator() + BUILD_DID_NOT_COMPLETE_MESSAGE);
163+
}
128164
}
129165

130166
@Test

src/test/java/com/google/devtools/build/lib/runtime/UiStateTrackerTest.java

+4-16
Original file line numberDiff line numberDiff line change
@@ -1360,7 +1360,7 @@ public void testMultipleBuildEventProtocolTransports() throws Exception {
13601360
new AnnounceBuildEventTransportsEvent(ImmutableList.of(transport1, transport2)));
13611361
stateTracker.buildEventTransportsAnnounced(
13621362
new AnnounceBuildEventTransportsEvent(ImmutableList.of(transport3)));
1363-
stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
1363+
var unused = stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
13641364

13651365
LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(true);
13661366

@@ -1371,8 +1371,6 @@ public void testMultipleBuildEventProtocolTransports() throws Exception {
13711371
assertThat(output, containsString("BuildEventTransport1"));
13721372
assertThat(output, containsString("BuildEventTransport2"));
13731373
assertThat(output, containsString("BuildEventTransport3"));
1374-
assertThat(output, containsString("success"));
1375-
assertThat(output, containsString("complete"));
13761374

13771375
clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
13781376
stateTracker.buildEventTransportClosed(new BuildEventTransportClosedEvent(transport1));
@@ -1383,8 +1381,6 @@ public void testMultipleBuildEventProtocolTransports() throws Exception {
13831381
assertThat(output, not(containsString("BuildEventTransport1")));
13841382
assertThat(output, containsString("BuildEventTransport2"));
13851383
assertThat(output, containsString("BuildEventTransport3"));
1386-
assertThat(output, containsString("success"));
1387-
assertThat(output, containsString("complete"));
13881384

13891385
clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
13901386
stateTracker.buildEventTransportClosed(new BuildEventTransportClosedEvent(transport3));
@@ -1395,8 +1391,6 @@ public void testMultipleBuildEventProtocolTransports() throws Exception {
13951391
assertThat(output, not(containsString("BuildEventTransport1")));
13961392
assertThat(output, containsString("BuildEventTransport2"));
13971393
assertThat(output, not(containsString("BuildEventTransport3")));
1398-
assertThat(output, containsString("success"));
1399-
assertThat(output, containsString("complete"));
14001394

14011395
clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
14021396
stateTracker.buildEventTransportClosed(new BuildEventTransportClosedEvent(transport2));
@@ -1407,8 +1401,6 @@ public void testMultipleBuildEventProtocolTransports() throws Exception {
14071401
assertThat(output, not(containsString("BuildEventTransport1")));
14081402
assertThat(output, not(containsString("BuildEventTransport2")));
14091403
assertThat(output, not(containsString("BuildEventTransport3")));
1410-
assertThat(output, containsString("success"));
1411-
assertThat(output, containsString("complete"));
14121404
assertThat(output.split("\\n")).hasLength(1);
14131405
}
14141406

@@ -1426,16 +1418,14 @@ public void testBuildEventTransportsOnNarrowTerminal() throws IOException {
14261418
stateTracker.buildStarted();
14271419
stateTracker.buildEventTransportsAnnounced(
14281420
new AnnounceBuildEventTransportsEvent(ImmutableList.of(transport1, transport2)));
1429-
stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
1421+
var unused = stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
14301422
clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
14311423
stateTracker.writeProgressBar(terminalWriter);
14321424
String output = terminalWriter.getTranscript();
14331425
assertThat(longestLine(output)).isAtMost(60);
14341426
assertThat(output, containsString("1s"));
14351427
assertThat(output, containsString("A".repeat(30) + "..."));
14361428
assertThat(output, containsString("BuildEventTransport"));
1437-
assertThat(output, containsString("success"));
1438-
assertThat(output, containsString("complete"));
14391429

14401430
clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
14411431
stateTracker.buildEventTransportClosed(new BuildEventTransportClosedEvent(transport2));
@@ -1446,8 +1436,6 @@ public void testBuildEventTransportsOnNarrowTerminal() throws IOException {
14461436
assertThat(output, containsString("2s"));
14471437
assertThat(output, containsString("A".repeat(30) + "..."));
14481438
assertThat(output, not(containsString("BuildEventTransport")));
1449-
assertThat(output, containsString("success"));
1450-
assertThat(output, containsString("complete"));
14511439
assertThat(output.split("\\n")).hasLength(2);
14521440
}
14531441

@@ -1526,7 +1514,7 @@ public void waitingRemoteCacheMessage_afterBuildComplete_visible() throws IOExce
15261514
BuildResult buildResult = new BuildResult(clock.currentTimeMillis());
15271515
buildResult.setDetailedExitCode(DetailedExitCode.success());
15281516
buildResult.setStopTime(clock.currentTimeMillis());
1529-
stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
1517+
var unused = stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
15301518
clock.advanceMillis(Duration.ofSeconds(2).toMillis());
15311519
LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
15321520

@@ -1545,7 +1533,7 @@ public void waitingRemoteCacheMessage_multipleUploadEvents_countCorrectly() thro
15451533
BuildResult buildResult = new BuildResult(clock.currentTimeMillis());
15461534
buildResult.setDetailedExitCode(DetailedExitCode.success());
15471535
buildResult.setStopTime(clock.currentTimeMillis());
1548-
stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
1536+
var unused = stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
15491537
stateTracker.actionUploadStarted(ActionUploadStartedEvent.create(action, "b"));
15501538
stateTracker.actionUploadStarted(ActionUploadStartedEvent.create(action, "c"));
15511539
stateTracker.actionUploadFinished(ActionUploadFinishedEvent.create(action, "a"));

0 commit comments

Comments
 (0)