// 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.starlark;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.Streams.stream;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.devtools.build.lib.analysis.OutputGroupInfo.INTERNAL_SUFFIX;
import static java.util.stream.Collectors.toList;
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.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.AnalysisResult;
import com.google.devtools.build.lib.analysis.AspectValue;
import com.google.devtools.build.lib.analysis.ConfiguredAspect;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
import com.google.devtools.build.lib.analysis.util.TestAspects;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.AspectClass;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.StarlarkAspectClass;
import com.google.devtools.build.lib.packages.StarlarkInfo;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
import com.google.devtools.build.lib.server.FailureDetails.Analysis;
import com.google.devtools.build.lib.server.FailureDetails.Analysis.Code;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectKey;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkInt;
import net.starlark.java.eval.StarlarkList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for Starlark aspects */
@RunWith(JUnit4.class)
public class StarlarkDefinedAspectsTest extends AnalysisTestCase {
  protected boolean keepGoing() {
    return false;
  }

  @Test
  public void simpleAspect() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           print('This aspect does nothing')
           return []
        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    assertThat(getAspectDescriptions(analysisResult))
        .containsExactly("//test:aspect.bzl%MyAspect(//test:xxx)");
  }

  @Test
  public void aspectWithSingleDeclaredProvider() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        foo = provider()
        def _impl(target, ctx):
           return foo()
        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    assertThat(getAspectDescriptions(analysisResult))
        .containsExactly("//test:aspect.bzl%MyAspect(//test:xxx)");
    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());

    StarlarkProvider.Key fooKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "foo");

    assertThat(configuredAspect.get(fooKey).getProvider().getKey()).isEqualTo(fooKey);
  }

  @Test
  public void aspectWithDeclaredProviders() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        foo = provider()
        bar = provider()
        def _impl(target, ctx):
           return [foo(), bar()]
        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    assertThat(getAspectDescriptions(analysisResult))
        .containsExactly("//test:aspect.bzl%MyAspect(//test:xxx)");
    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());

    StarlarkProvider.Key fooKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "foo");
    StarlarkProvider.Key barKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "bar");

    assertThat(configuredAspect.get(fooKey).getProvider().getKey()).isEqualTo(fooKey);
    assertThat(configuredAspect.get(barKey).getProvider().getKey()).isEqualTo(barKey);
  }

  @Test
  public void aspectWithDeclaredProvidersInAStruct() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        foo = provider()
        bar = provider()
        def _impl(target, ctx):
           return [foo(), bar()]
        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    assertThat(getAspectDescriptions(analysisResult))
        .containsExactly("//test:aspect.bzl%MyAspect(//test:xxx)");

    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());

    StarlarkProvider.Key fooKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "foo");
    StarlarkProvider.Key barKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "bar");

    assertThat(configuredAspect.get(fooKey).getProvider().getKey()).isEqualTo(fooKey);
    assertThat(configuredAspect.get(barKey).getProvider().getKey()).isEqualTo(barKey);
  }

  private static Iterable<String> getAspectDescriptions(AnalysisResult analysisResult) {
    return Iterables.transform(
        analysisResult.getAspectsMap().keySet(),
        aspectKey ->
            String.format("%s(%s)", aspectKey.getAspectClass().getName(), aspectKey.getLabel()));
  }

  @Test
  public void aspectCommandLineLabel() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           print('This aspect does nothing')
           return []
        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    AnalysisResult analysisResult =
        update(ImmutableList.of("//test:aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    assertThat(getAspectDescriptions(analysisResult))
        .containsExactly("//test:aspect.bzl%MyAspect(//test:xxx)");
  }

  @Test
  public void aspectCommandLineRepoLabel() throws Exception {
    scratch.overwriteFile(
        "WORKSPACE",
        scratch.readFile("WORKSPACE"),
        "local_repository(name='local', path='local/repo')");
    scratch.file("local/repo/WORKSPACE");
    scratch.file(
        "local/repo/aspect.bzl",
        """
        def _impl(target, ctx):
           print('This aspect does nothing')
           return []
        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("local/repo/BUILD");

    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    AnalysisResult analysisResult =
        update(ImmutableList.of("@local//:aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    assertThat(getAspectDescriptions(analysisResult))
        .containsExactly("@@local//:aspect.bzl%MyAspect(//test:xxx)");
  }

  private static Iterable<String> getLabelsToBuild(AnalysisResult analysisResult) {
    return Iterables.transform(
        analysisResult.getTargetsToBuild(),
        configuredTarget -> configuredTarget.getLabel().toString());
  }

  @Test
  public void aspectAllowsFragmentsToBeSpecified() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           print('This aspect does nothing')
           return []
        MyAspect = aspect(implementation=_impl, fragments=['java'])
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");

    AspectKey key = Iterables.getOnlyElement(analysisResult.getAspectsMap().keySet());
    AspectValue aspectValue = (AspectValue) skyframeExecutor.getEvaluator().getExistingValue(key);
    AspectDefinition aspectDefinition = aspectValue.getAspect().getDefinition();
    assertThat(
            aspectDefinition
                .getConfigurationFragmentPolicy()
                .isLegalConfigurationFragment(JavaConfiguration.class))
        .isTrue();
    assertThat(
            aspectDefinition
                .getConfigurationFragmentPolicy()
                .isLegalConfigurationFragment(CppConfiguration.class))
        .isFalse();
  }

  @Test
  public void aspectPropagating() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
Info = provider()
def _impl(target, ctx):
   s = depset([target.label], transitive = [i[Info].target_labels for i in ctx.rule.attr.deps])
   c = depset([ctx.rule.kind], transitive = [i[Info].rule_kinds for i in ctx.rule.attr.deps])
   return Info(target_labels = s, rule_kinds = c)

MyAspect = aspect(
   implementation=_impl,
   attr_aspects=['deps'],
)
""");
    scratch.file(
        "test/BUILD",
        """
        java_library(
             name = 'yyy',
        )
        java_library(
             name = 'xxx',
             srcs = ['A.java'],
             deps = [':yyy'],
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    ConfiguredAspect configuredAspect = analysisResult.getAspectsMap().values().iterator().next();
    assertThat(configuredAspect).isNotNull();
    StarlarkInfo info = getStarlarkProvider(configuredAspect, "//test:aspect.bzl", "Info");
    NestedSet<Label> names =
        Depset.cast(info.getValue("target_labels"), Label.class, "target_labels");
    assertThat(names.toList().stream().map(Label::toString))
        .containsExactly("//test:xxx", "//test:yyy");
    Object ruleKinds =
        getStarlarkProvider(configuredAspect, "//test:aspect.bzl", "Info").getValue("rule_kinds");
    assertThat(ruleKinds).isInstanceOf(Depset.class);
    assertThat(((Depset) ruleKinds).toList()).containsExactly("java_library");
  }

  @Test
  public void aspectsPropagatingForDefaultAndImplicit() throws Exception {
    useConfiguration(
        "--experimental_builtins_injection_override=+cc_library",
        "--incompatible_enable_cc_toolchain_resolution");
    scratch.file(
        "test/aspect.bzl",
        """
        Info = provider()
        def _impl(target, ctx):
           s = []
           c = []
           a = ctx.rule.attr
           if getattr(a, '_defaultattr', None):
               s += [a._defaultattr[Info].target_labels]
               c += [a._defaultattr[Info].rule_kinds]
           if getattr(a, '_cc_toolchain', None):
               s += [a._cc_toolchain[Info].target_labels]
               c += [a._cc_toolchain[Info].rule_kinds]
           return Info(
               target_labels = depset([target.label], transitive = s),
               rule_kinds = depset([ctx.rule.kind], transitive = c))

        def _rule_impl(ctx):
           pass

        my_rule = rule(implementation = _rule_impl,
           attrs = { '_defaultattr' : attr.label(default = Label('//test:xxx')) },
        )
        MyAspect = aspect(
           implementation=_impl,
           attr_aspects=['_defaultattr', '_cc_toolchain'],
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        cc_library(
             name = 'xxx',
        )
        my_rule(
             name = 'yyy',
        )
        """);
    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:yyy");
    ConfiguredAspect configuredAspect = analysisResult.getAspectsMap().values().iterator().next();
    assertThat(configuredAspect).isNotNull();
    StarlarkProvider.Key infoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "Info");
    Object nameSet = ((StarlarkInfo) configuredAspect.get(infoKey)).getValue("target_labels");
    ImmutableList<String> names =
        ImmutableList.copyOf(
            Iterables.transform(
                ((Depset) nameSet).toList(),
                o -> {
                  assertThat(o).isInstanceOf(Label.class);
                  return ((Label) o).getName();
                }));

    assertThat(names).containsAtLeast("xxx", "yyy");
  }

  @Test
  public void aspectsDirOnMergedTargets() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        Info = provider()
        def _impl(target, ctx):
           return Info(aspect_provider = 'data')

        p = provider()
        MyAspect = aspect(implementation=_impl)
        def _rule_impl(ctx):
           if ctx.attr.dep:
              return [p(dir = dir(ctx.attr.dep))]
           return [p()]

        my_rule = rule(implementation = _rule_impl,
           attrs = { 'dep' : attr.label(aspects = [MyAspect]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx',)
        my_rule(name = 'yyy', dep = ':xxx')
        """);
    AnalysisResult analysisResult = update("//test:yyy");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());

    StructImpl names = getStarlarkProvider(target, "p");
    assertThat((Iterable<?>) names.getValue("dir"))
        .containsExactly(
            "actions",
            "data_runfiles",
            "default_runfiles",
            "files",
            "files_to_run",
            "label",
            "output_groups");
  }

  @Test
  public void aspectWithOutputGroupsDeclaredProvider() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        "def _impl(target, ctx):",
        "   f = target[OutputGroupInfo]._hidden_top_level" + INTERNAL_SUFFIX,
        "   return [OutputGroupInfo(my_result = f)]",
        "",
        "MyAspect = aspect(",
        "   implementation=_impl,",
        ")");
    scratch.file(
        "test/BUILD",
        """
        java_library(
             name = 'xxx',
             srcs = ['A.java'],
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    ConfiguredAspect configuredAspect = analysisResult.getAspectsMap().values().iterator().next();
    OutputGroupInfo outputGroupInfo = OutputGroupInfo.get(configuredAspect);

    assertThat(outputGroupInfo).isNotNull();
    NestedSet<Artifact> names = outputGroupInfo.getOutputGroup("my_result");
    assertThat(names.toList()).isNotEmpty();

    // Configuration of the true Artifact may diverge slightly (e.g. be trimmed) causing owners to
    // also diverge so just compare paths instead of the whole Artifact.
    ImmutableList<Path> paths =
        names.toList().stream().map(Artifact::getPath).collect(toImmutableList());
    ImmutableList<Path> expectedPaths =
        OutputGroupInfo.get(getConfiguredTarget("//test:xxx"))
            .getOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL)
            .toList()
            .stream()
            .map(Artifact::getPath)
            .collect(toImmutableList());
    assertThat(paths).containsExactlyElementsIn(expectedPaths);
  }

  @Test
  public void aspectWithOutputGroupsAsListDeclaredProvider() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        "def _impl(target, ctx):",
        "   g = target[OutputGroupInfo]._hidden_top_level" + INTERNAL_SUFFIX,
        "   return [OutputGroupInfo(my_result=g.to_list())]",
        "",
        "MyAspect = aspect(",
        "   implementation=_impl,",
        ")");
    scratch.file(
        "test/BUILD",
        """
        java_library(
             name = 'xxx',
             srcs = ['A.java'],
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(
            Iterables.transform(
                analysisResult.getTargetsToBuild(),
                configuredTarget -> configuredTarget.getLabel().toString()))
        .containsExactly("//test:xxx");
    ConfiguredAspect configuredAspect = analysisResult.getAspectsMap().values().iterator().next();
    OutputGroupInfo outputGroupInfo = OutputGroupInfo.get(configuredAspect);
    assertThat(outputGroupInfo).isNotNull();
    NestedSet<Artifact> names = outputGroupInfo.getOutputGroup("my_result");
    assertThat(names.toList()).isNotEmpty();

    // Configuration of the true Artifact may diverge slightly (e.g. be trimmed) causing owners to
    // also diverge so just compare paths instead of the whole Artifact.
    ImmutableList<Path> paths =
        names.toList().stream().map(Artifact::getPath).collect(toImmutableList());
    ImmutableList<Path> expectedPaths =
        OutputGroupInfo.get(getConfiguredTarget("//test:xxx"))
            .getOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL)
            .toList()
            .stream()
            .map(Artifact::getPath)
            .collect(toImmutableList());
    assertThat(paths).containsExactlyElementsIn(expectedPaths);
  }

  @Test
  public void aspectsFromStarlarkRules() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
AspectInfo = provider()
def _aspect_impl(target, ctx):
   s = depset([target.label], transitive =
       [i[AspectInfo].target_labels for i in ctx.rule.attr.deps])
   return AspectInfo(target_labels = s)

TargetInfo = provider()
def _rule_impl(ctx):
   s = depset(transitive = [i[AspectInfo].target_labels for i in ctx.attr.attr])
   return TargetInfo(rule_deps = s)

