// Copyright 2016 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.runtime;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
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.ActionLookupData;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.ActionStartedEvent;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.actions.RunningActionEvent;
import com.google.devtools.build.lib.actions.ScanningActionEvent;
import com.google.devtools.build.lib.actions.SchedulingActionEvent;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.bazel.repository.downloader.DownloadProgressEvent;
import com.google.devtools.build.lib.buildeventstream.AnnounceBuildEventTransportsEvent;
import com.google.devtools.build.lib.buildeventstream.BuildEventTransport;
import com.google.devtools.build.lib.buildeventstream.BuildEventTransportClosedEvent;
import com.google.devtools.build.lib.buildtool.BuildResult;
import com.google.devtools.build.lib.buildtool.buildevent.BuildCompleteEvent;
import com.google.devtools.build.lib.buildtool.buildevent.TestFilteringCompleteEvent;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.ExtendedEventHandler.FetchProgress;
import com.google.devtools.build.lib.packages.AspectDescriptor;
import com.google.devtools.build.lib.runtime.UiStateTracker.ProgressMode;
import com.google.devtools.build.lib.runtime.UiStateTracker.StrategyIds;
import com.google.devtools.build.lib.skyframe.LoadingPhaseStartedEvent;
import com.google.devtools.build.lib.skyframe.PackageProgressReceiver;
import com.google.devtools.build.lib.testutil.FoundationTestCase;
import com.google.devtools.build.lib.testutil.ManualClock;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.io.LoggingTerminalWriter;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.view.test.TestStatus.BlazeTestStatus;
import java.io.IOException;
import java.net.URL;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;

/** Tests {@link UiStateTracker}. */
@RunWith(JUnit4.class)
public class UiStateTrackerTest extends FoundationTestCase {

  @Test
  public void testStrategyIds_getId_idsAreBitmasks() {
    StrategyIds strategyIds = new StrategyIds();
    Integer id1 = strategyIds.getId("foo");
    Integer id2 = strategyIds.getId("bar");
    Integer id3 = strategyIds.getId("baz");

    assertThat(id1).isGreaterThan(0);
    assertThat(id2).isGreaterThan(0);
    assertThat(id3).isGreaterThan(0);

    assertThat(id1 & id2).isEqualTo(0);
    assertThat(id1 & id3).isEqualTo(0);
    assertThat(id2 & id3).isEqualTo(0);
  }

  @Test
  public void testStrategyIds_getId_idsAreReusedIfAlreadyExist() {
    StrategyIds strategyIds = new StrategyIds();
    Integer id1 = strategyIds.getId("foo");
    Integer id2 = strategyIds.getId("bar");
    Integer id3 = strategyIds.getId("foo");

    assertThat(id1).isNotEqualTo(id2);
    assertThat(id1).isEqualTo(id3);
  }

  @Test
  public void testStrategyIds_getId_exhaustIds() {
    StrategyIds strategyIds = new StrategyIds();
    Set<Integer> ids = new HashSet<>();
    StringBuilder name = new StringBuilder();
    for (; ; ) {
      name.append('a');
      Integer id = strategyIds.getId(name.toString());
      if (id.equals(strategyIds.fallbackId)) {
        break;
      }
      ids.add(id);
    }
    assertThat(ids).hasSize(Integer.SIZE - 1); // Minus 1 for FALLBACK_NAME.

    assertThat(strategyIds.getId("some")).isEqualTo(strategyIds.fallbackId);
    assertThat(strategyIds.getId("more")).isEqualTo(strategyIds.fallbackId);
  }

  @Test
  public void testStrategyIds_formatNames_fallbackExistsByDefault() {
    StrategyIds strategyIds = new StrategyIds();
    assertThat(strategyIds.formatNames(strategyIds.fallbackId))
        .isEqualTo(StrategyIds.FALLBACK_NAME);
  }

  @Test
  public void testStrategyIds_formatNames_oneHasNoComma() {
    StrategyIds strategyIds = new StrategyIds();
    Integer id1 = strategyIds.getId("abc");
    assertThat(strategyIds.formatNames(id1)).isEqualTo("abc");
  }

  @Test
  public void testStrategyIds_formatNames() {
    StrategyIds strategyIds = new StrategyIds();
    Integer id1 = strategyIds.getId("abc");
    Integer id2 = strategyIds.getId("xyz");
    Integer id3 = strategyIds.getId("def");

    // Names are not sorted alphabetically but their order is stable based on prior getId calls.
    assertThat(strategyIds.formatNames(id1 | id2)).isEqualTo("abc, xyz");
    assertThat(strategyIds.formatNames(id1 | id3)).isEqualTo("abc, def");
    assertThat(strategyIds.formatNames(id2 | id3)).isEqualTo("xyz, def");
    assertThat(strategyIds.formatNames(id1 | id2 | id3)).isEqualTo("abc, xyz, def");
  }

