// Copyright 2023 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.analysis;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.rules.cpp.CppRuleClasses.CPP_LINK_EXEC_GROUP;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ObjectArrays;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.analysis.actions.LazyWritePathsFileAction;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.config.ToolchainTypeRequirement;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.ExecGroup;
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.rules.cpp.CppCompileAction;
import com.google.devtools.build.lib.rules.cpp.CppLinkAction;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
import com.google.devtools.build.lib.rules.java.JavaGenJarsProvider;
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
import java.util.regex.Pattern;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Test for automatic exec groups. */
@RunWith(TestParameterInjector.class)
public class AutoExecGroupsTest extends BuildViewTestCase {
  /**
   * Sets up two toolchains types, each with a single toolchain implementation and a single
   * exec_compatible_with platform.
   *
   * <p>toolchain_type_1 -> foo_toolchain -> exec_compatible_with platform_1 toolchain_type_2 ->
   * bar_toolchain -> exec_compatible_with platform_2
   */
  @Before
  public void createToolchainsAndPlatforms() throws Exception {
    scratch.file(
        "rule/test_toolchain.bzl",
        "def _impl(ctx):",
        "    return [platform_common.ToolchainInfo(",
        "      tool = ctx.executable._tool,",
        "      files_to_run = ctx.attr._tool[DefaultInfo].files_to_run,",
        "    )]",
        "test_toolchain = rule(",
        "    implementation = _impl,",
        "    attrs = {",
        "       '_tool': attr.label(default='//toolchain:b_tool', executable=True, cfg='exec'),",
        "    },",
        ")");
    scratch.file(
        "rule/BUILD",
        "exports_files(['test_toolchain/bzl'])",
        "toolchain_type(name = 'toolchain_type_1')",
        "toolchain_type(name = 'toolchain_type_2')",
        "java_runtime(",
        "    name = 'jvm-k8',",
        "    srcs = [",
        "        'k8/a', ",
        "        'k8/b',",
        "    ], ",
        "    java_home = 'k8',",
        ")");
    scratch.file(
        "toolchain/BUILD",
        "load('//rule:test_toolchain.bzl', 'test_toolchain')",
        "genrule(name = 'a_tool', outs = ['atool'], cmd = '', executable = True)",
        "genrule(name = 'b_tool', outs = ['btool'], cmd = '', executable = True)",
        "test_toolchain(",
        "    name = 'foo',",
        ")",
        "toolchain(",
        "    name = 'foo_toolchain',",
        "    toolchain_type = '//rule:toolchain_type_1',",
        "    target_compatible_with = ['//platforms:constraint_1'],",
        "    exec_compatible_with = ['//platforms:constraint_1'],",
        "    toolchain = ':foo',",
        ")",
        "test_toolchain(",
        "    name = 'bar',",
        ")",
        "toolchain(",
        "    name = 'bar_toolchain',",
        "    toolchain_type = '//rule:toolchain_type_2',",
        "    target_compatible_with = ['//platforms:constraint_1'],",
        "    exec_compatible_with = ['//platforms:constraint_2'],",
        "    toolchain = ':bar',",
        ")");

    scratch.file(
        "platforms/BUILD",
        "constraint_setting(name = 'setting')",
        "constraint_value(",
        "    name = 'constraint_1',",
        "    constraint_setting = ':setting',",
        ")",
        "constraint_value(",
        "    name = 'constraint_2',",
        "    constraint_setting = ':setting',",
        ")",
        "platform(",
        "    name = 'platform_1',",
        "    constraint_values = [':constraint_1'],",
        ")",
        "platform(",
        "    name = 'platform_2',",
        "    constraint_values = [':constraint_2'],",
        "    exec_properties = {",
        "        'watermelon.ripeness': 'unripe',",
        "        'watermelon.color': 'red',",
        "    },",
        ")");
  }

  @Before
  public void setup() throws Exception {
    useConfiguration();
  }

  @Override
  public void useConfiguration(String... args) throws Exception {
    String[] flags = {
      "--extra_toolchains=//toolchain:foo_toolchain,//toolchain:bar_toolchain",
      "--platforms=//platforms:platform_1",
      "--extra_execution_platforms=//platforms:platform_1,//platforms:platform_2"
    };

    super.useConfiguration(ObjectArrays.concat(flags, args, String.class));
  }