MyAspect = aspect(
   implementation=_aspect_impl,
   attr_aspects=['deps'],
)
my_rule = rule(
   implementation=_rule_impl,
   attrs = { 'attr' :
             attr.label_list(mandatory=True, allow_files=True, aspects = [MyAspect]) },
)
""");

    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        java_library(
             name = 'yyy',
        )
        my_rule(
             name = 'xxx',
             attr = [':yyy'],
        )
        """);

    AnalysisResult analysisResult = update("//test:xxx");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:xxx");
    ConfiguredTarget target = analysisResult.getTargetsToBuild().iterator().next();
    NestedSet<Label> names =
        Depset.cast(
            getStarlarkProvider(target, "TargetInfo").getValue("rule_deps", Depset.class),
            Label.class,
            "rule_deps");
    assertThat(names.toList().stream().map(Label::toString)).containsExactly("//test:yyy");
  }

  @Test
  public void aspectsNonExported() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _aspect_impl(target, ctx):
           return []

        def _rule_impl(ctx):
           pass

        def mk_aspect():
           return aspect(implementation=_aspect_impl)
        my_rule = rule(
           implementation=_rule_impl,
           attrs = { 'attr' : attr.label_list(aspects = [mk_aspect()]) },  # line 11
        )
        """);

    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        java_library(
             name = 'yyy',
        )
        my_rule(
             name = 'xxx',
             attr = [':yyy'],
        )
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult analysisResult = update("//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(analysisResult.hasError()).isTrue();
    } catch (ViewCreationFailedException | TargetParsingException e) {
      // expected
    }

    // attr.label_list() fails, stack=[<toplevel>@rules.bzl:11:38, label_list:<builtin>]
    assertContainsEvent("File \"/workspace/test/aspect.bzl\", line 11, column 38, in <toplevel>");
    assertContainsEvent(
        "Error in label_list: Aspects should be top-level values in extension files that define"
            + " them.");
  }

  @Test
  @SuppressWarnings("EmptyCatchBlock")
  public void aspectReturnsNonExportedProvider() throws Exception {
    scratch.file(
        "test/inc.bzl",
        """
        a = aspect(implementation = lambda target, ctx: [provider()()])
        r = rule(
          implementation = lambda ctx: [],
          attrs = {'a': attr.label_list(aspects = [a])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:inc.bzl', 'r')
        java_library(name = 'j')
        r(name = 'test', a = [':j'])
        """);

    reporter.removeHandler(failFastHandler);
    try {
      update("//test");
      /* reached if --keep_going=true */
    } catch (ViewCreationFailedException unused) {
      /* reached if --keep_going=false */
    }
    assertContainsEvent(
        "aspect function returned an instance of a provider "
            + "(defined at /workspace/test/inc.bzl:1:58) that is not a global");
  }

  @Test
  public void providerNonExported() throws Exception {
    scratch.file(
        "test/rule.bzl",
        """
        def mk_provider():
           return provider()
        def _rule_impl(ctx):
           pass
        my_rule = rule(
           implementation=_rule_impl,
           attrs = { 'attr' : attr.label_list(providers = [mk_provider()]) },  # line 7
        )
        """);

    scratch.file(
        "test/BUILD",
        """
        load('//test:rule.bzl', 'my_rule')
        java_library(
             name = 'yyy',
        )
        my_rule(
             name = 'xxx',
             attr = [':yyy'],
        )
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult analysisResult = update("//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(analysisResult.hasError()).isTrue();
    } catch (ViewCreationFailedException | TargetParsingException e) {
      // expected
    }

    // attr.label_list() fails, stack=[<toplevel>@rules.bzl:7:38, label_list:<builtin>]
    assertContainsEvent("File \"/workspace/test/rule.bzl\", line 7, column 38, in <toplevel>");
    assertContainsEvent(
        "Error in label_list: Providers should be top-level values in extension files that define"
            + " them.");
  }

  @Test
  public void aspectOnLabelAttr() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
           return AspectInfo(aspect_data='foo')

        RuleInfo = provider()
        def _rule_impl(ctx):
           return RuleInfo(data=ctx.attr.attr[AspectInfo].aspect_data)

        MyAspect = aspect(
           implementation=_aspect_impl,
        )
        my_rule = rule(
           implementation=_rule_impl,
           attrs = { 'attr' :
                     attr.label(aspects = [MyAspect]) },
        )
        """);

    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        java_library(
             name = 'yyy',
        )
        my_rule(
             name = 'xxx',
             attr = ':yyy',
        )
        """);

    AnalysisResult analysisResult = update("//test:xxx");
    ConfiguredTarget target = analysisResult.getTargetsToBuild().iterator().next();
    String value = getStarlarkProvider(target, "RuleInfo").getValue("data", String.class);
    assertThat(value).isEqualTo("foo");
  }

  @Test
  public void labelKeyedStringDictAllowsAspects() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
           return AspectInfo(aspect_data=target.label.name)

        RuleInfo = provider()
        def _rule_impl(ctx):
           return RuleInfo(
               data=','.join(['{}:{}'.format(dep[AspectInfo].aspect_data, val)
                              for dep, val in ctx.attr.attr.items()]))

        MyAspect = aspect(
           implementation=_aspect_impl,
        )
        my_rule = rule(
           implementation=_rule_impl,
           attrs = { 'attr' :
                     attr.label_keyed_string_dict(aspects = [MyAspect]) },
        )
        """);

    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        java_library(
             name = 'yyy',
        )
        my_rule(
             name = 'xxx',
             attr = {':yyy': 'zzz'},
        )
        """);

    AnalysisResult analysisResult = update("//test:xxx");
    ConfiguredTarget target = analysisResult.getTargetsToBuild().iterator().next();
    String value = getStarlarkProvider(target, "RuleInfo").getValue("data", String.class);
    assertThat(value).isEqualTo("yyy:zzz");
  }

  @Test
  public void aspectsDoNotAttachToFiles() throws Exception {
    FileSystemUtils.appendIsoLatin1(
        scratch.resolve("WORKSPACE"), "bind(name = 'yyy', actual = '//test:zzz.jar')");
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []

        MyAspect = aspect(
           implementation=_impl,
           attr_aspects=['deps'],
        )
        """);
    scratch.file("test/zzz.jar");
    scratch.file(
        "test/BUILD",
        """
        exports_files(['zzz.jar'])
        java_library(
             name = 'xxx',
             srcs = ['A.java'],
             deps = ['//external:yyy'],
        )
        """);

    AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(result.hasError()).isFalse();
  }

  @Test
  public void aspectsDoNotAttachToTopLevelFiles() throws Exception {
    FileSystemUtils.appendIsoLatin1(
        scratch.resolve("WORKSPACE"), "bind(name = 'yyy', actual = '//test:zzz.jar')");
    scratch.file(
        "test/aspect.bzl",
        """
        p = provider()
        def _impl(target, ctx):
           return [p()]

        MyAspect = aspect(
           implementation=_impl,
           attr_aspects=['deps'],
        )
        """);
    scratch.file("test/zzz.jar");
    scratch.file(
        "test/BUILD",
        """
        exports_files(['zzz.jar'])
        java_library(
             name = 'xxx',
             srcs = ['A.java'],
             deps = ['//external:yyy'],
        )
        """);

    AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:zzz.jar");
    assertThat(result.hasError()).isFalse();
    assertThat(
            Iterables.getOnlyElement(result.getAspectsMap().values())
                .getProviders()
                .getProviderCount())
        .isEqualTo(0);
  }

  @Test
  public void aspectFailingExecution() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return 1 // 0

        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    // Stack doesn't include source lines because we haven't told EvalException
    // how to read from scratch.
    assertContainsEvent(
        "ERROR /workspace/test/BUILD:1:13: in "
            + "//test:aspect.bzl%MyAspect aspect on java_library rule //test:xxx: \n"
            + "Traceback (most recent call last):\n"
            + "\tFile \"/workspace/test/aspect.bzl\", line 2, column 13, in _impl\n"
            + "Error: integer division by zero");
  }

  @Test
  public void aspectFailingReturnsNotAStruct() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return 0

        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent(
        "Aspect implementation should return a struct, a list, or a provider "
            + "instance, but got int");
  }

  @Test
  public void aspectFailingOrphanArtifacts() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
          ctx.actions.declare_file('missing_in_action.txt')
          return []

        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent(
        "ERROR /workspace/test/BUILD:1:13: in "
            + "//test:aspect.bzl%MyAspect aspect on java_library rule //test:xxx: \n"
            + "The following files have no generating action:\n"
            + "test/missing_in_action.txt");
  }

  @Test
  public void aspectSkippingOrphanArtifactsWithLocation() throws Exception {
    scratch.file(
        "simple/print.bzl",
        """
        Info = provider()
        def _print_expanded_location_impl(target, ctx):
            return Info(result=ctx.expand_location(ctx.rule.attr.cmd, []))

        print_expanded_location = aspect(
            implementation = _print_expanded_location_impl,
        )
        """);
    scratch.file(
        "simple/BUILD",
        """
        filegroup(
            name = "files",
            srcs = ["afile"],
        )

        genrule(
            name = "concat_all_files",
            srcs = [":files"],
            outs = ["concatenated.txt"],
            cmd = "$(location :files)"
        )
        """);

    reporter.removeHandler(failFastHandler);
    AnalysisResult analysisResult =
        update(
            ImmutableList.of("//simple:print.bzl%print_expanded_location"),
            "//simple:concat_all_files");
    assertThat(analysisResult.hasError()).isFalse();
    ConfiguredAspect configuredAspect = analysisResult.getAspectsMap().values().iterator().next();
    String result =
        getStarlarkProvider(configuredAspect, "//simple:print.bzl", "Info")
            .getValue("result", String.class);

    assertThat(result).isEqualTo("simple/afile");
  }

  @Test
  public void expandLocationFailsForTargetsWithSameLabel() throws Exception {
    scratch.overwriteFile(
        "tools/allowlists/function_transition_allowlist/BUILD",
        """
        package_group(
            name = 'function_transition_allowlist',
            packages = [
                '//a/...',
            ],
        )
        """);
    scratch.file(
        "a/defs.bzl",
        "def _transition_impl(settings, attr):",
        "    return {",
        "        'opt': {'//command_line_option:compilation_mode': 'opt'},",
        "        'dbg': {'//command_line_option:compilation_mode': 'dbg'},",
        "    }",
        "split_transition = transition(",
        "    implementation = _transition_impl,",
        "    inputs = [],",
        "    outputs = ['//command_line_option:compilation_mode'])",
        "def _split_deps_rule_impl(ctx):",
        "    pass",
        "split_deps_rule = rule(",
        "    implementation = _split_deps_rule_impl,",
        "    attrs = {",
        "        'my_dep': attr.label(cfg = split_transition),",
        "    })",
        "",
        "Info = provider()",
        "def _print_expanded_location_impl(target, ctx):",
        "    return Info(result=ctx.expand_location('$(location //a:lib)',"
            + " [ctx.rule.attr.my_dep[0], ctx.rule.attr.my_dep[1]]))",
        "",
        "print_expanded_location = aspect(",
        "    implementation = _print_expanded_location_impl,",
        ")");
    scratch.file(
        "a/BUILD",
        """
        load('//a:defs.bzl', 'split_deps_rule')
        cc_library(name = 'lib', srcs = ['lib.cc'])
        split_deps_rule(
            name = 'a',
            my_dep = ':lib')
        """);

    reporter.removeHandler(failFastHandler);

    try {
      AnalysisResult analysisResult =
          update(ImmutableList.of("//a:defs.bzl%print_expanded_location"), "//a");
      assertThat(keepGoing()).isTrue();
      assertThat(analysisResult.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent("Label \"//a:lib\" is found more than once in 'targets' list.");
  }

  @Test
  public void topLevelAspectIsNotAnAspect() throws Exception {
    scratch.file("test/aspect.bzl", "MyAspect = 4");
    scratch.file("test/BUILD", "java_library(name = 'xxx')");

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent("MyAspect from //test:aspect.bzl is not an aspect");
  }

  @Test
  public void duplicateOutputGroups() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
          f = ctx.actions.declare_file('f.txt')
          ctx.actions.write(f, 'f')
          return [OutputGroupInfo(duplicate = depset([f]))]

        MyAspect = aspect(implementation=_impl)
        def _rule_impl(ctx):
          g = ctx.actions.declare_file('g.txt')
          ctx.actions.write(g, 'g')
          return [OutputGroupInfo(duplicate = depset([g]))]
        my_rule = rule(_rule_impl)
        def _noop(ctx):
          pass
        rbase = rule(_noop, attrs = { 'dep' : attr.label(aspects = [MyAspect]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'my_rule', 'rbase')
        my_rule(name = 'xxx')
        rbase(name = 'yyy', dep = ':xxx')
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update("//test:yyy");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent("ERROR /workspace/test/BUILD:3:6: Output group duplicate provided twice");
  }

  @Test
  public void outputGroupsFromOneAspect() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _a1_impl(target, ctx):
          f = ctx.actions.declare_file(target.label.name + '_a1.txt')
          ctx.actions.write(f, 'f')
          return [OutputGroupInfo(a1_group = depset([f]))]

        a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])
        def _rule_impl(ctx):
          if not ctx.attr.dep:
             return []
          og = {k:ctx.attr.dep.output_groups[k] for k in ctx.attr.dep[OutputGroupInfo]}
          return [OutputGroupInfo(**og)]
        my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'my_rule1')
        my_rule1(name = 'base')
        my_rule1(name = 'xxx', dep = ':base')
        """);

    AnalysisResult analysisResult = update("//test:xxx");
    OutputGroupInfo outputGroupInfo =
        OutputGroupInfo.get(Iterables.getOnlyElement(analysisResult.getTargetsToBuild()));
    assertThat(getOutputGroupContents(outputGroupInfo, "a1_group"))
        .containsExactly("test/base_a1.txt");
  }

  @Test
  public void outputGroupsDeclaredProviderFromOneAspect() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _a1_impl(target, ctx):
          f = ctx.actions.declare_file(target.label.name + '_a1.txt')
          ctx.actions.write(f, 'f')
          return [OutputGroupInfo(a1_group = depset([f]))]

        a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])
        def _rule_impl(ctx):
          if not ctx.attr.dep:
             return []
          return [OutputGroupInfo(a1_group = ctx.attr.dep[OutputGroupInfo].a1_group)]
        my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'my_rule1')
        my_rule1(name = 'base')
        my_rule1(name = 'xxx', dep = ':base')
        """);

    AnalysisResult analysisResult = update("//test:xxx");
    OutputGroupInfo outputGroupInfo =
        OutputGroupInfo.get(Iterables.getOnlyElement(analysisResult.getTargetsToBuild()));
    assertThat(getOutputGroupContents(outputGroupInfo, "a1_group"))
        .containsExactly("test/base_a1.txt");
  }

  @Test
  public void outputGroupsFromTwoAspects() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _a1_impl(target, ctx):
          f = ctx.actions.declare_file(target.label.name + '_a1.txt')
          ctx.actions.write(f, 'f')
          return [OutputGroupInfo(a1_group = depset([f]))]

        a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])
        def _rule_impl(ctx):
          if not ctx.attr.dep:
             return []
          og = {k:ctx.attr.dep.output_groups[k] for k in ctx.attr.dep.output_groups}
          return [OutputGroupInfo(**og)]
        my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })
        def _a2_impl(target, ctx):
          g = ctx.actions.declare_file(target.label.name + '_a2.txt')
          ctx.actions.write(g, 'f')
          return [OutputGroupInfo(a2_group = depset([g]))]

        a2 = aspect(implementation=_a2_impl, attr_aspects = ['dep'])
        my_rule2 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a2]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'my_rule1', 'my_rule2')
        my_rule1(name = 'base')
        my_rule1(name = 'xxx', dep = ':base')
        my_rule2(name = 'yyy', dep = ':xxx')
        """);

    AnalysisResult analysisResult = update("//test:yyy");
    OutputGroupInfo outputGroupInfo =
        OutputGroupInfo.get(Iterables.getOnlyElement(analysisResult.getTargetsToBuild()));
    assertThat(getOutputGroupContents(outputGroupInfo, "a1_group"))
        .containsExactly("test/base_a1.txt");
    assertThat(getOutputGroupContents(outputGroupInfo, "a2_group"))
        .containsExactly("test/xxx_a2.txt");
  }

  @Test
  public void outputGroupsDeclaredProvidersFromTwoAspects() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _a1_impl(target, ctx):
          f = ctx.actions.declare_file(target.label.name + '_a1.txt')
          ctx.actions.write(f, 'f')
          return [OutputGroupInfo(a1_group = depset([f]))]

        a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])
        def _rule_impl(ctx):
          if not ctx.attr.dep:
             return []
          og = dict()
          dep_og = ctx.attr.dep[OutputGroupInfo]
          if hasattr(dep_og, 'a1_group'):
             og['a1_group'] = dep_og.a1_group
          if hasattr(dep_og, 'a2_group'):
             og['a2_group'] = dep_og.a2_group
          return [OutputGroupInfo(**og)]
        my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })
        def _a2_impl(target, ctx):
          g = ctx.actions.declare_file(target.label.name + '_a2.txt')
          ctx.actions.write(g, 'f')
          return [OutputGroupInfo(a2_group = depset([g]))]

        a2 = aspect(implementation=_a2_impl, attr_aspects = ['dep'])
        my_rule2 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a2]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'my_rule1', 'my_rule2')
        my_rule1(name = 'base')
        my_rule1(name = 'xxx', dep = ':base')
        my_rule2(name = 'yyy', dep = ':xxx')
        """);

    AnalysisResult analysisResult = update("//test:yyy");
    OutputGroupInfo outputGroupInfo =
        OutputGroupInfo.get(Iterables.getOnlyElement(analysisResult.getTargetsToBuild()));
    assertThat(getOutputGroupContents(outputGroupInfo, "a1_group"))
        .containsExactly("test/base_a1.txt");
    assertThat(getOutputGroupContents(outputGroupInfo, "a2_group"))
        .containsExactly("test/xxx_a2.txt");
  }

  @Test
  public void duplicateOutputGroupsFromTwoAspects() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _a1_impl(target, ctx):
          f = ctx.actions.declare_file(target.label.name + '_a1.txt')
          ctx.actions.write(f, 'f')
          return [OutputGroupInfo(a1_group = depset([f]))]

        a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])
        def _rule_impl(ctx):
          if not ctx.attr.dep:
             return []
          og = {k:ctx.attr.dep.output_groups[k] for k in ctx.attr.dep[OutputGroupInfo]}
          return [OutputGroupInfo(**og)]
        my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })
        def _a2_impl(target, ctx):
          g = ctx.actions.declare_file(target.label.name + '_a2.txt')
          ctx.actions.write(g, 'f')
          return [OutputGroupInfo(a1_group = depset([g]))]

        a2 = aspect(implementation=_a2_impl, attr_aspects = ['dep'])
        my_rule2 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a2]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'my_rule1', 'my_rule2')
        my_rule1(name = 'base')
        my_rule1(name = 'xxx', dep = ':base')
        my_rule2(name = 'yyy', dep = ':xxx')
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult analysisResult = update("//test:yyy");
      assertThat(analysisResult.hasError()).isTrue();
      assertThat(keepGoing()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expected.
    }
    assertContainsEvent("ERROR /workspace/test/BUILD:3:9: Output group a1_group provided twice");
  }

  private static Iterable<String> getOutputGroupContents(
      OutputGroupInfo outputGroupInfo, String groupName) {
    return Iterables.transform(
        outputGroupInfo.getOutputGroup(groupName).toList(), Artifact::getRootRelativePathString);
  }

  @Test
  public void duplicateStarlarkProviders() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        Info = provider()
        def _impl(target, ctx):
          return Info(duplicate = 'x')

        MyAspect = aspect(implementation=_impl)
        def _rule_impl(ctx):
          return Info(duplicate = 'y')
        my_rule = rule(_rule_impl)
        def _noop(ctx):
          pass
        rbase = rule(_noop, attrs = { 'dep' : attr.label(aspects = [MyAspect]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'my_rule', 'rbase')
        my_rule(name = 'xxx')
        rbase(name = 'yyy', dep = ':xxx')
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update("//test:yyy");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent("ERROR /workspace/test/BUILD:3:6: Provider Info provided twice");
  }

  @Test
  public void topLevelAspectDoesNotExist() throws Exception {
    scratch.file("test/aspect.bzl", "");
    scratch.file("test/BUILD", "java_library(name = 'xxx')");

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent("MyAspect is not exported from //test:aspect.bzl");
  }

  @Test
  public void topLevelAspectDoesNotExist2() throws Exception {
    scratch.file("test/BUILD", "java_library(name = 'xxx')");

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent("cannot load '//test:aspect.bzl': no such file");
  }

  @Test
  public void topLevelAspectDoesNotExistNoBuildFile() throws Exception {
    scratch.file("test/BUILD", "java_library(name = 'xxx')");

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of("foo/aspect.bzl%MyAspect"), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
    }
    assertContainsEvent("Every .bzl file must have a corresponding package");
  }

  /**
   * Tests that a loading-level error (missing bzl file) is properly transformed by the configured
   * target that requested the relevant package, and doesn't bubble up to a higher configured
   * target/aspect that wasn't expecting a loading-level error. The complication is that the
   * configured target that depends directly on the error tries to do configuration resolution after
   * noticing the error, and configuration resolution is interruptible, so it is interrupted. It
   * needs to then throw the error, rather than the interruption.
   *
   * <p>This test covers error propagation up to both the configured target that depends on the one
   * in error, as well as the aspect on that configured target, since the error goes through both.
   */
  @Test
  public void aspectBaseConfiguredTargetTransitivelyDependingOnPackageInError() throws Exception {
    setRulesAndAspectsAvailableInTests(ImmutableList.of(), ImmutableList.of());
    scratch.overwriteFile(
        "tools/allowlists/function_transition_allowlist/BUILD",
        "package_group(name = 'function_transition_allowlist', packages = ['//aspect/...'])");
    scratch.file(
        "aspect/aspect.bzl",
        """
        def _setting_impl(ctx):
          return []

        string_flag = rule(
          implementation = _setting_impl,
          build_setting = config.string(flag=True),
        )

        def _rule_impl(ctx):
          pass

        def _transition_impl(settings, attr):
          return {'//aspect:formation': 'mesa'}

        formation_transition = transition(
          implementation = _transition_impl,
          inputs = ['//aspect:formation'],
          outputs = ['//aspect:formation'],
        )

        def _aspect_impl(target, ctx):
          pass

        myaspect = aspect(implementation = _aspect_impl)

        cfgrule = rule(
          implementation = _rule_impl,
          attrs = {
            'to': attr.label(),
            'innocent': attr.label(cfg = formation_transition),
          }
        )
        """);
    scratch.file(
        "aspect/BUILD",
        """
        load('aspect.bzl', 'cfgrule', 'string_flag')
        string_flag(name = 'formation', build_setting_default = 'canyon')
        sh_library(name = 'innocent')
        cfgrule(name = 'top', to = '//baz:baz', innocent = ':innocent')
        """);
    scratch.file("bar/BUILD", "sh_library(name = 'bar', deps = ['//baz:baz'])");
    scratch.file(
        "baz/BUILD",
        """
        load('//baz/subdir:missing.bzl', 'sym')
        sh_library(name = 'baz')
        """);
    scratch.file("baz/subdir/missing.bzl");
    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result =
          update(ImmutableList.of("//aspect:aspect.bzl%myaspect"), "//aspect:top");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect to fail.
      assertThat(keepGoing()).isFalse();
    }
    assertContainsEvent("Label '//baz/subdir:missing.bzl' is invalid");
  }

  @Test
  public void aspectParametersUncovered() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.string(values=['aaa']) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx')
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (Exception e) {
      // expect to fail.
    }
    assertContainsEvent( // "ERROR /workspace/test/aspect.bzl:9:11: "
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type string.");
  }

  @Test
  public void aspectParametersTypeMismatch() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectMismatch = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.string(values=['aaa']) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectMismatch]),
                      'my_attr' : attr.int() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx', my_attr = 4)
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (Exception e) {
      // expect to fail.
    }
    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectMismatch requires rule my_rule to specify attribute "
            + "'my_attr' with type string.");
  }

  @Test
  public void aspectParametersDontSupportSelect() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectMismatch = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.string(values=['aaa']) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectMismatch]),
                      'my_attr' : attr.string() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx', my_attr = select({'//conditions:default': 'foo'}))
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (Exception e) {
      // expect to fail.
    }
    assertContainsEvent(
        "//test:xxx: attribute 'my_attr' has a select() and aspect "
            + "//test:aspect.bzl%MyAspectMismatch also declares '//test:xxx'. Aspect attributes "
            + "don't currently support select().");
  }

  @Test
  public void aspectParametersBadDefault() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectBadDefault = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.string(values=['a'], default='b') },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectBadDefault]) },  # line 11
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx')
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (Exception e) {
      // expect to fail.
    }

    // aspect fails, stack = [<toplevel>@:5:28, aspect@<builtin>]
    assertContainsEvent("File \"/workspace/test/aspect.bzl\", line 5, column 28, in <toplevel>");
    assertContainsEvent(
        "Error in aspect: Aspect parameter attribute 'my_attr' has a bad default value: has to be"
            + " one of 'a' instead of 'b'");
  }

  @Test
  public void aspectParametersBadValue() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectBadValue = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.string(values=['a']) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectBadValue]),
                      'my_attr' : attr.string() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx', my_attr='b')
        """);

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(result.hasError()).isTrue();
    } catch (Exception e) {
      // expect to fail.
    }
    assertContainsEvent(
        "ERROR /workspace/test/BUILD:2:8: //test:xxx: invalid value in 'my_attr' "
            + "attribute: has to be one of 'a' instead of 'b'");
  }

  @Test
  public void aspectParameters() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspect = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.string(values=['aaa']) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspect]),
                      'my_attr' : attr.string() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx', my_attr = 'aaa')
        """);

    AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
    assertThat(result.hasError()).isFalse();
  }

  @Test
  public void aspectParametersConfigurationField() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspect = aspect(
            implementation=_impl,
            attrs = { '_my_attr' : attr.label(default=
                     configuration_field(fragment='cpp', name = 'cc_toolchain')) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspect]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx')
        """);

    AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
    assertThat(result.hasError()).isFalse();
  }

  @Test
  public void aspectParameterComputedDefault() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        def _defattr():
           return Label('//foo/bar:baz')
        MyAspect = aspect(
            implementation=_impl,
            attrs = { '_extra' : attr.label(default = _defattr) }
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspect]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx')
        """);
    reporter.removeHandler(failFastHandler);

    if (keepGoing()) {
      AnalysisResult result = update("//test:xxx");
      assertThat(result.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update("//test:xxx"));
    }
    assertContainsEvent(
        "Aspect attribute '_extra' (label) with computed default value is unsupported.");
  }

  @Test
  public void aspectParametersOptional() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectOptParam = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.string(values=['aaa'], default='aaa') },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectOptParam]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx')
        """);

    AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
    assertThat(result.hasError()).isFalse();
  }

  @Test
  public void aspectParametersOptionalOverride() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           if (ctx.attr.my_attr == 'a'):
               fail('Rule is not overriding default, still has value ' + ctx.attr.my_attr)
           return []
        def _rule_impl(ctx):
           return []
        MyAspectOptOverride = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.string(values=['a', 'b'], default='a') },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectOptOverride]),
                      'my_attr' : attr.string() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'xxx', my_attr = 'b')
        """);

    AnalysisResult result = update(ImmutableList.of(), "//test:xxx");
    assertThat(result.hasError()).isFalse();
  }

  @Test
  public void testMultipleExecutablesInTarget() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        """
        def _aspect_impl(target, ctx):
           return []
        my_aspect = aspect(_aspect_impl)
        def _main_rule_impl(ctx):
           pass
        my_rule = rule(_main_rule_impl,
           attrs = {
              'exe1' : attr.label(executable = True, allow_files = True, cfg = 'exec'),
              'exe2' : attr.label(executable = True, allow_files = True, cfg = 'exec'),
           },
        )
        """);

    scratch.file("foo/tool.sh", "#!/bin/bash");
    scratch.file(
        "foo/BUILD",
        """
        load(':extension.bzl',  'my_rule')
        my_rule(name = 'main', exe1 = ':tool.sh', exe2 = ':tool.sh')
        """);
    AnalysisResult analysisResultOfRule = update(ImmutableList.of(), "//foo:main");
    assertThat(analysisResultOfRule.hasError()).isFalse();

    AnalysisResult analysisResultOfAspect =
        update(ImmutableList.of("/foo/extension.bzl%my_aspect"), "//foo:main");
    assertThat(analysisResultOfAspect.hasError()).isFalse();
  }

  @Test
  public void aspectFragmentAccessSuccess() throws Exception {
    analyzeConfiguredTargetForAspectFragment("ctx.fragments.java.strict_java_deps", "'java'", "");
    assertNoEvents();
  }

  @Test
  public void aspectFragmentAccessError() {
    reporter.removeHandler(failFastHandler);
    assertThrows(
        ViewCreationFailedException.class,
        () ->
            analyzeConfiguredTargetForAspectFragment(
                "ctx.fragments.java.strict_java_deps", "'cpp'", "'cpp'"));
    assertContainsEvent(
        "//test:aspect.bzl%MyAspect aspect on my_rule has to declare 'java' as a "
            + "required fragment in order to access it. Please update the 'fragments' argument of "
            + "the rule definition (for example: fragments = [\"java\"])");
  }

  private void analyzeConfiguredTargetForAspectFragment(
      String fullFieldName, String fragments, String ruleFragments) throws Exception {
    scratch.file(
        "test/aspect.bzl",
        "AspectInfo = provider()",
        "def _aspect_impl(target, ctx):",
        "   return AspectInfo(result = str(" + fullFieldName + "))",
        "",
        "RuleInfo = provider()",
        "def _rule_impl(ctx):",
        "   return RuleInfo(stuff = '...')",
        "",
        "MyAspect = aspect(",
        "   implementation=_aspect_impl,",
        "   attr_aspects=['deps'],",
        "   fragments=[" + fragments + "],",
        ")",
        "my_rule = rule(",
        "   implementation=_rule_impl,",
        "   attrs = { 'attr' : ",
        "             attr.label_list(mandatory=True, allow_files=True, aspects = [MyAspect]) },",
        "   fragments=[" + ruleFragments + "],",
        ")");
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        exports_files(['zzz'])
        my_rule(
             name = 'yyy',
             attr = ['zzz'],
        )
        my_rule(
             name = 'xxx',
             attr = ['yyy'],
        )
        """);

    AnalysisResult result = update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    if (result.hasError()) {
      assertThat(keepGoing()).isTrue();
      String errorMessage = "Analysis failed";
      throw new ViewCreationFailedException(
          errorMessage,
          FailureDetail.newBuilder()
              .setMessage(errorMessage)
              .setAnalysis(Analysis.newBuilder().setCode(Code.ANALYSIS_UNKNOWN))
              .build());
    }

    assertThat(getConfiguredTarget("//test:xxx")).isNotNull();
  }

  @Test
  public void invalidateAspectOnBzlFileChange() throws Exception {
    scratch.file("test/build_defs.bzl", aspectBzlFile("'deps'"));
    scratch.file(
        "test/BUILD",
        """
        load(':build_defs.bzl', 'repro', 'repro_no_aspect')
        repro_no_aspect(name = 'r0')
        repro_no_aspect(name = 'r1', deps = [':r0'])
        repro(name = 'r2', deps = [':r1'])
        """);
    buildTargetAndCheckRuleInfo("@//test:r0", "@//test:r1");

    // Make aspect propagation list empty.
    scratch.overwriteFile("test/build_defs.bzl", aspectBzlFile(""));

    // The aspect should not propagate to //test:r0 anymore.
    buildTargetAndCheckRuleInfo("@//test:r1");
  }

  private void buildTargetAndCheckRuleInfo(String... expectedLabels) throws Exception {
    AnalysisResult result = update(ImmutableList.of(), "//test:r2");
    ConfiguredTarget configuredTarget = result.getTargetsToBuild().iterator().next();
    Depset ruleInfoValue =
        (Depset) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("rule_info");
    assertThat(ruleInfoValue.getSet(String.class).toList())
        .containsExactlyElementsIn(expectedLabels);
  }

  private static String[] aspectBzlFile(String attrAspects) {
    return new String[] {
      "AspectInfo = provider()",
      "def _repro_aspect_impl(target, ctx):",
      "    s = depset([str(target.label)], transitive =",
      "      [d[AspectInfo].aspect_info for d in ctx.rule.attr.deps if AspectInfo in d])",
      "    return AspectInfo(aspect_info = s)",
      "",
      "_repro_aspect = aspect(",
      "    _repro_aspect_impl,",
      "    attr_aspects = [" + attrAspects + "],",
      ")",
      "",
      "RuleInfo = provider()",
      "def repro_impl(ctx):",
      "    s = depset(transitive = ",
      "      [d[AspectInfo].aspect_info for d in ctx.attr.deps if AspectInfo in d])",
      "    return RuleInfo(rule_info = s)",
      "",
      "def repro_no_aspect_impl(ctx):",
      "    pass",
      "",
      "repro_no_aspect = rule(implementation = repro_no_aspect_impl,",
      "             attrs = {",
      "                       'deps': attr.label_list(",
      "                             allow_files = True,",
      "                       )",
      "                      },",
      ")",
      "",
      "repro = rule(implementation = repro_impl,",
      "             attrs = {",
      "                       'deps': attr.label_list(",
      "                             allow_files = True,",
      "                             aspects = [_repro_aspect],",
      "                       )",
      "                      },",
      ")"
    };
  }

  @Test
  public void aspectOutputsToBinDirectory() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
           file = ctx.actions.declare_file('aspect-output-' + target.label.name)
           ctx.actions.write(file, 'data')
           return AspectInfo(aspect_file = file)
        my_aspect = aspect(_aspect_impl)
        def _rule_impl(ctx):
           pass
        rule_bin_out = rule(_rule_impl, output_to_genfiles=False)
        rule_gen_out = rule(_rule_impl, output_to_genfiles=True)
        RuleInfo = provider()
        def _main_rule_impl(ctx):
           s = depset([d[AspectInfo].aspect_file for d in ctx.attr.deps])
           return RuleInfo(aspect_files = s)
        main_rule = rule(_main_rule_impl,
           attrs = { 'deps' : attr.label_list(aspects = [my_aspect]) },
        )
        """);

    scratch.file(
        "foo/BUILD",
        """
        load(':extension.bzl', 'rule_bin_out', 'rule_gen_out', 'main_rule')
        rule_bin_out(name = 'rbin')
        rule_gen_out(name = 'rgen')
        main_rule(name = 'main', deps = [':rbin', ':rgen'])
        """);
    AnalysisResult analysisResult = update(ImmutableList.of(), "//foo:main");
    ConfiguredTarget target = analysisResult.getTargetsToBuild().iterator().next();
    NestedSet<Artifact> aspectFiles =
        getStarlarkProvider(target, "RuleInfo")
            .getValue("aspect_files", Depset.class)
            .getSet(Artifact.class);
    assertThat(Iterables.transform(aspectFiles.toList(), Artifact::getFilename))
        .containsExactly("aspect-output-rbin", "aspect-output-rgen");
    for (Artifact aspectFile : aspectFiles.toList()) {
      String rootPath = aspectFile.getRoot().getExecPath().toString();
      assertWithMessage("Artifact %s should not be in genfiles", aspectFile)
          .that(rootPath)
          .doesNotContain("genfiles");
      assertWithMessage("Artifact %s should be in bin", aspectFile).that(rootPath).endsWith("bin");
    }
  }

  @Test
  public void toplevelAspectOnFile() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           print('This aspect does nothing')
           return []
        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file("test/BUILD", "exports_files(['file.txt'])");
    scratch.file("test/file.txt", "");
    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:file.txt");
    assertThat(analysisResult.hasError()).isFalse();
    assertThat(
            Iterables.getOnlyElement(analysisResult.getAspectsMap().values())
                .getProviders()
                .getProviderCount())
        .isEqualTo(0);
  }

  @Test
  public void sharedAttributeDefinitionWithAspects() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _aspect_impl(target,ctx):
          return []
        my_aspect = aspect(implementation = _aspect_impl)
        _ATTR = { 'deps' : attr.label_list(aspects = [my_aspect]) }
        def _dummy_impl(ctx):
          pass
        r1 = rule(_dummy_impl, attrs =  _ATTR)
        r2 = rule(_dummy_impl, attrs =  _ATTR)
        """);

    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r1', 'r2')
        r1(name = 't1')
        r2(name = 't2', deps = [':t1'])
        """);
    AnalysisResult analysisResult = update("//test:t2");
    assertThat(analysisResult.hasError()).isFalse();
  }

  @Test
  public void multipleAspects() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _aspect_impl(target,ctx):
          return []
        my_aspect = aspect(implementation = _aspect_impl)
        def _dummy_impl(ctx):
          pass
        r1 = rule(_dummy_impl,
                  attrs = { 'deps' : attr.label_list(aspects = [my_aspect, my_aspect]) })
        """);

    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r1')
        r1(name = 't1')
        """);
    reporter.removeHandler(failFastHandler);
    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult result = update("//test:r1");
      assertThat(result.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update("//test:r1"));
    }
    assertContainsEvent("aspect //test:aspect.bzl%my_aspect added more than once");
  }

  @Test
  public void topLevelAspectsAndExtraActions() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _aspect_impl(target,ctx):
          f = ctx.actions.declare_file('dummy.txt')
          ctx.actions.run_shell(outputs = [f], command='echo xxx > $(location f)',
                                mnemonic='AspectAction')
          return []
        my_aspect = aspect(implementation = _aspect_impl)
        """);
    scratch.file(
        "test/BUILD",
        """
        extra_action(
            name = 'xa',
            cmd = 'echo $(EXTRA_ACTION_FILE) > $(output file.xa)',
            out_templates = ['file.xa'],
        )
        action_listener(
            name = 'al',
            mnemonics = [ 'AspectAction' ],
            extra_actions = [ ':xa' ])
        java_library(name = 'xxx')
        """);
    useConfiguration("--experimental_action_listener=//test:al");
    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%my_aspect"), "//test:xxx");
    assertThat(Iterables.transform(analysisResult.getArtifactsToBuild(), Artifact::getFilename))
        .contains("file.xa");
  }

  /** Regression test for b/137960630. */
  @Test
  public void topLevelAspectsAndExtraActionsWithConflict() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _aspect_impl(target, ctx):
          f = ctx.actions.declare_file('dummy.txt')
          ctx.actions.run_shell(outputs = [f], command='echo xxx > $(location f)',
                                mnemonic='AspectAction')
          return []
        my_aspect = aspect(implementation = _aspect_impl)
        """);
    scratch.file(
        "test/BUILD",
        """
        extra_action(
            name = 'xa',
            cmd = 'echo $(EXTRA_ACTION_FILE) > $(output file.xa)',
            out_templates = ['file.xa'],
        )
        action_listener(
            name = 'al',
            mnemonics = ['AspectAction'],
            extra_actions = [':xa'],
        )
        java_library(name = 'xxx')
        java_library(name = 'yyy')
        """);
    useConfiguration("--experimental_action_listener=//test:al");
    reporter.removeHandler(failFastHandler); // We expect an error.

    if (keepGoing()) {
      AnalysisResult result =
          update(ImmutableList.of("test/aspect.bzl%my_aspect"), "//test:xxx", "//test:yyy");
      assertThat(result.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () -> update(ImmutableList.of("test/aspect.bzl%my_aspect"), "//test:xxx", "//test:yyy"));
    }
    assertContainsEvent(
        "file 'extra_actions/test/xa/test/file.xa' is generated by these conflicting actions");
  }

  @Test
  public void aspectsPropagatingToAllAttributes() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           s = depset([target.label], transitive =
             [i.target_labels for i in ctx.rule.attr.runtime_deps]
             if hasattr(ctx.rule.attr, 'runtime_deps') else [])
           return struct(target_labels = s)

        MyAspect = aspect(
            implementation=_impl,
            attrs = { '_tool' : attr.label(default = Label('//test:tool')) },
            attr_aspects=['*'],
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        java_library(
            name = 'tool',
        )
        java_library(
             name = 'bar',
             runtime_deps = [':tool'],
        )
        java_library(
             name = 'foo',
             runtime_deps = [':bar'],
        )
        """);
    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:foo");
    ConfiguredAspect configuredAspect = analysisResult.getAspectsMap().values().iterator().next();
    assertThat(configuredAspect).isNotNull();
    Object names = configuredAspect.get("target_labels");
    assertThat(names).isInstanceOf(Depset.class);
    assertThat(
            Iterables.transform(
                ((Depset) names).toList(),
                o -> {
                  assertThat(o).isInstanceOf(Label.class);
                  return ((Label) o).getName();
                }))
        .containsExactly("foo", "bar", "tool");
  }

  /** Simple straightforward linear aspects-on-aspects. */
  @Test
  public void aspectOnAspectLinear() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        a1p = provider()
        def _a1_impl(target,ctx):
          return a1p(text = 'random')
        a1 = aspect(_a1_impl, attr_aspects = ['dep'], provides = [a1p])
        a2p = provider()
        def _a2_impl(target,ctx):
          value = []
          if  ctx.rule.attr.dep and a2p in ctx.rule.attr.dep:
             value += ctx.rule.attr.dep[a2p].value
          if a1p in target:
             value.append(str(target.label) + str(ctx.aspect_ids) + '=yes')
          else:
             value.append(str(target.label) + str(ctx.aspect_ids) + '=no')
          return a2p(value = value)
        a2 = aspect(_a2_impl, attr_aspects = ['dep'], required_aspect_providers = [a1p])
        def _r1_impl(ctx):
          pass
        r2info = provider()
        def _r2_impl(ctx):
          return r2info(result = ctx.attr.dep[a2p].value)
        r1 = rule(_r1_impl, attrs = { 'dep' : attr.label(aspects = [a1])})
        r2 = rule(_r2_impl, attrs = { 'dep' : attr.label(aspects = [a2])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r1', 'r2')
        r1(name = 'r0')
        r1(name = 'r1', dep = ':r0')
        r2(name = 'r2', dep = ':r1')
        """);
    AnalysisResult analysisResult = update("//test:r2");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    Sequence<?> result = getStarlarkProvider(target, "r2info").getValue("result", Sequence.class);

    // "yes" means that aspect a2 sees a1's providers.
    assertThat(result)
        .containsExactly(
            "@//test:r0[\"//test:aspect.bzl%a1\", \"//test:aspect.bzl%a2\"]=yes",
            "@//test:r1[\"//test:aspect.bzl%a2\"]=no");
  }

  /**
   * Diamond case. rule r1 depends or r0 with aspect a1. rule r2 depends or r0 with aspect a2. rule
   * rcollect depends on r1, r2 with aspect a3.
   *
   * <p>Aspect a3 should be applied twice to target r0: once in [a1, a3] sequence and once in [a2,
   * a3] sequence.
   */
  @Test
  public void aspectOnAspectDiamond() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        a1p = provider()
        a2p = provider()
        a3p = provider()
        def _a1_impl(target,ctx):
          return [a1p(value = 'text from a1')]
        a1 = aspect(_a1_impl, attr_aspects = ['deps'], provides = [a1p])

        def _a2_impl(target,ctx):
          return [a2p(value = 'text from a2')]
        a2 = aspect(_a2_impl, attr_aspects = ['deps'], provides = [a2p])

        def _a3_impl(target,ctx):
          value = []
          f = ctx.actions.declare_file('a3.out')
          ctx.actions.write(f, 'text')
          for dep in ctx.rule.attr.deps:
             if a3p in dep:
                 value += dep[a3p].value
          s = str(target.label) + str(ctx.aspect_ids) + '='
          if a1p in target:
             s += 'a1p'
          if a2p in target:
             s += 'a2p'
          value.append(s)
          return [a3p(value = value)]
        a3 = aspect(_a3_impl, attr_aspects = ['deps'],
                    required_aspect_providers = [[a1p], [a2p]])
        def _r1_impl(ctx):
          pass
        RCollectInfo = provider()
        def _rcollect_impl(ctx):
          value = []
          for dep in ctx.attr.deps:
             if a3p in dep:
                 value += dep[a3p].value
          return RCollectInfo(result = value)
        r1 = rule(_r1_impl, attrs = { 'deps' : attr.label_list(aspects = [a1])})
        r2 = rule(_r1_impl, attrs = { 'deps' : attr.label_list(aspects = [a2])})
        rcollect = rule(_rcollect_impl, attrs = { 'deps' : attr.label_list(aspects = [a3])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r1', 'r2', 'rcollect')
        r1(name = 'r0')
        r1(name = 'r1', deps = [':r0'])
        r2(name = 'r2', deps = [':r0'])
        rcollect(name = 'rcollect', deps = [':r1', ':r2'])
        """);
    AnalysisResult analysisResult = update("//test:rcollect");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    Sequence<?> result =
        (Sequence<?>) getStarlarkProvider(target, "RCollectInfo").getValue("result");
    assertThat(result)
        .containsExactly(
            "@//test:r0[\"//test:aspect.bzl%a1\", \"//test:aspect.bzl%a3\"]=a1p",
            "@//test:r1[\"//test:aspect.bzl%a3\"]=",
            "@//test:r0[\"//test:aspect.bzl%a2\", \"//test:aspect.bzl%a3\"]=a2p",
            "@//test:r2[\"//test:aspect.bzl%a3\"]=");
  }

  /**
   * Linear with duplicates. r2_1 depends on r0 with aspect a2. r1 depends on r2_1 with aspect a1.
   * r2 depends on r1 with aspect a2.
   *
   * <p>a2 is not interested in a1. There should be just one instance of aspect a2 on r0, and is
   * should *not* see a1.
   */
  @Test
  public void aspectOnAspectLinearDuplicates() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        a1p = provider()
        def _a1_impl(target,ctx):
          return a1p()
        a1 = aspect(_a1_impl, attr_aspects = ['dep'], provides = [a1p])
        a2p = provider()
        def _a2_impl(target,ctx):
          value = []
          if ctx.rule.attr.dep and a2p in ctx.rule.attr.dep:
             value += ctx.rule.attr.dep[a2p].value
          if a1p in target:
             value.append(str(target.label) + str(ctx.aspect_ids) + '=yes')
          else:
             value.append(str(target.label) + str(ctx.aspect_ids) + '=no')
          return a2p(value = value)
        a2 = aspect(_a2_impl, attr_aspects = ['dep'], required_aspect_providers = [])
        def _r1_impl(ctx):
          pass
        r2info = provider()
        def _r2_impl(ctx):
          return r2info(result = ctx.attr.dep[a2p].value)
        r1 = rule(_r1_impl, attrs = { 'dep' : attr.label(aspects = [a1])})
        r2 = rule(_r2_impl, attrs = { 'dep' : attr.label(aspects = [a2])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r1', 'r2')
        r1(name = 'r0')
        r2(name = 'r2_1', dep = ':r0')
        r1(name = 'r1', dep = ':r2_1')
        r2(name = 'r2', dep = ':r1')
        """);
    AnalysisResult analysisResult = update("//test:r2");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    Sequence<?> result = getStarlarkProvider(target, "r2info").getValue("result", Sequence.class);
    // "yes" means that aspect a2 sees a1's providers.
    assertThat(result)
        .containsExactly(
            "@//test:r0[\"//test:aspect.bzl%a2\"]=no",
            "@//test:r1[\"//test:aspect.bzl%a2\"]=no", "@//test:r2_1[\"//test:aspect.bzl%a2\"]=no");
  }

  /** Linear aspects-on-aspects with alias rule. */
  @Test
  public void aspectOnAspectLinearAlias() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        a1p = provider()
        def _a1_impl(target,ctx):
          return [a1p(text = 'random')]
        a1 = aspect(_a1_impl, attr_aspects = ['dep'], provides = [a1p])
        a2p = provider()
        def _a2_impl(target,ctx):
          value = []
          if ctx.rule.attr.dep and a2p in ctx.rule.attr.dep:
             value += ctx.rule.attr.dep[a2p].value
          if a1p in target:
             value.append(str(target.label) + str(ctx.aspect_ids) + '=yes')
          else:
             value.append(str(target.label) + str(ctx.aspect_ids) + '=no')
          return [a2p(value = value)]
        a2 = aspect(_a2_impl, attr_aspects = ['dep'], required_aspect_providers = [a1p])
        def _r1_impl(ctx):
          pass
        r2info = provider()
        def _r2_impl(ctx):
          return r2info(result = ctx.attr.dep[a2p].value)
        r1 = rule(_r1_impl, attrs = { 'dep' : attr.label(aspects = [a1])})
        r2 = rule(_r2_impl, attrs = { 'dep' : attr.label(aspects = [a2])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r1', 'r2')
        r1(name = 'r0')
        alias(name = 'a0', actual = ':r0')
        r1(name = 'r1', dep = ':a0')
        r2(name = 'r2', dep = ':r1')
        """);
    AnalysisResult analysisResult = update("//test:r2");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    Sequence<?> result = getStarlarkProvider(target, "r2info").getValue("result", Sequence.class);

    // "yes" means that aspect a2 sees a1's providers.
    assertThat(result)
        .containsExactly(
            "@//test:r0[\"//test:aspect.bzl%a1\", \"//test:aspect.bzl%a2\"]=yes",
            "@//test:r1[\"//test:aspect.bzl%a2\"]=no");
  }

  @Test
  public void aspectDescriptions() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
