experimental UI: Keep track of completed tests

When running tests, a useful information to know is the number of tests
that have passed and failed already. Hence subscribe to the relevant events
and provide this information in the progress bar as well.

--
Change-Id: I6fabec3f4585500f096b820dbbd5e8e6897647fa
Reviewed-on: https://bazel-review.googlesource.com/#/c/3350
MOS_MIGRATED_REVID=119727962
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java b/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
index eaf4a50..bf53b69 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/ExperimentalStateTrackerTest.java
@@ -17,11 +17,14 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.when;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.actions.Action;
 import com.google.devtools.build.lib.actions.ActionCompletionEvent;
 import com.google.devtools.build.lib.actions.ActionStartedEvent;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.buildtool.buildevent.TestFilteringCompleteEvent;
 import com.google.devtools.build.lib.testutil.FoundationTestCase;
 import com.google.devtools.build.lib.testutil.ManualClock;
 import com.google.devtools.build.lib.util.io.AnsiTerminalWriter;
@@ -246,4 +249,30 @@
         "Progress bar showing a running action should be time dependent",
         stateTracker.progressBarTimeDependent());
   }
+
+  @Test
+  public void testCountVisible() throws IOException {
+    // The test count should be visible in the status bar, as well as the short status bar
+    ManualClock clock = new ManualClock();
+    ExperimentalStateTracker stateTracker = new ExperimentalStateTracker(clock);
+    TestFilteringCompleteEvent filteringComplete = Mockito.mock(TestFilteringCompleteEvent.class);
+    ConfiguredTarget targetA = Mockito.mock(ConfiguredTarget.class);
+    ConfiguredTarget targetB = Mockito.mock(ConfiguredTarget.class);
+    when(filteringComplete.getTestTargets()).thenReturn(ImmutableSet.of(targetA, targetB));
+    TestSummary testSummary = Mockito.mock(TestSummary.class);
+    stateTracker.testFilteringComplete(filteringComplete);
+    stateTracker.testSummary(testSummary);
+
+    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter();
+    stateTracker.writeProgressBar(terminalWriter);
+    String output = terminalWriter.getWritten();
+    assertTrue(
+        "Test count should be visible in output: " + output, output.contains(" 1 / 2 tests"));
+
+    terminalWriter = new LoggingTerminalWriter();
+    stateTracker.writeProgressBar(terminalWriter, /* shortVersion=*/ true);
+    output = terminalWriter.getWritten();
+    assertTrue(
+        "Test count should be visible in short output: " + output, output.contains(" 1 / 2 tests"));
+  }
 }