  /**
   * Creates custom rule which produces action with `actionParameters`, adds `extraAttributes`,
   * defines `toolchains`, and adds custom exec groups from `execGroups`. Depending on
   * `actionRunCommand` parameter, `actions.run` or `actions.run_shell` is created.
   */
  private void createCustomRule(
      String action,
      String actionParameters,
      String extraAttributes,
      String toolchains,
      String execGroups,
      String execCompatibleWith)
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file(ctx.label.name + '_dummy_output.jar')",
        "  " + action + "(",
        actionParameters,
        "    outputs = [output_jar],",
        action.equals("ctx.actions.run")
            ? (actionParameters.contains("executable =") // avoid adding executable parameter twice
                ? ""
                : "executable = ctx.toolchains['//rule:toolchain_type_1'].tool,")
            : "    command = 'echo',",
        "  )",
        "  return [DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_tool': attr.label(default = '//toolchain:a_tool', cfg = 'exec', executable = True),",
        "    '_nonexecutable_tool': attr.label(default = '//toolchain:b_tool', cfg = 'exec'),",
        extraAttributes,
        "  },",
        "  exec_groups = {",
        execGroups,
        "  },",
        "  toolchains = " + toolchains + ",",
        execCompatibleWith,
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_disabledAndAttributeFalse_disabled(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "'_use_auto_exec_groups': attr.bool(default = False),",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableMap<String, ExecGroup> execGroups =
        getRuleContext(target).getExecGroups().execGroups();

    assertThat(execGroups).isEmpty();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_disabledAndAttributeTrue_enabled(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "'_use_auto_exec_groups': attr.bool(default = True),",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableMap<String, ExecGroup> execGroups =
        getRuleContext(target).getExecGroups().execGroups();

    assertThat(execGroups).isNotEmpty();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_disabledAndAttributeNotSet_disabled(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableMap<String, ExecGroup> execGroups =
        getRuleContext(target).getExecGroups().execGroups();

    assertThat(execGroups).isEmpty();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_enabledAndAttributeFalse_disabled(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "'_use_auto_exec_groups': attr.bool(default = False),",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableMap<String, ExecGroup> execGroups =
        getRuleContext(target).getExecGroups().execGroups();

    assertThat(execGroups).isEmpty();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_enabledAndAttributeTrue_enabled(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "'_use_auto_exec_groups': attr.bool(default = True)",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableMap<String, ExecGroup> execGroups =
        getRuleContext(target).getExecGroups().execGroups();

    assertThat(execGroups).isNotEmpty();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void automaticExecutionGroups_enabledAndAttributeNotSet_enabled(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableMap<String, ExecGroup> execGroups =
        getRuleContext(target).getExecGroups().execGroups();

    assertThat(execGroups).isNotEmpty();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void getToolchainInfoAndContext_automaticExecGroupsEnabled(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    RuleContext ruleContext = getRuleContext(target);
    ImmutableMap<ToolchainTypeInfo, ToolchainInfo> defaultExecGroupToolchains =
        ruleContext.getToolchainContext().toolchains();
    ToolchainInfo toolchainInfo =
        ruleContext.getToolchainInfo(Label.parseCanonical("//rule:toolchain_type_1"));

    assertThat(defaultExecGroupToolchains).isEmpty();
    assertThat(toolchainInfo).isNotNull();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void getToolchainInfoAndContext_automaticExecGroupsDisabled(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    RuleContext ruleContext = getRuleContext(target);
    ImmutableMap<ToolchainTypeInfo, ToolchainInfo> defaultExecGroupToolchains =
        ruleContext.getToolchainContext().toolchains();
    ToolchainInfo toolchainInfo =
        ruleContext.getToolchainInfo(Label.parseCanonical("//rule:toolchain_type_1"));

    assertThat(defaultExecGroupToolchains).isNotEmpty();
    assertThat(toolchainInfo).isNotNull();
  }

  @Test
  public void toolInExecutableIdentified_noToolchainParameter_noError() throws Exception {
    createCustomRule(
        /* action= */ "ctx.actions.run",
        /* actionParameters= */ "executable = ctx.executable._tool, ",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");

    assertNoEvents();
  }

  @Test
  public void toolWithFilesToRunExecutable_noToolchainParameter_reportsError() throws Exception {
    createCustomRule(
        /* action= */ "ctx.actions.run",
        /* actionParameters= */ "executable ="
            + " ctx.attr._nonexecutable_tool[DefaultInfo].files_to_run.executable,",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "Couldn't identify if tools are from implicit dependencies or a toolchain. Please set"
            + " the toolchain parameter. If you're not using a toolchain, set it to 'None'.");
  }

  @Test
  public void toolWithFilesToRunExecutable_toolchainParameterSetToNone_noError() throws Exception {
    createCustomRule(
        /* action= */ "ctx.actions.run",
        /* actionParameters= */ "toolchain = None,"
            + " executable = ctx.attr._nonexecutable_tool[DefaultInfo].files_to_run.executable,",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");

    assertNoEvents();
  }

  @Test
  public void toolInExecutableUnidentified_noToolchainParameter_reportsError() throws Exception {
    createCustomRule(
        /* action= */ "ctx.actions.run",
        /* actionParameters= */ "executable = ctx.toolchains['//rule:toolchain_type_1'].tool, ",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "Couldn't identify if tools are from implicit dependencies or a toolchain. Please set"
            + " the toolchain parameter. If you're not using a toolchain, set it to 'None'.");
  }

  @Test
  public void toolWithFilesToRunInExecutableUnidentified_noToolchainParameter_reportsError()
      throws Exception {
    createCustomRule(
        /* action= */ "ctx.actions.run",
        /* actionParameters= */ "executable ="
            + " ctx.toolchains['//rule:toolchain_type_1'].files_to_run, ",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "Couldn't identify if tools are from implicit dependencies or a toolchain. Please set"
            + " the toolchain parameter. If you're not using a toolchain, set it to 'None'.");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void toolInToolsUnidentified_noToolchainParameter_reportsError(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "tools = [ctx.toolchains['//rule:toolchain_type_1'].tool],",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "Couldn't identify if tools are from implicit dependencies or a toolchain. Please set"
            + " the toolchain parameter. If you're not using a toolchain, set it to 'None'.");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void toolWithFilesToRunInToolsUnidentified_noToolchainParameter_reportsError(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "tools = [ctx.toolchains['//rule:toolchain_type_1'].files_to_run],",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "Couldn't identify if tools are from implicit dependencies or a toolchain. Please set"
            + " the toolchain parameter. If you're not using a toolchain, set it to 'None'.");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void depsetInTools_noToolchainParameter_reportsError(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "tools = [depset([ctx.executable._tool])], ",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "Couldn't identify if tools are from implicit dependencies or a toolchain. Please set"
            + " the toolchain parameter. If you're not using a toolchain, set it to 'None'.");
  }

  @Test
  public void toolInExecutableUnidentified_toolchainParameter_noError() throws Exception {
    createCustomRule(
        /* action= */ "ctx.actions.run",
        /* actionParameters= */ "executable = ctx.toolchains['//rule:toolchain_type_1'].tool, "
            + "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");

    assertNoEvents();
  }

  @Test
  public void toolInExecutableUnidentified_toolchainParameterNone_noError() throws Exception {
    // Setting toolchain parameter that doesn't match what is used in the executable is technically
    // an error. However, we cannot detect this error at analysis time.
    // It's possible to construct a correct case where executable is from a provider from a
    // dependency that is not a toolchain (like proto_lang_toolchain). In this case the user should
    // set `toolchain = None` (because we wouldn't/couldn't detect where executable is coming from)
    createCustomRule(
        /* action= */ "ctx.actions.run",
        /* actionParameters= */ "executable = ctx.toolchains['//rule:toolchain_type_1'].tool, "
            + "toolchain = None,",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");

    assertNoEvents();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void twoToolchains_createTwoExecutionGroups(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ExecGroupCollection execGroups = getRuleContext(target).getExecGroups();

    assertThat(execGroups.execGroups().keySet())
        .containsExactly("//rule:toolchain_type_1", "//rule:toolchain_type_2");
    ExecGroup execGroupTT1 = execGroups.getExecGroup("//rule:toolchain_type_1");
    assertThat(execGroupTT1.toolchainTypes())
        .containsExactly(
            ToolchainTypeRequirement.create(Label.parseCanonical("//rule:toolchain_type_1")));
    assertThat(execGroupTT1.execCompatibleWith()).isEmpty();
    ExecGroup execGroupTT2 = execGroups.getExecGroup("//rule:toolchain_type_2");
    assertThat(execGroupTT2.toolchainTypes())
        .containsExactly(
            ToolchainTypeRequirement.create(Label.parseCanonical("//rule:toolchain_type_2")));
    assertThat(execGroupTT2.execCompatibleWith()).isEmpty();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void twoToolchains_threeToolchainContexts(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableSet<String> toolchainContextsKeys =
        getRuleContext(target).getToolchainContexts().getContextMap().keySet();

    assertThat(toolchainContextsKeys)
        .containsExactly(
            ExecGroup.DEFAULT_EXEC_GROUP_NAME,
            "//rule:toolchain_type_1",
            "//rule:toolchain_type_2");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void defaultExecGroupHasNoToolchains(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ResolvedToolchainContext defaultExecGroupContext =
        getRuleContext(target).getToolchainContexts().getDefaultToolchainContext();

    assertThat(defaultExecGroupContext).isNotNull();
    assertThat(defaultExecGroupContext.toolchainTypes()).isEmpty();
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void defaultExecGroupHasBasicExecutionPlatform(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ResolvedToolchainContext defaultExecGroupContext =
        getRuleContext(target).getToolchainContexts().getDefaultToolchainContext();

    assertThat(defaultExecGroupContext).isNotNull();
    assertThat(defaultExecGroupContext.executionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void toolchainParameterAsLabel_correctParsingOfToolchain(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = Label('@//rule:toolchain_type_1'),",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    Action generatedAction = getGeneratingAction(target, "test/custom_rule_name_dummy_output.jar");

    assertThat(generatedAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void toolchainParameterAsString_correctParsingOfToolchain(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '@//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    Action generatedAction = getGeneratingAction(target, "test/custom_rule_name_dummy_output.jar");

    assertThat(generatedAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void toolchainParameterAsString_syntaxErrorInParsingOfToolchain(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = 'rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "invalid label 'rule:toolchain_type_1': absolute label must begin with '@'" + " or '//'");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void independentExecPlatformForAction_toolchainType1(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    Action generatedAction = getGeneratingAction(target, "test/custom_rule_name_dummy_output.jar");

    assertThat(generatedAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void independentExecPlatformForAction_toolchainType2(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_2',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    Action generatedAction = getGeneratingAction(target, "test/custom_rule_name_dummy_output.jar");

    assertThat(generatedAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void actionWithTwoToolchains_automaticExecGroupsDisabled_error(String action)
      throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1', '//rule:toolchain_type_2']",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        Pattern.compile(
            "Unable to find an execution platform for toolchains \\[(//rule:toolchain_type_1,"
                + " //rule:toolchain_type_2)|(//rule:toolchain_type_2, //rule:toolchain_type_1)\\]"
                + " and target platform //platforms:platform_1 from available execution platforms"
                + " \\[//platforms:platform_1, //platforms:platform_2,"
                + " //third_party/local_config_platform:host\\]"));
  }

  @Test
  public void ctxToolchains_automaticExecGroupsEnabled() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  toolchain_info = ctx.toolchains['//rule:toolchain_type_1']",
        "  if toolchain_info == None:",
        "    fail('Toolchain info is None.')",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'dep': attr.label(cfg = 'exec'),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_1'],",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");

    assertNoEvents();
  }

  @Test
  public void ctxToolchains_automaticExecGroupsEnabled_wrongToolchainError() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  toolchain_info = ctx.toolchains['//rule:wrong_toolchain_type']",
        "  if toolchain_info == None:",
        "    fail('Toolchain info is None.')",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'dep': attr.label(cfg = 'exec'),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_1'],",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "In custom_rule rule //test:custom_rule_name, toolchain type //rule:wrong_toolchain_type"
            + " was requested but only types [//rule:toolchain_type_1] are configured");
  }

  @Test
  public void ctxToolchainsPrint_automaticExecGroupsEnabled() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  print(ctx.toolchains)",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'dep': attr.label(cfg = 'exec'),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_1'],",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent("<toolchain_context.resolved_labels: //rule:toolchain_type_1>");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void toolchainNotDefinedButUsedInAction(String action) throws Exception {
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ (action.equals("ctx.actions.run")
                ? "executable = ctx.executable._tool, "
                : "")
            + "toolchain = '//rule:toolchain_type_1',",
        /* extraAttributes= */ "",
        /* toolchains= */ "[]",
        /* execGroups= */ "",
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent("Action declared for non-existent toolchain '//rule:toolchain_type_1'");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void customExecGroupsAndToolchain(String action) throws Exception {
    String customExecGroups =
        "    'custom_exec_group': exec_group(\n"
            + "      exec_compatible_with = ['//platforms:constraint_1'],\n"
            + "      toolchains = ['//rule:toolchain_type_1'],\n"
            + "    ),\n";
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_1', "
            + "exec_group = 'custom_exec_group',",
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ customExecGroups,
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableMap<String, ExecGroup> execGroups =
        getRuleContext(target).getExecGroups().execGroups();
    Action generatedAction = getGeneratingAction(target, "test/custom_rule_name_dummy_output.jar");

    assertThat(execGroups.keySet()).containsExactly("//rule:toolchain_type_1", "custom_exec_group");
    assertThat(generatedAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void customExecGroups_execCompatibleWith(String action) throws Exception {
    String customExecGroups =
        "    'custom_exec_group': exec_group(\n"
            + "      exec_compatible_with = ['//platforms:constraint_1'],\n"
            + "      toolchains = ['//rule:toolchain_type_1'],\n"
            + "    ),\n";
    String executable =
        action.equals("ctx.actions.run") ? "executable = ctx.executable._tool," : "";
    String execCompatibleWith = "  exec_compatible_with = ['//platforms:constraint_1'],";
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "exec_group = 'custom_exec_group'," + executable,
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_1']",
        /* execGroups= */ customExecGroups,
        /* execCompatibleWith= */ execCompatibleWith);
    scratch.overwriteFile(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(",
        "  name = 'custom_rule_name',",
        "  exec_properties = {'custom_exec_group.mem': '64'}",
        ")");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    ImmutableMap<String, ExecGroup> execGroups =
        getRuleContext(target).getExecGroups().execGroups();
    Action ruleAction = (Action) ((RuleConfiguredTarget) target).getActions().get(0);

    assertThat(execGroups.keySet()).containsExactly("custom_exec_group", "//rule:toolchain_type_1");
    assertThat(execGroups.get("custom_exec_group").toolchainTypes())
        .containsExactly(
            ToolchainTypeRequirement.create(Label.parseCanonical("//rule:toolchain_type_1")));
    assertThat(execGroups.get("custom_exec_group").execCompatibleWith())
        .isEqualTo(ImmutableSet.of(Label.parseCanonical("//platforms:constraint_1")));
    assertThat(ruleAction.getOwner().getExecProperties()).containsExactly("mem", "64");
  }

  @Test
  @TestParameters({
    "{action: ctx.actions.run}",
    "{action: ctx.actions.run_shell}",
  })
  public void customExecGroupsAndToolchain_notCompatibleError(String action) throws Exception {
    String customExecGroups =
        "    'custom_exec_group': exec_group(\n"
            + "      exec_compatible_with = ['//platforms:constraint_1'],\n"
            + "      toolchains = ['//rule:toolchain_type_1'],\n"
            + "    ),\n";
    createCustomRule(
        /* action= */ action,
        /* actionParameters= */ "toolchain = '//rule:toolchain_type_2', "
            + "exec_group = 'custom_exec_group',"
            + (action.equals("ctx.actions.run")
                ? "executable = ctx.toolchains['//rule:toolchain_type_2'].tool, "
                : ""),
        /* extraAttributes= */ "",
        /* toolchains= */ "['//rule:toolchain_type_2']",
        /* execGroups= */ customExecGroups,
        /* execCompatibleWith= */ "");
    useConfiguration("--incompatible_auto_exec_groups");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//test:custom_rule_name");

    assertContainsEvent(
        "`toolchain` and `exec_group` parameters inside actions.{run, run_shell} are not"
            + " compatible; use one of them or define `toolchain` which is compatible with the"
            + " exec_group (already exists inside the `exec_group`)");
  }

  @Test
  public void
      javaCommonCompile_automaticExecGroupsEnabled_optimizationJarActionExecutesOnFirstPlatform()
          throws Exception {
    scratch.file(
        "java/com/google/optimizationtest/BUILD",
        "java_binary(",
        "    name = 'optimizer',",
        "    srcs = ['Foo.java'],",
        ")",
        "exports_files(['config.txt'])");
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "  )",
        "  return [DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_use_auto_exec_groups': attr.bool(default = True),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration(
        "--experimental_local_java_optimizations",
        "--experimental_bytecode_optimizers=Optimizer=//java/com/google/optimizationtest:optimizer",
        "--experimental_local_java_optimization_configuration=//java/com/google/optimizationtest:config.txt");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    Action action = getGeneratingAction(target, "test/lib_custom_rule_name.jar");

    assertThat(action.getMnemonic()).isEqualTo("Optimizer");
    assertThat(action.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void
      javaCommonCompile_automaticExecGroupsDisabled_optimizationJarActionExecutesOnSecondPlatform()
          throws Exception {
    scratch.file(
        "java/com/google/optimizationtest/BUILD",
        "java_binary(",
        "    name = 'optimizer',",
        "    srcs = ['Foo.java'],",
        ")",
        "exports_files(['config.txt'])");
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "  )",
        "  return [java_info, DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  provides = [JavaInfo],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration(
        "--experimental_local_java_optimizations",
        "--experimental_bytecode_optimizers=Optimizer=//java/com/google/optimizationtest:optimizer",
        "--experimental_local_java_optimization_configuration=//java/com/google/optimizationtest:config.txt");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    Action action = getGeneratingAction(target, "test/lib_custom_rule_name.jar");

    assertThat(action.getMnemonic()).isEqualTo("Optimizer");
    assertThat(action.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
  }

  @Test
  public void javaCommonCompile_automaticExecGroupsEnabled_outputActionExecutesOnFirstPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "  )",
        "  return [DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    Action action = getGeneratingAction(target, "test/lib_custom_rule_name.jar");

    assertThat(action.getMnemonic()).isEqualTo("Javac");
    assertThat(action.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void javaCommonCompile_automaticExecGroupsDisabled_outputActionExecutesOnSecondPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "  )",
        "  return [DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    Action action = getGeneratingAction(target, "test/lib_custom_rule_name.jar");

    assertThat(action.getMnemonic()).isEqualTo("Javac");
    assertThat(action.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
  }

  @Test
  public void javaCommonCompile_automaticExecGroupsEnabled_javaInfoActionsExecuteOnFirstPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "    plugins = [ctx.attr._plugins[JavaPluginInfo]],",
        "  )",
        "  return [java_info]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_plugins': attr.label(",
        "      default = Label('//test:test_plugin'),",
        "    ),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  provides = [JavaInfo],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "java_plugin(",
        "  name = 'test_plugin',",
        "  processor_class = 'GeneratedProcessor',",
        ")",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    JavaInfo javaInfo = (JavaInfo) target.get(JavaInfo.PROVIDER.getKey());
    Action genSrcOutputAction =
        getGeneratingAction(javaInfo.getOutputJars().getAllSrcOutputJars().get(0));
    JavaGenJarsProvider javaGenJarsProvider = javaInfo.getGenJarsProvider();
    Action genClassAction = getGeneratingAction(javaGenJarsProvider.getGenClassJar());
    Action genSourceAction = getGeneratingAction(javaGenJarsProvider.getGenSourceJar());

    assertThat(genSrcOutputAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
    assertThat(genClassAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
    assertThat(genSourceAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void javaCommonCompile_automaticExecGroupsDisabled_javaInfoActionsExecuteOnSecondPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "    plugins = [ctx.attr._plugins[JavaPluginInfo]],",
        "  )",
        "  return [java_info]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_plugins': attr.label(",
        "      default = Label('//test:test_plugin'),",
        "    ),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  provides = [JavaInfo],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "java_plugin(",
        "  name = 'test_plugin',",
        "  processor_class = 'GeneratedProcessor',",
        ")",
        "custom_rule(name = 'custom_rule_name')");

    ConfiguredTarget target = getConfiguredTarget("//test:custom_rule_name");
    JavaInfo javaInfo = (JavaInfo) target.get(JavaInfo.PROVIDER.getKey());
    Action genSrcOutputAction =
        getGeneratingAction(javaInfo.getOutputJars().getAllSrcOutputJars().get(0));
    JavaGenJarsProvider javaGenJarsProvider = javaInfo.getGenJarsProvider();
    Action genClassAction = getGeneratingAction(javaGenJarsProvider.getGenClassJar());
    Action genSourceAction = getGeneratingAction(javaGenJarsProvider.getGenSourceJar());

    assertThat(genSrcOutputAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
    assertThat(genClassAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
    assertThat(genSourceAction.getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
  }

  @Test
  public void javaCommonCompile_automaticExecGroupsEnabled_lazyActionExecutesOnFirstPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "    source_files = ctx.files.srcs,",
        "  )",
        "  return [java_info, DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "  },",
        "  provides = [JavaInfo],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name', srcs = ['Main.java'])");
    useConfiguration("--incompatible_auto_exec_groups", "--collect_code_coverage");

    ImmutableList<Action> actions =
        getActions("//test:custom_rule_name", LazyWritePathsFileAction.class);

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void javaCommonCompile_automaticExecGroupsDisabled_lazyActionExecutesOnSecondPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "    source_files = ctx.files.srcs,",
        "  )",
        "  return [java_info, DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "  },",
        "  provides = [JavaInfo],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name', srcs = ['Main.java'])");
    useConfiguration("--collect_code_coverage");

    ImmutableList<Action> actions =
        getActions("//test:custom_rule_name", LazyWritePathsFileAction.class);

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
  }

  @Test
  public void
      javaCommonCompile_automaticExecGroupsEnabled_javaResourceActionsExecuteOnFirstPlatform()
          throws Exception {
    scratch.file(
        "bazel_internal/test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "    resources = ctx.files.resources,",
        "    resource_jars = ctx.files.resource_jars,",
        "    classpath_resources = ctx.files.classpath_resources,",
        "  )",
        "  return [java_info, DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  attrs = {",
        "    'resources': attr.label_list(allow_files = True),",
        "    'resource_jars': attr.label_list(allow_files = True),",
        "    'classpath_resources': attr.label_list(allow_files = True),",
        "  },",
        "  provides = [JavaInfo],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "bazel_internal/test/BUILD",
        "load('//bazel_internal/test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name', resources = ['Resources.java'], resource_jars ="
            + " ['ResourceJars.java'], classpath_resources = ['ClasspathResources.java'])");
    useConfiguration(
        "--incompatible_auto_exec_groups", "--experimental_turbine_annotation_processing");

    ImmutableList<Action> actions = getActions("//bazel_internal/test:custom_rule_name");
    ImmutableList<Action> javaResourceActions =
        actions.stream()
            .filter(action -> action.getMnemonic().equals("JavaResourceJar"))
            .collect(toImmutableList());

    assertThat(javaResourceActions).hasSize(1);
    assertThat(javaResourceActions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void
      javaCommonCompile_automaticExecGroupsDisabled_javaResourceActionsExecuteOnSecondPlatform()
          throws Exception {
    scratch.file(
        "bazel_internal/test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "    resources = ctx.files.resources,",
        "    resource_jars = ctx.files.resource_jars,",
        "    classpath_resources = ctx.files.classpath_resources,",
        "  )",
        "  return [java_info, DefaultInfo(files = depset([output_jar]))]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  attrs = {",
        "    'resources': attr.label_list(allow_files = True),",
        "    'resource_jars': attr.label_list(allow_files = True),",
        "    'classpath_resources': attr.label_list(allow_files = True),",
        "  },",
        "  provides = [JavaInfo],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "bazel_internal/test/BUILD",
        "load('//bazel_internal/test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name', resources = ['Resources.java'], resource_jars ="
            + " ['ResourceJars.java'], classpath_resources = ['ClasspathResources.java'])");
    useConfiguration("--experimental_turbine_annotation_processing");

    ImmutableList<Action> actions = getActions("//bazel_internal/test:custom_rule_name");
    ImmutableList<Action> javaResourceActions =
        actions.stream()
            .filter(action -> action.getMnemonic().equals("JavaResourceJar"))
            .collect(toImmutableList());

    assertThat(javaResourceActions).hasSize(1);
    assertThat(javaResourceActions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_2"));
  }

  @Test
  public void javaCommonBuildIjar_automaticExecGroupsEnabled_ijarActionsExecuteOnFirstPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  ctx.actions.run(",
        "    outputs = [output_jar],",
        "    executable = ctx.toolchains['//rule:toolchain_type_2'].tool,",
        "    toolchain = '//rule:toolchain_type_2',",
        "  )",
        "  compile_jar = java_common.run_ijar(",
        "    actions = ctx.actions,",
        "    jar = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<Action> actions = getActions("//test:custom_rule_name", SpawnAction.class);

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getMnemonic()).isEqualTo("JavaIjar");
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void javaCommonPackSources_automaticExecGroupsEnabled_sourceActionExecutesOnFirstPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  source_jar = java_common.pack_sources(",
        "    ctx.actions,",
        "    output_source_jar = output_jar,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<Action> actions = getActions("//test:custom_rule_name", SpawnAction.class);

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getMnemonic()).isEqualTo("JavaSourceJar");
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void javaCommonStampJar_automaticExecGroupsEnabled_actionExecutesOnFirstPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib_' + ctx.label.name + '.jar')",
        "  ctx.actions.run(",
        "    outputs = [output_jar],",
        "    executable = ctx.toolchains['//rule:toolchain_type_2'].tool,",
        "    toolchain = '//rule:toolchain_type_2',",
        "  )",
        "  source_jar = java_common.stamp_jar(",
        "    ctx.actions,",
        "    jar = output_jar,",
        "    target_label = ctx.label,",
        "    java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  toolchains = ['//rule:toolchain_type_2', '" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<Action> actions = getActions("//test:custom_rule_name", SpawnAction.class);

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getProgressMessage())
        .isEqualTo("Stamping target label into jar lib_custom_rule_name.jar");
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonLink_fileWriteActionExecutesOnFirstPlatform() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "     unsupported_features = ctx.disabled_features,",
        "  )",
        "  linking_outputs = cc_common.link(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = { '_cc_toolchain': attr.label(default=Label('//test:alias')) },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<Action> actions =
        getActions("//test:custom_rule_name", ParameterFileWriteAction.class);

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonLink_cppLinkExecGroupNotDefined_cppLinkActionExecutesOnFirstPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "     unsupported_features = ctx.disabled_features,",
        "  )",
        "  linking_outputs = cc_common.link(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = { '_cc_toolchain': attr.label(default=Label('//test:alias')) },",
        "  exec_groups = { ",
        "    '" + CPP_LINK_EXEC_GROUP + "': exec_group(toolchains = _use_cpp_toolchain()),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<Action> actions = getActions("//test:custom_rule_name", CppLinkAction.class);

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getMnemonic()).isEqualTo("CppLink");
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonLink_cppLinkExecGroupDefined_cppLinkActionExecutesOnFirstPlatform()
      throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "     unsupported_features = ctx.disabled_features,",
        "  )",
        "  linking_outputs = cc_common.link(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = { '_cc_toolchain': attr.label(default=Label('//test:alias')) },",
        "  exec_groups = { ",
        "    '" + CPP_LINK_EXEC_GROUP + "': exec_group(toolchains = _use_cpp_toolchain()),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom_rule_name')");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<Action> actions = getActions("//test:custom_rule_name", CppLinkAction.class);

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getMnemonic()).isEqualTo("CppLink");
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonLink_cppLTOActionExecutesOnFirstPlatform() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "      unsupported_features = ctx.disabled_features,",
        "  )",
        "  linking_outputs = cc_common.link(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "    linking_contexts = [dep[CcInfo].linking_context for dep in ctx.attr.deps if"
            + " CcInfo in dep]",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "    '_cc_toolchain': attr.label(default=Label('//test:alias')),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "test/BUILD",
        "load('//test:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_library(",
        "  name = 'dep',",
        "  srcs = ['dep.cc'],",
        ")",
        "custom_rule(",
        "  name = 'custom_rule_name',",
        "  srcs = ['custom.cc'],",
        "  deps = ['dep'],",
        ")");
    useConfiguration("--incompatible_auto_exec_groups", "--features=thin_lto");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.THIN_LTO, CppRuleClasses.SUPPORTS_START_END_LIB));

    ImmutableList<Action> actions = getActions("//test:custom_rule_name", CppLinkAction.class);
    ImmutableList<Action> cppLTOActions =
        actions.stream()
            .filter(action -> action.getMnemonic().equals("CppLTOIndexing"))
            .collect(toImmutableList());

    assertThat(cppLTOActions).hasSize(1);
    assertThat(cppLTOActions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonLink_linkstampCompileActionExecutesOnFirstPlatform() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "      unsupported_features = ctx.disabled_features,",
        "  )",
        "  linking_outputs = cc_common.link(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "    linking_contexts = [dep[CcInfo].linking_context for dep in ctx.attr.deps if"
            + " CcInfo in dep]",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    '_cc_toolchain': attr.label(default=Label('//bazel_internal/test_rules/cc:alias')),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load('//bazel_internal/test_rules/cc:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_library(",
        "  name = 'dep',",
        "  linkstamp = 'stamp.cc',",
        ")",
        "custom_rule(",
        "  name = 'custom_rule_name',",
        "  deps = ['dep'],",
        ")");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<Action> cppCompileActions =
        getActions("//bazel_internal/test_rules/cc:custom_rule_name", CppCompileAction.class);

    assertThat(cppCompileActions).hasSize(1);
    assertThat(cppCompileActions.get(0).getMnemonic()).isEqualTo("CppLinkstampCompile");
    assertThat(cppCompileActions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonCompile_cppCompileActionExecutesOnFirstPlatform() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "      unsupported_features = ctx.disabled_features,",
        "  )",
        "  (compilation_context, compilation_outputs) = cc_common.compile(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "    srcs = ctx.files.srcs,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "    '_cc_toolchain': attr.label(default=Label('//bazel_internal/test_rules/cc:alias')),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load('//bazel_internal/test_rules/cc:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(",
        "  name = 'custom_rule_name',",
        "  srcs = ['custom.cc'],",
        ")");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<Action> cppCompileActions =
        getActions("//bazel_internal/test_rules/cc:custom_rule_name", CppCompileAction.class);

    assertThat(cppCompileActions).hasSize(1);
    assertThat(cppCompileActions.get(0).getProgressMessage())
        .isEqualTo("Compiling bazel_internal/test_rules/cc/custom.cc");
    assertThat(cppCompileActions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonCompile_moduleActionsExecuteOnFirstPlatform() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "      unsupported_features = ctx.disabled_features,",
        "  )",
        "  (compilation_context, compilation_outputs) = cc_common.compile(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "    srcs = ctx.files.srcs,",
        "    public_hdrs = ctx.files.hdrs,",
        "    separate_module_headers = ctx.files.hdrs,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "    'hdrs': attr.label_list(allow_files = ['.h']),",
        "    '_cc_toolchain': attr.label(default=Label('//bazel_internal/test_rules/cc:alias')),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load('//bazel_internal/test_rules/cc:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(",
        "  name = 'custom_rule_name',",
        "  srcs = ['custom.cc'],",
        "  hdrs = ['custom.h'],",
        ")");
    useConfiguration("--incompatible_auto_exec_groups", "--features=header_modules");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(MockCcSupport.HEADER_MODULES_FEATURES));

    ImmutableList<Action> cppCompileActions =
        getActions("//bazel_internal/test_rules/cc:custom_rule_name", CppCompileAction.class);
    ImmutableList<Action> moduleActions =
        cppCompileActions.stream()
            .filter(action -> action.getProgressMessage().contains("custom_rule_name.cppmap"))
            .collect(toImmutableList());

    assertThat(moduleActions).hasSize(2);
    assertThat(moduleActions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
    assertThat(moduleActions.get(1).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonCompile_codeGenModuleActionExecutesOnFirstPlatform() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "      unsupported_features = ctx.disabled_features,",
        "  )",
        "  (compilation_context, compilation_outputs) = cc_common.compile(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "    srcs = ctx.files.srcs,",
        "    public_hdrs = ctx.files.hdrs,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "    'hdrs': attr.label_list(allow_files = ['.h']),",
        "    '_cc_toolchain': attr.label(default=Label('//bazel_internal/test_rules/cc:alias')),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load('//bazel_internal/test_rules/cc:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(",
        "  name = 'custom_rule_name',",
        "  srcs = ['custom.cc'],",
        "  hdrs = ['custom.h'],",
        ")");
    useConfiguration(
        "--incompatible_auto_exec_groups",
        "--features=header_modules",
        "--features=header_module_codegen");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(MockCcSupport.HEADER_MODULES_FEATURES));

    ImmutableList<Action> cppCompileActions =
        getActions("//bazel_internal/test_rules/cc:custom_rule_name", CppCompileAction.class);
    ImmutableList<Action> codeGenCompileActions =
        cppCompileActions.stream()
            .filter(action -> action.getProgressMessage().contains("custom_rule_name.pcm"))
            .collect(toImmutableList());

    assertThat(codeGenCompileActions).hasSize(1);
    assertThat(codeGenCompileActions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonCompile_compileHeaderActionExecutesOnFirstPlatform() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "      unsupported_features = ctx.disabled_features,",
        "  )",
        "  (compilation_context, compilation_outputs) = cc_common.compile(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "    srcs = ctx.files.srcs,",
        "    private_hdrs = ctx.files.hdrs,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "    'hdrs': attr.label_list(allow_files = ['.h']),",
        "    '_cc_toolchain': attr.label(default=Label('//bazel_internal/test_rules/cc:alias')),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load('//bazel_internal/test_rules/cc:defs.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(",
        "  name = 'custom_rule_name',",
        "  srcs = ['custom.cc'],",
        "  hdrs = ['custom.h'],",
        ")");
    useConfiguration("--incompatible_auto_exec_groups", "--features=parse_headers");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(CppRuleClasses.PARSE_HEADERS));

    ImmutableList<Action> cppCompileActions =
        getActions("//bazel_internal/test_rules/cc:custom_rule_name", CppCompileAction.class);
    ImmutableList<Action> compileHeaderActions =
        cppCompileActions.stream()
            .filter(
                action ->
                    action
                        .getProgressMessage()
                        .equals("Compiling bazel_internal/test_rules/cc/custom.h"))
            .collect(toImmutableList());

    assertThat(compileHeaderActions).hasSize(1);
    assertThat(compileHeaderActions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }

  @Test
  public void ccCommonCompile_treeArtifactActionExecutesOnFirstPlatform() throws Exception {
    scratch.file(
        "test/defs.bzl",
        "def _use_cpp_toolchain():",
        "   return [",
        "      config_common.toolchain_type('"
            + TestConstants.CPP_TOOLCHAIN_TYPE
            + "', mandatory = False),",
        "   ]",
        "def _ta_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 = _ta_impl)",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = cc_toolchain,",
        "      requested_features = ctx.features,",
        "      unsupported_features = ctx.disabled_features,",
        "  )",
        "  (compilation_context, compilation_outputs) = cc_common.compile(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = cc_toolchain,",
        "    srcs = ctx.files.srcs,",
        "  )",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "    '_cc_toolchain': attr.label(default=Label('//test:alias')),",
        "  },",
        "  toolchains = ['//rule:toolchain_type_2'] + _use_cpp_toolchain(),",
        "  fragments = ['cpp']",
        ")");
    scratch.file(
        "test/BUILD",
        "package(default_visibility = ['//visibility:public'])",
        "load('//test:defs.bzl', 'custom_rule', 'create_tree_artifact')",
        "cc_toolchain_alias(name='alias')",
        "create_tree_artifact(name = 'tree_artifact')",
        "custom_rule(",
        "  name = 'custom_rule_name',",
        "  srcs = ['tree_artifact'],",
        ")");
    useConfiguration("--incompatible_auto_exec_groups");

    ImmutableList<ActionAnalysisMetadata> actions =
        ((RuleConfiguredTarget) getConfiguredTarget("//test:custom_rule_name")).getActions();

    assertThat(actions).hasSize(1);
    assertThat(actions.get(0).getOwner().getExecutionPlatform().label())
        .isEqualTo(Label.parseCanonical("//platforms:platform_1"));
  }
}
