// 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");

    // For null build, we don't do any conflict checking. As the metrics are collected during the
    // traversal that's part of conflict checking, these analysis-related numbers are 0.
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .isEqualTo(
            BuildGraphMetrics.newBuilder()
                .setActionLookupValueCount(0)
                .setActionLookupValueCountNotIncludingAspects(0)
                .setActionCount(0)
                .setActionCountNotIncludingAspects(0)
                .setInputFileConfiguredTargetCount(0)
                .setOutputArtifactCount(0)
                .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());
    }
  }

  @Test
  public void skymeldNullIncrementalBuild_buildGraphMetricsCollected() throws Exception {
    write(
        "foo/BUILD",
        "genrule(",
        "    name = 'foo',",
        "    outs = ['dir'],",
        "    cmd = '/bin/mkdir $(location dir)',",
        "    srcs = [],",
        ")",
        "genrule(",
        "    name = 'bar',",
        "    outs = ['dir2'],",
        "    cmd = '/bin/mkdir $(location dir2)',",
        "    srcs = [],",
        ")");
    addOptions("--experimental_merged_skyframe_analysis_execution");
    BuildGraphMetrics expected =
        BuildGraphMetrics.newBuilder()
            .setActionLookupValueCount(3)
            .setActionLookupValueCountNotIncludingAspects(3)
            .setActionCount(2)
            .setActionCountNotIncludingAspects(2)
            .setInputFileConfiguredTargetCount(1)
            .setOutputArtifactCount(2)
            .build();
    buildTarget("//foo:foo", "//foo:bar");

    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .comparingExpectedFieldsOnly()
        .isEqualTo(expected);

    // Null build.
    buildTarget("//foo:foo", "//foo:bar");

    // For Skymeld, we expect BuildGraphMetrics to include all the entities that were touched in the
    // build. This is not true for regular blaze: the metric is only collected if there's conflict
    // checking.
    assertThat(buildMetricsEventListener.event.getBuildMetrics().getBuildGraphMetrics())
        .comparingExpectedFieldsOnly()
        .isEqualTo(expected);
  }
}
