// Copyright 2018 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.query2.cquery;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.Type.STRING;
import static com.google.devtools.build.lib.packages.Types.STRING_LIST;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.BuildOptionsView;
import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.analysis.config.TransitionFactories;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.test.TestConfiguration.TestOptions;
import com.google.devtools.build.lib.analysis.util.DummyTestFragment.DummyTestOptions;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.LabelPrinter;
import com.google.devtools.build.lib.query2.common.CqueryNode;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.Setting;
import com.google.devtools.build.lib.query2.engine.QueryException;
import com.google.devtools.build.lib.query2.testutil.PostAnalysisQueryHelper;
import com.google.devtools.build.lib.server.FailureDetails;
import com.google.devtools.build.lib.server.FailureDetails.ConfigurableQuery;
import com.google.devtools.build.lib.server.FailureDetails.Query;
import com.google.devtools.build.lib.server.FailureDetails.Query.Code;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.build.lib.vfs.Path;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link ConfiguredTargetQueryEnvironment}.
 *
 * <p>This tests core cquery behavior (behavior that doesn't depend on <code>--output</code>).
 * Output format-specific behavior is covered in dedicated test classes.
 */
@RunWith(JUnit4.class)
public class ConfiguredTargetQuerySemanticsTest extends ConfiguredTargetQueryTest {
  @Test
  public void testConfigurationRespected() throws Exception {
    writeBuildFilesWithConfigurableAttributesUnconditionally();
    assertThat(eval("deps(//configurable:main) ^ //configurable:adep")).isEmpty();
    assertThat(eval("deps(//configurable:main) ^ //configurable:defaultdep")).hasSize(1);
  }

  private void setUpLabelsFunctionTests() throws Exception {
    MockRule ruleWithTransitions =
        () ->
            MockRule.define(
                "rule_with_transitions",
                attr("patch_dep", LABEL)
                    .allowedFileTypes(FileTypeSet.ANY_FILE)
                    .cfg(TransitionFactories.of(new FooPatchTransition("SET BY PATCH"))),
                attr("string_dep", STRING),
                attr("split_dep", LABEL)
                    .allowedFileTypes(FileTypeSet.ANY_FILE)
                    .cfg(
                        TransitionFactories.of(
                            new FooSplitTransition("SET BY SPLIT 1", "SET BY SPLIT 2"))),
                attr("patch_dep_list", LABEL_LIST)
                    .allowedFileTypes(FileTypeSet.ANY_FILE)
                    .cfg(TransitionFactories.of(new FooPatchTransition("SET BY PATCH 2"))));
    MockRule noAttributeRule = () -> MockRule.define("no_attribute_rule");

    helper.useRuleClassProvider(
        setRuleClassProviders(ruleWithTransitions, noAttributeRule).build());

    writeFile(
        "test/BUILD",
        """
        rule_with_transitions(
            name = "my_rule",
            patch_dep = ":dep-1",
            patch_dep_list = [
                ":dep-3",
                ":dep-4",
            ],
            split_dep = ":dep-2",
            string_dep = "some string",
        )

        no_attribute_rule(name = "dep-1")

        no_attribute_rule(name = "dep-2")

        no_attribute_rule(name = "dep-3")

        no_attribute_rule(name = "dep-4")
        """);

    helper.setUniverseScope("//test:*");
  }

  @Test
  public void testLabelFunction_getsCorrectConfigurations() throws Exception {
    setUpLabelsFunctionTests();

    // (Test that you can use the labels function without an error (b/112593112)).
    // Note - 'labels' as a command for cquery is a slight misnomer since it always prints
    // labels AND configurations. But still a helpful function so oh well.
    assertThat(Iterables.getOnlyElement(eval("labels('patch_dep', //test:my_rule)"))).isNotNull();
  }

  @Test
  public void testLabelFunction_getCorrectlyConfiguredDeps() throws Exception {
    setUpLabelsFunctionTests();

    // Test that this retrieves the correctly configured version(s) of the dep(s).
    CqueryNode patchDep = Iterables.getOnlyElement(eval("labels('patch_dep', //test:my_rule)"));
    CqueryNode myRule = Iterables.getOnlyElement(eval("//test:my_rule"));
    String targetConfiguration = myRule.getConfigurationChecksum();
    assertThat(patchDep.getConfigurationChecksum()).doesNotMatch(targetConfiguration);
  }

  @Test
  public void testLabelsFunction_splitTransitionAttribute() throws Exception {
    setUpLabelsFunctionTests();

    CqueryNode myRule = Iterables.getOnlyElement(eval("//test:my_rule"));
    String targetConfiguration = myRule.getConfigurationChecksum();

    Set<CqueryNode> splitDeps = eval("labels('split_dep', //test:my_rule)");
    assertThat(splitDeps).hasSize(2);
    for (CqueryNode kct : splitDeps) {
      assertThat(kct.getConfigurationChecksum()).doesNotMatch(targetConfiguration);
    }
  }

  @Test
  public void testLabelsFunction_labelListAttribute() throws Exception {
    setUpLabelsFunctionTests();

    CqueryNode myRule = Iterables.getOnlyElement(eval("//test:my_rule"));
    String targetConfiguration = myRule.getConfigurationChecksum();

    // Test that this works for label_lists as well.
    Set<CqueryNode> deps = eval("labels('patch_dep_list', //test:my_rule)");
    assertThat(deps).hasSize(2);
    for (CqueryNode kct : deps) {
      assertThat(kct.getConfigurationChecksum()).doesNotMatch(targetConfiguration);
    }
  }

  @Test
  public void testLabelsFunction_errorsOnBadAttribute() throws Exception {
    setUpLabelsFunctionTests();

    // Test that the proper error is thrown when requesting an attribute that doesn't exist.
    EvalThrowsResult evalThrowsResult = evalThrows("labels('fake_attr', //test:my_rule)", true);
    assertConfigurableQueryCode(
        evalThrowsResult.getFailureDetail(), ConfigurableQuery.Code.ATTRIBUTE_MISSING);
    assertThat(evalThrowsResult.getMessage())
        .isEqualTo(
            "in 'fake_attr' of rule //test:my_rule: configured target of type"
                + " rule_with_transitions does not have attribute 'fake_attr'");
  }

  @Test
  public void testLabelsFunction_nonLabelAttribute() throws Exception {
    setUpLabelsFunctionTests();
    assertThat(eval("labels('string_dep', //test:my_rule)")).isEmpty();
  }

  /**
   * Regression test for b/162431514. the {@code labels} query operator uses {@link
   * ConfiguredTargetAccessor#getPrerequisites} which is the actual logic being tested here.
   */
  @Test
  public void testGetPrerequisitesFromAliasReturnsActualPrerequisites() throws Exception {
    MockRule ruleWithDep =
        () ->
            MockRule.define(
                "rule_with_dep", attr("dep", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE));

    helper.useRuleClassProvider(setRuleClassProviders(ruleWithDep).build());
    writeFile(
        "test/BUILD",
        """
        alias(
            name = "alias",
            actual = ":actual",
        )

        rule_with_dep(
            name = "actual",
            dep = ":dep",
        )

        rule_with_dep(name = "dep")
        """);

    CqueryNode dep = Iterables.getOnlyElement(eval("labels('dep', '//test:alias')"));
    assertThat(dep.getLabel()).isEqualTo(Label.parseCanonicalUnchecked("//test:dep"));
  }

  @Test
  public void testAlias_filtering() throws Exception {
    MockRule ruleWithExecDep =
        () ->
            MockRule.define(
                "rule_with_exec_dep",
                attr("exec_dep", LABEL)
                    .allowedFileTypes(FileTypeSet.ANY_FILE)
                    .cfg(ExecutionTransitionFactory.createFactory()),
                attr("$impl_dep", LABEL)
                    .allowedFileTypes(FileTypeSet.ANY_FILE)
                    .value(Label.parseCanonicalUnchecked("//test:other")));
    MockRule simpleRule = () -> MockRule.define("simple_rule");

    helper.useRuleClassProvider(setRuleClassProviders(ruleWithExecDep, simpleRule).build());
    writeFile(
        "test/BUILD",
        """
        alias(
            name = "other_my_rule",
            actual = ":my_rule",
        )

        rule_with_exec_dep(
            name = "my_rule",
            exec_dep = ":exec_dep",
        )

        alias(
            name = "other_exec_dep",
            actual = ":exec_dep",
        )

        simple_rule(name = "exec_dep")

        alias(
            name = "other_impl_dep",
            actual = "impl_dep",
        )

        simple_rule(name = "impl_dep")
        """);

    CqueryNode other = Iterables.getOnlyElement(eval("//test:other_my_rule"));
    CqueryNode myRule = Iterables.getOnlyElement(eval("//test:my_rule"));
    // Note: {@link ConfiguredTarget#getLabel} returns the label of the "actual" value not the
    // label of the alias, so we need to check the underlying label.
    assertThat(other.getLabel()).isEqualTo(myRule.getLabel());

    // Regression test for b/73496081 in which alias-ed configured targets were skipping filtering.
    helper.setQuerySettings(Setting.ONLY_TARGET_DEPS, Setting.NO_IMPLICIT_DEPS);
    assertThat(
            evalToListOfStrings(
                "deps(//test:other_my_rule)-//test:other_my_rule"
                    + getDependencyCorrectionWithGen()))
        .isEqualTo(evalToListOfStrings("//test:my_rule"));
  }

  @Test
  public void testTopLevelTransition() throws Exception {
    MockRule ruleClassTransition =
        () ->
            MockRule.define(
                "rule_class_transition",
                (builder, env) ->
                    builder.cfg(unused -> new FooPatchTransition("SET BY PATCH")).build());

    helper.useRuleClassProvider(setRuleClassProviders(ruleClassTransition).build());
    helper.setUniverseScope("//test:rule_class");

    writeFile("test/BUILD", "rule_class_transition(name='rule_class')");

    Set<CqueryNode> ruleClass = eval("//test:rule_class");
    DummyTestOptions testOptions =
        getConfiguration(Iterables.getOnlyElement(ruleClass))
            .getOptions()
            .get(DummyTestOptions.class);
    assertThat(testOptions.foo).isEqualTo("SET BY PATCH");
  }

  private void createConfigRulesAndBuild() throws Exception {
    MockRule ruleWithTransitions =
        () ->
            MockRule.define(
                "my_rule",
                attr("target", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE),
                attr("exec", LABEL)
                    .allowedFileTypes(FileTypeSet.ANY_FILE)
                    .cfg(ExecutionTransitionFactory.createFactory()),
                attr("deps", BuildType.LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE));
    MockRule simpleRule =
        () ->
            MockRule.define(
                "simple_rule", attr("dep", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE));
    helper.useRuleClassProvider(setRuleClassProviders(ruleWithTransitions, simpleRule).build());

    writeFile(
        "test/BUILD",
        """
        my_rule(
            name = "my_rule",
            exec = ":exec_dep",
            target = ":target_dep",
            deps = [":dep"],
        )

        simple_rule(
            name = "target_dep",
            dep = ":dep",
        )

        simple_rule(
            name = "exec_dep",
            dep = ":dep",
        )

        simple_rule(name = "dep")
        """);
  }

  private void createConfigTransitioningRuleClass() throws Exception {
    overwriteFile(
        "tools/allowlists/function_transition_allowlist/BUILD",
        """
        package_group(
            name = "function_transition_allowlist",
            packages = [
                "//test/...",
            ],
        )
        """);
    writeFile(
        "test/rules.bzl",
        """
        def _rule_impl(ctx):
            return []

        string_flag = rule(
            implementation = _rule_impl,
            build_setting = config.string(),
        )

        def _transition_impl(settings, attr):
            return {"//test:my_flag": "custom string"}

        my_transition = transition(
            implementation = _transition_impl,
            inputs = [],
            outputs = ["//test:my_flag"],
        )
        rule_with_deps_transition = rule(
            implementation = _rule_impl,
            attrs = {
                "deps": attr.label_list(cfg = my_transition),
            },
        )
        simple_rule = rule(
            implementation = _rule_impl,
            attrs = {},
        )
        """);
  }

  @Test
  public void testConfig_target() throws Exception {
    createConfigRulesAndBuild();

    assertThat(eval("config(//test:target_dep, target)")).isEqualTo(eval("//test:target_dep"));

    getHelper().setWholeTestUniverseScope("test:my_rule");

    assertThat(eval("config(//test:target_dep, target)")).isEqualTo(eval("//test:target_dep"));
    EvalThrowsResult execResult = evalThrows("config(//test:exec_dep, target)", true);
    assertThat(execResult.getMessage())
        .isEqualTo("No target (in) //test:exec_dep could be found in the 'target' configuration");
    assertConfigurableQueryCode(
        execResult.getFailureDetail(), ConfigurableQuery.Code.TARGET_MISSING);

    BuildConfigurationValue configuration =
        getConfiguration(Iterables.getOnlyElement(eval("config(//test:dep, target)")));

    assertThat(configuration).isNotNull();
    assertThat(configuration.isExecConfiguration()).isFalse();
    assertThat(configuration.isToolConfiguration()).isFalse();
  }

  @Test
  public void testConfig_nullConfig() throws Exception {
    writeFile(
        "test/BUILD",
        """
        java_library(
            name = "my_java",
            srcs = ["foo.java"],
        )
        """);

    assertThat(getConfiguration(Iterables.getOnlyElement(eval("config(//test:foo.java,null)"))))
        .isNull();
  }

  @Test
  public void testConfig_configHash() throws Exception {
    createConfigTransitioningRuleClass();
    writeFile(
        "test/BUILD",
        """
        load("//test:rules.bzl", "rule_with_deps_transition", "simple_rule", "string_flag")

        string_flag(
            name = "my_flag",
            build_setting_default = "",
        )

        rule_with_deps_transition(
            name = "buildme",
            deps = [":mydep"],
        )

        simple_rule(name = "mydep")
        """);

    // If we don't set --universe_scope=//test:buildme, cquery builds both //test:buildme and
    // //test:mydep as top-level targets. That means //test:mydep will have two configured targets:
    // one under the transitioned configuration and one under the top-level configuration. By
    // setting --universe_scope we ensure only the transitioned version exists.
    helper.setUniverseScope("//test:buildme");
    helper.setQuerySettings(Setting.ONLY_TARGET_DEPS, Setting.NO_IMPLICIT_DEPS);
    Set<CqueryNode> result = eval("deps(//test:buildme, 1)" + getDependencyCorrection());
    assertThat(result).hasSize(2);

    ImmutableList<CqueryNode> stableOrderList = ImmutableList.copyOf(result);
    int myDepIndex = stableOrderList.get(0).getLabel().toString().equals("//test:mydep") ? 0 : 1;
    BuildConfigurationValue myDepConfig = getConfiguration(stableOrderList.get(myDepIndex));
    BuildConfigurationValue stringFlagConfig =
        getConfiguration(stableOrderList.get(1 - myDepIndex));

    // Note: eval() resets the universe scope after each call. We have to xplicitly set it again.
    helper.setUniverseScope("//test:buildme");
    assertThat(eval("config(//test:mydep, " + myDepConfig.checksum() + ")")).hasSize(1);

    helper.setUniverseScope("//test:buildme");
    QueryException e =
        assertThrows(
            QueryException.class,
            () -> eval("config(//test:mydep, " + stringFlagConfig.checksum() + ")"));
    assertThat(e)
        .hasMessageThat()
        .contains("No target (in) //test:mydep could be found in the configuration with checksum");
  }

  @Test
  public void testConfig_configHashPrefix() throws Exception {
    createConfigRulesAndBuild();
    writeFile("mytest/BUILD", "simple_rule(name = 'mytarget')");

    Set<CqueryNode> result = eval("//mytest:mytarget");
    String configHash = getConfiguration(Iterables.getOnlyElement(result)).checksum();
    String hashPrefix = configHash.substring(0, configHash.length() / 2);

    Set<CqueryNode> resultFromPrefix = eval("config(//mytest:mytarget," + hashPrefix + ")");
    assertThat(resultFromPrefix).containsExactlyElementsIn(result);
  }

  @Test
  public void testConfig_configHashUnknownPrefix() throws Exception {
    createConfigRulesAndBuild();
    writeFile("mytest/BUILD", "simple_rule(name = 'mytarget')");

    Set<CqueryNode> result = eval("//mytest:mytarget");
    String configHash = getConfiguration(Iterables.getOnlyElement(result)).checksum();
    String rightPrefix = configHash.substring(0, configHash.length() / 2);
    char lastChar = rightPrefix.charAt(rightPrefix.length() - 1);
    String wrongPrefix = rightPrefix.substring(0, rightPrefix.length() - 1) + (lastChar + 1);

    QueryException e =
        assertThrows(
            QueryException.class, () -> eval("config(//mytest:mytarget," + wrongPrefix + ")"));
    assertConfigurableQueryCode(
        e.getFailureDetail(), ConfigurableQuery.Code.INCORRECT_CONFIG_ARGUMENT_ERROR);
    assertThat(e)
        .hasMessageThat()
        .contains("config()'s second argument must identify a unique configuration");
  }

  @Test
  public void testConfig_exprArgumentFailure() throws Exception {
    writeFile(
        "test/BUILD",
        """
        java_library(
            name = "my_java",
            srcs = ["foo.java"],
        )
        """);

    EvalThrowsResult evalThrowsResult =
        evalThrows(
            "config(filter(\"??not-a-valid-regex\", //test:foo.java), null)",
            /* unconditionallyThrows= */ true);
    assertThat(evalThrowsResult.getMessage())
        .startsWith("illegal 'filter' pattern regexp '??not-a-valid-regex'");
    assertThat(evalThrowsResult.getFailureDetail().hasQuery()).isTrue();
    assertThat(evalThrowsResult.getFailureDetail().getQuery().getCode())
        .isEqualTo(Code.SYNTAX_ERROR);
  }

  @Test
  public void testExecTransitionNotFilteredByNoToolDeps() throws Exception {
    createConfigRulesAndBuild();
    helper.setQuerySettings(Setting.ONLY_TARGET_DEPS, Setting.NO_IMPLICIT_DEPS);
    assertThat(evalToListOfStrings("deps(//test:my_rule)" + getDependencyCorrection()))
        .containsExactly("//test:my_rule", "//test:target_dep", "//test:dep");
  }

  @Test
  public void testRecursiveTargetPatternNeverThrowsError() throws Exception {
    Path parent =
        getHelper()
            .getScratch()
            .file("parent/BUILD", "sh_library(name = 'parent')")
            .getParentDirectory();
    Path child = parent.getRelative("child");
    child.createDirectory();
    Path badBuild = child.getRelative("BUILD");
    badBuild.createSymbolicLink(badBuild);

    helper.setKeepGoing(true);
    assertThat(eval("//parent:all")).isEqualTo(eval("//parent:parent"));

    helper.setKeepGoing(false);
    getHelper().turnOffFailFast();
    TargetParsingException e =
        assertThrows(TargetParsingException.class, () -> eval("//parent/..."));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo(
            "error loading package under directory 'parent': no such package 'parent/child':"
                + " Symlink cycle detected while trying to find BUILD file"
                + " /workspace/parent/child/BUILD");
    assertThat(e.getDetailedExitCode().getFailureDetail().getPackageLoading().getCode())
        .isEqualTo(FailureDetails.PackageLoading.Code.SYMLINK_CYCLE_OR_INFINITE_EXPANSION);
  }

  // Regression test for b/175739699
  @Test
  public void testRecursiveTargetPatternOutsideOfScopeFailsGracefully() throws Exception {
    writeFile("testA/BUILD", "sh_library(name = 'testA')");
    writeFile("testB/BUILD", "sh_library(name = 'testB')");
    writeFile("testB/testC/BUILD", "sh_library(name = 'testC')");
    helper.setUniverseScope("//testA");
    QueryException e = assertThrows(QueryException.class, () -> eval("//testB/..."));
    assertThat(e.getFailureDetail().getQuery().getCode())
        .isEqualTo(Query.Code.TARGET_NOT_IN_UNIVERSE_SCOPE);
    assertThat(e).hasMessageThat().contains("package is not in scope");
  }

  @Override
  @Test
  public void testMultipleTopLevelConfigurations_nullConfigs() throws Exception {
    writeFile(
        "test/BUILD",
        """
        java_library(
            name = "my_java",
            srcs = ["foo.java"],
        )
        """);

    Set<CqueryNode> result = eval("//test:my_java+//test:foo.java");

    assertThat(result).hasSize(2);

    Iterator<CqueryNode> resultIterator = result.iterator();
    CqueryNode first = resultIterator.next();
    if (first.getLabel().toString().equals("//test:foo.java")) {
      assertThat(getConfiguration(first)).isNull();
      assertThat(getConfiguration(resultIterator.next())).isNotNull();
    } else {
      assertThat(getConfiguration(first)).isNotNull();
      assertThat(getConfiguration(resultIterator.next())).isNull();
    }
  }

  @Test
  public void testSomePath_depInCustomConfiguration() throws Exception {
    createConfigTransitioningRuleClass();
    writeFile(
        "test/BUILD",
        """
        load("//test:rules.bzl", "rule_with_deps_transition", "simple_rule", "string_flag")

        string_flag(
            name = "my_flag",
            build_setting_default = "",
        )

        rule_with_deps_transition(
            name = "buildme",
            deps = [":mydep"],
        )

        simple_rule(name = "mydep")
        """);

    // If we don't set --universe_scope=//test:buildme, then cquery builds both //test:buildme and
    // //test:mydep as top-level targets. That means //test:mydep will have two configured targets:
    // one under the transitioned configuration and one under the top-level configuration. In these
    // cases cquery prefers the top-level configured one, which won't produce a match since that's
    // not the one down this dependency path.
    helper.setUniverseScope("//test:buildme");
    Set<CqueryNode> result = eval("somepath(//test:buildme, //test:mydep)");
    assertThat(result.stream().map(kct -> kct.getLabel().toString()).collect(Collectors.toList()))
        .contains("//test:mydep");
  }

  /** Return an empty BuildOptions for testing fragment dropping. * */
  public static class RemoveTestOptionsTransition implements PatchTransition {
    @Override
    public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() {
      return ImmutableSet.of(TestOptions.class);
    }

    @Override
    public BuildOptions patch(BuildOptionsView options, EventHandler eventHandler) {
      BuildOptions.Builder builder = BuildOptions.builder();
      for (FragmentOptions option : options.underlying().getNativeOptions()) {
        if (!(option instanceof TestOptions)) {
          builder.addFragmentOptions(option);
        }
      }
      // This does not copy over Starlark options!!
      return builder.build();
    }
  }

  @Test
  public void testQueryHandlesDroppingFragments() throws Exception {
    MockRule ruleDropOptions =
        () ->
            MockRule.define(
                "rule_drop_options",
                attr("dep", LABEL)
                    .allowedFileTypes(FileTypeSet.ANY_FILE)
                    .cfg(TransitionFactories.of(new RemoveTestOptionsTransition())));
    MockRule simpleRule =
        () ->
            MockRule.define(
                "simple_rule", attr("deps", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE));

    helper.useRuleClassProvider(setRuleClassProviders(ruleDropOptions, simpleRule).build());
    writeFile(
        "test/BUILD",
        """
        rule_drop_options(
            name = "top",
            dep = ":foo",
        )

        simple_rule(
            name = "foo",
            deps = [":bar"],
        )

        simple_rule(name = "bar")
        """);

    Set<CqueryNode> result = eval("somepath(//test:top, filter(//test:bar, deps(//test:top)))");
    assertThat(result).isNotEmpty();
  }

  @Test
  public void testLabelExpressionsMatchesAllConfiguredTargetsWithLabel() throws Exception {
    createConfigTransitioningRuleClass();
    writeFile(
        "test/BUILD",
        """
        load("//test:rules.bzl", "rule_with_deps_transition", "simple_rule", "string_flag")

        string_flag(
            name = "my_flag",
            build_setting_default = "",
        )

        rule_with_deps_transition(
            name = "transitioner",
            deps = [":simple"],
        )

        simple_rule(name = "simple")
        """);

    helper.setUniverseScope("//test:transitioner,//test:simple");
    Set<CqueryNode> result = eval("//test:simple");
    assertThat(result.size()).isEqualTo(2);
  }

  @Test
  public void testConfigFunctionRefinesMultipleMatches() throws Exception {
    // Peer to testLabelExpressionsMatchesAllConfiguredTargetsWithLabel. The point of that test is
    // to show "cquery //foo:bar" might return multiple configured targets. The point of this test
    // is to show that config() can refine the same query to a specific one.
    createConfigTransitioningRuleClass();
    writeFile(
        "test/BUILD",
        """
        load("//test:rules.bzl", "rule_with_deps_transition", "simple_rule", "string_flag")

        string_flag(
            name = "my_flag",
            build_setting_default = "",
        )

        rule_with_deps_transition(
            name = "transitioner",
            deps = [":simple"],
        )

        simple_rule(name = "simple")
        """);

    helper.setUniverseScope("//test:transitioner,//test:simple");
    Set<CqueryNode> result = eval("config(//test:simple, target)");
    assertThat(result.size()).isEqualTo(1);
  }

  @Test
  public void testAspectDepsAppearInCqueryDeps() throws Exception {
    writeFile(
        "donut/test.bzl",
        """
        TestAspectInfo = provider("TestAspectInfo", fields = ["info"])

        def _test_aspect_impl(target, ctx):
            return [
                TestAspectInfo(
                    info = depset([target.label]),
                ),
            ]

        _test_aspect = aspect(
            implementation = _test_aspect_impl,
            attr_aspects = ["deps"],
            attrs = {
                "_test_attr": attr.label(
                    allow_files = True,
                    default = Label("//donut:test_filegroup"),
                ),
            },
            provides = [TestAspectInfo],
        )

        def _test_impl(ctx):
            pass

        test_rule = rule(
            _test_impl,
            attrs = {
                "deps": attr.label_list(
                    aspects = [_test_aspect],
                ),
            },
        )
        """);
    writeFile(
        "donut/BUILD",
        """
        load(":test.bzl", "test_rule")

        filegroup(
            name = "test_filegroup",
            srcs = ["test.bzl"],
        )

        test_rule(
            name = "test_rule_dep",
        )

        test_rule(
            name = "test_rule",
            deps = [":test_rule_dep"],
        )
        """);

    helper.setQuerySettings(Setting.INCLUDE_ASPECTS, Setting.EXPLICIT_ASPECTS);
    var result =
        eval("filter(//donut, deps(//donut:test_rule))").stream()
            .map(cf -> cf.getDescription(LabelPrinter.legacy()))
            .collect(ImmutableList.toImmutableList());
    assertThat(result)
        .containsExactly(
            "//donut:test_rule",
            "//donut:test_rule_dep",
            "//donut:test.bzl%_test_aspect of //donut:test_rule_dep",
            "//donut:test.bzl",
            "//donut:test_filegroup");
  }

  @Test
  public void testAspectOnAspectDepsAppearInCqueryDeps() throws Exception {
    writeFile(
        "donut/test.bzl",
        """
        TestAspectInfo = provider("TestAspectInfo", fields = ["info"])
        TestAspectOnAspectInfo = provider("TestAspectOnAspectInfo", fields = ["info"])

        def _test_aspect_impl(target, ctx):
            return [
                TestAspectInfo(
                    info = depset([target.label]),
                ),
            ]

        _test_aspect = aspect(
            implementation = _test_aspect_impl,
            attr_aspects = ["deps"],
            attrs = {
                "_test_attr": attr.label(
                    allow_files = True,
                    default = Label("//donut:test_aspect_filegroup"),
                ),
            },
            provides = [TestAspectInfo],
        )

        def _test_aspect_on_aspect_impl(target, ctx):
            return [
                TestAspectOnAspectInfo(
                    info = depset(
                        direct = [target.label],
                        transitive = [target[TestAspectInfo].info],
                    ),
                ),
            ]

        _test_aspect_on_aspect = aspect(
            implementation = _test_aspect_on_aspect_impl,
            attr_aspects = ["deps"],
            attrs = {
                "_test_attr": attr.label(
                    allow_files = True,
                    default = Label("//donut:test_aspect_on_aspect_filegroup"),
                ),
            },
            required_aspect_providers = [TestAspectInfo],
            provides = [TestAspectOnAspectInfo],
        )

        def _test_impl(ctx):
            pass

        test_rule = rule(
            _test_impl,
            attrs = {
                "deps": attr.label_list(
                    aspects = [_test_aspect],
                ),
            },
        )

        def _test_aspect_on_aspect_rule_impl(ctx):
            pass

        test_aspect_on_aspect_rule = rule(
            _test_aspect_on_aspect_rule_impl,
            attrs = {
                "deps": attr.label_list(
                    aspects = [_test_aspect, _test_aspect_on_aspect],
                ),
            },
        )
        """);
    writeFile("donut/test_aspect.file");
    writeFile("donut/test_aspect_on_aspect.file");
    writeFile(
        "donut/BUILD",
        """
        load(":test.bzl", "test_aspect_on_aspect_rule", "test_rule")

        filegroup(
            name = "test_aspect_filegroup",
            srcs = ["test_aspect.file"],
        )

        filegroup(
            name = "test_aspect_on_aspect_filegroup",
            srcs = ["test_aspect_on_aspect.file"],
        )

        test_rule(
            name = "test_rule_dep",
        )

        test_rule(
            name = "test_rule",
            deps = [":test_rule_dep"],
        )

        test_aspect_on_aspect_rule(
            name = "test_aspect_on_aspect_rule",
            deps = ["test_rule"],
        )
        """);

    helper.setUniverseScope("//donut/...");
    helper.setQuerySettings(Setting.INCLUDE_ASPECTS, Setting.EXPLICIT_ASPECTS);
    var result =
        eval("filter(//donut, deps(//donut:test_aspect_on_aspect_rule))").stream()
            .map(cf -> cf.getDescription(LabelPrinter.legacy()))
            .collect(toImmutableList());
    assertThat(result)
        .containsExactly(
            "//donut:test.bzl%_test_aspect_on_aspect on top of"
                + " [//donut:test.bzl%_test_aspect of //donut:test_rule_dep]",
            "//donut:test.bzl%_test_aspect_on_aspect on top of"
                + " [//donut:test.bzl%_test_aspect of //donut:test_rule]",
            "//donut:test_rule_dep",
            "//donut:test_rule",
            "//donut:test.bzl%_test_aspect of //donut:test_rule_dep",
            "//donut:test.bzl%_test_aspect of //donut:test_rule",
            "//donut:test_aspect_on_aspect_rule",
            "//donut:test_aspect.file",
            "//donut:test_aspect_on_aspect_filegroup",
            "//donut:test_aspect_on_aspect.file",
            "//donut:test_aspect_filegroup");
  }

  @Test
  public void testAspectDepsAppearInCqueryRdeps() throws Exception {
    writeFile(
        "donut/test.bzl",
        """
        TestAspectInfo = provider("TestAspectInfo", fields = ["info"])

        def _test_aspect_impl(target, ctx):
            return [
                TestAspectInfo(
                    info = depset([target.label]),
                ),
            ]

        _test_aspect = aspect(
            implementation = _test_aspect_impl,
            attr_aspects = ["deps"],
            attrs = {
                "_test_attr": attr.label(
                    allow_files = True,
                    default = Label("//donut:test_filegroup"),
                ),
            },
            provides = [TestAspectInfo],
        )

        def _test_impl(ctx):
            pass

        test_rule = rule(
            _test_impl,
            attrs = {
                "deps": attr.label_list(
                    aspects = [_test_aspect],
                ),
            },
        )
        """);
    writeFile(
        "donut/BUILD",
        """
        load(":test.bzl", "test_rule")

        filegroup(
            name = "test_filegroup",
            srcs = ["test.bzl"],
        )

        test_rule(
            name = "test_rule_dep",
        )

        test_rule(
            name = "test_rule",
            deps = [":test_rule_dep"],
        )
        """);

    helper.setQuerySettings(Setting.INCLUDE_ASPECTS, Setting.EXPLICIT_ASPECTS);
    var result =
        eval("rdeps(//donut/..., //donut:test_filegroup)").stream()
            .map(cf -> cf.getDescription(LabelPrinter.legacy()))
            .collect(toImmutableList());
    assertThat(result)
        .containsExactly(
            "//donut:test_filegroup",
            "//donut:test_rule",
            "//donut:test.bzl%_test_aspect of //donut:test_rule_dep");
  }

  @Test
  public void testAttrRespectsConfiguration() throws Exception {
    MockRule ruleWithList =
        () -> MockRule.define("rule_with_list", attr("string_values", STRING_LIST));

    helper.useRuleClassProvider(setRuleClassProviders(ruleWithList).build());

    writeFile(
        "test/BUILD",
        """
        load(":flag.bzl", "bool_flag")
        bool_flag(
            name = "enable",
            build_setting_default = False,
        )
        """);
    writeFile(
        "configurable/BUILD",
        """
        config_setting(
            name = "enabled",
            define_values = {"test_enable": "true"})
        rule_with_list(
            name = 'target',
            string_values = select({
                ':enabled': ['foo', 'bar'],
                '//conditions:default': ['quux'],
            }),
        )
        """);

    // Using default configuration, 'quux' is the only value in the attribute.
    assertThat(evalToString("attr(string_values, 'foo', '//configurable:target')")).isEmpty();
    assertThat(evalToString("attr(string_values, 'bar', '//configurable:target')")).isEmpty();
    assertThat(evalToString("attr(string_values, 'quux', '//configurable:target')"))
        .isEqualTo("//configurable:target");

    // When the flag is enabled, 'foo' and 'bar' are present, but not 'quux'
    ((PostAnalysisQueryHelper<CqueryNode>) helper).useConfiguration("--define=test_enable=true");
    assertThat(evalToString("attr(string_values, 'foo', '//configurable:target')"))
        .isEqualTo("//configurable:target");
    assertThat(evalToString("attr(string_values, 'bar', '//configurable:target')"))
        .isEqualTo("//configurable:target");
    assertThat(evalToString("attr(string_values, 'quux', '//configurable:target')")).isEmpty();
  }
}
