// 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.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
  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).containsAnyOf("//x:y", "//x:fail_analysis");
    }
  }

  // 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 {
    // TODO(b/245923465) Limitation with Skymeld.
    addOptions("--noexperimental_merged_skyframe_analysis_execution");
    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 skymeld and noskymeld modes in case of --keep_going.
  // noskymeld: bazel would stop at the end of the analysis phase and build nothing.
  // skymeld: we either finish building one of the 2 conflicting artifacts, or none at all.
  //
  // The overall build would still fail in both cases.
  @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 these 2 conflicting artifacts can't both exist.
      assertThat(outputXYY.isFile() && outputXY.isFile()).isFalse();
    } 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");
  }

  @Test
  public void conflict_noTrackIncrementalState_detected(
      @TestParameter boolean mergedAnalysisExecution) throws Exception {
    addOptions("--experimental_merged_skyframe_analysis_execution=" + mergedAnalysisExecution);
    addOptions("--notrack_incremental_state");
    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"));
    events.assertContainsError(
        "file 'foo/conflict_output' is generated by these conflicting actions:");
  }

  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());
  }
}
