// Copyright 2022 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.metrics;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.common.eventbus.Subscribe;
import com.google.devtools.build.lib.actions.BuildFailedException;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.ActionSummary.ActionData;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.ArtifactMetrics;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.BuildGraphMetrics;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.CumulativeMetrics;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.clock.JavaClock;
import com.google.devtools.build.lib.profiler.MemoryProfiler;
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.BlazeRuntime;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.worker.WorkerMetricsCollector;
import java.util.List;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests metric collection. */
@RunWith(JUnit4.class)
public class MetricsCollectorTest extends BuildIntegrationTestCase {

  static class BuildMetricsEventListener extends BlazeModule {

    private BuildMetricsEvent event;

    @Override
    public void beforeCommand(CommandEnvironment env) {
      env.getEventBus().register(this);
    }

    @Subscribe
    public void onBuildMetrics(BuildMetricsEvent event) {
      this.event = event;
    }
  }

  private BuildMetricsEventListener buildMetricsEventListener = new BuildMetricsEventListener();

  @Override
  protected BlazeRuntime.Builder getRuntimeBuilder() throws Exception {
    return super.getRuntimeBuilder()
        .addBlazeModule(new MetricsModule())
        .addBlazeModule(buildMetricsEventListener);
  }

  @Before
  public void writeTrivialFooTarget() throws Exception {
    write(
        "foo/BUILD",
        "genrule(",
        "    name = 'foo',",
        "    outs = ['dir'],",
        "    cmd = '/bin/mkdir $(location dir)',",
        "    srcs = [],",
        ")");
  }

  @Before
  public void setUpWorkerMetricsCollecto() {
    WorkerMetricsCollector.instance().setClock(new JavaClock());
  }

  @After
  public void resetProfilers() throws Exception {
    MemoryProfiler.instance().stop();
    PostGCMemoryUseRecorder.get().reset();
  }

