// Copyright 2015 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.analysis;

import static com.google.common.collect.MoreCollectors.onlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.analysis.BaseRuleClasses.ACTION_LISTENER;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil.NullAction;
import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.analysis.util.TestAspects;
import com.google.devtools.build.lib.analysis.util.TestAspects.AspectApplyingToFiles;
import com.google.devtools.build.lib.analysis.util.TestAspects.AspectInfo;
import com.google.devtools.build.lib.analysis.util.TestAspects.DummyRuleFactory;
import com.google.devtools.build.lib.analysis.util.TestAspects.ExtraAttributeAspect;
import com.google.devtools.build.lib.analysis.util.TestAspects.RuleInfo;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.events.OutputFilter.RegexOutputFilter;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.NativeAspectClass;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectKey;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.ModifiedFileSet;
import com.google.devtools.build.lib.vfs.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import net.starlark.java.eval.StarlarkInt;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for aspect creation and merging with configured targets.
 *
 * <p>Uses the complete analysis machinery and depends on custom rules so that behaviors related to
 * aspects can be tested even if they aren't used by regular rules.
 */
@RunWith(JUnit4.class)
public class AspectTest extends AnalysisTestCase {

  private void pkg(String name, String... contents) throws Exception {
    scratch.file(name + "/BUILD", contents);
  }