AspectInfo = provider()
def _a_impl(target,ctx):
  s = str(target.label) + str(ctx.aspect_ids) + '='
  value = []
  if ctx.rule.attr.dep:
     d = ctx.rule.attr.dep
     this_id = ctx.aspect_ids[len(ctx.aspect_ids) - 1]
     s += str(d.label) + str(d[AspectInfo].my_ids) + ',' + str(this_id in d[AspectInfo].my_ids)
     value += ctx.rule.attr.dep[AspectInfo].ap
  else:
     s += 'None'
  value.append(s)
  return AspectInfo(ap = value, my_ids = ctx.aspect_ids)
a = aspect(_a_impl, attr_aspects = ['dep'])
RuleInfo = provider()
def _r_impl(ctx):
  if not ctx.attr.dep:
     return RuleInfo(result = [])
  return RuleInfo(result = ctx.attr.dep[AspectInfo].ap)
r = rule(_r_impl, attrs = { 'dep' : attr.label(aspects = [a])})
""");
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r')
        r(name = 'r0')
        r(name = 'r1', dep = ':r0')
        r(name = 'r2', dep = ':r1')
        """);
    AnalysisResult analysisResult = update("//test:r2");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    Sequence<?> result = (Sequence<?>) getStarlarkProvider(target, "RuleInfo").getValue("result");

    assertThat(result)
        .containsExactly(
            "@//test:r0[\"//test:aspect.bzl%a\"]=None",
            "@//test:r1[\"//test:aspect.bzl%a\"]=@//test:r0[\"//test:aspect.bzl%a\"],True");
  }

  @Test
  public void attributesWithAspectsReused() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        my_aspect = aspect(_impl)
        a_dict = { 'foo' : attr.label_list(aspects = [my_aspect]) }
        """);

    scratch.file(
        "test/r1.bzl",
        """
        load(':aspect.bzl', 'my_aspect', 'a_dict')
        def _rule_impl(ctx):
           pass
        r1 = rule(_rule_impl, attrs = a_dict)
        """);

    scratch.file(
        "test/r2.bzl",
        """
        load(':aspect.bzl', 'my_aspect', 'a_dict')
        def _rule_impl(ctx):
           pass
        r2 = rule(_rule_impl, attrs = a_dict)
        """);

    scratch.file(
        "test/BUILD",
        """
        load(':r1.bzl', 'r1')
        load(':r2.bzl', 'r2')
        r1(name = 'x1')
        r2(name = 'x2', foo = [':x1'])
        """);
    AnalysisResult analysisResult = update("//test:x2");
    assertThat(analysisResult.hasError()).isFalse();
  }

  @Test
  public void aspectAdvertisingProviders() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        my_aspect = aspect(_impl, provides = ['foo'])
        a_dict = { 'foo' : attr.label_list(aspects = [my_aspect]) }
        """);
    scratch.file("test/BUILD", "java_library(name = 'xxx',)");

    reporter.removeHandler(failFastHandler);
    try {
      AnalysisResult analysisResult =
          update(ImmutableList.of("//test:aspect.bzl%my_aspect"), "//test:xxx");
      assertThat(keepGoing()).isTrue();
      assertThat(analysisResult.hasError()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expect exception
    }
    assertContainsEvent(
        "Aspect '//test:aspect.bzl%my_aspect', applied to '//test:xxx', "
            + "does not provide advertised provider 'foo'");
  }

  @Test
  public void aspectOnAspectInconsistentVisibility() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        a1p = provider()
        def _a1_impl(target,ctx):
          return [a1p(text = 'random')]
        a1 = aspect(_a1_impl, attr_aspects = ['dep'], provides = [a1p])
        a2p = provider()
        def _a2_impl(target,ctx):
          return [a2p(value = 'random')]
        a2 = aspect(_a2_impl, attr_aspects = ['dep'], required_aspect_providers = [a1p])
        def _r1_impl(ctx):
          pass
        r2info = provider()
        def _r2_impl(ctx):
          return r2info(result = ctx.attr.dep[a2p].value)
        r1 = rule(_r1_impl, attrs = { 'dep' : attr.label(aspects = [a1])})
        r2 = rule(_r2_impl, attrs = { 'dep' : attr.label(aspects = [a2])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r1', 'r2')
        r1(name = 'r0')
        r1(name = 'r1', dep = ':r0')
        r2(name = 'r2', dep = ':r1')
        r1(name = 'r1_1', dep = ':r2')
        r2(name = 'r2_1', dep = ':r1_1')
        """);
    reporter.removeHandler(failFastHandler);

    try {
      AnalysisResult analysisResult = update("//test:r2_1");
      assertThat(analysisResult.hasError()).isTrue();
      assertThat(keepGoing()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expected
    }
    assertContainsEvent(
        "ERROR /workspace/test/BUILD:3:3: Aspect //test:aspect.bzl%a2 is"
            + " applied twice, both before and after aspect //test:aspect.bzl%a1 "
            + "(when propagating to //test:r1)");
  }

  @Test
  public void aspectOnAspectInconsistentVisibilityIndirect() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        a1p = provider()
        def _a1_impl(target,ctx):
          return [a1p(text = 'random')]
        a1 = aspect(_a1_impl, attr_aspects = ['dep'], provides = [a1p])
        a2p = provider()
        def _a2_impl(target,ctx):
          return [a2p(value = 'random')]
        a2 = aspect(_a2_impl, attr_aspects = ['dep'], required_aspect_providers = [a1p])
        def _r1_impl(ctx):
          pass
        r2info = provider()
        def _r2_impl(ctx):
          return r2info(result = ctx.attr.dep[a2p].value)
        r1 = rule(_r1_impl, attrs = { 'dep' : attr.label(aspects = [a1])})
        r2 = rule(_r2_impl, attrs = { 'dep' : attr.label(aspects = [a2])})
        def _r0_impl(ctx):
          pass
        r0 = rule(_r0_impl, attrs = { 'dep' : attr.label()})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r0', 'r1', 'r2')
        r0(name = 'r0')
        r1(name = 'r1', dep = ':r0')
        r2(name = 'r2', dep = ':r1')
        r1(name = 'r1_1', dep = ':r2')
        r2(name = 'r2_1', dep = ':r1_1')
        r0(name = 'r0_2', dep = ':r2_1')
        """);
    reporter.removeHandler(failFastHandler);

    try {
      AnalysisResult analysisResult = update("//test:r0_2");
      assertThat(analysisResult.hasError()).isTrue();
      assertThat(keepGoing()).isTrue();
    } catch (ViewCreationFailedException e) {
      // expected
    }
    assertContainsEvent(
        "ERROR /workspace/test/BUILD:3:3: Aspect //test:aspect.bzl%a2 is"
            + " applied twice, both before and after aspect //test:aspect.bzl%a1 "
            + "(when propagating to //test:r1)");
  }

  /**
   * Aspect a3 sees aspect a2, aspect a2 sees aspect a1, but a3 does not see a1. All three aspects
   * should still propagate together.
   */
  @Test
  public void aspectOnAspectOnAspect() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        p1 = provider()
        def _a1_impl(target, ctx):
           return [p1()]
        a1 = aspect(_a1_impl, attr_aspects = ['dep'], provides = [p1])
        p2 = provider()
        def _a2_impl(target, ctx):
           value = True if p1 in target else False
           return [p2(has_p1 = value)]
        a2 = aspect(_a2_impl, attr_aspects = ['dep'],
           required_aspect_providers = [p1], provides = [p2])
        p3 = provider()
        def _a3_impl(target, ctx):
           list = []
           if ctx.rule.attr.dep:
             list = ctx.rule.attr.dep[p3].value
           my_value = str(target.label) +'=' + str(target[p2].has_p1 if p2 in target else False)
           return [p3(value = list + [my_value])]
        a3 = aspect(_a3_impl, attr_aspects = ['dep'],
           required_aspect_providers = [p2])
        def _r0_impl(ctx):
          pass
        r0 = rule(_r0_impl, attrs = { 'dep' : attr.label()})
        def _r1_impl(ctx):
          pass
        def _r2_impl(ctx):
          pass
        r1 = rule(_r1_impl, attrs = { 'dep' : attr.label(aspects = [a1])})
        r2 = rule(_r2_impl, attrs = { 'dep' : attr.label(aspects = [a2])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r0', 'r1', 'r2')
        r0(name = 'r0_1')
        r0(name = 'r0_2', dep = ':r0_1')
        r0(name = 'r0_3', dep = ':r0_2')
        r1(name = 'r1_1', dep = ':r0_3')
        r2(name = 'r2_1', dep = ':r1_1')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of("//test:aspect.bzl%a3"), "//test:r2_1");
    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    StarlarkProvider.Key p3 =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "p3");
    StructImpl p3Provider = (StructImpl) configuredAspect.get(p3);
    assertThat((Sequence<?>) p3Provider.getValue("value"))
        .containsExactly(
            "@//test:r0_1=True",
            "@//test:r0_2=True",
            "@//test:r0_3=True",
            "@//test:r1_1=False",
            "@//test:r2_1=False");
  }

  /**
   * r0 is a dependency of r1 via two attributes, dep1 and dep2. r1 sends an aspect 'a' along dep1
   * but not along dep2.
   *
   * <p>rcollect depends upon r1 and sends another aspect, 'collector', along its dep dependency.
   * 'collector' wants to see aspect 'a' and propagates along dep1 and dep2. It should be applied
   * both to r0 and to r0+a.
   */
  @Test
  public void multipleDepsDifferentAspects() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        PAspect = provider()
        PCollector = provider()
        def _aspect_impl(target, ctx):
           return [PAspect()]
        a = aspect(_aspect_impl, attr_aspects = ['dep'], provides = [PAspect])
        def _collector_impl(target, ctx):
           suffix = '+PAspect' if PAspect in target else ''
           result = [str(target.label)+suffix]
           for a in ['dep', 'dep1', 'dep2']:
             if hasattr(ctx.rule.attr, a):
                result += getattr(ctx.rule.attr, a)[PCollector].result
           return [PCollector(result=result)]
        collector = aspect(_collector_impl, attr_aspects = ['*'],
                           required_aspect_providers = [PAspect])
        def _rimpl(ctx):
           pass
        r0 = rule(_rimpl)
        r1 = rule(_rimpl,
                  attrs = {
                     'dep1' : attr.label(),
                     'dep2' : attr.label(aspects = [a]),
                  },
        )
        def _rcollect_impl(ctx):
            return [ctx.attr.dep[PCollector]]
        rcollect = rule(_rcollect_impl,
                        attrs = {
                          'dep' : attr.label(aspects = [collector]),
                        })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r0', 'r1', 'rcollect')
        r0(name = 'r0')
        r1(name = 'r1', dep1 = ':r0', dep2 = ':r0')
        rcollect(name = 'rcollect', dep = ':r1')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of(), "//test:rcollect");
    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkProvider.Key pCollector =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "PCollector");
    StructImpl pCollectorProvider = (StructImpl) configuredTarget.get(pCollector);
    assertThat((Sequence<?>) pCollectorProvider.getValue("result"))
        .containsExactly("@//test:r1", "@//test:r0", "@//test:r0+PAspect");
  }

  @Test
  public void aspectSeesOtherAspectAttributes() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        PAspect = provider(fields = [])
        PCollector = provider(fields = ['aspect_attr'])
        def _a_impl(target, ctx):
          return [PAspect()]
        a = aspect(_a_impl,
                   provides = [PAspect],
                   attrs = {'_a_attr' : attr.label(default = '//test:foo')})
        def _rcollect(target, ctx):
          if hasattr(ctx.rule.attr, '_a_attr'):
             return [PCollector(aspect_attr = ctx.rule.attr._a_attr.label)]
          if hasattr(ctx.rule.attr, 'dep'):
             return [ctx.rule.attr.dep[PCollector]]
          return [PCollector()]
        acollect = aspect(_rcollect, attr_aspects = ['*'], required_aspect_providers = [PAspect])
        def _rimpl(ctx):
          pass
        r0 = rule(_rimpl)
        r = rule(_rimpl, attrs = { 'dep' : attr.label(aspects = [a]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r0', 'r')
        r0(name = 'foo')
        r0(name = 'bar')
        r(name = 'baz', dep = ':bar')
        """);
    AnalysisResult analysisResult =
        update(ImmutableList.of("//test:aspect.bzl%acollect"), "//test:baz");
    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    StarlarkProvider.Key pCollector =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "PCollector");
    StructImpl collector = (StructImpl) configuredAspect.get(pCollector);
    assertThat(collector.getValue("aspect_attr")).isEqualTo(Label.parseCanonical("//test:foo"));
  }

  @Test
  public void ruleAttributesWinOverAspects() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        PAspect = provider(fields = [])
        PCollector = provider(fields = ['attr_value'])
        def _a_impl(target, ctx):
          return [PAspect()]
        a = aspect(_a_impl,
                   provides = [PAspect],
                   attrs = {'_same_attr' : attr.int(default = 239)})
        def _rcollect(target, ctx):
          if hasattr(ctx.rule.attr, '_same_attr'):
             return [PCollector(attr_value = ctx.rule.attr._same_attr)]
          if hasattr(ctx.rule.attr, 'dep'):
             return [ctx.rule.attr.dep[PCollector]]
          return [PCollector()]
        acollect = aspect(_rcollect, attr_aspects = ['*'], required_aspect_providers = [PAspect])
        def _rimpl(ctx):
          pass
        r0 = rule(_rimpl)
        r = rule(_rimpl,
                  attrs = {
                          'dep' : attr.label(aspects = [a]),
                          '_same_attr' : attr.int(default = 30)
                  })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r0', 'r')
        r0(name = 'foo')
        r0(name = 'bar')
        r(name = 'baz', dep = ':bar')
        """);
    AnalysisResult analysisResult =
        update(ImmutableList.of("//test:aspect.bzl%acollect"), "//test:baz");
    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    StarlarkProvider.Key pCollector =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "PCollector");
    StructImpl collector = (StructImpl) configuredAspect.get(pCollector);
    assertThat(collector.getValue("attr_value")).isEqualTo(StarlarkInt.of(30));
  }

  @Test
  public void earlyAspectAttributesWin() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        PAspect1 = provider(fields = [])
        PAspect2 = provider(fields = [])
        PCollector = provider(fields = ['attr_value'])
        def _a1_impl(target, ctx):
          return [PAspect1()]
        def _a2_impl(target, ctx):
          return [PAspect2()]
        a1 = aspect(_a1_impl,
                    provides = [PAspect1],
                    attrs = {'_same_attr' : attr.int(default = 30)})
        a2 = aspect(_a2_impl,
                    provides = [PAspect2],
                    attrs = {'_same_attr' : attr.int(default = 239)})
        def _rcollect(target, ctx):
          if hasattr(ctx.rule.attr, 'dep'):
             return [ctx.rule.attr.dep[PCollector]]
          if hasattr(ctx.rule.attr, '_same_attr'):
             return [PCollector(attr_value = ctx.rule.attr._same_attr)]
          fail('???')
          return [PCollector()]
        acollect = aspect(_rcollect, attr_aspects = ['*'],
                          required_aspect_providers = [[PAspect1], [PAspect2]])
        def _rimpl(ctx):
          pass
        r0 = rule(_rimpl)
        r1 = rule(_rimpl,
                  attrs = {
                          'dep' : attr.label(aspects = [a1]),
                  })
        r2 = rule(_rimpl,
                  attrs = {
                          'dep' : attr.label(aspects = [a2]),
                  })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r0', 'r1', 'r2')
        r0(name = 'bar')
        r1(name = 'baz', dep = ':bar')
        r2(name = 'quux', dep = ':baz')
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("//test:aspect.bzl%acollect"), "//test:quux");
    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    StarlarkProvider.Key pCollector =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "PCollector");
    StructImpl collector = (StructImpl) configuredAspect.get(pCollector);
    assertThat(collector.getValue("attr_value")).isEqualTo(StarlarkInt.of(30));
  }

  @Test
  public void aspectPropagatesOverOtherAspectAttributes() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        PAspect = provider(fields = [])
        PCollector = provider(fields = ['visited'])
        def _a_impl(target, ctx):
          return [PAspect()]
        a = aspect(_a_impl,
               provides = [PAspect],
               attrs = {'_a_attr' : attr.label(default = '//test:referenced_from_aspect_only')})
        def _rcollect(target, ctx):
          transitive = []
          if hasattr(ctx.rule.attr, 'dep') and ctx.rule.attr.dep:
             transitive += [ctx.rule.attr.dep[PCollector].visited]
          if hasattr(ctx.rule.attr, '_a_attr') and ctx.rule.attr._a_attr:
             transitive += [ctx.rule.attr._a_attr[PCollector].visited]
          visited = depset([target.label], transitive = transitive, )
          return [PCollector(visited = visited)]
        acollect = aspect(_rcollect, attr_aspects = ['*'], required_aspect_providers = [PAspect])
        def _rimpl(ctx):
          pass
        r0 = rule(_rimpl)
        r = rule(_rimpl, attrs = { 'dep' : attr.label(aspects = [a]) })
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r0', 'r')
        r0(name = 'referenced_from_aspect_only')
        r0(name = 'bar')
        r(name = 'baz', dep = ':bar')
        """);
    AnalysisResult analysisResult =
        update(ImmutableList.of("//test:aspect.bzl%acollect"), "//test:baz");
    ConfiguredAspect configuredAspect =
        Iterables.getOnlyElement(analysisResult.getAspectsMap().values());
    StarlarkProvider.Key pCollector =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "PCollector");
    StructImpl collector = (StructImpl) configuredAspect.get(pCollector);
    assertThat(((Depset) collector.getValue("visited")).toList())
        .containsExactly(
            Label.parseCanonical("//test:referenced_from_aspect_only"),
            Label.parseCanonical("//test:bar"),
            Label.parseCanonical("//test:baz"));
  }

  @Test
  public void testAspectActionProvider() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        a1p = provider()
        def _a1_impl(target,ctx):
          ctx.actions.run_shell(
            outputs = [ctx.actions.declare_file('a1')],
            command = 'touch $@'
          )
          return [a1p()]
        a1 = aspect(_a1_impl, attr_aspects = ['dep'], provides = [a1p])
        a2p = provider()
        def _a2_impl(target, ctx):
          value = []
          if hasattr(ctx.rule.attr, 'dep') and a2p in ctx.rule.attr.dep:
             value += ctx.rule.attr.dep[a2p].value
          value += target.actions
          return [a2p(value = value)]
        a2 = aspect(_a2_impl, attr_aspects = ['dep'], required_aspect_providers = [a1p])
        def _r0_impl(ctx):
          ctx.actions.run_shell(
            outputs = [ctx.actions.declare_file('r0')],
            command = 'touch $@'
          )
        RuleInfo = provider()
        def _r1_impl(ctx):
          pass
        def _r2_impl(ctx):
          return RuleInfo(result = ctx.attr.dep[a2p].value)
        r0 = rule(_r0_impl)
        r1 = rule(_r1_impl, attrs = { 'dep' : attr.label(aspects = [a1])})
        r2 = rule(_r2_impl, attrs = { 'dep' : attr.label(aspects = [a2])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r0', 'r1', 'r2')
        r0(name = 'r0')
        r1(name = 'r1', dep = ':r0')
        r2(name = 'r2', dep = ':r1')
        """);
    AnalysisResult analysisResult = update("//test:r2");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    Sequence<?> result = (Sequence<?>) getStarlarkProvider(target, "RuleInfo").getValue("result");

    // We should see both the action from the 'r0' rule, and the action from the 'a1' aspect
    assertThat(result).hasSize(2);
    assertThat(
            result.stream()
                .map(a -> ((Action) a).getPrimaryOutput().getExecPath().getBaseName())
                .collect(toList()))
        .containsExactly("r0", "a1");
  }

  @Test
  public void testRuleAndAspectAttrConflict() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        MyInfo = provider()
        def _impl(target, ctx):
           return [MyInfo(hidden_attr_label = str(ctx.attr._hiddenattr.label))]

        def _rule_impl(ctx):
           return []

        my_rule = rule(implementation = _rule_impl,
           attrs = { '_hiddenattr' : attr.label(default = Label('//test:xxx')) },
        )
        MyAspect = aspect(
           implementation=_impl,
           attrs = { '_hiddenattr' : attr.label(default = Label('//test:zzz')) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        cc_library(
             name = 'xxx',
        )
        my_rule(
             name = 'yyy',
        )
        cc_library(
             name = 'zzz',
        )
        """);
    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:yyy");
    ConfiguredAspect configuredAspect = analysisResult.getAspectsMap().values().iterator().next();
    assertThat(configuredAspect).isNotNull();

    StarlarkProvider.Key myInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:aspect.bzl"), "MyInfo");
    StructImpl myInfo = (StructImpl) configuredAspect.get(myInfoKey);
    assertThat(myInfo.getValue("hidden_attr_label")).isEqualTo("@//test:zzz");
  }

  /** Simple straightforward linear aspects-on-aspects. */
  @Test
  public void aspectOnAspectAttrConflict() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        MyInfo = provider()
        a1p = provider()
        def _a1_impl(target,ctx):
          return a1p(text = 'random')
        a1 = aspect(_a1_impl,
           attrs = { '_hiddenattr' : attr.label(default = Label('//test:xxx')) },
           attr_aspects = ['dep'], provides = [a1p])
        a2p = provider()
        def _a2_impl(target,ctx):
           return [MyInfo(hidden_attr_label = str(ctx.attr._hiddenattr.label))]
        a2 = aspect(_a2_impl,
          attrs = { '_hiddenattr' : attr.label(default = Label('//test:zzz')) },
          attr_aspects = ['dep'], required_aspect_providers = [a1p])
        RuleInfo = provider()
        def _r1_impl(ctx):
          pass
        def _r2_impl(ctx):
          return RuleInfo(result = ctx.attr.dep[MyInfo].hidden_attr_label)
        r1 = rule(_r1_impl, attrs = { 'dep' : attr.label(aspects = [a1])})
        r2 = rule(_r2_impl, attrs = { 'dep' : attr.label(aspects = [a1, a2])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':aspect.bzl', 'r1', 'r2')
        r1(name = 'r0')
        r1(name = 'r1', dep = ':r0')
        r2(name = 'r2', dep = ':r1')
        cc_library(
             name = 'xxx',
        )
        cc_library(
             name = 'zzz',
        )
        """);

    AnalysisResult analysisResult = update("//test:r2");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    String result = getStarlarkProvider(target, "RuleInfo").getValue("result", String.class);

    assertThat(result).isEqualTo("@//test:zzz");
  }

  @Test
  public void testAllCcLibraryAttrsAreValidTypes() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
          for entry in dir(ctx.rule.attr):
            val = getattr(ctx.rule.attr, entry, None)
            # Only legitimate Starlark values can be passed to dir(), so this effectively
            # verifies val is an appropriate Starlark type.
            _test_dir = dir(val)
          return []

        MyAspect = aspect(
          implementation=_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        cc_library(
             name = 'xxx',
        )
        """);
    AnalysisResult analysisResult =
        update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
    assertThat(analysisResult.getAspectsMap().values().iterator().next()).isNotNull();
  }

  @Test
  public void testApplyToGeneratingRules() throws Exception {
    // Create test rules:
    // dep_rule: a rule which may depend on other dep_rule targets and may optionally create
    //     an output file.
    // root_{with,no}_files: a rule which depends on dep_rule targets and attaches an aspect.
    //     The rule returns a RootInfo provider which contains two fields:
    //        'from_aspect' : a list of all labels that the aspect propagated to
    //        'non_aspect' : a list of all labels that information was obtained from without aspect
    //     root_with_files uses an aspect with apply_to_generating_rules=True, and root_no_files
    //     uses an aspect with apply_to_generating_rules=False.
    scratch.file(
        "test/lib.bzl",
        """
        RootInfo = provider()
        NonAspectInfo = provider()
        FromAspectInfo = provider()
        def _aspect_impl(target, ctx):
          dep_labels = []
          for dep in ctx.rule.attr.deps:
            if FromAspectInfo in dep:
              dep_labels += [dep[FromAspectInfo].labels]
          return FromAspectInfo(labels = depset(direct = [ctx.label], transitive = dep_labels))

        def _rule_impl(ctx):
          non_aspect = []
          from_aspect = []
          for dep in ctx.attr.deps:
            if NonAspectInfo in dep:
              non_aspect +=  dep[NonAspectInfo].labels.to_list()
            if FromAspectInfo in dep:
              from_aspect += dep[FromAspectInfo].labels.to_list()
          return RootInfo(from_aspect = from_aspect, non_aspect = non_aspect)

        def _dep_rule_impl(ctx):
          if ctx.outputs.output:
            ctx.actions.run_shell(outputs = [ctx.outputs.output], command = 'dont run me')
          dep_labels = []
          for dep in ctx.attr.deps:
            if NonAspectInfo in dep:
              dep_labels += [dep[NonAspectInfo].labels]
          return NonAspectInfo(labels = depset(direct = [ctx.label], transitive = dep_labels))

        aspect_with_files = aspect(
          implementation = _aspect_impl,
          attr_aspects = ['deps'],
          apply_to_generating_rules = True)

        aspect_no_files = aspect(
          implementation = _aspect_impl,
          attr_aspects = ['deps'],
          apply_to_generating_rules = False)

        root_with_files = rule(implementation = _rule_impl,
          attrs = {'deps' : attr.label_list(aspects = [aspect_with_files])})

        root_no_files = rule(implementation = _rule_impl,
          attrs = {'deps' : attr.label_list(aspects = [aspect_no_files])})

        dep_rule = rule(implementation = _dep_rule_impl,
          attrs = {'deps' : attr.label_list(allow_files = True), 'output' : attr.output()})
        """);

    // Create a target graph such that two graph roots each point to a common subgraph
    // alpha -> beta_output -> charlie, where beta_output is a generated output file of target
    // 'beta'.
    scratch.file(
        "test/BUILD",
        """
        load('//test:lib.bzl', 'root_with_files', 'root_no_files', 'dep_rule')

        root_with_files(name = 'test_with_files', deps = [':alpha'])
        root_no_files(name = 'test_no_files', deps = [':alpha'])
        dep_rule(name = 'alpha', deps = [':beta_output'])
        dep_rule(name = 'beta', deps = [':charlie'], output = 'beta_output')
        dep_rule(name = 'charlie')
        """);

    StarlarkProvider.Key rootInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "RootInfo");

    AnalysisResult analysisResultWithFiles = update("//test:test_with_files");
    ConfiguredTarget targetWithFiles =
        Iterables.getOnlyElement(analysisResultWithFiles.getTargetsToBuild());
    StructImpl rootInfoWithFiles = (StructImpl) targetWithFiles.get(rootInfoKey);
    // With apply_to_generating_rules=True, the aspect should have traversed :beta_output and
    // applied to both :beta and :charlie.
    assertThat(rootInfoWithFiles.getValue("from_aspect", Sequence.class))
        .containsExactly(
            Label.parseCanonical("//test:charlie"),
            Label.parseCanonical("//test:beta"),
            Label.parseCanonical("//test:alpha"));
    assertThat(rootInfoWithFiles.getValue("non_aspect", Sequence.class))
        .containsExactly(Label.parseCanonical("//test:alpha"));

    AnalysisResult analysisResultNoFiles = update("//test:test_no_files");
    ConfiguredTarget targetNoFiles =
        Iterables.getOnlyElement(analysisResultNoFiles.getTargetsToBuild());
    StructImpl rootInfoNoFiles = (StructImpl) targetNoFiles.get(rootInfoKey);
    // With apply_to_generating_rules=False, the aspect should have only accessed :alpha, as it
    // must have stopped before :beta_output.
    assertThat(rootInfoNoFiles.getValue("from_aspect", Sequence.class))
        .containsExactly(Label.parseCanonical("//test:alpha"));
    assertThat(rootInfoWithFiles.getValue("non_aspect", Sequence.class))
        .containsExactly(Label.parseCanonical("//test:alpha"));
  }

  private void setupAspectOnAspectTargetGraph(
      boolean applyRootToGeneratingRules, boolean applyDepToGeneratingRules) throws Exception {
    // RootAspectInfo.both_labels returns a list of target labels which
    //     were evaluated as [root_aspect(dep_aspect(target))].
    // RootAspectInfo.root_only_labels returns a list of target labels which
    //     were evaluated as [root_aspect(target)].
    // DepAspectInfo.labels returns a list of target labels which were evaluated by dep_aspect.
    scratch.file(
        "test/lib.bzl",
        "RootAspectInfo = provider()",
        "DepAspectInfo = provider()",
        "def _root_aspect_impl(target, ctx):",
        "  both_labels = []",
        "  root_only_labels = []",
        "  for dep in ctx.rule.attr.deps:",
        "    if RootAspectInfo in dep:",
        "      both_labels += dep[RootAspectInfo].both_labels",
        "      root_only_labels += dep[RootAspectInfo].root_only_labels",
        "      if DepAspectInfo in dep:",
        "        both_labels += [dep.label]",
        "      else:",
        "        root_only_labels += [dep.label]",
        "  return RootAspectInfo(both_labels = both_labels, root_only_labels = root_only_labels)",
        "",
        "def _dep_aspect_impl(target, ctx):",
        "  dep_labels = [ctx.label]",
        "  for dep in ctx.rule.attr.deps:",
        "    if DepAspectInfo in dep:",
        "      dep_labels += dep[DepAspectInfo].labels",
        "  return DepAspectInfo(labels = dep_labels)",
        "",
        "def _root_rule_impl(ctx):",
        "  return [ctx.attr.deps[0][RootAspectInfo], ctx.attr.deps[0][DepAspectInfo]]",
        "",
        "def _dep_with_aspect_rule_impl(ctx):",
        "  return [ctx.attr.deps[0][DepAspectInfo]]",
        "",
        "def _dep_rule_impl(ctx):",
        "  if ctx.outputs.output:",
        "    ctx.actions.run_shell(outputs = [ctx.outputs.output], command = 'dont run me')",
        "  return []",
        "",
        "root_aspect = aspect(",
        "  implementation = _root_aspect_impl,",
        "  attr_aspects = ['deps'],",
        "  required_aspect_providers = [DepAspectInfo],",
        "  apply_to_generating_rules = " + (applyRootToGeneratingRules ? "True" : "False") + ")",
        "",
        "dep_aspect = aspect(",
        "  implementation = _dep_aspect_impl,",
        "  attr_aspects = ['deps'],",
        "  provides = [DepAspectInfo],",
        "  apply_to_generating_rules = " + (applyDepToGeneratingRules ? "True" : "False") + ")",
        "",
        "root_rule = rule(implementation = _root_rule_impl,",
        "  attrs = {'deps' : attr.label_list(aspects = [root_aspect])})",
        "",
        "dep_with_aspect_rule = rule(implementation = _dep_with_aspect_rule_impl,",
        "  attrs = {'deps' : attr.label_list(aspects = [dep_aspect])})",
        "",
        "dep_rule = rule(implementation = _dep_rule_impl,",
        "  attrs = {'deps' : attr.label_list(allow_files = True), 'output' : attr.output()})");

    // Target graph: test -> aspect_propagating_target -> alpha -> beta_output
    // beta_output is an output of target `beta`
    // beta -> charlie
    scratch.file(
        "test/BUILD",
        """
        load('//test:lib.bzl', 'root_rule', 'dep_with_aspect_rule', 'dep_rule')

        root_rule(name = 'test', deps = [':aspect_propagating_target'])
        dep_with_aspect_rule(name = 'aspect_propagating_target', deps = [':alpha'])
        dep_rule(name = 'alpha', deps = [':beta_output'])
        dep_rule(name = 'beta', deps = [':charlie'], output = 'beta_output')
        dep_rule(name = 'charlie')
        """);
  }

  @Test
  public void testAspectOnAspectApplyToGeneratingRules_bothPropagate() throws Exception {
    setupAspectOnAspectTargetGraph(
        /* applyRootToGeneratingRules= */ true, /* applyDepToGeneratingRules= */ true);

    StarlarkProvider.Key rootInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "RootAspectInfo");
    StarlarkProvider.Key depInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "DepAspectInfo");

    AnalysisResult analysisResult = update("//test:test");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StructImpl rootInfo = (StructImpl) target.get(rootInfoKey);
    StructImpl depInfo = (StructImpl) target.get(depInfoKey);

    assertThat(rootInfo.getValue("both_labels", Sequence.class))
        .containsExactly(
            Label.parseCanonical("//test:alpha"),
            Label.parseCanonical("//test:beta_output"),
            Label.parseCanonical("//test:charlie"));
    assertThat(rootInfo.getValue("root_only_labels", Sequence.class)).isEmpty();
    assertThat(depInfo.getValue("labels", Sequence.class))
        .containsExactly(
            Label.parseCanonical("//test:alpha"),
            Label.parseCanonical("//test:beta"),
            Label.parseCanonical("//test:charlie"));
  }

  @Test
  public void testAspectOnAspectApplyToGeneratingRules_neitherPropagate() throws Exception {
    setupAspectOnAspectTargetGraph(
        /* applyRootToGeneratingRules= */ false, /* applyDepToGeneratingRules= */ false);

    StarlarkProvider.Key rootInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "RootAspectInfo");
    StarlarkProvider.Key depInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "DepAspectInfo");

    AnalysisResult analysisResult = update("//test:test");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StructImpl rootInfo = (StructImpl) target.get(rootInfoKey);
    StructImpl depInfo = (StructImpl) target.get(depInfoKey);

    assertThat(rootInfo.getValue("both_labels", Sequence.class))
        .containsExactly(Label.parseCanonical("//test:alpha"));
    assertThat(rootInfo.getValue("root_only_labels", Sequence.class)).isEmpty();
    assertThat(depInfo.getValue("labels", Sequence.class))
        .containsExactly(Label.parseCanonical("//test:alpha"));
  }

  @Test
  public void testAspectOnAspectApplyToGeneratingRules_rootOnly() throws Exception {
    setupAspectOnAspectTargetGraph(
        /* applyRootToGeneratingRules= */ true, /* applyDepToGeneratingRules= */ false);

    StarlarkProvider.Key rootInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "RootAspectInfo");
    StarlarkProvider.Key depInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "DepAspectInfo");

    AnalysisResult analysisResult = update("//test:test");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StructImpl rootInfo = (StructImpl) target.get(rootInfoKey);
    StructImpl depInfo = (StructImpl) target.get(depInfoKey);

    assertThat(rootInfo.getValue("both_labels", Sequence.class))
        .containsExactly(Label.parseCanonical("//test:alpha"));
    assertThat(rootInfo.getValue("root_only_labels", Sequence.class))
        .containsExactly(
            Label.parseCanonical("//test:beta_output"), Label.parseCanonical("//test:charlie"));
    assertThat(depInfo.getValue("labels", Sequence.class))
        .containsExactly(Label.parseCanonical("//test:alpha"));
  }

  @Test
  public void testAspectOnAspectApplyToGeneratingRules_depOnly() throws Exception {
    setupAspectOnAspectTargetGraph(
        /* applyRootToGeneratingRules= */ false, /* applyDepToGeneratingRules= */ true);

    StarlarkProvider.Key rootInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "RootAspectInfo");
    StarlarkProvider.Key depInfoKey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:lib.bzl"), "DepAspectInfo");

    AnalysisResult analysisResult = update("//test:test");
    ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StructImpl rootInfo = (StructImpl) target.get(rootInfoKey);
    StructImpl depInfo = (StructImpl) target.get(depInfoKey);

    assertThat(rootInfo.getValue("both_labels", Sequence.class))
        .containsExactly(Label.parseCanonical("//test:alpha"));
    assertThat(rootInfo.getValue("root_only_labels", Sequence.class)).isEmpty();
    assertThat(depInfo.getValue("labels", Sequence.class))
        .containsExactly(
            Label.parseCanonical("//test:alpha"),
            Label.parseCanonical("//test:beta"),
            Label.parseCanonical("//test:charlie"));
  }

  @Test
  public void testAspectActionsDontInheritExecProperties() throws Exception {
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'my_target',
          deps = [':my_dep'],
        )
        cc_binary(
          name = 'my_dep',
          srcs = ['dep.cc'],
          exec_properties = {'mem': '16g'},
        )
        """);
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_impl(target, ctx):
          f = ctx.actions.declare_file('f.txt')
          ctx.actions.write(f, 'f')
          return []
        my_aspect = aspect(
          implementation = _aspect_impl,
          attr_aspects = ['deps'],
        )
        def _rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _rule_impl,
          attrs = {
            'deps': attr.label_list(aspects = [my_aspect])
          },
        )
        """);
    scratch.file("test/dep.cc", "int main() {return 0;}");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%my_aspect"), "//test:my_target");
    assertThat(analysisResult).isNotNull();
    ActionOwner owner =
        Iterables.getOnlyElement(
                Iterables.getOnlyElement(analysisResult.getAspectsMap().values()).getActions())
            .getOwner();
    assertThat(owner.getExecProperties()).isEmpty();
  }

  @Test
  public void testAspectRequiredProviders_defaultNoRequiredProviders() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()

        AspectInfo = provider()
        def _my_aspect_impl(target, ctx):
          targets_labels = ["//test:defs.bzl%my_aspect({})".format(target.label)]
          for dep in ctx.rule.attr.deps:
            if AspectInfo in dep:
              targets_labels.extend(dep[AspectInfo].target_labels)
          return [AspectInfo(target_labels = targets_labels)]

        my_aspect = aspect(
          implementation = _my_aspect_impl,
          attr_aspects = ['deps'],
        )

        RuleInfo = provider()
        def _rule_without_providers_impl(ctx):
          s = []
          for dep in ctx.attr.deps:
            if AspectInfo in dep:
              s.extend(dep[AspectInfo].target_labels)
          return RuleInfo(rule_deps = s)

        rule_without_providers = rule(
          implementation = _rule_without_providers_impl,
          attrs = {
            'deps': attr.label_list(aspects = [my_aspect])
          },
        )

        def _rule_with_providers_impl(ctx):
          return [prov_a(), prov_b()]

        rule_with_providers = rule(
          implementation = _rule_with_providers_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = [prov_a, prov_b]
        )

        rule_with_providers_not_advertised = rule(
          implementation = _rule_with_providers_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = []
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'rule_with_providers', 'rule_without_providers',
                                'rule_with_providers_not_advertised')
        rule_without_providers(
          name = 'main',
          deps = [':target_without_providers', ':target_with_providers',
                  ':target_with_providers_not_advertised'],
        )
        rule_without_providers(
          name = 'target_without_providers',
        )
        rule_with_providers(
          name = 'target_with_providers',
        )
        rule_with_providers(
          name = 'target_with_providers_indeps',
        )
        rule_with_providers_not_advertised(
          name = 'target_with_providers_not_advertised',
          deps = [':target_with_providers_indeps'],
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    // my_aspect does not require any providers so it will be applied to all the dependencies of
    // main target
    List<String> expected = new ArrayList<>();
    expected.add("//test:defs.bzl%my_aspect(@//test:target_without_providers)");
    expected.add("//test:defs.bzl%my_aspect(@//test:target_with_providers)");
    expected.add("//test:defs.bzl%my_aspect(@//test:target_with_providers_not_advertised)");
    expected.add("//test:defs.bzl%my_aspect(@//test:target_with_providers_indeps)");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:main");
    ConfiguredTarget target = analysisResult.getTargetsToBuild().iterator().next();
    Object ruleDepsUnchecked = getStarlarkProvider(target, "RuleInfo").getValue("rule_deps");
    assertThat(ruleDepsUnchecked).isInstanceOf(StarlarkList.class);
    StarlarkList<?> ruleDeps = (StarlarkList) ruleDepsUnchecked;
    assertThat(Starlark.toIterable(ruleDeps)).containsExactlyElementsIn(expected);
  }

  @Test
  public void testAspectRequiredProviders_flatSetOfRequiredProviders() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()

        AspectInfo = provider()
        def _my_aspect_impl(target, ctx):
          targets_labels = ["//test:defs.bzl%my_aspect({})".format(target.label)]
          for dep in ctx.rule.attr.deps:
            if AspectInfo in dep:
              targets_labels.extend(dep[AspectInfo].target_labels)
          return AspectInfo(target_labels = targets_labels)

        my_aspect = aspect(
          implementation = _my_aspect_impl,
          attr_aspects = ['deps'],
          required_providers = [prov_a, prov_b],
        )

        RuleInfo = provider()
        def _rule_without_providers_impl(ctx):
          s = []
          for dep in ctx.attr.deps:
            if AspectInfo in dep:
              s.extend(dep[AspectInfo].target_labels)
          return RuleInfo(rule_deps = s)

        rule_without_providers = rule(
          implementation = _rule_without_providers_impl,
          attrs = {
            'deps': attr.label_list(aspects=[my_aspect])
          },
          provides = []
        )

        def _rule_with_a_impl(ctx):
          return [prov_a()]

        rule_with_a = rule(
          implementation = _rule_with_a_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = [prov_a]
        )

        def _rule_with_ab_impl(ctx):
          return [prov_a(), prov_b()]

        rule_with_ab = rule(
          implementation = _rule_with_ab_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = [prov_a, prov_b]
        )

        rule_with_ab_not_advertised = rule(
          implementation = _rule_with_ab_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = []
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'rule_without_providers', 'rule_with_a', 'rule_with_ab',
                                'rule_with_ab_not_advertised')
        rule_without_providers(
          name = 'main',
          deps = [':target_without_providers', ':target_with_a', ':target_with_ab',
                  ':target_with_ab_not_advertised'],
        )
        rule_without_providers(
          name = 'target_without_providers',
        )
        rule_with_a(
          name = 'target_with_a',
          deps = [':target_with_ab_indeps_not_reached']
        )
        rule_with_ab(
          name = 'target_with_ab',
          deps = [':target_with_ab_indeps_reached']
        )
        rule_with_ab(
          name = 'target_with_ab_indeps_not_reached',
        )
        rule_with_ab(
          name = 'target_with_ab_indeps_reached',
        )
        rule_with_ab_not_advertised(
          name = 'target_with_ab_not_advertised',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    // my_aspect will only be applied on target_with_ab and target_with_ab_indeps_reached since
    // their rule (rule_with_ab) is the only rule that advertises the aspect required providers.
    // However, my_aspect cannot be propagated to target_with_ab_indeps_not_reached because it was
    // not applied to its parent (target_with_a)
    List<String> expected = new ArrayList<>();
    expected.add("//test:defs.bzl%my_aspect(@//test:target_with_ab)");
    expected.add("//test:defs.bzl%my_aspect(@//test:target_with_ab_indeps_reached)");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:main");
    ConfiguredTarget target = analysisResult.getTargetsToBuild().iterator().next();
    Object ruleDepsUnchecked = getStarlarkProvider(target, "RuleInfo").getValue("rule_deps");
    assertThat(ruleDepsUnchecked).isInstanceOf(StarlarkList.class);
    StarlarkList<?> ruleDeps = (StarlarkList) ruleDepsUnchecked;
    assertThat(Starlark.toIterable(ruleDeps)).containsExactlyElementsIn(expected);
  }

  @Test
  public void testAspectRequiredProviders_listOfRequiredProvidersLists() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()
        prov_c = provider()
        AspectInfo = provider()
        def _my_aspect_impl(target, ctx):
          targets_labels = ["//test:defs.bzl%my_aspect({})".format(target.label)]
          for dep in ctx.rule.attr.deps:
            if AspectInfo in dep:
              targets_labels.extend(dep[AspectInfo].target_labels)
          return [AspectInfo(target_labels = targets_labels)]

        my_aspect = aspect(
          implementation = _my_aspect_impl,
          attr_aspects = ['deps'],
          required_providers = [[prov_a, prov_b], [prov_c]],
        )

        RuleInfo = provider()
        def _rule_without_providers_impl(ctx):
          s = []
          for dep in ctx.attr.deps:
            if AspectInfo in dep:
              s.extend(dep[AspectInfo].target_labels)
          return RuleInfo(rule_deps = s)

        rule_without_providers = rule(
          implementation = _rule_without_providers_impl,
          attrs = {
            'deps': attr.label_list(aspects=[my_aspect])
          },
          provides = []
        )

        def _rule_with_a_impl(ctx):
          return [prov_a()]

        rule_with_a = rule(
          implementation = _rule_with_a_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = [prov_a]
        )

        def _rule_with_c_impl(ctx):
          return [prov_c()]

        rule_with_c = rule(
          implementation = _rule_with_c_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = [prov_c]
        )

        def _rule_with_ab_impl(ctx):
          return [prov_a(), prov_b()]

        rule_with_ab = rule(
          implementation = _rule_with_ab_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = [prov_a, prov_b]
        )

        rule_with_ab_not_advertised = rule(
          implementation = _rule_with_ab_impl,
          attrs = {
            'deps': attr.label_list()
          },
          provides = []
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'rule_without_providers', 'rule_with_a', 'rule_with_c',
                                'rule_with_ab', 'rule_with_ab_not_advertised')
        rule_without_providers(
          name = 'main',
          deps = [':target_without_providers', ':target_with_a', ':target_with_c',
                  ':target_with_ab', 'target_with_ab_not_advertised'],
        )
        rule_without_providers(
          name = 'target_without_providers',
        )
        rule_with_a(
          name = 'target_with_a',
          deps = [':target_with_c_indeps_not_reached'],
        )
        rule_with_c(
          name = 'target_with_c',
        )
        rule_with_c(
          name = 'target_with_c_indeps_reached',
        )
        rule_with_c(
          name = 'target_with_c_indeps_not_reached',
        )
        rule_with_ab(
          name = 'target_with_ab',
          deps = [':target_with_c_indeps_reached'],
        )
        rule_with_ab_not_advertised(
          name = 'target_with_ab_not_advertised',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    // my_aspect will only be applied on target_with_ab, target_wtih_c and
    // target_with_c_indeps_reached because their rules (rule_with_ab and rule_with_c) are the only
    // rules advertising the aspect required providers
    // However, my_aspect cannot be propagated to target_with_c_indeps_not_reached because it was
    // not applied to its parent (target_with_a)
    List<String> expected = new ArrayList<>();
    expected.add("//test:defs.bzl%my_aspect(@//test:target_with_ab)");
    expected.add("//test:defs.bzl%my_aspect(@//test:target_with_c)");
    expected.add("//test:defs.bzl%my_aspect(@//test:target_with_c_indeps_reached)");
    assertThat(getLabelsToBuild(analysisResult)).containsExactly("//test:main");
    ConfiguredTarget target = analysisResult.getTargetsToBuild().iterator().next();
    Object ruleDepsUnchecked = getStarlarkProvider(target, "RuleInfo").getValue("rule_deps");
    assertThat(ruleDepsUnchecked).isInstanceOf(StarlarkList.class);
    StarlarkList<?> ruleDeps = (StarlarkList) ruleDepsUnchecked;
    assertThat(Starlark.toIterable(ruleDeps)).containsExactlyElementsIn(expected);
  }

  @Test
  public void testAspectRequiredByMultipleAspects_inheritsAttrAspects() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()
        prov_c = provider()

        def _aspect_c_impl(target, ctx):
          res = ['aspect_c runs on target {}'.format(target.label)]
          return [prov_c(val = res)]
        aspect_c = aspect(
          implementation = _aspect_c_impl,
        )

        def _aspect_b_impl(target, ctx):
          res = []
          res += target[prov_c].val
          res += ['aspect_b runs on target {}'.format(target.label)]
          if ctx.rule.attr.dep_b:
            res += ctx.rule.attr.dep_b[prov_b].val
          return [prov_b(val = res)]
        aspect_b = aspect(
          implementation = _aspect_b_impl,
          attr_aspects = ['dep_b'],
          requires = [aspect_c],
        )

        def _aspect_a_impl(target, ctx):
          res = []
          res += target[prov_c].val
          res += ['aspect_a runs on target {}'.format(target.label)]
          if ctx.rule.attr.dep_a:
            res += ctx.rule.attr.dep_a[prov_a].val
          return [prov_a(val = res)]
        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep_a'],
          requires = [aspect_c],
        )

        def _my_rule_impl(ctx):
          pass

        my_rule = rule(
          implementation = _my_rule_impl,
          attrs = {
            'dep_a': attr.label(),
            'dep_b': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep_a = ':dep_target_a',
          dep_b = ':dep_target_b',
        )
        my_rule(
          name = 'dep_target_a',
        )
        my_rule(
          name = 'dep_target_b',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
            "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    // aspect_a should run on main_target and dep_target_a and can retrieve aspect_c provider value
    // on both of them
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkProvider.Key aResult =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "prov_a");
    StructImpl aResultProvider = (StructImpl) aspectA.get(aResult);
    assertThat((Sequence<?>) aResultProvider.getValue("val"))
        .containsExactly(
            "aspect_c runs on target @//test:dep_target_a",
            "aspect_a runs on target @//test:dep_target_a",
            "aspect_c runs on target @//test:main_target",
            "aspect_a runs on target @//test:main_target");

    // aspect_b should run on main_target and dep_target_b and can retrieve aspect_c provider value
    // on both of them
    ConfiguredAspect aspectB = getConfiguredAspect(configuredAspects, "aspect_b");
    assertThat(aspectA).isNotNull();
    StarlarkProvider.Key bResult =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "prov_b");
    StructImpl bResultProvider = (StructImpl) aspectB.get(bResult);
    assertThat((Sequence<?>) bResultProvider.getValue("val"))
        .containsExactly(
            "aspect_c runs on target @//test:dep_target_b",
            "aspect_b runs on target @//test:dep_target_b",
            "aspect_c runs on target @//test:main_target",
            "aspect_b runs on target @//test:main_target");
  }

  @Test
  public void testAspectRequiredByMultipleAspects_inheritsRequiredProviders() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        aspect_prov_a = provider()
        aspect_prov_b = provider()
        aspect_prov_c = provider()
        rule_prov_a = provider()
        rule_prov_b = provider()
        rule_prov_c = provider()

        def _aspect_c_impl(target, ctx):
          res = ['aspect_c runs on target {}'.format(target.label)]
          return [aspect_prov_c(val = res)]
        aspect_c = aspect(
          implementation = _aspect_c_impl,
          required_providers = [rule_prov_c],
        )

        def _aspect_b_impl(target, ctx):
          res = []
          if aspect_prov_c in target:
            res += target[aspect_prov_c].val
          res += ['aspect_b runs on target {}'.format(target.label)]
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              if aspect_prov_b in dep:
                res += dep[aspect_prov_b].val
          return [aspect_prov_b(val = res)]
        aspect_b = aspect(
          implementation = _aspect_b_impl,
          attr_aspects = ['deps'],
          required_providers = [[rule_prov_b], [rule_prov_c]],
          requires = [aspect_c],
        )

        def _aspect_a_impl(target, ctx):
          res = []
          if aspect_prov_c in target:
            res += target[aspect_prov_c].val
          res += ['aspect_a runs on target {}'.format(target.label)]
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              if aspect_prov_a in dep:
                res += dep[aspect_prov_a].val
          return [aspect_prov_a(val = res)]
        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['deps'],
          required_providers = [[rule_prov_a], [rule_prov_c]],
          requires = [aspect_c],
        )

        def _my_rule_impl(ctx):
          return [rule_prov_a(), rule_prov_b()]

        my_rule = rule(
          implementation = _my_rule_impl,
          attrs = {
            'deps': attr.label_list(),
          },
          provides = [rule_prov_a, rule_prov_b]
        )

        def _rule_with_prov_a_impl(ctx):
          return [rule_prov_a()]

        rule_with_prov_a = rule(
          implementation = _rule_with_prov_a_impl,
          attrs = {
            'deps': attr.label_list(),
          },
          provides = [rule_prov_a]
        )

        def _rule_with_prov_b_impl(ctx):
          return [rule_prov_b()]

        rule_with_prov_b = rule(
          implementation = _rule_with_prov_b_impl,
          attrs = {
            'deps': attr.label_list(),
          },
          provides = [rule_prov_b]
        )

        def _rule_with_prov_c_impl(ctx):
          return [rule_prov_c()]
        rule_with_prov_c = rule(
          implementation = _rule_with_prov_c_impl,
          attrs = {
            'deps': attr.label_list(),
          },
          provides = [rule_prov_c]
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule', 'rule_with_prov_a',
                                'rule_with_prov_b', 'rule_with_prov_c')
        my_rule(
          name = 'main_target',
          deps = [':dep_target_with_prov_a', ':dep_target_with_prov_b']
        )
        rule_with_prov_a(
          name = 'dep_target_with_prov_a',
          deps = [':dep_target_with_prov_c'],
        )
        rule_with_prov_b(
          name = 'dep_target_with_prov_b',
          deps = [':dep_target_with_prov_c'],
        )
        rule_with_prov_c(
          name = 'dep_target_with_prov_c',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
            "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    // aspect_a runs on main_target, dep_target_with_prov_a and dep_target_with_prov_c and it can
    // only retrieve aspect_c provider value on dep_target_with_prov_c
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkProvider.Key aResult =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "aspect_prov_a");
    StructImpl aResultProvider = (StructImpl) aspectA.get(aResult);
    assertThat((Sequence<?>) aResultProvider.getValue("val"))
        .containsExactly(
            "aspect_c runs on target @//test:dep_target_with_prov_c",
            "aspect_a runs on target @//test:dep_target_with_prov_c",
            "aspect_a runs on target @//test:dep_target_with_prov_a",
            "aspect_a runs on target @//test:main_target");

    // aspect_b runs on main_target, dep_target_with_prov_b and dep_target_with_prov_c and it can
    // only retrieve aspect_c provider value on dep_target_with_prov_c
    ConfiguredAspect aspectB = getConfiguredAspect(configuredAspects, "aspect_b");
    assertThat(aspectA).isNotNull();
    StarlarkProvider.Key bResult =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "aspect_prov_b");
    StructImpl bResultProvider = (StructImpl) aspectB.get(bResult);
    assertThat((Sequence<?>) bResultProvider.getValue("val"))
        .containsExactly(
            "aspect_c runs on target @//test:dep_target_with_prov_c",
            "aspect_b runs on target @//test:dep_target_with_prov_c",
            "aspect_b runs on target @//test:dep_target_with_prov_b",
            "aspect_b runs on target @//test:main_target");
  }

  @Test
  public void testAspectRequiredByMultipleAspects_withDifferentParametersValues() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()
        prov_c = provider()

        def _aspect_c_impl(target, ctx):
          res = ['aspect_c runs on target {} and param = {}'.format(target.label, ctx.attr.p)]
          return [prov_c(val = res)]
        aspect_c = aspect(
          implementation = _aspect_c_impl,
          attrs = {
            'p': attr.string(values=['rule_1_val', 'rule_2_val']),
          },
        )

        def _aspect_b_impl(target, ctx):
          res = []
          res += target[prov_c].val
          res += ['aspect_b runs on target {}'.format(target.label)]
          if ctx.rule.attr.dep:
            res += ctx.rule.attr.dep[prov_b].val
          return [prov_b(val = res)]
        aspect_b = aspect(
          implementation = _aspect_b_impl,
          attr_aspects = ['dep'],
          requires = [aspect_c],
        )

        def _aspect_a_impl(target, ctx):
          res = []
          res += target[prov_c].val
          res += ['aspect_a runs on target {}'.format(target.label)]
          if ctx.rule.attr.dep:
            res += ctx.rule.attr.dep[prov_a].val
          return [prov_a(val = res)]
        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          requires = [aspect_c],
        )

        def _rule_1_impl(ctx):
          return ctx.attr.dep[prov_a]

        rule_1 = rule(
          implementation = _rule_1_impl,
          attrs = {
            'dep': attr.label(aspects = [aspect_a]),
            'p': attr.string(values = ['rule_1_val', 'rule_2_val'])
          },
        )

        def _rule_2_impl(ctx):
          return ctx.attr.dep[prov_b]

        rule_2 = rule(
          implementation = _rule_2_impl,
          attrs = {
            'dep': attr.label(aspects = [aspect_b]),
            'p': attr.string(values = ['rule_1_val', 'rule_2_val'])
          },
        )

        def _rule_3_impl(ctx):
          pass

        rule_3 = rule(
          implementation = _rule_3_impl,
          attrs = {
            'dep': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'rule_1', 'rule_2', 'rule_3')
        rule_1(
          name = 'target_1',
          dep = ':dep_1',
          p = 'rule_1_val'
        )
        rule_2(
          name = 'target_2',
          dep = ':dep_2',
          p = 'rule_2_val'
        )
        rule_3(
          name = 'dep_1',
          dep = ':dep_3',
        )
        rule_3(
          name = 'dep_2',
          dep = ':dep_3',
        )
        rule_3(
          name = 'dep_3',
        )
        """);

    AnalysisResult analysisResult = update("//test:target_1", "//test:target_2");

    Iterator<ConfiguredTarget> it = analysisResult.getTargetsToBuild().iterator();
    // aspect_a runs on dep_1 and dep_3 and it can retrieve aspect_c provider value on them
    // aspect_c here should get its parameter value from rule_2
    ConfiguredTarget target1 = it.next();
    StarlarkProvider.Key provAkey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "prov_a");
    StructImpl provA = (StructImpl) target1.get(provAkey);
    assertThat((Sequence<?>) provA.getValue("val"))
        .containsExactly(
            "aspect_c runs on target @//test:dep_1 and param = rule_1_val",
            "aspect_a runs on target @//test:dep_1",
            "aspect_c runs on target @//test:dep_3 and param = rule_1_val",
            "aspect_a runs on target @//test:dep_3");

    // aspect_b runs on dep_2 and dep_3 and it can retrieve aspect_c provider value on them.
    // aspect_c here should get its parameter value from rule_2
    ConfiguredTarget target2 = it.next();
    StarlarkProvider.Key provBkey =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "prov_b");
    StructImpl provB = (StructImpl) target2.get(provBkey);
    assertThat((Sequence<?>) provB.getValue("val"))
        .containsExactly(
            "aspect_c runs on target @//test:dep_2 and param = rule_2_val",
            "aspect_b runs on target @//test:dep_2",
            "aspect_c runs on target @//test:dep_3 and param = rule_2_val",
            "aspect_b runs on target @//test:dep_3");
  }

  @Test
  public void testAspectRequiresAspect_requireNativeAspect() throws Exception {
    exposeNativeAspectToStarlark();
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        def _impl(target, ctx):
          res = 'aspect_a on target {} '.format(target.label)
          if hasattr(target, 'native_aspect_prov'):
            res += 'can see native aspect provider'
          else:
            res += 'cannot see native aspect provider'
          complete_res = [res]
          if hasattr(ctx.rule.attr, 'dep'):
            complete_res += ctx.rule.attr.dep[prov_a].val
          return [prov_a(val = complete_res)]
        aspect_a = aspect(implementation = _impl,
                          requires = [starlark_native_aspect],
                          attr_aspects = ['dep'],)

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(implementation = _my_rule_impl,
                       attrs = {'dep': attr.label()})
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_1',
        )
        my_rule(
          name = 'dep_1',
          dep = ':dep_2',
        )
        honest(
          name = 'dep_2',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    // aspect_a runs on main_target, dep_1 and dep_2 but it can only see the required native aspect
    // run on dep_2 because its rule satisfies its required provider.
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkProvider.Key aResult =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "prov_a");
    StructImpl aResultProvider = (StructImpl) aspectA.get(aResult);
    assertThat((Sequence<?>) aResultProvider.getValue("val"))
        .containsExactly(
            "aspect_a on target @//test:main_target cannot see native aspect provider",
            "aspect_a on target @//test:dep_1 cannot see native aspect provider",
            "aspect_a on target @//test:dep_2 can see native aspect provider");
  }

  @Test
  public void testAspectRequiresAspect_aspectsParameters() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        RequiredAspectProv = provider()
        BaseAspectProv = provider()

        def _required_aspect_impl(target, ctx):
          p1_val = 'In required_aspect, p1 = {} on target {}'.format(ctx.attr.p1, target.label)
          p2_val = 'invalid value'
          if not hasattr(ctx.attr, 'p2'):
            p2_val = 'In required_aspect, p2 not found on target {}'.format(target.label)
          return [RequiredAspectProv(p1_val = p1_val, p2_val = p2_val)]
        required_aspect = aspect(
          implementation = _required_aspect_impl,
          attr_aspects = ['dep'],
          attrs = {'p1' : attr.string(values = ['p1_v1', 'p1_v2'])}
        )

        def _base_aspect_impl(target, ctx):
          p2_val = 'In base_aspect, p2 = {} on target {}'.format(ctx.attr.p2, target.label)
          p1_val = 'invalid value'
          if not hasattr(ctx.attr, 'p1'):
            p1_val = 'In base_aspect, p1 not found on target {}'.format(target.label)
          return [BaseAspectProv(p1_val = p1_val, p2_val = p2_val)]
        base_aspect = aspect(
          implementation = _base_aspect_impl,
          attr_aspects = ['dep'],
          attrs = {'p2' : attr.string(values = ['p2_v1', 'p2_v2'])},
          requires = [required_aspect],
        )

        def _main_rule_impl(ctx):
          return [ctx.attr.dep[RequiredAspectProv], ctx.attr.dep[BaseAspectProv]]
        def _dep_rule_impl(ctx):
          pass

        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'dep': attr.label(aspects=[base_aspect]),
            'p1' : attr.string(values = ['p1_v1', 'p1_v2']),
            'p2' : attr.string(values = ['p2_v1', 'p2_v2'])
          },
        )

        dep_rule = rule(
          implementation = _dep_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule', 'dep_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
          p1 = 'p1_v1',
          p2 = 'p2_v1'
        )
        dep_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    // Both base_aspect and required_aspect can get their parameters values from the base rule
    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkProvider.Key requiredAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "RequiredAspectProv");
    StructImpl requiredAspectProvider = (StructImpl) configuredTarget.get(requiredAspectProv);
    assertThat(requiredAspectProvider.getValue("p1_val"))
        .isEqualTo("In required_aspect, p1 = p1_v1 on target @//test:dep_target");
    assertThat(requiredAspectProvider.getValue("p2_val"))
        .isEqualTo("In required_aspect, p2 not found on target @//test:dep_target");

    StarlarkProvider.Key baseAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "BaseAspectProv");
    StructImpl baseAspectProvider = (StructImpl) configuredTarget.get(baseAspectProv);
    assertThat(baseAspectProvider.getValue("p1_val"))
        .isEqualTo("In base_aspect, p1 not found on target @//test:dep_target");
    assertThat(baseAspectProvider.getValue("p2_val"))
        .isEqualTo("In base_aspect, p2 = p2_v1 on target @//test:dep_target");
  }

  @Test
  public void testAspectRequiresAspect_ruleAttributes() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        RequiredAspectProv = provider()
        BaseAspectProv = provider()

        def _required_aspect_impl(target, ctx):
          p_val = 'In required_aspect, p = {} on target {}'.format(ctx.rule.attr.p, target.label)
          return [RequiredAspectProv(p_val = p_val)]
        required_aspect = aspect(
          implementation = _required_aspect_impl,
        )

        def _base_aspect_impl(target, ctx):
          p_val = 'In base_aspect, p = {} on target {}'.format(ctx.rule.attr.p, target.label)
          return [BaseAspectProv(p_val = p_val)]
        base_aspect = aspect(
          implementation = _base_aspect_impl,
          attr_aspects = ['dep'],
          requires = [required_aspect],
        )

        def _main_rule_impl(ctx):
          return [ctx.attr.dep[RequiredAspectProv], ctx.attr.dep[BaseAspectProv]]
        def _dep_rule_impl(ctx):
          pass

        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'dep': attr.label(aspects=[base_aspect]),
          },
        )

        dep_rule = rule(
          implementation = _dep_rule_impl,
          attrs = {
            'p' : attr.string(values = ['p_v1', 'p_v2']),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule', 'dep_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
        )
        dep_rule(
          name = 'dep_target',
          p = 'p_v2',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    // Both base_aspect and required_aspect can see the attributes of the rule they run on
    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkProvider.Key requiredAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "RequiredAspectProv");
    StructImpl requiredAspectProvider = (StructImpl) configuredTarget.get(requiredAspectProv);
    assertThat(requiredAspectProvider.getValue("p_val"))
        .isEqualTo("In required_aspect, p = p_v2 on target @//test:dep_target");

    StarlarkProvider.Key baseAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "BaseAspectProv");
    StructImpl baseAspectProvider = (StructImpl) configuredTarget.get(baseAspectProv);
    assertThat(baseAspectProvider.getValue("p_val"))
        .isEqualTo("In base_aspect, p = p_v2 on target @//test:dep_target");
  }

  @Test
  public void testAspectRequiresAspect_inheritPropagationAttributes() throws Exception {
    // base_aspect propagates over base_dep attribute and requires first_required_aspect which
    // propagates over first_dep attribute and requires second_required aspect which propagates
    // over second_dep attribute
    scratch.file(
        "test/defs.bzl",
        """
        BaseAspectProv = provider()
        FirstRequiredAspectProv = provider()
        SecondRequiredAspectProv = provider()

        def _second_required_aspect_impl(target, ctx):
          result = []
          if getattr(ctx.rule.attr, 'second_dep'):
            result += getattr(ctx.rule.attr, 'second_dep')[SecondRequiredAspectProv].result
          result += ['second_required_aspect run on target {}'.format(target.label)]
          return [SecondRequiredAspectProv(result = result)]
        second_required_aspect = aspect(
          implementation = _second_required_aspect_impl,
          attr_aspects = ['second_dep'],
        )

        def _first_required_aspect_impl(target, ctx):
          result = []
          result += target[SecondRequiredAspectProv].result
          if getattr(ctx.rule.attr, 'first_dep'):
            result += getattr(ctx.rule.attr, 'first_dep')[FirstRequiredAspectProv].result
          result += ['first_required_aspect run on target {}'.format(target.label)]
          return [FirstRequiredAspectProv(result = result)]
        first_required_aspect = aspect(
          implementation = _first_required_aspect_impl,
          attr_aspects = ['first_dep'],
          requires = [second_required_aspect],
        )

        def _base_aspect_impl(target, ctx):
          result = []
          result += target[FirstRequiredAspectProv].result
          if getattr(ctx.rule.attr, 'base_dep'):
            result += getattr(ctx.rule.attr, 'base_dep')[BaseAspectProv].result
          result += ['base_aspect run on target {}'.format(target.label)]
          return [BaseAspectProv(result = result)]
        base_aspect = aspect(
          implementation = _base_aspect_impl,
          attr_aspects = ['base_dep'],
          requires = [first_required_aspect],
        )

        def _main_rule_impl(ctx):
          return [ctx.attr.dep[BaseAspectProv]]
        def _dep_rule_impl(ctx):
          pass

        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'dep': attr.label(aspects=[base_aspect]),
          },
        )

        dep_rule = rule(
          implementation = _dep_rule_impl,
          attrs = {
            'base_dep': attr.label(),
            'first_dep': attr.label(),
            'second_dep': attr.label()
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule', 'dep_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
        )
        dep_rule(
          name = 'dep_target',
          base_dep = ':base_dep_target',
          first_dep = ':first_dep_target',
          second_dep = ':second_dep_target',
        )
        dep_rule(
          name = 'base_dep_target',
        )
        dep_rule(
          name = 'first_dep_target',
        )
        dep_rule(
          name = 'second_dep_target',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    // base_aspect should propagate only along its attr_aspects: 'base_dep'
    // first_required_aspect should propagate along 'base_dep' and 'first_dep'
    // second_required_aspect should propagate along 'base_dep', 'first_dep' and `second_dep`
    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkProvider.Key baseAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "BaseAspectProv");
    StructImpl baseAspectProvider = (StructImpl) configuredTarget.get(baseAspectProv);
    assertThat((Sequence<?>) baseAspectProvider.getValue("result"))
        .containsExactly(
            "second_required_aspect run on target @//test:second_dep_target",
            "second_required_aspect run on target @//test:dep_target",
            "second_required_aspect run on target @//test:first_dep_target",
            "first_required_aspect run on target @//test:first_dep_target",
            "first_required_aspect run on target @//test:dep_target",
            "second_required_aspect run on target @//test:base_dep_target",
            "first_required_aspect run on target @//test:base_dep_target",
            "base_aspect run on target @//test:base_dep_target",
            "base_aspect run on target @//test:dep_target");
  }

  @Test
  public void testAspectRequiresAspect_inheritRequiredProviders() throws Exception {
    // aspect_a requires provider Prov_A and requires aspect_b which requires
    // provider Prov_B and requires aspect_c which requires provider Prov_C
    scratch.file(
        "test/defs.bzl",
        "Prov_A = provider()",
        "Prov_B = provider()",
        "Prov_C = provider()",
        "",
        "CollectorProv = provider()",
        "",
        "def _aspect_c_impl(target, ctx):",
        "  collector_result = ['aspect_c run on target {} and value of Prov_C ="
            + " {}'.format(target.label, target[Prov_C].val)]",
        "  return [CollectorProv(result = collector_result)]",
        "aspect_c = aspect(",
        "  implementation = _aspect_c_impl,",
        "  required_providers = [Prov_C],",
        "  attr_aspects = ['dep'],",
        ")",
        "",
        "def _aspect_b_impl(target, ctx):",
        "  collector_result = []",
        "  collector_result += ctx.rule.attr.dep[CollectorProv].result",
        "  collector_result += ['aspect_b run on target {} and value of Prov_B ="
            + " {}'.format(target.label, target[Prov_B].val)]",
        "  return [ CollectorProv(result = collector_result)]",
        "aspect_b = aspect(",
        "  implementation = _aspect_b_impl,",
        "  required_providers = [Prov_B],",
        "  requires = [aspect_c],",
        "  attr_aspects = ['dep'],",
        ")",
        "",
        "def _aspect_a_impl(target, ctx):",
        "  collector_result = []",
        "  collector_result += ctx.rule.attr.dep[CollectorProv].result",
        "  collector_result += ['aspect_a run on target {} and value of Prov_A ="
            + " {}'.format(target.label, target[Prov_A].val)]",
        "  return [CollectorProv(result = collector_result)]",
        "aspect_a = aspect(",
        "  implementation = _aspect_a_impl,",
        "  attr_aspects = ['dep'],",
        "  required_providers = [Prov_A],",
        "  requires = [aspect_b],",
        ")",
        "",
        "def _main_rule_impl(ctx):",
        "  return [ctx.attr.dep[CollectorProv]]",
        "main_rule = rule(",
        "  implementation = _main_rule_impl,",
        "  attrs = {",
        "    'dep': attr.label(aspects = [aspect_a]),",
        "  },",
        ")",
        "",
        "def _rule_with_prov_a_impl(ctx):",
        "  return [Prov_A(val='val_a')]",
        "rule_with_prov_a = rule(",
        "  implementation = _rule_with_prov_a_impl,",
        "  attrs = {",
        "    'dep': attr.label(),",
        "  },",
        "  provides = [Prov_A]",
        ")",
        "",
        "def _rule_with_prov_b_impl(ctx):",
        "  return [Prov_B(val = 'val_b')]",
        "rule_with_prov_b = rule(",
        "  implementation = _rule_with_prov_b_impl,",
        "  attrs = {",
        "    'dep': attr.label(),",
        "  },",
        "  provides = [Prov_B]",
        ")",
        "",
        "def _rule_with_prov_c_impl(ctx):",
        "  return [Prov_C(val = 'val_c')]",
        "rule_with_prov_c = rule(",
        "  implementation = _rule_with_prov_c_impl,",
        "  provides = [Prov_C]",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'main_rule', 'rule_with_prov_a', 'rule_with_prov_b',"
            + " 'rule_with_prov_c')",
        "main_rule(",
        "  name = 'main',",
        "  dep = ':target_with_prov_a',",
        ")",
        "rule_with_prov_a(",
        "  name = 'target_with_prov_a',",
        "  dep = ':target_with_prov_b'",
        ")",
        "rule_with_prov_b(",
        "  name = 'target_with_prov_b',",
        "  dep = ':target_with_prov_c'",
        ")",
        "rule_with_prov_c(",
        "  name = 'target_with_prov_c'",
        ")");

    AnalysisResult analysisResult = update("//test:main");

    // aspect_a should only run on target_with_prov_a, aspect_b should only run on
    // target_with_prov_b and aspect_c should only run on target_with_prov_c.
    // aspect_c will reach target target_with_prov_c because it inherits the required_providers of
    // aspect_b otherwise it would have stopped propagating after target_with_prov_b.
    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkProvider.Key collectorProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "CollectorProv");
    StructImpl collectorProvider = (StructImpl) configuredTarget.get(collectorProv);
    assertThat((Sequence<?>) collectorProvider.getValue("result"))
        .containsExactly(
            "aspect_c run on target @//test:target_with_prov_c and value of Prov_C = val_c",
            "aspect_b run on target @//test:target_with_prov_b and value of Prov_B = val_b",
            "aspect_a run on target @//test:target_with_prov_a and value of Prov_A = val_a")
        .inOrder();
  }

  @Test
  public void testAspectRequiresAspect_inspectRequiredAspectActions() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _required_aspect_impl(target, ctx):
          f = ctx.actions.declare_file('dummy.txt')
          ctx.actions.run_shell(outputs = [f], command='echo xxx > $(location f)',
                                mnemonic='RequiredAspectAction')
          return []
        required_aspect = aspect(
          implementation = _required_aspect_impl,
        )

        AspectInfo = provider()
        def _base_aspect_impl(target, ctx):
          required_aspect_action = None
          for action in target.actions:
            if action.mnemonic == 'RequiredAspectAction':
              required_aspect_action = action
          if required_aspect_action:
            return AspectInfo(result = 'base_aspect can see required_aspect action')
          else:
            return AspectInfo(result = 'base_aspect cannot see required_aspect action')
        base_aspect = aspect(
          implementation = _base_aspect_impl,
          attr_aspects = ['dep'],
          requires = [required_aspect]
        )

        RuleInfo = provider()
        def _main_rule_impl(ctx):
          return RuleInfo(result = ctx.attr.dep[AspectInfo].result)
        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'dep': attr.label(aspects = [base_aspect]),
          },
        )

        def _dep_rule_impl(ctx):
          pass
        dep_rule = rule(
          implementation = _dep_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule', 'dep_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
        )
        dep_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    String result = (String) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("result");
    assertThat(result).isEqualTo("base_aspect can see required_aspect action");
  }

  @Test
  public void testAspectRequiresAspect_inspectRequiredAspectGeneratedFiles() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _required_aspect_impl(target, ctx):",
        "  file = ctx.actions.declare_file('required_aspect_file')",
        "  ctx.actions.write(file, 'data')",
        "  return [OutputGroupInfo(out = [file])]",
        "required_aspect = aspect(",
        "  implementation = _required_aspect_impl,",
        ")",
        "",
        "AspectInfo = provider()",
        "def _base_aspect_impl(target, ctx):",
        "  files = ['base_aspect can see file ' + f.path.split('/')[-1] for f in"
            + " target[OutputGroupInfo].out.to_list()]",
        "  return AspectInfo(my_files = files)",
        "base_aspect = aspect(",
        "  implementation = _base_aspect_impl,",
        "  attr_aspects = ['dep'],",
        "  requires = [required_aspect]",
        ")",
        "",
        "RuleInfo = provider()",
        "def _main_rule_impl(ctx):",
        "  return RuleInfo(my_files = ctx.attr.dep[AspectInfo].my_files)",
        "main_rule = rule(",
        "  implementation = _main_rule_impl,",
        "  attrs = {",
        "    'dep': attr.label(aspects = [base_aspect]),",
        "  },",
        ")",
        "",
        "def _dep_rule_impl(ctx):",
        "  pass",
        "dep_rule = rule(",
        "  implementation = _dep_rule_impl,",
        ")");
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule', 'dep_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
        )
        dep_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkList<?> files =
        (StarlarkList) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("my_files");
    assertThat(Starlark.toIterable(files))
        .containsExactly("base_aspect can see file required_aspect_file");
  }

  @Test
  public void testAspectRequiresAspect_withRequiredAspectProvidersSatisfied() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()
        prov_b_forwarded = provider()
        AspectAInfo = provider()
        AspectBInfo = provider()
        RuleInfo = provider()
        def _aspect_b_impl(target, ctx):
          result = 'aspect_b on target {} '.format(target.label)
          if prov_b in target:
            result += 'found prov_b = {}'.format(target[prov_b].val)
            return [AspectBInfo(aspect_b_result = result),
                    prov_b_forwarded(val = target[prov_b].val)]
          else:
            result += 'cannot find prov_b'
            return [AspectBInfo(aspect_b_result = result)]
        aspect_b = aspect(
          implementation = _aspect_b_impl,
          required_aspect_providers = [prov_b]
        )

        def _aspect_a_impl(target, ctx):
          result = 'aspect_a on target {} '.format(target.label)
          if prov_a in target:
            result += 'found prov_a = {}'.format(target[prov_a].val)
          else:
            result += 'cannot find prov_a'
          if prov_b_forwarded in target:
            result += ' and found prov_b = {}'.format(target[prov_b_forwarded].val)
          else:
            result += ' but cannot find prov_b'
          return AspectAInfo(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          required_aspect_providers = [prov_a],
          attr_aspects = ['dep'],
          requires = [aspect_b]
        )

        def _aspect_with_prov_a_impl(target, ctx):
          return [prov_a(val = 'a1')]
        aspect_with_prov_a = aspect(
          implementation = _aspect_with_prov_a_impl,
          provides = [prov_a],
          attr_aspects = ['dep'],
        )

        def _aspect_with_prov_b_impl(target, ctx):
          return [prov_b(val = 'b1')]
        aspect_with_prov_b = aspect(
          implementation = _aspect_with_prov_b_impl,
          provides = [prov_b],
          attr_aspects = ['dep'],
        )

        def _main_rule_impl(ctx):
          return RuleInfo(aspect_a_result = ctx.attr.dep[AspectAInfo].aspect_a_result,
                        aspect_b_result = ctx.attr.dep[AspectBInfo].aspect_b_result)
        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'dep': attr.label(aspects = [aspect_with_prov_a, aspect_with_prov_b, aspect_a]),
          },
        )

        def _dep_rule_impl(ctx):
          pass
        dep_rule = rule(
          implementation = _dep_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule', 'dep_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
        )
        dep_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkInfo targetInfo = getStarlarkProvider(configuredTarget, "RuleInfo");
    String aspectAResult = targetInfo.getValue("aspect_a_result", String.class);
    assertThat(aspectAResult)
        .isEqualTo("aspect_a on target @//test:dep_target found prov_a = a1 and found prov_b = b1");

    String aspectBResult = targetInfo.getValue("aspect_b_result", String.class);
    assertThat(aspectBResult).isEqualTo("aspect_b on target @//test:dep_target found prov_b = b1");
  }

  @Test
  public void testAspectRequiresAspect_withRequiredAspectProvidersNotFound() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()
        AspectAInfo = provider()
        AspectBInfo = provider()
        def _aspect_b_impl(target, ctx):
          result = 'aspect_b on target {} '.format(target.label)
          if prov_b in target:
            result += 'found prov_b = {}'.format(target[prov_b].val)
          else:
            result += 'cannot find prov_b'
          return AspectBInfo(aspect_b_result = result)
        aspect_b = aspect(
          implementation = _aspect_b_impl,
          required_aspect_providers = [prov_b]
        )

        def _aspect_a_impl(target, ctx):
          result = 'aspect_a on target {} '.format(target.label)
          if prov_a in target:
            result += 'found prov_a = {}'.format(target[prov_a].val)
          else:
            result += 'cannot find prov_a'
          return AspectAInfo(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          required_aspect_providers = [prov_a],
          attr_aspects = ['dep'],
          requires = [aspect_b]
        )

        def _aspect_with_prov_a_impl(target, ctx):
          return [prov_a(val = 'a1')]
        aspect_with_prov_a = aspect(
          implementation = _aspect_with_prov_a_impl,
          provides = [prov_a],
          attr_aspects = ['dep'],
        )

        RuleInfo = provider()
        def _main_rule_impl(ctx):
          return RuleInfo(aspect_a_result = ctx.attr.dep[AspectAInfo].aspect_a_result,
                        aspect_b_result = ctx.attr.dep[AspectBInfo].aspect_b_result)
        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'dep': attr.label(aspects = [aspect_with_prov_a, aspect_a]),
          },
        )

        def _dep_rule_impl(ctx):
          pass
        dep_rule = rule(
          implementation = _dep_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule', 'dep_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
        )
        dep_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkInfo ruleInfo = getStarlarkProvider(configuredTarget, "RuleInfo");
    String aspectAResult = ruleInfo.getValue("aspect_a_result", String.class);
    assertThat(aspectAResult).isEqualTo("aspect_a on target @//test:dep_target found prov_a = a1");

    String aspectBResult = ruleInfo.getValue("aspect_b_result", String.class);
    assertThat(aspectBResult).isEqualTo("aspect_b on target @//test:dep_target cannot find prov_b");
  }

  /**
   * --aspects = a3, a2, a1: aspect a1 requires provider a1p, aspect a2 requires provider a2p and
   * provides a1p and aspect a3 provides a2p. The three aspects will propagate together but aspect
   * a1 will only see a1p and aspect a2 will only see a2p.
   */
  @Test
  public void testTopLevelAspectOnAspect_stackOfAspects() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a2p = provider()
        a1_result = provider()
        a2_result = provider()
        a3_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          if a2p in target:
            result += ' and sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' and cannot see a2p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a1_result].value + [result]
          else:
            complete_result = [result]
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['dep'],
          required_aspect_providers = [a1p]
        )

        def _a2_impl(target, ctx):
          result = 'aspect a2 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          if a2p in target:
            result += ' and sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' and cannot see a2p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a2_result].value + [result]
          else:
            complete_result = [result]
          return [a2_result(value = complete_result), a1p(value = 'a1p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['dep'],
          provides = [a1p],
          required_aspect_providers = [a2p],
        )

        def _a3_impl(target, ctx):
          result = 'aspect a3 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          if a2p in target:
            result += ' and sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' and cannot see a2p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a3_result].value + [result]
          else:
            complete_result = [result]
          return [a3_result(value = complete_result), a2p(value = 'a2p_val')]
        a3 = aspect(
          implementation = _a3_impl,
          attr_aspects = ['dep'],
          provides = [a2p],
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'dep': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          dep = ':dep_target',
        )
        simple_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
            "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a3 = getConfiguredAspect(configuredAspects, "a3");
    assertThat(a3).isNotNull();
    StarlarkProvider.Key a3Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a3_result");
    StructImpl a3ResultProvider = (StructImpl) a3.get(a3Result);
    assertThat((Sequence<?>) a3ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a3 on target @//test:dep_target cannot see a1p and cannot see a2p",
            "aspect a3 on target @//test:main cannot see a1p and cannot see a2p");

    ConfiguredAspect a2 = getConfiguredAspect(configuredAspects, "a2");
    assertThat(a2).isNotNull();
    StarlarkProvider.Key a2Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a2_result");
    StructImpl a2ResultProvider = (StructImpl) a2.get(a2Result);
    assertThat((Sequence<?>) a2ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a2 on target @//test:dep_target cannot see a1p and sees a2p = a2p_val",
            "aspect a2 on target @//test:main cannot see a1p and sees a2p = a2p_val");

    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target sees a1p = a1p_val and cannot see a2p",
            "aspect a1 on target @//test:main sees a1p = a1p_val and cannot see a2p");
  }

  /**
   * --aspects = a3, a2, a1: aspect a1 requires provider a1p, aspect a2 and aspect a3 provides a1p.
   * This should fail because provider a1p is provided twice.
   */
  @Test
  public void testTopLevelAspectOnAspect_requiredProviderProvidedTwiceFailed() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a1_result].value + [result]
          else:
            complete_result = [result]
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['dep'],
          required_aspect_providers = [a1p]
        )

        def _a2_impl(target, ctx):
          return [a1p(value = 'a1p_a2_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['dep'],
          provides = [a1p],
        )

        def _a3_impl(target, ctx):
          return [a1p(value = 'a1p_a3_val')]
        a3 = aspect(
          implementation = _a3_impl,
          attr_aspects = ['dep'],
          provides = [a1p],
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'dep': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          dep = ':dep_target',
        )
        simple_rule(
          name = 'dep_target',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // The call to `update` does not throw an exception when "--keep_going" is passed in the
    // WithKeepGoing test suite. Otherwise, it throws ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult result =
          update(
              ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
              "//test:main");
      assertThat(result.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
                  "//test:main"));
    }
    assertContainsEvent("ERROR /workspace/test/BUILD:2:12: Provider a1p provided twice");
  }

  /**
   * --aspects = a3, a1, a2: aspect a1 requires provider a1p, aspect a2 and aspect a3 provide a1p.
   * a1 should see the value provided by a3 because a3 is listed before a1.
   */
  @Test
  public void testTopLevelAspectOnAspect_requiredProviderProvidedTwicePassed() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a1_result].value + [result]
          else:
            complete_result = [result]
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['dep'],
          required_aspect_providers = [a1p]
        )

        def _a2_impl(target, ctx):
          return [a1p(value = 'a1p_a2_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['dep'],
          provides = [a1p],
        )

        def _a3_impl(target, ctx):
          return [a1p(value = 'a1p_a3_val')]
        a3 = aspect(
          implementation = _a3_impl,
          attr_aspects = ['dep'],
          provides = [a1p],
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'dep': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          dep = ':dep_target',
        )
        simple_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a1", "test/defs.bzl%a2"),
            "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target sees a1p = a1p_a3_val",
            "aspect a1 on target @//test:main sees a1p = a1p_a3_val");
  }

  @Test
  public void testTopLevelAspectOnAspect_requiredProviderNotProvided() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a2p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a1_result].value + [result]
          else:
            complete_result = [result]
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['dep'],
          required_aspect_providers = [a1p]
        )

        def _a2_impl(target, ctx):
          return [a2p(value = 'a2p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['dep'],
          provides = [a2p],
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'dep': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          dep = ':dep_target',
        )
        simple_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%a2", "test/defs.bzl%a1"), "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target cannot see a1p",
            "aspect a1 on target @//test:main cannot see a1p");
  }

  /**
   * --aspects = a1, a2: aspect a1 requires provider a1p, aspect a2 provides a1p but it was listed
   * after a1 so aspect a1 cannot see a1p value.
   */
  @Test
  public void testTopLevelAspectOnAspect_requiredProviderProvidedAfterTheAspect() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a1_result].value + [result]
          else:
            complete_result = [result]
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['dep'],
          required_aspect_providers = [a1p]
        )

        def _a2_impl(target, ctx):
          return [a1p(value = 'a1p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['dep'],
          provides = [a1p],
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'dep': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          dep = ':dep_target',
        )
        simple_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2"), "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target cannot see a1p",
            "aspect a1 on target @//test:main cannot see a1p");
  }

  /**
   * --aspects = a2, a1: aspect a1 requires provider a1p, aspect a2 provides a1p. But aspect a2
   * propagates along different attr_aspects from a1 so a1 cannot get a1p on all dependency targets.
   */
  @Test
  public void testTopLevelAspectOnAspect_differentAttrAspects() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result += ctx.rule.attr.dep[a1_result].value
          if ctx.rule.attr.extra_dep:
            complete_result += ctx.rule.attr.extra_dep[a1_result].value
          complete_result += [result]
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['dep', 'extra_dep'],
          required_aspect_providers = [a1p]
        )

        def _a2_impl(target, ctx):
          return [a1p(value = 'a1p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['dep'],
          provides = [a1p],
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'dep': attr.label(),
            'extra_dep': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          dep = ':dep_target',
          extra_dep = ':extra_dep_target',
        )
        simple_rule(
          name = 'dep_target',
        )
        simple_rule(
          name = 'extra_dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%a2", "test/defs.bzl%a1"), "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target sees a1p = a1p_val",
            "aspect a1 on target @//test:extra_dep_target cannot see a1p",
            "aspect a1 on target @//test:main sees a1p = a1p_val");
  }

  /**
   * --aspects = a2, a1: aspect a1 requires provider a1p, aspect a2 provides a1p. But aspect a2
   * propagates along different required_providers from a1 so a1 cannot get a1p on all dependency
   * targets.
   */
  @Test
  public void testTopLevelAspectOnAspect_differentRequiredRuleProviders() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a1_result = provider()
        rule_prov_a = provider()
        rule_prov_b = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          complete_result = []
          if hasattr(ctx.rule.attr, 'deps'):
            for dep in ctx.rule.attr.deps:
              complete_result += dep[a1_result].value
          complete_result += [result]
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [a1p],
          required_providers = [[rule_prov_a], [rule_prov_b]],
        )

        def _a2_impl(target, ctx):
          return [a1p(value = 'a1p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['deps'],
          provides = [a1p],
          required_providers = [rule_prov_a],
        )

        def _main_rule_impl(ctx):
          return [rule_prov_a(), rule_prov_b()]
        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'deps': attr.label_list(),
          },
        )

        def _rule_with_prov_a_impl(ctx):
          return [rule_prov_a()]
        rule_with_prov_a = rule(
          implementation = _rule_with_prov_a_impl,
          provides = [rule_prov_a]
        )

        def _rule_with_prov_b_impl(ctx):
          return [rule_prov_b()]
        rule_with_prov_b = rule(
          implementation = _rule_with_prov_b_impl,
          provides = [rule_prov_b]
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule', 'rule_with_prov_a', 'rule_with_prov_b')
        main_rule(
          name = 'main',
          deps = [':target_with_prov_a', ':target_with_prov_b'],
        )
        rule_with_prov_a(
          name = 'target_with_prov_a',
        )
        rule_with_prov_b(
          name = 'target_with_prov_b',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%a2", "test/defs.bzl%a1"), "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:target_with_prov_a sees a1p = a1p_val",
            "aspect a1 on target @//test:target_with_prov_b cannot see a1p",
            "aspect a1 on target @//test:main sees a1p = a1p_val");
  }

  /**
   * --aspects = a3, a2, a1: both aspects a1 and a2 require provider a3p, aspect a3 provides a3p. a1
   * and a2 should be able to read a3p.
   */
  @Test
  public void testTopLevelAspectOnAspect_providerRequiredByMultipleAspects() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a3p = provider()
        a1_result = provider()
        a2_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a3p in target:
            result += ' sees a3p = {}'.format(target[a3p].value)
          else:
            result += ' cannot see a3p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a1_result].value + [result]
          else:
            complete_result = [result]
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['dep'],
          required_aspect_providers = [a3p]
        )

        def _a2_impl(target, ctx):
          result = 'aspect a2 on target {}'.format(target.label)
          if a3p in target:
            result += ' sees a3p = {}'.format(target[a3p].value)
          else:
            result += ' cannot see a3p'
          complete_result = []
          if ctx.rule.attr.dep:
            complete_result = ctx.rule.attr.dep[a2_result].value + [result]
          else:
            complete_result = [result]
          return [a2_result(value = complete_result)]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['dep'],
          required_aspect_providers = [a3p]
        )

        def _a3_impl(target, ctx):
          return [a3p(value = 'a3p_val')]
        a3 = aspect(
          implementation = _a3_impl,
          attr_aspects = ['dep'],
          provides = [a3p],
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'dep': attr.label(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          dep = ':dep_target',
        )
        simple_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
            "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a2 = getConfiguredAspect(configuredAspects, "a2");
    assertThat(a2).isNotNull();
    StarlarkProvider.Key a2Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a2_result");
    StructImpl a2ResultProvider = (StructImpl) a2.get(a2Result);
    assertThat((Sequence<?>) a2ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a2 on target @//test:dep_target sees a3p = a3p_val",
            "aspect a2 on target @//test:main sees a3p = a3p_val");

    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target sees a3p = a3p_val",
            "aspect a1 on target @//test:main sees a3p = a3p_val");
  }

  /**
   * --aspects = a1, a2, a3: aspect a3 requires a1p and a2p, a1 provides a1p and a2 provides a2p.
   *
   * <p>top level target (main) has two dependencies t1 and t2. Aspects a1 and a3 can propagate to
   * t1 and aspects a2 and a3 can propagate to t2. Both t1 and t2 have t0 as dependency, aspect a3
   * will run twice on t0 once with aspects path (a1, a3) and the other with (a2, a3).
   */
  @Test
  public void testTopLevelAspectOnAspect_diamondCase() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a2p = provider()
        a3_result = provider()

        r1p = provider()
        r2p = provider()

        def _a1_impl(target, ctx):
          return [a1p(value = 'a1p_val')]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['deps'],
          required_providers = [r1p],
          provides = [a1p]
        )

        def _a2_impl(target, ctx):
          return [a2p(value = 'a2p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['deps'],
          required_providers = [r2p],
          provides = [a2p]
        )

        def _a3_impl(target, ctx):
          result = 'aspect a3 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          if a2p in target:
            result += ' and sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' and cannot see a2p'
          complete_result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              complete_result.extend(dep[a3_result].value)
          complete_result.append(result)
          return [a3_result(value = complete_result)]
        a3 = aspect(
          implementation = _a3_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [[a1p], [a2p]],
        )

        def _r0_impl(ctx):
          return [r1p(), r2p()]
        r0 = rule(
          implementation = _r0_impl,
          attrs = {
            'deps': attr.label_list(),
          },
          provides = [r1p, r2p]
        )
        def _r1_impl(ctx):
          return [r1p()]
        r1 = rule(
          implementation = _r1_impl,
          attrs = {
            'deps': attr.label_list(),
          },
          provides = [r1p]
        )
        def _r2_impl(ctx):
          return [r2p()]
        r2 = rule(
          implementation = _r2_impl,
          attrs = {
            'deps': attr.label_list(),
          },
          provides = [r2p]
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'r0', 'r1', 'r2')
        r0(
          name = 'main',
          deps = [':t1', ':t2'],
        )
        r1(
          name = 't1',
          deps = [':t0'],
        )
        r2(
          name = 't2',
          deps = [':t0'],
        )
        r0(
          name = 't0',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2", "test/defs.bzl%a3"),
            "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a3 = getConfiguredAspect(configuredAspects, "a3");
    assertThat(a3).isNotNull();
    StarlarkProvider.Key a3Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a3_result");
    StructImpl a3ResultProvider = (StructImpl) a3.get(a3Result);
    assertThat((Sequence<?>) a3ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a3 on target @//test:t0 sees a1p = a1p_val and cannot see a2p",
            "aspect a3 on target @//test:t0 cannot see a1p and sees a2p = a2p_val",
            "aspect a3 on target @//test:t1 sees a1p = a1p_val and cannot see a2p",
            "aspect a3 on target @//test:t2 cannot see a1p and sees a2p = a2p_val",
            "aspect a3 on target @//test:main sees a1p = a1p_val and sees a2p = a2p_val");
  }

  @Test
  public void testTopLevelAspectOnAspect_duplicateAspectsNotAllowed() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a2p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a2p in target:
            result += ' sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' cannot see a2p'
          complete_result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              complete_result.extend(dep[a1_result].value)
          complete_result.append(result)
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [a2p]
        )

        def _a2_impl(target, ctx):
          return [a2p(value = 'a2p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['deps'],
          provides = [a2p]
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'deps': attr.label_list(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          deps = [':dep_target'],
        )
        simple_rule(
          name = 'dep_target',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // The call to `update` does not throw an exception when "--keep_going" is passed in the
    // WithKeepGoing test suite. Otherwise, it throws ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult result =
          update(
              ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2", "test/defs.bzl%a1"),
              "//test:main");
      assertThat(result.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2", "test/defs.bzl%a1"),
                  "//test:main"));
    }
    assertContainsEvent("aspect //test:defs.bzl%a1 added more than once");
  }

  /**
   * --aspects = a1 requires provider a2p provided by aspect a2. a1 is applied on top level target
   * `main` whose rule propagates aspect a2 to its `deps`. So a1 on `main` cannot see a2p but it can
   * see a2p on `main` deps.
   */
  @Test
  public void testTopLevelAspectOnAspect_requiredAspectProviderOnlyAvailableOnDep()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a2p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a2p in target:
            result += ' sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' cannot see a2p'
          complete_result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              complete_result.extend(dep[a1_result].value)
          complete_result.append(result)
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [a2p]
        )

        def _a2_impl(target, ctx):
          return [a2p(value = 'a2p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['deps'],
          provides = [a2p]
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'deps': attr.label_list(aspects=[a2]),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          deps = [':dep_target'],
        )
        simple_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult = update(ImmutableList.of("test/defs.bzl%a1"), "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target sees a2p = a2p_val",
            "aspect a1 on target @//test:main cannot see a2p");
  }

  @Test
  public void testTopLevelAspectOnAspect_multipleTopLevelTargets() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a2p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a2p in target:
            result += ' sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' cannot see a2p'
          complete_result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              complete_result.extend(dep[a1_result].value)
          complete_result.append(result)
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [a2p],
        )

        def _a2_impl(target, ctx):
          return [a2p(value = 'a2p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['deps'],
          provides = [a2p]
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'deps': attr.label_list(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 't1',
        )
        simple_rule(
          name = 't2',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%a2", "test/defs.bzl%a1"), "//test:t2", "//test:t1");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1Ont1 = getConfiguredAspect(configuredAspects, "a1", "t1");
    assertThat(a1Ont1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1Ont1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly("aspect a1 on target @//test:t1 sees a2p = a2p_val");

    ConfiguredAspect a1Ont2 = getConfiguredAspect(configuredAspects, "a1", "t2");
    assertThat(a1Ont2).isNotNull();
    a1ResultProvider = (StructImpl) a1Ont2.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly("aspect a1 on target @//test:t2 sees a2p = a2p_val");
  }

  @Test
  public void testTopLevelAspectOnAspect_multipleRequiredProviders() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a2p = provider()
        a3p = provider()
        a1_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a2p in target:
            result += ' sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' cannot see a2p'
          if a3p in target:
            result += ' and sees a3p = {}'.format(target[a3p].value)
          else:
            result += ' and cannot see a3p'
          complete_result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              complete_result.extend(dep[a1_result].value)
          complete_result.append(result)
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [[a2p], [a3p]],
        )

        def _a2_impl(target, ctx):
          return [a2p(value = 'a2p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['deps'],
          provides = [a2p]
        )

        def _a3_impl(target, ctx):
          return [a3p(value = 'a3p_val')]
        a3 = aspect(
          implementation = _a3_impl,
          attr_aspects = ['deps'],
          provides = [a3p]
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'deps': attr.label_list(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          deps = [':dep_target'],
        )
        simple_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
            "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target sees a2p = a2p_val and sees a3p = a3p_val",
            "aspect a1 on target @//test:main sees a2p = a2p_val and sees a3p = a3p_val");
  }

  @Test
  public void testTopLevelAspectOnAspect_multipleRequiredProviders2() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a2p = provider()
        a3p = provider()
        a1_result = provider()
        a2_result = provider()

        def _a1_impl(target, ctx):
          result = 'aspect a1 on target {}'.format(target.label)
          if a2p in target:
            result += ' sees a2p = {}'.format(target[a2p].value)
          else:
            result += ' cannot see a2p'
          if a3p in target:
            result += ' and sees a3p = {}'.format(target[a3p].value)
          else:
            result += ' and cannot see a3p'
          complete_result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              complete_result.extend(dep[a1_result].value)
          complete_result.append(result)
          return [a1_result(value = complete_result)]
        a1 = aspect(
          implementation = _a1_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [[a2p], [a3p]],
        )

        def _a2_impl(target, ctx):
          result = 'aspect a2 on target {}'.format(target.label)
          if a3p in target:
            result += ' sees a3p = {}'.format(target[a3p].value)
          else:
            result += ' cannot see a3p'
          complete_result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              complete_result.extend(dep[a2_result].value)
          complete_result.append(result)
          return [a2_result(value = complete_result), a2p(value = 'a2p_val')]
        a2 = aspect(
          implementation = _a2_impl,
          attr_aspects = ['deps'],
          provides = [a2p],
          required_aspect_providers = [a3p]
        )

        def _a3_impl(target, ctx):
          return [a3p(value = 'a3p_val')]
        a3 = aspect(
          implementation = _a3_impl,
          attr_aspects = ['deps'],
          provides = [a3p]
        )

        def _simple_rule_impl(ctx):
          pass
        simple_rule = rule(
          implementation = _simple_rule_impl,
          attrs = {
            'deps': attr.label_list(),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'simple_rule')
        simple_rule(
          name = 'main',
          deps = [':dep_target'],
        )
        simple_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%a3", "test/defs.bzl%a2", "test/defs.bzl%a1"),
            "//test:main");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect a1 = getConfiguredAspect(configuredAspects, "a1");
    assertThat(a1).isNotNull();
    StarlarkProvider.Key a1Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a1_result");
    StructImpl a1ResultProvider = (StructImpl) a1.get(a1Result);
    assertThat((Sequence<?>) a1ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a1 on target @//test:dep_target sees a2p = a2p_val and sees a3p = a3p_val",
            "aspect a1 on target @//test:main sees a2p = a2p_val and sees a3p = a3p_val");

    ConfiguredAspect a2 = getConfiguredAspect(configuredAspects, "a2");
    assertThat(a2).isNotNull();
    StarlarkProvider.Key a2Result =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "a2_result");
    StructImpl a2ResultProvider = (StructImpl) a2.get(a2Result);
    assertThat((Sequence<?>) a2ResultProvider.getValue("value"))
        .containsExactly(
            "aspect a2 on target @//test:dep_target sees a3p = a3p_val",
            "aspect a2 on target @//test:main sees a3p = a3p_val");
  }

  /**
   * aspects = a1, a2; aspect a1 provides a1p provider and aspect a2 requires a1p provider. These
   * top-level aspects are applied on top-level target `main` whose rule also provides a1p.
   *
   * <p>By default, the dependency between a1 and a2 will be established, the build will fail since
   * a2 will receive provider a1p twice (from a1 applied on `main` and from `main` target itself).
   */
  @Test
  public void testTopLevelAspects_duplicateRuleProviderError() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a1p = provider()
        a2p = provider()

        def _a1_impl(target, ctx):
          return [a1p(value = 'aspect_a1p_val')]
        a1 = aspect(
          implementation = _a1_impl,
          provides = [a1p],
        )

        def _a2_impl(target, ctx):
          result = 'aspect a2 on target {}'.format(target.label)
          if a1p in target:
            result += ' sees a1p = {}'.format(target[a1p].value)
          else:
            result += ' cannot see a1p'
          return [a2p(value = result)]
        a2 = aspect(
          implementation = _a2_impl,
          provides = [a2p],
          required_aspect_providers = [a1p]
        )

        def _my_rule_impl(ctx):
          return [a1p(value = 'rule_a1p_val')]
        my_rule = rule(
          implementation = _my_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(name = 'main')
        """);
    reporter.removeHandler(failFastHandler);

    // The call to `update` does not throw an exception when "--keep_going" is passed in the
    // WithKeepGoing test suite. Otherwise, it throws ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult result =
          update(ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2"), "//test:main");
      assertThat(result.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () -> update(ImmutableList.of("test/defs.bzl%a1", "test/defs.bzl%a2"), "//test:main"));
    }
    assertContainsEvent("Provider a1p provided twice");
  }

  @Test
  public void testTopLevelAspectRequiresAspect_stackOfRequiredAspects() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _impl(target, ctx):
           return []
        aspect_c = aspect(implementation = _impl)
        aspect_b = aspect(implementation = _impl, requires = [aspect_c])
        aspect_a = aspect(implementation = _impl, requires = [aspect_b])
        """);
    scratch.file("test/BUILD", "cc_binary(name = 'main_target')");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    assertThat(configuredAspects).hasSize(3);
    assertThat(getConfiguredAspect(configuredAspects, "aspect_a")).isNotNull();
    assertThat(getConfiguredAspect(configuredAspects, "aspect_b")).isNotNull();
    assertThat(getConfiguredAspect(configuredAspects, "aspect_c")).isNotNull();
  }

  @Test
  public void testTopLevelAspectRequiresAspect_aspectRequiredByMultipleAspects() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _impl(target, ctx):
           return []
        aspect_c = aspect(implementation = _impl)
        aspect_b = aspect(implementation = _impl, requires = [aspect_c])
        aspect_a = aspect(implementation = _impl, requires = [aspect_c])
        """);
    scratch.file("test/BUILD", "cc_binary(name = 'main_target')");

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
            "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    assertThat(configuredAspects).hasSize(3);
    assertThat(getConfiguredAspect(configuredAspects, "aspect_a")).isNotNull();
    assertThat(getConfiguredAspect(configuredAspects, "aspect_b")).isNotNull();
    assertThat(getConfiguredAspect(configuredAspects, "aspect_c")).isNotNull();
  }

  @Test
  public void testTopLevelAspectRequiresAspect_aspectRequiredByMultipleAspects2() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _impl(target, ctx):
           return []
        aspect_d = aspect(implementation = _impl)
        aspect_c = aspect(implementation = _impl, requires = [aspect_d])
        aspect_b = aspect(implementation = _impl, requires = [aspect_d])
        aspect_a = aspect(implementation = _impl, requires = [aspect_b, aspect_c])
        """);
    scratch.file("test/BUILD", "cc_binary(name = 'main_target')");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    assertThat(configuredAspects).hasSize(4);
    assertThat(getConfiguredAspect(configuredAspects, "aspect_a")).isNotNull();
    assertThat(getConfiguredAspect(configuredAspects, "aspect_b")).isNotNull();
    assertThat(getConfiguredAspect(configuredAspects, "aspect_c")).isNotNull();
    assertThat(getConfiguredAspect(configuredAspects, "aspect_d")).isNotNull();
  }

  @Test
  public void testTopLevelAspectRequiresAspect_requireExistingAspect_passed() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _impl(target, ctx):
           return []
        aspect_b = aspect(implementation = _impl)
        aspect_a = aspect(implementation = _impl, requires = [aspect_b])
        """);
    scratch.file("test/BUILD", "cc_binary(name = 'main_target')");

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%aspect_b", "test/defs.bzl%aspect_a"),
            "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    assertThat(configuredAspects).hasSize(2);
    assertThat(getConfiguredAspect(configuredAspects, "aspect_a")).isNotNull();
    assertThat(getConfiguredAspect(configuredAspects, "aspect_b")).isNotNull();
  }

  @Test
  public void testTopLevelAspectRequiresAspect_requireExistingAspect_failed() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _impl(target, ctx):
           return []
        aspect_b = aspect(implementation = _impl)
        aspect_a = aspect(implementation = _impl, requires = [aspect_b])
        """);
    scratch.file("test/BUILD", "cc_binary(name = 'main_target')");
    reporter.removeHandler(failFastHandler);

    // The call to `update` does not throw an exception when "--keep_going" is passed in the
    // WithKeepGoing test suite. Otherwise, it throws ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult result =
          update(
              ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
              "//test:main_target");
      assertThat(result.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"),
                  "//test:main_target"));
    }
    assertContainsEvent(
        "aspect //test:defs.bzl%aspect_b was added before as a required"
            + " aspect of aspect //test:defs.bzl%aspect_a");
  }

  @Test
  public void testTopLevelAspectRequiresAspect_ruleAttributes() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        RequiredAspectProv = provider()
        BaseAspectProv = provider()

        def _required_aspect_impl(target, ctx):
          p_val = ['In required_aspect, p = {} on target {}'
                      .format(ctx.rule.attr.p, target.label)]
          if ctx.rule.attr.dep and RequiredAspectProv in ctx.rule.attr.dep:
            p_val += ctx.rule.attr.dep[RequiredAspectProv].p_val
          return [RequiredAspectProv(p_val = p_val)]
        required_aspect = aspect(
          implementation = _required_aspect_impl,
        )

        def _base_aspect_impl(target, ctx):
          p_val = []
          p_val += target[RequiredAspectProv].p_val
          p_val += ['In base_aspect, p = {} on target {}'.format(ctx.rule.attr.p, target.label)]
          if ctx.rule.attr.dep:
            p_val += ctx.rule.attr.dep[BaseAspectProv].p_val
          return [BaseAspectProv(p_val = p_val)]
        base_aspect = aspect(
          implementation = _base_aspect_impl,
          attr_aspects = ['dep'],
          requires = [required_aspect],
        )

        def _rule_impl(ctx):
          pass

        my_rule = rule(
          implementation = _rule_impl,
          attrs = {
            'dep': attr.label(),
            'p' : attr.string(values = ['main_val', 'dep_val']),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target',
          p = 'main_val',
        )
        my_rule(
          name = 'dep_target',
          p = 'dep_val',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%base_aspect"), "//test:main_target");

    // required_aspect can only run on main_target when propagated alone since its attr_aspects is
    // empty.
    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect requiredAspect = getConfiguredAspect(configuredAspects, "required_aspect");
    assertThat(requiredAspect).isNotNull();
    StarlarkProvider.Key requiredAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "RequiredAspectProv");
    StructImpl requiredAspectProvider = (StructImpl) requiredAspect.get(requiredAspectProv);
    assertThat((Sequence<?>) requiredAspectProvider.getValue("p_val"))
        .containsExactly("In required_aspect, p = main_val on target @//test:main_target");

    // base_aspect can run on main_target and dep_target and it can also see the providers created
    // by running required_target on them.
    ConfiguredAspect baseAspect = getConfiguredAspect(configuredAspects, "base_aspect");
    assertThat(baseAspect).isNotNull();
    StarlarkProvider.Key baseAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "BaseAspectProv");
    StructImpl baseAspectProvider = (StructImpl) baseAspect.get(baseAspectProv);
    assertThat((Sequence<?>) baseAspectProvider.getValue("p_val"))
        .containsExactly(
            "In base_aspect, p = dep_val on target @//test:dep_target",
            "In base_aspect, p = main_val on target @//test:main_target",
            "In required_aspect, p = dep_val on target @//test:dep_target",
            "In required_aspect, p = main_val on target @//test:main_target");
  }

  @Test
  public void testTopLevelAspectRequiresAspect_inheritPropagationAttributes() throws Exception {
    // base_aspect propagates over base_dep attribute and requires first_required_aspect which
    // propagates over first_dep attribute and requires second_required_aspect which propagates over
    // second_dep attribute
    scratch.file(
        "test/defs.bzl",
        """
        BaseAspectProv = provider()
        FirstRequiredAspectProv = provider()
        SecondRequiredAspectProv = provider()

        def _second_required_aspect_impl(target, ctx):
          result = []
          if getattr(ctx.rule.attr, 'second_dep'):
            result += getattr(ctx.rule.attr, 'second_dep')[SecondRequiredAspectProv].result
          result += ['second_required_aspect run on target {}'.format(target.label)]
          return [SecondRequiredAspectProv(result = result)]
        second_required_aspect = aspect(
          implementation = _second_required_aspect_impl,
          attr_aspects = ['second_dep'],
        )

        def _first_required_aspect_impl(target, ctx):
          result = []
          result += target[SecondRequiredAspectProv].result
          if getattr(ctx.rule.attr, 'first_dep'):
            result += getattr(ctx.rule.attr, 'first_dep')[FirstRequiredAspectProv].result
          result += ['first_required_aspect run on target {}'.format(target.label)]
          return [FirstRequiredAspectProv(result = result)]
        first_required_aspect = aspect(
          implementation = _first_required_aspect_impl,
          attr_aspects = ['first_dep'],
          requires = [second_required_aspect],
        )

        def _base_aspect_impl(target, ctx):
          result = []
          result += target[FirstRequiredAspectProv].result
          if getattr(ctx.rule.attr, 'base_dep'):
            result += getattr(ctx.rule.attr, 'base_dep')[BaseAspectProv].result
          result += ['base_aspect run on target {}'.format(target.label)]
          return [BaseAspectProv(result = result)]
        base_aspect = aspect(
          implementation = _base_aspect_impl,
          attr_aspects = ['base_dep'],
          requires = [first_required_aspect],
        )

        def _my_rule_impl(ctx):
          pass

        my_rule = rule(
          implementation = _my_rule_impl,
          attrs = {
            'base_dep': attr.label(),
            'first_dep': attr.label(),
            'second_dep': attr.label()
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          base_dep = ':base_dep_target',
          first_dep = ':first_dep_target',
          second_dep = ':second_dep_target',
        )
        my_rule(
          name = 'base_dep_target',
        )
        my_rule(
          name = 'first_dep_target',
        )
        my_rule(
          name = 'second_dep_target',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%base_aspect"), "//test:main_target");

    // base_aspect should propagate only along its attr_aspects: 'base_dep'
    // first_required_aspect should propagate along 'base_dep' and 'first_dep'
    // second_required_aspect should propagate along 'base_dep', 'first_dep' and 'second_dep'
    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect baseAspect = getConfiguredAspect(configuredAspects, "base_aspect");
    assertThat(baseAspect).isNotNull();
    StarlarkProvider.Key baseAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "BaseAspectProv");
    StructImpl baseAspectProvider = (StructImpl) baseAspect.get(baseAspectProv);
    assertThat((Sequence<?>) baseAspectProvider.getValue("result"))
        .containsExactly(
            "second_required_aspect run on target @//test:second_dep_target",
            "second_required_aspect run on target @//test:main_target",
            "second_required_aspect run on target @//test:first_dep_target",
            "second_required_aspect run on target @//test:base_dep_target",
            "first_required_aspect run on target @//test:first_dep_target",
            "first_required_aspect run on target @//test:main_target",
            "first_required_aspect run on target @//test:base_dep_target",
            "base_aspect run on target @//test:base_dep_target",
            "base_aspect run on target @//test:main_target");
  }

  @Test
  public void testTopLevelAspectRequiresAspect_inheritRequiredProviders() throws Exception {
    // aspect_a requires provider Prov_A and requires aspect_b which requires
    // provider Prov_B and requires aspect_c which requires provider Prov_C
    scratch.file(
        "test/defs.bzl",
        """
        Prov_A = provider()
        Prov_B = provider()
        Prov_C = provider()

        CollectorProv = provider()

        def _aspect_c_impl(target, ctx):
          collector_result = ['aspect_c run on target {} and value of Prov_C = {}'
                                        .format(target.label, target[Prov_C].val)]
          return [CollectorProv(result = collector_result)]
        aspect_c = aspect(
          implementation = _aspect_c_impl,
          required_providers = [Prov_C],
          attr_aspects = ['dep'],
        )

        def _aspect_b_impl(target, ctx):
          collector_result = []
          collector_result += ctx.rule.attr.dep[CollectorProv].result
          collector_result += ['aspect_b run on target {} and value of Prov_B = {}'
                                         .format(target.label, target[Prov_B].val)]
          return [CollectorProv(result = collector_result)]
        aspect_b = aspect(
          implementation = _aspect_b_impl,
          required_providers = [Prov_B],
          requires = [aspect_c],
          attr_aspects = ['dep'],
        )

        def _aspect_a_impl(target, ctx):
          collector_result = []
          collector_result += ctx.rule.attr.dep[CollectorProv].result
          collector_result += ['aspect_a run on target {} and value of Prov_A = {}'
                                         .format(target.label, target[Prov_A].val)]
          return [CollectorProv(result = collector_result)]
        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          required_providers = [Prov_A],
          requires = [aspect_b],
        )

        def _my_rule_impl(ctx):
          return [Prov_A(val='main_val_a')]
        my_rule = rule(
          implementation = _my_rule_impl,
          attrs = {
            'dep': attr.label(),
          },
          provides = [Prov_A]
        )

        def _rule_with_prov_a_impl(ctx):
          return [Prov_A(val='val_a')]
        rule_with_prov_a = rule(
          implementation = _rule_with_prov_a_impl,
          attrs = {
            'dep': attr.label(),
          },
          provides = [Prov_A]
        )

        def _rule_with_prov_b_impl(ctx):
          return [Prov_B(val = 'val_b')]
        rule_with_prov_b = rule(
          implementation = _rule_with_prov_b_impl,
          attrs = {
            'dep': attr.label(),
          },
          provides = [Prov_B]
        )

        def _rule_with_prov_c_impl(ctx):
          return [Prov_C(val = 'val_c')]
        rule_with_prov_c = rule(
          implementation = _rule_with_prov_c_impl,
          provides = [Prov_C]
        )
        """);
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'my_rule', 'rule_with_prov_a', 'rule_with_prov_b',"
            + " 'rule_with_prov_c')",
        "my_rule(",
        "  name = 'main_target',",
        "  dep = ':target_with_prov_a',",
        ")",
        "rule_with_prov_a(",
        "  name = 'target_with_prov_a',",
        "  dep = ':target_with_prov_b'",
        ")",
        "rule_with_prov_b(",
        "  name = 'target_with_prov_b',",
        "  dep = ':target_with_prov_c'",
        ")",
        "rule_with_prov_c(",
        "  name = 'target_with_prov_c'",
        ")");

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%aspect_a"), "//test:main_target");

    // aspect_a should run on main_target and target_with_prov_a
    // aspect_b can reach target_with_prov_b because it inherits the required_providers of aspect_a
    // aspect_c can reach target_with_prov_c because it inherits the required_providers of aspect_a
    // and aspect_b
    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkProvider.Key collectorProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "CollectorProv");
    StructImpl collectorProvider = (StructImpl) aspectA.get(collectorProv);
    assertThat((Sequence<?>) collectorProvider.getValue("result"))
        .containsExactly(
            "aspect_c run on target @//test:target_with_prov_c and value of Prov_C = val_c",
            "aspect_b run on target @//test:target_with_prov_b and value of Prov_B = val_b",
            "aspect_a run on target @//test:target_with_prov_a and value of Prov_A = val_a",
            "aspect_a run on target @//test:main_target and value of Prov_A = main_val_a")
        .inOrder();
  }

  @Test
  public void testTopLevelAspectRequiresAspect_inspectRequiredAspectActions() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        BaseAspectProvider = provider()
        def _required_aspect_impl(target, ctx):
          f = ctx.actions.declare_file('dummy.txt')
          ctx.actions.run_shell(outputs = [f], command='echo xxx > $(location f)',
                                mnemonic='RequiredAspectAction')
          return []
        required_aspect = aspect(
          implementation = _required_aspect_impl,
        )

        def _base_aspect_impl(target, ctx):
          required_aspect_action = None
          for action in target.actions:
            if action.mnemonic == 'RequiredAspectAction':
              required_aspect_action = action
          if required_aspect_action:
            return [BaseAspectProvider(result = 'base_aspect can see required_aspect action')]
          else:
            return [BaseAspectProvider(result = 'base_aspect cannot see required_aspect action')]
        base_aspect = aspect(
          implementation = _base_aspect_impl,
          attr_aspects = ['dep'],
          requires = [required_aspect]
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%base_aspect"), "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect baseAspect = getConfiguredAspect(configuredAspects, "base_aspect");
    assertThat(baseAspect).isNotNull();
    StarlarkProvider.Key baseAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "BaseAspectProvider");
    StructImpl baseAspectProvider = (StructImpl) baseAspect.get(baseAspectProv);
    assertThat(baseAspectProvider.getValue("result"))
        .isEqualTo("base_aspect can see required_aspect action");
  }

  @Test
  public void testTopLevelAspectRequiresAspect_inspectRequiredAspectGeneratedFiles()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        BaseAspectProvider = provider()
        def _required_aspect_impl(target, ctx):
          file = ctx.actions.declare_file('required_aspect_file')
          ctx.actions.write(file, 'data')
          return [OutputGroupInfo(out = [file])]
        required_aspect = aspect(
          implementation = _required_aspect_impl,
        )

        def _base_aspect_impl(target, ctx):
          files = ['base_aspect can see file ' + f.path.split('/')[-1]
                       for f in target[OutputGroupInfo].out.to_list()]
          return [BaseAspectProvider(my_files = files)]
        base_aspect = aspect(
          implementation = _base_aspect_impl,
          attr_aspects = ['dep'],
          requires = [required_aspect]
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("test/defs.bzl%base_aspect"), "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect baseAspect = getConfiguredAspect(configuredAspects, "base_aspect");
    assertThat(baseAspect).isNotNull();
    StarlarkProvider.Key baseAspectProv =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "BaseAspectProvider");
    StructImpl baseAspectProvider = (StructImpl) baseAspect.get(baseAspectProv);
    assertThat((Sequence<?>) baseAspectProvider.getValue("my_files"))
        .containsExactly("base_aspect can see file required_aspect_file");
  }

  @Test
  public void testTopLevelAspectRequiresAspect_withRequiredAspectProvidersSatisfied()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()
        prov_b_forwarded = provider()

        def _aspect_b_impl(target, ctx):
          result = 'aspect_b on target {} '.format(target.label)
          if prov_b in target:
            result += 'found prov_b = {}'.format(target[prov_b].val)
            return struct(aspect_b_result = result,
                          providers = [prov_b_forwarded(val = target[prov_b].val)])
          else:
            result += 'cannot find prov_b'
            return struct(aspect_b_result = result)
        aspect_b = aspect(
          implementation = _aspect_b_impl,
          required_aspect_providers = [prov_b]
        )

        def _aspect_a_impl(target, ctx):
          result = 'aspect_a on target {} '.format(target.label)
          if prov_a in target:
            result += 'found prov_a = {}'.format(target[prov_a].val)
          else:
            result += 'cannot find prov_a'
          if prov_b_forwarded in target:
            result += ' and found prov_b = {}'.format(target[prov_b_forwarded].val)
          else:
            result += ' but cannot find prov_b'
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          required_aspect_providers = [prov_a],
          attr_aspects = ['dep'],
          requires = [aspect_b]
        )

        def _aspect_with_prov_a_impl(target, ctx):
          return [prov_a(val = 'a1')]
        aspect_with_prov_a = aspect(
          implementation = _aspect_with_prov_a_impl,
          provides = [prov_a],
          attr_aspects = ['dep'],
        )

        def _aspect_with_prov_b_impl(target, ctx):
          return [prov_b(val = 'b1')]
        aspect_with_prov_b = aspect(
          implementation = _aspect_with_prov_b_impl,
          provides = [prov_b],
          attr_aspects = ['dep'],
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of(
                "test/defs.bzl%aspect_with_prov_a",
                "test/defs.bzl%aspect_with_prov_b", "test/defs.bzl%aspect_a"),
            "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    String aspectAResult = (String) aspectA.get("aspect_a_result");
    assertThat(aspectAResult)
        .isEqualTo(
            "aspect_a on target @//test:main_target found prov_a = a1 and found prov_b = b1");

    ConfiguredAspect aspectB = getConfiguredAspect(configuredAspects, "aspect_b");
    assertThat(aspectB).isNotNull();
    String aspectBResult = (String) aspectB.get("aspect_b_result");
    assertThat(aspectBResult).isEqualTo("aspect_b on target @//test:main_target found prov_b = b1");
  }

  @Test
  public void testTopLevelAspectRequiresAspect_withRequiredAspectProvidersNotFound()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        prov_a = provider()
        prov_b = provider()

        def _aspect_b_impl(target, ctx):
          result = 'aspect_b on target {} '.format(target.label)
          if prov_b in target:
            result += 'found prov_b = {}'.format(target[prov_b].val)
          else:
            result += 'cannot find prov_b'
          return struct(aspect_b_result = result)
        aspect_b = aspect(
          implementation = _aspect_b_impl,
          required_aspect_providers = [prov_b]
        )

        def _aspect_a_impl(target, ctx):
          result = 'aspect_a on target {} '.format(target.label)
          if prov_a in target:
            result += 'found prov_a = {}'.format(target[prov_a].val)
          else:
            result += 'cannot find prov_a'
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          required_aspect_providers = [prov_a],
          attr_aspects = ['dep'],
          requires = [aspect_b]
        )

        def _aspect_with_prov_a_impl(target, ctx):
          return [prov_a(val = 'a1')]
        aspect_with_prov_a = aspect(
          implementation = _aspect_with_prov_a_impl,
          provides = [prov_a],
          attr_aspects = ['dep'],
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("test/defs.bzl%aspect_with_prov_a", "test/defs.bzl%aspect_a"),
            "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    String aspectAResult = (String) aspectA.get("aspect_a_result");
    assertThat(aspectAResult).isEqualTo("aspect_a on target @//test:main_target found prov_a = a1");

    ConfiguredAspect aspectB = getConfiguredAspect(configuredAspects, "aspect_b");
    assertThat(aspectB).isNotNull();
    String aspectBResult = (String) aspectB.get("aspect_b_result");
    assertThat(aspectBResult)
        .isEqualTo("aspect_b on target @//test:main_target cannot find prov_b");
  }

  @Test
  public void testDependentAspectWithNonExecutableTool_doesNotCrash() throws Exception {
    scratch.file(
        "test/BUILD",
        """
        sh_binary(name='bin', srcs=['bin.sh'])
        sh_library(name='lib')
        """);
    scratch.file(
        "test/defs.bzl",
        "AInfo = provider()",
        "BInfo = provider()",
        "def _aspect_a(target, ctx):",
        "  return [AInfo(value=str(ctx.attr._attr.label))]",
        "aspect_a = aspect(",
        "  implementation = _aspect_a,",
        "  provides=[AInfo],",
        "  attrs = {'_attr':" + " attr.label(default=':lib')},",
        ")",
        "def _aspect_b(target, ctx):",
        "  return [BInfo(value=str(ctx.executable._attr.path.split('/')[-1]))]",
        "aspect_b = aspect(",
        "  implementation = _aspect_b,",
        "  required_aspect_providers = [AInfo],",
        "  attrs = {'_attr': attr.label(default=':bin', executable=True, cfg='exec')},",
        ")");
    scratch.file("test/bin.sh").setExecutable(true);

    AnalysisResult result =
        update(ImmutableList.of("test/defs.bzl%aspect_a", "test/defs.bzl%aspect_b"), "//test:bin");

    ConfiguredAspect aspectB =
        result.getAspectsMap().entrySet().stream()
            .filter(a -> a.getKey().getAspectName().endsWith("aspect_b"))
            .map(Map.Entry::getValue)
            .findFirst()
            .orElse(null);
    assertThat(aspectB).isNotNull();

    StarlarkProvider.Key provB =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "BInfo");
    assertThat(((StructImpl) aspectB.get(provB)).getValue("value")).isEqualTo("bin");

    ConfiguredAspect aspectA =
        result.getAspectsMap().entrySet().stream()
            .filter(a -> a.getKey().getAspectName().endsWith("aspect_a"))
            .map(Map.Entry::getValue)
            .findFirst()
            .orElse(null);
    assertThat(aspectA).isNotNull();

    StarlarkProvider.Key provA =
        new StarlarkProvider.Key(Label.parseCanonical("//test:defs.bzl"), "AInfo");
    assertThat(((StructImpl) aspectA.get(provA)).getValue("value")).isEqualTo("@//test:lib");
  }

  @Test
  public void testTopLevelAspectsWithParameters() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p1 = {} and a_p = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.a_p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v1', 'p1_v2']),
                    'a_p' : attr.string(values = ['a_p_v1', 'a_p_v2'])},
        )

        def _aspect_b_impl(target, ctx):
          result = ['aspect_b on target {}, p1 = {} and b_p = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.b_p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_b_result
          return struct(aspect_b_result = result)

        aspect_b = aspect(
          implementation = _aspect_b_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v1', 'p1_v2']),
                    'b_p' : attr.string(values = ['b_p_v1', 'b_p_v2'])},
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("//test:defs.bzl%aspect_a", "//test:defs.bzl%aspect_b"),
            ImmutableMap.of("p1", "p1_v1", "a_p", "a_p_v1", "b_p", "b_p_v1"),
            "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkList<?> aspectAResult = (StarlarkList) aspectA.get("aspect_a_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect_a on target @//test:main_target, p1 = p1_v1 and a_p = a_p_v1",
            "aspect_a on target @//test:dep_target_1, p1 = p1_v1 and a_p = a_p_v1",
            "aspect_a on target @//test:dep_target_2, p1 = p1_v1 and a_p = a_p_v1");

    ConfiguredAspect aspectB = getConfiguredAspect(configuredAspects, "aspect_b");
    assertThat(aspectB).isNotNull();
    StarlarkList<?> aspectBResult = (StarlarkList) aspectB.get("aspect_b_result");
    assertThat(Starlark.toIterable(aspectBResult))
        .containsExactly(
            "aspect_b on target @//test:main_target, p1 = p1_v1 and b_p = b_p_v1",
            "aspect_b on target @//test:dep_target_1, p1 = p1_v1 and b_p = b_p_v1",
            "aspect_b on target @//test:dep_target_2, p1 = p1_v1 and b_p = b_p_v1");
  }

  @Test
  public void testTopLevelAspectsWithParameters_differentAllowedValues() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p1 = {} and p2 = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.p2)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v1', 'p1_v2']) },
        )

        def _aspect_b_impl(target, ctx):
          result = ['aspect_b on target {}, p1 = {} and p2 = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.p2)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_b_result
          return struct(aspect_b_result = result)

        aspect_b = aspect(
          implementation = _aspect_b_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v2', 'p1_v3']) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult analysisResult =
          update(
              ImmutableList.of("//test:defs.bzl%aspect_a", "//test:defs.bzl%aspect_b"),
              ImmutableMap.of("p1", "p1_v1"),
              "//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("//test:defs.bzl%aspect_a", "//test:defs.bzl%aspect_b"),
                  ImmutableMap.of("p1", "p1_v1"),
                  "//test:main_target"));
    }
    assertContainsEvent(
        "//test:defs.bzl%aspect_b: invalid value in 'p1' attribute: has to be one of 'p1_v2' or"
            + " 'p1_v3' instead of 'p1_v1'");
  }

  @Test
  public void testTopLevelAspectsWithParameters_useDefaultValue() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p1 = {} and p2 = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.p2)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v1', 'p1_v2'], default = 'p1_v1'),
                    'p2' : attr.string(values = ['p2_v1', 'p2_v2'], default = 'p2_v1')},
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("//test:defs.bzl%aspect_a"),
            ImmutableMap.of("p1", "p1_v2"),
            "//test:main_target");

    Map<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkList<?> aspectAResult = (StarlarkList) aspectA.get("aspect_a_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect_a on target @//test:main_target, p1 = p1_v2 and p2 = p2_v1",
            "aspect_a on target @//test:dep_target_1, p1 = p1_v2 and p2 = p2_v1",
            "aspect_a on target @//test:dep_target_2, p1 = p1_v2 and p2 = p2_v1");
  }

  @Test
  public void testTopLevelAspectsWithParameters_passParametersToRequiredAspect() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_b_impl(target, ctx):
          result = ['aspect_b on target {}, p1 = {} and p3 = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.p3)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_b_result
          return struct(aspect_b_result = result)

        aspect_b = aspect(
          implementation = _aspect_b_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v1', 'p1_v2']),
                    'p3' : attr.string(values = ['p3_v1', 'p3_v2', 'p3_v3'])},
        )

        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p1 = {} and p2 = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.p2)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v1', 'p1_v2']),
                    'p2' : attr.string(values = ['p2_v1', 'p2_v2'])},
          requires = [aspect_b],
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("//test:defs.bzl%aspect_a"),
            ImmutableMap.of("p1", "p1_v1", "p2", "p2_v2", "p3", "p3_v3"),
            "//test:main_target");

    ImmutableMap<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkList<?> aspectAResult = (StarlarkList) aspectA.get("aspect_a_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect_a on target @//test:main_target, p1 = p1_v1 and p2 = p2_v2",
            "aspect_a on target @//test:dep_target_1, p1 = p1_v1 and p2 = p2_v2",
            "aspect_a on target @//test:dep_target_2, p1 = p1_v1 and p2 = p2_v2");

    ConfiguredAspect aspectB = getConfiguredAspect(configuredAspects, "aspect_b");
    assertThat(aspectB).isNotNull();
    StarlarkList<?> aspectBResult = (StarlarkList) aspectB.get("aspect_b_result");
    assertThat(Starlark.toIterable(aspectBResult))
        .containsExactly(
            "aspect_b on target @//test:main_target, p1 = p1_v1 and p3 = p3_v3",
            "aspect_b on target @//test:dep_target_1, p1 = p1_v1 and p3 = p3_v3",
            "aspect_b on target @//test:dep_target_2, p1 = p1_v1 and p3 = p3_v3");
  }

  @Test
  public void testTopLevelAspectsWithParameters_invalidParameterValue() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.string(values = ['p_v1', 'p_v2']) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult analysisResult =
          update(
              ImmutableList.of("//test:defs.bzl%aspect_a"),
              ImmutableMap.of("p", "p_v"),
              "//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("//test:defs.bzl%aspect_a"),
                  ImmutableMap.of("p", "p_v"),
                  "//test:main_target"));
    }
    assertContainsEvent(
        "//test:defs.bzl%aspect_a: invalid value in 'p' attribute: has to be one of 'p_v1' or"
            + " 'p_v2' instead of 'p_v'");
  }

  @Test
  public void testTopLevelAspectsWithParameters_missingMandatoryParameter() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p1 = {}'.
                                            format(target.label, ctx.attr.p1)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(mandatory = True, default = 'p1_v1',
                                       values = ['p1_v1', 'p1_v2']),
                    'p2' : attr.string(values = ['p2_v1', 'p2_v2'])},
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult analysisResult =
          update(
              ImmutableList.of("//test:defs.bzl%aspect_a"),
              ImmutableMap.of("p2", "p2_v1"),
              "//test:main_target");

      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("//test:defs.bzl%aspect_a"),
                  ImmutableMap.of("p2", "p2_v1"),
                  "//test:main_target"));
    }
    assertContainsEvent("Missing mandatory attribute 'p1' for aspect '//test:defs.bzl%aspect_a'");
  }

  @Test
  public void testTopLevelAspectsWithParameters_unusedParameter() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p1 = {} and a_p = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.a_p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v1', 'p1_v2']),
                    'a_p' : attr.string(values = ['a_p_v1', 'a_p_v2'])},
        )

        def _aspect_b_impl(target, ctx):
          result = ['aspect_b on target {}, p1 = {} and b_p = {}'.
                                            format(target.label, ctx.attr.p1, ctx.attr.b_p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_b_result
          return struct(aspect_b_result = result)

        aspect_b = aspect(
          implementation = _aspect_b_impl,
          attr_aspects = ['dep'],
          attrs = { 'p1' : attr.string(values = ['p1_v1', 'p1_v2']),
                    'b_p' : attr.string(values = ['b_p_v1', 'b_p_v2'])},
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult analysisResult =
          update(
              ImmutableList.of("//test:defs.bzl%aspect_a", "//test:defs.bzl%aspect_b"),
              ImmutableMap.of("p2", "p2_v1", "b_p", "b_p_v1"),
              "//test:main_target");

      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("//test:defs.bzl%aspect_a", "//test:defs.bzl%aspect_b"),
                  ImmutableMap.of("p2", "p2_v1", "b_p", "b_p_v1"),
                  "//test:main_target"));
    }
    assertContainsEvent(
        "Parameters '[p2]' are not parameters of any of the top-level aspects but they are"
            + " specified in --aspects_parameters.");
  }

  @Test
  public void testTopLevelAspectsWithParameters_invalidDefaultParameterValue() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.string(values = ['p_v1', 'p_v2']) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult analysisResult =
          update(ImmutableList.of("//test:defs.bzl%aspect_a"), "//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () -> update(ImmutableList.of("//test:defs.bzl%aspect_a"), "//test:main_target"));
    }
    assertContainsEvent(
        "//test:defs.bzl%aspect_a: invalid value in 'p' attribute: has to be one of 'p_v1' or"
            + " 'p_v2' instead of ''");
  }

  @Test
  public void testTopLevelAspectsWithParameters_noNeedForAllowedValues() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.string(default='val') },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("//test:defs.bzl%aspect_a"),
            ImmutableMap.of("p", "p_v"),
            "//test:main_target");

    ImmutableMap<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkList<?> aspectAResult = (StarlarkList) aspectA.get("aspect_a_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect_a on target @//test:main_target, p = p_v",
            "aspect_a on target @//test:dep_target_1, p = p_v",
            "aspect_a on target @//test:dep_target_2, p = p_v");
  }

  /**
   * Aspect parameter has to require set of values only if the aspect is used in a rule attribute.
   */
  @Test
  public void testAttrAspectParameterMissingRequiredValues() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _impl(target, ctx):
           pass
        my_aspect = aspect(_impl,
           attrs = { 'param' : attr.string(default = 'c') }
        )
        def _rule_impl(ctx):
           pass
        r1 = rule(_rule_impl, attrs={'dep': attr.label(aspects = [my_aspect])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'r1')
        r1(name = 'main_target')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update("//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update("//test:main_target"));
    }
    assertContainsEvent(
        "Aspect //test:defs.bzl%my_aspect: Aspect parameter attribute 'param' must use the 'values'"
            + " restriction.");
  }

  /**
   * Aspect parameter has to require set of values only if the aspect is used in a rule attribute.
   */
  @Test
  public void testAttrRequiredAspectParameterMissingRequiredValues() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _impl(target, ctx):
           pass
        required_aspect = aspect(_impl,
           attrs = { 'p1' : attr.string(default = 'b') }
        )
        my_aspect = aspect(_impl,
           attrs = { 'p2' : attr.string(default = 'c', values = ['c']) },
           requires = [required_aspect],
        )
        def _rule_impl(ctx):
           pass
        r1 = rule(_rule_impl, attrs={'dep': attr.label(aspects = [my_aspect])})
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'r1')
        r1(name = 'main_target')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update("//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update("//test:main_target"));
    }
    assertContainsEvent(
        "Aspect //test:defs.bzl%required_aspect: Aspect parameter attribute 'p1' must use the"
            + " 'values' restriction.");
  }

  @Test
  public void integerAspectParameter_mandatoryAttrNotCoveredByRule() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.int(default = 1, values = [1, 2], mandatory = True) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type int.");
  }

  @Test
  public void integerAspectParameter_mandatoryAttrWithWrongTypeInRule() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.int(default = 1, values = [1, 2], mandatory = True) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]),
                      'my_attr': attr.string() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type int.");
  }

  @Test
  public void integerAspectParameter_attrWithoutDefaultNotCoveredByRule() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.int(values = [1, 2]) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type int.");
  }

  @Test
  public void integerAspectParameter_attrWithoutDefaultWrongTypeInRule() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.int(values = [1, 2]) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]),
                      'my_attr': attr.string() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type int.");
  }

  @Test
  public void integerAspectParameter_missingValuesRestriction() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.int() },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]),
                      'my_attr' : attr.int() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered: Aspect parameter attribute 'my_attr' must use"
            + " the 'values' restriction.");
  }

  @Test
  public void integerAspectParameter_invalidDefault() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.int(default = 2, values = [0, 1]) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect parameter attribute 'my_attr' has a bad default value: has to be one of '0' or '1'"
            + " instead of '2'");
  }

  @Test
  public void aspectIntegerParameter_withDefaultValue() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
          result = ['my_aspect on target {}, my_attr = {}'.
                                            format(target.label, ctx.attr.my_attr)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep[AspectInfo].my_aspect_result
          return AspectInfo(my_aspect_result = result)

        RuleInfo = provider()
        def _rule_impl(ctx):
          if ctx.attr.dep:
            return RuleInfo(my_rule_result = ctx.attr.dep[AspectInfo].my_aspect_result)
          pass

        MyAspect = aspect(
            implementation = _aspect_impl,
            attrs = { 'my_attr' : attr.int(default = 1, values = [1, 2, 3]) },
        )

        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'dep' : attr.label(aspects=[MyAspect]) }
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'main_target',
                dep = ':dep_target',
        )
        my_rule(name = 'dep_target')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main_target");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkList<?> ruleResult =
        (StarlarkList) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("my_rule_result");
    assertThat(Starlark.toIterable(ruleResult))
        .containsExactly("my_aspect on target @//test:dep_target, my_attr = 1");
  }

  @Test
  public void aspectIntegerParameter_valueOverwrittenByRuleDefault() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
          result = ['my_aspect on target {}, my_attr = {}'.
                                            format(target.label, ctx.attr.my_attr)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.my_aspect_result
          return [AspectInfo(my_aspect_result = result)]

        RuleInfo = provider()
        def _rule_impl(ctx):
          if ctx.attr.dep:
            return RuleInfo(my_rule_result = ctx.attr.dep[AspectInfo].my_aspect_result)
          pass

        MyAspect = aspect(
            implementation = _aspect_impl,
            attrs = { 'my_attr' : attr.int(default = 1, values = [1, 2, 3]) },
        )

        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'dep' : attr.label(aspects=[MyAspect]),
                      'my_attr': attr.int(default = 2) }
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'main_target',
                dep = ':dep_target',
        )
        my_rule(name = 'dep_target')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main_target");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkList<?> ruleResult =
        (StarlarkList) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("my_rule_result");
    assertThat(Starlark.toIterable(ruleResult))
        .containsExactly("my_aspect on target @//test:dep_target, my_attr = 2");
  }

  @Test
  public void aspectIntegerParameter_valueOverwrittenByTargetValue() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
          result = ['my_aspect on target {}, my_attr = {}'.
                                            format(target.label, ctx.attr.my_attr)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep[AspectInfo].my_aspect_result
          return AspectInfo(my_aspect_result = result)

        RuleInfo = provider()
        def _rule_impl(ctx):
          if ctx.attr.dep:
            return RuleInfo(my_rule_result = ctx.attr.dep[AspectInfo].my_aspect_result)
          pass

        MyAspect = aspect(
            implementation = _aspect_impl,
            attrs = { 'my_attr' : attr.int(default = 1, values = [1, 2, 3]) },
        )

        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'dep' : attr.label(aspects=[MyAspect]),
                      'my_attr': attr.int(default = 2) }
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'main_target',
                dep = ':dep_target',
                my_attr = 3,
        )
        my_rule(name = 'dep_target')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main_target");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkList<?> ruleResult =
        (StarlarkList) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("my_rule_result");
    assertThat(Starlark.toIterable(ruleResult))
        .containsExactly("my_aspect on target @//test:dep_target, my_attr = 3");
  }

  @Test
  public void testTopLevelAspectsWithParameters_invalidIntegerParameterValue() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.int(values = [1, 2]) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult analysisResult =
          update(
              ImmutableList.of("//test:defs.bzl%aspect_a"),
              ImmutableMap.of("p", "3"),
              "//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("//test:defs.bzl%aspect_a"),
                  ImmutableMap.of("p", "3"),
                  "//test:main_target"));
    }
    assertContainsEvent(
        "//test:defs.bzl%aspect_a: invalid value in 'p' attribute: has to be one of '1' or"
            + " '2' instead of '3'");
  }

  @Test
  public void testTopLevelAspectsWithIntegerParameter() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.int(values = [1, 2, 3]) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("//test:defs.bzl%aspect_a"),
            ImmutableMap.of("p", "2"),
            "//test:main_target");

    ImmutableMap<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkList<?> aspectAResult = (StarlarkList) aspectA.get("aspect_a_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect_a on target @//test:main_target, p = 2",
            "aspect_a on target @//test:dep_target_1, p = 2",
            "aspect_a on target @//test:dep_target_2, p = 2");
  }

  @Test
  public void testTopLevelAspectsWithIntegerParameter_useDefaultValue() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.int(default = 1, values = [1, 2, 3]) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("//test:defs.bzl%aspect_a"), "//test:main_target");

    ImmutableMap<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkList<?> aspectAResult = (StarlarkList) aspectA.get("aspect_a_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect_a on target @//test:main_target, p = 1",
            "aspect_a on target @//test:dep_target_1, p = 1",
            "aspect_a on target @//test:dep_target_2, p = 1");
  }

  @Test
  public void booleanAspectParameter_mandatoryAttrNotCoveredByRule() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.bool(default = True, mandatory = True) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type boolean.");
  }

  @Test
  public void booleanAspectParameter_mandatoryAttrWithWrongTypeInRule() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.bool(default = True, mandatory = True) },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]),
                      'my_attr': attr.string() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type boolean.");
  }

  @Test
  public void booleanAspectParameter_attrWithoutDefaultNotCoveredByRule() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.bool() },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type boolean.");
  }

  @Test
  public void booleanAspectParameter_attrWithoutDefaultWrongTypeInRule() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        def _impl(target, ctx):
           return []
        def _rule_impl(ctx):
           return []
        MyAspectUncovered = aspect(
            implementation=_impl,
            attrs = { 'my_attr' : attr.bool() },
        )
        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'deps' : attr.label_list(aspects=[MyAspectUncovered]),
                      'my_attr': attr.string() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name ='main')
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update(ImmutableList.of(), "//test:main"));
    }

    assertContainsEvent(
        "Aspect //test:aspect.bzl%MyAspectUncovered requires rule my_rule to specify attribute "
            + "'my_attr' with type boolean.");
  }

  @Test
  public void aspectBooleanParameter_withDefaultValue() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
          result = ['my_aspect on target {}, my_attr = {}'.
                                            format(target.label, ctx.attr.my_attr)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.my_aspect_result
          return AspectInfo(my_aspect_result = result)

        RuleInfo = provider()
        def _rule_impl(ctx):
          if ctx.attr.dep:
            return RuleInfo(my_rule_result = ctx.attr.dep[AspectInfo].my_aspect_result)
          pass

        MyAspect = aspect(
            implementation = _aspect_impl,
            attrs = { 'my_attr' : attr.bool(default = True) },
        )

        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'dep' : attr.label(aspects=[MyAspect]) }
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'main_target',
                dep = ':dep_target',
        )
        my_rule(name = 'dep_target')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main_target");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkList<?> ruleResult =
        getStarlarkProvider(configuredTarget, "RuleInfo")
            .getValue("my_rule_result", StarlarkList.class);
    assertThat(Starlark.toIterable(ruleResult))
        .containsExactly("my_aspect on target @//test:dep_target, my_attr = True");
  }

  @Test
  public void aspectBooleanParameter_valueOverwrittenByRuleDefault() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
          result = ['my_aspect on target {}, my_attr = {}'.
                                            format(target.label, ctx.attr.my_attr)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep[AspectInfo].my_aspect_result
          return AspectInfo(my_aspect_result = result)

        RuleInfo = provider()
        def _rule_impl(ctx):
          if ctx.attr.dep:
            return RuleInfo(my_rule_result = ctx.attr.dep[AspectInfo].my_aspect_result)
          pass

        MyAspect = aspect(
            implementation = _aspect_impl,
            attrs = { 'my_attr' : attr.bool(default = True) },
        )

        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'dep' : attr.label(aspects=[MyAspect]),
                      'my_attr': attr.bool(default = False) }
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'main_target',
                dep = ':dep_target',
        )
        my_rule(name = 'dep_target')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main_target");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkList<?> ruleResult =
        (StarlarkList) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("my_rule_result");
    assertThat(Starlark.toIterable(ruleResult))
        .containsExactly("my_aspect on target @//test:dep_target, my_attr = False");
  }

  @Test
  public void aspectBooleanParameter_valueOverwrittenByTargetValue() throws Exception {
    scratch.file(
        "test/aspect.bzl",
        """
        AspectInfo = provider()
        def _aspect_impl(target, ctx):
          result = ['my_aspect on target {}, my_attr = {}'.
                                            format(target.label, ctx.attr.my_attr)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep[AspectInfo].my_aspect_result
          return AspectInfo(my_aspect_result = result)

        RuleInfo = provider()
        def _rule_impl(ctx):
          if ctx.attr.dep:
            return RuleInfo(my_rule_result = ctx.attr.dep[AspectInfo].my_aspect_result)
          pass

        MyAspect = aspect(
            implementation = _aspect_impl,
            attrs = { 'my_attr' : attr.bool(default = True) },
        )

        my_rule = rule(
            implementation=_rule_impl,
            attrs = { 'dep' : attr.label(aspects=[MyAspect]),
                      'my_attr': attr.bool(default = True) }
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:aspect.bzl', 'my_rule')
        my_rule(name = 'main_target',
                dep = ':dep_target',
                my_attr = False,
        )
        my_rule(name = 'dep_target')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of(), "//test:main_target");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkList<?> ruleResult =
        (StarlarkList) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("my_rule_result");
    assertThat(Starlark.toIterable(ruleResult))
        .containsExactly("my_aspect on target @//test:dep_target, my_attr = False");
  }

  @Test
  public void testTopLevelAspectsWithBooleanParameter() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.bool() },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);

    AnalysisResult analysisResult =
        update(
            ImmutableList.of("//test:defs.bzl%aspect_a"),
            ImmutableMap.of("p", "y"),
            "//test:main_target");

    ImmutableMap<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkList<?> aspectAResult = (StarlarkList) aspectA.get("aspect_a_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect_a on target @//test:main_target, p = True",
            "aspect_a on target @//test:dep_target_1, p = True",
            "aspect_a on target @//test:dep_target_2, p = True");
  }

  @Test
  public void testTopLevelAspectsWithBooleanParameter_useDefaultValue() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.bool(default = False) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);

    AnalysisResult analysisResult =
        update(ImmutableList.of("//test:defs.bzl%aspect_a"), "//test:main_target");

    ImmutableMap<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkList<?> aspectAResult = (StarlarkList) aspectA.get("aspect_a_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect_a on target @//test:main_target, p = False",
            "aspect_a on target @//test:dep_target_1, p = False",
            "aspect_a on target @//test:dep_target_2, p = False");
  }

  @Test
  public void testTopLevelAspectsWithBooleanParameter_invalidValue() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.bool() },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label() },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a ViewCreationFailedException.
    if (keepGoing()) {
      AnalysisResult analysisResult =
          update(
              ImmutableList.of("//test:defs.bzl%aspect_a"),
              ImmutableMap.of("p", "x"),
              "//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(
          ViewCreationFailedException.class,
          () ->
              update(
                  ImmutableList.of("//test:defs.bzl%aspect_a"),
                  ImmutableMap.of("p", "x"),
                  "//test:main_target"));
    }
    assertContainsEvent(
        "//test:defs.bzl%aspect_a: expected value of type 'bool' for attribute 'p' but got 'x'");
  }

  @Test
  public void testRuleAspectWithMandatoryParameterNotProvided() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.string(default = 'p_v', values = ['p_v'], mandatory = True) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label(aspects = [aspect_a]) },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update("//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update("//test:main_target"));
    }
    assertContainsEvent(
        "Aspect //test:defs.bzl%aspect_a requires rule my_rule to specify attribute 'p' with type"
            + " string");
  }

  @Test
  public void testRuleAspectWithMandatoryParameterProvidedWrongType() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _aspect_a_impl(target, ctx):
          result = ['aspect_a on target {}, p = {}'.
                                            format(target.label, ctx.attr.p)]
          if ctx.rule.attr.dep:
            result += ctx.rule.attr.dep.aspect_a_result
          return struct(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.string(default = 'p_v', values = ['p_v'], mandatory = True) },
        )

        def _my_rule_impl(ctx):
          pass
        my_rule = rule(
          implementation = _my_rule_impl,
           attrs = { 'dep' : attr.label(aspects = [aspect_a]),
                     'p': attr.int() }
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'my_rule')
        my_rule(
          name = 'main_target',
          dep = ':dep_target_1',
        )
        my_rule(
          name = 'dep_target_1',
          dep = ':dep_target_2',
        )
        my_rule(
          name = 'dep_target_2',
        )
        """);
    reporter.removeHandler(failFastHandler);

    // This call succeeds if "--keep_going" was passed, which it does in the WithKeepGoing test
    // suite. Otherwise, it fails and throws a TargetParsingException.
    if (keepGoing()) {
      AnalysisResult analysisResult = update("//test:main_target");
      assertThat(analysisResult.hasError()).isTrue();
    } else {
      assertThrows(TargetParsingException.class, () -> update("//test:main_target"));
    }
    assertContainsEvent(
        "Aspect //test:defs.bzl%aspect_a requires rule my_rule to specify attribute 'p' with type"
            + " string");
  }

  @Test
  public void testRuleAspectWithMandatoryParameter_useRuleDefault() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        AspectInfo = provider()
        def _aspect_a_impl(target, ctx):
          result = 'aspect_a on target {}, p = {}'.format(target.label, ctx.attr.p)
          return AspectInfo(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.string(default = 'p_v1', values = ['p_v1', 'p_v2'],
                                      mandatory = True) },
        )

        RuleInfo = provider()
        def _main_rule_impl(ctx):
          if ctx.attr.dep:
            return RuleInfo(aspect_a_result = ctx.attr.dep[AspectInfo].aspect_a_result)
          pass
        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'dep': attr.label(aspects = [aspect_a]),
            'p' : attr.string(default = 'p_v2'),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
        )
        main_rule(
          name = 'dep_target',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    String aspectAResult =
        getStarlarkProvider(configuredTarget, "RuleInfo").getValue("aspect_a_result", String.class);
    assertThat(aspectAResult).isEqualTo("aspect_a on target @//test:dep_target, p = p_v2");
  }

  @Test
  public void testRuleAspectWithMandatoryParameterProvided() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        AspectInfo = provider()
        def _aspect_a_impl(target, ctx):
          result = 'aspect_a on target {}, p = {}'.format(target.label, ctx.attr.p)
          return AspectInfo(aspect_a_result = result)

        aspect_a = aspect(
          implementation = _aspect_a_impl,
          attr_aspects = ['dep'],
          attrs = { 'p' : attr.string(default = 'p_v2', values = ['p_v1', 'p_v2'],
                                      mandatory = True) },
        )

        RuleInfo = provider()
        def _main_rule_impl(ctx):
          if ctx.attr.dep:
            return RuleInfo(aspect_a_result = ctx.attr.dep[AspectInfo].aspect_a_result)
          pass
        main_rule = rule(
          implementation = _main_rule_impl,
          attrs = {
            'dep': attr.label(aspects = [aspect_a]),
            'p' : attr.string(mandatory = True),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'main_rule')
        main_rule(
          name = 'main',
          dep = ':dep_target',
          p = 'p_v1',
        )
        main_rule(
          name = 'dep_target',
          p = 'p_v2',
        )
        """);

    AnalysisResult analysisResult = update("//test:main");

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    String aspectAResult =
        (String) getStarlarkProvider(configuredTarget, "RuleInfo").getValue("aspect_a_result");
    assertThat(aspectAResult).isEqualTo("aspect_a on target @//test:dep_target, p = p_v1");
  }

  @Test
  public void testAspectLabelIsRepoMapped() throws Exception {
    scratch.appendFile("WORKSPACE", "workspace(name = 'my_repo')");
    scratch.file(
        "test/aspect.bzl",
        """
        load(':rule.bzl', 'MyInfo')
        def _impl(target, ctx):
           if MyInfo not in target:
               fail('Provider identity mismatch')
           return []
        MyAspect = aspect(implementation=_impl)
        """);
    scratch.file(
        "test/rule.bzl",
        """
        MyInfo = provider()
        def _impl(ctx):
            return [MyInfo()]
        my_rule = rule(implementation=_impl)
        """);
    scratch.file(
        "test/BUILD",
        """
        load(':rule.bzl', 'my_rule')
        my_rule(name = 'target')
        """);

    AnalysisResult result =
        update(ImmutableList.of("@my_repo//test:aspect.bzl%MyAspect"), "//test:target");
    assertThat(result.hasError()).isFalse();
  }

  @Test
  public void testAspectKeyCreatedOnlyOnceForSameBaseKeysInDiffOrder() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a_provider = provider()
        b_provider = provider()
        c_provider = provider()
        RuleInfo = provider()

        def _a_impl(target, ctx):
          result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              result.extend(dep[a_provider].value)
          result.append('aspect a on target {} aspect_ids {}'.format(target.label,
                                                                        ctx.aspect_ids))
          return [a_provider(value = result)]
        a = aspect(
          implementation = _a_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [[b_provider], [c_provider]],
        )

        def _b_impl(target, ctx):
          return [b_provider(value = ['aspect b on target {}'.format(target.label)])]
        b = aspect(
          implementation = _b_impl,
          attr_aspects = ['deps'],
          provides = [b_provider],
        )

        def _c_impl(target, ctx):
          return [c_provider(value = ['aspect c on target {}'.format(target.label)])]
        c = aspect(
          implementation = _c_impl,
          attr_aspects = ['deps'],
          provides = [c_provider]
        )

        def _r1_impl(ctx):
          result = []
          if ctx.attr.deps:
            for dep in ctx.attr.deps:
              result.extend(dep[a_provider].value)
          return RuleInfo(aspect_a_collected_result = result)
        r1 = rule(
          implementation = _r1_impl,
          attrs = {
            'deps': attr.label_list(aspects = [c, b, a]),
          },
        )

        def _r2_impl(ctx):
          pass
        r2 = rule(
          implementation = _r2_impl,
          attrs = {
            'deps': attr.label_list(aspects = [b]),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'r1', 'r2')
        r1(
          name = 't1',
        # base_keys of aspect a on t3 are [c, b]
          deps = [':t2', ':t3'],
        )
        r2(
          name = 't2',
          # aspects reaching t3 will be [b, c, b, a], after deduplicating aspects path, it will be
          # [b, c, a] and as a result the base_keys of aspect a will be [b, c]
          deps = [':t3'],
        )
        r2(
          name = 't3',
        )
        """);

    update("//test:t1");

    // Aspect a should have a single AspectKey for its application on t3 and the baseKeys in it will
    // be sorted as [b, c]
    ImmutableList<AspectKey> keysForAspectAOnT3 = getAspectKeys("//test:t3", "//test:defs.bzl%a");
    assertThat(keysForAspectAOnT3).hasSize(1);

    ImmutableList<AspectKey> baseKeys = keysForAspectAOnT3.get(0).getBaseKeys();
    assertThat(baseKeys.stream().map(k -> k.getAspectClass().getName()))
        .containsExactly("//test:defs.bzl%b", "//test:defs.bzl%c")
        .inOrder();
  }

  @Test
  public void testAspectRunsTwiceWithDiffBaseAspectsDeps() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        a_provider = provider()
        b_provider = provider()
        c_provider = provider()

        def _a_impl(target, ctx):
          result = []
          if ctx.rule.attr.deps:
            for dep in ctx.rule.attr.deps:
              result.extend(dep[a_provider].value)
          if b_provider in target:
            result.append('aspect a on {} sees b_provider = {}'.format(target.label,
                                                                      target[b_provider].value))
          return [a_provider(value = result)]
        a = aspect(
          implementation = _a_impl,
          attr_aspects = ['deps'],
          required_aspect_providers = [[b_provider], [c_provider]],
        )

        def _b_impl(target, ctx):
          result = 'aspect b cannot see c_provider'
          if c_provider in target:
            result = 'aspect b can see c_provider'
          return [b_provider(value = result)]
        b = aspect(
          implementation = _b_impl,
          attr_aspects = ['deps'],
          provides = [b_provider],
          required_aspect_providers = [[c_provider]]
        )

        def _c_impl(target, ctx):
          return [c_provider(value = ['aspect c on target {}'.format(target.label)])]
        c = aspect(
          implementation = _c_impl,
          attr_aspects = ['deps'],
          provides = [c_provider]
        )

        RuleInfo = provider()
        def _r1_impl(ctx):
          result = []
          if ctx.attr.deps:
            for dep in ctx.attr.deps:
              result.extend(dep[a_provider].value)
          return RuleInfo(aspect_a_collected_result = result)
        r1 = rule(
          implementation = _r1_impl,
          attrs = {
            'deps': attr.label_list(aspects = [a]),
          },
        )

        def _r2_impl(ctx):
          pass
        r2 = rule(
          implementation = _r2_impl,
          attrs = {
            'deps': attr.label_list(aspects = [c, b]),
          },
        )

        def _r3_impl(ctx):
          pass
        r3 = rule(
          implementation = _r3_impl,
          attrs = {
            'deps': attr.label_list(aspects = [b, c]),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'r1', 'r2', 'r3')
        r1(
          name = 't1',
          # t1 propagate aspect (a) to targets (t2 and t3)
          deps = [':t2', ':t3'],
        )
        r2(
          name = 't2',
          # t2 propagates aspects (c, b) to target t4 and aspect a is propagated from the prev
          # level aspects path on t4 is [c, b, a], this means a can see b and b can see c
          deps = [':t4'],
        )
        r3(
          name = 't3',
        # t3 propagates aspects (b, c) to target t4 and aspect a is propagated from the prev level
        # aspects path on t4 is [b, c, a], this means a can see b but b cannot see c
         deps = [':t4'],
        )
        r1(
          name = 't4',
        )
        """);

    AnalysisResult analysisResult = update("//test:t1");

    // Aspect a should have 2 AspectKeys for its application on t4, one where in the basekeys b can
    // see c and the other is where b cannot see c
    ImmutableList<AspectKey> keysForAspectAOnT4 = getAspectKeys("//test:t4", "//test:defs.bzl%a");
    assertThat(keysForAspectAOnT4).hasSize(2);

    ConfiguredTarget configuredTarget =
        Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
    StarlarkList<?> aspectAResult =
        (StarlarkList)
            getStarlarkProvider(configuredTarget, "RuleInfo").getValue("aspect_a_collected_result");
    assertThat(Starlark.toIterable(aspectAResult))
        .containsExactly(
            "aspect a on @//test:t4 sees b_provider = aspect b can see c_provider",
            "aspect a on @//test:t4 sees b_provider = aspect b cannot see c_provider");
  }

  @Test
  public void testAspectWithSameExplicitAttributeNameAsUnderlyingTarget() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _a_impl(target, ctx):
          value = 'x from aspect = {}, x from target = {}'.format(ctx.attr.x, ctx.rule.attr.x)
          return struct(aspect_result = value)
        a = aspect(
          implementation = _a_impl,
          attrs = {
            'x': attr.string(default = 'xyz')
          },
        )

        def _rule_impl(ctx):
          pass
        r1 = rule(
          implementation = _rule_impl,
          attrs = {
            'x': attr.int(default = 4)
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'r1')
        r1(name = 't1')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of("//test:defs.bzl%a"), "//test:t1");

    ImmutableMap<AspectKey, ConfiguredAspect> configuredAspects = analysisResult.getAspectsMap();
    ConfiguredAspect aspectA = getConfiguredAspect(configuredAspects, "a");
    assertThat(aspectA).isNotNull();
    String aspectAResult = (String) aspectA.get("aspect_result");
    assertThat(aspectAResult).isEqualTo("x from aspect = xyz, x from target = 4");
  }

  @Test
  public void testAspectNotDependOnTargetDeps() throws Exception {
    scratch.file(
        "test/defs.bzl",
        """
        def _a_impl(target, ctx):
          return []
        a = aspect(
          implementation = _a_impl,
          attr_aspects = ['dep'],
          attrs = {
            '_tool': attr.label(default = '//test:tool'),
          },
        )

        def _rule_impl(ctx):
          pass
        r1 = rule(
          implementation = _rule_impl,
          attrs = {
            'dep': attr.label(),
            'another_dep': attr.label(),
            '_tool': attr.label(default = '//test:tool'),
          },
        )
        """);
    scratch.file(
        "test/BUILD",
        """
        load('//test:defs.bzl', 'r1')
        r1(name = 't1', dep = ':t2', another_dep = 't4')
        r1(name = 't2', dep = ':t3')
        r1(name = 't3')
        r1(name = 't4')
        sh_library(name = 'tool')
        """);

    AnalysisResult analysisResult = update(ImmutableList.of("//test:defs.bzl%a"), "//test:t1");

    AspectKey key = Iterables.getOnlyElement(analysisResult.getAspectsMap().keySet());
    var aspectNode =
        skyframeExecutor.getEvaluator().getInMemoryGraph().getAllNodeEntries().stream()
            .filter(n -> n.getKey().equals(key))
            .findFirst()
            .orElse(null);
    assertThat(aspectNode).isNotNull();

    ImmutableList<String> configuredTargetsDeps =
        stream(Iterables.filter(aspectNode.getDirectDeps(), ConfiguredTargetKey.class))
            .map(k -> k.getLabel().toString())
            .collect(toImmutableList());
    // aspect depends only on its target and its implicit dependencies not the dependencies of its
    // target
    assertThat(configuredTargetsDeps).containsAtLeast("//test:tool", "//test:t1");
    assertThat(configuredTargetsDeps).doesNotContain("//test:t2");
    assertThat(configuredTargetsDeps).doesNotContain("//test:t3");
    assertThat(configuredTargetsDeps).doesNotContain("//test:t4");

    ImmutableList<String> aspectsDeps =
        stream(Iterables.filter(aspectNode.getDirectDeps(), AspectKey.class))
            .map(k -> k.getLabel().toString())
            .collect(toImmutableList());
    // aspect depends on the result of its application on the target deps if it propagates to them
    assertThat(aspectsDeps).containsExactly("//test:t2");
  }

  private ImmutableList<AspectKey> getAspectKeys(String targetLabel, String aspectLabel) {
    return skyframeExecutor.getEvaluator().getDoneValues().entrySet().stream()
        .filter(
            entry ->
                entry.getKey() instanceof AspectKey
                    && ((AspectKey) entry.getKey()).getAspectClass().getName().equals(aspectLabel)
                    && ((AspectKey) entry.getKey()).getLabel().toString().equals(targetLabel))
        .map(e -> (AspectKey) e.getKey())
        .collect(toImmutableList());
  }

  private ConfiguredAspect getConfiguredAspect(
      Map<AspectKey, ConfiguredAspect> aspectsMap, String aspectName) {
    for (Map.Entry<AspectKey, ConfiguredAspect> entry : aspectsMap.entrySet()) {
      AspectClass aspectClass = entry.getKey().getAspectClass();
      if (aspectClass instanceof StarlarkAspectClass) {
        String aspectExportedName = ((StarlarkAspectClass) aspectClass).getExportedName();
        if (aspectExportedName.equals(aspectName)) {
          return entry.getValue();
        }
      }
    }
    return null;
  }

  private ConfiguredAspect getConfiguredAspect(
      Map<AspectKey, ConfiguredAspect> aspectsMap, String aspectName, String targetName) {
    for (Map.Entry<AspectKey, ConfiguredAspect> entry : aspectsMap.entrySet()) {
      AspectClass aspectClass = entry.getKey().getAspectClass();
      if (aspectClass instanceof StarlarkAspectClass) {
        String aspectExportedName = ((StarlarkAspectClass) aspectClass).getExportedName();
        String target = entry.getKey().getLabel().getName();
        if (aspectExportedName.equals(aspectName) && target.equals(targetName)) {
          return entry.getValue();
        }
      }
    }
    return null;
  }

  private void exposeNativeAspectToStarlark() throws Exception {
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    builder.addBzlToplevel(
        "starlark_native_aspect", TestAspects.STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
    builder.addBzlToplevel(
        "parametrized_native_aspect",
        TestAspects.PARAMETRIZED_STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
    builder.addNativeAspectClass(TestAspects.STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
    builder.addNativeAspectClass(TestAspects.PARAMETRIZED_STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
    builder.addRuleDefinition(TestAspects.BASE_RULE);
    builder.addRuleDefinition(TestAspects.HONEST_RULE);
    useRuleClassProvider(builder.build());
  }

  /** StarlarkAspectTest with "keep going" flag */
  @RunWith(JUnit4.class)
  public static final class WithKeepGoing extends StarlarkDefinedAspectsTest {
    @Override
    protected FlagBuilder defaultFlags() {
      return super.defaultFlags().with(Flag.KEEP_GOING);
    }

    @Override
    protected boolean keepGoing() {
      return true;
    }
  }
}
