// Copyright 2020 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.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertNoEvents;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;

import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.eventbus.Subscribe;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.BuildFailedException;
import com.google.devtools.build.lib.actions.MutableActionGraph;
import com.google.devtools.build.lib.analysis.AnalysisFailureEvent;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.TargetCompletedId;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
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.server.FailureDetails;
import com.google.devtools.build.lib.server.FailureDetails.Analysis.Code;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.Path;
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.List;
import java.util.regex.Pattern;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests for action conflicts. */
@RunWith(TestParameterInjector.class)
public class OutputArtifactConflictTest extends BuildIntegrationTestCase {

  static class AnalysisFailureEventListener extends BlazeModule {

    private final List<TargetCompletedId> eventIds = new ArrayList<>();
    private final List<String> failedTargetNames = new ArrayList<>();

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

    @Subscribe
    public void onAnalysisFailure(AnalysisFailureEvent event) {
      eventIds.add(event.getEventId().getTargetCompleted());
      failedTargetNames.add(event.getFailedTarget().getLabel().toString());
    }
  }

  private final AnalysisFailureEventListener eventListener = new AnalysisFailureEventListener();

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

  private void writeConflictBzl() throws IOException {
    write(
        "foo/conflict.bzl",
        "def _conflict_impl(ctx):",
        "  inputs = depset(",
        "    ctx.files.srcs, transitive = [dep[DefaultInfo].files for dep in ctx.attr.deps])",
        "  conflict_output = ctx.actions.declare_file('conflict_output')",
        "  other = ctx.actions.declare_file('other' + ctx.attr.name)",
        "  ctx.actions.run_shell(",
        "    inputs = inputs,",
        "    outputs = [conflict_output, other],",
        "    command = 'touch %s %s' % (conflict_output.path, other.path)",
        "  )",
        "  return [DefaultInfo(files = depset([conflict_output, other]))]",
        "",
        "my_rule = rule(",
        "  implementation=_conflict_impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = True),",
        "    'deps': attr.label_list(providers = [DefaultInfo]),",
        "  }",
        ")");
  }

  /**
   * Builds the provided targets and asserts expected exceptions.
   *
   * @return the exit code extracted from the failure detail.
   */
  private Code assertThrowsExceptionWhenBuildingTargets(boolean keepGoing, String... targets) {
    FailureDetail failureDetail =
        keepGoing
            ? assertThrows(BuildFailedException.class, () -> buildTarget(targets))
                .getDetailedExitCode()
                .getFailureDetail()
            : assertThrows(ViewCreationFailedException.class, () -> buildTarget(targets))
                .getFailureDetail();
    return Preconditions.checkNotNull(failureDetail).getAnalysis().getCode();
  }

  @Test
  public void testArtifactPrefix(
      @TestParameter boolean keepGoing,
      @TestParameter boolean modifyBuildFile,
      @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    write("x/y/BUILD", "genrule(name = 'y', outs = ['whatever'], cmd = 'touch $@')");
    if (modifyBuildFile) {
      write("x/BUILD", "genrule(name = 'y', outs = ['not_y'], cmd = 'touch $@')");
      buildTarget("//x:y", "//x/y:y");
      write("x/BUILD", "genrule(name = 'y', outs = ['y'], cmd = 'touch $@')");
    } else {
      write("x/BUILD", "genrule(name = 'y', outs = ['y'], cmd = 'touch $@')");
      buildTarget("//x/y:y");
    }

    assertNoEvents(events.errors());
    assertThat(eventListener.failedTargetNames).isEmpty();

    addOptions("--keep_going=" + keepGoing);
    Code errorCode = assertThrowsExceptionWhenBuildingTargets(keepGoing, "//x/y:y", "//x:y");
    assertThat(errorCode)
        .isEqualTo(keepGoing ? Code.NOT_ALL_TARGETS_ANALYZED : Code.ARTIFACT_PREFIX_CONFLICT);

    if (keepGoing) {
      assertThat(eventListener.failedTargetNames).containsExactly("//x:y", "//x/y:y");
    } else {
      assertThat(eventListener.failedTargetNames).containsAnyOf("//x:y", "//x/y:y");
    }

    events.assertContainsError("One of the output paths '" + TestConstants.PRODUCT_NAME + "-out/");
    events.assertContainsError("/bin/x/y/whatever' (belonging to //x/y:y)");
    events.assertContainsError("/bin/x/y' (belonging to //x:y)");
    events.assertContainsError("is a prefix of the other");
    assertThat(events.errors()).hasSize(1);
  }