  @Test
  public void testAspectAppliedToAliasWithSelect() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
    pkg("a",
        "aspect(name='a', foo=[':b'])",
        "alias(name='b', actual=select({'//conditions:default': ':c'}))",
        "base(name='c')");
    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("aspect //a:c", "rule //a:a");
  }

  @Test
  public void testAspectAppliedToChainedAliases() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
    pkg("a",
        "aspect(name='a', foo=[':b'])",
        "alias(name='b', actual=':c')",
        "alias(name='c', actual=':d')",
        "alias(name='d', actual=':e')",
        "base(name='e')");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("aspect //a:e", "rule //a:a");
  }

  @Test
  public void testAspectAppliedToChainedAliasesAndSelect() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
    pkg("a",
        "aspect(name='a', foo=[':b'])",
        "alias(name='b', actual=select({'//conditions:default': ':c'}))",
        "alias(name='c', actual=select({'//conditions:default': ':d'}))",
        "base(name='d')");
    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("aspect //a:d", "rule //a:a");
  }

  @Test
  public void providersOfAspectAreMergedIntoDependency() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);
    pkg("a",
        "aspect(name='a', foo=[':b'])",
        "aspect(name='b', foo=[])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("aspect //a:b", "rule //a:a");
  }

  @Test
  public void aspectIsNotCreatedIfAdvertisedProviderIsNotPresent() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.LIAR_RULE,
        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);

    pkg("a",
        "aspect_requiring_provider(name='a', foo=[':b'])",
        "liar(name='b', foo=[])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList()).containsExactly("rule //a:a");
  }

  @Test
  public void aspectIsNotCreatedIfAdvertisedProviderIsNotPresentWithAlias() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.LIAR_RULE,
        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);

    pkg("a",
        "aspect_requiring_provider(name='a', foo=[':b'])",
        "alias(name = 'b_alias', actual = ':b')",
        "liar(name='b', foo=[])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList()).containsExactly("rule //a:a");
  }

  @Test
  public void aspectIsNotPropagatedThroughLiars() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.LIAR_RULE,
        TestAspects.HONEST_RULE, TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);

    pkg("a",
        "aspect_requiring_provider(name='a', foo=[':b_alias'])",
        "alias(name = 'b_alias', actual = ':b')",
        "liar(name='b', foo=[':c'])",
        "honest(name = 'c', foo = [])"
    );

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList()).containsExactly("rule //a:a");
  }

  @Test
  public void aspectPropagatedThroughAliasRule() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);

    pkg("a",
        "aspect_requiring_provider(name='a', foo=[':b_alias'])",
        "alias(name = 'b_alias', actual = ':b')",
        "honest(name='b', foo=[])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("rule //a:a", "aspect //a:b");
  }

  @Test
  public void aspectPropagatedThroughAliasRuleAndHonestRules() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);

    pkg("a",
        "aspect_requiring_provider(name='a', foo=[':b'])",
        "alias(name = 'b_alias', actual = ':b')",
        "honest(name='b', foo=[':c'])",
        "honest(name='c', foo=[])"
    );

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("rule //a:a", "aspect //a:b", "aspect //a:c");
  }





  @Test
  public void aspectCreationWorksThroughBind() throws Exception {
    if (getInternalTestExecutionMode() != TestConstants.InternalTestExecutionMode.NORMAL) {
      // TODO(b/67651960): fix or justify disabling.
      return;
    }
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
    pkg("a",
        "aspect_requiring_provider(name='a', foo=['//external:b'])",
        "honest(name='b', foo=[])");

    scratch.overwriteFile("WORKSPACE",
        new ImmutableList.Builder<String>()
            .addAll(analysisMock.getWorkspaceContents(mockToolsConfig))
            .add("bind(name='b', actual='//a:b')")
            .build());

    skyframeExecutor.invalidateFilesUnderPathForTesting(
        reporter, ModifiedFileSet.EVERYTHING_MODIFIED, Root.fromPath(rootDirectory));

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("rule //a:a", "aspect //a:b");
  }


  @Test
  public void aspectCreatedIfAdvertisedProviderIsPresent() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);

    pkg("a",
        "aspect_requiring_provider(name='a', foo=[':b'])",
        "honest(name='b', foo=[])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("rule //a:a", "aspect //a:b");
  }

  @Test
  public void aspectCreatedIfAtLeastOneSetOfAdvertisedProvidersArePresent() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
        TestAspects.HONEST_RULE_2, TestAspects.ASPECT_REQUIRING_PROVIDER_SETS_RULE);

    pkg("a",
        "aspect_requiring_provider_sets(name='a', foo=[':b', ':c'])",
        "honest(name='b', foo=[])",
        "honest2(name='c', foo=[])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("rule //a:a", "aspect //a:b", "aspect //a:c");
  }

  @Test
  public void aspectWithParametrizedDefinition() throws Exception {
    setRulesAvailableInTests(
        TestAspects.BASE_RULE,
        TestAspects.HONEST_RULE,
        TestAspects.PARAMETERIZED_DEFINITION_ASPECT_RULE);

    pkg(
        "a",
        "honest(name='q', foo=[])",
        "parametrized_definition_aspect(name='a', foo=[':b'], baz='//a:q')",
        "honest(name='c', foo=[])",
        "honest(name='b', foo=[':c'])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(TestAspects.RuleInfo.class).getData().toList())
        .containsExactly(
            "rule //a:a",
            "aspect //a:b data //a:q $dep:[ //a:q]",
            "aspect //a:c data //a:q $dep:[ //a:q]");
  }

  @Test
  public void aspectInError() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ERROR_ASPECT_RULE,
        TestAspects.SIMPLE_RULE);

    pkg("a",
        "simple(name='a', foo=[':b'])",
        "error_aspect(name='b', foo=[':c'])",
        "simple(name='c')");

    reporter.removeHandler(failFastHandler);
    // getConfiguredTarget() uses a separate code path that does not hit
    // SkyframeBuildView#configureTargets
    assertThrows(ViewCreationFailedException.class, () -> update("//a:a"));
    assertContainsEvent("Aspect error");
  }

  @Test
  public void transitiveAspectInError() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ERROR_ASPECT_RULE,
        TestAspects.SIMPLE_RULE);

    pkg("a",
        "error_aspect(name='a', foo=[':b'])",
        "error_aspect(name='b', bar=[':c'])",
        "error_aspect(name='c', bar=[':d'])",
        "error_aspect(name='d')");

    reporter.removeHandler(failFastHandler);
    // getConfiguredTarget() uses a separate code path that does not hit
    // SkyframeBuildView#configureTargets
    assertThrows(ViewCreationFailedException.class, () -> update("//a:a"));
    assertContainsEvent("Aspect error");
  }

  @Test
  public void aspectDependenciesDontShowDeprecationWarnings() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.EXTRA_ATTRIBUTE_ASPECT_RULE);

    pkg("extra", "base(name='extra', deprecation='bad aspect')");

    pkg("a",
        "rule_with_extra_deps_aspect(name='a', foo=[':b'])",
        "base(name='b')");

    getConfiguredTarget("//a:a");
    assertContainsEventWithFrequency("bad aspect", 0);
  }

  @Test
  public void aspectDependsOnPackageGroup() throws Exception {
    setRulesAvailableInTests(
        TestAspects.BASE_RULE, TestAspects.PACKAGE_GROUP_ATTRIBUTE_ASPECT_RULE);
    pkg("extra", "package_group(name='extra')");
    pkg("a", "rule_with_package_group_deps_aspect(name='a', foo=[':b'])", "base(name='b')");

    getConfiguredTarget("//a:a");
    assertContainsEventWithFrequency("bad aspect", 0);
  }

  @Test
  public void aspectWithComputedAttribute() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.COMPUTED_ATTRIBUTE_ASPECT_RULE);

    pkg("a", "rule_with_computed_deps_aspect(name='a', foo=[':b'])", "base(name='b')");

    getConfiguredTarget("//a:a");
  }

  @Test
  public void ruleDependencyDeprecationWarningsAbsentDuringAspectEvaluations() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE);

    pkg("a", "aspect(name='a', foo=['//b:b'])");
    pkg("b", "aspect(name='b', bar=['//d:d'])");
    pkg("d", "base(name='d', deprecation='bad rule')");

    getConfiguredTarget("//a:a");
    assertContainsEventWithFrequency("bad rule", 1);
  }

  @Test
  public void aspectWarningsFilteredByOutputFiltersForAssociatedRules() throws Exception {
    if (getInternalTestExecutionMode() != TestConstants.InternalTestExecutionMode.NORMAL) {
      // TODO(b/67651960): fix or justify disabling.
      return;
    }
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.WARNING_ASPECT_RULE);
    pkg("a", "warning_aspect(name='a', foo=['//b:b', '//c:c'])");
    pkg("b", "base(name='b')");
    pkg("c", "base(name='c')");

    reporter.setOutputFilter(RegexOutputFilter.forPattern(Pattern.compile("^//b:")));

    getConfiguredTarget("//a:a");
    assertContainsEventWithFrequency("Aspect warning on //b:b", 1);
    assertContainsEventWithFrequency("Aspect warning on //c:c", 0);
  }

  @Test
  public void sameTargetInDifferentAttributes() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.ASPECT_REQUIRING_RULE,
        TestAspects.SIMPLE_RULE);
    pkg("a",
        "aspect(name='a', foo=[':b'], bar=[':b'])",
        "aspect(name='b', foo=[])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("aspect //a:b", "rule //a:a");
  }

  @Test
  public void sameTargetInDifferentAttributesWithDifferentAspects() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.MULTI_ASPECT_RULE,
        TestAspects.SIMPLE_RULE);
    pkg("a",
        "multi_aspect(name='a', foo=':b', bar=':b')",
        "simple(name='b')");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList()).containsExactly("foo", "bar");
  }

  @Test
  public void informationFromBaseRulePassedToAspect() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.HONEST_RULE,
        TestAspects.ASPECT_REQUIRING_PROVIDER_RULE);
    pkg("a",
        "aspect_requiring_provider(name='a', foo=[':b'], baz='hello')",
        "honest(name='b', foo=[])");

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("rule //a:a", "aspect //a:b data hello");
  }

  /**
   * Rule definitions to be used in emptyAspectAttributesAreAvailableInRuleContext().
   */
  public static class EmptyAspectAttributesAreAvailableInRuleContext {
    public static final MockRule TEST_RULE =
        () ->
            MockRule.ancestor(TestAspects.BASE_RULE.getClass())
                .factory(DummyRuleFactory.class)
                .define(
                    "testrule",
                    (builder, env) ->
                        builder.add(
                            attr("foo", LABEL_LIST)
                                .legacyAllowAnyFileType()
                                .aspect(AspectWithEmptyLateBoundAttribute.INSTANCE)));

    public static class AspectWithEmptyLateBoundAttribute extends NativeAspectClass
      implements ConfiguredAspectFactory {
      static final AspectWithEmptyLateBoundAttribute INSTANCE =
          new AspectWithEmptyLateBoundAttribute();

      private AspectWithEmptyLateBoundAttribute() {}

      @Override
      public AspectDefinition getDefinition(AspectParameters params) {
        return new AspectDefinition.Builder(this)
            .add(attr(":late", LABEL).value(LateBoundDefault.alwaysNull()))
            .build();
      }

      @Override
      public ConfiguredAspect create(
          ConfiguredTargetAndData ctadBase,
          RuleContext ruleContext,
          AspectParameters parameters,
          RepositoryName toolsRepository)
          throws InterruptedException, ActionConflictException {
        Object lateBoundPrereq = ruleContext.getPrerequisite(":late");
        return new ConfiguredAspect.Builder(ruleContext)
            .addProvider(
                AspectInfo.class,
                new AspectInfo(
                    NestedSetBuilder.create(
                        Order.STABLE_ORDER, lateBoundPrereq != null ? "non-empty" : "empty")))
            .build();
      }
    }
  }

  /**
   * An Aspect has a late-bound attribute with no value (that is, a LateBoundDefault whose
   * getDefault() returns `null`). Test that this attribute is available in the RuleContext which is
   * provided to the Aspect's `create()` method.
   */
  @Test
  public void emptyAspectAttributesAreAvailableInRuleContext() throws Exception {
    setRulesAndAspectsAvailableInTests(
        ImmutableList.of(
            TestAspects.SIMPLE_ASPECT,
            EmptyAspectAttributesAreAvailableInRuleContext.AspectWithEmptyLateBoundAttribute
                .INSTANCE),
        ImmutableList.of(
            TestAspects.BASE_RULE, EmptyAspectAttributesAreAvailableInRuleContext.TEST_RULE));
    pkg("a",
        "testrule(name='a', foo=[':b'])",
        "testrule(name='b')");
    ConfiguredTarget a = getConfiguredTarget("//a:a");
    assertThat(a.getProvider(RuleInfo.class).getData().toList()).contains("empty");
  }

  /**
   * Rule definitions to be used in extraActionsAreEmitted().
   */
  public static class ExtraActionsAreEmitted {
    public static final MockRule TEST_RULE =
        () ->
            MockRule.ancestor(TestAspects.BASE_RULE.getClass())
                .factory(DummyRuleFactory.class)
                .define(
                    "testrule",
                    (builder, env) ->
                        builder
                            .add(
                                attr("foo", LABEL_LIST)
                                    .legacyAllowAnyFileType()
                                    .aspect(AspectThatRegistersAction.INSTANCE))
                            .add(
                                attr(":action_listener", LABEL_LIST)
                                    .cfg(ExecutionTransitionFactory.create())
                                    .value(ACTION_LISTENER)));

    public static class AspectThatRegistersAction extends NativeAspectClass
      implements ConfiguredAspectFactory {

      static final AspectThatRegistersAction INSTANCE = new AspectThatRegistersAction();

      private AspectThatRegistersAction() {}

      @Override
      public AspectDefinition getDefinition(AspectParameters params) {
        return new AspectDefinition.Builder(this).build();
      }

      @Override
      public ConfiguredAspect create(
          ConfiguredTargetAndData ctadBase,
          RuleContext ruleContext,
          AspectParameters parameters,
          RepositoryName toolsRepository)
          throws InterruptedException, ActionConflictException {
        ruleContext.registerAction(new NullAction(ruleContext.createOutputArtifact()));
        return new ConfiguredAspect.Builder(ruleContext).build();
      }
    }
  }

  /**
   * Test that actions registered in an Aspect are reported as extra-actions on the attached rule.
   * AspectThatRegistersAction registers a NullAction, whose mnemonic is "Null". We have an
   * action_listener that targets that mnemonic, which makes sure the Aspect machinery will expose
   * an ExtraActionArtifactsProvider.
   * The rule //a:a doesn't have an aspect, so the only action we get is the one on //a:b
   * (which does have an aspect).
   */
  @Test
  public void extraActionsAreEmitted() throws Exception {
    setRulesAndAspectsAvailableInTests(
        ImmutableList.of(
            TestAspects.SIMPLE_ASPECT, ExtraActionsAreEmitted.AspectThatRegistersAction.INSTANCE),
        ImmutableList.of(TestAspects.BASE_RULE, ExtraActionsAreEmitted.TEST_RULE));
    useConfiguration("--experimental_action_listener=//extra_actions:listener");
    scratch.file(
        "extra_actions/BUILD",
        "extra_action(name='xa', cmd='echo dont-care')",
        "action_listener(name='listener', mnemonics=['Null'], extra_actions=[':xa'])");
    pkg("a",
        "testrule(name='a', foo=[':b'])",
        "testrule(name='b')");
    update();

    ConfiguredTarget a = getConfiguredTarget("//a:a");
    NestedSet<Artifact.DerivedArtifact> extraActionArtifacts =
        a.getProvider(ExtraActionArtifactsProvider.class).getTransitiveExtraActionArtifacts();
    for (Artifact artifact : extraActionArtifacts.toList()) {
      assertThat(artifact.getOwnerLabel()).isEqualTo(Label.create("@//a", "b"));
    }
  }

  @Test
  public void aspectPropagatesToAllAttributes() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
        TestAspects.ALL_ATTRIBUTES_ASPECT_RULE);
    pkg("a",
        "simple(name='a', foo=[':b'], foo1=':c', txt='some text')",
        "simple(name='b', foo=[], txt='some text')",
        "simple(name='c', foo=[], txt='more text')",
        "all_attributes_aspect(name='x', foo=[':a'])");

    ConfiguredTarget a = getConfiguredTarget("//a:x");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("aspect //a:a", "aspect //a:b", "aspect //a:c", "rule //a:x");
  }

  /**
   * Tests that when --experimental_extra_action_top_level_only, Blaze reports extra-actions for
   * actions registered by Aspects injected by a top-level rule. Because we can't know whether an
   * aspect was injected by a top-level target or one of its children, we approximate it by only
   * reporting extra-actions from Aspects that the top-level target could have injected.
   *
   * <p>Here, injector1() and injector2() inject aspects into their children. null_rule() just
   * passes the aspects to its children. The test makes sure that actions registered by aspect1
   * (injected by injector1()) are reported to the extra-action mechanism. Actions registered by
   * aspect2 (from injector2) are not reported, because the target under test (//x:a) doesn't inject
   * aspect2.
   */
  @Test
  public void extraActionsAreEmitted_topLevel() throws Exception {
    useConfiguration(
        "--experimental_action_listener=//pkg1:listener",
        "--experimental_extra_action_top_level_only");

    scratch.file(
        "x/BUILD",
        "load(':extension.bzl', 'injector1', 'injector2', 'null_rule')",
        "injector1(name='a', deps=[':b'])",
        "null_rule(name='b', deps=[':c'])",
        "null_rule(name='c', deps=[':d'])",
        "injector2(name = 'd', extra_deps=[':e'])",
        "null_rule(name = 'e')");

    scratch.file(
        "x/extension.bzl",
        "def _aspect_impl(target, ctx):",
        "  ctx.actions.do_nothing(mnemonic='Mnemonic')",
        "  return []",
        "aspect1 = aspect(_aspect_impl, attr_aspects=['deps'])",
        "aspect2 = aspect(_aspect_impl, attr_aspects=['extra_deps'])",
        "def _rule_impl(ctx):",
        "  return []",
        "injector1 = rule(_rule_impl, attrs = { 'deps' : attr.label_list(aspects = [aspect1]) })",
        "null_rule = rule(_rule_impl, attrs = { 'deps' : attr.label_list() })",
        "injector2 = rule(",
        "  _rule_impl, attrs = { 'extra_deps' : attr.label_list(aspects = [aspect2]) })");

    scratch.file(
        "pkg1/BUILD",
        "extra_action(name='xa', cmd='echo dont-care')",
        "action_listener(name='listener', mnemonics=['Mnemonic'], extra_actions=[':xa'])");

    // Check: //x:d injects an aspect which produces some extra-action.
    {
      AnalysisResult analysisResult = update("//x:d");

      // Get owners of all extra-action artifacts.
      List<Label> extraArtifactOwners = new ArrayList<>();
      for (Artifact artifact : analysisResult.getArtifactsToBuild()) {
        if (artifact.getRootRelativePathString().endsWith(".xa")) {
          extraArtifactOwners.add(artifact.getOwnerLabel());
        }
      }
      assertThat(extraArtifactOwners).containsExactly(Label.create("@//x", "e"));
    }

    // Actual test: //x:a reports actions registered by the aspect it injects.
    {
      AnalysisResult analysisResult = update("//x:a");

      // Get owners of all extra-action artifacts.
      List<Label> extraArtifactOwners = new ArrayList<>();
      for (Artifact artifact : analysisResult.getArtifactsToBuild()) {
        if (artifact.getRootRelativePathString().endsWith(".xa")) {
          extraArtifactOwners.add(artifact.getOwnerLabel());
        }
      }
      assertThat(extraArtifactOwners)
          .containsExactly(
              Label.create("@//x", "b"), Label.create("@//x", "c"), Label.create("@//x", "d"));
    }
  }

  @Test
  public void extraActionsFromDifferentAspectsDontConflict() throws Exception {
    useConfiguration(
        "--experimental_action_listener=//pkg1:listener",
        "--experimental_extra_action_top_level_only");

    scratch.file(
        "x/BUILD",
        "load(':extension.bzl', 'injector1', 'injector2', 'null_rule')",
        "injector2(name='i2_a', deps = [':i1_a'])",
        "injector1(name='i1_a', deps=[':n'], param = 'a')",
        "injector1(name='i1_b', deps=[':n'], param = 'b')",
        "injector2(name='i2', deps=[':n'])",
        "null_rule(name = 'n')");

    scratch.file(
        "x/extension.bzl",
        "def _aspect_impl(target, ctx):",
        "  ctx.actions.do_nothing(mnemonic='Mnemonic')",
        "  return []",
        "aspect1 = aspect(_aspect_impl, attr_aspects=['deps'], attrs =",
        "    {'param': attr.string(values = ['a', 'b'])})",
        "aspect2 = aspect(_aspect_impl, attr_aspects=['deps'])",
        "def _rule_impl(ctx):",
        "  return []",
        "injector1 = rule(_rule_impl, attrs =",
        "    { 'deps' : attr.label_list(aspects = [aspect1]), 'param' : attr.string() })",
        "injector2 = rule(_rule_impl, attrs = { 'deps' : attr.label_list(aspects = [aspect2]) })",
        "null_rule = rule(_rule_impl, attrs = { 'deps' : attr.label_list() })");

    scratch.file(
        "pkg1/BUILD",
        "extra_action(name='xa', cmd='echo dont-care')",
        "action_listener(name='listener', mnemonics=['Mnemonic'], extra_actions=[':xa'])");

    update("//x:i1_a", "//x:i1_b", "//x:i2", "//x:i2_a");

    // Implicitly check that update() didn't throw an exception because of two actions producing
    // the same outputs.
  }

  @Test
  public void sharedArtifactsInAspect() throws Exception {
    scratch.file(
        "foo/shared_aspect.bzl",
        "def _shared_aspect_impl(target, ctx):",
        "  shared_file = ctx.actions.declare_file('shared_file')",
        "  ctx.actions.write(output=shared_file, content='Shared content')",
        "  lib = ctx.rule.attr.lib",
        "  if lib:",
        "    result = depset([shared_file], transitive=[ctx.rule.attr.lib.prov])",
        "  else:",
        "    result = depset([shared_file])",
        "  return struct(prov=result)",
        "",
        "shared_aspect = aspect(implementation = _shared_aspect_impl,",
        "                       attr_aspects = ['lib'])",
        "",
        "def _rule_impl(ctx):",
        "  pass",
        "",
        "simple_rule = rule(",
        "    implementation=_rule_impl,",
        "    attrs = {'lib': attr.label(providers = ['prov'],",
        "                               aspects=[shared_aspect])})");
    scratch.file(
        "foo/BUILD",
        "load(':shared_aspect.bzl', 'shared_aspect', 'simple_rule')",
        "",
        "simple_rule(name = 'top_rule', lib = ':first_dep')",
        "simple_rule(name = 'first_dep', lib = ':second_dep')",
        "simple_rule(name = 'second_dep')");
    // Confirm that load is successful and doesn't crash.
    update("//foo:top_rule");
  }

  @Test
  public void aspectPropagatesToAllAttributesImplicit() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
        TestAspects.IMPLICIT_DEP_RULE, TestAspects.ALL_ATTRIBUTES_ASPECT_RULE);
    scratch.file(
        "extra/BUILD",
        "simple(name ='extra')"
    );
    pkg("a",
        "simple(name='a', foo=[':b'], foo1=':c', txt='some text')",
        "simple(name='b', foo=[], txt='some text')",
        "implicit_dep(name='c')",
        "all_attributes_aspect(name='x', foo=[':a'])");
    update();

    ConfiguredTarget a = getConfiguredTarget("//a:x");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly(
            "aspect //a:a", "aspect //a:b", "aspect //a:c", "aspect //extra:extra", "rule //a:x");
  }


  @Test
  public void aspectPropagatesToAllAttributesLateBound() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
        TestAspects.LATE_BOUND_DEP_RULE, TestAspects.ALL_ATTRIBUTES_ASPECT_RULE);

    scratch.file(
        "extra/BUILD",
        "simple(name ='extra')"
    );
    pkg("a",
        "simple(name='a', foo=[':b'], foo1=':c', txt='some text')",
        "simple(name='b', foo=[], txt='some text')",
        "late_bound_dep(name='c')",
        "all_attributes_aspect(name='x', foo=[':a'])");
    useConfiguration("--plugin=//extra:extra");
    update();

    ConfiguredTarget a = getConfiguredTarget("//a:x");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly(
            "aspect //a:a", "aspect //a:b", "aspect //a:c", "aspect //extra:extra", "rule //a:x");
  }

  /**
   * Ensures an aspect with attr = '*' doesn't try to propagate to its own implicit attributes.
   * Doing so leads to a dependency cycle.
   */
  @Test
  public void aspectWithAllAttributesDoesNotPropagateToOwnImplicitAttributes() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
        TestAspects.ALL_ATTRIBUTES_WITH_TOOL_ASPECT_RULE);
    pkg(
        "a",
        "simple(name='tool')",
        "simple(name='a')",
        "all_attributes_with_tool_aspect(name='x', foo=[':a'])");

    ConfiguredTarget a = getConfiguredTarget("//a:x");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly("aspect //a:a", "rule //a:x");
  }

  /**
   * Makes sure the aspect *will* propagate to its implicit attributes if there is a "regular"
   * dependency path to it (i.e. not through its own implicit attributes).
   */
  @Test
  public void aspectWithAllAttributesPropagatesToItsToolIfThereIsPath() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
        TestAspects.ALL_ATTRIBUTES_WITH_TOOL_ASPECT_RULE);
    pkg(
        "a",
        "simple(name='tool')",
        "simple(name='a', foo=[':b'], foo1=':c', txt='some text')",
        "simple(name='b', foo=[], txt='some text')",
        "simple(name='c', foo=[':tool'], txt='more text')",
        "all_attributes_with_tool_aspect(name='x', foo=[':a'])");

    ConfiguredTarget a = getConfiguredTarget("//a:x");
    assertThat(a.getProvider(RuleInfo.class).getData().toList())
        .containsExactly(
            "aspect //a:a", "aspect //a:b", "aspect //a:c", "aspect //a:tool", "rule //a:x");
  }

  @Test
  public void aspectTruthInAdvertisement() throws Exception {
    reporter.removeHandler(failFastHandler); // expect errors
    setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE,
        TestAspects.FALSE_ADVERTISEMENT_ASPECT_RULE);
    pkg(
        "a",
        "simple(name = 's')",
        "false_advertisement_aspect(name = 'x', deps = [':s'])"
    );
    try {
      update("//a:x");
    } catch (ViewCreationFailedException e) {
      // expected.
    }
    assertContainsEvent(
        "Aspect 'FalseAdvertisementAspect', applied to '//a:s',"
            + " does not provide advertised provider 'RequiredProvider'");
    assertContainsEvent(
        "Aspect 'FalseAdvertisementAspect', applied to '//a:s',"
            + " does not provide advertised provider 'advertised_provider'");
  }

  @Test
  public void aspectApplyingToFiles() throws Exception {
    AspectApplyingToFiles aspectApplyingToFiles = new AspectApplyingToFiles();
    setRulesAndAspectsAvailableInTests(ImmutableList.of(aspectApplyingToFiles), ImmutableList.of());
    pkg(
        "a",
        "java_binary(name = 'x', main_class = 'x.FooBar', srcs = ['x.java'])"
    );
    AnalysisResult analysisResult = update(new EventBus(), defaultFlags(),
        ImmutableList.of(aspectApplyingToFiles.getName()),
        "//a:x_deploy.jar");
    ConfiguredAspect aspect = Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    AspectApplyingToFiles.Provider provider =
        aspect.getProvider(AspectApplyingToFiles.Provider.class);
    assertThat(provider.getLabel())
        .isEqualTo(Label.parseAbsoluteUnchecked("//a:x_deploy.jar"));
  }

  @Test
  public void aspectApplyingToSourceFilesIgnored() throws Exception {
    AspectApplyingToFiles aspectApplyingToFiles = new AspectApplyingToFiles();
    setRulesAndAspectsAvailableInTests(ImmutableList.of(aspectApplyingToFiles), ImmutableList.of());
    pkg(
        "a",
        "java_binary(name = 'x', main_class = 'x.FooBar', srcs = ['x.java'])"
    );
    scratch.file("a/x.java", "");
    AnalysisResult analysisResult = update(new EventBus(), defaultFlags(),
        ImmutableList.of(aspectApplyingToFiles.getName()),
        "//a:x.java");
    ConfiguredAspect aspect = Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    assertThat(aspect.getProvider(AspectApplyingToFiles.Provider.class)).isNull();
  }

  @Test
  public void duplicateTopLevelAspects_duplicateAspectsNotAllowed() throws Exception {
    AspectApplyingToFiles aspectApplyingToFiles = new AspectApplyingToFiles();
    setRulesAndAspectsAvailableInTests(ImmutableList.of(aspectApplyingToFiles), ImmutableList.of());
    pkg("a", "java_binary(name = 'x', main_class = 'x.FooBar', srcs = ['x.java'])");
    reporter.removeHandler(failFastHandler);

    assertThrows(
        ViewCreationFailedException.class,
        () ->
            update(
                new EventBus(),
                defaultFlags(),
                ImmutableList.of(aspectApplyingToFiles.getName(), aspectApplyingToFiles.getName()),
                "//a:x_deploy.jar"));
    assertContainsEvent("Aspect AspectApplyingToFiles has already been added");
  }

  @Test
  public void aspectWithExtraAttribute_ignoredForOutputFile() throws Exception {
    ExtraAttributeAspect aspect =
        new ExtraAttributeAspect("//nonexistent", /*applyToFiles=*/ false);
    setRulesAndAspectsAvailableInTests(ImmutableList.of(aspect), ImmutableList.of());
    scratch.file("a/BUILD", "genrule(name='gen_a', outs=['a'], cmd='touch $@')");

    AnalysisResult analysisResult =
        update(new EventBus(), defaultFlags(), ImmutableList.of(aspect.getName()), "//a");

    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    assertThat(configuredAspect.getProvider(ExtraAttributeAspect.Provider.class)).isNull();
  }

  @Test
  public void aspectWithExtraAttributeApplyToFiles_outputFile_hasResolvedAttribute()
      throws Exception {
    ExtraAttributeAspect aspect = new ExtraAttributeAspect("//extra", /*applyToFiles=*/ true);
    setRulesAndAspectsAvailableInTests(
        ImmutableList.of(aspect), ImmutableList.of(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE));
    scratch.file("extra/BUILD", "simple(name='extra')");
    scratch.file("a/BUILD", "genrule(name='gen_a', outs=['a'], cmd='touch $@')");

    AnalysisResult analysisResult =
        update(new EventBus(), defaultFlags(), ImmutableList.of(aspect.getName()), "//a");

    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    ExtraAttributeAspect.Provider provider =
        configuredAspect.getProvider(ExtraAttributeAspect.Provider.class);
    assertThat(provider.label()).isEqualTo("//extra:extra");
  }

  @Test
  public void aspectWithExtraAttributeApplyToFiles_ignoredForSourceFile() throws Exception {
    ExtraAttributeAspect aspect = new ExtraAttributeAspect("//nonexistent", /*applyToFiles=*/ true);
    setRulesAndAspectsAvailableInTests(ImmutableList.of(aspect), ImmutableList.of());
    scratch.file("a/BUILD", "exports_files(['a.txt'])");
    scratch.file("a/a.txt", "hello");

    AnalysisResult analysisResult =
        update(new EventBus(), defaultFlags(), ImmutableList.of(aspect.getName()), "//a:a.txt");

    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    assertThat(configuredAspect.getProvider(ExtraAttributeAspect.Provider.class)).isNull();
  }

  @Test
  public void aspectWithExtraAttributeApplyToFilesAndNot_outputFile_onlyApplyToFilesIsResolved()
      throws Exception {
    ExtraAttributeAspect aspectApplies =
        new ExtraAttributeAspect("//extra", /*applyToFiles=*/ true);
    ExtraAttributeAspect aspectDoesNotApply =
        new ExtraAttributeAspect("//nonexistent", /*applyToFiles=*/ false);
    setRulesAndAspectsAvailableInTests(
        ImmutableList.of(aspectApplies, aspectDoesNotApply),
        ImmutableList.of(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE));
    scratch.file("extra/BUILD", "simple(name='extra')");
    scratch.file("a/BUILD", "genrule(name='gen_a', outs=['a'], cmd='touch $@')");

    AnalysisResult analysisResult =
        update(
            new EventBus(),
            defaultFlags(),
            ImmutableList.of(aspectApplies.getName(), aspectDoesNotApply.getName()),
            "//a");

    assertThat(analysisResult.getAspectsMap()).hasSize(2);
    ExtraAttributeAspect.Provider provider =
        getAspectByName(analysisResult.getAspectsMap(), aspectApplies.getName())
            .getProvider(ExtraAttributeAspect.Provider.class);
    assertThat(provider.label()).isEqualTo("//extra:extra");
    assertThat(
            getAspectByName(analysisResult.getAspectsMap(), aspectDoesNotApply.getName())
                .getProviders()
                .getProviderCount())
        .isEqualTo(0);
  }

  @Test
  public void aspectWithExtraAttributeDependsOnNotApplicable_usesAttributeFromDependentAspect()
      throws Exception {
    ExtraAttributeAspect aspectApplies =
        new ExtraAttributeAspect(
            "//extra", /*applyToFiles=*/ true, ExtraAttributeAspect.Provider.class);
    ExtraAttributeAspect aspectDoesNotApply =
        new ExtraAttributeAspect("//extra:extra2", /*applyToFiles=*/ false);
    setRulesAndAspectsAvailableInTests(
        ImmutableList.of(aspectApplies, aspectDoesNotApply),
        ImmutableList.of(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE));
    scratch.file("extra/BUILD", "simple(name='extra')", "simple(name='extra2')");
    scratch.file("a/BUILD", "genrule(name='gen_a', outs=['a'], cmd='touch $@')");

    AnalysisResult analysisResult =
        update(
            new EventBus(),
            defaultFlags(),
            ImmutableList.of(aspectDoesNotApply.getName(), aspectApplies.getName()),
            "//a");

    assertThat(analysisResult.getAspectsMap()).hasSize(2);
    ExtraAttributeAspect.Provider provider =
        getAspectByName(analysisResult.getAspectsMap(), aspectApplies.getName())
            .getProvider(ExtraAttributeAspect.Provider.class);
    assertThat(provider.label()).isEqualTo("//extra:extra2");
    assertThat(
            getAspectByName(analysisResult.getAspectsMap(), aspectDoesNotApply.getName())
                .getProviders()
                .getProviderCount())
        .isEqualTo(0);
  }

  @Test
  public void sameConfiguredAttributeOnAspectAndRule() throws Exception {
    scratch.file(
        "a/a.bzl",
        "def _a_impl(t, ctx):",
        "  return [DefaultInfo()]",
        "def _r_impl(ctx):",
        "  return [DefaultInfo()]",
        "a = aspect(",
        "  implementation = _a_impl,",
        "  attrs = {'_f': attr.label(",
        "                   default = configuration_field(",
        "                     fragment = 'cpp', name = 'cc_toolchain'))})",
        "r = rule(",
        "  implementation = _r_impl,",
        "  attrs = {'_f': attr.label(",
        "                   default = configuration_field(",
        "                     fragment = 'cpp', name = 'cc_toolchain')),",
        "           'dep': attr.label(aspects=[a])})");

    scratch.file("a/BUILD", "load(':a.bzl', 'r')", "r(name='r')");

    setRulesAndAspectsAvailableInTests(ImmutableList.of(), ImmutableList.of());
    getConfiguredTarget("//a:r");
  }

  @Test
  public void topLevelConflictDetected() throws Exception {
    String bzlFileTemplate =
        String.join(
            "\n",
            "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(files = [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 \"%s\" > ' + outfile.path,",
            "  )",
            "  return [OutputGroupInfo(files = [outfile])]",
            "aspect1 = aspect(implementation = _aspect1_impl)",
            "aspect2 = aspect(implementation = _aspect2_impl)");
    scratch.file("foo/aspect.bzl", String.format(bzlFileTemplate, "2"));
    scratch.file("foo/BUILD", "sh_library(name = 'foo', srcs = ['foo.sh'])");
    // Expect errors.
    reporter.removeHandler(failFastHandler);
    ViewCreationFailedException exception =
        assertThrows(
            ViewCreationFailedException.class,
            () ->
                update(
                    new EventBus(),
                    defaultFlags(),
                    ImmutableList.of("//foo:aspect.bzl%aspect1", "//foo:aspect.bzl%aspect2"),
                    "//foo:foo"));
    assertThat(exception)
        .hasMessageThat()
        .containsMatch(
            "ConflictException: for foo/aspect.out, previous action: action 'Action for aspect .',"
                + " attempted action: action 'Action for aspect .'");
    MoreAsserts.assertContainsEvent(
        eventCollector,
        Pattern.compile(
            "Aspects: \\[//foo:aspect.bzl%aspect[12]], \\[//foo:aspect.bzl%aspect[12]]"),
        EventKind.ERROR);

    // Fix bzl file so actions are shared: analysis should succeed now.
    scratch.overwriteFile("foo/aspect.bzl", String.format(bzlFileTemplate, "1"));
    reporter.addHandler(failFastHandler);
    AnalysisResult result =
        update(
            new EventBus(),
            defaultFlags(),
            ImmutableList.of("//foo:aspect.bzl%aspect1", "//foo:aspect.bzl%aspect2"),
            "//foo:foo");
    assertThat(result.getAspectsMap()).hasSize(2);

    // Break bzl file again: we should notice.
    scratch.overwriteFile("foo/aspect.bzl", String.format(bzlFileTemplate, "2"));
    // Expect errors.
    reporter.removeHandler(failFastHandler);
    exception =
        assertThrows(
            ViewCreationFailedException.class,
            () ->
                update(
                    new EventBus(),
                    defaultFlags(),
                    ImmutableList.of("//foo:aspect.bzl%aspect1", "//foo:aspect.bzl%aspect2"),
                    "//foo:foo"));
    assertThat(exception)
        .hasMessageThat()
        .containsMatch(
            "ConflictException: for foo/aspect.out, previous action: action 'Action for aspect .',"
                + " attempted action: action 'Action for aspect .'");
  }

  @Test
  public void conflictBetweenTargetAndAspect() throws Exception {
    scratch.file(
        "foo/aspect.bzl",
        "def _aspect_impl(target, ctx):",
        "  outfile = ctx.actions.declare_file('conflict.out')",
        "  ctx.actions.run_shell(",
        "    outputs = [outfile],",
        "    progress_message = 'Action for aspect',",
        "    command = 'echo \"aspect\" > ' + outfile.path,",
        "  )",
        "  return [OutputGroupInfo(files = [outfile])]",
        "",
        "def _rule_impl(ctx):",
        "  outfile = ctx.actions.declare_file('conflict.out')",
        "  ctx.actions.run_shell(",
        "    outputs = [outfile],",
        "    progress_message = 'Action for target',",
        "    command = 'echo \"target\" > ' + outfile.path,",
        "  )",
        "  return [DefaultInfo(files = depset([outfile]))]",
        "my_aspect = aspect(implementation = _aspect_impl)",
        "my_rule = rule(implementation = _rule_impl, attrs = {'deps' : attr.label_list(aspects ="
            + " [my_aspect])})");
    scratch.file(
        "foo/BUILD",
        "load('//foo:aspect.bzl', 'my_aspect', 'my_rule')",
        "my_rule(name = 'foo', deps = [':dep'])",
        "sh_library(name = 'dep', srcs = ['dep.sh'])");
    // Expect errors.
    reporter.removeHandler(failFastHandler);
    ViewCreationFailedException exception =
        assertThrows(ViewCreationFailedException.class, () -> update("//foo:foo"));
    assertThat(exception).hasMessageThat().containsMatch("ConflictException: for foo/conflict.out");
    MoreAsserts.assertContainsEvent(
        eventCollector,
        Pattern.compile(
            "Aspects: (\\[], \\[//foo:aspect.bzl%my_aspect]|\\[//foo:aspect.bzl%my_aspect], \\[])"),
        EventKind.ERROR);
  }

  @Test
  public void aspectDuplicatesRuleProviderError() throws Exception {
    setRulesAndAspectsAvailableInTests(ImmutableList.of(), ImmutableList.of());
    scratch.file(
        "aspect/build_defs.bzl",
        "def _aspect_impl(target, ctx):",
        "    return [DefaultInfo()]",
        "",
        "returns_default_info_aspect = aspect(implementation = _aspect_impl)",
        "",
        "def _rule_impl(ctx):",
        "    pass",
        "",
        "duplicate_provider_aspect_applying_rule = rule(",
        "    implementation = _rule_impl,",
        "    attrs = {'to': attr.label(aspects = [returns_default_info_aspect])},",
        ")");
    scratch.file(
        "aspect/BUILD",
        "load('build_defs.bzl', 'duplicate_provider_aspect_applying_rule')",
        "cc_library(name = 'rule_target')",
        "duplicate_provider_aspect_applying_rule(name='applies_aspect', to=':rule_target')");
    assertThat(
            assertThrows(
                AssertionError.class, () -> getConfiguredTarget("//aspect:applies_aspect")))
        .hasMessageThat()
        .contains("Provider DefaultInfo provided twice");
  }

  @Test
  public void instrumentedFilesInfoFromBaseRuleAndAspectUsesAspect() throws Exception {
    scratch.file(
        "aspect/build_defs.bzl",
        "def _instrumented_files_info_aspect_impl(target, ctx):",
        "    return [coverage_common.instrumented_files_info(ctx, source_attributes=['a'])]",
        "",
        "instrumented_files_info_aspect = aspect(",
        "    implementation = _instrumented_files_info_aspect_impl,",
        ")",
        "",
        "def _no_instrumented_files_info_aspect_impl(target, ctx):",
        "    return []",
        "",
        "no_instrumented_files_info_aspect = aspect(",
        "    implementation = _no_instrumented_files_info_aspect_impl,",
        ")",
        "",
        "def _applies_aspect_impl(ctx):",
        "    return coverage_common.instrumented_files_info(ctx, dependency_attributes=['to'])",
        "",
        "instrumented_files_info_aspect_rule = rule(",
        "    implementation = _applies_aspect_impl,",
        "    attrs = {'to': attr.label(aspects = [instrumented_files_info_aspect])},",
        ")",
        "",
        "no_instrumented_files_info_aspect_rule = rule(",
        "    implementation = _applies_aspect_impl,",
        "    attrs = {'to': attr.label(aspects = [no_instrumented_files_info_aspect])},",
        ")",
        "",
        "def _base_rule_impl(ctx):",
        "    return [coverage_common.instrumented_files_info(ctx, source_attributes=['b'])]",
        "",
        "base_rule = rule(",
        "    implementation = _base_rule_impl,",
        "    attrs = {'a': attr.label(allow_files=True), 'b': attr.label(allow_files=True)},",
        ")",
        "",
        "def _base_rule_no_coverage_impl(ctx):",
        "    return []",
        "",
        "base_rule_no_coverage = rule(",
        "    implementation = _base_rule_no_coverage_impl,",
        "    attrs = {'a': attr.label(allow_files=True), 'b': attr.label(allow_files=True)},",
        ")");
    scratch.file(
        "aspect/BUILD",
        "load(",
        "    'build_defs.bzl',",
        "    'base_rule',",
        "    'base_rule_no_coverage',",
        "    'instrumented_files_info_aspect_rule',",
        "    'no_instrumented_files_info_aspect_rule',",
        ")",
        "",
        "base_rule(",
        "    name = 'rule_target',",
        // Ends up in coverage sources when instrumented_files_info_aspect is applied
        "    a = 'a',",
        // Ends up in coverage sources for the base rule's InstrumentedFilesInfo is used
        "    b = 'b',",
        ")",
        "",
        "instrumented_files_info_aspect_rule(",
        "    name='duplicate_instrumented_file_info',",
        "    to=':rule_target',",
        ")",
        "",
        "no_instrumented_files_info_aspect_rule(",
        "    name='instrumented_file_info_from_base_target',",
        "    to=':rule_target',",
        ")",
        "",
        "base_rule_no_coverage(",
        "    name = 'rule_target_no_coverage',",
        // Ends up in coverage sources when instrumented_files_info_aspect is applied
        "    a = 'a',",
        // Ends up in coverage sources never
        "    b = 'b',",
        ")",
        "",
        "instrumented_files_info_aspect_rule(",
        "    name='instrumented_files_info_only_from_aspect',",
        "    to=':rule_target_no_coverage',",
        ")",
        "",
        "no_instrumented_files_info_aspect_rule(",
        "    name='no_instrumented_files_info',",
        "    to=':rule_target_no_coverage',",
        ")");
    useConfiguration("--collect_code_coverage", "--instrumentation_filter=.*");
    update();
    assertThat(getInstrumentedFiles("//aspect:rule_target")).containsExactly("b");
    assertThat(getInstrumentedFiles("//aspect:duplicate_instrumented_file_info"))
        .containsExactly("a");
    assertThat(getInstrumentedFiles("//aspect:instrumented_file_info_from_base_target"))
        .containsExactly("b");
    assertThat(getInstrumentedFiles("//aspect:rule_target_no_coverage")).isEmpty();
    assertThat(getInstrumentedFiles("//aspect:instrumented_files_info_only_from_aspect"))
        .containsExactly("a");
    assertThat(getInstrumentedFiles("//aspect:no_instrumented_files_info")).isEmpty();
  }

  private List<String> getInstrumentedFiles(String label) throws InterruptedException {
    return ActionsTestUtil.baseArtifactNames(
        getConfiguredTarget(label)
            .get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR)
            .getInstrumentedFiles());
  }

  @Test
  public void aspectSeesAspectHintsAttributeOnNativeRule() throws Exception {
    useConfiguration("--experimental_enable_aspect_hints");
    setupAspectHints();
    scratch.file(
        "aspect_hints/BUILD",
        "load('//aspect_hints:hints_counter.bzl', 'count_hints')",
        "load('//aspect_hints:hints.bzl', 'hint')",
        "",
        "hint(name = 'my_hint', hints_cnt = 3)",
        "cc_library(name = 'lib1', deps = [':lib2'])",
        "cc_library(name = 'lib2', aspect_hints = [':my_hint'])",
        "count_hints(name = 'cnt', deps = [':lib1'])");
    update();

    ConfiguredTarget a = getConfiguredTarget("//aspect_hints:cnt");
    StarlarkInt info = (StarlarkInt) getHintsCntInfo(a).getValue("cnt");

    assertThat(info.truncateToInt()).isEqualTo(3);
  }

  @Test
  public void aspectSeesAspectHintsAttributeOnStarlarkRule() throws Exception {
    useConfiguration("--experimental_enable_aspect_hints");
    setupAspectHints();
    setupStarlarkRule();
    scratch.file(
        "aspect_hints/BUILD",
        "load('//aspect_hints:hints_counter.bzl', 'count_hints')",
        "load('//aspect_hints:custom_rule.bzl', 'custom_rule')",
        "load('//aspect_hints:hints.bzl', 'hint')",
        "",
        "hint(name = 'my_hint', hints_cnt = 2)",
        "custom_rule(name = 'lib1', deps = [':lib2'])",
        "custom_rule(name = 'lib2', aspect_hints = [':my_hint'])",
        "count_hints(name = 'cnt', deps = [':lib1'])");
    update();

    ConfiguredTarget a = getConfiguredTarget("//aspect_hints:cnt");
    StarlarkInt info = (StarlarkInt) getHintsCntInfo(a).getValue("cnt");

    assertThat(info.truncateToInt()).isEqualTo(2);
  }

  private void setupAspectHints() throws Exception {
    scratch.file(
        "aspect_hints/hints.bzl",
        "HintInfo = provider(fields = ['hints_cnt'])",
        "def _hint_impl(ctx):",
        "    return [HintInfo(hints_cnt = ctx.attr.hints_cnt)]",
        "",
        "hint = rule(",
        "    implementation = _hint_impl,",
        "    attrs = {'hints_cnt': attr.int(default=0)},",
        ")");
    scratch.file(
        "aspect_hints/hints_counter.bzl",
        "load('//aspect_hints:hints.bzl', 'HintInfo')",
        "HintsCntInfo = provider(fields = ['cnt'])",
        "",
        "def _my_aspect_impl(target, ctx):",
        "    transitive_hints = 0",
        "    for dep in ctx.rule.attr.deps:",
        "        transitive_hints = transitive_hints + dep[HintsCntInfo].cnt",
        "",
        "    hints = 0",
        "    for hint in ctx.rule.attr.aspect_hints:",
        "        hints = hints + hint[HintInfo].hints_cnt",
        "",
        "    return [HintsCntInfo(cnt = hints + transitive_hints)]",
        "",
        "my_aspect = aspect(",
        "    implementation = _my_aspect_impl,",
        "    attr_aspects = ['deps'],",
        ")",
        "",
        "def _count_hints_impl(ctx):",
        "    hints = 0",
        "    for dep in ctx.attr.deps:",
        "        hints = hints + dep[HintsCntInfo].cnt",
        "    return [HintsCntInfo(cnt = hints)]",
        "",
        "count_hints = rule(",
        "    implementation = _count_hints_impl,",
        "    attrs = {",
        "        'deps': attr.label_list(aspects = [my_aspect])",
        "    }",
        ")");
  }

  private void setupStarlarkRule() throws Exception {
    scratch.file(
        "aspect_hints/custom_rule.bzl",
        "def _custom_rule_impl(ctx):",
        "    return []",
        "",
        "custom_rule = rule(",
        "    implementation = _custom_rule_impl,",
        "    attrs = {",
        "        'deps': attr.label_list(),",
        "    },",
        ")");
  }

  private static StructImpl getHintsCntInfo(ConfiguredTarget configuredTarget)
      throws LabelSyntaxException {
    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseCanonical("//aspect_hints:hints_counter.bzl"), "HintsCntInfo");
    return (StructImpl) configuredTarget.get(key);
  }

  private static ConfiguredAspect getAspectByName(
      ImmutableMap<AspectKey, ConfiguredAspect> aspectMap, String name) {
    return aspectMap.entrySet().stream()
        .filter(e -> e.getKey().getAspectName().equals(name))
        .map(Map.Entry::getValue)
        .collect(onlyElement());
  }
}
