// 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.rules.cpp;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.baseArtifactNames;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.prettyArtifactNames;
import static org.junit.Assert.assertThrows;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.AnalysisTestUtil;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.packages.StarlarkInfo;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StarlarkProviderIdentifier;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.packages.util.Crosstool.CcToolchainConfig;
import com.google.devtools.build.lib.packages.util.MockCcSupport;
import com.google.devtools.build.lib.packages.util.ResourceLoader;
import com.google.devtools.build.lib.rules.cpp.CcLinkingContext.Linkstamp;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ActionConfig;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ArtifactNamePattern;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.EnvEntry;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.EnvSet;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Feature;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Flag.SingleChunkFlag;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FlagGroup;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FlagSet;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Tool;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.VariableWithValue;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.WithFeatureSet;
import com.google.devtools.build.lib.rules.cpp.CcToolchainVariables.StringValueParser;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.MakeVariable;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath;
import com.google.protobuf.TextFormat;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for the {@code cc_common} Starlark module. */
@RunWith(JUnit4.class)
public class StarlarkCcCommonTest extends BuildViewTestCase {

  @Before
  public void setUp() throws Exception {
    scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()");

    scratch.file("myinfo/BUILD");
  }

  private static StructImpl getMyInfoFromTarget(ConfiguredTarget configuredTarget)
      throws LabelSyntaxException {
    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//myinfo:myinfo.bzl", ImmutableMap.of()), "MyInfo");
    return (StructImpl) configuredTarget.get(key);
  }

  private static Iterable<Artifact> getArtifactsFromMyInfo(ConfiguredTarget target, String field)
      throws Exception {
    StructImpl myInfo = getMyInfoFromTarget(target);
    @SuppressWarnings("unchecked")
    Iterable<Artifact> artifacts = (Iterable<Artifact>) myInfo.getValue(field);
    return artifacts;
  }

