// 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.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.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
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);
  }

  @Test
  public void testArtifactPrefix(
      @TestParameter boolean keepGoing, @TestParameter boolean modifyBuildFile) throws Exception {
    if (modifyBuildFile) {
      write("x/BUILD", "cc_library(name = 'y', srcs = ['y.cc'])");
    } else {
      write("x/BUILD", "cc_binary(name = 'y', srcs = ['y.cc'], malloc = '//base:system_malloc')");
    }
    write("x/y/y.cc", "");
    write("x/y/BUILD", "cc_library(name = 'y', srcs=['y.cc'])");
    write("x/y.cc", "int main() { return 0; }");

    if (modifyBuildFile) {
      buildTarget("//x/y", "//x:y");
      write("x/BUILD", "cc_binary(name = 'y', srcs = ['y.cc'], malloc = '//base:system_malloc')");
    } else {
      buildTarget("//x/y");
    }
    assertNoEvents(events.errors());
    assertThat(eventListener.failedTargetNames).isEmpty();

    if (keepGoing) {
      runtimeWrapper.addOptions("--keep_going");
    }
    try {
      // Skyframe full should throw an error here even if we just build //x:y. However, because our
      // testing infrastructure sets up lots of symlinks, Skyframe invalidates the //x/y action, and
      // so would not find a conflict here without re-evaluating //x/y. Note that in a real client,
      // requesting the //x/y target would not be necessary to throw an exception.
      buildTarget("//x:y", "//x/y");
      fail();
    } catch (BuildFailedException | ViewCreationFailedException e) {
      // Expected.
    }
    events.assertContainsError("output path 'blaze-out/");
    // Skip over config key string ...
    events.assertContainsError(
        "/bin/x/y' (belonging to //x:y) is a prefix of output path 'blaze-out");
    assertThat(Iterables.size(events.errors())).isGreaterThan(1);
    if (keepGoing) {
      assertThat(eventListener.failedTargetNames).containsExactly("//x:y", "//x/y:y");
    } else {
      assertThat(eventListener.failedTargetNames).containsAnyOf("//x:y", "//x/y:y");
    }
  }

  @Test
  public void testAspectArtifactSharesPrefixWithTargetArtifact(
      @TestParameter boolean keepGoing, @TestParameter boolean modifyBuildFile) throws Exception {
    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/y.cc", "");
    write("x/y/BUILD", "cc_library(name = 'y', srcs=['y.cc'])");
    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");
    if (keepGoing) {
      addOptions("--keep_going");
    }
    try {
      // Skyframe full should throw an error here even if we just build //x:y. However, because our
      // testing infrastructure sets up lots of symlinks, Skyframe invalidates the //x/y action, and
      // so would not find a conflict here without re-evaluating //x/y. Note that in a real client,
      // requesting the //x/y target would not be necessary to throw an exception.
      buildTarget("//x:y", "//x/y");
      fail();
    } catch (BuildFailedException | ViewCreationFailedException e) {
      // Expected.
    }
    events.assertContainsError("output path 'blaze-out/");
    // Skip over config key string ...
    events.assertContainsError(
        "/bin/x/y' (belonging to //x:y) is a prefix of output path 'blaze-out");
    // When an aspect artifact's path is in aa prefix conflict with a target artifact's path, the
    // target artifact is created and only the aspect fails analysis.
    assertThat(Iterables.size(events.errors())).isGreaterThan(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) throws Exception {
    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");
    if (keepGoing) {
      addOptions("--keep_going");
    }
    try {
      // Skyframe full should throw an error here even if we just build //x:y. However, because our
      // testing infrastructure sets up lots of symlinks, Skyframe invalidates the //x/y action, and
      // so would not find a conflict here without re-evaluating //x/y. Note that in a real client,
      // requesting the //x/y target would not be necessary to throw an exception.
      buildTarget("//x:y", "//x:ydir");
      fail();
    } catch (BuildFailedException | ViewCreationFailedException e) {
      // Expected.
    }
    events.assertContainsError("output path 'blaze-out/");
    // Skip over config key string ...
    events.assertContainsError(
        "/bin/x/y' (belonging to //x:y) is a prefix of output path 'blaze-out");
    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() throws Exception {
    write("x/BUILD", "cc_binary(name = 'y', srcs = ['y.cc'], malloc = '//base:system_malloc')");
    write("x/y/BUILD", "cc_library(name = 'y')");
    write("x/y.cc", "int main() { return 0; }");
    try {
      buildTarget("//x:y", "//x/y");
      fail();
    } catch (BuildFailedException | ViewCreationFailedException e) {
      // Expected.
    }
    assertThat(eventListener.failedTargetNames).containsAnyOf("//x:y", "//x/y:y");
    write("x/BUILD", "# no conflict");
    events.clear();
    buildTarget("//x/y");
    events.assertNoWarningsOrErrors();
  }

  @Test
  public void testNewTargetConflict() throws Exception {
    write("x/BUILD", "cc_binary(name = 'y', srcs = ['y.cc'], malloc = '//base:system_malloc')");
    write("x/y/y.cc", "");
    write("x/y/BUILD", "cc_library(name = 'y', srcs=['y.cc'])");
    write("x/y.cc", "int main() { return 0; }");
    buildTarget("//x/y");
    events.assertNoWarningsOrErrors();
    try {
      buildTarget("//x:y", "//x/y");
      fail();
    } catch (BuildFailedException | ViewCreationFailedException e) {
      // Expected.
    }
    assertThat(eventListener.failedTargetNames).containsAnyOf("//x:y", "//x/y:y");
  }

  @Test
  public void testTwoOverlappingBuildsHasNoConflict() throws Exception {
    write("x/BUILD", "cc_binary(name = 'y', srcs = ['y.cc'], malloc = '//base:system_malloc')");
    write("x/y/y.cc", "");
    write("x/y/BUILD", "cc_library(name = 'y', srcs=['y.cc'])");
    write("x/y.cc", "int main() { return 0; }");
    buildTarget("//x/y");
    events.assertNoWarningsOrErrors();
    buildTarget("//x:y");
    events.assertNoWarningsOrErrors();

    // Verify that together they fail, even though no new targets have been analyzed
    try {
      buildTarget("//x:y", "//x/y");
      fail();
    } catch (BuildFailedException | ViewCreationFailedException e) {
      // Expected.
    }
    events.clear();

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

  @Test
  public void testFailingTargetsDoNotCauseActionConflicts() throws Exception {
    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() throws Exception {
    write(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo.cc'])",
        "cc_binary(name='_objs/x/foo.pic.o', srcs=['bar.cc'], "
            + "malloc = '//base:system_malloc')");
    write("conflict/foo.cc", "int main() { return 0; }");
    write("conflict/bar.cc", "int main() { return 0; }");
    write("x/BUILD", "sh_library(name = 'x', deps = ['//y:y'])");
    write("y/BUILD", "sh_library(name = 'y', visibility = ['//visibility:private'])");
    runtimeWrapper.addOptions("--keep_going");

    assertThrows(
        BuildFailedException.class,
        () -> buildTarget("//x:x", "//conflict:x", "//conflict:_objs/x/foo.pic.o"));
    events.assertContainsError(
        "file 'conflict/_objs/x/foo.pic.o' 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("//conflict:x", "//conflict:_objs/x/foo.pic.o");
  }

  // 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() throws Exception {
    write(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo.cc'])",
        "cc_binary(name='_objs/x/foo.pic.o', srcs=['bar.cc'], "
            + "malloc = '//base:system_malloc')");
    write("x/BUILD", "cc_binary(name = 'y', srcs = ['y.cc'], malloc = '//base:system_malloc')");
    write("x/y.cc", "int main() { return 0; }");
    write("conflict/foo.cc", "int main() { return 0; }");
    write("conflict/bar.cc", "int main() { return 0; }");
    write("x/y/y.cc", "");
    write("x/y/BUILD", "cc_library(name = 'y', srcs=['y.cc'])");
    runtimeWrapper.addOptions("--keep_going");

    assertThrows(
        BuildFailedException.class,
        () -> buildTarget("//x/y", "//x:y", "//conflict:x", "//conflict:_objs/x/foo.pic.o"));
    events.assertContainsError(
        "file 'conflict/_objs/x/foo.pic.o' is generated by these conflicting actions:");
    events.assertContainsError(
        "/bin/x/y' (belonging to //x:y) is a prefix of output path 'blaze-out");
    // 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("//conflict:x", "//conflict:_objs/x/foo.pic.o");
  }

  @Test
  public void repeatedConflictBuild() throws Exception {
    write(
        "foo/conflict.bzl",
        "def _conflict_impl(ctx):",
        "  conflict_output = ctx.actions.declare_file('conflict_output')",
        "  other = ctx.actions.declare_file('other' + ctx.attr.other_name)",
        "  ctx.actions.run_shell(",
        "    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 = { 'other_name': attr.string() },",
        ")");
    write(
        "foo/BUILD",
        "load('//foo:conflict.bzl', 'my_rule')",
        "my_rule(name = 'first', other_name = '1')",
        "my_rule(name = 'second', other_name = '2')");
    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");
  }
}
