// 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.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(
          Label targetLabel,
          ConfiguredTarget ct,
          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.createFactory())
                                    .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(
          Label targetLabel,
          ConfiguredTarget ct,
          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.parseCanonicalUnchecked("//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 aspectApplyingToPackageGroupIgnored() throws Exception {
    AspectApplyingToFiles aspectApplyingToFiles = new AspectApplyingToFiles();
    setRulesAndAspectsAvailableInTests(ImmutableList.of(aspectApplyingToFiles), ImmutableList.of());
    pkg("b");
    pkg(
        "a",
        "package_group(name = 'group', packages = ['//b'])",
        "java_binary(name = 'x', main_class = 'x.F', srcs = ['x.java'], visibility = [':group'])");
    scratch.file("a/x.java", "");

    // This exercises a code path that crashes if the PackageGroup is matched as an aspect provider.
    AnalysisResult analysisResult =
        update(
            new EventBus(),
            defaultFlags(),
            ImmutableList.of(aspectApplyingToFiles.getName()),
            "//a:group");
    assertThat(analysisResult.getAspectsMap()).hasSize(1);
  }

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