  @Test
  public void testActionsCreated() throws Exception {
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getActionSummary().getActionsCreated()).isGreaterThan(0L);
  }

  @Test
  public void testActionsCreatedIsZeroOnSecondBuild() throws Exception {
    buildTarget("//foo:foo");
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getActionSummary().getActionsCreated()).isEqualTo(0);
  }

  @Test
  public void testActionsExecuted() throws Exception {
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getActionSummary().getActionsExecuted()).isGreaterThan(0L);
  }

  @Test
  public void testActionsExecutedIsZeroOnSecondBuild() throws Exception {
    buildTarget("//foo:foo");
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getActionSummary().getActionsExecuted()).isEqualTo(0);
  }

  @Test
  public void buildGraphAndArtifactMetrics() throws Exception {
    write(
        "a/BUILD",
        "genrule(name = 'a', srcs = ['//b:b', '//b:c'], outs = ['a.out'], cmd = 'cat $(SRCS) >"
            + " $@')");
    write(
        "b/BUILD",
        "genrule(name = 'b', srcs = ['b.in', 'c.in'], outs = ['b.out'], cmd = 'cat $(SRCS) > $@')",
        "genrule(name = 'c', srcs = ['c.in', 'c2.in'], outs = ['c.out'], cmd = 'cat $(SRCS) >"
            + " $@')");
    if (OS.getCurrent() == OS.WINDOWS) {
      // On Windows we have \r\n line endings while on other platforms only \n. So make the file one
      // byte shorter on Windows so that the byte counts below match.
      write("b/b.in", "1234");
      write("b/c.in", "1");
    } else {
      write("b/b.in", "12345");
      write("b/c.in", "12");
    }
    createSymlink("c.in", "b/c2.in");
    write(
        "e/BUILD",
        "alias(name = 'facade', actual = ':e.out')",
        "genrule(name = 'e', srcs = ['e.in'], outs = ['e.out'], cmd = 'cat $(SRCS) > $@')");
    if (OS.getCurrent() == OS.WINDOWS) {
      // On Windows we have \r\n line endings while on other platforms only \n. So make the file one
      // byte shorter on Windows so that the byte counts below match.
      write("e/e.in", "ab");
    } else {
      write("e/e.in", "abc");
    }

    // Do one build of a target in a standalone package. Gets us a baseline for analysis/execution.
    buildTarget("//e:facade");
    BuildGraphMetrics buildGraphMetrics =
        buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics();
    int actionLookupValueCount = buildGraphMetrics.getActionLookupValueCount();
    // All these numbers should be big, but just want a basic check.
    assertThat(actionLookupValueCount).isGreaterThan(0);
    assertThat(buildGraphMetrics.getActionLookupValueCountNotIncludingAspects())
        .isEqualTo(actionLookupValueCount);
    int actionCount = buildGraphMetrics.getActionCount();
    assertThat(actionCount).isGreaterThan(0);
    assertThat(buildGraphMetrics.getActionCountNotIncludingAspects()).isEqualTo(actionCount);
    assertThat(buildGraphMetrics)
        .comparingExpectedFieldsOnly()
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                .setOutputFileConfiguredTargetCount(1)
                .setOtherConfiguredTargetCount(1)
                .build());
    int outputArtifactCount = buildGraphMetrics.getOutputArtifactCount();
    assertThat(outputArtifactCount).isGreaterThan(0);
    int graphSize = buildGraphMetrics.getPostInvocationSkyframeNodeCount();
    assertThat(graphSize).isGreaterThan(0);
    ArtifactMetrics artifactMetrics =
        buildMetricsEventListener.event.getBuildMetrics().getArtifactMetrics();
    assertThat(artifactMetrics.getSourceArtifactsRead().getSizeInBytes()).isGreaterThan(0L);
    assertThat(artifactMetrics.getOutputArtifactsSeen())
        .isEqualTo(ArtifactMetrics.FilesMetric.newBuilder().setSizeInBytes(4L).setCount(3).build());
    assertThat(artifactMetrics.getOutputArtifactsFromActionCache().getCount()).isEqualTo(0);
    assertThat(artifactMetrics.getTopLevelArtifacts())
        .isEqualTo(ArtifactMetrics.FilesMetric.newBuilder().setSizeInBytes(4L).setCount(1).build());
    // Adjust for the "alias", "input" and "output" configured targets, which won't be in play
    // later.
    actionLookupValueCount -= 3;

    // Now do a build of a target with non-trivial transitive deps, and verify the metrics. Blaze
    // won't redo analysis of dependencies or re-read their sources.
    buildTarget("//a");

    buildGraphMetrics = buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics();
    assertThat(buildGraphMetrics)
        .comparingExpectedFieldsOnly()
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                // Two dependencies and three source files for action lookup values.
                .setActionLookupValueCount(5 + actionLookupValueCount)
                .setActionCount(2 + actionCount)
                .setInputFileConfiguredTargetCount(4)
                .setOutputArtifactCount(2 + outputArtifactCount)
                .build());

    int newGraphSize = buildGraphMetrics.getPostInvocationSkyframeNodeCount();
    assertThat(newGraphSize).isGreaterThan(graphSize);

    assertThat(buildMetricsEventListener.event.getBuildMetrics().getArtifactMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            ArtifactMetrics.newBuilder()
                // 2 distinct artifacts of 6 and 3 bytes, with a symlink to the 3-byte one.
                .setSourceArtifactsRead(
                    ArtifactMetrics.FilesMetric.newBuilder().setSizeInBytes(12).setCount(3))
                // b outputs 9 bytes, c outputs 6, a outputs 15, 30 total.
                .setOutputArtifactsSeen(
                    ArtifactMetrics.FilesMetric.newBuilder().setSizeInBytes(30).setCount(3).build())
                .setTopLevelArtifacts(
                    ArtifactMetrics.FilesMetric.newBuilder().setSizeInBytes(15).setCount(1).build())
                .build());

    // Do a null build. No useful analysis stats.
    buildTarget("//a");

    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                .setPostInvocationSkyframeNodeCount(newGraphSize)
                .build());
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getArtifactMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(ArtifactMetrics.getDefaultInstance());

    // Change a BUILD file and rebuild: no source artifacts read, but analysis stats present.
    write(
        "a/BUILD",
        "genrule(name = 'a', srcs = ['//b:c', '//b:b'], outs = ['a.out'], cmd = 'cat $(SRCS) >"
            + " $@')");
    buildTarget("//a");

    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                .setActionLookupValueCount(5 + actionLookupValueCount)
                .setActionLookupValueCountNotIncludingAspects(5 + actionLookupValueCount)
                .setActionCount(2 + actionCount)
                .setActionCountNotIncludingAspects(2 + actionCount)
                .setInputFileConfiguredTargetCount(4)
                .setOutputArtifactCount(2 + outputArtifactCount)
                // ArtifactNestedSet node for stale nested set is still in graph, since it is
                // technically still valid (even though nobody wants that nested set anymore).
                .setPostInvocationSkyframeNodeCount(newGraphSize + 1)
                .build());
    ArtifactMetrics.FilesMetric singleFileMetric =
        ArtifactMetrics.FilesMetric.newBuilder().setSizeInBytes(15L).setCount(1).build();
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getArtifactMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            ArtifactMetrics.newBuilder()
                .setOutputArtifactsSeen(singleFileMetric)
                .setTopLevelArtifacts(singleFileMetric)
                .build());

    // Change BUILD file back, but don't do a full build.
    write(
        "a/BUILD",
        "genrule(name = 'a', srcs = ['//b:c', '//b:b'], outs = ['a.out'], cmd = 'cat $(SRCS) >"
            + " $@')");
    addOptions("--nobuild");
    buildTarget("//a");
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                .setActionLookupValueCount(5 + actionLookupValueCount)
                .setActionLookupValueCountNotIncludingAspects(5 + actionLookupValueCount)
                .setActionCount(2 + actionCount)
                .setActionCountNotIncludingAspects(2 + actionCount)
                .setInputFileConfiguredTargetCount(4)
                .setOutputArtifactCount(2 + outputArtifactCount)
                .setPostInvocationSkyframeNodeCount(newGraphSize + 1)
                .build());
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getArtifactMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(ArtifactMetrics.getDefaultInstance());

    // Null --nobuild.
    buildTarget("//a");
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                // Stale action execution nodes have been GC'ed.
                .setPostInvocationSkyframeNodeCount(newGraphSize - 1)
                .build());

    // Do a null full build. Back to baseline.
    addOptions("--build");
    buildTarget("//a");
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                // We now have three copies of the ArtifactNestedSetKey, since the re-analysis
                // didn't re-use the old nested set.
                .setPostInvocationSkyframeNodeCount(newGraphSize + 2)
                .build());
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getArtifactMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            ArtifactMetrics.newBuilder()
                .setOutputArtifactsSeen(singleFileMetric)
                .setOutputArtifactsFromActionCache(singleFileMetric)
                .setTopLevelArtifacts(singleFileMetric)
                .build());

    // Change a source file. It and its symlink are both re-read.
    write("b/c.in", "1234");
    buildTarget("//a");
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                // Analysis not re-triggered, even of the input file that was changed.
                .setInputFileConfiguredTargetCount(0)
                .setPostInvocationSkyframeNodeCount(newGraphSize + 2)
                .build());
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getArtifactMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            ArtifactMetrics.newBuilder()
                .setSourceArtifactsRead(
                    ArtifactMetrics.FilesMetric.newBuilder()
                        .setSizeInBytes(OS.getCurrent() == OS.WINDOWS ? 6 : 10)
                        .setCount(OS.getCurrent() == OS.WINDOWS ? 1 : 2))
                .setOutputArtifactsSeen(
                    ArtifactMetrics.FilesMetric.newBuilder()
                        .setSizeInBytes(42L)
                        .setCount(3)
                        .build())
                .setTopLevelArtifacts(
                    ArtifactMetrics.FilesMetric.newBuilder()
                        .setSizeInBytes(21L)
                        .setCount(1)
                        .build())
                .build());
  }

  @Test
  public void treeArtifactAndTopLevelMetrics() throws Exception {
    write(
        "foo/tree_artifact_rule.bzl",
        "def _tree_artifact_files_impl(ctx):",
        "    directory = ctx.actions.declare_directory(ctx.attr.name + '_artifact')",
        "    ctx.actions.run_shell(",
        "      outputs = [directory],",
        "      command = 'cd %s && echo a > file1 && echo bcde > file2}' % (directory.path))",
        "    return [DefaultInfo(files = depset([directory]))]",
        "def _several_outputs_impl(ctx):",
        "    file = ctx.actions.declare_file(ctx.attr.name + '_file')",
        "    ctx.actions.write(output = file, content = 'abc')",
        "    return [DefaultInfo(files = depset([file])),",
        "            OutputGroupInfo(dep_files = ctx.attr.dep[DefaultInfo].files)]",
        "my_tree = rule(implementation = _tree_artifact_files_impl)",
        "my_rule = rule(",
        "               implementation = _several_outputs_impl,",
        "               attrs = { 'dep': attr.label()},",
        " )");
    write(
        "foo/BUILD",
        "load('//foo:tree_artifact_rule.bzl', 'my_rule', 'my_tree')",
        "my_tree(name = 'tree')",
        "my_rule(name = 'top', dep = ':tree')");
    // Null build to populate silly things like fake build-info artifact.
    buildTarget();
    addOptions("--output_groups=+dep_files");
    buildTarget("//foo:top");
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getArtifactMetrics())
        .ignoringFieldAbsence()
        .isEqualTo(
            ArtifactMetrics.newBuilder()
                .setOutputArtifactsSeen(
                    ArtifactMetrics.FilesMetric.newBuilder()
                        .setSizeInBytes(10L)
                        .setCount(3)
                        .build())
                .setTopLevelArtifacts(
                    ArtifactMetrics.FilesMetric.newBuilder()
                        .setSizeInBytes(10L)
                        .setCount(3)
                        .build())
                .build());
  }

  @Test
  public void testTargetCounts() throws Exception {
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getTargetMetrics().getTargetsConfigured()).isGreaterThan(0L);
    assertThat(buildMetrics.getTargetMetrics().getTargetsConfiguredNotIncludingAspects())
        .isGreaterThan(0L);
  }

  @Test
  public void testTargetsCountsAreZeroOnSecondBuild() throws Exception {
    buildTarget("//foo:foo");
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getTargetMetrics().getTargetsLoaded()).isEqualTo(0);
    assertThat(buildMetrics.getTargetMetrics().getTargetsConfigured()).isEqualTo(0);
  }

  @Test
  public void aspectLoadedMetric() throws Exception {
    write(
        "foo/foo.bzl",
        "def _aspect_impl(target, ctx):",
        "  outfile = ctx.actions.declare_file(ctx.rule.attr.name + 'aspect.out')",
        "  ctx.actions.run_shell(",
        "    outputs = [outfile],",
        "    command = 'echo \"1\" > ' + outfile.path,",
        "  )",
        "  return [OutputGroupInfo(files = [outfile])]",
        "",
        "def _impl(ctx):",
        "    return []",
        "",
        "rule_aspect = aspect(implementation = _aspect_impl, attr_aspects = ['deps'])",
        "",
        "aspected = rule(",
        "    implementation = _impl,",
        "    attrs = { 'deps': attr.label_list(aspects = [rule_aspect]) })");
    write(
        "foo/BUILD",
        "load('//foo:foo.bzl', 'aspected')",
        "aspected(name = 'top', deps = [':dep'])",
        "aspected(name = 'dep')");
    buildTarget("//foo:top");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    // 2 additional: aspect and workspace status action.
    assertThat(buildMetrics.getTargetMetrics().getTargetsConfigured())
        .isEqualTo(2L + buildMetrics.getTargetMetrics().getTargetsConfiguredNotIncludingAspects());
    assertThat(buildMetrics.getActionSummary().getActionsCreated())
        .isEqualTo(2L + buildMetrics.getActionSummary().getActionsCreatedNotIncludingAspects());
    // Traversing the Skyframe graph doesn't hit the workspace status action.
    assertThat(buildMetrics.getBuildGraphMetrics().getActionLookupValueCount())
        .isEqualTo(
            1L
                + buildMetrics
                    .getBuildGraphMetrics()
                    .getActionLookupValueCountNotIncludingAspects());
    assertThat(buildMetrics.getBuildGraphMetrics().getActionCount())
        .isEqualTo(1L + buildMetrics.getBuildGraphMetrics().getActionCountNotIncludingAspects());

    // Analyzing a new target makes the aspect drop out of the target metric, but the build graph
    // metric still knows about it.
    write("bar/BUILD", "genrule(name = 'bar', outs = ['out'], cmd = 'touch $@')");
    buildTarget("//foo:top", "//bar:bar");
    buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getTargetMetrics().getTargetsConfigured())
        .isEqualTo(buildMetrics.getTargetMetrics().getTargetsConfiguredNotIncludingAspects());
    assertThat(buildMetrics.getActionSummary().getActionsCreated())
        .isEqualTo(buildMetrics.getActionSummary().getActionsCreatedNotIncludingAspects());
    assertThat(buildMetrics.getBuildGraphMetrics().getActionLookupValueCount())
        .isEqualTo(
            1L
                + buildMetrics
                    .getBuildGraphMetrics()
                    .getActionLookupValueCountNotIncludingAspects());
    assertThat(buildMetrics.getBuildGraphMetrics().getActionCount())
        .isEqualTo(1L + buildMetrics.getBuildGraphMetrics().getActionCountNotIncludingAspects());
  }

  @Test
  public void testPackagesLoaded() throws Exception {
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getPackageMetrics().getPackagesLoaded()).isGreaterThan(0L);
  }

  @Test
  public void testPackagesLoadedIsZeroOnSecondBuild() throws Exception {
    buildTarget("//foo:foo");
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getPackageMetrics().getPackagesLoaded()).isEqualTo(0);
  }

  @Test
  public void testAnalysisTimeInMs() throws Exception {
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getTimingMetrics().getAnalysisPhaseTimeInMs()).isGreaterThan(0);
  }

  @Test
  public void testUsedHeapSizePostBuild() throws Exception {
    // TODO(bazel-team): Fix recording used heap size on Windows.
    Assume.assumeTrue(OS.getCurrent() != OS.WINDOWS);
    addOptions("--memory_profile=/dev/null");

    // The options from above do not get added to the initial command environment,
    // so it has to be recreated here.
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getMemoryMetrics().getUsedHeapSizePostBuild()).isGreaterThan(0L);
    // Note that we cannot test peak heap size here since the tiny builds that we do here don't
    // trigger a full GC.
  }

  @Test
  public void testUsedHeapSizePostBuildCollectionOffByDefault() throws Exception {
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getMemoryMetrics().getUsedHeapSizePostBuild()).isEqualTo(0);
    assertThat(buildMetrics.getMemoryMetrics().getPeakPostGcHeapSize()).isEqualTo(0);
    assertThat(buildMetrics.getMemoryMetrics().getPeakPostGcTenuredSpaceHeapSize()).isEqualTo(0);
  }

  @Test
  public void testWallTimePostBuild() throws Exception {
    buildTarget("//foo:foo");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    assertThat(buildMetrics.getTimingMetrics().getWallTimeInMs()).isGreaterThan(0);
  }

  @Test
  public void cumulativeMetrics() throws Exception {
    buildTarget("//foo:foo");
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getCumulativeMetrics())
        .isEqualTo(CumulativeMetrics.newBuilder().setNumAnalyses(1).setNumBuilds(1).build());

    addOptions("--nobuild");
    buildTarget("//foo:foo");
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getCumulativeMetrics())
        .isEqualTo(CumulativeMetrics.newBuilder().setNumAnalyses(2).setNumBuilds(1).build());

    addOptions("--build", "--noanalyze");
    buildTarget("//foo:foo");
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getCumulativeMetrics())
        .isEqualTo(CumulativeMetrics.newBuilder().setNumAnalyses(2).setNumBuilds(1).build());

    write(
        "foo/BUILD",
        "genrule(",
        "    name = 'foo',",
        "    outs = ['dir'],",
        "    srcs = ['//noexist:noexist'],",
        "    cmd = '/bin/mkdir $(location dir)',",
        ")");

    addOptions("--analyze");
    assertThrows(ViewCreationFailedException.class, () -> buildTarget("//foo:foo"));
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getCumulativeMetrics())
        .isEqualTo(CumulativeMetrics.newBuilder().setNumAnalyses(3).setNumBuilds(1).build());

    write(
        "foo/BUILD",
        "genrule(",
        "    name = 'foo',",
        "    outs = ['dir'],",
        "    cmd = '/bin/false',",
        ")");

    assertThrows(BuildFailedException.class, () -> buildTarget("//foo:foo"));
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getCumulativeMetrics())
        .isEqualTo(CumulativeMetrics.newBuilder().setNumAnalyses(4).setNumBuilds(2).build());
  }

  @Test
  public void testActionData() throws Exception {
    write(
        "bar/BUILD",
        "genrule(name='bar', srcs=[':dep1',':dep2'], outs=['out'], cmd='touch $@')",
        "genrule(name='dep1', outs=['out1'], cmd='touch $@')",
        "genrule(name='dep2', outs=['out2'], cmd='touch $@')");
    buildTarget("//bar");
    BuildMetrics buildMetrics = buildMetricsEventListener.event.getBuildMetrics();
    List<ActionData> actionDataList = buildMetrics.getActionSummary().getActionDataList();
    assertThat(actionDataList).hasSize(2);
    assertThat(actionDataList.get(0).getMnemonic()).isEqualTo("Genrule");
    assertThat(actionDataList.get(0).getActionsExecuted()).isEqualTo(3);

    assertThat(actionDataList.get(1).getMnemonic()).isEqualTo("DummyBuildInfoAction");
    assertThat(actionDataList.get(1).getActionsExecuted()).isEqualTo(1);

    for (ActionData actionData : actionDataList) {
      assertThat(actionData.getFirstStartedMs()).isAtMost(actionData.getLastEndedMs());
    }
  }
}