  @Test
  public void testAspectArtifactSharesPrefixWithTargetArtifact(
      @TestParameter boolean keepGoing,
      @TestParameter boolean modifyBuildFile,
      @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    if (modifyBuildFile) {
      write("x/BUILD", "genrule(name = 'y', outs = ['y.out'], cmd = 'touch $@')");
    } else {
      write("x/BUILD", "genrule(name = 'y', outs = ['y.bad'], cmd = 'touch $@')");
    }
    write("x/y/BUILD", "genrule(name = 'y', outs = ['whatever'], cmd = 'touch $@')");
    write(
        "x/aspect.bzl",
        "def _aspect_impl(target, ctx):",
        "    if not getattr(ctx.rule.attr, 'outs', None):",
        "        return struct(output_groups = {})",
        "    conflict_outputs = list()",
        "    for out in ctx.rule.attr.outs:",
        "        if out.name[1:] == '.bad':",
        "            aspect_out = ctx.actions.declare_file(out.name[:1])",
        "            conflict_outputs.append(aspect_out)",
        "            cmd = 'echo %s > %s' % (out.name, aspect_out.path)",
        "            ctx.actions.run_shell(",
        "                outputs = [aspect_out],",
        "                command = cmd,",
        "            )",
        "    return [OutputGroupInfo(",
        "        files = depset(conflict_outputs)",
        "    )]",
        "",
        "my_aspect = aspect(implementation = _aspect_impl)");

    if (modifyBuildFile) {
      buildTarget("//x/y", "//x:y");
      write("x/BUILD", "genrule(name = 'y', outs = ['y.bad'], cmd = 'touch $@')");
    } else {
      buildTarget("//x/y");
    }
    assertNoEvents(events.errors());
    assertThat(eventListener.failedTargetNames).isEmpty();

    addOptions("--aspects=//x:aspect.bzl%my_aspect", "--output_groups=files");
    addOptions("--keep_going=" + keepGoing);
    Code errorCode = assertThrowsExceptionWhenBuildingTargets(keepGoing, "//x/y", "//x:y");
    assertThat(errorCode)
        .isEqualTo(keepGoing ? Code.NOT_ALL_TARGETS_ANALYZED : Code.ARTIFACT_PREFIX_CONFLICT);
    events.assertContainsError("One of the output paths '" + TestConstants.PRODUCT_NAME + "-out/");
    events.assertContainsError("/bin/x/y/whatever' (belonging to //x/y:y)");
    events.assertContainsError("/bin/x/y' (belonging to //x:y)");
    events.assertContainsError("is a prefix of the other");

    // As we have --output_groups=file, the CTs won't actually be built. Only the
    // AnalysisFailureEvent from Aspect(//x:y) is expected even though there are 2 conflicting
    // actions.
    assertThat(events.errors()).hasSize(1);
    assertThat(eventListener.failedTargetNames).containsExactly("//x:y");
    assertThat(eventListener.eventIds.get(0).getAspect()).isEqualTo("//x:aspect.bzl%my_aspect");
  }

