// 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.buildtool;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.TestConstants.WORKSPACE_NAME;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.eventbus.Subscribe;
import com.google.devtools.build.lib.actions.BuildFailedException;
import com.google.devtools.build.lib.analysis.AnalysisPhaseCompleteEvent;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.skyframe.SkymeldModule;
import com.google.devtools.build.lib.skyframe.TopLevelStatusEvents.TopLevelEntityAnalysisConcludedEvent;
import com.google.devtools.build.lib.util.io.RecordingOutErr;
import com.google.devtools.build.lib.vfs.Path;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Integration tests for project Skymeld: interleaving Skyframe's analysis and execution phases. */
@RunWith(TestParameterInjector.class)
public class SkymeldBuildIntegrationTest extends BuildIntegrationTestCase {
  private EventsSubscriber eventsSubscriber;

  @Before
  public void setUp() {
    addOptions("--experimental_merged_skyframe_analysis_execution");
    this.eventsSubscriber = new EventsSubscriber();
    runtimeWrapper.registerSubscriber(eventsSubscriber);
  }

  /** A simple rule that has srcs, deps and writes these attributes to its output. */
  private void writeMyRuleBzl() throws IOException {
    write(
        "foo/my_rule.bzl",
        """
        def _path(file):
            return file.path

        def _impl(ctx):
            inputs = depset(
                ctx.files.srcs,
                transitive = [dep[DefaultInfo].files for dep in ctx.attr.deps],
            )
            output = ctx.actions.declare_file(ctx.attr.name + ".out")
            command = "echo $@ > %s" % (output.path)
            args = ctx.actions.args()
            args.add_all(inputs, map_each = _path)
            ctx.actions.run_shell(
                inputs = inputs,
                outputs = [output],
                command = command,
                arguments = [args],
            )
            return DefaultInfo(files = depset([output]))

        my_rule = rule(
            implementation = _impl,
            attrs = {
                "srcs": attr.label_list(allow_files = True),
                "deps": attr.label_list(providers = ["DefaultInfo"]),
            },
        )
        """);
  }

  private void writeAnalysisFailureAspectBzl() throws IOException {
    write(
        "foo/aspect.bzl",
        """
        def _aspect_impl(target, ctx):
            malformed

        analysis_err_aspect = aspect(implementation = _aspect_impl)
        """);
  }

  private void writeExecutionFailureAspectBzl() throws IOException {
    write(
        "foo/aspect.bzl",
        """
        def _aspect_impl(target, ctx):
            output = ctx.actions.declare_file("aspect_output")
            ctx.actions.run_shell(
                outputs = [output],
                command = "false",
            )
            return [OutputGroupInfo(
                files = depset([output]),
            )]

        execution_err_aspect = aspect(implementation = _aspect_impl)
        """);
  }

  private void writeEnvironmentRules(String... defaults) throws Exception {
    StringBuilder defaultsBuilder = new StringBuilder();
    for (String defaultEnv : defaults) {
      defaultsBuilder.append("'").append(defaultEnv).append("', ");
    }

    write(
        "buildenv/BUILD",
        "environment_group(",
        "    name = 'group',",
        "    environments = [':one', ':two'],",
        "    defaults = [" + defaultsBuilder + "])",
        "environment(name = 'one')",
        "environment(name = 'two')");
  }

  @CanIgnoreReturnValue
  private Path assertSingleOutputBuilt(String target) throws Exception {
    Path singleOutput = Iterables.getOnlyElement(getArtifacts(target)).getPath();
    assertThat(singleOutput.isFile()).isTrue();

    return singleOutput;
  }

  @Test
  public void nobuild_warning() throws Exception {
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");
    addOptions("--nobuild");

    RecordingOutErr recordedOutput = divertInfoLogToOutErr();
    BuildResult result = buildTarget("//foo:foo");

    assertThat(result.getSuccess()).isTrue();
    assertThat(recordedOutput.errAsLatin1())
        .containsMatch(
            "--experimental_merged_skyframe_analysis_execution is incompatible with --nobuild"
                + " and will be ignored");
  }