  private Action mockAction(String progressMessage, String primaryOutput) {
    Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
    Artifact artifact =
        ActionsTestUtil.createArtifact(ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)), path);

    Action action = Mockito.mock(Action.class);
    when(action.getProgressMessage()).thenReturn(progressMessage);
    when(action.getPrimaryOutput()).thenReturn(artifact);
    return action;
  }

  private int longestLine(String output) {
    int maxLength = 0;
    for (String line : output.split("\n")) {
      maxLength = Math.max(maxLength, line.length());
    }
    return maxLength;
  }

  @Test
  public void testLoadingActivity() throws IOException {
    // During loading phase, state and activity, as reported by the PackageProgressReceiver,
    // should be visible in the progress bar.
    String state = "42 packages loaded";
    String activity = "currently loading //src/foo/bar and 17 more";
    PackageProgressReceiver progress = Mockito.mock(PackageProgressReceiver.class);
    when(progress.progressState()).thenReturn(new Pair<String, String>(state, activity));

    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock);

    stateTracker.loadingStarted(new LoadingPhaseStartedEvent(progress));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    assertWithMessage(
            "Output should indicate that we are in the loading phase, but was:\n" + output)
        .that(output.contains("Loading"))
        .isTrue();
    assertWithMessage("Output should contain loading state '" + state + "', but was:\n" + output)
        .that(output.contains(state))
        .isTrue();
    assertWithMessage("Output should contain loading state '" + activity + "', but was:\n" + output)
        .that(output.contains(activity))
        .isTrue();
  }

  @Test
  public void testActionVisible() throws IOException {
    // If there is only one action running, it should be visible
    // somewhere in the progress bar, and also the short version thereof.

    String message = "Building foo";
    ManualClock clock = new ManualClock();
    clock.advanceMillis(120000);

    UiStateTracker stateTracker = new UiStateTracker(clock);
    stateTracker.actionStarted(new ActionStartedEvent(mockAction(message, "bar/foo"), 123456789));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();
    assertWithMessage("Action message '" + message + "' should be present in output: " + output)
        .that(output.contains(message))
        .isTrue();

    terminalWriter = new LoggingTerminalWriter();
    stateTracker.writeProgressBar(terminalWriter, /* shortVersion=*/ true);
    output = terminalWriter.getTranscript();
    assertWithMessage(
            "Action message '" + message + "' should be present in short output: " + output)
        .that(output.contains(message))
        .isTrue();
  }

  @Test
  public void testCompletedActionNotShown() throws IOException {
    // Completed actions should not be reported in the progress bar, nor in the
    // short progress bar.

    String messageFast = "Running quick action";
    String messageSlow = "Running slow action";

    ManualClock clock = new ManualClock();
    clock.advanceMillis(120000);
    Action fastAction = mockAction(messageFast, "foo/fast");
    Action slowAction = mockAction(messageSlow, "bar/slow");
    UiStateTracker stateTracker = new UiStateTracker(clock);
    stateTracker.actionStarted(new ActionStartedEvent(fastAction, 123456789));
    stateTracker.actionStarted(new ActionStartedEvent(slowAction, 123456999));
    stateTracker.actionCompletion(
        new ActionCompletionEvent(20, fastAction, Mockito.mock(ActionLookupData.class)));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();
    assertWithMessage(
            "Completed action '" + messageFast + "' should not be present in output: " + output)
        .that(output.contains(messageFast))
        .isFalse();
    assertWithMessage(
            "Only running action '" + messageSlow + "' should be present in output: " + output)
        .that(output.contains(messageSlow))
        .isTrue();

    terminalWriter = new LoggingTerminalWriter();
    stateTracker.writeProgressBar(terminalWriter, /* shortVersion=*/ true);
    output = terminalWriter.getTranscript();
    assertWithMessage(
            "Completed action '"
                + messageFast
                + "' should not be present in short output: "
                + output)
        .that(output.contains(messageFast))
        .isFalse();
    assertWithMessage(
            "Only running action '"
                + messageSlow
                + "' should be present in short output: "
                + output)
        .that(output.contains(messageSlow))
        .isTrue();
  }

  @Test
  public void testOldestActionVisible() throws IOException {
    // The earliest-started action is always visible somehow in the progress bar
    // and its short version.

    String messageOld = "Running the first-started action";

    ManualClock clock = new ManualClock();
    clock.advanceMillis(120000);
    UiStateTracker stateTracker = new UiStateTracker(clock);
    stateTracker.actionStarted(
        new ActionStartedEvent(mockAction(messageOld, "bar/foo"), 123456789));
    for (int i = 0; i < 30; i++) {
      stateTracker.actionStarted(
          new ActionStartedEvent(
              mockAction("Other action " + i, "some/other/actions/number" + i), 123456790 + i));
    }

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();
    assertWithMessage(
            "Longest running action '" + messageOld + "' should be visible in output: " + output)
        .that(output.contains(messageOld))
        .isTrue();

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter, /* shortVersion=*/ true);
    output = terminalWriter.getTranscript();
    assertWithMessage(
            "Longest running action '"
                + messageOld
                + "' should be visible in short output: "
                + output)
        .that(output.contains(messageOld))
        .isTrue();
  }

  @Test
  public void testSampleSize() throws IOException {
    // Verify that the number of actions shown in the progress bar can be set as sample size.
    ManualClock clock = new ManualClock();
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(123));
    UiStateTracker stateTracker = new UiStateTracker(clock);
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(2));

    // Start 10 actions (numbered 0 to 9).
    for (int i = 0; i < 10; i++) {
      clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
      Action action = mockAction("Performing action A" + i + ".", "action_A" + i + ".out");
      stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
    }

    // For various sample sizes verify the progress bar
    for (int i = 1; i < 11; i++) {
      stateTracker.setProgressMode(ProgressMode.OLDEST_ACTIONS, i);
      LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
      stateTracker.writeProgressBar(terminalWriter);
      String output = terminalWriter.getTranscript();
      assertWithMessage("Action " + (i - 1) + " should still be shown in the output: '" + output)
          .that(output.contains("A" + (i - 1) + "."))
          .isTrue();
      assertWithMessage("Action " + i + " should not be shown in the output: " + output)
          .that(output.contains("A" + i + "."))
          .isFalse();
      if (i < 10) {
        assertWithMessage("Ellipsis symbol should be shown in output: " + output)
            .that(output.contains("..."))
            .isTrue();
      } else {
        assertWithMessage("Ellipsis symbol should not be shown in output: " + output)
            .that(output.contains("..."))
            .isFalse();
      }
    }
  }

  @Test
  public void testTimesShown() throws IOException {
    // For sufficiently long running actions, the time that has passed since their start is shown.
    // In the short version of the progress bar, this should be true at least for the oldest action.

    ManualClock clock = new ManualClock();
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(123));
    UiStateTracker stateTracker = new UiStateTracker(clock);
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(2));

    stateTracker.actionStarted(
        new ActionStartedEvent(mockAction("First action", "foo"), clock.nanoTime()));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(7));
    stateTracker.actionStarted(
        new ActionStartedEvent(mockAction("Second action", "bar"), clock.nanoTime()));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(20));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();
    assertWithMessage("Runtime of first action should be visible in output: " + output)
        .that(output.contains("27s"))
        .isTrue();
    assertWithMessage("Runtime of second action should be visible in output: " + output)
        .that(output.contains("20s"))
        .isTrue();

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter, /* shortVersion=*/ true);
    output = terminalWriter.getTranscript();
    assertWithMessage("Runtime of first action should be visible in short output: " + output)
        .that(output.contains("27s"))
        .isTrue();
  }

  @Test
  public void initialProgressBarTimeIndependent() {
    ManualClock clock = new ManualClock();
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(123));
    UiStateTracker stateTracker = new UiStateTracker(clock);

    assertWithMessage("Initial progress status should be time independent")
        .that(stateTracker.progressBarTimeDependent())
        .isFalse();
  }

  @Test
  public void runningActionTimeIndependent() {
    ManualClock clock = new ManualClock();
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(123));
    UiStateTracker stateTracker = new UiStateTracker(clock);
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.actionStarted(
        new ActionStartedEvent(mockAction("Some action", "foo"), clock.nanoTime()));

    assertWithMessage("Progress bar showing a running action should be time dependent")
        .that(stateTracker.progressBarTimeDependent())
        .isTrue();
  }

  @Test
  public void testCountVisible() throws Exception {
    // The test count should be visible in the status bar, as well as the short status bar
    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock);
    TestFilteringCompleteEvent filteringComplete = Mockito.mock(TestFilteringCompleteEvent.class);
    Label labelA = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    ConfiguredTarget targetA = Mockito.mock(ConfiguredTarget.class);
    when(targetA.getLabel()).thenReturn(labelA);
    ConfiguredTarget targetB = Mockito.mock(ConfiguredTarget.class);
    when(filteringComplete.getTestTargets()).thenReturn(ImmutableSet.of(targetA, targetB));
    TestSummary testSummary = Mockito.mock(TestSummary.class);
    when(testSummary.getTarget()).thenReturn(targetA);
    when(testSummary.getLabel()).thenReturn(labelA);

    stateTracker.testFilteringComplete(filteringComplete);
    stateTracker.testSummary(testSummary);

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();
    assertWithMessage("Test count should be visible in output: " + output)
        .that(output.contains(" 1 / 2 tests"))
        .isTrue();

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter, /* shortVersion=*/ true);
    output = terminalWriter.getTranscript();
    assertWithMessage("Test count should be visible in short output: " + output)
        .that(output.contains(" 1 / 2 tests"))
        .isTrue();
  }

  @Test
  public void testPassedVisible() throws Exception {
    // The last test should still be visible in the long status bar, and colored as ok if it passed.
    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock);
    TestFilteringCompleteEvent filteringComplete = Mockito.mock(TestFilteringCompleteEvent.class);
    Label labelA = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    ConfiguredTarget targetA = Mockito.mock(ConfiguredTarget.class);
    when(targetA.getLabel()).thenReturn(labelA);
    ConfiguredTarget targetB = Mockito.mock(ConfiguredTarget.class);
    when(filteringComplete.getTestTargets()).thenReturn(ImmutableSet.of(targetA, targetB));
    TestSummary testSummary = Mockito.mock(TestSummary.class);
    when(testSummary.getStatus()).thenReturn(BlazeTestStatus.PASSED);
    when(testSummary.getTarget()).thenReturn(targetA);
    when(testSummary.getLabel()).thenReturn(labelA);

    stateTracker.testFilteringComplete(filteringComplete);
    stateTracker.testSummary(testSummary);

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter();
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    String expected = LoggingTerminalWriter.OK + labelA;
    assertWithMessage(
            "Sequence '" + expected + "' should be present in colored progress bar: " + output)
        .that(output.contains(expected))
        .isTrue();
  }

  @Test
  public void testFailedVisible() throws Exception {
    // The last test should still be visible in the long status bar, and colored as fail if it
    // did not pass.
    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock);
    TestFilteringCompleteEvent filteringComplete = Mockito.mock(TestFilteringCompleteEvent.class);
    Label labelA = Label.parseAbsolute("//foo/bar:baz", ImmutableMap.of());
    ConfiguredTarget targetA = Mockito.mock(ConfiguredTarget.class);
    when(targetA.getLabel()).thenReturn(labelA);
    ConfiguredTarget targetB = Mockito.mock(ConfiguredTarget.class);
    when(filteringComplete.getTestTargets()).thenReturn(ImmutableSet.of(targetA, targetB));
    TestSummary testSummary = Mockito.mock(TestSummary.class);
    when(testSummary.getStatus()).thenReturn(BlazeTestStatus.FAILED);
    when(testSummary.getTarget()).thenReturn(targetA);
    when(testSummary.getLabel()).thenReturn(labelA);

    stateTracker.testFilteringComplete(filteringComplete);
    stateTracker.testSummary(testSummary);

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter();
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    String expected = LoggingTerminalWriter.FAIL + labelA;
    assertWithMessage(
            "Sequence '" + expected + "' should be present in colored progress bar: " + output)
        .that(output.contains(expected))
        .isTrue();
  }

  @Test
  public void testSensibleShortening() throws Exception {
    // Verify that in the typical case, we shorten the progress message by shortening
    // the path implicit in it, that can also be extracted from the label. In particular,
    // the parts
    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock, 70);
    Action action =
        mockAction(
            "Building some/very/very/long/path/for/some/library/directory/foo.jar (42 source"
                + " files)",
            "some/very/very/long/path/for/some/library/directory/foo.jar");
    Label label =
        Label.parseAbsolute(
            "//some/very/very/long/path/for/some/library/directory:libfoo", ImmutableMap.of());
    ActionOwner owner =
        ActionOwner.create(
            label,
            ImmutableList.<AspectDescriptor>of(),
            null,
            null,
            null,
            "fedcba",
            null,
            null,
            ImmutableMap.of(),
            null);
    when(action.getOwner()).thenReturn(owner);

    clock.advanceMillis(TimeUnit.SECONDS.toMillis(3));
    stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(5));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    assertWithMessage("Progress bar should contain 'Building ', but was:\n" + output)
        .that(output.contains("Building "))
        .isTrue();
    assertWithMessage(
            "Progress bar should contain 'foo.jar (42 source files)', but was:\n" + output)
        .that(output.contains("foo.jar (42 source files)"))
        .isTrue();
  }

  @Test
  public void testActionStrategyVisible() throws Exception {
    // verify that, if a strategy was reported for a shown action, it is visible
    // in the progress bar.
    String strategy = "verySpecialStrategy";
    String primaryOutput = "some/path/to/a/file";

    ManualClock clock = new ManualClock();
    Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
    Artifact artifact =
        ActionsTestUtil.createArtifact(ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)), path);
    Action action = mockAction("Some random action", primaryOutput);
    when(action.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
    when(action.getPrimaryOutput()).thenReturn(artifact);

    UiStateTracker stateTracker = new UiStateTracker(clock);
    stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
    stateTracker.runningAction(new RunningActionEvent(action, strategy));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    assertWithMessage("Output should mention strategy '" + strategy + "', but was: " + output)
        .that(output.contains(strategy))
        .isTrue();
  }

  @Test
  public void testMultipleActionStrategiesVisibleForDynamicScheduling() throws Exception {
    String strategy1 = "strategy1";
    String strategy2 = "stratagy2";
    String primaryOutput = "some/path/to/a/file";

    ManualClock clock = new ManualClock();
    Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
    Artifact artifact =
        ActionsTestUtil.createArtifact(ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)), path);
    Action action = mockAction("Some random action", primaryOutput);
    when(action.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
    when(action.getPrimaryOutput()).thenReturn(artifact);

    UiStateTracker stateTracker = new UiStateTracker(clock);
    stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
    stateTracker.runningAction(new RunningActionEvent(action, strategy1));
    stateTracker.runningAction(new RunningActionEvent(action, strategy2));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    assertWithMessage(
            "Output should mention strategies '"
                + strategy1
                + "' and '"
                + strategy2
                + "', but was: "
                + output)
        .that(output.contains(strategy1 + ", " + strategy2))
        .isTrue();
  }

  @Test
  public void testActionCountsWithDynamicScheduling() throws Exception {
    String primaryOutput1 = "some/path/to/a/file";
    String primaryOutput2 = "some/path/to/b/file";

    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock);
    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);

    Path path1 = outputBase.getRelative(PathFragment.create(primaryOutput1));
    Artifact artifact1 =
        ActionsTestUtil.createArtifact(ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)), path1);
    Action action1 = mockAction("First random action", primaryOutput1);
    when(action1.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
    when(action1.getPrimaryOutput()).thenReturn(artifact1);
    stateTracker.actionStarted(new ActionStartedEvent(action1, clock.nanoTime()));

    Path path2 = outputBase.getRelative(PathFragment.create(primaryOutput2));
    Artifact artifact2 =
        ActionsTestUtil.createArtifact(ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)), path2);
    Action action2 = mockAction("First random action", primaryOutput1);
    when(action2.getOwner()).thenReturn(Mockito.mock(ActionOwner.class));
    when(action2.getPrimaryOutput()).thenReturn(artifact2);
    stateTracker.actionStarted(new ActionStartedEvent(action2, clock.nanoTime()));

    stateTracker.runningAction(new RunningActionEvent(action1, "strategy1"));
    stateTracker.schedulingAction(new SchedulingActionEvent(action2, "strategy1"));
    terminalWriter.reset();
    stateTracker.writeProgressBar(terminalWriter);
    assertThat(terminalWriter.getTranscript()).contains("2 actions, 1 running");

    stateTracker.runningAction(new RunningActionEvent(action1, "strategy2"));
    terminalWriter.reset();
    stateTracker.writeProgressBar(terminalWriter);
    assertThat(terminalWriter.getTranscript()).contains("3 actions, 2 running");

    stateTracker.runningAction(new RunningActionEvent(action2, "strategy1"));
    terminalWriter.reset();
    stateTracker.writeProgressBar(terminalWriter);
    assertThat(terminalWriter.getTranscript()).contains("3 actions running");

    stateTracker.runningAction(new RunningActionEvent(action2, "strategy2"));
    terminalWriter.reset();
    stateTracker.writeProgressBar(terminalWriter);
    assertThat(terminalWriter.getTranscript()).contains("4 actions running");
  }

  private void doTestOutputLength(boolean withTest, int actions) throws Exception {
    // If we target 70 characters, then there should be enough space to both,
    // keep the line limit, and show the local part of the running actions and
    // the passed test.
    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock, 70);

    Action foobuildAction =
        mockAction(
            "Building"
                + " //src/some/very/long/path/long/long/long/long/long/long/long/foo/foobuild.jar",
            "src/some/very/long/path/long/long/long/long/long/long/long/foo/foobuild.jar");
    Action bazbuildAction =
        mockAction(
            "Building"
                + " //src/some/very/long/path/long/long/long/long/long/long/long/baz/bazbuild.jar",
            "src/some/very/long/path/long/long/long/long/long/long/long/baz/bazbuild.jar");

    Label bartestLabel =
        Label.parseAbsolute(
            "//src/another/very/long/long/path/long/long/long/long/long/long/long/long/bars:bartest",
            ImmutableMap.of());
    ConfiguredTarget bartestTarget = Mockito.mock(ConfiguredTarget.class);
    when(bartestTarget.getLabel()).thenReturn(bartestLabel);

    TestFilteringCompleteEvent filteringComplete = Mockito.mock(TestFilteringCompleteEvent.class);
    when(filteringComplete.getTestTargets()).thenReturn(ImmutableSet.of(bartestTarget));

    TestSummary testSummary = Mockito.mock(TestSummary.class);
    when(testSummary.getStatus()).thenReturn(BlazeTestStatus.PASSED);
    when(testSummary.getTarget()).thenReturn(bartestTarget);
    when(testSummary.getLabel()).thenReturn(bartestLabel);

    if (actions >= 1) {
      stateTracker.actionStarted(new ActionStartedEvent(foobuildAction, 123456789));
    }
    if (actions >= 2) {
      stateTracker.actionStarted(new ActionStartedEvent(bazbuildAction, 123456900));
    }
    if (withTest) {
      stateTracker.testFilteringComplete(filteringComplete);
      stateTracker.testSummary(testSummary);
    }

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    assertWithMessage(
            "Only lines with at most 70 chars should be present in the output:\n" + output)
        .that(longestLine(output) <= 70)
        .isTrue();
    if (actions >= 1) {
      assertWithMessage("Running action 'foobuild' should be mentioned in output:\n" + output)
          .that(output.contains("foobuild"))
          .isTrue();
    }
    if (actions >= 2) {
      assertWithMessage("Running action 'bazbuild' should be mentioned in output:\n" + output)
          .that(output.contains("bazbuild"))
          .isTrue();
    }
    if (withTest) {
      assertWithMessage("Passed test ':bartest' should be mentioned in output:\n" + output)
          .that(output.contains(":bartest"))
          .isTrue();
    }
  }

  @Test
  public void testOutputLength() throws Exception {
    for (int i = 0; i < 3; i++) {
      doTestOutputLength(true, i);
      doTestOutputLength(false, i);
    }
  }

  @Test
  public void testStatusShown() throws Exception {
    // Verify that for non-executing actions, at least the first 3 characters of the
    // status are shown.
    // Also verify that the number of running actions is reported correctly, if there is
    // more than one active action and not all are running.
    ManualClock clock = new ManualClock();
    clock.advanceMillis(120000);
    UiStateTracker stateTracker = new UiStateTracker(clock);
    Action actionFoo = mockAction("Building foo", "foo/foo");
    ActionOwner ownerFoo = Mockito.mock(ActionOwner.class);
    when(actionFoo.getOwner()).thenReturn(ownerFoo);
    Action actionBar = mockAction("Building bar", "bar/bar");
    ActionOwner ownerBar = Mockito.mock(ActionOwner.class);
    when(actionBar.getOwner()).thenReturn(ownerBar);
    LoggingTerminalWriter terminalWriter;
    String output;

    // Action foo being scanned.
    stateTracker.actionStarted(new ActionStartedEvent(actionFoo, 123456700));
    stateTracker.scanningAction(new ScanningActionEvent(actionFoo));

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertWithMessage("Action foo being scanned should be visible in output:\n" + output)
        .that(output.contains("sca") || output.contains("Sca"))
        .isTrue();

    // Then action bar gets scheduled.
    stateTracker.actionStarted(new ActionStartedEvent(actionBar, 123456701));
    stateTracker.schedulingAction(new SchedulingActionEvent(actionBar, "bar-sandbox"));

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertWithMessage("Action bar being scheduled should be visible in output:\n" + output)
        .that(output.contains("sch") || output.contains("Sch"))
        .isTrue();
    assertWithMessage("Action foo being scanned should still be visible in output:\n" + output)
        .that(output.contains("sca") || output.contains("Sca"))
        .isTrue();
    assertWithMessage("Indication at no actions are running is missing in output:\n" + output)
        .that(output.contains("0 running"))
        .isTrue();
    assertWithMessage("Total number of actions expected  in output:\n" + output)
        .that(output.contains("2 actions"))
        .isTrue();

    // Then foo starts.
    stateTracker.runningAction(new RunningActionEvent(actionFoo, "xyz-sandbox"));
    stateTracker.writeProgressBar(terminalWriter);

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertWithMessage("Action foo's xyz-sandbox strategy should be shown in output:\n" + output)
        .that(output.contains("xyz-sandbox"))
        .isTrue();
    assertWithMessage("Action foo should no longer be analyzed in output:\n" + output)
        .that(output.contains("ana") || output.contains("Ana"))
        .isFalse();
    assertWithMessage("Action bar being scheduled should still be visible in output:\n" + output)
        .that(output.contains("sch") || output.contains("Sch"))
        .isTrue();
    assertWithMessage("Indication at one action is running is missing in output:\n" + output)
        .that(output.contains("1 running"))
        .isTrue();
    assertWithMessage("Total number of actions expected  in output:\n" + output)
        .that(output.contains("2 actions"))
        .isTrue();
  }

  @Test
  public void testTimerReset() throws Exception {
    // Verify that a change in an action state (e.g., from scheduling to executing) resets
    // the time associated with that action.

    ManualClock clock = new ManualClock();
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(123));
    UiStateTracker stateTracker = new UiStateTracker(clock);
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(2));
    LoggingTerminalWriter terminalWriter;
    String output;

    Action actionFoo = mockAction("Building foo", "foo/foo");
    ActionOwner ownerFoo = Mockito.mock(ActionOwner.class);
    when(actionFoo.getOwner()).thenReturn(ownerFoo);
    Action actionBar = mockAction("Building bar", "bar/bar");
    ActionOwner ownerBar = Mockito.mock(ActionOwner.class);
    when(actionBar.getOwner()).thenReturn(ownerBar);

    stateTracker.actionStarted(new ActionStartedEvent(actionFoo, clock.nanoTime()));
    stateTracker.runningAction(new RunningActionEvent(actionFoo, "foo-sandbox"));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(7));
    stateTracker.actionStarted(new ActionStartedEvent(actionBar, clock.nanoTime()));
    stateTracker.schedulingAction(new SchedulingActionEvent(actionBar, "bar-sandbox"));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(21));

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertWithMessage("Runtime of first action should be visible in output: " + output)
        .that(output.contains("28s"))
        .isTrue();
    assertWithMessage("Scheduling time of second action should be visible in output: " + output)
        .that(output.contains("21s"))
        .isTrue();

    stateTracker.runningAction(new RunningActionEvent(actionBar, "bar-sandbox"));
    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertWithMessage("Runtime of first action should still be visible in output: " + output)
        .that(output.contains("28s"))
        .isTrue();
    assertWithMessage("Time of second action should no longer be visible in output: " + output)
        .that(output.contains("21s"))
        .isFalse();

    clock.advanceMillis(TimeUnit.SECONDS.toMillis(30));
    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertWithMessage("New runtime of first action should be visible in output: " + output)
        .that(output.contains("58s"))
        .isTrue();
    assertWithMessage("Runtime of second action should be visible in output: " + output)
        .that(output.contains("30s"))
        .isTrue();
  }

  @Test
  public void testEarlyStatusHandledGracefully() throws Exception {
    // On the event bus, events sometimes are sent out of order; verify that we handle an
    // early message that an action is running gracefully.
    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock);
    Action actionFoo = mockAction("Building foo", "foo/foo");
    ActionOwner ownerFoo = Mockito.mock(ActionOwner.class);
    when(actionFoo.getOwner()).thenReturn(ownerFoo);
    LoggingTerminalWriter terminalWriter;
    String output;

    // Early status announcement
    stateTracker.runningAction(new RunningActionEvent(actionFoo, "foo-sandbox"));

    // Here we don't expect any particular output, just some description; in particular, we do
    // not expect the state tracker to hit an internal error.
    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertWithMessage("Expected at least some status bar").that(output.length() != 0).isTrue();

    // Action actually started
    stateTracker.actionStarted(new ActionStartedEvent(actionFoo, clock.nanoTime()));

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertWithMessage("Even a strategy announced early should be shown in output:\n" + output)
        .that(output.contains("foo-sandbox"))
        .isTrue();
  }

  @Test
  public void testExecutingActionsFirst() throws Exception {
    // Verify that executing actions, even if started late, are visible.
    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock);
    clock.advanceMillis(120000);

    for (int i = 0; i < 30; i++) {
      Action action = mockAction("Takes long to schedule number " + i, "long/startup" + i);
      ActionOwner owner = Mockito.mock(ActionOwner.class);
      when(action.getOwner()).thenReturn(owner);
      stateTracker.actionStarted(new ActionStartedEvent(action, 123456789 + i));
      stateTracker.schedulingAction(new SchedulingActionEvent(action, "xyz-sandbox"));
    }

    for (int i = 0; i < 3; i++) {
      Action action = mockAction("quickstart" + i, "pkg/quickstart" + i);
      ActionOwner owner = Mockito.mock(ActionOwner.class);
      when(action.getOwner()).thenReturn(owner);
      stateTracker.actionStarted(new ActionStartedEvent(action, 123457000 + i));
      stateTracker.runningAction(new RunningActionEvent(action, "xyz-sandbox"));

      LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
      stateTracker.writeProgressBar(terminalWriter);
      String output = terminalWriter.getTranscript();
      assertWithMessage("Action quickstart" + i + " should be visible in output:\n" + output)
          .that(output.contains("quickstart" + i))
          .isTrue();
      assertWithMessage("Number of running actions should be indicated in output:\n" + output)
          .that(output.contains("" + (i + 1) + " running"))
          .isTrue();
    }
  }

  @Test
  public void testAggregation() throws Exception {
    // Assert that actions for the same test are aggregated so that an action afterwards
    // is still shown.
    ManualClock clock = new ManualClock();
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1234));
    UiStateTracker stateTracker = new UiStateTracker(clock, 80);

    Label labelFooTest = Label.parseAbsolute("//foo/bar:footest", ImmutableMap.of());
    ConfiguredTarget targetFooTest = Mockito.mock(ConfiguredTarget.class);
    when(targetFooTest.getLabel()).thenReturn(labelFooTest);
    ActionOwner fooOwner =
        ActionOwner.create(
            labelFooTest,
            ImmutableList.<AspectDescriptor>of(),
            null,
            null,
            null,
            "abcdef",
            null,
            null,
            ImmutableMap.of(),
            null);

    Label labelBarTest = Label.parseAbsolute("//baz:bartest", ImmutableMap.of());
    ConfiguredTarget targetBarTest = Mockito.mock(ConfiguredTarget.class);
    when(targetBarTest.getLabel()).thenReturn(labelBarTest);
    TestFilteringCompleteEvent filteringComplete = Mockito.mock(TestFilteringCompleteEvent.class);
    when(filteringComplete.getTestTargets())
        .thenReturn(ImmutableSet.of(targetFooTest, targetBarTest));
    ActionOwner barOwner =
        ActionOwner.create(
            labelBarTest,
            ImmutableList.<AspectDescriptor>of(),
            null,
            null,
            null,
            "fedcba",
            null,
            null,
            ImmutableMap.of(),
            null);

    stateTracker.testFilteringComplete(filteringComplete);

    // First produce 10 actions for footest...
    for (int i = 0; i < 10; i++) {
      clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
      Action action = mockAction("Testing foo, shard " + i, "testlog_foo_" + i);
      when(action.getOwner()).thenReturn(fooOwner);
      stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
    }
    // ...then produce 10 actions for bartest...
    for (int i = 0; i < 10; i++) {
      clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
      Action action = mockAction("Testing bar, shard " + i, "testlog_bar_" + i);
      when(action.getOwner()).thenReturn(barOwner);
      stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
    }
    // ...and finally a completely unrelated action
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.actionStarted(
        new ActionStartedEvent(mockAction("Other action", "other/action"), clock.nanoTime()));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    assertWithMessage("Progress bar should contain ':footest', but was:\n" + output)
        .that(output.contains(":footest"))
        .isTrue();
    assertWithMessage("Progress bar should contain ':bartest', but was:\n" + output)
        .that(output.contains(":bartest"))
        .isTrue();
    assertWithMessage("Progress bar should contain 'Other action', but was:\n" + output)
        .that(output.contains("Other action"))
        .isTrue();
  }

  @Test
  public void testSuffix() throws Exception {
    assertThat(UiStateTracker.suffix("foobar", 3)).isEqualTo("bar");
    assertThat(UiStateTracker.suffix("foo", -2)).isEmpty();
    assertThat(UiStateTracker.suffix("foobar", 200)).isEqualTo("foobar");
  }

  @Test
  public void testDownloadShown() throws Exception {
    // Verify that, whenever a single download is running in loading face, it is shown in the status
    // bar.
    ManualClock clock = new ManualClock();
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1234));
    UiStateTracker stateTracker = new UiStateTracker(clock, 80);

    URL url = new URL("http://example.org/first/dep");

    stateTracker.buildStarted(null);
    stateTracker.downloadProgress(new DownloadProgressEvent(url));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(6));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    assertWithMessage("Progress bar should contain '" + url.toString() + "', but was:\n" + output)
        .that(output.contains(url.toString()))
        .isTrue();
    assertWithMessage("Progress bar should contain '6s', but was:\n" + output)
        .that(output.contains("6s"))
        .isTrue();

    // Progress on the pending download should be reported appropriately
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.downloadProgress(new DownloadProgressEvent(url, 256));

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();

    assertWithMessage("Progress bar should contain '" + url.toString() + "', but was:\n" + output)
        .that(output.contains(url.toString()))
        .isTrue();
    assertWithMessage("Progress bar should contain '7s', but was:\n" + output)
        .that(output.contains("7s"))
        .isTrue();
    assertWithMessage("Progress bar should contain '256', but was:\n" + output)
        .that(output.contains("256"))
        .isTrue();

    // After finishing the download, it should no longer be reported.
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.downloadProgress(new DownloadProgressEvent(url, 256, true));

    terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();

    assertWithMessage("Progress bar should not contain url, but was:\n" + output)
        .that(output.contains("example.org"))
        .isFalse();
  }

  @Test
  public void testDownloadOutputLength() throws Exception {
    // Verify that URLs are shortened in a reasonable way, if the terminal is not wide enough
    // Also verify that the length is respected, even if only a download sample is shown.
    ManualClock clock = new ManualClock();
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1234));
    UiStateTracker stateTracker = new UiStateTracker(clock, 60);
    URL url = new URL("http://example.org/some/really/very/very/long/path/filename.tar.gz");

    stateTracker.buildStarted(null);
    stateTracker.downloadProgress(new DownloadProgressEvent(url));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(6));
    for (int i = 0; i < 10; i++) {
      stateTracker.downloadProgress(
          new DownloadProgressEvent(
              new URL(
                  "http://otherhost.example/another/also/length/path/to/another/download"
                      + i
                      + ".zip")));
      clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    }

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();

    assertWithMessage(
            "Only lines with at most 60 chars should be present in the output:\n" + output)
        .that(longestLine(output) <= 60)
        .isTrue();
    assertWithMessage("Output still should contain the filename, but was:\n" + output)
        .that(output.contains("filename.tar.gz"))
        .isTrue();
    assertWithMessage("Output still should contain the host name, but was:\n" + output)
        .that(output.contains("example.org"))
        .isTrue();
  }

  @Test
  public void testMultipleBuildEventProtocolTransports() throws Exception {
    // Verify that all announced transports are present in the progress bar
    // and that as transports are closed they disappear from the progress bar.
    // Verify that the wait duration is displayed.
    // Verify that after all transports have been closed, the build status is displayed.
    ManualClock clock = new ManualClock();
    BuildEventTransport transport1 = newBepTransport("BuildEventTransport1");
    BuildEventTransport transport2 = newBepTransport("BuildEventTransport2");
    BuildEventTransport transport3 = newBepTransport("BuildEventTransport3");
    BuildResult buildResult = new BuildResult(clock.currentTimeMillis());
    buildResult.setExitCondition(ExitCode.SUCCESS);
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    buildResult.setStopTime(clock.currentTimeMillis());

    UiStateTracker stateTracker = new UiStateTracker(clock, 80);
    stateTracker.buildStarted(null);
    stateTracker.buildEventTransportsAnnounced(
        new AnnounceBuildEventTransportsEvent(ImmutableList.of(transport1, transport2)));
    stateTracker.buildEventTransportsAnnounced(
        new AnnounceBuildEventTransportsEvent(ImmutableList.of(transport3)));
    stateTracker.buildComplete(new BuildCompleteEvent(buildResult));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(true);

    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();
    assertThat(output, containsString("1s"));
    assertThat(output, containsString("BuildEventTransport1"));
    assertThat(output, containsString("BuildEventTransport2"));
    assertThat(output, containsString("BuildEventTransport3"));
    assertThat(output, containsString("success"));
    assertThat(output, containsString("complete"));

    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.buildEventTransportClosed(new BuildEventTransportClosedEvent(transport1));
    terminalWriter = new LoggingTerminalWriter(true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertThat(output, containsString("2s"));
    assertThat(output, not(containsString("BuildEventTransport1")));
    assertThat(output, containsString("BuildEventTransport2"));
    assertThat(output, containsString("BuildEventTransport3"));
    assertThat(output, containsString("success"));
    assertThat(output, containsString("complete"));

    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.buildEventTransportClosed(new BuildEventTransportClosedEvent(transport3));
    terminalWriter = new LoggingTerminalWriter(true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertThat(output, containsString("3s"));
    assertThat(output, not(containsString("BuildEventTransport1")));
    assertThat(output, containsString("BuildEventTransport2"));
    assertThat(output, not(containsString("BuildEventTransport3")));
    assertThat(output, containsString("success"));
    assertThat(output, containsString("complete"));

    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.buildEventTransportClosed(new BuildEventTransportClosedEvent(transport2));
    terminalWriter = new LoggingTerminalWriter(true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertThat(output, not(containsString("3s")));
    assertThat(output, not(containsString("BuildEventTransport1")));
    assertThat(output, not(containsString("BuildEventTransport2")));
    assertThat(output, not(containsString("BuildEventTransport3")));
    assertThat(output, containsString("success"));
    assertThat(output, containsString("complete"));
    assertThat(output.split("\\n")).hasLength(1);
  }

  @Test
  public void testBuildEventTransportsOnNarrowTerminal() throws IOException {
    // Verify that the progress bar contains useful information on a 60-character terminal.
    //   - Too long names should be shortened to reasonably long prefixes of the name.
    ManualClock clock = new ManualClock();
    BuildEventTransport transport1 = newBepTransport(Strings.repeat("A", 61));
    BuildEventTransport transport2 = newBepTransport("BuildEventTransport");
    BuildResult buildResult = new BuildResult(clock.currentTimeMillis());
    buildResult.setExitCondition(ExitCode.SUCCESS);
    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(true);
    UiStateTracker stateTracker = new UiStateTracker(clock, 60);
    stateTracker.buildStarted(null);
    stateTracker.buildEventTransportsAnnounced(
        new AnnounceBuildEventTransportsEvent(ImmutableList.of(transport1, transport2)));
    stateTracker.buildComplete(new BuildCompleteEvent(buildResult));
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();
    assertThat(longestLine(output)).isAtMost(60);
    assertThat(output, containsString("1s"));
    assertThat(output, containsString(Strings.repeat("A", 30) + "..."));
    assertThat(output, containsString("BuildEventTransport"));
    assertThat(output, containsString("success"));
    assertThat(output, containsString("complete"));

    clock.advanceMillis(TimeUnit.SECONDS.toMillis(1));
    stateTracker.buildEventTransportClosed(new BuildEventTransportClosedEvent(transport2));
    terminalWriter = new LoggingTerminalWriter(true);
    stateTracker.writeProgressBar(terminalWriter);
    output = terminalWriter.getTranscript();
    assertThat(longestLine(output)).isAtMost(60);
    assertThat(output, containsString("2s"));
    assertThat(output, containsString(Strings.repeat("A", 30) + "..."));
    assertThat(output, not(containsString("BuildEventTransport")));
    assertThat(output, containsString("success"));
    assertThat(output, containsString("complete"));
    assertThat(output.split("\\n")).hasLength(2);
  }

  private BuildEventTransport newBepTransport(String name) {
    BuildEventTransport transport = Mockito.mock(BuildEventTransport.class);
    when(transport.name()).thenReturn(name);
    return transport;
  }

  @Test
  public void testTotalFetchesReported() throws IOException {
    ManualClock clock = new ManualClock();
    UiStateTracker stateTracker = new UiStateTracker(clock, 80);

    stateTracker.buildStarted(null);
    for (int i = 0; i < 30; i++) {
      stateTracker.downloadProgress(new FetchEvent("@repoFoo" + i));
    }
    clock.advanceMillis(TimeUnit.SECONDS.toMillis(7));

    LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(true);
    stateTracker.writeProgressBar(terminalWriter);
    String output = terminalWriter.getTranscript();
    assertThat(output, containsString("@repoFoo"));
    assertThat(output, containsString("7s"));
    assertThat(output, containsString("30 fetches"));
  }

  private Action mockActionWithMnemonic(String mnemonic, String primaryOutput) {
    Path path = outputBase.getRelative(PathFragment.create(primaryOutput));
    Artifact artifact =
        ActionsTestUtil.createArtifact(ArtifactRoot.asSourceRoot(Root.fromPath(outputBase)), path);
    Action action = Mockito.mock(Action.class);
    when(action.getMnemonic()).thenReturn(mnemonic);
    when(action.getPrimaryOutput()).thenReturn(artifact);
    return action;
  }

  @Test
  public void testMnemonicHistogram() throws IOException {
    // Verify that the number of actions shown in the progress bar can be set as sample size.
    ManualClock clock = new ManualClock();
    clock.advanceMillis(Duration.ofSeconds(123).toMillis());
    UiStateTracker stateTracker = new UiStateTracker(clock);
    clock.advanceMillis(Duration.ofSeconds(2).toMillis());

    // Start actions with 10 different mnemonics Mnemonic0-9, n+1 of each mnemonic.
    for (int i = 0; i < 10; i++) {
      clock.advanceMillis(Duration.ofSeconds(1).toMillis());
      for (int j = 0; j <= i; j++) {
        Action action = mockActionWithMnemonic("Mnemonic" + i, "action-" + i + "-" + j + ".out");
        stateTracker.actionStarted(new ActionStartedEvent(action, clock.nanoTime()));
      }
    }

    for (int sampleSize = 1; sampleSize < 11; sampleSize++) {
      stateTracker.setProgressMode(ProgressMode.MNEMONIC_HISTOGRAM, sampleSize);
      LoggingTerminalWriter terminalWriter = new LoggingTerminalWriter(/*discardHighlight=*/ true);
      stateTracker.writeProgressBar(terminalWriter);
      String output = terminalWriter.getTranscript();
      assertThat(output).contains("Mnemonic" + (10 - sampleSize) + " " + (10 - sampleSize + 1));
      assertThat(output).doesNotContain("Mnemonic" + (10 - sampleSize - 1));
    }
  }

  private static class FetchEvent implements FetchProgress {
    private final String id;

    FetchEvent(String id) {
      this.id = id;
    }

    @Override
    public String getResourceIdentifier() {
      return id;
    }

    @Override
    public String getProgress() {
      return "working...";
    }

    @Override
    public boolean isFinished() {
      return false;
    }
  }
}