  @Test
  public void testAspectArtifactPrefix(
      @TestParameter boolean keepGoing,
      @TestParameter boolean modifyBuildFile,
      @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    if (modifyBuildFile) {
      write(
          "x/BUILD",
          "genrule(name = 'y', outs = ['y.out'], cmd = 'touch $@')",
          "genrule(name = 'ydir', outs = ['y.dir'], cmd = 'touch $@')");
    } else {
      write(
          "x/BUILD",
          "genrule(name = 'y', outs = ['y.bad'], cmd = 'touch $@')",
          "genrule(name = 'ydir', outs = ['y.dir'], cmd = 'touch $@')");
    }
    write(
        "x/aspect.bzl",
        "def _aspect_impl(target, ctx):",
        "    if not getattr(ctx.rule.attr, 'outs', None):",
        "        return struct(output_groups = {})",
        "    conflict_outputs = list()",
        "    for out in ctx.rule.attr.outs:",
        "        if out.name[1:] == '.bad':",
        "            aspect_out = ctx.actions.declare_file(out.name[:1])",
        "            conflict_outputs.append(aspect_out)",
        "            cmd = 'echo %s > %s' % (out.name, aspect_out.path)",
        "            ctx.actions.run_shell(",
        "                outputs = [aspect_out],",
        "                command = cmd,",
        "            )",
        "        elif out.name[1:] == '.dir':",
        "            aspect_out = ctx.actions.declare_file(out.name[:1] + '/' + out.name)",
        "            conflict_outputs.append(aspect_out)",
        "            out_dir = aspect_out.path[:len(aspect_out.path) - len(out.name) + 1]",
        "            cmd = 'mkdir %s && echo %s > %s' % (out_dir, out.name, aspect_out.path)",
        "            ctx.actions.run_shell(",
        "                outputs = [aspect_out],",
        "                command = cmd,",
        "            )",
        "    return [OutputGroupInfo(",
        "        files = depset(conflict_outputs)",
        "    )]",
        "",
        "my_aspect = aspect(implementation = _aspect_impl)");

    if (modifyBuildFile) {
      buildTarget("//x:y", "//x:ydir");
      write(
          "x/BUILD",
          "genrule(name = 'y', outs = ['y.bad'], cmd = 'touch $@')",
          "genrule(name = 'ydir', outs = ['y.dir'], cmd = 'touch $@')");
    } else {
      buildTarget("//x:y");
    }
    assertNoEvents(events.errors());
    assertThat(eventListener.failedTargetNames).isEmpty();

    addOptions("--aspects=//x:aspect.bzl%my_aspect", "--output_groups=files");
    addOptions("--keep_going=" + keepGoing);
    Code errorCode = assertThrowsExceptionWhenBuildingTargets(keepGoing, "//x:ydir", "//x:y");
    assertThat(errorCode)
        .isEqualTo(keepGoing ? Code.NOT_ALL_TARGETS_ANALYZED : Code.ARTIFACT_PREFIX_CONFLICT);
    events.assertContainsError("One of the output paths '" + TestConstants.PRODUCT_NAME + "-out/");
    events.assertContainsError("bin/x/y' (belonging to //x:y)");
    events.assertContainsError("bin/x/y/y.dir' (belonging to //x:ydir)");
    events.assertContainsError("is a prefix of the other");
    assertThat(events.errors()).hasSize(1);
    assertThat(eventListener.eventIds.get(0).getAspect()).isEqualTo("//x:aspect.bzl%my_aspect");
    if (keepGoing) {
      assertThat(eventListener.failedTargetNames).containsExactly("//x:y", "//x:ydir");
    } else {
      assertThat(eventListener.failedTargetNames).containsAnyOf("//x:y", "//x:ydir");
    }
  }

  @Test
  public void testInvalidatedConflict(@TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeConflictBzl();
    write(
        "foo/BUILD",
        "load('//foo:conflict.bzl', 'my_rule')",
        "my_rule(name = 'first')",
        "my_rule(name = 'second')");

    assertThrows(
        ViewCreationFailedException.class, () -> buildTarget("//foo:first", "//foo:second"));
    assertThat(eventListener.failedTargetNames).containsAnyOf("//foo:first", "//foo:second");

    write("foo/BUILD", "load('//foo:conflict.bzl', 'my_rule')", "my_rule(name = 'first')");
    events.clear();
    buildTarget("//foo:first");

    events.assertNoWarningsOrErrors();
  }