  @Test
  public void multiTargetBuild_success() throws Exception {
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "bar",
            srcs = ["bar.in"],
        )

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");
    write("foo/bar.in");

    BuildResult result = buildTarget("//foo:foo", "//foo:bar");

    assertThat(result.getSuccess()).isTrue();
    assertSingleOutputBuilt("//foo:foo");
    assertSingleOutputBuilt("//foo:bar");

    assertThat(getLabelsOfAnalyzedTargets()).containsExactly("//foo:foo", "//foo:bar");
    assertThat(getLabelsOfBuiltTargets()).containsExactly("//foo:foo", "//foo:bar");

    assertThat(eventsSubscriber.getTopLevelEntityAnalysisConcludedEvents()).hasSize(2);
    assertSingleAnalysisPhaseCompleteEventWithLabels("//foo:foo", "//foo:bar");

    assertThat(directories.getOutputPath(WORKSPACE_NAME).getRelative("build-info.txt").isFile())
        .isTrue();
    assertThat(
            directories.getOutputPath(WORKSPACE_NAME).getRelative("build-changelist.txt").isFile())
        .isTrue();
  }

  @Test
  public void multiTargetNullIncrementalBuild_success() throws Exception {
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "bar",
            srcs = ["bar.in"],
        )

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");
    write("foo/bar.in");

    // First build, ignored.
    buildTarget("//foo:foo", "//foo:bar");
    BuildResult result = buildTarget("//foo:foo", "//foo:bar");

    assertThat(result.getSuccess()).isTrue();
    assertSingleOutputBuilt("//foo:foo");
    assertSingleOutputBuilt("//foo:bar");

    assertThat(directories.getOutputPath(WORKSPACE_NAME).getRelative("build-info.txt").isFile())
        .isTrue();
    assertThat(
        directories.getOutputPath(WORKSPACE_NAME).getRelative("build-changelist.txt").isFile())
        .isTrue();
  }

  @Test
  public void aspectAnalysisFailure_consistentWithNonSkymeld(
      @TestParameter boolean keepGoing, @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--keep_going=" + keepGoing);
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeMyRuleBzl();
    writeAnalysisFailureAspectBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");

    addOptions("--aspects=//foo:aspect.bzl%analysis_err_aspect", "--output_groups=files");
    if (keepGoing) {
      assertThrows(BuildFailedException.class, () -> buildTarget("//foo:foo"));
    } else {
      assertThrows(ViewCreationFailedException.class, () -> buildTarget("//foo:foo"));
    }
    events.assertContainsError("compilation of module 'foo/aspect.bzl' failed");
  }

  @Test
  public void aspectExecutionFailure_consistentWithNonSkymeld(
      @TestParameter boolean keepGoing, @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--keep_going=" + keepGoing);
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeMyRuleBzl();
    writeExecutionFailureAspectBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");

    addOptions("--aspects=//foo:aspect.bzl%execution_err_aspect", "--output_groups=files");
    assertThrows(BuildFailedException.class, () -> buildTarget("//foo:foo"));
    events.assertContainsError(
        "Action foo/aspect_output failed: (Exit 1): bash failed: error executing Action command");
  }

  @Test
  public void targetExecutionFailure_consistentWithNonSkymeld(
      @TestParameter boolean keepGoing, @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--keep_going=" + keepGoing);
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "execution_failure",
            srcs = ["missing"],
        )

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");

    assertThrows(
        BuildFailedException.class, () -> buildTarget("//foo:foo", "//foo:execution_failure"));
    if (keepGoing) {
      assertSingleOutputBuilt("//foo:foo");
    }
    events.assertContainsError(
        "Action foo/execution_failure.out failed: missing input file '//foo:missing'");
  }

  @Test
  public void targetAnalysisFailure_consistentWithNonSkymeld(
      @TestParameter boolean keepGoing, @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--keep_going=" + keepGoing);
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "analysis_failure",
            srcs = ["foo.in"],
            deps = [":missing"],
        )

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");

    if (keepGoing) {
      assertThrows(
          BuildFailedException.class, () -> buildTarget("//foo:foo", "//foo:analysis_failure"));
      assertSingleOutputBuilt("//foo:foo");
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () -> buildTarget("//foo:foo", "//foo:analysis_failure"));
    }
    events.assertContainsError("rule '//foo:missing' does not exist");
  }

  // Regression test for https://github.com/bazelbuild/bazel/issues/20443
  @Test
  public void testKeepGoingWarningContainsDetails() throws Exception {
    addOptions("--keep_going");
    write(
        "foo/BUILD",
        """
        constraint_setting(name = "incompatible_setting")

        constraint_value(
            name = "incompatible",
            constraint_setting = ":incompatible_setting",
            visibility = ["//visibility:public"],
        )

        cc_library(
            name = "foo",
            srcs = ["foo.cc"],
            target_compatible_with = ["//foo:incompatible"],
        )
        """);
    assertThrows(BuildFailedException.class, () -> buildTarget("//foo:foo"));
    events.assertContainsWarning(
        "errors encountered while analyzing target '//foo:foo', it will not be built.");
    // The details.
    events.assertContainsWarning("Dependency chain:");
  }

  @Test
  public void analysisAndExecutionFailure_keepGoing_bothReported() throws Exception {
    addOptions("--keep_going");
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "execution_failure",
            srcs = ["missing"],
        )

        my_rule(
            name = "analysis_failure",
            srcs = ["foo.in"],
            deps = [":missing"],
        )
        """);
    write("foo/foo.in");

    assertThrows(
        BuildFailedException.class,
        () -> buildTarget("//foo:analysis_failure", "//foo:execution_failure"));
    events.assertContainsError(
        "Action foo/execution_failure.out failed: missing input file '//foo:missing'");
    events.assertContainsError("rule '//foo:missing' does not exist");

    assertThat(getLabelsOfAnalyzedTargets()).contains("//foo:execution_failure");
    assertThat(getLabelsOfBuiltTargets()).isEmpty();
  }

  @Test
  public void symlinkPlantedLocalAction_success() throws Exception {
    addOptions("--spawn_strategy=standalone");
    write(
        "foo/BUILD",
        """
        genrule(
            name = "foo",
            srcs = ["foo.in"],
            outs = ["foo.out"],
            cmd = "cp $< $@",
        )
        """);
    write("foo/foo.in");

    BuildResult result = buildTarget("//foo:foo");

    assertThat(result.getSuccess()).isTrue();
    assertSingleOutputBuilt("//foo:foo");
  }

  @Test
  public void symlinksPlanted() throws Exception {
    Path execroot = directories.getExecRoot(directories.getWorkspace().getBaseName());
    writeMyRuleBzl();
    Path fooDir =
        write(
                "foo/BUILD",
                """
                load("//foo:my_rule.bzl", "my_rule")

                my_rule(
                    name = "foo",
                    srcs = ["foo.in"],
                )
                """)
            .getParentDirectory();
    write("foo/foo.in");
    Path unusedDir = write("unused/dummy").getParentDirectory();

    // Before the build: no symlink.
    assertThat(execroot.getRelative("foo").exists()).isFalse();

    buildTarget("//foo:foo");

    // After the build: symlinks to the source directory, even unused packages.
    assertThat(execroot.getRelative("foo").resolveSymbolicLinks()).isEqualTo(fooDir);
    assertThat(execroot.getRelative("unused").resolveSymbolicLinks()).isEqualTo(unusedDir);
  }

  @Test
  public void symlinksPlantedExceptProductNamePrefixAndIgnoredPaths() throws Exception {
    String productName = getRuntime().getProductName();
    Path execroot = directories.getExecRoot(directories.getWorkspace().getBaseName());
    writeMyRuleBzl();
    Path fooDir =
        write(
                "foo/BUILD",
                """
                load("//foo:my_rule.bzl", "my_rule")

                my_rule(
                    name = "foo",
                    srcs = ["foo.in"],
                )
                """)
            .getParentDirectory();
    write("foo/foo.in");
    Path unusedDir = write("unused/dummy").getParentDirectory();
    write(".bazelignore", "ignored");
    write("ignored/dummy");
    write(productName + "-dir/dummy");

    // Before the build: no symlink.
    assertThat(execroot.getRelative("foo").exists()).isFalse();

    buildTarget("//foo:foo");

    // After the build: symlinks to the source directory, even unused packages, except for those
    // in the .bazelignore file and those with the bazel- prefix.
    assertThat(execroot.getRelative("foo").resolveSymbolicLinks()).isEqualTo(fooDir);
    assertThat(execroot.getRelative("unused").resolveSymbolicLinks()).isEqualTo(unusedDir);
    assertThat(execroot.getRelative("ignored").exists()).isFalse();
    assertThat(execroot.getRelative(productName + "-dir").exists()).isFalse();
  }

  @Test
  public void symlinksReplantedEachBuild() throws Exception {
    Path execroot = directories.getExecRoot(directories.getWorkspace().getBaseName());
    writeMyRuleBzl();
    Path fooDir =
        write(
                "foo/BUILD",
                """
                load("//foo:my_rule.bzl", "my_rule")

                my_rule(
                    name = "foo",
                    srcs = ["foo.in"],
                )
                """)
            .getParentDirectory();
    write("foo/foo.in");
    Path unusedDir = write("unused/dummy").getParentDirectory();

    buildTarget("//foo:foo");

    // After the 1st build: symlinks to the source directory, even unused packages.
    assertThat(execroot.getRelative("foo").resolveSymbolicLinks()).isEqualTo(fooDir);
    assertThat(execroot.getRelative("unused").resolveSymbolicLinks()).isEqualTo(unusedDir);

    unusedDir.deleteTree();

    buildTarget("//foo:foo");

    // After the 2nd build: symlink to unusedDir is gone, since the package itself was deleted.
    assertThat(execroot.getRelative("foo").resolveSymbolicLinks()).isEqualTo(fooDir);
    assertThat(execroot.getRelative("unused").exists()).isFalse();
  }

  @Test
  public void targetAnalysisFailure_skymeld_correctAnalysisEvents(@TestParameter boolean keepGoing)
      throws Exception {
    addOptions("--keep_going=" + keepGoing);
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "analysis_failure",
            srcs = ["foo.in"],
            deps = [":missing"],
        )

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");

    if (keepGoing) {
      assertThrows(
          BuildFailedException.class, () -> buildTarget("//foo:foo", "//foo:analysis_failure"));

      assertThat(eventsSubscriber.getTopLevelEntityAnalysisConcludedEvents()).hasSize(2);
      assertSingleAnalysisPhaseCompleteEventWithLabels("//foo:foo");
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () -> buildTarget("//foo:foo", "//foo:analysis_failure"));
      assertThat(eventsSubscriber.getAnalysisPhaseCompleteEvents()).isEmpty();
    }
  }

  @Test
  public void aspectAnalysisFailure_skymeld_correctAnalysisEvents(@TestParameter boolean keepGoing)
      throws Exception {
    addOptions("--keep_going=" + keepGoing);
    writeMyRuleBzl();
    writeAnalysisFailureAspectBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");

    addOptions("--aspects=//foo:aspect.bzl%analysis_err_aspect", "--output_groups=files");
    if (keepGoing) {
      assertThrows(BuildFailedException.class, () -> buildTarget("//foo:foo"));
      assertThat(eventsSubscriber.getTopLevelEntityAnalysisConcludedEvents()).hasSize(2);
      assertSingleAnalysisPhaseCompleteEventWithLabels("//foo:foo");
    } else {
      assertThrows(ViewCreationFailedException.class, () -> buildTarget("//foo:foo"));
      assertThat(eventsSubscriber.getAnalysisPhaseCompleteEvents()).isEmpty();
    }
    events.assertContainsError("compilation of module 'foo/aspect.bzl' failed");
  }

  @Test
  public void targetSkipped_skymeld_correctAnalysisEvents(@TestParameter boolean keepGoing)
      throws Exception {
    writeEnvironmentRules();
    addOptions("--keep_going=" + keepGoing);
    write(
        "foo/BUILD",
        """
        sh_library(
            name = "good_bar",
            srcs = ["bar.sh"],
            compatible_with = ["//buildenv:one"],
        )

        sh_library(
            name = "bad_bar",
            srcs = ["bar.sh"],
            compatible_with = ["//buildenv:two"],
        )
        """);
    write("foo/bar.sh");
    addOptions("--target_environment=//buildenv:one");
    if (keepGoing) {
      assertThrows(
          BuildFailedException.class, () -> buildTarget("//foo:good_bar", "//foo:bad_bar"));

      assertThat(eventsSubscriber.getTopLevelEntityAnalysisConcludedEvents()).hasSize(2);
      assertThat(eventsSubscriber.getAnalysisPhaseCompleteEvents()).hasSize(1);
      AnalysisPhaseCompleteEvent analysisPhaseCompleteEvent =
          Iterables.getOnlyElement(eventsSubscriber.getAnalysisPhaseCompleteEvents());
      assertThat(analysisPhaseCompleteEvent.getTimeInMs()).isGreaterThan(0);
      assertThat(getLabelsOfAnalyzedTargets(analysisPhaseCompleteEvent))
          .containsExactly("//foo:good_bar", "//foo:bad_bar");
    } else {
      assertThrows(
          ViewCreationFailedException.class, () -> buildTarget("//foo:good_bar", "//foo:bad_bar"));
      assertThat(eventsSubscriber.getAnalysisPhaseCompleteEvents()).isEmpty();
    }
  }

  @Test
  public void targetWithNoConfiguration_success() throws Exception {
    write("foo/BUILD", "exports_files(['bar.txt'])");
    write("foo/bar.txt", "This is just a test file to pretend to build.");
    BuildResult result = buildTarget("//foo:bar.txt");

    assertThat(result.getSuccess()).isTrue();
  }

  @Test
  public void explain_ignoreSkymeldWithWarning() throws Exception {
    addOptions("--explain=/dev/null");
    write("foo/BUILD", "genrule(name = 'foo', outs = ['foo.out'], cmd = 'touch $@')");
    RecordingOutErr recordedOutput = divertInfoLogToOutErr();
    BuildResult buildResult = buildTarget("//foo");

    assertThat(buildResult.getSuccess()).isTrue();

    assertThat(recordedOutput.errAsLatin1())
        .containsMatch(
            "--experimental_merged_skyframe_analysis_execution is incompatible with --explain"
                + " and will be ignored.");
  }

  @Test
  public void multiplePackagePath_ignoreSkymeldWithWarning() throws Exception {
    write("foo/BUILD", "genrule(name = 'foo', outs = ['foo.out'], cmd = 'touch $@')");
    write("otherroot/bar/BUILD", "genrule(name = 'bar', outs = ['bar.out'], cmd = 'touch $@')");
    addOptions("--package_path=%workspace%:otherroot");

    RecordingOutErr recordedOutput = divertInfoLogToOutErr();
    BuildResult buildResult = buildTarget("//foo", "//bar");

    assertThat(buildResult.getSuccess()).isTrue();

    assertThat(recordedOutput.errAsLatin1())
        .containsMatch(
            "--experimental_merged_skyframe_analysis_execution is incompatible with multiple"
                + " --package_path.*and its value will be ignored.");
  }

  // Regression test for b/245919888.
  @Test
  public void outputFileRemoved_regeneratedWithIncrementalBuild() throws Exception {
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");

    BuildResult result = buildTarget("//foo:foo");

    assertThat(result.getSuccess()).isTrue();
    Path fooOut = assertSingleOutputBuilt("//foo:foo");

    fooOut.delete();

    BuildResult incrementalBuild = buildTarget("//foo:foo");

    assertThat(incrementalBuild.getSuccess()).isTrue();
    assertSingleOutputBuilt("//foo:foo");
  }

  // Regression test for b/245922900.
  @Test
  public void executionFailure_discardAnalysisCache_doesNotCrash() throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution", "--discard_analysis_cache");
    writeExecutionFailureAspectBzl();
    write(
        "foo/BUILD",
        """
        cc_library(
            name = "foo",
            srcs = ["foo.cc"],
            deps = [":bar"],
        )

        cc_library(
            name = "bar",
            srcs = ["bar.cc"],
        )
        """);
    write("foo/foo.cc");
    write("foo/bar.cc");
    addOptions("--aspects=//foo:aspect.bzl%execution_err_aspect", "--output_groups=files");

    // Verify that the build did not crash.
    assertThrows(BuildFailedException.class, () -> buildTarget("//foo:foo"));
    events.assertContainsError(
        "Action foo/aspect_output failed: (Exit 1): bash failed: error executing Action command");
  }

  @Test
  public void targetCycle_doesNotCrash() throws Exception {
    write(
        "a/BUILD",
        """
        alias(
            name = "a",
            actual = ":b",
        )

        alias(
            name = "b",
            actual = ":c",
        )

        alias(
            name = "c",
            actual = ":a",
        )

        filegroup(
            name = "d",
            srcs = [":c"],
        )
        """);
    assertThrows(ViewCreationFailedException.class, () -> buildTarget("//a:d"));
    events.assertContainsError("cycle in dependency graph");
  }

  @Test
  public void analysisOverlapPercentageSanityCheck_success() throws Exception {
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "bar",
            srcs = ["bar.in"],
        )

        my_rule(
            name = "foo",
            srcs = ["foo.in"],
        )
        """);
    write("foo/foo.in");
    write("foo/bar.in");

    addOptions("--experimental_skymeld_analysis_overlap_percentage=5");
    BuildResult result = buildTarget("//foo:foo", "//foo:bar");

    assertThat(result.getSuccess()).isTrue();
    assertSingleOutputBuilt("//foo:foo");
    assertSingleOutputBuilt("//foo:bar");

    assertThat(getLabelsOfAnalyzedTargets()).containsExactly("//foo:foo", "//foo:bar");
    assertThat(getLabelsOfBuiltTargets()).containsExactly("//foo:foo", "//foo:bar");

    assertThat(eventsSubscriber.getTopLevelEntityAnalysisConcludedEvents()).hasSize(2);
    assertSingleAnalysisPhaseCompleteEventWithLabels("//foo:foo", "//foo:bar");
  }

  // Regression test for b/277783687.
  @Test
  public void targetAnalysisFailureNullBuild_correctErrorsPropagated(
      @TestParameter boolean keepGoing) throws Exception {
    addOptions("--keep_going=" + keepGoing);
    writeMyRuleBzl();
    write(
        "foo/BUILD",
        """
        load("//foo:my_rule.bzl", "my_rule")

        my_rule(
            name = "analysis_failure",
            srcs = ["foo.in"],
            deps = [":missing"],
        )
        """);
    write("foo/foo.in");

    if (keepGoing) {
      assertThrows(BuildFailedException.class, () -> buildTarget("//foo:analysis_failure"));

    } else {
      assertThrows(ViewCreationFailedException.class, () -> buildTarget("//foo:analysis_failure"));
    }
    events.assertContainsError(
        "in deps attribute of my_rule rule //foo:analysis_failure: rule '//foo:missing' does not"
            + " exist");

    // Null build
    if (keepGoing) {
      assertThrows(BuildFailedException.class, () -> buildTarget("//foo:analysis_failure"));

    } else {
      assertThrows(ViewCreationFailedException.class, () -> buildTarget("//foo:analysis_failure"));
    }
    events.assertContainsError(
        "in deps attribute of my_rule rule //foo:analysis_failure: rule '//foo:missing' does not"
            + " exist");
  }

  // Regression test for b/300391729.
  @Test
  public void executionFailure_keepGoing_doesNotSpamWarnings() throws Exception {
    addOptions("--keep_going");
    writeExecutionFailureAspectBzl();
    write(
        "foo/BUILD",
        """
        cc_library(
            name = "foo",
            srcs = ["foo.cc"],
            deps = [":bar"],
        )

        cc_library(
            name = "bar",
            srcs = ["bar.cc"],
        )
        """);
    write("foo/foo.cc");
    write("foo/bar.cc");
    addOptions("--aspects=//foo:aspect.bzl%execution_err_aspect", "--output_groups=files");

    assertThrows(BuildFailedException.class, () -> buildTarget("//foo/..."));
    // No warnings.
    events.assertNoWarnings();
  }

  // Regression test for b/301289073.
  @Test
  public void conflictCheck_doesNotTimeout() throws Exception {
    addOptions("--keep_going");
    write(
        "foo/BUILD",
        """
        BASE_SIZE = 500

        TOP_SIZE = 100

        genrule(
            name = "base_0",
            outs = ["base_0.txt"],
            cmd = "touch $@",
        )

        [genrule(
            name = "base_%s" % x,
            srcs = ["base_%s.txt" % (x - 1)],
            outs = ["base_%s.txt" % x],
            cmd = "touch $@",
        ) for x in range(1, BASE_SIZE)]

        [genrule(
            name = "level_%s" % y,
            srcs = ["base_%s.txt" % (
                x,
            ) for x in range(0, BASE_SIZE)],
            outs = ["level_%s.txt" % y],
            cmd = "touch $@",
        ) for y in range(0, TOP_SIZE)]

        genrule(
            name = "conflict",
            outs = ["conflict"],
            cmd = "touch $@",
        )
        """);
    write(
        "foo/conflict/BUILD",
        """
        genrule(
            name = "conflict",
            outs = ["conflict"],
            cmd = "touch $@",
        )
        """);

    // Building a set of targets with recursive dependencies that would trivially finish in time
    // with memoization and time out without.
    assertThrows(BuildFailedException.class, () -> buildTarget("//foo/..."));
    events.assertContainsError("is a prefix of the other");
  }

  private void assertSingleAnalysisPhaseCompleteEventWithLabels(String... labels) {
    assertThat(eventsSubscriber.getAnalysisPhaseCompleteEvents()).hasSize(1);
    AnalysisPhaseCompleteEvent analysisPhaseCompleteEvent =
        Iterables.getOnlyElement(eventsSubscriber.getAnalysisPhaseCompleteEvents());
    assertThat(analysisPhaseCompleteEvent.getTimeInMs()).isGreaterThan(0);
    assertThat(getLabelsOfAnalyzedTargets(analysisPhaseCompleteEvent))
        .containsExactlyElementsIn(labels);
  }

  private static ImmutableSet<String> getLabelsOfAnalyzedTargets(AnalysisPhaseCompleteEvent event) {
    return event.getTopLevelTargets().stream()
        .map(x -> x.getOriginalLabel().getCanonicalForm())
        .collect(toImmutableSet());
  }

  private RecordingOutErr divertInfoLogToOutErr() {
    // Divert output into recorder:
    RecordingOutErr recordedOutput = new RecordingOutErr();
    this.outErr = recordedOutput;
    divertLogging(
        Level.INFO, outErr, ImmutableList.of(Logger.getLogger(SkymeldModule.class.getName())));
    return recordedOutput;
  }

  private static final class EventsSubscriber {

    private final List<TopLevelEntityAnalysisConcludedEvent> topLevelEntityAnalysisConcludedEvents =
        Collections.synchronizedList(new ArrayList<>());

    private final List<AnalysisPhaseCompleteEvent> analysisPhaseCompleteEvents =
        Collections.synchronizedList(new ArrayList<>());

    EventsSubscriber() {}

    @Subscribe
    void recordTopLevelEntityAnalysisConcludedEvent(TopLevelEntityAnalysisConcludedEvent event) {
      topLevelEntityAnalysisConcludedEvents.add(event);
    }

    @Subscribe
    void recordAnalysisPhaseCompleteEvent(AnalysisPhaseCompleteEvent event) {
      analysisPhaseCompleteEvents.add(event);
    }

    public List<TopLevelEntityAnalysisConcludedEvent> getTopLevelEntityAnalysisConcludedEvents() {
      return topLevelEntityAnalysisConcludedEvents;
    }

    public List<AnalysisPhaseCompleteEvent> getAnalysisPhaseCompleteEvents() {
      return analysisPhaseCompleteEvents;
    }
  }
}