  @Test
  public void testAllFiles() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  return [MyInfo(all_files = toolchain.all_files)]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    Depset allFiles = (Depset) getMyInfoFromTarget(r).getValue("all_files");
    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    assertThat(allFiles.getSet(Artifact.class)).isEqualTo(toolchain.getAllFiles());
  }

  @Test
  public void testRuntimeLib() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "CruleInfo = provider(fields=['static', 'dynamic'])",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [CruleInfo(",
        "    static = toolchain.static_runtime_lib(feature_configuration = feature_configuration),",
        "    dynamic = toolchain.dynamic_runtime_lib(",
        "      feature_configuration = feature_configuration),",
        "  )]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    // 1. Build without static_link_cpp_runtimes
    ConfiguredTarget r = getConfiguredTarget("//a:r");
    Provider.Key key =
        new StarlarkProvider.Key(
            Label.create(r.getLabel().getPackageIdentifier(), "rule.bzl"), "CruleInfo");
    StarlarkInfo cruleInfo = (StarlarkInfo) r.get(key);
    Depset staticRuntimeLib = (Depset) cruleInfo.getValue("static");
    Depset dynamicRuntimeLib = (Depset) cruleInfo.getValue("dynamic");

    assertThat(staticRuntimeLib.getSet(Artifact.class).toList()).isEmpty();
    assertThat(dynamicRuntimeLib.getSet(Artifact.class).toList()).isEmpty();

    // 2. Build with static_link_cpp_runtimes
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES));
    invalidatePackages();
    r = getConfiguredTarget("//a:r");
    cruleInfo = (StarlarkInfo) r.get(key);
    staticRuntimeLib = (Depset) cruleInfo.getValue("static");
    dynamicRuntimeLib = (Depset) cruleInfo.getValue("dynamic");

    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    assertThat(staticRuntimeLib.getSet(Artifact.class))
        .isEqualTo(toolchain.getStaticRuntimeLibForTesting());
    assertThat(dynamicRuntimeLib.getSet(Artifact.class))
        .isEqualTo(toolchain.getDynamicRuntimeLibForTesting());
  }

  @Test
  public void testGetValuesFromCcToolchain() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  return [MyInfo(",
        "    dynamic_runtime_solib_dir = toolchain.dynamic_runtime_solib_dir,",
        "    toolchain_id = toolchain.toolchain_id,",
        "  )]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    StructImpl info = getMyInfoFromTarget(r);
    String dynamicRuntimeSolibDir = (String) info.getValue("dynamic_runtime_solib_dir");
    String toolchainId = (String) info.getValue("toolchain_id");

    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));

    assertThat(dynamicRuntimeSolibDir).isEqualTo(toolchain.getDynamicRuntimeSolibDirForStarlark());
    assertThat(toolchainId).isEqualTo(toolchain.getToolchainIdentifier());
  }

  @Test
  public void testGetToolForAction() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    action_tool_path = cc_common.get_tool_for_action(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'c++-compile'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    String actionToolPath = (String) getMyInfoFromTarget(r).getValue("action_tool_path");
    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    FeatureConfiguration featureConfiguration =
        CcCommon.configureFeaturesOrThrowEvalException(
            ImmutableSet.of(),
            ImmutableSet.of(),
            toolchain,
            ruleContext.getFragment(CppConfiguration.class));
    assertThat(actionToolPath)
        .isEqualTo(featureConfiguration.getToolPathForAction(CppActionNames.CPP_COMPILE));
  }

  @Test
  public void testExecutionRequirements() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(MockCcSupport.CPP_COMPILE_ACTION_WITH_REQUIREMENTS));
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    requirements = cc_common.get_execution_requirements(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'yolo_action_with_requirements'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    @SuppressWarnings("unchecked")
    Sequence<String> requirements =
        (Sequence<String>) getMyInfoFromTarget(r).getValue("requirements");
    assertThat(requirements).containsExactly("requires-yolo");
  }

  @Test
  public void testFeatureConfigurationWithAdditionalEnabledFeature() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("foo_feature"));
    useConfiguration();
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "      requested_features = ['foo_feature'])",
        "  return [MyInfo(",
        "    foo_feature_enabled = cc_common.is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        feature_name = 'foo_feature'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    boolean fooFeatureEnabled = (boolean) getMyInfoFromTarget(r).getValue("foo_feature_enabled");
    assertThat(fooFeatureEnabled).isTrue();
  }

  @Test
  public void testFeatureConfigurationWithAdditionalUnsupportedFeature() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("foo_feature"));
    useConfiguration("--features=foo_feature");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "      unsupported_features = ['foo_feature'])",
        "  return [MyInfo(",
        "    foo_feature_enabled = cc_common.is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        feature_name = 'foo_feature'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    boolean fooFeatureEnabled = (boolean) getMyInfoFromTarget(r).getValue("foo_feature_enabled");
    assertThat(fooFeatureEnabled).isFalse();
  }

  @Test
  public void testGetCommandLine() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    command_line = cc_common.get_memory_inefficient_command_line(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'c++-link-executable',",
        "        variables = cc_common.empty_variables()))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    @SuppressWarnings("unchecked")
    Sequence<String> commandLine =
        (Sequence<String>) getMyInfoFromTarget(r).getValue("command_line");
    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    FeatureConfiguration featureConfiguration =
        CcCommon.configureFeaturesOrThrowEvalException(
            ImmutableSet.of(),
            ImmutableSet.of(),
            toolchain,
            ruleContext.getFragment(CppConfiguration.class));
    assertThat(commandLine)
        .containsExactlyElementsIn(
            featureConfiguration.getCommandLine("c++-link-executable", CcToolchainVariables.EMPTY));
  }

  @Test
  public void testGetEnvironment() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    environment_variables = cc_common.get_environment_variables(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'c++-compile',",
        "        variables = cc_common.empty_variables()))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    @SuppressWarnings("unchecked")
    Map<String, String> environmentVariables =
        (Map<String, String>) getMyInfoFromTarget(r).getValue("environment_variables");
    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    FeatureConfiguration featureConfiguration =
        CcCommon.configureFeaturesOrThrowEvalException(
            ImmutableSet.of(),
            ImmutableSet.of(),
            toolchain,
            ruleContext.getFragment(CppConfiguration.class));
    assertThat(environmentVariables)
        .containsExactlyEntriesIn(
            featureConfiguration.getEnvironmentVariables(
                CppActionNames.CPP_COMPILE, CcToolchainVariables.EMPTY));
  }

  @Test
  public void testActionIsEnabled() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    enabled_action = cc_common.action_is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'c-compile'),",
        "    disabled_action = cc_common.action_is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'wololoo'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    StructImpl myInfo = getMyInfoFromTarget(getConfiguredTarget("//a:r"));
    boolean enabledActionIsEnabled = (boolean) myInfo.getValue("enabled_action");
    boolean disabledActionIsDisabled = (boolean) myInfo.getValue("disabled_action");
    assertThat(enabledActionIsEnabled).isTrue();
    assertThat(disabledActionIsDisabled).isFalse();
  }

  @Test
  public void testIsEnabled() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    enabled_feature = cc_common.is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        feature_name = 'libraries_to_link'),",
        "    disabled_feature = cc_common.is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        feature_name = 'wololoo'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    StructImpl myInfo = getMyInfoFromTarget(getConfiguredTarget("//a:r"));

    boolean enabledFeatureIsEnabled = (boolean) myInfo.getValue("enabled_feature");
    boolean disabledFeatureIsDisabled = (boolean) myInfo.getValue("disabled_feature");
    assertThat(enabledFeatureIsEnabled).isTrue();
    assertThat(disabledFeatureIsDisabled).isFalse();
  }

  @Test
  public void testFeatureConfigurationRequiresCtx() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(cc_toolchain = toolchain)",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");
    useConfiguration("--incompatible_require_ctx_in_configure_features");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//a:r");
    assertContainsEvent("mandatory parameter 'ctx' of cc_common.configure_features is missing");
  }

  @Test
  public void testActionNames() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");
    scratch.overwriteFile("tools/build_defs/cc/BUILD");
    scratch.overwriteFile(
        "tools/build_defs/cc/action_names.bzl",
        ResourceLoader.readFromResources(
            TestConstants.RULES_CC_REPOSITORY_EXECROOT + "cc/action_names.bzl"));

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "load('//tools/build_defs/cc:action_names.bzl',",
        "    'C_COMPILE_ACTION_NAME',",
        "    'CPP_COMPILE_ACTION_NAME',",
        "    'LINKSTAMP_COMPILE_ACTION_NAME',",
        "    'CC_FLAGS_MAKE_VARIABLE_ACTION_NAME',",
        "    'CPP_MODULE_CODEGEN_ACTION_NAME',",
        "    'CPP_HEADER_PARSING_ACTION_NAME',",
        "    'CPP_MODULE_COMPILE_ACTION_NAME',",
        "    'ASSEMBLE_ACTION_NAME',",
        "    'PREPROCESS_ASSEMBLE_ACTION_NAME',",
        "    'LTO_INDEXING_ACTION_NAME',",
        "    'LTO_BACKEND_ACTION_NAME',",
        "    'CPP_LINK_EXECUTABLE_ACTION_NAME',",
        "    'CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME',",
        "    'CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME',",
        "    'CPP_LINK_STATIC_LIBRARY_ACTION_NAME',",
        "    'STRIP_ACTION_NAME')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "      c_compile_action_name=C_COMPILE_ACTION_NAME,",
        "      cpp_compile_action_name=CPP_COMPILE_ACTION_NAME,",
        "      linkstamp_compile_action_name=LINKSTAMP_COMPILE_ACTION_NAME,",
        "      cc_flags_make_variable_action_name_action_name=CC_FLAGS_MAKE_VARIABLE_ACTION_NAME,",
        "      cpp_module_codegen_action_name=CPP_MODULE_CODEGEN_ACTION_NAME,",
        "      cpp_header_parsing_action_name=CPP_HEADER_PARSING_ACTION_NAME,",
        "      cpp_module_compile_action_name=CPP_MODULE_COMPILE_ACTION_NAME,",
        "      assemble_action_name=ASSEMBLE_ACTION_NAME,",
        "      preprocess_assemble_action_name=PREPROCESS_ASSEMBLE_ACTION_NAME,",
        "      lto_indexing_action_name=LTO_INDEXING_ACTION_NAME,",
        "      lto_backend_action_name=LTO_BACKEND_ACTION_NAME,",
        "      cpp_link_executable_action_name=CPP_LINK_EXECUTABLE_ACTION_NAME,",
        "      cpp_link_dynamic_library_action_name=CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME,",
        "     "
            + " cpp_link_nodeps_dynamic_library_action_name=CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME,",
        "      cpp_link_static_library_action_name=CPP_LINK_STATIC_LIBRARY_ACTION_NAME,",
        "      strip_action_name=STRIP_ACTION_NAME)]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ")");

    assertThat(getTarget("//a:r")).isNotNull();

    StructImpl myInfo = getMyInfoFromTarget(getConfiguredTarget("//a:r"));

    assertThat(myInfo.getValue("c_compile_action_name")).isEqualTo(CppActionNames.C_COMPILE);
    assertThat(myInfo.getValue("cpp_compile_action_name")).isEqualTo(CppActionNames.CPP_COMPILE);
    assertThat(myInfo.getValue("linkstamp_compile_action_name"))
        .isEqualTo(CppActionNames.LINKSTAMP_COMPILE);
    assertThat(myInfo.getValue("cc_flags_make_variable_action_name_action_name"))
        .isEqualTo(CppActionNames.CC_FLAGS_MAKE_VARIABLE);
    assertThat(myInfo.getValue("cpp_module_codegen_action_name"))
        .isEqualTo(CppActionNames.CPP_MODULE_CODEGEN);
    assertThat(myInfo.getValue("cpp_header_parsing_action_name"))
        .isEqualTo(CppActionNames.CPP_HEADER_PARSING);
    assertThat(myInfo.getValue("cpp_module_compile_action_name"))
        .isEqualTo(CppActionNames.CPP_MODULE_COMPILE);
    assertThat(myInfo.getValue("assemble_action_name")).isEqualTo(CppActionNames.ASSEMBLE);
    assertThat(myInfo.getValue("preprocess_assemble_action_name"))
        .isEqualTo(CppActionNames.PREPROCESS_ASSEMBLE);
    assertThat(myInfo.getValue("lto_indexing_action_name")).isEqualTo(CppActionNames.LTO_INDEXING);
    assertThat(myInfo.getValue("lto_backend_action_name")).isEqualTo(CppActionNames.LTO_BACKEND);
    assertThat(myInfo.getValue("cpp_link_executable_action_name"))
        .isEqualTo(CppActionNames.CPP_LINK_EXECUTABLE);
    assertThat(myInfo.getValue("cpp_link_dynamic_library_action_name"))
        .isEqualTo(CppActionNames.CPP_LINK_DYNAMIC_LIBRARY);
    assertThat(myInfo.getValue("cpp_link_nodeps_dynamic_library_action_name"))
        .isEqualTo(CppActionNames.CPP_LINK_NODEPS_DYNAMIC_LIBRARY);
    assertThat(myInfo.getValue("cpp_link_static_library_action_name"))
        .isEqualTo(CppActionNames.CPP_LINK_STATIC_LIBRARY);
    assertThat(myInfo.getValue("strip_action_name")).isEqualTo(CppActionNames.STRIP);
  }

  @Test
  public void testCompileBuildVariablesWithSourceFile() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "source_file = 'foo/bar/hello'",
                ")"))
        .containsAtLeast("-c", "foo/bar/hello")
        .inOrder();
  }

  @Test
  public void testCompileBuildVariablesWithOutputFile() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "output_file = 'foo/bar/hello.o'",
                ")"))
        .containsAtLeast("-o", "foo/bar/hello.o")
        .inOrder();
  }

  @Test
  public void testCompileBuildVariablesForIncludes() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "include_directories = depset(['foo/bar/include'])",
                ")"))
        .contains("-Ifoo/bar/include");
  }

  @Test
  public void testCompileBuildVariablesForFrameworkIncludes() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "framework_include_directories = depset(['foo/bar'])",
                ")"))
        .contains("-Ffoo/bar");
  }

  @Test
  public void testCompileBuildVariablesForDefines() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "preprocessor_defines = depset(['DEBUG_FOO'])",
                ")"))
        .contains("-DDEBUG_FOO");
  }

  @Test
  public void testCompileBuildVariablesForPic() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "use_pic = True",
                ")"))
        .contains("-fPIC");
  }

  @Test
  public void testUserCompileFlags() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "user_compile_flags = ['-foo']",
                ")"))
        .contains("-foo");
  }

  @Test
  public void testCompileBuildVariablesForDummyLtoBackendAction() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures(CppRuleClasses.THIN_LTO));
    useConfiguration("--features=thin_lto");
    Sequence<String> commandLine =
        commandLineForVariables(
            CppActionNames.LTO_BACKEND,
            "cc_common.create_compile_variables(",
            "feature_configuration = feature_configuration,",
            "cc_toolchain = toolchain,",
            "thinlto_input_bitcode_file = 'path/to/input',",
            "thinlto_output_object_file = 'path/to/output',",
            "thinlto_index = '/dev/null'",
            ")");

    assertThat(commandLine)
        .containsAtLeast(
            "thinlto_index=/dev/null",
            "thinlto_output_object_file=path/to/output",
            "thinlto_input_bitcode_file=path/to/input");
  }

  @Test
  public void testCompileBuildVariablesWithVariablesExtension() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures("check_additional_variables_feature"));
    useConfiguration("--features=check_additional_variables_feature");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "    feature_configuration = feature_configuration,",
                "    cc_toolchain = toolchain,",
                "    variables_extension = {",
                "        'string_variable': 'foo',",
                "        'list_variable': ['bar', 'baz']",
                "    }",
                ")"))
        .containsAtLeast("--my_string=foo", "--my_list_element=bar", "--my_list_element=baz");
  }

  @Test
  public void testEmptyLinkVariables() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "user_link_flags = [ '-foo' ],",
                ")"))
        .contains("-foo");
  }

  @Test
  public void testEmptyLinkVariablesContainSysroot() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withSysroot("/foo/bar/sysroot"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                ")"))
        .contains("--sysroot=/foo/bar/sysroot");
  }

  @Test
  public void testLibrarySearchDirectoriesLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures("library_search_directories"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "library_search_directories = depset([ 'a', 'b', 'c' ]),",
                ")"))
        .containsAtLeast("--library=a", "--library=b", "--library=c")
        .inOrder();
  }

  @Test
  public void testRuntimeLibrarySearchDirectoriesLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures("runtime_library_search_directories"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "runtime_library_search_directories = depset([ 'a', 'b', 'c' ]),",
                ")"))
        .containsAtLeast("--runtime_library=a", "--runtime_library=b", "--runtime_library=c")
        .inOrder();
  }

  @Test
  public void testUserLinkFlagsLinkVariables() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "user_link_flags = [ '-avocado' ],",
                ")"))
        .contains("-avocado");
  }

  @Test
  public void testIfsoRelatedVariablesAreNotExposed() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("uses_ifso_variables"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_DYNAMIC_LIBRARY,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                ")"))
        .doesNotContain("--generate_interface_library_was_available");
  }

  @Test
  public void testOutputFileLinkVariables() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "output_file = 'foo/bar/executable',",
                ")"))
        .contains("foo/bar/executable");
  }

  @Test
  public void testParamFileLinkVariables() throws Exception {
    AnalysisMock.get().ccSupport().setupCcToolchainConfig(mockToolsConfig);
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "param_file = 'foo/bar/params',",
                ")"))
        .contains("@foo/bar/params");
  }

  @Test
  public void testDefFileLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(mockToolsConfig, CcToolchainConfig.builder().withFeatures("def"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "def_file = 'foo/bar/def',",
                ")"))
        .contains("-qux_foo/bar/def");
  }

  @Test
  public void testMustKeepDebugLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("strip_debug_symbols"));

    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                0,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "must_keep_debug = False,",
                ")"))
        .contains("-strip_stuff");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                1,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "must_keep_debug = True,",
                ")"))
        .doesNotContain("-strip_stuff");
  }

  @Test
  public void testIsLinkingDynamicLibraryLinkVariables() throws Exception {
    useConfiguration("--linkopt=-pie");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                0,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "is_linking_dynamic_library = True,",
                "user_link_flags = [ '-pie' ],",
                ")"))
        .doesNotContain("-pie");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                1,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "is_linking_dynamic_library = False,",
                "user_link_flags = [ '-pie' ],",
                ")"))
        .contains("-pie");
  }

  @Test
  public void testIsUsingLinkerLinkVariables() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                0,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "is_using_linker = True,",
                "user_link_flags = [ '-i_dont_want_to_see_this_on_archiver_command_line' ],",
                ")"))
        .contains("-i_dont_want_to_see_this_on_archiver_command_line");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                1,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "is_using_linker = False,",
                "user_link_flags = [ '-i_dont_want_to_see_this_on_archiver_command_line' ],",
                ")"))
        .doesNotContain("-i_dont_want_to_see_this_on_archiver_command_line");
  }

  private Sequence<String> commandLineForVariables(String actionName, String... variables)
      throws Exception {
    return commandLineForVariables(actionName, 0, variables);
  }

  // This method is only there to change the package to fix multiple runs of this method in a single
  // test.
  // TODO(b/109917616): Remove pkgSuffix argument when bzl files are not cached within single test
  private Sequence<String> commandLineForVariables(
      String actionName, int pkgSuffix, String... variables) throws Exception {
    scratch.file(
        "a" + pkgSuffix + "/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a" + pkgSuffix + "/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "    requested_features = ctx.features,",
        "  )",
        "  variables = " + Joiner.on("\n").join(variables),
        "  return [MyInfo(",
        "    command_line = cc_common.get_memory_inefficient_command_line(",
        "        feature_configuration = feature_configuration,",
        "        action_name = '" + actionName + "',",
        "        variables = variables))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a" + pkgSuffix + ":alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    /** Calling {@link #getTarget} to get loading errors */
    getTarget("//a" + pkgSuffix + ":r");
    ConfiguredTarget r = getConfiguredTarget("//a" + pkgSuffix + ":r");
    if (r == null) {
      return null;
    }
    @SuppressWarnings("unchecked")
    Sequence<String> result = (Sequence<String>) getMyInfoFromTarget(r).getValue("command_line");
    return result;
  }

  @Test
  public void testCcCompilationProvider() throws Exception {
    scratch.file(
        "a/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "licenses(['notice'])",
        "cc_library(",
        "    name='lib',",
        "    hdrs = ['lib.h'],",
        "    srcs = ['lib.cc'],",
        "    deps = ['r']",
        ")",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = ['dep1.cc'],",
        "    hdrs = ['dep1.h'],",
        "    includes = ['dep1/baz'],",
        "    defines = ['DEP1'],",
        "    local_defines = ['LOCALDEP1'],",
        ")",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = ['dep2.cc'],",
        "    hdrs = ['dep2.h'],",
        "    includes = ['dep2/qux'],",
        "    defines = ['DEP2'],",
        ")",
        "crule(name='r')");
    scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
    scratch.file(
        "tools/build_defs/cc/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  compilation_context = cc_common.create_compilation_context(",
        "    headers=depset([ctx.file._header]),",
        "    direct_textual_headers=[ctx.file._textual_header],",
        "    direct_public_headers=[ctx.file._public_header],",
        "    direct_private_headers=[ctx.file._private_header],",
        "    system_includes=depset([ctx.attr._system_include]),",
        "    includes=depset([ctx.attr._include]),",
        "    quote_includes=depset([ctx.attr._quote_include]),",
        "    framework_includes=depset([ctx.attr._framework_include]),",
        "    defines=depset([ctx.attr._define]))",
        "  cc_infos = [CcInfo(compilation_context=compilation_context)]",
        "  for dep in ctx.attr._deps:",
        "      cc_infos.append(dep[CcInfo])",
        "  merged_cc_info=cc_common.merge_cc_infos(cc_infos=cc_infos)",
        "  return [",
        "      merged_cc_info,",
        "      MyInfo(",
        "          merged_headers=merged_cc_info.compilation_context.headers,",
        "          textual_headers=compilation_context.direct_textual_headers,",
        "          public_headers=compilation_context.direct_public_headers,",
        "          private_headers=compilation_context.direct_private_headers,",
        "          merged_system_includes=merged_cc_info.compilation_context.system_includes,",
        "          merged_includes=merged_cc_info.compilation_context.includes,",
        "          merged_quote_includes=merged_cc_info.compilation_context.quote_includes,",
        "         "
            + " merged_framework_includes=merged_cc_info.compilation_context.framework_includes,",
        "          merged_defines=merged_cc_info.compilation_context.defines",
        "      )]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_header': attr.label(allow_single_file=True,",
        "        default=Label('//a:header.h')),",
        "    '_textual_header': attr.label(allow_single_file=True,",
        "        default=Label('//a:textual_header.h')),",
        "    '_public_header': attr.label(allow_single_file=True,",
        "        default=Label('//a:public_header.h')),",
        "    '_private_header': attr.label(allow_single_file=True,",
        "        default=Label('//a:private_header.h')),",
        "    '_system_include': attr.string(default='foo/bar'),",
        "    '_include': attr.string(default='baz/qux'),",
        "    '_quote_include': attr.string(default='quux/abc'),",
        "    '_framework_include': attr.string(default='fuux/fgh'),",
        "    '_define': attr.string(default='MYDEFINE'),",
        "    '_local_define': attr.string(default='MYLOCALDEFINE'),",
        "    '_deps': attr.label_list(default=['//a:dep1', '//a:dep2'])",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget lib = getConfiguredTarget("//a:lib");
    CcCompilationContext ccCompilationContext = lib.get(CcInfo.PROVIDER).getCcCompilationContext();
    assertThat(
            ccCompilationContext.getDeclaredIncludeSrcs().toList().stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("lib.h", "header.h", "dep1.h", "dep2.h");

    StructImpl myInfo = getMyInfoFromTarget(getConfiguredTarget("//a:r"));

    List<Artifact> mergedHeaders =
        ((Depset) myInfo.getValue("merged_headers")).getSet(Artifact.class).toList();
    assertThat(
            mergedHeaders.stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .containsAtLeast("header.h", "dep1.h", "dep2.h");

    @SuppressWarnings("unchecked")
    List<Artifact> textualHeaders =
        ((Sequence<Artifact>) myInfo.getValue("textual_headers")).getImmutableList();
    assertThat(
            textualHeaders.stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .contains("textual_header.h");
    @SuppressWarnings("unchecked")
    List<Artifact> publicHeaders =
        ((Sequence<Artifact>) myInfo.getValue("public_headers")).getImmutableList();
    assertThat(
            publicHeaders.stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .contains("public_header.h");
    @SuppressWarnings("unchecked")
    List<Artifact> privateHeaders =
        ((Sequence<Artifact>) myInfo.getValue("private_headers")).getImmutableList();
    assertThat(
            privateHeaders.stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .contains("private_header.h");

    List<String> mergedDefines =
        ((Depset) myInfo.getValue("merged_defines")).getSet(String.class).toList();
    assertThat(mergedDefines).containsAtLeast("MYDEFINE", "DEP1", "DEP2");
    assertThat(mergedDefines).doesNotContain("LOCALDEP1");

    List<String> mergedSystemIncludes =
        ((Depset) myInfo.getValue("merged_system_includes")).getSet(String.class).toList();
    assertThat(mergedSystemIncludes).containsAtLeast("foo/bar", "a/dep1/baz", "a/dep2/qux");

    List<String> mergedIncludes =
        ((Depset) myInfo.getValue("merged_includes")).getSet(String.class).toList();
    assertThat(mergedIncludes).contains("baz/qux");

    List<String> mergedQuoteIncludes =
        ((Depset) myInfo.getValue("merged_quote_includes")).getSet(String.class).toList();
    assertThat(mergedQuoteIncludes).contains("quux/abc");

    List<String> mergedFrameworkIncludes =
        ((Depset) myInfo.getValue("merged_framework_includes")).getSet(String.class).toList();
    assertThat(mergedFrameworkIncludes).contains("fuux/fgh");
  }

  @Test
  public void testCcCompilationProviderDefaultValues() throws Exception {
    scratch.file(
        "a/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "licenses(['notice'])",
        "crule(name='r')");
    scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
    scratch.file(
        "tools/build_defs/cc/rule.bzl",
        "def _impl(ctx):",
        "  compilation_context = cc_common.create_compilation_context()",
        "crule = rule(",
        "  _impl,",
        "  fragments = ['cpp'],",
        ");");

    assertThat(getConfiguredTarget("//a:r")).isNotNull();
  }

  @Test
  public void testCcCompilationProviderInvalidValues() throws Exception {
    reporter.removeHandler(failFastHandler);
    scratch.file(
        "a/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "licenses(['notice'])",
        "crule(name='r')");
    scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
    scratch.file(
        "tools/build_defs/cc/rule.bzl",
        "def _impl(ctx):",
        "  compilation_context = cc_common.create_compilation_context(headers=[])",
        "crule = rule(",
        "  _impl,",
        "  fragments = ['cpp'],",
        ");");

    getConfiguredTarget("//a:r");
    assertContainsEvent("for headers, got list, want a depset of File");
  }

  @Test
  public void testCreateCompilationOutputs_invalidDepset() throws Exception {
    reporter.removeHandler(failFastHandler);
    scratch.file("test/BUILD", "load(':my_rule.bzl', 'my_rule')", "my_rule(name='x')");
    scratch.file(
        "test/my_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_compilation_outputs(",
        "      objects = depset([1, 2]), pic_objects = depset([1, 2]))",
        "my_rule = rule(",
        "  _impl,",
        ");");

    assertThat(getConfiguredTarget("//test:x")).isNull();
    assertContainsEvent("for 'objects', got a depset of 'int', expected a depset of 'File'");
  }

  @Test
  public void testCreateCompilationOutputs_empty() throws Exception {
    scratch.file("test/BUILD", "load(':my_rule.bzl', 'my_rule')", "my_rule(name='x')");
    scratch.file(
        "test/my_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_compilation_outputs()",
        "my_rule = rule(",
        "  _impl,",
        ");");

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

  @Test
  public void testCcLinkingContextOnWindows() throws Exception {
    if (!AnalysisMock.get().isThisBazel()) {
      return;
    }
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.COPY_DYNAMIC_LIBRARIES_TO_BINARY,
                    CppRuleClasses.TARGETS_WINDOWS,
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    doTestCcLinkingContext(
        ImmutableList.of("a.a", "libdep2.a", "b.rlib", "c.a", "d.a", "libdep1.a"),
        ImmutableList.of("a.pic.a", "b.rlib", "c.pic.a", "e.pic.a"),
        // The suffix of dynamic library is caculated based on repository name and package path
        // to avoid conflicts with dynamic library from other packages.
        ImmutableList.of("a.so", "libdep2_c092dd9ce2.so", "b.so", "e.so", "libdep1_c092dd9ce2.so"));
  }

  @Test
  public void testCcLinkingContext() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.PIC,
                    CppRuleClasses.SUPPORTS_PIC,
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    doTestCcLinkingContext(
        ImmutableList.of("a.a", "b.rlib", "c.a", "d.a"),
        ImmutableList.of("a.pic.a", "libdep2.a", "b.rlib", "c.pic.a", "e.pic.a", "libdep1.a"),
        ImmutableList.of("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so"));
  }

  @Test
  public void testCcLinkingContextForExperimentalCcSharedLibrary() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.PIC,
                    CppRuleClasses.SUPPORTS_PIC,
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    doTestCcLinkingContext(
        ImmutableList.of("a.a", "b.rlib", "c.a", "d.a"),
        ImmutableList.of("a.pic.a", "libdep2.a", "b.rlib", "c.pic.a", "e.pic.a", "libdep1.a"),
        ImmutableList.of("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so"));
  }

  /** TODO(#8118): This test can go away once flag is flipped. */
  @Test
  public void testIncompatibleDepsetForLibrariesToLinkGetter() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.PIC,
                    CppRuleClasses.SUPPORTS_PIC,
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    this.setBuildLanguageOptions("--incompatible_depset_for_libraries_to_link_getter");
    setUpCcLinkingContextTest(false);
    ConfiguredTarget a = getConfiguredTarget("//a:a");
    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));

    Depset librariesToLink = info.getValue("libraries_to_link", Depset.class);
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getStaticLibrary() != null)
                .map(x -> x.getStaticLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("a.a", "b.rlib", "c.a", "d.a");
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getPicStaticLibrary() != null)
                .map(x -> x.getPicStaticLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("a.pic.a", "libdep2.a", "b.rlib", "c.pic.a", "e.pic.a", "libdep1.a");
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getDynamicLibrary() != null)
                .map(x -> x.getDynamicLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so");
  }

  private static String getSolibRelativePath(Artifact library, CcToolchainProvider toolchain) {
    return library.getRootRelativePath().relativeTo(toolchain.getSolibDirectory()).toString();
  }

  @Test
  public void testSolibLinkDefault() throws Exception {
    setUpCcLinkingContextTest(false);
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "cc_binary(name='bin',",
        "   deps = [':a'],",
        ")",
        "crule(name='a',",
        "   dynamic_library = 'a.so',",
        "   interface_library = 'a.ifso',",
        ")");
    ConfiguredTarget a = getConfiguredTarget("//foo:a");
    RuleContext ruleContext = getRuleContext(a);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));
    Depset librariesToLink = info.getValue("libraries_to_link", Depset.class);
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getDynamicLibrary() != null)
                .map(x -> getSolibRelativePath(x.getDynamicLibrary(), toolchain))
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("_U_S_Sfoo_Ca___Ufoo/a.so");
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getInterfaceLibrary() != null)
                .map(x -> getSolibRelativePath(x.getInterfaceLibrary(), toolchain))
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("_U_S_Sfoo_Ca___Ufoo/a.ifso");
  }

  @Test
  public void testSolibLinkCustom() throws Exception {
    setUpCcLinkingContextTest(false);
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "cc_binary(name='bin',",
        "   deps = [':a'],",
        ")",
        "crule(name='a',",
        "   dynamic_library = 'a.so',",
        "   interface_library = 'a.ifso',",
        "   dynamic_library_symlink_path = 'custom/libcustom.so',",
        "   interface_library_symlink_path = 'libcustom.ifso',",
        ")");
    ConfiguredTarget a = getConfiguredTarget("//foo:a");
    RuleContext ruleContext = getRuleContext(a);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));
    Depset librariesToLink = info.getValue("libraries_to_link", Depset.class);
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getDynamicLibrary() != null)
                .map(
                    x ->
                        x.getDynamicLibrary()
                            .getRootRelativePath()
                            .relativeTo(toolchain.getSolibDirectory())
                            .toString())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("custom/libcustom.so");
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getInterfaceLibrary() != null)
                .map(
                    x ->
                        x.getInterfaceLibrary()
                            .getRootRelativePath()
                            .relativeTo(toolchain.getSolibDirectory())
                            .toString())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("libcustom.ifso");
  }

  private void doTestCcLinkingContext(
      List<String> staticLibraryList,
      List<String> picStaticLibraryList,
      List<String> dynamicLibraryList)
      throws Exception {
    useConfiguration("--features=-supports_interface_shared_libraries");
    this.setBuildLanguageOptions("--incompatible_depset_for_libraries_to_link_getter");
    setUpCcLinkingContextTest(false);
    ConfiguredTarget a = getConfiguredTarget("//a:a");

    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));
    @SuppressWarnings("unchecked")
    Sequence<String> userLinkFlags =
        (Sequence<String>) info.getValue("user_link_flags", Sequence.class);
    assertThat(userLinkFlags.getImmutableList())
        .containsExactly("-la", "-lc2", "-DEP2_LINKOPT", "-lc1", "-lc2", "-DEP1_LINKOPT");
    Depset additionalInputs = info.getValue("additional_inputs", Depset.class);
    assertThat(additionalInputs.toList(Artifact.class).stream().map(Artifact::getFilename))
        .containsExactly("b.lds", "d.lds");
    Depset linkstamps = info.getValue("linkstamps", Depset.class);
    assertThat(
            artifactsToStrings(
                linkstamps.toList(Linkstamp.class).stream()
                    .map(Linkstamp::getArtifact)
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("src a/linkstamp.cc");
    Collection<LibraryToLink> librariesToLink =
        info.getValue("libraries_to_link", Depset.class).toList(LibraryToLink.class);
    assertThat(
            librariesToLink.stream()
                .filter(x -> x.getStaticLibrary() != null)
                .map(x -> x.getStaticLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactlyElementsIn(staticLibraryList);
    assertThat(
            librariesToLink.stream()
                .filter(x -> x.getPicStaticLibrary() != null)
                .map(x -> x.getPicStaticLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactlyElementsIn(picStaticLibraryList);
    assertThat(
            librariesToLink.stream()
                .filter(x -> x.getDynamicLibrary() != null)
                .map(x -> x.getDynamicLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactlyElementsIn(dynamicLibraryList);
    assertThat(
            librariesToLink.stream()
                .filter(x -> x.getInterfaceLibrary() != null)
                .map(x -> x.getInterfaceLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("a.ifso");
    Artifact staticLibrary = info.getValue("static_library", Artifact.class);
    assertThat(staticLibrary.getFilename()).isEqualTo("a.a");
    Artifact picStaticLibrary = info.getValue("pic_static_library", Artifact.class);
    assertThat(picStaticLibrary.getFilename()).isEqualTo("a.pic.a");
    Artifact dynamicLibrary = info.getValue("dynamic_library", Artifact.class);
    assertThat(dynamicLibrary.getFilename()).isEqualTo("a.so");
    Artifact interfaceLibrary = info.getValue("interface_library", Artifact.class);
    assertThat(interfaceLibrary.getFilename()).isEqualTo("a.ifso");
    boolean alwayslink = info.getValue("alwayslink", Boolean.class);
    assertThat(alwayslink).isTrue();

    ConfiguredTarget bin = getConfiguredTarget("//a:bin");
    assertThat(bin).isNotNull();
  }

  private void setUpCcLinkingContextTest(boolean enableExperimentalCcImport) throws Exception {
    if (enableExperimentalCcImport) {
      useConfiguration("--experimental_starlark_cc_import");
    }
    scratch.file(
        "a/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "cc_binary(name='bin',",
        "   deps = [':a'],",
        ")",
        "crule(name='a',",
        "   static_library = 'a.a',",
        "   pic_static_library = 'a.pic.a',",
        "   dynamic_library = 'a.so',",
        "   interface_library = 'a.ifso',",
        "   user_link_flags = ['-la', '-lc2'],",
        "   alwayslink = True,",
        "   deps = [':c', ':dep2', ':b'],",
        ")",
        "crule(name='b',",
        "   static_library = 'b.rlib',",
        "   pic_static_library = 'b.rlib',",
        "   dynamic_library = 'b.so',",
        "   deps = [':c', ':d'],",
        "   additional_inputs = ['b.lds'],",
        ")",
        "crule(name='c',",
        "   static_library = 'c.a',",
        "   pic_static_library = 'c.pic.a',",
        "   user_link_flags = ['-lc1', '-lc2'],",
        ")",
        "crule(name='d',",
        "   static_library = 'd.a',",
        "   alwayslink = True,",
        "   deps = [':e'],",
        "   additional_inputs = ['d.lds'],",
        ")",
        "crule(name='e',",
        "   pic_static_library = 'e.pic.a',",
        "   dynamic_library = 'e.so',",
        "   deps = [':dep1'],",
        ")",
        "cc_toolchain_alias(name='alias')",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = ['dep1.cc'],",
        "    linkstamp = 'linkstamp.cc',",
        "    hdrs = ['dep1.h'],",
        "    linkopts = ['-DEP1_LINKOPT'],",
        ")",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = ['dep2.cc'],",
        "    hdrs = ['dep2.h'],",
        "    linkopts = ['-DEP2_LINKOPT'],",
        ")");
    scratch.file("a/lib.a", "");
    scratch.file("a/lib.so", "");
    scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
    scratch.file(
        "tools/build_defs/cc/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "linker_input = cc_common.create_linker_input(",
        "                 owner=Label('//toplevel'),",
        "                 user_link_flags=[['-first_flag'], ['-second_flag']])",
        "top_linking_context_smoke = cc_common.create_linking_context(",
        "   linker_inputs=depset([linker_input]))",
        "def _create(ctx, feature_configuration, static_library, pic_static_library,",
        "  dynamic_library,",
        "  interface_library, dynamic_library_symlink_path, interface_library_symlink_path,",
        "  alwayslink, objects, pic_objects):",
        "  return cc_common.create_library_to_link(",
        "    actions=ctx.actions, feature_configuration=feature_configuration, ",
        "    cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo], ",
        "    static_library=static_library, pic_static_library=pic_static_library,",
        "    dynamic_library=dynamic_library, interface_library=interface_library,",
        "    dynamic_library_symlink_path=dynamic_library_symlink_path,",
        "    interface_library_symlink_path=interface_library_symlink_path,",
        "    alwayslink=alwayslink, ",
        enableExperimentalCcImport ? "    objects=objects, " : "",
        enableExperimentalCcImport ? "    pic_objects=pic_objects" : "",
        "    )",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  library_to_link = _create(ctx, feature_configuration, ctx.file.static_library, ",
        "     ctx.file.pic_static_library, ctx.file.dynamic_library, ctx.file.interface_library,",
        "     ctx.attr.dynamic_library_symlink_path,",
        "     ctx.attr.interface_library_symlink_path,",
        "     ctx.attr.alwayslink, ctx.files.objects, ctx.files.pic_objects)",
        "  linker_input = cc_common.create_linker_input(",
        "                   owner=ctx.label,",
        "                   libraries=depset([library_to_link]),",
        "                   user_link_flags=depset(ctx.attr.user_link_flags),",
        "                   additional_inputs=depset(ctx.files.additional_inputs))",
        "  linking_context = cc_common.create_linking_context(",
        "     linker_inputs=depset([linker_input]))",
        "  cc_infos = [CcInfo(linking_context=linking_context)]",
        "  for dep in ctx.attr.deps:",
        "      cc_infos.append(dep[CcInfo])",
        "  merged_cc_info = cc_common.merge_cc_infos(cc_infos=cc_infos)",
        "  merged_libraries = []",
        "  merged_additional_inputs = []",
        "  merged_user_link_flags = []",
        "  merged_linkstamps = []",
        "  for l in merged_cc_info.linking_context.linker_inputs.to_list():",
        "      merged_libraries.extend(l.libraries)",
        "      merged_additional_inputs.extend(l.additional_inputs)",
        "      merged_user_link_flags.extend(l.user_link_flags)",
        "      merged_linkstamps.extend(l.linkstamps)",
        "  linkstamps_linker_input = cc_common.create_linker_input(",
        "                   owner=ctx.label,",
        "                   linkstamps=depset(merged_linkstamps))",
        "  return [",
        "     MyInfo(",
        "         info = struct(",
        "             cc_info = merged_cc_info,",
        "             user_link_flags = merged_user_link_flags,",
        "             additional_inputs = depset(merged_additional_inputs),",
        "             libraries_to_link = depset(merged_libraries),",
        "             linkstamps = depset(linkstamps_linker_input.linkstamps),",
        "             static_library = library_to_link.static_library,",
        "             pic_static_library = library_to_link.pic_static_library,",
        "             dynamic_library = library_to_link.dynamic_library,",
        "             interface_library = library_to_link.interface_library,",
        "             alwayslink = library_to_link.alwayslink,",
        "             objects = library_to_link.objects,",
        "             pic_objects = library_to_link.pic_objects),",
        "      ),",
        "      merged_cc_info]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    'user_link_flags' : attr.string_list(),",
        "    'additional_inputs': attr.label_list(allow_files=True),",
        "    'static_library': attr.label(allow_single_file=True),",
        "    'pic_static_library': attr.label(allow_single_file=True),",
        "    'dynamic_library': attr.label(allow_single_file=True),",
        "    'dynamic_library_symlink_path': attr.string(),",
        "    'interface_library': attr.label(allow_single_file=True),",
        "    'interface_library_symlink_path': attr.string(),",
        "    'objects': attr.label_list(allow_files=True),",
        "    'pic_objects': attr.label_list(allow_files=True),",
        "    'alwayslink': attr.bool(),",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias')),",
        "    'deps': attr.label_list(),",
        "  },",
        "  fragments = ['cpp'],",
        ");");
  }

  private void loadCcToolchainConfigLib() throws IOException {
    scratch.appendFile("tools/cpp/BUILD", "");
    scratch.overwriteFile(
        "tools/cpp/cc_toolchain_config_lib.bzl",
        ResourceLoader.readFromResources(
            TestConstants.RULES_CC_REPOSITORY_EXECROOT + "cc/cc_toolchain_config_lib.bzl"));
  }

  @Test
  public void testVariableWithValue() throws Exception {
    loadCcToolchainConfigLib();
    createVariableWithValueRule("one", /* name= */ "None", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of variable_with_value should be a string, found NoneType");

    createVariableWithValueRule("two", /* name= */ "'abc'", /* value= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of variable_with_value should be a string, found NoneType");

    createVariableWithValueRule("three", /* name= */ "''", /* value= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of variable_with_value must be a nonempty string");

    createVariableWithValueRule("four", /* name= */ "'abc'", /* value= */ "''");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of variable_with_value must be a nonempty string");

    createVariableWithValueRule("five", /* name= */ "'abc'", /* value= */ "'def'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    assertThat(variable).isNotNull();
    VariableWithValue v = CcModule.variableWithValueFromStarlark(variable);
    assertThat(v).isNotNull();
    assertThat(v.variable).isEqualTo("abc");
    assertThat(v.value).isEqualTo("def");

    createEnvEntryRule("six", /* key= */ "'abc'", /* value= */ "'def'");
    t = getConfiguredTarget("//six:a");
    StarlarkInfo envEntry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException ee =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(envEntry));
    assertThat(ee)
        .hasMessageThat()
        .contains("Expected object of type 'variable_with_value', received 'env_entry");
  }

  private void createVariableWithValueRule(String pkg, String name, String value)
      throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'variable_with_value')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(variable = variable_with_value(",
        "       name = " + name + ",",
        "       value = " + value + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomVariableWithValue_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomVariableWithValueRule("one", /* name= */ "None", /* value= */ "None");
    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("'name' parameter of variable_with_value must be a nonempty string.");
  }

  @Test
  public void testCustomVariableWithValue_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomVariableWithValueRule("two", /* name= */ "'abc'", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("'value' parameter of variable_with_value must be a nonempty string.");
  }

  @Test
  public void testCustomVariableWithValue_string_struct() throws Exception {
    loadCcToolchainConfigLib();
    createCustomVariableWithValueRule("three", /* name= */ "'abc'", /* value= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(variable));
    assertThat(e).hasMessageThat().contains("Field 'value' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomVariableWithValue_boolean_string() throws Exception {
    loadCcToolchainConfigLib();
    createCustomVariableWithValueRule("four", /* name= */ "True", /* value= */ "'abc'");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(variable));
    assertThat(e).hasMessageThat().contains("Field 'name' is not of 'java.lang.String' type.");
  }

  private void createCustomVariableWithValueRule(String pkg, String name, String value)
      throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(variable = struct(",
        "       name = " + name + ",",
        "       value = " + value + ",",
        "       type_name = 'variable_with_value'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testEnvEntry_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("one", "None", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("key parameter of env_entry should be a string, found NoneType");
  }

  @Test
  public void testEnvEntry_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("two", "'abc'", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of env_entry should be a string, found NoneType");
  }

  @Test
  public void testEnvEntry_emptyString_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("three", "''", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e).hasMessageThat().contains("key parameter of env_entry must be a nonempty string");
  }

  @Test
  public void testEnvEntry_string_emptyString() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("four", "'abc'", /* value= */ "''");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of env_entry must be a nonempty string");
  }

  @Test
  public void testEnvEntry_string_string() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("five", "'abc'", /* value= */ "'def'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo entryProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    assertThat(entryProvider).isNotNull();
    EnvEntry entry = CcModule.envEntryFromStarlark(entryProvider);
    assertThat(entry).isNotNull();
    StringValueParser parser = new StringValueParser("def");
    assertThat(entry).isEqualTo(new EnvEntry("abc", parser.getChunks()));
  }

  @Test
  public void testEnvEntryVariable_string_string() throws Exception {
    loadCcToolchainConfigLib();
    createVariableWithValueRule("six", /* name= */ "'abc'", /* value= */ "'def'");
    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envEntryFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'env_entry', received 'variable_with_value");
  }

  private void createEnvEntryRule(String pkg, String key, String value) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'env_entry')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(entry = env_entry(",
        "       key = " + key + ",",
        "       value = " + value + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomEnvEntry_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvEntryRule("one", /* key= */ "None", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo entry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException e = assertThrows(EvalException.class, () -> CcModule.envEntryFromStarlark(entry));
    assertThat(e)
        .hasMessageThat()
        .contains("'key' parameter of env_entry must be a nonempty string.");
  }

  @Test
  public void testCustomEnvEntry_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvEntryRule("two", /* key= */ "'abc'", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo entry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException e =
        assertThrows(
            "Should have failed because of empty string.",
            EvalException.class,
            () -> CcModule.envEntryFromStarlark(entry));
    assertThat(e)
        .hasMessageThat()
        .contains("'value' parameter of env_entry must be a nonempty string.");
  }

  @Test
  public void testCustomEnvEntry_string_struct() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvEntryRule("three", /* key= */ "'abc'", /* value= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo entry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException e = assertThrows(EvalException.class, () -> CcModule.envEntryFromStarlark(entry));
    assertThat(e).hasMessageThat().contains("Field 'value' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomEnvEntry_boolean_string() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvEntryRule("four", /* key= */ "True", /* value= */ "'abc'");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo entry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException e = assertThrows(EvalException.class, () -> CcModule.envEntryFromStarlark(entry));
    assertThat(e).hasMessageThat().contains("Field 'key' is not of 'java.lang.String' type.");
  }

  private void createCustomEnvEntryRule(String pkg, String key, String value) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(entry = struct(",
        "       key = " + key + ",",
        "       value = " + value + ",",
        "       type_name = 'env_entry'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testToolPath_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("one", /* name= */ "None", "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of tool_path should be a string, found NoneType");
  }

  @Test
  public void testToolPath_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("two", /* name= */ "'abc'", "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("path parameter of tool_path should be a string, found NoneType");
  }

  @Test
  public void testToolPath_emptyString_none() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("three", /* name= */ "''", "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of tool_path must be a nonempty string");
  }

  @Test
  public void testToolPath_string_emptyString() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("four", /* name= */ "'abc'", "''");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("path parameter of tool_path must be a nonempty string");
  }

  @Test
  public void testToolPath_string_escapedString() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("five", /* name= */ "'abc'", "'/d/e/f'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo toolPathProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    assertThat(toolPathProvider).isNotNull();
    Pair<String, String> toolPath = CcModule.toolPathFromStarlark(toolPathProvider);
    assertThat(toolPath).isNotNull();
    assertThat(toolPath.first).isEqualTo("abc");
    assertThat(toolPath.second).isEqualTo("/d/e/f");
  }

  @Test
  public void testToolPath_string_string() throws Exception {
    loadCcToolchainConfigLib();
    createVariableWithValueRule("six", /* name= */ "'abc'", /* value= */ "'def'");
    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'tool_path', received 'variable_with_value");
  }

  private void createToolPathRule(String pkg, String name, String path) throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'tool_path')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(toolpath = tool_path(",
        "       name = " + name + ",",
        "       path = " + path + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomToolPath_name_mustBeNonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolPathRule("one", /* name= */ "None", /* path= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo toolPath = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(toolPath));
    assertThat(e)
        .hasMessageThat()
        .contains("'name' parameter of tool_path must be a nonempty string.");
  }

  @Test
  public void testCustomToolPath_path_mustBeNonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolPathRule("two", /* name= */ "'abc'", /* path= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo toolPath = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(toolPath));
    assertThat(e)
        .hasMessageThat()
        .contains("'path' parameter of tool_path must be a nonempty string.");
  }

  @Test
  public void testCustomToolPath_path_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolPathRule("three", /* name= */ "'abc'", /* path= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo toolPath = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(toolPath));
    assertThat(e).hasMessageThat().contains("Field 'path' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomToolPath_name_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolPathRule("four", /* name= */ "True", /* path= */ "'abc'");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo toolPath = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(toolPath));
    assertThat(e).hasMessageThat().contains("Field 'name' is not of 'java.lang.String' type.");
  }

  private void createCustomToolPathRule(String pkg, String name, String path) throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'tool_path')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(toolpath = struct(",
        "       name = " + name + ",",
        "       path = " + path + ",",
        "       type_name = 'tool_path'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testMakeVariable() throws Exception {
    loadCcToolchainConfigLib();
    createMakeVariablerule("one", /* name= */ "None", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of make_variable should be a string, found NoneType");

    createMakeVariablerule("two", /* name= */ "'abc'", /* value= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of make_variable should be a string, found NoneType");

    createMakeVariablerule("three", /* name= */ "''", /* value= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of make_variable must be a nonempty string");

    createMakeVariablerule("four", /* name= */ "'abc'", /* value= */ "''");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of make_variable must be a nonempty string");

    createMakeVariablerule("five", /* name= */ "'abc'", /* value= */ "'val'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    assertThat(makeVariableProvider).isNotNull();
    Pair<String, String> makeVariable = CcModule.makeVariableFromStarlark(makeVariableProvider);
    assertThat(makeVariable).isNotNull();
    assertThat(makeVariable.first).isEqualTo("abc");
    assertThat(makeVariable.second).isEqualTo("val");

    createVariableWithValueRule("six", /* name= */ "'abc'", /* value= */ "'def'");
    t = getConfiguredTarget("//six:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException ee =
        assertThrows(EvalException.class, () -> CcModule.makeVariableFromStarlark(variable));
    assertThat(ee)
        .hasMessageThat()
        .contains("Expected object of type 'make_variable', received 'variable_with_value");
  }

  private void createMakeVariablerule(String pkg, String name, String value) throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'make_variable')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(variable = make_variable(",
        "       name = " + name + ",",
        "       value = " + value + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomMakeVariable_none_none() throws Exception {
    createCustomMakeVariableRule("one", /* name= */ "None", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.makeVariableFromStarlark(makeVariableProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("'name' parameter of make_variable must be a nonempty string.");
  }

  @Test
  public void testCustomMakeVariable_string_none() throws Exception {
    createCustomMakeVariableRule("two", /* name= */ "'abc'", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.makeVariableFromStarlark(makeVariableProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("'value' parameter of make_variable must be a nonempty string.");
  }

  @Test
  public void testCustomMakeVariable_list_none() throws Exception {
    createCustomMakeVariableRule("three", /* name= */ "[]", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.makeVariableFromStarlark(makeVariableProvider));
    assertThat(e).hasMessageThat().contains("Field 'name' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomMakeVariable_string_boolean() throws Exception {
    createCustomMakeVariableRule("four", /* name= */ "'abc'", /* value= */ "True");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.makeVariableFromStarlark(makeVariableProvider));
    assertThat(e).hasMessageThat().contains("Field 'value' is not of 'java.lang.String' type.");
  }

  private void createCustomMakeVariableRule(String pkg, String name, String value)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(variable = struct(",
        "       name = " + name + ",",
        "       value = " + value + ",",
        "       type_name = 'make_variable'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testWithFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createWithFeatureSetRule("one", /* features= */ "None", /* notFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("features parameter of with_feature_set should be a list, found NoneType");

    createWithFeatureSetRule("two", /* features= */ "['abc']", /* notFeatures= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("not_features parameter of with_feature_set should be a list, found NoneType");

    createWithFeatureSetRule("three", /* features= */ "'asdf'", /* notFeatures= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("features parameter of with_feature_set should be a list, found string");

    createWithFeatureSetRule("four", /* features= */ "['abc']", /* notFeatures= */ "'def'");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("not_features parameter of with_feature_set should be a list, found string");

    createWithFeatureSetRule(
        "five", /* features= */ "['f1', 'f2']", /* notFeatures= */ "['nf1', 'nf2']");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    WithFeatureSet withFeatureSet = CcModule.withFeatureSetFromStarlark(withFeatureSetProvider);
    assertThat(withFeatureSet).isNotNull();
    assertThat(withFeatureSet.getFeatures()).containsExactly("f1", "f2");
    assertThat(withFeatureSet.getNotFeatures()).containsExactly("nf1", "nf2");

    createVariableWithValueRule("six", /* name= */ "'abc'", /* value= */ "'def'");
    t = getConfiguredTarget("//six:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException ee =
        assertThrows(EvalException.class, () -> CcModule.withFeatureSetFromStarlark(variable));
    assertThat(ee)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'variable_with_value");
  }

  private void createWithFeatureSetRule(String pkg, String features, String notFeatures)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(wfs = with_feature_set(",
        "       features = " + features + ",",
        "       not_features = " + notFeatures + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomWithFeatureSet_struct_none() throws Exception {
    createCustomWithFeatureSetRule("one", /* features= */ "struct()", /* notFeatures= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.withFeatureSetFromStarlark(withFeatureSetProvider));
    assertThat(e).hasMessageThat().contains("for features, got struct, want sequence");
  }

  @Test
  public void testCustomWithFeatureSet_listOfString_struct() throws Exception {
    createCustomWithFeatureSetRule("two", /* features= */ "['abc']", /* notFeatures= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.withFeatureSetFromStarlark(withFeatureSetProvider));
    assertThat(e).hasMessageThat().contains("for not_features, got struct, want sequence");
  }

  @Test
  public void testCustomWithFeatureSet_listOfStruct_emptyList() throws Exception {
    createCustomWithFeatureSetRule("three", /* features= */ "[struct()]", /* notFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.withFeatureSetFromStarlark(withFeatureSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of features, got element of type struct, want string");
  }

  @Test
  public void testCustomWithFeatureSet_emptyList_listOfStruct() throws Exception {
    createCustomWithFeatureSetRule("four", /* features= */ "[]", /* notFeatures= */ "[struct()]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.withFeatureSetFromStarlark(withFeatureSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of not_features, got element of type struct, want string");
  }

  private void createCustomWithFeatureSetRule(String pkg, String features, String notFeatures)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(wfs = struct(",
        "       features = " + features + ",",
        "       not_features = " + notFeatures + ",",
        "       type_name = 'with_feature_set'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testEnvSet_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "one", /* actions= */ "['a1']", /* envEntries= */ "None", /* withFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("env_entries parameter of env_set should be a list, found NoneType");
  }

  @Test
  public void testEnvSet_list_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "two", /* actions= */ "['a1']", /* envEntries= */ "['abc']", /* withFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("with_features parameter of env_set should be a list, found NoneType");
  }

  @Test
  public void testEnvSet_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "three", /* actions= */ "['a1']", /* envEntries= */ "'asdf'", /* withFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("env_entries parameter of env_set should be a list, found string");
  }

  @Test
  public void testEnvSet_list_string() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "four", /* actions= */ "['a1']", /* envEntries= */ "['abc']", /* withFeatures= */ "'def'");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("with_features parameter of env_set should be a list, found string");
  }

  @Test
  public void testEnvSet_envEntry_emptyList() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "five",
        /* actions= */ "['a1']",
        /* envEntries= */ "[env_entry(key = 'a', value = 'b'),"
            + "variable_with_value(name = 'a', value = 'b')]",
        /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'env_entry', received 'variable_with_value'");
  }

  @Test
  public void testEnvSet_emptyList_emptyList() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule("six", /* actions= */ "[]", /* envEntries= */ "[]", /* withFeatures= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//six:a"));
    assertThat(e).hasMessageThat().contains("actions parameter of env_set must be a nonempty list");
  }

  @Test
  public void testEnvSet_envEntry_featureSet() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "seven",
        /* actions= */ "['a1']",
        /* envEntries= */ "[env_entry(key = 'a', value = 'b')]",
        /* withFeatures= */ "[with_feature_set(features = ['a'])]");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EnvSet envSet = CcModule.envSetFromStarlark(envSetProvider);
    assertThat(envSet).isNotNull();
  }

  @Test
  public void testEnvSet_string_string() throws Exception {
    loadCcToolchainConfigLib();
    createVariableWithValueRule("eight", /* name= */ "'abc'", /* value= */ "'def'");
    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'env_set', received 'variable_with_value");
  }

  private void createEnvSetRule(String pkg, String actions, String envEntries, String withFeatures)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(envset = env_set(",
        "       actions = " + actions + ",",
        "       env_entries = " + envEntries + ",",
        "       with_features = " + withFeatures + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomEnvSet_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvSetRule(
        "one", /* actions= */ "[]", /* envEntries= */ "None", /* withFeatures= */ "None");
    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e).hasMessageThat().contains("actions parameter of env_set must be a nonempty list");
  }

  @Test
  public void testCustomEnvSet_struct_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvSetRule(
        "two", /* actions= */ "['a1']", /* envEntries= */ "struct()", /* withFeatures= */ "None");
    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e).hasMessageThat().contains("for env_entries, got struct, want sequence");
  }

  @Test
  public void testCustomEnvSet_structList_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvSetRule(
        "three",
        /* actions= */ "['a1']",
        /* envEntries= */ "[struct()]",
        /* withFeatures= */ "None");
    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'env_entry', received 'struct'");
  }

  @Test
  public void testCustomEnvSet_envEntry_string() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvSetRule(
        "four",
        /* actions= */ "['a1']",
        /* envEntries= */ "[env_entry(key = 'a', value = 'b')]",
        /* withFeatures= */ "'a'");
    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e).hasMessageThat().contains("for with_features, got string, want sequence");
  }

  @Test
  public void testCustomEnvSet_envEntry_envEntry() throws Exception {
    loadCcToolchainConfigLib();

    createCustomEnvSetRule(
        "five",
        /* actions= */ "['a1']",
        /* envEntries= */ "[env_entry(key = 'a', value = 'b')]",
        /* withFeatures= */ "[env_entry(key = 'a', value = 'b')]");
    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'env_entry'.");
  }

  private void createCustomEnvSetRule(
      String pkg, String actions, String envEntries, String withFeatures) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_entry', 'with_feature_set', 'variable_with_value')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(envset = struct(",
        "       actions = " + actions + ",",
        "       env_entries = " + envEntries + ",",
        "       with_features = " + withFeatures + ",",
        "       type_name = 'env_set'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testFlagGroup_flagGroup_notListofFlags() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "one",
        /* flags= */ "[]",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("flag_group must contain either a list of flags or a list of flag_groups");
  }

  @Test
  public void testFlagGroup_iterateOver_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "two",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "struct(val = 'a')",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("iterate_over parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_expandIfTrue_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "three",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "struct(val = 'a')",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("expand_if_true parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_expandIfFalse_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "four",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "struct(val = 'a')",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("expand_if_false parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_expandIfAvailable_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "five",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "struct(val = 'a')",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//five:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("expand_if_available parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_expandIfNotAvailable_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "six",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "struct(val = 'a')",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//six:a"));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "expand_if_not_available parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_flagGroup_cannotContainFlagAndGroup() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "seven",
        /* flags= */ "['a']",
        /* flagGroups= */ "['b']",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "struct(val = 'a')",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//seven:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("flag_group must not contain both a flag and another flag_group");
  }

  @Test
  public void testFlagGroup_expandIfEqual_notStarlarkInfo() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "eight",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "'a'",
        /* expandIfTrue= */ "'b'",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "Field 'expand_if_equal' is not of "
                + "'com.google.devtools.build.lib.packages.StarlarkInfo' type.");
  }

  @Test
  public void testFlagGroup() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "nine",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a']), flag_group(flags = ['b'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//nine:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    FlagGroup f = CcModule.flagGroupFromStarlark(flagGroupProvider);
    assertThat(f).isNotNull();
  }

  @Test
  public void testFlagGroup_flagGroup_notStruct() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "ten",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a']), struct(value = 'a')]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//ten:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'flag_group', received 'struct'");
  }

  private void createFlagGroupRule(
      String pkg,
      String flags,
      String flagGroups,
      String iterateOver,
      String expandIfTrue,
      String expandIfFalse,
      String expandIfAvailable,
      String expandIfNotAvailable,
      String expandIfEqual)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value', 'flag_group')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(flaggroup = flag_group(",
        "       flags = " + flags + ",",
        "       flag_groups = " + flagGroups + ",",
        "       expand_if_true = " + expandIfTrue + ",",
        "       expand_if_false = " + expandIfFalse + ",",
        "       expand_if_available = " + expandIfAvailable + ",",
        "       expand_if_not_available = " + expandIfNotAvailable + ",",
        "       expand_if_equal = " + expandIfEqual + ",",
        "       iterate_over = " + iterateOver + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testSingleChunkFlagIsUsed() throws Exception {
    loadCcToolchainConfigLib();

    createCustomFlagGroupRule(
        "single_chunk_flag",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//single_chunk_flag:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    FlagGroup flagGroup = CcModule.flagGroupFromStarlark(flagGroupProvider);
    assertThat(flagGroup.getExpandables()).isNotEmpty();
    assertThat(flagGroup.getExpandables().get(0)).isInstanceOf(SingleChunkFlag.class);
  }

  @Test
  public void testCustomFlagGroup_iterateOver_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "one",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "struct()",
        /* expandIfTrue= */ "'b'",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'iterate_over' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfTrue_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "two",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a']), flag_group(flags = ['b'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "struct()",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'expand_if_true' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfFalse_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "three",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "True",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'expand_if_false' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfAvailable_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "four",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "struct()",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'expand_if_available' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfNotAvailable_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "five",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "3",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'expand_if_not_available' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfEqual_notStruct() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "six",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "struct(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'variable_with_value', received 'struct'.");
  }

  private void createCustomFlagGroupRule(
      String pkg,
      String flags,
      String flagGroups,
      String iterateOver,
      String expandIfTrue,
      String expandIfFalse,
      String expandIfAvailable,
      String expandIfNotAvailable,
      String expandIfEqual)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value', 'flag_group')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(flaggroup = struct(",
        "       flags = " + flags + ",",
        "       flag_groups = " + flagGroups + ",",
        "       expand_if_true = " + expandIfTrue + ",",
        "       expand_if_false = " + expandIfFalse + ",",
        "       expand_if_available = " + expandIfAvailable + ",",
        "       expand_if_not_available = " + expandIfNotAvailable + ",",
        "       expand_if_equal = " + expandIfEqual + ",",
        "       iterate_over = " + iterateOver + ",",
        "       type_name = 'flag_group'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testTool_path_mustBeNonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule("one", /* path= */ "''", /* withFeatures= */ "[]", /* requirements= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e).hasMessageThat().contains("path parameter of tool must be a nonempty string");
  }

  @Test
  public void testTool_withFeatures_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule("two", /* path= */ "'a'", /* withFeatures= */ "None", /* requirements= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("with_features parameter of tool should be a list, found NoneType");
  }

  @Test
  public void testTool_executionRequirements_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule(
        "three", /* path= */ "'a'", /* withFeatures= */ "[]", /* requirements= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("execution_requirements parameter of tool should be a list, found NoneType");
  }

  @Test
  public void testTool_withFeatures_mustBeWithFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule(
        "four",
        /* path= */ "'a'",
        /* withFeatures= */ "[struct(val = 'a')]",
        /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'struct'");
  }

  @Test
  public void testTool_requirements_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule(
        "five",
        /* path= */ "'a'",
        /* withFeatures= */ "[]",
        /* requirements= */ "[struct(val = 'a')]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of execution_requirements, got element of type struct, want string");
  }

  @Test
  public void testTool() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule(
        "six",
        /* path= */ "'/a/b/c'",
        /* withFeatures= */ "[with_feature_set(features = ['a'])]",
        /* requirements= */ "['a', 'b']");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    Tool tool = CcModule.toolFromStarlark(toolStruct);
    assertThat(tool.getExecutionRequirements()).containsExactly("a", "b");
    assertThat(tool.getToolPathString(PathFragment.EMPTY_FRAGMENT)).isEqualTo("/a/b/c");
    assertThat(tool.getWithFeatureSetSets())
        .contains(new WithFeatureSet(ImmutableSet.of("a"), ImmutableSet.of()));
  }

  private void createToolRule(String pkg, String path, String withFeatures, String requirements)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set', 'tool')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(tool = tool(",
        "       path = " + path + ",",
        "       with_features = " + withFeatures + ",",
        "       execution_requirements = " + requirements + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomTool_path_nonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "one", /* path= */ "''", /* withFeatures= */ "[]", /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e).hasMessageThat().contains("The 'path' field of tool must be a nonempty string.");
  }

  @Test
  public void testCustomTool_path_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "two", /* path= */ "struct()", /* withFeatures= */ "[]", /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e).hasMessageThat().contains("Field 'path' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomTool_withFeatures_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "three", /* path= */ "'a'", /* withFeatures= */ "struct()", /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e).hasMessageThat().contains("for with_features, got struct, want sequence");
  }

  @Test
  public void testCustomTool_withFeatures_mustBeWithFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "four",
        /* path= */ "'a'",
        /* withFeatures= */ "[struct(val = 'a')]",
        /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'struct'");
  }

  @Test
  public void testCustomTool_executionRequirements_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "five", /* path= */ "'a'", /* withFeatures= */ "[]", /* requirements= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("for execution_requirements, got string, want sequence");
  }

  @Test
  public void testCustomTool_executionRequirements_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "six", /* path= */ "'a'", /* withFeatures= */ "[]", /* requirements= */ "[struct()]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of execution_requirements, got element of type struct, want string");
  }

  private void createCustomToolRule(
      String pkg, String path, String withFeatures, String requirements) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(tool = struct(",
        "       path = " + path + ",",
        "       with_features = " + withFeatures + ",",
        "       execution_requirements = " + requirements + ",",
        "       type_name = 'tool'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testFlagSet_withFeatures_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "two", /* actions= */ "['a']", /* flagGroups= */ "[]", /* withFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("with_features parameter of flag_set should be a list, found NoneType");
  }

  @Test
  public void testFlagSet_flagGroups_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "three", /* actions= */ "['a']", /* flagGroups= */ "None", /* withFeatures= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("flag_groups parameter of flag_set should be a list, found NoneType");
  }

  @Test
  public void testFlagSet_actions_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "four",
        /* actions= */ "['a', struct(val = 'a')]",
        /* flagGroups= */ "[]",
        /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ null));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of actions, got element of type struct, want string");
  }

  @Test
  public void testFlagSet_flagGroups_mustBeFlagGroup() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "five",
        /* actions= */ "['a']",
        /* flagGroups= */ "[flag_group(flags = ['a']), struct(value = 'a')]",
        /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ null));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'flag_group', received 'struct'");
  }

  @Test
  public void testFlagSet_withFeatures_mustBeWithFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "six",
        /* actions= */ "['a']",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* withFeatures= */ "[struct(val = 'a')]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ null));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'struct'");
  }

  @Test
  public void testFlagSet() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "seven",
        /* actions= */ "['a']",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* withFeatures= */ "[with_feature_set(features = ['a'])]");
    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    FlagSet f = CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ null);
    assertThat(f).isNotNull();
  }

  @Test
  public void testFlagSet_actionConfig_notActionList() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "eight",
        /* actions= */ "['a']",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* withFeatures= */ "[struct(val = 'a')]");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ "action"));
    assertThat(e)
        .hasMessageThat()
        .contains("Thus, you must not specify action lists in an action_config's flag set.");
  }

  @Test
  public void testFlagSet_emptyAction() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "nine",
        /* actions= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* withFeatures= */ "[with_feature_set(features = ['a'])]");
    ConfiguredTarget t = getConfiguredTarget("//nine:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    FlagSet f = CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ "action");
    assertThat(f).isNotNull();
    assertThat(f.getActions()).containsExactly("action");
  }

  private void createFlagSetRule(String pkg, String actions, String flagGroups, String withFeatures)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value', 'flag_group',",
        "   'flag_set')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(flagset = flag_set(",
        "       flag_groups = " + flagGroups + ",",
        "       actions = " + actions + ",",
        "       with_features = " + withFeatures + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomFlagSet() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagSetRule(
        "one", /* actions= */ "[]", /* flagGroups= */ "[]", /* withFeatures= */ "[]");

    ConfiguredTarget target = getConfiguredTarget("//one:a");
    StarlarkInfo flagSet = (StarlarkInfo) getMyInfoFromTarget(target).getValue("flagset");
    assertThat(flagSet).isNotNull();
    FlagSet flagSetObject = CcModule.flagSetFromStarlark(flagSet, /* actionName */ null);
    assertThat(flagSetObject).isNotNull();
  }

  @Test
  public void testCustomFlagSet_flagGroups_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagSetRule(
        "two", /* actions= */ "['a']", /* flagGroups= */ "struct()", /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName */ null));
    assertThat(e).hasMessageThat().contains("for flag_groups, got struct, want sequence");
  }

  @Test
  public void testCustomFlagSet_withFeatures_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagSetRule(
        "three", /* actions= */ "['a']", /* flagGroups= */ "[]", /* withFeatures= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName */ null));
    assertThat(e).hasMessageThat().contains("for with_features, got struct, want sequence");
  }

  @Test
  public void testCustomFlagSet_actions_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagSetRule(
        "four", /* actions= */ "struct()", /* flagGroups= */ "[]", /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName */ null));
    assertThat(e).hasMessageThat().contains("for actions, got struct, want sequence");
  }

  private void createCustomFlagSetRule(
      String pkg, String actions, String flagGroups, String withFeatures) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value', 'flag_group',",
        "   'flag_set')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(flagset = struct(",
        "       flag_groups = " + flagGroups + ",",
        "       actions = " + actions + ",",
        "       with_features = " + withFeatures + ",",
        "       type_name = 'flag_set'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testActionConfig_actionName_mustBeNonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "one",
        /* actionName= */ "''",
        /* enabled= */ "True",
        /* tools= */ "[]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of action_config must be a nonempty string");
  }

  @Test
  public void testActionConfig_enabled_mustBeBool() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "two",
        /* actionName= */ "'actionname'",
        /* enabled= */ "['asd']",
        /* tools= */ "[]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("enabled parameter of action_config should be a bool, found list");
  }

  @Test
  public void testActionConfig_tools_mustBeTool() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "three",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[with_feature_set(features = ['a'])]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'tool', received 'with_feature_set'");
  }

  @Test
  public void testActionConfig_flagSets_mustBeFlagSet() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "four",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[tool(path = 'a/b/c')]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("Expected object of type 'flag_set', received 'tool'");
  }

  @Test
  public void testActionConfig_implies_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "five",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "flag_set(actions = ['a', 'b'])");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//five:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("implies parameter of action_config should be a list, found struct");
  }

  @Test
  public void testActionConfig_implies_mustContainString() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "six",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "[flag_set(actions = ['a', 'b'])]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of implies, got element of type struct, want string");
  }

  @Test
  public void testActionConfig_implies_mustContainString_notStruct() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "seven",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "[flag_set(actions = ['a', 'b'])]");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of implies, got element of type struct, want string");
  }

  @Test
  public void testActionConfig() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "eight",
        /* actionName= */ "'actionname32._++-'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[flag_set(flag_groups=[flag_group(flags=['a'])])]",
        /* implies= */ "['a', 'b']");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    ActionConfig a = CcModule.actionConfigFromStarlark(actionConfigStruct);
    assertThat(a).isNotNull();
    assertThat(a.getActionName()).isEqualTo("actionname32._++-");
    assertThat(a.getImplies()).containsExactly("a", "b").inOrder();
    assertThat(Iterables.getOnlyElement(a.getFlagSets()).getActions())
        .containsExactly("actionname32._++-");
  }

  @Test
  public void testActionConfig_actionName_validChars_notUpper() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "nine",
        /* actionName= */ "'Upper'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "[flag_set(actions = ['a', 'b'])]");

    ConfiguredTarget t = getConfiguredTarget("//nine:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "An action_config's name must consist solely "
                + "of lowercase ASCII letters, digits, '.', '_', '+', and '-', got 'Upper'");
  }

  @Test
  public void testActionConfig_actionName_validChars_notWhitespace() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "ten",
        /* actionName= */ "'white\tspace'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "[flag_set(actions = ['a', 'b'])]");

    ConfiguredTarget t = getConfiguredTarget("//ten:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "An action_config's name must consist solely "
                + "of lowercase ASCII letters, digits, '.', '_', '+', and '-', "
                + "got 'white\tspace'");
  }

  private void createActionConfigRule(
      String pkg, String actionName, String enabled, String tools, String flagSets, String implies)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set',",
        "             'tool', 'flag_set', 'action_config', 'flag_group')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(config = action_config(",
        "       action_name = " + actionName + ",",
        "       enabled = " + enabled + ",",
        "       tools = " + tools + ",",
        "       flag_sets = " + flagSets + ",",
        "       implies = " + implies + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomActionConfig_actionName_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "one",
        /* actionName= */ "struct()",
        /* enabled= */ "True",
        /* tools= */ "[]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'action_name' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomActionConfig_enabled_mustBeBool() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "two",
        /* actionName= */ "'actionname'",
        /* enabled= */ "['asd']",
        /* tools= */ "[]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("Field 'enabled' is not of 'java.lang.Boolean' type.");
  }

  @Test
  public void testCustomActionConfig_tools_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "three",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "struct()",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("for tools, got struct, want sequence");
  }

  @Test
  public void testCustomActionConfig_flagSets_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "four",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "True",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("for flag_sets, got bool, want sequence");
  }

  @Test
  public void testCustomActionConfig_implies_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "five",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "flag_set(actions = ['a', 'b'])");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("for implies, got struct, want sequence");
  }

  private void createCustomActionConfigRule(
      String pkg, String actionName, String enabled, String tools, String flagSets, String implies)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set',",
        "             'tool', 'flag_set', 'action_config', )",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(config = struct(",
        "       action_name = " + actionName + ",",
        "       enabled = " + enabled + ",",
        "       tools = " + tools + ",",
        "       flag_sets = " + flagSets + ",",
        "       implies = " + implies + ",",
        "       type_name = 'action_config'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testFeature_name_mustBeNonempty() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "one",
        /* name= */ "''",
        /* enabled= */ "False",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    String msg = e.getMessage();
    assertThat(msg).contains("A feature must either have a nonempty 'name' field or be enabled.");
    assertThat(msg)
        .contains(
            "in FeatureInfo instantiated at /workspace/tools/cpp/cc_toolchain_config_lib.bzl:");
  }

  @Test
  public void testFeature_enabled_mustBeBool() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "two",
        /* name= */ "'featurename'",
        /* enabled= */ "None",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("enabled parameter of feature should be a bool, found NoneType");
  }

  @Test
  public void testFeature_flagSets_mustBeFlagSet() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "three",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[struct()]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'flag_set', received 'struct'");
  }

  @Test
  public void testFeature_envSets_mustBeEnvSet() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "four",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[tool(path = 'a/b/c')]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("Expected object of type 'env_set', received 'tool'");
  }

  @Test
  public void testFeature_something_mustBeFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "five",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[env_set(actions = ['a1'], "
            + "env_entries = [env_entry(key = 'a', value = 'b')])]",
        /* requires= */ "[tool(path = 'a/b/c')]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("expected object of type 'feature_set'");
  }

  @Test
  public void testFeature_implies_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "six",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[env_set(actions = ['a1'], "
            + "env_entries = [env_entry(key = 'a', value = 'b')])]",
        /* requires= */ "[feature_set(features = ['f1', 'f2'])]",
        /* implies= */ "[tool(path = 'a/b/c')]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of implies, got element of type struct, want string");
  }

  @Test
  public void testFeature_provides_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "seven",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[env_set(actions = ['a1'], "
            + "env_entries = [env_entry(key = 'a', value = 'b')])]",
        /* requires= */ "[feature_set(features = ['f1', 'f2'])]",
        /* implies= */ "['a', 'b', 'c']",
        /* provides= */ "[struct()]");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of provides, got element of type struct, want string");
  }

  @Test
  public void testFeature() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "eight",
        /* name= */ "'featurename32+.-_'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[env_set(actions = ['a1'], "
            + "env_entries = [env_entry(key = 'a', value = 'b')])]",
        /* requires= */ "[feature_set(features = ['f1', 'f2'])]",
        /* implies= */ "['a', 'b', 'c']",
        /* provides= */ "['a', 'b', 'c']");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    Feature a = CcModule.featureFromStarlark(featureStruct);
    assertThat(a).isNotNull();
  }

  @Test
  public void testFeature_name_validCharacters_notUpper() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "nine",
        /* name= */ "'UpperCase'",
        /* enabled= */ "False",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//nine:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "A feature's name must consist solely of lowercase ASCII letters, digits, "
                + "'.', '_', '+', and '-', got 'UpperCase'");
  }

  @Test
  public void testFeature_name_validCharacters_notWhitespace() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "ten",
        /* name= */ "'white space'",
        /* enabled= */ "False",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//ten:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "A feature's name must consist solely of "
                + "lowercase ASCII letters, digits, '.', '_', '+', and '-', got 'white space");
  }

  private void createFeatureRule(
      String pkg,
      String name,
      String enabled,
      String flagSets,
      String envSets,
      String requires,
      String implies,
      String provides)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set', 'feature_set',",
        "             'flag_set', 'flag_group', 'tool', 'env_set', 'env_entry', 'feature')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(f = feature(",
        "       name = " + name + ",",
        "       enabled = " + enabled + ",",
        "       flag_sets = " + flagSets + ",",
        "       env_sets = " + envSets + ",",
        "       requires = " + requires + ",",
        "       implies = " + implies + ",",
        "       provides = " + provides + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomFeature_name_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "one",
        /* name= */ "struct()",
        /* enabled= */ "False",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("Field 'name' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFeature_enabled_mustBeBool() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "two",
        /* name= */ "'featurename'",
        /* enabled= */ "struct()",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("Field 'enabled' is not of 'java.lang.Boolean' type.");
  }

  @Test
  public void testCustomFeature_flagSets_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "three",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "struct()",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for flag_sets, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_envSets_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "four",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[]",
        /* envSets= */ "struct()",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for env_sets, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_requires_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "five",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "struct()",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for requires, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_implies_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "six",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "struct()",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for implies, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_provides_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "seven",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for provides, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_flagSet_musthaveActions() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "eight",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set()]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("A flag_set that belongs to a feature must have nonempty 'actions' parameter.");
  }

  private void createCustomFeatureRule(
      String pkg,
      String name,
      String enabled,
      String flagSets,
      String envSets,
      String requires,
      String implies,
      String provides)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set', 'feature_set',",
        "             'flag_set', 'flag_group', 'tool', 'env_set', 'env_entry', 'feature')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(f = struct(",
        "       name = " + name + ",",
        "       enabled = " + enabled + ",",
        "       flag_sets = " + flagSets + ",",
        "       env_sets = " + envSets + ",",
        "       requires = " + requires + ",",
        "       implies = " + implies + ",",
        "       provides = " + provides + ",",
        "       type_name = 'feature'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomArtifactNamePattern_categoryName_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "one", /* categoryName= */ "struct()", /* extension= */ "'a'", /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'category_name' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomArtifactNamePattern_extension_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "two",
        /* categoryName= */ "'static_library'",
        /* extension= */ "struct()",
        /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e).hasMessageThat().contains("Field 'extension' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomArtifactNamePattern_prefix_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "three",
        /* categoryName= */ "'static_library'",
        /* extension= */ "'.a'",
        /* prefix= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e).hasMessageThat().contains("Field 'prefix' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomArtifactNamePattern_categoryName_mustBeNonempty() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "four", /* categoryName= */ "''", /* extension= */ "'.a'", /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("The 'category_name' field of artifact_name_pattern must be a nonempty string.");
  }

  @Test
  public void testCustomArtifactNamePattern_emptyString_emptyString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "five", /* categoryName= */ "'executable'", /* extension= */ "''", /* prefix= */ "''");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    ArtifactNamePattern artifactNamePattern =
        CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct);
    assertThat(artifactNamePattern).isNotNull();
  }

  @Test
  public void testCustomArtifactNamePattern_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "six", /* categoryName= */ "'executable'", /* extension= */ "None", /* prefix= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    ArtifactNamePattern artifactNamePattern =
        CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct);
    assertThat(artifactNamePattern).isNotNull();
  }

  @Test
  public void testCustomArtifactNamePattern_categoryName_unknown() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "seven", /* categoryName= */ "'unknown'", /* extension= */ "'.a'", /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e).hasMessageThat().contains("Artifact category unknown not recognized");
  }

  @Test
  public void testCustomArtifactNamePattern_fileExtension_unknown() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "eight",
        /* categoryName= */ "'static_library'",
        /* extension= */ "'a'",
        /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e).hasMessageThat().contains("Unrecognized file extension 'a'");
  }

  private void createCustomArtifactNamePatternRule(
      String pkg, String categoryName, String extension, String prefix) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(namepattern = struct(",
        "       category_name = " + categoryName + ",",
        "       extension = " + extension + ",",
        "       prefix = " + prefix + ",",
        "       type_name = 'artifact_name_pattern'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCcToolchainInfoFromStarlark() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "        'feature',",
        "        'action_config',",
        "        'artifact_name_pattern',",
        "        'env_entry',",
        "        'variable_with_value',",
        "        'make_variable',",
        "        'feature_set',",
        "        'with_feature_set',",
        "        'env_set',",
        "        'flag_group',",
        "        'flag_set',",
        "        'tool_path',",
        "        'tool')",
        "",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                features = [feature(name = 'featureone')],",
        "                action_configs = [action_config(action_name = 'action', enabled=True)],",
        "                artifact_name_patterns = [artifact_name_pattern(",
        "                   category_name = 'static_library',",
        "                   prefix = 'prefix',",
        "                   extension = '.a')],",
        "                cxx_builtin_include_directories = ['dir1', 'dir2', 'dir3'],",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi',",
        "                tool_paths = [tool_path(name = 'name1', path = 'path1')],",
        "                cc_target_os = 'os',",
        "                builtin_sysroot = 'sysroot',",
        "                make_variables = [make_variable(name = 'acs', value = 'asd')])",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    assertThat(ccToolchainConfigInfo).isNotNull();
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredToolchainIdentifier() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("toolchain_identifier");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e)
        .hasMessageThat()
        .contains("missing 1 required named argument: toolchain_identifier");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredTargetSystemName() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("target_system_name");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e)
        .hasMessageThat()
        .contains("missing 1 required named argument: target_system_name");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredTargetCpu() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("target_cpu");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: target_cpu");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredTargetLibc() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("target_libc");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: target_libc");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredCompiler() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("compiler");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: compiler");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkAllRequiredStringsPresent() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("");
    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    assertThat(ccToolchainConfigInfo).isNotNull();
  }

  private void setupStarlarkRuleForStringFieldsTesting(String fieldToExclude) throws Exception {
    ImmutableList<String> fields =
        ImmutableList.of(
            "toolchain_identifier = 'identifier'",
            "host_system_name = 'host_system_name'",
            "target_system_name = 'target_system_name'",
            "target_cpu = 'target_cpu'",
            "target_libc = 'target_libc'",
            "compiler = 'compiler'",
            "abi_version = 'abi'",
            "abi_libc_version = 'abi_libc'");

    scratch.file(
        "foo/crosstool.bzl",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "    ctx = ctx,",
        Joiner.on(",\n")
            .join(fields.stream().filter(el -> !el.startsWith(fieldToExclude + " =")).toArray()),
        ")",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkNoLegacyFeatures() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "        'feature',",
        "        'action_config',",
        "        'artifact_name_pattern',",
        "        'env_entry',",
        "        'variable_with_value',",
        "        'make_variable',",
        "        'feature_set',",
        "        'with_feature_set',",
        "        'env_set',",
        "        'flag_group',",
        "        'flag_set',",
        "        'tool_path',",
        "        'tool')",
        "",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                features = [",
        "                    feature(name = 'no_legacy_features'),",
        "                    feature(name = 'custom_feature'),",
        "                ],",
        "                action_configs = [action_config(action_name = 'custom_action')],",
        "                artifact_name_patterns = [artifact_name_pattern(",
        "                   category_name = 'static_library',",
        "                   prefix = 'prefix',",
        "                   extension = '.a')],",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi')",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    ImmutableSet<String> featureNames =
        ccToolchainConfigInfo.getFeatures().stream()
            .map(Feature::getName)
            .collect(ImmutableSet.toImmutableSet());
    ImmutableSet<String> actionConfigNames =
        ccToolchainConfigInfo.getActionConfigs().stream()
            .map(ActionConfig::getActionName)
            .collect(ImmutableSet.toImmutableSet());
    assertThat(featureNames).containsExactly("no_legacy_features", "custom_feature");
    assertThat(actionConfigNames).containsExactly("custom_action");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkWithLegacyFeatures() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "        'feature',",
        "        'action_config',",
        "        'artifact_name_pattern',",
        "        'env_entry',",
        "        'variable_with_value',",
        "        'make_variable',",
        "        'feature_set',",
        "        'with_feature_set',",
        "        'env_set',",
        "        'flag_group',",
        "        'flag_set',",
        "        'tool_path',",
        "        'tool')",
        "",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                features = [",
        "                    feature(name = 'custom_feature'),",
        "                    feature(name = 'legacy_compile_flags'),",
        "                    feature(name = 'fdo_optimize'),",
        "                    feature(name = 'default_compile_flags'),",
        "                ],",
        "                action_configs = [action_config(action_name = 'custom-action')],",
        "                artifact_name_patterns = [artifact_name_pattern(",
        "                   category_name = 'static_library',",
        "                   prefix = 'prefix',",
        "                   extension = '.a')],",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi')",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    ImmutableList<String> featureNames =
        ccToolchainConfigInfo.getFeatures().stream()
            .map(Feature::getName)
            .collect(ImmutableList.toImmutableList());
    ImmutableSet<String> actionConfigNames =
        ccToolchainConfigInfo.getActionConfigs().stream()
            .map(ActionConfig::getActionName)
            .collect(ImmutableSet.toImmutableSet());
    // fdo_optimize should not be re-added to the list of features by legacy behavior
    assertThat(featureNames).containsNoDuplicates();
    // legacy_compile_flags should appear first in the list of features, followed by
    // default_compile_flags.
    assertThat(featureNames)
        .containsAtLeast(
            "legacy_compile_flags", "default_compile_flags", "custom_feature", "fdo_optimize")
        .inOrder();
    // assemble is one of the action_configs added as a legacy behavior, therefore it needs to be
    // prepended to the action configs defined by the user.
    assertThat(actionConfigNames).containsAtLeast("assemble", "custom-action").inOrder();
  }

  @Test
  public void testCcToolchainInfoToProto() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "        'feature',",
        "        'action_config',",
        "        'artifact_name_pattern',",
        "        'env_entry',",
        "        'variable_with_value',",
        "        'make_variable',",
        "        'feature_set',",
        "        'with_feature_set',",
        "        'env_set',",
        "        'flag_group',",
        "        'flag_set',",
        "        'tool_path',",
        "        'tool')",
        "",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                features = [",
        "                    feature(name = 'featureone', enabled = True),",
        "                    feature(name = 'sysroot',",
        "                        flag_sets = [",
        "                            flag_set(",
        "                                actions = ['assemble', 'preprocess-assemble'],",
        "                                flag_groups = [",
        "                                    flag_group(",
        "                                        expand_if_available= 'available',",
        "                                        expand_if_not_available= 'notavailable',",
        "                                        expand_if_true = 'true',",
        "                                        expand_if_false = 'false',",
        "                                        expand_if_equal = variable_with_value(",
        "                                            name = 'variable', value = 'value'),",
        "                                        iterate_over = 'iterate_over',",
        "                                        flag_groups = [",
        "                                            flag_group(flags = ",
        "                                                ['foo%{libraries_to_link}bar',",
        "                                                 '-D__DATE__=\"redacted\"'])],",
        "                                    ),",
        "                                    flag_group(flags = ['a', 'b'])],",
        "                        )],",
        "                        implies = ['imply2', 'imply1'],",
        "                        provides = ['provides2', 'provides1'],",
        "                        requires = [feature_set(features = ['r1', 'r2']),",
        "                                    feature_set(features = ['r3'])],",
        "                        env_sets = [",
        "                             env_set(actions = ['a1', 'a2'],",
        "                                     env_entries = [",
        "                                         env_entry(key = 'k1', value = 'v1'),",
        "                                         env_entry(key = 'k2', value = 'v2')],",
        "                                     with_features = [",
        "                                         with_feature_set(",
        "                                             features = ['f1', 'f2'],",
        "                                             not_features = ['nf1', 'nf2'])]),",
        "                             env_set(actions = ['a1', 'a2'])]",
        "                    ),",
        "                ],",
        "                action_configs = [",
        "                    action_config(action_name = 'action_one', enabled=True),",
        "                    action_config(",
        "                        action_name = 'action_two',",
        "                        tools = [tool(path = 'fake/path',",
        "                                      with_features = [",
        "                                          with_feature_set(features = ['a'],",
        "                                                           not_features=['b', 'c']),",
        "                                          with_feature_set(features=['b'])],",
        "                                      execution_requirements = ['a', 'b', 'c'])],",
        "                        implies = ['compiler_input_flags', 'compiler_output_flags'],",
        "                        flag_sets = [flag_set(flag_groups = [flag_group(flags = ['a'])]",
        "                                             )])],",
        "                artifact_name_patterns = [artifact_name_pattern(",
        "                   category_name = 'static_library',",
        "                   prefix = 'prefix',",
        "                   extension = '.a')],",
        "                cxx_builtin_include_directories = ['dir1', 'dir2', 'dir3'],",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi',",
        "                tool_paths = [tool_path(name = 'name1', path = 'path1')],",
        "                make_variables = [make_variable(name = 'variable', value = '--a -b -c')],",
        "                builtin_sysroot = 'sysroot',",
        "                cc_target_os = 'os',",
        "        )",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");

    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    assertThat(ccToolchainConfigInfo).isNotNull();
    CToolchain.Builder toolchainBuilder = CToolchain.newBuilder();
    TextFormat.merge(ccToolchainConfigInfo.getProto(), toolchainBuilder);
    CToolchain toolchain = toolchainBuilder.build();

    assertThat(toolchain.getCxxBuiltinIncludeDirectoryList())
        .containsExactly("dir1", "dir2", "dir3");
    assertThat(toolchain.getToolchainIdentifier()).isEqualTo("toolchain");
    assertThat(toolchain.getHostSystemName()).isEqualTo("host");
    assertThat(toolchain.getTargetSystemName()).isEqualTo("target");
    assertThat(toolchain.getTargetCpu()).isEqualTo("cpu");
    assertThat(toolchain.getTargetLibc()).isEqualTo("libc");
    assertThat(toolchain.getCompiler()).isEqualTo("compiler");
    assertThat(toolchain.getAbiLibcVersion()).isEqualTo("abi_libc");
    assertThat(toolchain.getAbiVersion()).isEqualTo("abi");
    ToolPath toolPath = Iterables.getOnlyElement(toolchain.getToolPathList());
    assertThat(toolPath.getName()).isEqualTo("name1");
    assertThat(toolPath.getPath()).isEqualTo("path1");
    MakeVariable makeVariable = Iterables.getOnlyElement(toolchain.getMakeVariableList());
    assertThat(makeVariable.getName()).isEqualTo("variable");
    assertThat(makeVariable.getValue()).isEqualTo("--a -b -c");
    assertThat(toolchain.getBuiltinSysroot()).isEqualTo("sysroot");
    assertThat(toolchain.getCcTargetOs()).isEqualTo("os");
    assertThat(
            toolchain.getFeatureList().stream()
                .map(CToolchain.Feature::getName)
                .collect(ImmutableList.toImmutableList()))
        .containsAtLeast("featureone", "sysroot")
        .inOrder();
    // check for legacy features
    assertThat(toolchain.getFeatureCount()).isGreaterThan(2);
    CToolchain.Feature feature =
        toolchain.getFeatureList().stream()
            .filter(f -> f.getName().equals("sysroot"))
            .findFirst()
            .get();
    assertThat(feature.getName()).isEqualTo("sysroot");
    assertThat(feature.getImpliesList()).containsExactly("imply2", "imply1").inOrder();
    assertThat(feature.getProvidesList()).containsExactly("provides2", "provides1").inOrder();
    assertThat(feature.getRequires(0).getFeatureList()).containsExactly("r1", "r2");
    assertThat(feature.getRequires(1).getFeatureList()).containsExactly("r3");
    assertThat(feature.getEnvSetCount()).isEqualTo(2);
    CToolchain.EnvSet envSet = feature.getEnvSet(0);
    assertThat(envSet.getActionList()).containsExactly("a1", "a2");
    assertThat(envSet.getEnvEntry(0).getKey()).isEqualTo("k1");
    assertThat(envSet.getEnvEntry(0).getValue()).isEqualTo("v1");
    assertThat(Iterables.getOnlyElement(envSet.getWithFeatureList()).getFeatureList())
        .containsExactly("f1", "f2");
    assertThat(Iterables.getOnlyElement(envSet.getWithFeatureList()).getNotFeatureList())
        .containsExactly("nf1", "nf2");
    CToolchain.FlagSet flagSet = Iterables.getOnlyElement(feature.getFlagSetList());
    assertThat(flagSet.getActionList()).containsExactly("assemble", "preprocess-assemble");
    assertThat(flagSet.getFlagGroupCount()).isEqualTo(2);
    CToolchain.FlagGroup flagGroup = flagSet.getFlagGroup(0);
    assertThat(flagGroup.getExpandIfAllAvailableList()).containsExactly("available");
    assertThat(flagGroup.getExpandIfNoneAvailableList()).containsExactly("notavailable");
    assertThat(flagGroup.getIterateOver()).isEqualTo("iterate_over");
    assertThat(flagGroup.getExpandIfTrue()).isEqualTo("true");
    assertThat(flagGroup.getExpandIfFalse()).isEqualTo("false");
    CToolchain.VariableWithValue variableWithValue = flagGroup.getExpandIfEqual();
    assertThat(variableWithValue.getVariable()).isEqualTo("variable");
    assertThat(variableWithValue.getValue()).isEqualTo("value");
    assertThat(flagGroup.getFlagGroup(0).getFlagList())
        .containsExactly("foo%{libraries_to_link}bar", "-D__DATE__=\"redacted\"")
        .inOrder();

    assertThat(
            toolchain.getActionConfigList().stream()
                .map(CToolchain.ActionConfig::getActionName)
                .collect(ImmutableList.toImmutableList()))
        .containsAtLeast("action_one", "action_two")
        .inOrder();

    // legacy crosstool patching adds the missing action_configs as well
    assertThat(toolchain.getActionConfigCount()).isGreaterThan(2);

    CToolchain.ActionConfig actionConfig =
        toolchain.getActionConfigList().stream()
            .filter(config -> config.getConfigName().equals("action_two"))
            .findFirst()
            .get();
    assertThat(actionConfig.getImpliesList())
        .containsExactly("compiler_input_flags", "compiler_output_flags")
        .inOrder();
    CToolchain.Tool tool = Iterables.getOnlyElement(actionConfig.getToolList());
    assertThat(tool.getToolPath()).isEqualTo("fake/path");
    assertThat(tool.getExecutionRequirementList()).containsExactly("a", "b", "c");
    assertThat(tool.getWithFeature(0).getFeatureList()).containsExactly("a");
    assertThat(tool.getWithFeature(0).getNotFeatureList()).containsExactly("b", "c");
    // When we create an ActionConfig from a proto we put the action name as the only element of its
    // FlagSet.action lists. So when we convert back to proto, we need to remove it.
    assertThat(
            ccToolchainConfigInfo.getActionConfigs().stream()
                .filter(config -> config.getName().equals("action_two"))
                .findFirst()
                .get()
                .getFlagSets()
                .get(0)
                .getActions())
        .containsExactly("action_two");
    CToolchain.FlagSet actionConfigFlagSet =
        Iterables.getOnlyElement(actionConfig.getFlagSetList());
    assertThat(actionConfigFlagSet.getActionCount()).isEqualTo(0);

    // Missing artifact name patterns are filled in too
    assertThat(toolchain.getArtifactNamePatternCount()).isGreaterThan(1);
    assertThat(toolchain.getArtifactNamePattern(0))
        .isEqualTo(
            CToolchain.ArtifactNamePattern.newBuilder()
                .setCategoryName("static_library")
                .setPrefix("prefix")
                .setExtension(".a")
                .build());
  }

  // Tests that default None values in non-required fields do not cause trouble while building
  // the CToolchain
  @Test
  public void testCcToolchainInfoToProtoBareMinimum() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "        )",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");

    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    assertThat(ccToolchainConfigInfo).isNotNull();
    CToolchain.Builder toolchainBuilder = CToolchain.newBuilder();
    TextFormat.merge(ccToolchainConfigInfo.getProto(), toolchainBuilder);
    assertNoEvents();
  }

  @Test
  public void testWrongElementTypeInListParameter_features() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter(
        "features = ['string_instead_of_feature']");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'features' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
            + " of type 'string' instead of a 'FeatureInfo' provider.");
  }

  @Test
  public void testWrongElementTypeInListParameter_actionConfigs() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter("action_configs = [None]");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'action_configs' parameter of cc_common.create_cc_toolchain_config_info() contains an"
            + " element of type 'NoneType' instead of a 'ActionConfigInfo' provider.");
  }

  @Test
  public void testWrongElementTypeInListParameter_artifactNamePatterns() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter("artifact_name_patterns = [1]");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'artifact_name_patterns' parameter of cc_common.create_cc_toolchain_config_info()"
            + " contains an element of type 'int' instead of a 'ArtifactNamePatternInfo'"
            + " provider.");
  }

  @Test
  public void testWrongElementTypeInListParameter_makeVariables() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter("make_variables = [True]");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'make_variables' parameter of cc_common.create_cc_toolchain_config_info() contains an"
            + " element of type 'bool' instead of a 'MakeVariableInfo' provider.");
  }

  @Test
  public void testWrongElementTypeInListParameter_toolPaths() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter("tool_paths = [{}]");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'tool_paths' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
            + " of type 'dict' instead of a 'ToolPathInfo' provider.");
  }

  private void getBasicCcToolchainConfigInfoWithAdditionalParameter(String s) throws Exception {
    scratch.file(
        "foo/crosstool.bzl",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi',",
        "                " + s + ",",
        "        )",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
  }

  @Test
  public void testGetLegacyCcFlagsMakeVariable() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withMakeVariables(Pair.of("CC_FLAGS", "-test-cflag1 -testcflag2")));

    loadCcToolchainConfigLib();
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  cc_flags = cc_common.legacy_cc_flags_make_variable_do_not_use(",
        "      cc_toolchain = toolchain)",
        "  return [MyInfo(",
        "    cc_flags = cc_flags)]",
        "cc_flags = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

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

    String ccFlags =
        (String) getMyInfoFromTarget(getConfiguredTarget("//a:r")).getValue("cc_flags");

    assertThat(ccFlags).isEqualTo("-test-cflag1 -testcflag2");
  }

  private boolean toolchainResolutionEnabled() throws Exception {
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain_resolution_enabled = cc_common.is_cc_toolchain_resolution_enabled_do_not_use(",
        "      ctx = ctx)",
        "  return [MyInfo(",
        "    toolchain_resolution_enabled = toolchain_resolution_enabled)]",
        "toolchain_resolution_enabled = rule(",
        "  _impl,",
        ");");

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

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    // Use an extra variable in order to suppress the warning.
    boolean toolchainResolutionEnabled =
        (boolean) getMyInfoFromTarget(r).getValue("toolchain_resolution_enabled");
    return toolchainResolutionEnabled;
  }

  @Test
  public void testIsToolchainResolutionEnabled_disabled() throws Exception {
    useConfiguration("--incompatible_enable_cc_toolchain_resolution=false");

    assertThat(toolchainResolutionEnabled()).isFalse();
  }

  @Test
  public void testIsToolchainResolutionEnabled_enabled() throws Exception {
    useConfiguration("--incompatible_enable_cc_toolchain_resolution");

    assertThat(toolchainResolutionEnabled()).isTrue();
  }

  @Test
  public void testWrongExtensionThrowsError() throws Exception {
    setUpCcLinkingContextTest(false);
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "cc_binary(name='bin',",
        "   deps = [':a'],",
        ")",
        "crule(name='a',",
        "   static_library = 'a.o',",
        "   pic_static_library = 'a.pic.o',",
        "   dynamic_library = 'a.ifso',",
        "   interface_library = 'a.so',",
        "   dynamic_library_symlink_path = 'a.lib',",
        "   interface_library_symlink_path = 'a.dll',",
        ")");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:bin"));
    assertThat(e)
        .hasMessageThat()
        .contains("'a.o' does not have any of the allowed extensions .a, .lib, .pic.a or .rlib");
    assertThat(e)
        .hasMessageThat()
        .contains(
            "'a.pic.o' does not have any of the allowed extensions .a, .lib, .pic.a or .rlib");
    assertThat(e)
        .hasMessageThat()
        .contains("'a.ifso' does not have any of the allowed extensions .so, .dylib or .dll");
    assertThat(e)
        .hasMessageThat()
        .contains("'a.lib' does not have any of the allowed extensions .so, .dylib or .dll");
    assertThat(e)
        .hasMessageThat()
        .contains(
            "'a.dll' does not have any of the allowed extensions .ifso, .tbd, .lib or .dll.a");
  }

  @Test
  public void testCcOutputsMerging() throws Exception {
    setupCcOutputsTest();
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    object1 = 'object1.o',",
        "    pic_object1 = 'pic_object1.o',",
        "    object2 = 'object2.o',",
        "    pic_object2 = 'pic_object2.o',",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CcCompilationOutputs compilationOutputs =
        (CcCompilationOutputs) getMyInfoFromTarget(target).getValue("compilation_outputs");
    assertThat(
            AnalysisTestUtil.artifactsToStrings(
                masterConfig, compilationOutputs.getObjectFiles(/* usePic= */ true)))
        .containsExactly("src foo/pic_object1.o", "src foo/pic_object2.o");
    assertThat(
            AnalysisTestUtil.artifactsToStrings(
                masterConfig, compilationOutputs.getObjectFiles(/* usePic= */ false)))
        .containsExactly("src foo/object1.o", "src foo/object2.o");
  }

  @Test
  public void testObjectsWrongExtension() throws Exception {
    doTestCcOutputsWrongExtension("object1", "objects");
  }

  @Test
  public void testPicObjectsWrongExtension() throws Exception {
    doTestCcOutputsWrongExtension("pic_object1", "pic_objects");
  }

  @Test
  public void testObjectsRightExtension() throws Exception {
    doTestCcOutputsRightExtension("object1");
  }

  @Test
  public void testPicObjectsRightExtension() throws Exception {
    doTestCcOutputsRightExtension("pic_object1");
  }

  @Test
  public void testCreateOnlyPic() throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_PIC));
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", String.join("", "disallow_nopic_outputs=True"));
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(getFilenamesToBuild(target)).doesNotContain("starlark_lib.o");
    assertThat(getFilenamesToBuild(target)).contains("starlark_lib.pic.o");
  }

  @Test
  public void testCreateOnlyNoPic() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", String.join("", "disallow_pic_outputs=True"));
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(getFilenamesToBuild(target)).contains("starlark_lib.o");
    assertThat(getFilenamesToBuild(target)).doesNotContain("starlark_lib.pic.o");
  }

  @Test
  public void testCreatePicAndNoPic() throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_PIC));
    createFilesForTestingCompilation(scratch, "tools/build_defs/foo", "");
    useConfiguration("--compilation_mode=opt");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(getFilenamesToBuild(target)).contains("starlark_lib.pic.o");
    assertThat(getFilenamesToBuild(target)).contains("starlark_lib.o");
  }

  @Test
  public void testDoNotCreateEitherPicOrNoPic() throws Exception {
    createFilesForTestingCompilation(
        scratch,
        "tools/build_defs/foo",
        String.join("", "disallow_nopic_outputs=True, disallow_pic_outputs=True"));
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:bin");
    assertContainsEvent("Either PIC or no PIC actions have to be created.");
  }

  @Test
  public void testCreateStaticLibraries() throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.SUPPORTS_DYNAMIC_LINKER, CppRuleClasses.SUPPORTS_PIC));
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", /* linkProviderLines= */ "");
    assertThat(getConfiguredTarget("//foo:starlark_lib")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(
            getFilesToBuild(target).toList().stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .contains("libstarlark_lib.a");
  }

  @Test
  public void testDoNotCreateStaticLibraries() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", "disallow_static_libraries=True");
    assertThat(getConfiguredTarget("//foo:starlark_lib")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(
            getFilesToBuild(target).toList().stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .doesNotContain("libstarlark_lib.a");
  }

  private static ImmutableList<String> getFilenamesToBuild(ConfiguredTarget target) {
    return getFilesToBuild(target).toList().stream()
        .map(Artifact::getFilename)
        .collect(ImmutableList.toImmutableList());
  }

  @Test
  public void testCcNativeRuleDependingOnStarlarkDefinedRule() throws Exception {
    createFiles(scratch, "tools/build_defs/cc");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
  }

  @Test
  public void testUserCompileFlagsInRulesApi() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "user_compile_flags=['-COMPILATION_OPTION']");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).contains("-COMPILATION_OPTION");
  }

  @Test
  public void testIncludeDirs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "includes=['foo/bar', 'baz/qux']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-Ifoo/bar", "-Ibaz/qux");
  }

  @Test
  public void testSystemIncludeDirs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "system_includes=['foo/bar', 'baz/qux']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments())
        .containsAtLeast("-isystem", "foo/bar", "-isystem", "baz/qux")
        .inOrder();
  }

  @Test
  public void testQuoteIncludeDirs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "quote_includes=['foo/bar', 'baz/qux']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments())
        .containsAtLeast("-iquote", "foo/bar", "-iquote", "baz/qux")
        .inOrder();
  }

  @Test
  public void testFrameworkIncludeDirs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "framework_includes=['foo/bar', 'baz/qux']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-Ffoo/bar", "-Fbaz/qux").inOrder();
  }

  @Test
  public void testDefines() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "defines=['DEFINE1', 'DEFINE2']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-DDEFINE1", "-DDEFINE2");
  }

  @Test
  public void testLocalDefines() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "local_defines=['DEFINE1', 'DEFINE2']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-DDEFINE1", "-DDEFINE2");
  }

  @Test
  public void testIncludePrefix() throws Exception {
    createFilesForTestingCompilation(
        scratch, "third_party/tools/build_defs/foo", "include_prefix='prefix'");
    scratch.file(
        "third_party/bar/BUILD",
        "load('//third_party/tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.cc'],",
        "    public_hdrs = ['starlark_lib.h'],",
        "    private_hdrs = ['private_starlark_lib.h'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//third_party/bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin third_party/bar/_virtual_includes/starlark_lib/prefix/starlark_lib.h");
  }

  @Test
  public void testStripIncludePrefix() throws Exception {
    createFilesForTestingCompilation(
        scratch, "third_party/tools/build_defs/foo", "strip_include_prefix='v1'");
    scratch.file(
        "third_party/bar/BUILD",
        "load('//third_party/tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.cc'],",
        "    public_hdrs = ['v1/starlark_lib.h'],",
        "    private_hdrs = ['v1/private_starlark_lib.h'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//third_party/bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin third_party/bar/_virtual_includes/starlark_lib/starlark_lib.h");
  }

  @Test
  public void testStripIncludePrefixAndIncludePrefix() throws Exception {
    createFilesForTestingCompilation(
        scratch,
        "third_party/tools/build_defs/foo",
        "strip_include_prefix='v1', include_prefix='prefix'");
    scratch.file(
        "third_party/bar/BUILD",
        "load('//third_party/tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.cc'],",
        "    public_hdrs = ['v1/starlark_lib.h'],",
        "    private_hdrs = ['v1/private_starlark_lib.h'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//third_party/bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin third_party/bar/_virtual_includes/starlark_lib/prefix/starlark_lib.h");
  }

  @Test
  public void testHeaders() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", /* compileProviderLines= */ "");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDeclaredIncludeSrcs()))
        .containsAtLeast(
            "src foo/dep2.h", "src foo/starlark_lib.h", "src foo/private_starlark_lib.h");
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getTextualHdrs()))
        .containsExactly("src foo/textual_hdr.h");
  }

  @Test
  public void testCompileOutputHasSuffix() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", /* compileProviderLines= */ "");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(artifactsToStrings(getFilesToBuild(target)))
        .contains("bin foo/_objs/starlark_lib_suffix/starlark_lib.o");
  }

  @Test
  public void testCompilationContexts() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", /* compileProviderLines= */ "");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-DDEFINE_DEP1", "-DDEFINE_DEP2");
  }

  @Test
  public void testLinkingOutputs() throws Exception {
    createFiles(scratch, "tools/build_defs/foo");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    @SuppressWarnings("unchecked")
    Sequence<LibraryToLink> libraries =
        (Sequence<LibraryToLink>) getMyInfoFromTarget(target).getValue("libraries");
    assertThat(
            libraries.stream()
                .map(x -> x.getResolvedSymlinkDynamicLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .contains("libstarlark_lib.so");
  }

  @Test
  public void testUserLinkFlags() throws Exception {
    createFilesForTestingLinking(
        scratch, "tools/build_defs/foo", "user_link_flags=['-LINKING_OPTION']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(target.get(CcInfo.PROVIDER).getCcLinkingContext().getFlattenedUserLinkFlags())
        .contains("-LINKING_OPTION");
  }

  @Test
  public void testLinkingContexts() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", /* linkProviderLines= */ "");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    CppLinkAction action =
        (CppLinkAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), "bin"));
    assertThat(action.getArguments()).containsAtLeast("-DEP1_LINKOPT", "-DEP2_LINKOPT");
  }

  @Test
  public void testAlwayslinkTrue() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", "alwayslink=True");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(
            target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries().toList().stream()
                .filter(LibraryToLink::getAlwayslink)
                .collect(ImmutableList.toImmutableList()))
        .hasSize(1);
  }

  @Test
  public void testAlwayslinkFalse() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", "alwayslink=False");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(
            target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries().toList().stream()
                .filter(LibraryToLink::getAlwayslink)
                .collect(ImmutableList.toImmutableList()))
        .isEmpty();
  }

  @Test
  public void testAdditionalLinkingInputs() throws Exception {
    createFilesForTestingLinking(
        scratch, "tools/build_defs/foo", "additional_inputs=ctx.files._additional_inputs");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(target.get(CcInfo.PROVIDER).getCcLinkingContext().getNonCodeInputs().toList())
        .hasSize(1);
  }

  @Test
  public void testAdditionalCompilationInputs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "additional_inputs=ctx.files._additional_compiler_inputs");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(artifactsToStrings(action.getMandatoryInputs()))
        .contains("src foo/extra_compiler_input");
  }

  @Test
  public void testPossibleSrcsExtensions() throws Exception {
    doTestPossibleExtensionsOfSrcsAndHdrs(
        "srcs", CppFileTypes.ALL_C_CLASS_SOURCE.including(CppFileTypes.ASSEMBLER).getExtensions());
  }

  @Test
  public void testPossiblePrivateHdrExtensions() throws Exception {
    doTestPossibleExtensionsOfSrcsAndHdrs("private_hdrs", CppFileTypes.CPP_HEADER.getExtensions());
  }

  @Test
  public void testPossiblePublicHdrExtensions() throws Exception {
    doTestPossibleExtensionsOfSrcsAndHdrs("public_hdrs", CppFileTypes.CPP_HEADER.getExtensions());
  }

  @Test
  public void testTreeArtifactSrcs() throws Exception {
    doTestTreeAtrifactInSrcsAndHdrs("srcs");
  }

  @Test
  public void testTreeArtifactPrivateHdrs() throws Exception {
    doTestTreeAtrifactInSrcsAndHdrs("private_hdrs");
  }

  @Test
  public void testTreeArtifactPublicHdrs() throws Exception {
    doTestTreeAtrifactInSrcsAndHdrs("public_hdrs");
  }

  private static void createFilesForTestingCompilation(
      Scratch scratch, String bzlFilePath, String compileProviderLines) throws Exception {
    createFiles(scratch, bzlFilePath, compileProviderLines, "");
  }

  private static void createFilesForTestingLinking(
      Scratch scratch, String bzlFilePath, String linkProviderLines) throws Exception {
    createFiles(scratch, bzlFilePath, "", linkProviderLines);
  }

  private static void createFiles(Scratch scratch, String bzlFilePath) throws Exception {
    createFiles(scratch, bzlFilePath, "", "");
  }

  private static void createFiles(
      Scratch scratch, String bzlFilePath, String compileProviderLines, String linkProviderLines)
      throws Exception {
    String fragments = "    fragments = ['google_cpp', 'cpp'],";
    if (AnalysisMock.get().isThisBazel()) {
      fragments = "    fragments = ['cpp'],";
    }
    scratch.overwriteFile(bzlFilePath + "/BUILD");
    scratch.file(
        bzlFilePath + "/extension.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _cc_aspect_impl(target, ctx):",
        "    toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "    feature_configuration = cc_common.configure_features(",
        "        ctx = ctx,",
        "        cc_toolchain = toolchain,",
        "        requested_features = ctx.features,",
        "        unsupported_features = ctx.disabled_features,",
        "    )",
        "    (compilation_context, compilation_outputs) = cc_common.compile(",
        "        actions = ctx.actions,",
        "        feature_configuration = feature_configuration,",
        "        cc_toolchain = toolchain,",
        "        name = ctx.label.name + '_aspect',",
        "        srcs = ctx.rule.files.srcs,",
        "        public_hdrs = ctx.rule.files.hdrs,",
        "    )",
        "    (linking_context, linking_outputs) = (",
        "        cc_common.create_linking_context_from_compilation_outputs(",
        "            actions = ctx.actions,",
        "            feature_configuration = feature_configuration,",
        "            name = ctx.label.name + '_aspect',",
        "            cc_toolchain = toolchain,",
        "            compilation_outputs = compilation_outputs,",
        "        )",
        "    )",
        "    return []",
        "_cc_aspect = aspect(",
        "    implementation = _cc_aspect_impl,",
        "    attrs = {",
        "        '_cc_toolchain': attr.label(default ="
            + " '@bazel_tools//tools/cpp:current_cc_toolchain'),",
        "    },",
        fragments,
        ")",
        "def _cc_starlark_library_impl(ctx):",
        "    dep_compilation_contexts = []",
        "    dep_linking_contexts = []",
        "    for dep in ctx.attr._deps:",
        "        dep_compilation_contexts.append(dep[CcInfo].compilation_context)",
        "        dep_linking_contexts.append(dep[CcInfo].linking_context)",
        "    toolchain = ctx.attr._my_cc_toolchain[cc_common.CcToolchainInfo]",
        "    feature_configuration = cc_common.configure_features(",
        "        ctx = ctx,",
        "        cc_toolchain=toolchain,",
        "        requested_features = ctx.features,",
        "        unsupported_features = ctx.disabled_features)",
        "    foo_dict = {'string_variable': 'foo',",
        "            'string_sequence_variable' : ['foo'],",
        "            'string_depset_variable': depset(['foo'])}",
        "    (compilation_context, compilation_outputs) = cc_common.compile(",
        "        actions=ctx.actions,",
        "        feature_configuration=feature_configuration,",
        "        cc_toolchain=toolchain,",
        "        srcs=ctx.files.srcs,",
        "        name=ctx.label.name + '_suffix',",
        "        compilation_contexts = dep_compilation_contexts,",
        "        public_hdrs=ctx.files.public_hdrs,",
        "        textual_hdrs=ctx.files.textual_hdrs,",
        "        private_hdrs=ctx.files.private_hdrs" + (compileProviderLines.isEmpty() ? "" : ","),
        "        " + compileProviderLines,
        "    )",
        "    (linking_context,",
        "     linking_outputs) = cc_common.create_linking_context_from_compilation_outputs(",
        "        actions=ctx.actions,",
        "        feature_configuration=feature_configuration,",
        "        compilation_outputs=compilation_outputs,",
        "        name = ctx.label.name,",
        "        linking_contexts = dep_linking_contexts,",
        "        cc_toolchain=toolchain" + (linkProviderLines.isEmpty() ? "" : ","),
        "        " + linkProviderLines,
        "    )",
        "    files_to_build = []",
        "    files_to_build.extend(compilation_outputs.pic_objects)",
        "    files_to_build.extend(compilation_outputs.objects)",
        "    library_to_link = None",
        "    if len(ctx.files.srcs) > 0:",
        "        library_to_link = linking_outputs.library_to_link",
        "        if library_to_link.pic_static_library != None:",
        "            files_to_build.append(library_to_link.pic_static_library)",
        "        if library_to_link.static_library != None:",
        "            files_to_build.append(library_to_link.static_library)",
        "        files_to_build.append(library_to_link.dynamic_library)",
        "    return [MyInfo(libraries=[library_to_link]),",
        "            DefaultInfo(files=depset(files_to_build)),",
        "            CcInfo(compilation_context=compilation_context,",
        "                   linking_context=linking_context)]",
        "cc_starlark_library = rule(",
        "    implementation = _cc_starlark_library_impl,",
        "    attrs = {",
        "      'srcs': attr.label_list(allow_files=True),",
        "      'public_hdrs': attr.label_list(allow_files=True),",
        "      'textual_hdrs': attr.label_list(allow_files=True),",
        "      'private_hdrs': attr.label_list(allow_files=True),",
        "      '_additional_inputs': attr.label_list(allow_files=True,"
            + " default=['//foo:script.lds']),",
        "      '_additional_compiler_inputs': attr.label_list(allow_files=True,"
            + " default=['//foo:extra_compiler_input']),",
        "      '_deps': attr.label_list(default=['//foo:dep1', '//foo:dep2']),",
        "      'aspect_deps': attr.label_list(aspects=[_cc_aspect]),",
        "      '_my_cc_toolchain': attr.label(default =",
        "          configuration_field(fragment = 'cpp', name = 'cc_toolchain'))",
        "    },",
        fragments,
        ")");
    scratch.file(
        "foo/BUILD",
        "load('//" + bzlFilePath + ":extension.bzl', 'cc_starlark_library')",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = ['dep1.cc'],",
        "    hdrs = ['dep1.h'],",
        "    defines = ['DEFINE_DEP1'],",
        "    linkopts = ['-DEP1_LINKOPT'],",
        ")",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = ['dep2.cc'],",
        "    hdrs = ['dep2.h'],",
        "    defines = ['DEFINE_DEP2'],",
        "    linkopts = ['-DEP2_LINKOPT'],",
        ")",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.cc'],",
        "    public_hdrs = ['starlark_lib.h'],",
        "    textual_hdrs = ['textual_hdr.h'],",
        "    private_hdrs = ['private_starlark_lib.h'],",
        ")",
        "cc_binary(",
        "    name = 'bin',",
        "    deps = ['starlark_lib'],",
        ")");
  }

  @Test
  public void testTransitiveLinkWithDeps() throws Exception {
    setupTestTransitiveLink(scratch, "linking_contexts = dep_linking_contexts");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    Artifact executable = (Artifact) getMyInfoFromTarget(target).getValue("executable");
    assertThat(artifactsToStrings(getGeneratingAction(executable).getInputs()))
        .containsAtLeast("bin foo/libdep1.a", "bin foo/libdep2.a");
  }

  @Test
  public void testTransitiveLinkForDynamicLibrary() throws Exception {
    setupTestTransitiveLink(scratch, "output_type = 'dynamic_library'");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    LibraryToLink library = (LibraryToLink) getMyInfoFromTarget(target).getValue("library");
    assertThat(library).isNotNull();
    Object executable = getMyInfoFromTarget(target).getValue("executable");
    assertThat(Starlark.isNullOrNone(executable)).isTrue();
  }

  @Test
  public void testInterfaceLibraryProducedForTransitiveLinkOnWindows() throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER,
                    CppRuleClasses.TARGETS_WINDOWS,
                    CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES,
                    CppRuleClasses.COPY_DYNAMIC_LIBRARIES_TO_BINARY));
    setupTestTransitiveLink(scratch, "output_type = 'dynamic_library'");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    LibraryToLink library = (LibraryToLink) getMyInfoFromTarget(target).getValue("library");
    assertThat(library).isNotNull();
    assertThat(library.getDynamicLibrary()).isNotNull();
    assertThat(library.getInterfaceLibrary()).isNotNull();
  }

  @Test
  public void testTransitiveLinkForExecutable() throws Exception {
    setupTestTransitiveLink(scratch, "output_type = 'executable'");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    Artifact executable = (Artifact) getMyInfoFromTarget(target).getValue("executable");
    assertThat(executable).isNotNull();
    Object library = getMyInfoFromTarget(target).getValue("library");
    assertThat(Starlark.isNullOrNone(library)).isTrue();
  }

  @Test
  public void testPassGrepIncludesToApiEvenThoughItDoesntDoAnything() throws Exception {
    setupTestTransitiveLink(scratch, "grep_includes = ctx.executable._grep_includes");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
  }

  @Test
  public void testTransitiveLinkWithCompilationOutputs() throws Exception {
    setupTestTransitiveLink(scratch, "compilation_outputs=objects");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    Artifact executable = (Artifact) getMyInfoFromTarget(target).getValue("executable");
    assertThat(artifactsToStrings(getGeneratingAction(executable).getInputs()))
        .contains("src foo/file.o");
  }

  @Test
  public void testLinkStampExpliciltyEnabledOverridesNoStampFlag() throws Exception {
    useConfiguration("--nostamp");
    setupTestTransitiveLink(scratch, "stamp=1", "linking_contexts=dep_linking_contexts");
    assertStampEnabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkExplicitlyDisabledOverridesStampFlag() throws Exception {
    useConfiguration("--nostamp");
    setupTestTransitiveLink(scratch, "stamp=0", "linking_contexts=dep_linking_contexts");
    assertStampDisabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkStampUseFlagStamp() throws Exception {
    useConfiguration("--stamp");
    setupTestTransitiveLink(scratch, "stamp=-1", "linking_contexts=dep_linking_contexts");
    assertStampEnabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkStampUseFlagNoStamp() throws Exception {
    useConfiguration("--nostamp");
    setupTestTransitiveLink(scratch, "stamp=-1", "linking_contexts=dep_linking_contexts");
    assertStampDisabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkStampDisabledByDefaultDespiteStampFlag() throws Exception {
    useConfiguration("--stamp");
    setupTestTransitiveLink(scratch, "linking_contexts=dep_linking_contexts");
    assertStampDisabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkStampInvalid() throws Exception {
    setupTestTransitiveLink(scratch, "stamp=2");
    checkError(
        "//foo:bin",
        "stamp value 2 is not supported, must be 0 (disabled), 1 (enabled), or -1 (default)");
  }

  private CppCompileAction getLinkstampCompileAction(String label)
      throws LabelSyntaxException, EvalException {
    ConfiguredTarget target = getConfiguredTarget(label);
    Artifact executable = (Artifact) getMyInfoFromTarget(target).getValue("executable");
    CppLinkAction generatingAction = (CppLinkAction) getGeneratingAction(executable);
    Artifact compiledLinkstamp =
        ActionsTestUtil.getFirstArtifactEndingWith(generatingAction.getInputs(), "version.o");
    CppCompileAction linkstampCompileAction =
        (CppCompileAction) getGeneratingAction(compiledLinkstamp);
    assertThat(linkstampCompileAction.getMnemonic()).isEqualTo("CppLinkstampCompile");
    return linkstampCompileAction;
  }

  private void assertStampEnabled(CppCompileAction linkstampAction)
      throws CommandLineExpansionException {
    assertThat(linkstampAction.getArguments())
        .contains(getRelativeOutputPath() + "/k8-fastbuild/include/build-info-volatile.h");
  }

  private void assertStampDisabled(CppCompileAction linkstampAction)
      throws CommandLineExpansionException {
    assertThat(linkstampAction.getArguments())
        .contains(getRelativeOutputPath() + "/k8-fastbuild/include/build-info-redacted.h");
  }

  @Test
  public void testApiWithAspectsOnTargetsInExternalRepos() throws Exception {
    if (!AnalysisMock.get().isThisBazel()) {
      return;
    }
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", /* compileProviderLines= */ "");
    FileSystemUtils.appendIsoLatin1(
        scratch.resolve("WORKSPACE"), "local_repository(name='r', path='/r')");
    scratch.file("/r/WORKSPACE");
    scratch.file("/r/p/BUILD", "cc_library(", "    name = 'a',", "    srcs = ['a.cc'],", ")");
    invalidatePackages();
    scratch.file(
        "b/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'b',",
        "    srcs = ['b.cc'],",
        "    aspect_deps = ['@r//p:a']",
        ")");
    assertThat(getConfiguredTarget("//b:b")).isNotNull();
  }

  @Test
  public void testObjectsApi() throws Exception {
    useConfiguration("--compilation_mode=opt");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));

    scratchObjectsProvidingRule();

    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//foo:foo.bzl", ImmutableMap.of()), "FooInfo");
    LibraryToLink fooLibrary =
        Iterables.getOnlyElement(
            getConfiguredTarget("//foo:dep")
                .get(CcInfo.PROVIDER)
                .getCcLinkingContext()
                .getLibraries()
                .toList());
    StarlarkInfo fooInfo =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    assertThat(fooLibrary.getObjectFiles()).isEqualTo(fooInfo.getValue("objects"));
    assertThat(fooLibrary.getPicObjectFiles()).isEqualTo(fooInfo.getValue("pic_objects"));
  }

  @Test
  public void testObjectsApiNeverReturningNones() throws Exception {
    scratchObjectsProvidingRule();

    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//foo:foo.bzl", ImmutableMap.of()), "FooInfo");

    // Default toolchain is without PIC support, so pic_objects should be None
    StarlarkInfo fooInfoForPic =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    Object picObjects = fooInfoForPic.getValue("pic_objects");
    assertThat(picObjects).isNotEqualTo(Starlark.NONE);
    assertThat((List) picObjects).isEmpty();

    // With PIC and the default compilation_mode which is fastbuild C++ rules only produce PIC
    // objects.
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));
    invalidatePackages();
    StarlarkInfo fooInfoForNoPic =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    Object objects = fooInfoForNoPic.getValue("objects");
    assertThat(objects).isNotEqualTo(Starlark.NONE);
    assertThat((List) objects).isEmpty();
  }

  @Test
  public void testLtoBitcodeFilesApi() throws Exception {
    useConfiguration("--compilation_mode=opt", "--features=thin_lto");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.THIN_LTO, CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));

    scratchObjectsProvidingRule();

    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//foo:foo.bzl", ImmutableMap.of()), "FooInfo");
    LibraryToLink fooLibrary =
        Iterables.getOnlyElement(
            getConfiguredTarget("//foo:dep")
                .get(CcInfo.PROVIDER)
                .getCcLinkingContext()
                .getLibraries()
                .toList());
    StarlarkInfo fooInfo =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    assertThat(ImmutableList.copyOf(fooLibrary.getLtoCompilationContext().getBitcodeFiles()))
        .isEqualTo(fooInfo.getValue("lto_bitcode_files"));
    assertThat(fooLibrary.getLtoCompilationContext().getBitcodeFiles()).isNotEmpty();

    assertThat(ImmutableList.copyOf(fooLibrary.getPicLtoCompilationContext().getBitcodeFiles()))
        .isEqualTo(fooInfo.getValue("pic_lto_bitcode_files"));
    assertThat(fooLibrary.getPicLtoCompilationContext().getBitcodeFiles()).isNotEmpty();
  }

  @Test
  public void testLtoBitcodeFilesApiNeverReturningNones() throws Exception {
    // We do not add --features=thin_lto for this test.
    useConfiguration("--compilation_mode=opt");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                // We do not enable the THIN_LTO feature for this test.
                .withFeatures(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));

    scratchObjectsProvidingRule();

    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//foo:foo.bzl", ImmutableMap.of()), "FooInfo");
    StarlarkInfo fooInfo =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    Object picLtoBitcodeFiles = fooInfo.getValue("pic_lto_bitcode_files");
    assertThat(picLtoBitcodeFiles).isNotEqualTo(Starlark.NONE);
    assertThat((List) picLtoBitcodeFiles).isEmpty();

    Object ltoBitcodeFiles = fooInfo.getValue("lto_bitcode_files");
    assertThat(ltoBitcodeFiles).isNotEqualTo(Starlark.NONE);
    assertThat((List) ltoBitcodeFiles).isEmpty();
  }

  private void scratchObjectsProvidingRule() throws IOException {
    scratch.file(
        "foo/BUILD",
        "load(':foo.bzl', 'foo')",
        "foo(",
        "  name = 'foo',",
        "  dep = ':dep',",
        ")",
        "cc_library(",
        "  name = 'dep',",
        "  srcs = ['dep.cc'],",
        ")");
    scratch.file(
        "foo/foo.bzl",
        "FooInfo = provider(fields=['objects',"
            + " 'pic_objects','lto_bitcode_files','pic_lto_bitcode_files'])",
        "",
        "def _foo_impl(ctx):",
        "  lib = ctx.attr.dep[CcInfo].linking_context.linker_inputs.to_list()[0].libraries[0]",
        "  return [FooInfo(objects=lib.objects, pic_objects=lib.pic_objects,"
            + " lto_bitcode_files=lib.lto_bitcode_files,"
            + " pic_lto_bitcode_files=lib.pic_lto_bitcode_files)]",
        "",
        "foo = rule(",
        "  implementation = _foo_impl,",
        "  attrs = {",
        "    'dep': attr.label(),",
        "  }",
        ")");
  }

  private void doTestPossibleExtensionsOfSrcsAndHdrs(String attrName, List<String> extensions)
      throws Exception {
    createFiles(scratch, "tools/build_defs/foo");
    reporter.removeHandler(failFastHandler);

    for (String extension : extensions) {
      scratch.deleteFile("bar/BUILD");
      scratch.file(
          "bar/BUILD",
          "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
          "cc_starlark_library(",
          "    name = 'starlark_lib',",
          "    " + attrName + " = ['file" + extension + "'],",
          ")");
      getConfiguredTarget("//bar:starlark_lib");
      assertNoEvents();
    }
  }

  private void doTestTreeAtrifactInSrcsAndHdrs(String attrName) throws Exception {
    createFiles(scratch, "tools/build_defs/foo");
    reporter.removeHandler(failFastHandler);

    scratch.file(
        "bar/create_tree_artifact.bzl",
        "def _impl(ctx):",
        "    tree = ctx.actions.declare_directory('dir')",
        "    ctx.actions.run_shell(",
        "        outputs = [tree],",
        "        inputs = [],",
        "        arguments = [tree.path],",
        "        command = 'mkdir $1',",
        "    )",
        "    return [DefaultInfo(files = depset([tree]))]",
        "create_tree_artifact = rule(implementation = _impl)");
    scratch.file(
        "bar/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "load(':create_tree_artifact.bzl', 'create_tree_artifact')",
        "create_tree_artifact(name = 'tree_artifact')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    " + attrName + " = [':tree_artifact'],",
        ")");
    getConfiguredTarget("//bar:starlark_lib");
    assertNoEvents();
  }

  private void doTestCcOutputsWrongExtension(String attrName, String paramName) throws Exception {
    setupCcOutputsTest();
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    " + attrName + " = 'object.cannotpossiblybevalid',",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:starlark_lib");
    assertContainsEvent(
        "has wrong extension. The list of possible extensions for '" + paramName + "'");
  }

  private void doTestCcOutputsRightExtension(String paramName) throws Exception {
    setupCcOutputsTest();
    reporter.removeHandler(failFastHandler);

    for (String extension : Link.OBJECT_FILETYPES.getExtensions()) {
      scratch.deleteFile("foo/BUILD");
      scratch.file(
          "foo/BUILD",
          "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
          "cc_starlark_library(",
          "    name = 'starlark_lib',",
          "    " + paramName + " = 'object1" + extension + "',",
          ")");
      getConfiguredTarget("//foo:starlark_lib");
      assertNoEvents();
    }
  }

  private void setupCcOutputsTest() throws Exception {
    scratch.overwriteFile("tools/build_defs/foo/BUILD");
    scratch.file(
        "tools/build_defs/foo/extension.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _cc_starlark_library_impl(ctx):",
        "    objects = []",
        "    pic_objects = []",
        "    if ctx.file.object1 != None:",
        "        objects.append(ctx.file.object1)",
        "    if ctx.file.pic_object1 != None:",
        "        pic_objects.append(ctx.file.pic_object1)",
        "    c1 = cc_common.create_compilation_outputs(objects=depset(objects),",
        "        pic_objects=depset(pic_objects))",
        "    objects = []",
        "    pic_objects = []",
        "    if ctx.file.object2 != None:",
        "        objects.append(ctx.file.object2)",
        "    if ctx.file.pic_object2 != None:",
        "        pic_objects.append(ctx.file.pic_object2)",
        "    c2 = cc_common.create_compilation_outputs(objects=depset(objects),",
        "        pic_objects=depset(pic_objects))",
        "    compilation_outputs = cc_common.merge_compilation_outputs(",
        "        compilation_outputs=[c1, c2])",
        "    return [MyInfo(compilation_outputs=compilation_outputs)]",
        "cc_starlark_library = rule(",
        "    implementation = _cc_starlark_library_impl,",
        "    attrs = {",
        "      'object1': attr.label(allow_single_file=True),",
        "      'pic_object1': attr.label(allow_single_file=True),",
        "      'object2': attr.label(allow_single_file=True),",
        "      'pic_object2': attr.label(allow_single_file=True),",
        "    },",
        ")");
  }

  private static void createCcBinRule(Scratch scratch, String... additionalLines) throws Exception {
    String fragments = "    fragments = ['google_cpp', 'cpp'],";
    if (AnalysisMock.get().isThisBazel()) {
      fragments = "    fragments = ['cpp'],";
    }
    scratch.overwriteFile("tools/build_defs/BUILD");
    /*scratch.overwriteFile("tools/cpp/grep-includes");*/
    scratch.overwriteFile("tools/cpp/grep_includes/grep-includes.sh");
    scratch.appendFile(
        "tools/cpp/grep_includes/BUILD",
        "sh_binary(",
        "    name = 'grep-includes',",
        "    srcs = ['grep-includes.sh'],",
        ")");
    scratch.file(
        "tools/build_defs/extension.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _cc_bin_impl(ctx):",
        "    toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "    feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "    )",
        "    dep_linking_contexts = []",
        "    for dep in ctx.attr.deps:",
        "        dep_linking_contexts.append(dep[CcInfo].linking_context)",
        "    objects = cc_common.create_compilation_outputs(objects=depset(ctx.files.objects),",
        "        pic_objects=depset(ctx.files.pic_objects))",
        "    foo_dict = {'string_variable': 'foo',",
        "            'string_sequence_variable' : ['foo'],",
        "            'string_depset_variable': depset(['foo'])}",
        "    linking_outputs = cc_common.link(",
        "        actions=ctx.actions,",
        "        feature_configuration=feature_configuration,",
        "        name = ctx.label.name,",
        "        cc_toolchain=toolchain,",
        "        " + Joiner.on(",\n        ").join(additionalLines),
        "    )",
        "    return [",
        "      MyInfo(",
        "          library=linking_outputs.library_to_link,",
        "          executable=linking_outputs.executable",
        "      ),",
        "    ]",
        "cc_bin = rule(",
        "    implementation = _cc_bin_impl,",
        "    attrs = {",
        "      'objects': attr.label_list(allow_files=True),",
        "      'pic_objects': attr.label_list(allow_files=True),",
        "      'deps': attr.label_list(),",
        "      '_cc_toolchain': attr.label(default =",
        "          configuration_field(fragment = 'cpp', name = 'cc_toolchain')),",
        "      '_grep_includes': attr.label(",
        "             executable = True,",
        "             default = Label('//tools/cpp/grep_includes:grep-includes'),",
        "             cfg = 'host'",
        "       ),",
        "      'additional_outputs': attr.output_list(),",
        "    },",
        fragments,
        ")");
  }

  private static void setupTestTransitiveLink(Scratch scratch, String... additionalLines)
      throws Exception {
    createCcBinRule(scratch, additionalLines);
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs:extension.bzl', 'cc_bin')",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = ['dep1.cc'],",
        "    linkstamp = 'version.cc',",
        "    hdrs = ['dep1.h'],",
        "    includes = ['dep1/baz'],",
        "    defines = ['DEP1'],",
        ")",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = ['dep2.cc'],",
        "    hdrs = ['dep2.h'],",
        "    includes = ['dep2/qux'],",
        "    defines = ['DEP2'],",
        ")",
        "cc_bin(",
        "    name = 'bin',",
        "    objects = ['file.o'],",
        "    pic_objects = ['file.pic.o'],",
        "    deps = [':dep1', ':dep2'],",
        ")");
  }

  private static void setupDirectHeaderExtractionSupport(Scratch scratch) throws Exception {
    scratch.file(
        "direct/cc_info_extractor.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _cc_info_extractor_impl(ctx):",
        "    compilation_context = ctx.attr.dep[CcInfo].compilation_context",
        "    return [MyInfo(",
        "        direct_headers = compilation_context.direct_headers,",
        "        direct_public_headers = compilation_context.direct_public_headers,",
        "        direct_private_headers = compilation_context.direct_private_headers,",
        "        direct_textual_headers = compilation_context.direct_textual_headers,",
        "    )]",
        "cc_info_extractor = rule(",
        "    _cc_info_extractor_impl,",
        "    attrs = {",
        "        'dep': attr.label(providers = [[CcInfo]]),",
        "    }",
        ")");
    scratch.file(
        "direct/BUILD",
        "load('//direct:cc_info_extractor.bzl', 'cc_info_extractor')",
        "cc_info_extractor(",
        "    name = 'foo',",
        "    dep = '//direct/libs:foo_lib',",
        ")",
        "cc_info_extractor(",
        "    name = 'bar',",
        "    dep = '//direct/libs:bar_lib',",
        ")");
  }

  private static void setupCcLibraryDirectPropagationTestTargets(Scratch scratch) throws Exception {
    scratch.file(
        "direct/libs/BUILD",
        "cc_library(",
        "    name = 'foo_lib',",
        "    srcs = ['foo.cc', 'foo_impl.h'],",
        "    hdrs = ['foo.h'],",
        "    textual_hdrs = ['foo.def'],",
        ")",
        "cc_library(",
        "    name = 'bar_lib',",
        "    hdrs = ['bar.h'],",
        "    textual_hdrs = ['bar.def'],",
        "    deps = [':foo_lib'],",
        ")");
  }

  @Test
  public void testCcLibraryPropagatesCcInfoWithDirectHeaders() throws Exception {
    setupDirectHeaderExtractionSupport(scratch);
    setupCcLibraryDirectPropagationTestTargets(scratch);

    ConfiguredTarget fooTarget = getConfiguredTarget("//direct:foo");
    Iterable<Artifact> fooDirectHeaders = getArtifactsFromMyInfo(fooTarget, "direct_headers");
    assertThat(baseArtifactNames(fooDirectHeaders)).containsExactly("foo.h", "foo_impl.h");

    Iterable<Artifact> fooDirectPublicHeaders =
        getArtifactsFromMyInfo(fooTarget, "direct_public_headers");
    assertThat(baseArtifactNames(fooDirectPublicHeaders)).containsExactly("foo.h");

    Iterable<Artifact> fooDirectPrivateHeaders =
        getArtifactsFromMyInfo(fooTarget, "direct_private_headers");
    assertThat(baseArtifactNames(fooDirectPrivateHeaders)).containsExactly("foo_impl.h");

    ConfiguredTarget barTarget = getConfiguredTarget("//direct:bar");
    Iterable<Artifact> barDirectHeaders = getArtifactsFromMyInfo(barTarget, "direct_headers");
    assertThat(baseArtifactNames(barDirectHeaders)).containsExactly("bar.h");

    Iterable<Artifact> barDirectPublicHeaders =
        getArtifactsFromMyInfo(barTarget, "direct_public_headers");
    assertThat(baseArtifactNames(barDirectPublicHeaders)).containsExactly("bar.h");

    Iterable<Artifact> barDirectPrivateHeaders =
        getArtifactsFromMyInfo(barTarget, "direct_private_headers");
    assertThat(barDirectPrivateHeaders).isEmpty();
  }

  @Test
  public void testCcLibraryPropagatesCcInfoWithDirectTextualHeaders() throws Exception {
    setupDirectHeaderExtractionSupport(scratch);
    setupCcLibraryDirectPropagationTestTargets(scratch);

    ConfiguredTarget fooTarget = getConfiguredTarget("//direct:foo");
    Iterable<Artifact> fooDirectTextualHeaders =
        getArtifactsFromMyInfo(fooTarget, "direct_textual_headers");
    assertThat(baseArtifactNames(fooDirectTextualHeaders)).containsExactly("foo.def");

    ConfiguredTarget barTarget = getConfiguredTarget("//direct:bar");
    Iterable<Artifact> barDirectTextualHeaders =
        getArtifactsFromMyInfo(barTarget, "direct_textual_headers");
    assertThat(baseArtifactNames(barDirectTextualHeaders)).containsExactly("bar.def");
  }

  /** Fixes #10580 */
  @Test
  public void testMixedLinkerInputsWithOwnerAndWithout() throws Exception {
    setBuildLanguageOptions("--noincompatible_require_linker_input_cc_api");
    setUpCcLinkingContextTest(false);
    scratch.file("foo/BUILD", "load(':rule.bzl', 'crule')", "crule(name='a')");
    scratch.file(
        "foo/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  linker_input = cc_common.create_linker_input(owner=ctx.label, user_link_flags=['-l'])",
        "  linking_context = cc_common.create_linking_context(",
        "     linker_inputs=depset([linker_input]))",
        "  linking_context = cc_common.create_linking_context(",
        "     libraries_to_link=[],)",
        "  cc_info = CcInfo(linking_context=linking_context)",
        "  if cc_info.linking_context.linker_inputs.to_list()[0] == linker_input:",
        "     pass",
        "  return [cc_info]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    assertThat(getConfiguredTarget("//foo:a")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void testMergeCcInfosWithDirects() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(MockCcSupport.HEADER_MODULES_FEATURES));

    scratch.file(
        "direct/cc_merger.bzl",
        "def _cc_merger_impl(ctx):",
        "    direct_cc_infos = [dep[CcInfo] for dep in ctx.attr.exports]",
        "    cc_infos = [dep[CcInfo] for dep in ctx.attr.deps]",
        "    return [cc_common.merge_cc_infos(",
        "        direct_cc_infos = direct_cc_infos,",
        "        cc_infos = cc_infos,",
        "    )]",
        "cc_merger = rule(",
        "    _cc_merger_impl,",
        "    attrs = {",
        "        'deps': attr.label_list(providers = [[CcInfo]]),",
        "        'exports': attr.label_list(providers = [[CcInfo]]),",
        "    }",
        ")");
    scratch.file(
        "direct/BUILD",
        "load('//direct:cc_merger.bzl', 'cc_merger')",
        "cc_library(",
        "    name = 'public1',",
        "    srcs = ['public1.cc', 'public1_impl.h'],",
        "    hdrs = ['public1.h'],",
        "    textual_hdrs = ['public1.inc'],",
        ")",
        "cc_library(",
        "    name = 'public2',",
        "    srcs = ['public2.cc', 'public2_impl.h'],",
        "    hdrs = ['public2.h'],",
        "    textual_hdrs = ['public2.inc'],",
        ")",
        "cc_library(",
        "    name = 'private',",
        "    srcs = ['private.cc', 'private_impl.h'],",
        "    hdrs = ['private.h'],",
        "    textual_hdrs = ['private.inc'],",
        ")",
        "cc_merger(",
        "    name = 'merge',",
        "    exports = [':public1', ':public2'],",
        "    deps = [':private'],",
        ")");

    ConfiguredTarget lib = getConfiguredTarget("//direct:merge");
    CcCompilationContext ccCompilationContext = lib.get(CcInfo.PROVIDER).getCcCompilationContext();
    assertThat(
            baseArtifactNames(
                ccCompilationContext.getExportingModuleMaps().stream()
                    .map(CppModuleMap::getArtifact)
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("public1.cppmap", "public2.cppmap");
    assertThat(baseArtifactNames(ccCompilationContext.getDirectPublicHdrs()))
        .containsExactly("public1.h", "public2.h");
    assertThat(baseArtifactNames(ccCompilationContext.getDirectPrivateHdrs()))
        .containsExactly("public1_impl.h", "public2_impl.h");
    assertThat(baseArtifactNames(ccCompilationContext.getTextualHdrs()))
        .containsExactly("public1.inc", "public2.inc");
  }

  @Test
  public void testMergeCompilationContexts() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(MockCcSupport.HEADER_MODULES_FEATURES));

    scratch.file(
        "direct/cc_merger.bzl",
        "def _cc_merger_impl(ctx):",
        "    compilation_contexts = [dep[CcInfo].compilation_context for dep in ctx.attr.deps]",
        "    merged_context = cc_common.merge_compilation_contexts(",
        "        compilation_contexts = compilation_contexts,",
        "    )",
        "    return [CcInfo(compilation_context = merged_context)]",
        "cc_merger = rule(",
        "    _cc_merger_impl,",
        "    attrs = {",
        "        'deps': attr.label_list(providers = [[CcInfo]]),",
        "    }",
        ")");
    scratch.file(
        "direct/BUILD",
        "load('//direct:cc_merger.bzl', 'cc_merger')",
        "cc_library(",
        "    name = 'public1',",
        "    srcs = ['public1.cc', 'public1_impl.h'],",
        "    hdrs = ['public1.h'],",
        "    textual_hdrs = ['public1.inc'],",
        ")",
        "cc_library(",
        "    name = 'public2',",
        "    srcs = ['public2.cc', 'public2_impl.h'],",
        "    hdrs = ['public2.h'],",
        "    textual_hdrs = ['public2.inc'],",
        ")",
        "cc_merger(",
        "    name = 'merge',",
        "    deps = [':public1', ':public2'],",
        ")");

    ConfiguredTarget lib = getConfiguredTarget("//direct:merge");
    CcCompilationContext ccCompilationContext = lib.get(CcInfo.PROVIDER).getCcCompilationContext();
    assertThat(
            baseArtifactNames(
                ccCompilationContext.getExportingModuleMaps().stream()
                    .map(CppModuleMap::getArtifact)
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("public1.cppmap", "public2.cppmap");
    assertThat(baseArtifactNames(ccCompilationContext.getDirectPublicHdrs()))
        .containsExactly("public1.h", "public2.h");
    assertThat(baseArtifactNames(ccCompilationContext.getDirectPrivateHdrs()))
        .containsExactly("public1_impl.h", "public2_impl.h");
    assertThat(baseArtifactNames(ccCompilationContext.getTextualHdrs()))
        .containsExactly("public1.inc", "public2.inc");
  }

  @Test
  public void testObjectFilesInCreateLibraryToLinkApiGuardedByFlag() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("foo_feature"));
    useConfiguration("--noexperimental_starlark_cc_import");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "      requested_features = ['foo_feature'])",
        "  cc_common.create_library_to_link(",
        "    actions=ctx.actions, feature_configuration=feature_configuration, ",
        "    cc_toolchain = toolchain, objects = [])",
        "  return CcInfo()",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp']",
        ")");
    checkError("//a:r", "Cannot use objects/pic_objects without --experimental_starlark_cc_import");
  }

  @Test
  public void testObjectFilesInCreateLibrary() throws Exception {
    setUpCcLinkingContextTest(true);
    scratch.file(
        "b/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "crule(name='import_objects',",
        "   static_library = 'lib.a',",
        "   pic_static_library = 'lib.pic.a',",
        "   objects = ['object.o'],",
        "   pic_objects = ['object.pic.o'],",
        ")");

    assertNoEvents();
    ConfiguredTarget lib = getConfiguredTarget("//b:import_objects");
    CcLinkingContext ccLinkingContext = lib.get(CcInfo.PROVIDER).getCcLinkingContext();
    ImmutableList<LibraryToLink> libraries =
        ccLinkingContext.getLinkerInputs().toList().stream()
            .flatMap(i -> i.getLibraries().stream())
            .collect(ImmutableList.toImmutableList());

    assertThat(
            baseArtifactNames(
                libraries.stream()
                    .flatMap(l -> l.getObjectFiles().stream())
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("object.o");
    assertThat(
            baseArtifactNames(
                libraries.stream()
                    .flatMap(l -> l.getPicObjectFiles().stream())
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("object.pic.o");
  }

  @Test
  public void testObjectFilesInCreateLibraryWithoutStaticLibrary() throws Exception {
    setUpCcLinkingContextTest(true);
    scratch.file(
        "b/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "crule(name='import_objects_no_lib',",
        "   objects = ['object.o'],",
        ")");

    checkError(
        "//b:import_objects_no_lib", "If you pass 'objects' you must also pass a 'static_library'");
  }

  @Test
  public void testObjectFilesInCreateLibraryWithoutPicStaticLibrary() throws Exception {
    setUpCcLinkingContextTest(true);
    scratch.file(
        "b/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "crule(name='import_objects_no_pic_lib',",
        "   pic_objects = ['object.pic.o'],",
        ")");

    checkError(
        "//b:import_objects_no_pic_lib",
        "If you pass 'pic_objects' you must also pass a 'pic_static_library'");
  }

  private void setupDebugPackageProviderTest(String fission) throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(CppRuleClasses.PER_OBJECT_DEBUG_INFO));
    useConfiguration(fission);
    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "    out = ctx.actions.declare_file(ctx.label.name)",
        "    ctx.actions.run_shell(",
        "        inputs = [ctx.executable.cc_binary],",
        "        tools = [],",
        "        outputs = [out],",
        "        command = 'cp %s %s' % (ctx.executable.cc_binary.path, out.path),",
        "    )",
        "    wrapped_defaultinfo = ctx.attr.cc_binary[DefaultInfo]",
        "    runfiles = ctx.runfiles(files = [out])",
        "    wrapped_default_runfiles = wrapped_defaultinfo.default_runfiles.files.to_list()",
        "    if ctx.executable.cc_binary in wrapped_default_runfiles:",
        "        wrapped_default_runfiles.remove(ctx.executable.cc_binary)",
        "    result = [",
        "        DefaultInfo(",
        "            executable = out,",
        "            files = depset([out]),",
        "            runfiles = runfiles.merge(ctx.runfiles(files = wrapped_default_runfiles)),",
        "        ),",
        "    ]",
        "    if ctx.file.stripped_file:",
        "        wrapped_dbginfo = ctx.attr.cc_binary[DebugPackageInfo]",
        "        result.append(",
        "            DebugPackageInfo(",
        "                target_label = ctx.label,",
        "                stripped_file = ctx.file.stripped_file \\",
        "                                if wrapped_dbginfo.stripped_file else None,",
        "                unstripped_file = out,",
        "                dwp_file = ctx.file.dwp_file if wrapped_dbginfo.dwp_file else None,",
        "            ),",
        "        )",
        "    return result",
        "wrapped_binary = rule(",
        "    _impl,",
        "    attrs = {",
        "        'cc_binary': attr.label(",
        "            allow_single_file = True,",
        "            mandatory = True,",
        "            executable = True,",
        "            cfg = 'target',",
        "        ),",
        "        'stripped_file': attr.label(",
        "            allow_single_file = True,",
        "            default = None,",
        "        ),",
        "        'dwp_file': attr.label(",
        "            allow_single_file = True,",
        "            default = None,",
        "        )",
        "    },",
        "    executable = True,",
        ")");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'wrapped_binary')",
        "wrapped_binary(name = 'w',",
        "    cc_binary = ':native_binary',",
        "    stripped_file = ':w.stripped',",
        "    dwp_file = ':w.dwp',",
        ")",
        "wrapped_binary(name = 'w.stripped',",
        "    cc_binary = ':native_binary.stripped'",
        ")",
        "wrapped_binary(name = 'w.dwp',",
        "    cc_binary = ':native_binary.dwp'",
        ")",
        "cc_binary(name = 'native_binary',",
        "    srcs = ['main.cc']",
        ")");
    scratch.file("a/main.cc", "int main() {}");
  }

  @Test
  public void testDebugPackageProviderFissionDisabled() throws Exception {
    setupDebugPackageProviderTest("--fission=no");
    ConfiguredTarget target = getConfiguredTarget("//a:w");
    assertNoEvents();
    assertThat(target).isNotNull();
    DebugPackageProvider debugPackageProvider = target.get(DebugPackageProvider.PROVIDER);
    assertThat(debugPackageProvider.getStrippedArtifact().getFilename()).isEqualTo("w.stripped");
    assertThat(debugPackageProvider.getUnstrippedArtifact().getFilename()).isEqualTo("w");
    assertThat(debugPackageProvider.getDwpArtifact()).isNull();
  }

  @Test
  public void testDebugPackageProviderFissionEnabled() throws Exception {
    setupDebugPackageProviderTest("--fission=yes");
    ConfiguredTarget target = getConfiguredTarget("//a:w");
    assertNoEvents();
    assertThat(target).isNotNull();
    DebugPackageProvider debugPackageProvider = target.get(DebugPackageProvider.PROVIDER);
    assertThat(debugPackageProvider.getStrippedArtifact().getFilename()).isEqualTo("w.stripped");
    assertThat(debugPackageProvider.getUnstrippedArtifact().getFilename()).isEqualTo("w");
    assertThat(debugPackageProvider.getDwpArtifact().getFilename()).isEqualTo("w.dwp");
  }

  @Test
  public void testCcDebugContextDisabled() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//my_rules:rule.bzl', 'cc_compile_rule')",
        "cc_compile_rule(",
        "  name='b_lib',",
        "  srcs = ['b_lib.cc'],",
        ")");
    scratch.file("my_rules/BUILD");
    scratch.file(
        "my_rules/rule.bzl",
        "def _impl(ctx):",
        "  comp_context = cc_common.create_compilation_context()",
        "  comp_outputs = cc_common.create_compilation_outputs()",
        "  debug_info = cc_common.create_debug_context(comp_outputs)",
        "  return [CcInfo(compilation_context = comp_context, debug_info = debug_info)]",
        "cc_compile_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "  },",
        ")");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:b_lib"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
  }

  @Test
  public void testCcDebugContext() throws Exception {
    useConfiguration("--fission=yes");
    scratch.file(
        "b/BUILD",
        "load('//bazel_internal/test_rules/cc:rule.bzl', 'cc_compile_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_compile_rule(",
        "  name='b_lib',",
        "  srcs = ['b_lib.cc'],",
        ")");
    scratch.file("bazel_internal/test_rules/cc/BUILD");
    scratch.file(
        "bazel_internal/test_rules/cc/rule.bzl",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx=ctx,",
        "    cc_toolchain=toolchain,",
        "    requested_features=ctx.features + ['per_object_debug_info'],",
        "    unsupported_features=ctx.disabled_features)",
        "  (comp_context, comp_outputs) = cc_common.compile(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = toolchain,",
        "    srcs = ctx.files.srcs,",
        "  )",
        "  debug_info = cc_common.create_debug_context(comp_outputs)",
        "  return [CcInfo(compilation_context = comp_context, debug_context = debug_info)]",
        "cc_compile_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_cc_toolchain': attr.label(default=Label('//b:alias')),",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "  },",
        "  fragments = ['cpp'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//b:b_lib");
    assertThat(
            target
                .get(CcInfo.PROVIDER)
                .getCcDebugInfoContext()
                .getTransitiveDwoFiles()
                .toList()
                .stream()
                .map(Artifact::getFilename))
        .containsExactly("b_lib.dwo");
    assertThat(
            target.get(CcInfo.PROVIDER).getCcDebugInfoContext().getTransitivePicDwoFiles().toList())
        .isEmpty();
  }

  @Test
  public void testExpandedToolchainApiBlocked() throws Exception {
    List<String> toolchainCalls =
        ImmutableList.of(
            "toolchain.as_files()",
            "toolchain.ar_files()",
            "toolchain.objcopy_files()",
            "toolchain.tool_path(tool='ld')",
            "toolchain.solib_dir()",
            "toolchain.linker_files()",
            "toolchain.coverage_files()",
            "toolchain.strip_files()");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    for (String call : toolchainCalls) {
      scratch.overwriteFile(
          "a/rule.bzl",
          "CruleInfo = provider()",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  " + call,
          "  return [CruleInfo()]",
          "crule = rule(",
          "  _impl,",
          "  attrs = { ",
          "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ");");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//a:r"));
      assertThat(e).hasMessageThat().contains("cannot use private API");
    }
  }

  @Test
  public void testExpandedCompileApiBlocked() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load(':module_map.bzl', 'module_map')",
        "module_map(name='module_map', file = 'a_file.txt')");

    scratch.file(
        "bazel_internal/test_rules/cc/module_map.bzl",
        "ModuleMapInfo = provider(fields=['module_map', 'file'])",
        "def _impl(ctx):",
        "  module_map = cc_common.create_module_map(file=ctx.file.file,",
        "        umbrella_header=ctx.file.file, name='module')",
        "  return [ModuleMapInfo(module_map=module_map, file=ctx.file.file)]",
        "module_map = rule(",
        "  _impl,",
        "  attrs = { ",
        "    'file': attr.label(allow_single_file=True)",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    String compileCall =
        "cc_common.compile(actions = ctx.actions, feature_configuration = feature_configuration,"
            + " name = 'name', cc_toolchain = toolchain, ";
    List<String> calls =
        ImmutableList.of(
            "cc_common.create_module_map(file=file, umbrella_header=file, name='name')",
            "module_map.file()",
            "module_map.umbrella_header()",
            compileCall + " module_map = module_map)",
            compileCall + " additional_module_maps = [module_map])",
            compileCall + "additional_exported_hdrs = [])",
            compileCall + "propagate_module_map_to_compile_action = True)",
            compileCall + "do_not_generate_module_map = True)",
            compileCall + "code_coverage_enabled = True)",
            compileCall + "hdrs_checking_mode = 'strict')");
    scratch.overwriteFile(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r', deps=['//bazel_internal/test_rules/cc:module_map'])");

    for (String call : calls) {
      scratch.overwriteFile(
          "a/rule.bzl",
          "load('//bazel_internal/test_rules/cc:module_map.bzl', 'ModuleMapInfo')",
          "CruleInfo = provider()",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  module_map = ctx.attr.deps[0][ModuleMapInfo].module_map",
          "  file = ctx.attr.deps[0][ModuleMapInfo].file",
          "  " + call,
          "  return [CruleInfo()]",
          "crule = rule(",
          "  _impl,",
          "  attrs = { ",
          "    'deps': attr.label_list(),",
          "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ");");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//a:r"));
      assertThat(e).hasMessageThat().contains("cannot use private API");
    }
  }

  @Test
  public void testExpandedCcCompilationContextApiBlocked() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//my_rules:rule.bzl', 'method_rule', 'param_2_rule')",
        "param_2_rule(",
        "  name = 'p2',",
        ")",
        "method_rule(",
        "  name = 'm',",
        ")");
    scratch.file("my_rules/BUILD");
    scratch.file(
        "my_rules/rule.bzl",
        "def _m_impl(ctx):",
        "  comp_context = cc_common.create_compilation_context()",
        "  comp_context.transitive_compilation_prerequisites()",
        "  return [CcInfo(compilation_context = comp_context)]",
        "def _p2_impl(ctx):",
        "  comp_context = cc_common.create_compilation_context(purpose = 'testing')",
        "  return [CcInfo(compilation_context = comp_context)]",
        "method_rule = rule(",
        "  implementation = _m_impl,",
        ")",
        "param_2_rule = rule(",
        "  implementation = _p2_impl,",
        ")");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:m"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:p2"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
  }

  @Test
  public void testExpandedLinkApiRaisesError() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'link_rule')",
        "cc_toolchain_alias(name='alias')",
        "link_rule(name = 'foo')");
    String callFormatString =
        "cc_common.link(name='test', actions=ctx.actions,"
            + "feature_configuration=feature_configuration, cc_toolchain=toolchain, %s)";
    ImmutableList<String> calls =
        ImmutableList.of(
            String.format(callFormatString, "link_artifact_name_suffix='test'"),
            String.format(callFormatString, "never_link=False"),
            String.format(callFormatString, "test_only_target=False"),
            String.format(callFormatString, "always_link=False"),
            String.format(callFormatString, "additional_linkstamp_defines=[]"),
            String.format(callFormatString, "whole_archive=False"),
            String.format(callFormatString, "native_deps=False"),
            String.format(callFormatString, "only_for_dynamic_libs=False"));
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  " + call,
          "  return [DefaultInfo()]",
          "link_rule = rule(",
          "  implementation = _impl,",
          "  attrs = {",
          "    '_cc_toolchain': attr.label(default=Label('//b:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testExpandedCcCompilationOutputsApiRaisesError() throws Exception {
    scratch.file("b/BUILD", "load('//b:rule.bzl', 'cc_rule')", "cc_rule(", "  name='foo',", ")");
    ImmutableList<String> calls =
        ImmutableList.of(
            "comp_outputs.temps()",
            "comp_outputs.files_to_compile(parse_headers=False, use_pic=True)",
            "comp_outputs.header_tokens()");
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "def _impl(ctx):",
          "  comp_outputs = cc_common.create_compilation_outputs()",
          "  " + call,
          "  return [DefaultInfo()]",
          "cc_rule = rule(",
          "  implementation = _impl,",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testExpandedLtoAndFdoApiRaisesError() throws Exception {
    useConfiguration("--fdo_optimize=pkg/profile.afdo", "--compilation_mode=opt");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load(':lto_backend_artifacts.bzl', 'lto_backend_artifacts')",
        "lto_backend_artifacts(name='lto_backend_artifacts', file = 'a_file.txt')");

    scratch.file(
        "bazel_internal/test_rules/cc/lto_backend_artifacts.bzl",
        "LtoBackendArtifactsInfo = provider(fields=['lto_backend_artifacts',",
        "                                              'fdo_context', 'branch_fdo_profile'])",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  fdo_context = toolchain.fdo_context()",
        "  branch_fdo_profile = fdo_context.branch_fdo_profile()",
        "  lto_backend_artifacts = cc_common.create_lto_backend_artifacts(ctx=ctx,",
        "        lto_output_root_prefix=ctx.label.package, bitcode_file=ctx.file.file,",
        "        feature_configuration=feature_configuration, cc_toolchain=toolchain,",
        "        fdo_context=fdo_context, use_pic=True,",
        "        should_create_per_object_debug_info=False, argv=[])",
        "  return [LtoBackendArtifactsInfo(lto_backend_artifacts=lto_backend_artifacts,",
        "          fdo_context=fdo_context, branch_fdo_profile=branch_fdo_profile)]",
        "lto_backend_artifacts = rule(",
        "  _impl,",
        "  attrs = { ",
        "    'file': attr.label(allow_single_file=True),",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ImmutableList<String> calls =
        ImmutableList.of(
            "toolchain.fdo_context()",
            "library_to_link.shared_non_lto_backends()",
            "library_to_link.pic_shared_non_lto_backends()",
            "lto_backend_artifacts_info.lto_backend_artifacts.object_file()",
            "lto_backend_artifacts_info.fdo_context.branch_fdo_profile()",
            "lto_backend_artifacts_info.branch_fdo_profile.auto_fdo()",
            "lto_backend_artifacts_info.branch_fdo_profile.auto_xbinary_fdo()",
            "lto_backend_artifacts_info.branch_fdo_profile.llvm_fdo()",
            "lto_backend_artifacts_info.branch_fdo_profile.llvm_cs_fdo()");
    scratch.overwriteFile(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "cc_library(name='clib', srcs=['clib.cc'], hdrs=['clib.h'])",
        "crule(name='r', lto_dep='//bazel_internal/test_rules/cc:lto_backend_artifacts',",
        "      cc_dep=':clib')");

    for (String call : calls) {
      scratch.overwriteFile(
          "a/rule.bzl",
          "load('//bazel_internal/test_rules/cc:lto_backend_artifacts.bzl',",
          "             'LtoBackendArtifactsInfo')",
          "CruleInfo = provider()",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  library_to_link = (ctx.attr.cc_dep[CcInfo].linking_context",
          "                                     .linker_inputs.to_list()[0].libraries[0])",
          "  lto_backend_artifacts_info = ctx.attr.lto_dep[LtoBackendArtifactsInfo]",
          "  " + call,
          "  return [CruleInfo()]",
          "crule = rule(",
          "  _impl,",
          "  attrs = { ",
          "    'lto_dep': attr.label(),",
          "    'cc_dep': attr.label(),",
          "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ");");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//a:r"));
      assertThat(e).hasMessageThat().contains("cannot use private API");
    }
  }

  @Test
  public void testExpandedLibraryToLinkApiRaisesError() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo', cc_dep=':cc_dep')");
    ImmutableList<String> calls =
        ImmutableList.of(
            "cc_common.create_library_to_link(actions=ctx.actions,"
                + "feature_configuration=feature_configuration, cc_toolchain=toolchain,"
                + " must_keep_debug=False)",
            "library_to_link.must_keep_debug()");
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  library_to_link = (ctx.attr.cc_dep[CcInfo].linking_context",
          "                                     .linker_inputs.to_list()[0].libraries[0])",
          "  " + call,
          "  return [DefaultInfo()]",
          "cc_rule = rule(",
          "  implementation = _impl,",
          "  attrs = { ",
          "    'cc_dep': attr.label(),",
          "    '_cc_toolchain': attr.label(default=Label('//b:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testExpandedLinkstampApiRaisesError() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load(':linkstamps.bzl', 'linkstamps')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'], linkstamp='stamp.cc')",
        "linkstamps(name='linkstamps', deps = [':cc_dep'])");

    scratch.file(
        "bazel_internal/test_rules/cc/linkstamps.bzl",
        "LinkstampsInfo = provider(fields=['linkstamps'])",
        "def _impl(ctx):",
        "  linkstamps = ctx.attr.deps[0][CcInfo].linking_context.linkstamps().to_list()",
        "  return [LinkstampsInfo(linkstamps=linkstamps)]",
        "linkstamps = rule(",
        "  _impl,",
        "  attrs = { ",
        "    'deps': attr.label_list(),",
        "  },",
        ");");

    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo', cc_dep=':cc_dep',",
        "        file='file.cc',",
        "        linkstamps_dep='//bazel_internal/test_rules/cc:linkstamps')");
    scratch.appendFile(
        "tools/cpp/grep_includes/BUILD",
        "sh_binary(",
        "    name = 'grep-includes',",
        "    srcs = ['grep-includes.sh'],",
        ")");
    List<String> calls =
        new ArrayList<>(
            Arrays.asList("linkstamp.file()", "linkstamp.hdrs()", "linking_context.linkstamps()"));
    if (!analysisMock.isThisBazel()) {
      calls.add(
          "cc_common.register_linkstamp_compile_action(actions=ctx.actions,cc_toolchain=toolchain,"
              + " feature_configuration=feature_configuration, "
              + " grep_includes=ctx.executable._grep_includes, source_file=file, output_file=file,"
              + " compilation_inputs=depset([]), inputs_for_validation=depset([]),"
              + " label_replacement='', output_replacement='')");
    }
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "load('//bazel_internal/test_rules/cc:linkstamps.bzl',",
          "             'LinkstampsInfo')",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  linkstamp = ctx.attr.linkstamps_dep[LinkstampsInfo].linkstamps[0]",
          "  linking_context = ctx.attr.cc_dep[CcInfo].linking_context",
          "  file = ctx.file.file",
          "  " + call,
          "  return [DefaultInfo()]",
          "cc_rule = rule(",
          "  implementation = _impl,",
          "  attrs = { ",
          "    'cc_dep': attr.label(),",
          "    'linkstamps_dep': attr.label(),",
          "    '_cc_toolchain': attr.label(default=Label('//b:alias')),",
          "    'file': attr.label(allow_single_file=True),",
          "    '_grep_includes': attr.label(",
          "          executable = True,",
          "          default = Label('//tools/cpp/grep_includes:grep-includes'),",
          "          cfg = 'host'",
          "    ),",
          "  },",
          "  fragments = ['cpp'],",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testExtraLinkTimeLibraryApiRaisesError() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_rule(name='foo', cc_dep=':cc_dep')");
    ImmutableList<String> calls =
        ImmutableList.of(
            "cc_common.create_linking_context(linker_inputs=depset([]), go_link_c_archive=None)",
            "linking_context.go_link_c_archive()");
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "def _impl(ctx):",
          "  linking_context = ctx.attr.cc_dep[CcInfo].linking_context",
          "  " + call,
          "  return [DefaultInfo()]",
          "cc_rule = rule(",
          "  implementation = _impl,",
          "  attrs = { ",
          "    'cc_dep': attr.label(),",
          "  },",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testVariableExtensionCompileApi() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "variables_extension = foo_dict");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));

    action.getCompileCommandLine().getVariables().getSequenceVariable("string_sequence_variable");
    action.getCompileCommandLine().getVariables().getStringVariable("string_variable");
    action.getCompileCommandLine().getVariables().getSequenceVariable("string_depset_variable");
  }

  @Test
  public void testVariableExtensionLinkingContextApi() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", "variables_extension = foo_dict");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CppLinkAction action =
        (CppLinkAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".a"));

    action.getLinkCommandLine().getBuildVariables().getSequenceVariable("string_sequence_variable");
    action.getLinkCommandLine().getBuildVariables().getStringVariable("string_variable");
    action.getLinkCommandLine().getBuildVariables().getSequenceVariable("string_depset_variable");
  }

  @Test
  public void testVariableExtensionLinkApi() throws Exception {
    setupTestTransitiveLink(
        scratch, "output_type = 'executable'", "variables_extension = foo_dict");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    CppLinkAction action =
        (CppLinkAction)
            getGeneratingAction((Artifact) getMyInfoFromTarget(target).getValue("executable"));

    action.getLinkCommandLine().getBuildVariables().getSequenceVariable("string_sequence_variable");
    action.getLinkCommandLine().getBuildVariables().getStringVariable("string_variable");
    action.getLinkCommandLine().getBuildVariables().getSequenceVariable("string_depset_variable");
  }

  @Test
  public void testVariablesExtensionInvalidValueTypesThrowsError() throws Exception {
    String rulePkg = "b";
    scratch.overwriteFile(rulePkg + "/BUILD", "");
    scratch.overwriteFile(
        "b/BUILD",
        "load('//" + rulePkg + ":rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo', cc_dep=':cc_dep')");
    for (String value : ImmutableList.of("1", "[1]", "depset([1])")) {
      scratch.overwriteFile(
          rulePkg + "/rule.bzl",
          getVariablesExtensionStarlarkRule("compile", "dict = {'variable': " + value + "}"));
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Trying to build UserVariableExtension");
    }
  }

  @Test
  public void testAdditionalLinkingOutputsAppearAsOutputsOfLinkAction() throws Exception {
    createCcBinRule(scratch, "additional_outputs=ctx.outputs.additional_outputs");
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs:extension.bzl', 'cc_bin')",
        "cc_bin(",
        "    name = 'bin',",
        "    objects = ['file.o'],",
        "    pic_objects = ['file.pic.o'],",
        "    additional_outputs = [':bin.map'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    CppLinkAction action =
        (CppLinkAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".map"));
    assertThat(artifactsToStrings(action.getOutputs())).contains("bin foo/bin.map");
  }

  private String getVariablesExtensionStarlarkRule(String call, String dictionaryEntries) {
    return Joiner.on("\n")
        .join(
            "def _impl(ctx):",
            "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
            "  feature_configuration = cc_common.configure_features(",
            "      ctx = ctx,",
            "      cc_toolchain = toolchain,",
            "      requested_features = ctx.features,",
            "      unsupported_features = ctx.disabled_features,",
            "  )",
            "  " + dictionaryEntries,
            "  cc_common." + call + "(",
            "      actions = ctx.actions,",
            "      feature_configuration = feature_configuration,",
            "      cc_toolchain = toolchain,",
            "      name = ctx.label.name + '_aspect',",
            "      variables_extension = dict,",
            "  )",
            "  return [DefaultInfo()]",
            "cc_rule = rule(",
            "  implementation = _impl,",
            "  attrs = { ",
            "    'cc_dep': attr.label(),",
            "    '_cc_toolchain': attr.label(default=Label('//b:alias'))",
            "  },",
            "  fragments = ['cpp'],",
            ")");
  }

  @Test
  public void testBuildInfoArtifacts() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/rule.bzl",
        "def _impl(ctx):",
        "  artifacts = cc_common.get_build_info(ctx)",
        "  return [DefaultInfo(files = depset(artifacts))]",
        "build_info_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'stamp': attr.int()},",
        ")");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load(':rule.bzl', 'build_info_rule')",
        "build_info_rule(name = 'stamped', stamp = 1,)",
        "build_info_rule(name = 'unstamped', stamp = 0,)");
    assertThat(
            prettyArtifactNames(
                getConfiguredTarget("//bazel_internal/test_rules/cc:stamped")
                    .getProvider(FileProvider.class)
                    .getFilesToBuild()))
        .containsExactly("build-info-nonvolatile.h", "build-info-volatile.h");
    assertThat(
            prettyArtifactNames(
                getConfiguredTarget("//bazel_internal/test_rules/cc:unstamped")
                    .getProvider(FileProvider.class)
                    .getFilesToBuild()))
        .containsExactly("build-info-redacted.h");
  }

  @Test
  public void testGetLauncherProviderIsPrivateAPI() throws Exception {
    scratch.file(
        "foo/rule.bzl",
        "def _impl(ctx):",
        "  cc_common.launcher_provider()",
        "  return []",
        "build_info_rule = rule(implementation = _impl,)");
    scratch.file(
        "foo/BUILD",
        //
        "load(':rule.bzl', 'build_info_rule')",
        "build_info_rule(name = 'bar',)");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:bar"));
    assertThat(e).hasMessageThat().contains("Rule in 'foo' cannot use private API");
  }

  @Test
  public void testCreateStripActionIsPrivateAPI() throws Exception {
    scratch.file(
        "foo/rule.bzl",
        "def _impl(ctx):",
        "  toolchain = ctx.attr.cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "      requested_features = ctx.features,",
        "      unsupported_features = ctx.disabled_features,",
        "  )",
        "  cc_common.strip(",
        "    ctx = ctx,",
        "    toolchain = toolchain,",
        "    input = ctx.actions.declare_file('in'),",
        "    output = ctx.actions.declare_file('out'),",
        "    feature_configuration = feature_configuration",
        "  )",
        "  return []",
        "strip_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'cc_toolchain' : attr.label()},",
        "  fragments= ['cpp']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':rule.bzl', 'strip_rule')",
        "",
        "cc_toolchain_alias(name = 'tc')",
        "strip_rule(",
        "  name = 'bar',",
        "  cc_toolchain = ':tc',",
        ")");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:bar"));
    assertThat(e).hasMessageThat().contains("Rule in 'foo' cannot use private API");
  }

  @Test
  public void testMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink()
      throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'cc_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo')");

    runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
        "None,", "feature_configuration,", "ctx.file._artifact,", "None,");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
    assertThat(e)
        .hasMessageThat()
        .contains("If you pass 'dynamic_library', you must also pass a 'cc_toolchain'");

    runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
        "toolchain,", "None,", "ctx.file._artifact,", "None,");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
    assertThat(e)
        .hasMessageThat()
        .contains("If you pass 'dynamic_library', you must also pass a 'feature_configuration'");

    runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
        "None,", "feature_configuration,", "None,", "ctx.file._artifact,");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
    assertThat(e)
        .hasMessageThat()
        .contains("If you pass 'interface_library', you must also pass a 'cc_toolchain'");

    runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
        "toolchain,", "None,", "None,", "ctx.file._artifact,");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
    assertThat(e)
        .hasMessageThat()
        .contains("If you pass 'interface_library', you must also pass a 'feature_configuration'");
  }

  private void runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
      String toolchain, String featureConfiguration, String dynamicLibrary, String interfaceLibrary)
      throws Exception {
    scratch.overwriteFile(
        "b/rule.bzl",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  cc_common.create_library_to_link(",
        "    actions=ctx.actions, ",
        "    cc_toolchain = " + toolchain,
        "    feature_configuration = " + featureConfiguration,
        "    dynamic_library =" + dynamicLibrary,
        "    interface_library =" + interfaceLibrary,
        "  )",
        "  return [DefaultInfo()]",
        "cc_rule = rule(",
        "  implementation = _impl,",
        "  attrs = { ",
        "    '_artifact': attr.label(allow_single_file=True, default=Label('//b:foo.soifso')),",
        "    '_cc_toolchain': attr.label(default=Label('//b:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();
  }

  @Test
  public void testCcInternalIsNotAccessibleFromOutsideBuiltins() throws Exception {
    scratch.file("a/BUILD", "load(':rule.bzl', 'crule')", "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "  cc_internal",
        "  return DefaultInfo()",
        "crule = rule(",
        "  _impl,",
        ")");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//a:r"));
    assertThat(e).hasMessageThat().contains("name 'cc_internal' is not defined");
  }
}