  @Test
  public void testNewTargetConflict(
      @TestParameter boolean keepGoing, @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    addOptions("--keep_going=" + keepGoing);
    writeConflictBzl();
    write(
        "foo/BUILD",
        "load('//foo:conflict.bzl', 'my_rule')",
        "my_rule(name = 'first')",
        "my_rule(name = 'second')");
    buildTarget("//foo:first");
    events.assertNoWarningsOrErrors();

    Code errorCode =
        assertThrowsExceptionWhenBuildingTargets(keepGoing, "//foo:first", "//foo:second");
    assertThat(errorCode)
        .isEqualTo(keepGoing ? Code.NOT_ALL_TARGETS_ANALYZED : Code.ACTION_CONFLICT);
    events.assertContainsError(
        "file 'foo/conflict_output' is generated by these conflicting actions:");
    assertThat(eventListener.failedTargetNames).hasSize(1);
    assertThat(eventListener.failedTargetNames).containsAnyOf("//foo:first", "//foo:second");
  }

  @Test
  public void testTwoOverlappingBuildsHasNoConflict(
      @TestParameter boolean keepGoing, @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    addOptions("--keep_going=" + keepGoing);
    writeConflictBzl();
    write(
        "foo/BUILD",
        "load('//foo:conflict.bzl', 'my_rule')",
        "my_rule(name = 'first')",
        "my_rule(name = 'second')");

    // Verify that together they fail, even though no new targets have been analyzed
    Code errorCode =
        assertThrowsExceptionWhenBuildingTargets(keepGoing, "//foo:first", "//foo:second");
    assertThat(errorCode)
        .isEqualTo(keepGoing ? Code.NOT_ALL_TARGETS_ANALYZED : Code.ACTION_CONFLICT);
    events.clear();

    // Verify that they still don't fail individually, so no state remains
    buildTarget("//foo:first");
    events.assertNoWarningsOrErrors();
    buildTarget("//foo:second");
    events.assertNoWarningsOrErrors();
  }

  @Test
  public void testFailingTargetsDoNotCauseActionConflicts(
      @TestParameter boolean mergedAnalysisExecution) throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    write(
        "x/bad_rule.bzl",
        "def _impl(ctx):",
        "  return list().this_method_does_not_exist()",
        "bad_rule = rule(_impl, attrs = {'deps': attr.label_list()})");
    write(
        "x/BUILD",
        "load('//x:bad_rule.bzl', 'bad_rule')",
        "cc_binary(name = 'y', srcs = ['y.cc'], malloc = '//base:system_malloc')",
        "bad_rule(name = 'bad', deps = [':y'])");
    write("x/y/y.cc", "");
    write("x/y/BUILD", "cc_library(name = 'y', srcs=['y.cc'])");
    write("x/y.cc", "int main() { return 0; }");

    runtimeWrapper.addOptions("--keep_going");
    try {
      buildTarget("//x:y", "//x/y");
      fail();
    } catch (ViewCreationFailedException e) {
      fail("Unexpected artifact prefix conflict: " + e);
    } catch (BuildFailedException e) {
      // Expected.
    }
  }

  // Regression test for b/184944522.
  @Test
  public void testConflictErrorAndAnalysisError(@TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeConflictBzl();
    write(
        "foo/BUILD",
        "load('//foo:conflict.bzl', 'my_rule')",
        "my_rule(name = 'first')",
        "my_rule(name = 'second')");
    write("x/BUILD", "sh_library(name = 'x', deps = ['//y:y'])");
    write("y/BUILD", "sh_library(name = 'y', visibility = ['//visibility:private'])");
    addOptions("--keep_going");

    assertThrows(
        BuildFailedException.class, () -> buildTarget("//x:x", "//foo:first", "//foo:second"));
    events.assertContainsError(
        "file 'foo/conflict_output' is generated by these conflicting actions:");
    // When targets have conflicting artifacts, one of them "wins" and is successfully built. All
    // of the other targets with conflicting artifacts fail.
    assertThat(eventListener.failedTargetNames).contains("//x:x");
    assertThat(eventListener.failedTargetNames).hasSize(2);
    assertThat(eventListener.failedTargetNames).containsAnyOf("//foo:first", "//foo:second");
  }

  // Verify that an aspect whose analysis is unfinished doesn't fail the conflict reporting process.
  @Test
  @Ignore("b/216490090 - flaky")
  public void testConflictErrorAndUnfinishedAspectAnalysis_mergedAnalysisExecution(
      @TestParameter boolean keepGoing) throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution");
    addOptions("--keep_going=" + keepGoing);
    write(
        "x/aspect.bzl",
        "def _aspect_impl(target, ctx):",
        "    if not getattr(ctx.rule.attr, 'outs', None):",
        "        return struct(output_groups = {})",
        "    conflict_outputs = list()",
        "    for out in ctx.rule.attr.outs:",
        "        if out.name[1:] == '.bad':",
        "            aspect_out = ctx.actions.declare_file(out.name[:1])",
        "            conflict_outputs.append(aspect_out)",
        "            cmd = 'echo %s > %s' % (out.name, aspect_out.path)",
        "            ctx.actions.run_shell(",
        "                outputs = [aspect_out],",
        "                command = cmd,",
        "            )",
        "    return [OutputGroupInfo(",
        "        files = depset(conflict_outputs)",
        "    )]",
        "",
        "my_aspect = aspect(implementation = _aspect_impl)");

    write(
        "x/BUILD",
        "genrule(name = 'y', outs = ['y.bad'], cmd = 'touch $@')",
        "sh_library(name = 'fail_analysis', deps = ['//private:y'])");
    write("x/y/BUILD", "genrule(name = 'y', outs = ['whatever'], cmd = 'touch $@')");
    write("private/BUILD", "sh_library(name = 'y', visibility = ['//visibility:private'])");
    addOptions("--aspects=//x:aspect.bzl%my_aspect", "--output_groups=files");

    Code errorCode =
        assertThrowsExceptionWhenBuildingTargets(
            keepGoing, "//x/y:y", "//x:y", "//x:fail_analysis");
    if (keepGoing) {
      assertThat(errorCode).isEqualTo(Code.NOT_ALL_TARGETS_ANALYZED);
      events.assertContainsError(
          "One of the output paths '" + TestConstants.PRODUCT_NAME + "-out/");
      events.assertContainsError("/bin/x/y/whatever' (belonging to //x/y:y)");
      events.assertContainsError("/bin/x/y' (belonging to //x:y)");
      events.assertContainsError("is a prefix of the other");
      events.assertContainsError("Analysis of target '//x:fail_analysis' failed");

      assertThat(eventListener.failedTargetNames).containsExactly("//x:y", "//x:fail_analysis");
    } else {
      assertThat(errorCode)
          .isAnyOf(Code.ARTIFACT_PREFIX_CONFLICT, Code.CONFIGURED_VALUE_CREATION_FAILED);
      assertThat(
              eventListener.failedTargetNames.contains("//x:y")
                  ^ eventListener.failedTargetNames.contains("//x:fail_analysis"))
          .isTrue();
    }
  }

  // This test is documenting current behavior more than enforcing a contract: it might be ok for
  // Bazel to suppress the error message about an action conflict, since the relevant actions are
  // not run in this build. However, that might cause problems for users who aren't immediately
  // alerted when they introduce an action conflict. We already skip exhaustive checks for action
  // conflicts in the name of performance and that has prompted complaints, so suppressing actual
  // conflicts seems like a bad idea.
  //
  // While this test is written with aspects, any actions that generate conflicting outputs but
  // aren't run would exhibit this behavior.
  @Test
  public void unusedActionsStillConflict() throws Exception {
    write(
        "foo/aspect.bzl",
        "def _aspect1_impl(target, ctx):",
        "  outfile = ctx.actions.declare_file('aspect.out')",
        "  ctx.actions.run_shell(",
        "    outputs = [outfile],",
        "    progress_message = 'Action for aspect 1',",
        "    command = 'echo \"1\" > ' + outfile.path,",
        "  )",
        "  return [OutputGroupInfo(files1 = [outfile])]",
        "",
        "def _aspect2_impl(target, ctx):",
        "  outfile = ctx.actions.declare_file('aspect.out')",
        "  ctx.actions.run_shell(",
        "    outputs = [outfile],",
        "    progress_message = 'Action for aspect 2',",
        "    command = 'echo \"2\" > ' + outfile.path,",
        "  )",
        "  return [OutputGroupInfo(files2 = [outfile])]",
        "",
        "def _rule_impl(ctx):",
        "  outfile = ctx.actions.declare_file('file.out')",
        "  ctx.actions.run_shell(",
        "    outputs = [outfile],",
        "    progress_message = 'Action for target',",
        "    command = 'touch ' + outfile.path,",
        "  )",
        "  return [DefaultInfo(files = depset([outfile]))]",
        "aspect1 = aspect(implementation = _aspect1_impl)",
        "aspect2 = aspect(implementation = _aspect2_impl)",
        "",
        "bad_rule = rule(implementation = _rule_impl, attrs = {'deps' : attr.label_list(aspects ="
            + " [aspect1, aspect2])})");
    write(
        "foo/BUILD",
        "load('//foo:aspect.bzl', 'bad_rule')",
        "sh_library(name = 'dep', srcs = ['dep.sh'])",
        "bad_rule(name = 'foo', deps = [':dep'])");
    addOptions("--keep_going");
    // If Bazel decides to permit this scenario, the build should succeed instead of throwing here.
    BuildFailedException buildFailedException =
        assertThrows(BuildFailedException.class, () -> buildTarget("//foo:foo"));
    assertThat(buildFailedException)
        .hasMessageThat()
        .contains("command succeeded, but not all targets were analyzed");
    // We successfully built the output file despite the supposed failure.
    Iterable<Artifact> artifacts = getArtifacts("//foo:foo");
    assertThat(artifacts).hasSize(1);
    assertThat(Iterables.getOnlyElement(artifacts).getPath().exists()).isTrue();
    assertThat(
            buildFailedException.getDetailedExitCode().getFailureDetail().getAnalysis().getCode())
        .isEqualTo(FailureDetails.Analysis.Code.NOT_ALL_TARGETS_ANALYZED);
    events.assertContainsError("file 'foo/aspect.out' is generated by these conflicting actions:");
    events.assertContainsError(
        Pattern.compile(
            "Aspects: \\[//foo:aspect.bzl%aspect[12]], \\[//foo:aspect.bzl%aspect[12]]"));
  }

  @Test
  public void testMultipleConflictErrors(@TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeConflictBzl();
    write(
        "foo/BUILD",
        "load('//foo:conflict.bzl', 'my_rule')",
        "my_rule(name = 'first')",
        "my_rule(name = 'second')");
    write("x/BUILD", "genrule(name = 'y', outs = ['y'], cmd = 'touch $@')");
    write("x/y/BUILD", "genrule(name = 'y', outs = ['whatever'], cmd = 'touch $@')");

    addOptions("--keep_going");

    assertThrows(
        BuildFailedException.class,
        () -> buildTarget("//x/y", "//x:y", "//foo:first", "//foo:second"));
    events.assertContainsError(
        "file 'foo/conflict_output' is generated by these conflicting actions:");
    events.assertContainsError("One of the output paths '" + TestConstants.PRODUCT_NAME + "-out/");
    events.assertContainsError("bin/x/y' (belonging to //x:y)");
    events.assertContainsError("is a prefix of the other");
    // When targets have conflicting artifacts, one of them "wins" and is successfully built. All
    // of the other targets with conflicting artifacts fail.
    assertThat(eventListener.failedTargetNames).containsAtLeast("//x:y", "//x/y:y");
    assertThat(eventListener.failedTargetNames).hasSize(3);
    assertThat(eventListener.failedTargetNames).containsAnyOf("//foo:first", "//foo:second");
  }

  @Test
  public void repeatedConflictBuild(@TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeConflictBzl();
    write(
        "foo/BUILD",
        "load('//foo:conflict.bzl', 'my_rule')",
        "my_rule(name = 'first')",
        "my_rule(name = 'second')");
    ViewCreationFailedException e =
        assertThrows(
            ViewCreationFailedException.class, () -> buildTarget("//foo:first", "//foo:second"));
    assertThat(e)
        .hasCauseThat()
        .hasCauseThat()
        .isInstanceOf(MutableActionGraph.ActionConflictException.class);
    assertThat(eventListener.failedTargetNames).containsAnyOf("//foo:first", "//foo:second");
    eventListener.failedTargetNames.clear();

    e =
        assertThrows(
            ViewCreationFailedException.class, () -> buildTarget("//foo:first", "//foo:second"));
    assertThat(e)
        .hasCauseThat()
        .hasCauseThat()
        .isInstanceOf(MutableActionGraph.ActionConflictException.class);
    assertThat(eventListener.failedTargetNames).containsAnyOf("//foo:first", "//foo:second");
  }

  @Test
  public void testConflictAfterNullBuild(
      @TestParameter boolean keepGoing, @TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    addOptions("--aspects=//x:aspect.bzl%my_aspect", "--output_groups=files");
    addOptions("--keep_going=" + keepGoing);
    write("x/BUILD", "genrule(name = 'y', outs = ['y.out'], cmd = 'touch $@')");
    write("x/y/BUILD", "genrule(name = 'y', outs = ['whatever'], cmd = 'touch $@')");
    write(
        "x/aspect.bzl",
        "def _aspect_impl(target, ctx):",
        "    if not getattr(ctx.rule.attr, 'outs', None):",
        "        return struct(output_groups = {})",
        "    conflict_outputs = list()",
        "    for out in ctx.rule.attr.outs:",
        "        if out.name[1:] == '.bad':",
        "            aspect_out = ctx.actions.declare_file(out.name[:1])",
        "            conflict_outputs.append(aspect_out)",
        "            cmd = 'echo %s > %s' % (out.name, aspect_out.path)",
        "            ctx.actions.run_shell(",
        "                outputs = [aspect_out],",
        "                command = cmd,",
        "            )",
        "    return [OutputGroupInfo(",
        "        files = depset(conflict_outputs)",
        "    )]",
        "",
        "my_aspect = aspect(implementation = _aspect_impl)");
    // First build: no conflict expected.
    buildTarget("//x/y", "//x:y");
    // Null build
    buildTarget("//x/y", "//x:y");
    assertNoEvents(events.errors());
    assertThat(eventListener.failedTargetNames).isEmpty();

    // Modify BUILD file to introduce a conflict.
    write("x/BUILD", "genrule(name = 'y', outs = ['y.bad'], cmd = 'touch $@')");

    Code errorCode = assertThrowsExceptionWhenBuildingTargets(keepGoing, "//x/y", "//x:y");
    assertThat(errorCode)
        .isEqualTo(keepGoing ? Code.NOT_ALL_TARGETS_ANALYZED : Code.ARTIFACT_PREFIX_CONFLICT);
    events.assertContainsError("One of the output paths '" + TestConstants.PRODUCT_NAME + "-out/");
    events.assertContainsError("/bin/x/y/whatever' (belonging to //x/y:y)");
    events.assertContainsError("/bin/x/y' (belonging to //x:y)");
    events.assertContainsError("is a prefix of the other");
    assertThat(events.errors()).hasSize(1);
    assertThat(eventListener.failedTargetNames).containsExactly("//x:y");
    assertThat(eventListener.eventIds.get(0).getAspect()).isEqualTo("//x:aspect.bzl%my_aspect");
  }

  // There exists a discrepancy between --experimental_merged_skyframe_analysis_execution and
  // otherwise in case of --keep_going. The version with merged phases would still build one of the
  // 2 conflicting targets, while the one without would stop at the end of the analysis phase and
  // build nothing. The overall build would still fail.
  @Test
  public void testTwoConflictingTargets_keepGoing_behaviorDifferences(
      @TestParameter boolean mergedAnalysisExecution) throws Exception {
    addOptions("--keep_going");
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    write("x/BUILD", "genrule(name = 'y', outs = ['y'], cmd = 'touch $@')");
    write("x/y/BUILD", "genrule(name = 'y', outs = ['whatever'], cmd = 'touch $@')");

    Code errorCode =
        assertThrowsExceptionWhenBuildingTargets(/*keepGoing=*/ true, "//x:y", "//x/y:y");
    Path outputXY = Iterables.getOnlyElement(getArtifacts("//x:y")).getPath();
    Path outputXYY = Iterables.getOnlyElement(getArtifacts("//x/y:y")).getPath();

    if (mergedAnalysisExecution) {
      // Verify that one and only one of the output artifacts from these 2 targets were built.
      assertThat((outputXY.isDirectory() && outputXYY.isFile()) ^ outputXY.isFile()).isTrue();
    } else {
      // Verify that none of the output artifacts were built.
      assertThat(outputXY.exists()).isFalse();
      assertThat(outputXYY.exists()).isFalse();
    }
    assertThat(errorCode).isEqualTo(Code.NOT_ALL_TARGETS_ANALYZED);
  }

  @Test
  public void dependencyHasConflict_keepGoing_bothTopLevelTargetsFail(
      @TestParameter boolean mergedAnalysisExecution) throws Exception {
    addOptions("--keep_going");
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    writeConflictBzl();
    write(
        "foo/dummy.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]))]",
        "",
        "dummy = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = True),",
        "    'deps': attr.label_list(providers = [DefaultInfo]),",
        "  }",
        ")");
    write(
        "foo/BUILD",
        "load('//foo:conflict.bzl', 'my_rule')",
        "load('//foo:dummy.bzl', 'dummy')",
        "my_rule(name = 'conflict_first')",
        "my_rule(name = 'conflict_second', deps = [':conflict_first'])",
        "dummy(name = 'top_level_a', deps = [':conflict_second'])",
        "dummy(name = 'top_level_b', deps = [':conflict_second'])");
    assertThrows(
        BuildFailedException.class, () -> buildTarget("//foo:top_level_a", "//foo:top_level_b"));
    events.assertContainsError(
        "file 'foo/conflict_output' is generated by these conflicting actions:");
    assertThat(eventListener.failedTargetNames)
        .containsExactly("//foo:top_level_a", "//foo:top_level_b");
  }

  private void setupStrictConflictChecksTest() throws IOException {
    write(
        "foo/conflict.bzl",
        "def _impl(ctx):",
        "  dir = ctx.actions.declare_directory(ctx.label.name + '.dir')",
        "  file = ctx.actions.declare_file(ctx.label.name + '.dir/file.txt')",
        "  ctx.actions.run_shell(",
        "    outputs = [dir, file],",
        "    command = 'mkdir -p $1 && touch $2',",
        "    arguments = [dir.path, file.path],",
        "  )",
        "  return [DefaultInfo(files = depset([dir, file]))]",
        "",
        "my_rule = rule(implementation = _impl)");
    write("foo/BUILD", "load(':conflict.bzl', 'my_rule')", "my_rule(name = 'bar')");
  }

  @Test
  public void laxFollowedByStrictConflictChecks(@TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    setupStrictConflictChecksTest();
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);

    addOptions("--noincompatible_strict_conflict_checks");
    buildTarget("//foo:bar");
    assertNoEvents(events.errors());

    addOptions("--incompatible_strict_conflict_checks");
    assertThrows(ViewCreationFailedException.class, () -> buildTarget("//foo:bar"));
    events.assertContainsError("One of the output paths");
    events.assertContainsError("is a prefix of the other");
  }

  @Test
  public void strictFollowedByLaxConflictChecks(@TestParameter boolean mergedAnalysisExecution)
      throws Exception {
    setupStrictConflictChecksTest();
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);

    addOptions("--incompatible_strict_conflict_checks");
    assertThrows(ViewCreationFailedException.class, () -> buildTarget("//foo:bar"));
    events.assertContainsError("One of the output paths");
    events.assertContainsError("is a prefix of the other");

    events.clear();
    addOptions("--noincompatible_strict_conflict_checks");
    buildTarget("//foo:bar");
    assertNoEvents(events.errors());
  }
}
