// Copyright 2017 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.skyframe;

import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.syntax.Type.STRING;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationResolver;
import com.google.devtools.build.lib.analysis.config.TransitionFactories;
import com.google.devtools.build.lib.analysis.config.transitions.ComposingTransition;
import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionFactory;
import com.google.devtools.build.lib.analysis.test.TestConfiguration;
import com.google.devtools.build.lib.analysis.util.MockRule;
import com.google.devtools.build.lib.analysis.util.TestAspects;
import com.google.devtools.build.lib.analysis.util.TestAspects.DummyRuleFactory;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.testutil.Suite;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.testutil.TestSpec;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Runs an expanded set of ConfigurationsForTargetsTest with trimmed configurations. */
@TestSpec(size = Suite.SMALL_TESTS)
@RunWith(JUnit4.class)
public class ConfigurationsForTargetsWithTrimmedConfigurationsTest
    extends ConfigurationsForTargetsTest {
  @Override
  protected FlagBuilder defaultFlags() {
    return super.defaultFlags().with(Flag.TRIMMED_CONFIGURATIONS);
  }

  private static class NoopSplitTransition implements SplitTransition {
    @Override
    public List<BuildOptions> split(BuildOptions buildOptions) {
      return ImmutableList.of(buildOptions);
    }
  }

  private static class SetsHostCpuSplitTransition implements SplitTransition {
    @Override
    public List<BuildOptions> split(BuildOptions buildOptions) {
      BuildOptions result = buildOptions.clone();
      result.get(BuildConfiguration.Options.class).hostCpu = "SET BY SPLIT";
      return ImmutableList.of(result);
    }
  }

  private static class SetsCpuSplitTransition implements SplitTransition {

    @Override
    public List<BuildOptions> split(BuildOptions buildOptions) {
      BuildOptions result = buildOptions.clone();
      result.get(BuildConfiguration.Options.class).cpu = "SET BY SPLIT";
      return ImmutableList.of(result);
    }
  }

  private static class SetsCpuPatchTransition implements PatchTransition {

    @Override
    public BuildOptions patch(BuildOptions options) {
      BuildOptions result = options.clone();
      result.get(BuildConfiguration.Options.class).cpu = "SET BY PATCH";
      return result;
    }
  }

  /** Base rule that depends on the test configuration fragment. */
  private static final MockRule TEST_BASE_RULE = () ->
      MockRule.ancestor(TestAspects.BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "test_base",
          (builder, env) ->
              builder.requiresConfigurationFragments(TestConfiguration.class).build());

  /** A rule with an empty split transition on an attribute. */
  private static final MockRule EMPTY_SPLIT_RULE =
      () ->
          MockRule.ancestor(TEST_BASE_RULE.getClass())
              .factory(DummyRuleFactory.class)
              .define(
                  "empty_split",
                  attr("with_empty_transition", LABEL)
                      .allowedFileTypes(FileTypeSet.ANY_FILE)
                      .cfg(TransitionFactories.of(new NoopSplitTransition())));

  /** Rule with a split transition on an attribute. */
  private static final MockRule ATTRIBUTE_TRANSITION_RULE =
      () ->
          MockRule.ancestor(TEST_BASE_RULE.getClass())
              .factory(DummyRuleFactory.class)
              .define(
                  "attribute_transition",
                  attr("without_transition", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE),
                  attr("with_cpu_transition", LABEL)
                      .allowedFileTypes(FileTypeSet.ANY_FILE)
                      .cfg(TransitionFactories.of(new SetsCpuSplitTransition())),
                  attr("with_host_cpu_transition", LABEL)
                      .allowedFileTypes(FileTypeSet.ANY_FILE)
                      .cfg(TransitionFactories.of(new SetsHostCpuSplitTransition())));

  /** Rule with rule class configuration transition. */
  private static final MockRule RULE_CLASS_TRANSITION_RULE = () ->
      MockRule.ancestor(TEST_BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "rule_class_transition",
          (builder, env) -> builder.cfg(new SetsCpuPatchTransition()).build());

  private static class SetsTestFilterFromAttributePatchTransition implements PatchTransition {
    private final String value;

    public SetsTestFilterFromAttributePatchTransition(String value) {
      this.value = value;
    }

    @Override
    public BuildOptions patch(BuildOptions options) {
      BuildOptions result = options.clone();
      result.get(TestConfiguration.TestOptions.class).testFilter = "SET BY PATCH FACTORY: " + value;
      return result;
    }
  }

  @AutoCodec.VisibleForSerialization
  @AutoCodec
  static class SetsTestFilterFromAttributeTransitionFactory implements TransitionFactory<Rule> {
    @Override
    public PatchTransition create(Rule rule) {
      NonconfigurableAttributeMapper attributes = NonconfigurableAttributeMapper.of(rule);
      String value = attributes.get("sets_test_filter_to", STRING);
      if (Strings.isNullOrEmpty(value)) {
        return NoTransition.INSTANCE;
      } else {
        return new SetsTestFilterFromAttributePatchTransition(value);
      }
    }
  }

  /**
   * Rule with a RuleTransitionFactory which sets the --test_filter flag according to its attribute.
   */
  private static final MockRule USES_RULE_TRANSITION_FACTORY_RULE = () ->
      MockRule.ancestor(TEST_BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "uses_rule_transition_factory",
          (builder, env) ->
              builder
                  .cfg(new SetsTestFilterFromAttributeTransitionFactory())
                  .add(attr("sets_test_filter_to", STRING)
                      .nonconfigurable("used in RuleTransitionFactory")
                      .value("")));

  private static final class AddArgumentToTestArgsTransition implements PatchTransition {
    private final String argument;

    public AddArgumentToTestArgsTransition(String argument) {
      this.argument = argument;
    }

    @Override
    public BuildOptions patch(BuildOptions options) {
      BuildOptions result = options.clone();
      TestConfiguration.TestOptions testOpts = result.get(TestConfiguration.TestOptions.class);
      ImmutableList<String> testArgs =
          new ImmutableList.Builder<String>().addAll(testOpts.testArguments).add(argument).build();
      testOpts.testArguments = testArgs;
      return result;
    }
  }

  /** Rule which adds an argument to the --test_args flag for its dependencies. */
  private static final MockRule ADD_TEST_ARG_FOR_DEPS_RULE =
      () ->
          MockRule.ancestor(TEST_BASE_RULE.getClass())
              .factory(DummyRuleFactory.class)
              .define(
                  "add_test_arg_for_deps",
                  attr("deps", LABEL_LIST)
                      .allowedFileTypes(FileTypeSet.ANY_FILE)
                      .cfg(
                          TransitionFactories.of(
                              new AddArgumentToTestArgsTransition("deps transition"))));

  /** Rule which adds an argument to the --test_args flag for itself. */
  private static final MockRule ADD_TEST_ARG_FOR_SELF_RULE =
      () ->
          MockRule.ancestor(TEST_BASE_RULE.getClass())
              .factory(DummyRuleFactory.class)
              .define(
                  "add_test_arg_for_self",
                  (builder, env) ->
                      builder
                          .cfg(new AddArgumentToTestArgsTransition("rule class transition"))
                          .add(attr("deps", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)));

  @Test
  public void trimmingTransitionActivatesLastOnAllTargets() throws Exception {
    TransitionFactory<Rule> trimmingTransitionFactory =
        (rule) ->
            new AddArgumentToTestArgsTransition(
                "trimming transition for " + rule.getLabel().toString());
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    builder.addRuleDefinition(TestAspects.BASE_RULE);
    builder.addRuleDefinition(TEST_BASE_RULE);
    builder.addRuleDefinition(ADD_TEST_ARG_FOR_DEPS_RULE);
    builder.addRuleDefinition(ADD_TEST_ARG_FOR_SELF_RULE);
    builder.overrideTrimmingTransitionFactoryForTesting(trimmingTransitionFactory);
    useRuleClassProvider(builder.build());
    scratch.file(
        "a/skylark.bzl",
        "def _impl(ctx):",
        "  return",
        "skylark_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    '_base': attr.label(default = '//a:base'),",
        "  }",
        ")");
    scratch.file(
        "a/BUILD",
        "load(':skylark.bzl', 'skylark_rule')",
        // ensure that all Skylark rules get the TestConfiguration fragment
        "test_base(name = 'base')",
        // skylark rules get trimmed
        "skylark_rule(name = 'skylark_solo', deps = [':base'])",
        // native rules get trimmed; top-level targets get trimmed after the rule-class transition
        "add_test_arg_for_self(name = 'test_arg_on_self')",
        // deps with dependency transitions get trimmed after the dependency transition
        "add_test_arg_for_deps(name = 'attribute_transition', deps = [':dep_after_transition'])",
        "skylark_rule(name = 'dep_after_transition')",
        // deps on rule-class transitions get trimmed after the rule-class transition
        "skylark_rule(name = 'dep_on_ruleclass', deps = [':ruleclass_transition'])",
        "add_test_arg_for_self(name = 'ruleclass_transition')",
        // when all three (rule-class, attribute, trimming transitions) collide it's okay
        "add_test_arg_for_deps(name = 'attribute_outer', deps = [':ruleclass_inner'])",
        "add_test_arg_for_self(name = 'ruleclass_inner')");

    ConfiguredTarget configuredTarget;
    BuildConfiguration config;

    configuredTarget = Iterables.getOnlyElement(update("//a:skylark_solo").getTargetsToBuild());
    config = getConfiguration(configuredTarget);
    assertThat(config.getFragment(TestConfiguration.class).getTestArguments())
        .containsExactly("trimming transition for //a:skylark_solo");

    configuredTarget = Iterables.getOnlyElement(update("//a:test_arg_on_self").getTargetsToBuild());
    config = getConfiguration(configuredTarget);
    assertThat(config.getFragment(TestConfiguration.class).getTestArguments())
        .containsExactly("rule class transition", "trimming transition for //a:test_arg_on_self")
        .inOrder();

    configuredTarget =
        Iterables.getOnlyElement(update("//a:attribute_transition").getTargetsToBuild());
    config =
        getConfiguration(
            Iterables.getOnlyElement(getConfiguredDeps(configuredTarget, "deps")));
    assertThat(config.getFragment(TestConfiguration.class).getTestArguments())
        .containsExactly(
            "trimming transition for //a:attribute_transition",
            "deps transition",
            "trimming transition for //a:dep_after_transition")
        .inOrder();

    configuredTarget = Iterables.getOnlyElement(update("//a:dep_on_ruleclass").getTargetsToBuild());
    config =
        getConfiguration(
            Iterables.getOnlyElement(getConfiguredDeps(configuredTarget, "deps")));
    assertThat(config.getFragment(TestConfiguration.class).getTestArguments())
        .containsExactly(
            "trimming transition for //a:dep_on_ruleclass",
            "rule class transition",
            "trimming transition for //a:ruleclass_transition")
        .inOrder();

    configuredTarget = Iterables.getOnlyElement(update("//a:attribute_outer").getTargetsToBuild());
    config =
        getConfiguration(
            Iterables.getOnlyElement(getConfiguredDeps(configuredTarget, "deps")));
    assertThat(config.getFragment(TestConfiguration.class).getTestArguments())
        .containsExactly(
            "trimming transition for //a:attribute_outer",
            "deps transition",
            "rule class transition",
            "trimming transition for //a:ruleclass_inner")
        .inOrder();
  }

  @Test
  public void trimmingTransitionsAreComposedInOrderOfAdding() throws Exception {
    TransitionFactory<Rule> firstTrimmingTransitionFactory =
        (rule) ->
            new AddArgumentToTestArgsTransition(
                "first trimming transition for " + rule.getLabel().toString());
    TransitionFactory<Rule> secondTrimmingTransitionFactory =
        (rule) ->
            new AddArgumentToTestArgsTransition(
                "second trimming transition for " + rule.getLabel().toString());
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    builder.addRuleDefinition(TestAspects.BASE_RULE);
    builder.addRuleDefinition(TEST_BASE_RULE);
    builder.overrideTrimmingTransitionFactoryForTesting(firstTrimmingTransitionFactory);
    builder.addTrimmingTransitionFactory(secondTrimmingTransitionFactory);
    useRuleClassProvider(builder.build());
    scratch.file(
        "a/skylark.bzl",
        "def _impl(ctx):",
        "  return",
        "skylark_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    '_base': attr.label(default = '//a:base'),",
        "  }",
        ")");
    scratch.file(
        "a/BUILD",
        "load(':skylark.bzl', 'skylark_rule')",
        // ensure that all Skylark rules get the TestConfiguration fragment
        "test_base(name = 'base')",
        // skylark rules get trimmed
        "skylark_rule(name = 'skylark_solo', deps = [':base'])");

    ConfiguredTarget configuredTarget;
    BuildConfiguration config;

    configuredTarget = Iterables.getOnlyElement(update("//a:skylark_solo").getTargetsToBuild());
    config = getConfiguration(configuredTarget);
    assertThat(config.getFragment(TestConfiguration.class).getTestArguments())
        .containsExactly(
            "first trimming transition for //a:skylark_solo",
            "second trimming transition for //a:skylark_solo")
        .inOrder();
  }

  @Test
  public void testRuleClassTransition() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
        RULE_CLASS_TRANSITION_RULE);
    scratch.file("a/BUILD",
        "attribute_transition(",
        "   name='attribute',",
        "   without_transition = ':rule_class',",
        ")",
        "rule_class_transition(name='rule_class')");
    List<ConfiguredTarget> deps = getConfiguredDeps("//a:attribute", "without_transition");
    BuildConfiguration ruleclass = getConfiguration(Iterables.getOnlyElement(deps));
    assertThat(ruleclass.getCpu()).isEqualTo("SET BY PATCH");
  }

  @Test
  public void testNonConflictingAttributeAndRuleClassTransitions() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
        RULE_CLASS_TRANSITION_RULE);
    scratch.file("a/BUILD",
        "attribute_transition(",
        "   name='attribute',",
        "   with_host_cpu_transition = ':rule_class',",
        ")",
        "rule_class_transition(name='rule_class')");
    List<ConfiguredTarget> deps = getConfiguredDeps("//a:attribute", "with_host_cpu_transition");
    BuildConfiguration ruleclass = getConfiguration(Iterables.getOnlyElement(deps));
    assertThat(ruleclass.getCpu()).isEqualTo("SET BY PATCH");
    assertThat(ruleclass.getHostCpu()).isEqualTo("SET BY SPLIT");
  }

  @Test
  public void testConflictingAttributeAndRuleClassTransitions() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
        RULE_CLASS_TRANSITION_RULE);
    scratch.file("a/BUILD",
        "attribute_transition(",
        "   name='attribute',",
        "   with_cpu_transition = ':rule_class',",
        ")",
        "rule_class_transition(name='rule_class')");
    List<ConfiguredTarget> deps = getConfiguredDeps("//a:attribute", "with_cpu_transition");
    BuildConfiguration ruleclass = getConfiguration(Iterables.getOnlyElement(deps));
    assertThat(ruleclass.getCpu()).isEqualTo("SET BY PATCH");
  }

  @Test
  public void testEmptySplitDoesNotSuppressRuleClassTransition() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, EMPTY_SPLIT_RULE,
        RULE_CLASS_TRANSITION_RULE);
    scratch.file(
        "a/BUILD",
        "empty_split(",
        "   name = 'empty',",
        "   with_empty_transition = ':rule_class',",
        ")",
        "rule_class_transition(name='rule_class')");
    List<ConfiguredTarget> deps = getConfiguredDeps("//a:empty", "with_empty_transition");
    BuildConfiguration ruleclass = getConfiguration(Iterables.getOnlyElement(deps));
    assertThat(ruleclass.getCpu()).isEqualTo("SET BY PATCH");
  }

  @Test
  public void testTopLevelRuleClassTransition() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, RULE_CLASS_TRANSITION_RULE);
    scratch.file(
        "a/BUILD",
        "rule_class_transition(",
        "   name = 'rule_class',",
        ")");
    ConfiguredTarget target =
        Iterables.getOnlyElement(update("//a:rule_class").getTargetsToBuild());
    assertThat(getConfiguration(target).getCpu()).isEqualTo("SET BY PATCH");
  }

  @Test
  public void testTopLevelRuleClassTransitionAndNoTransition() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, RULE_CLASS_TRANSITION_RULE,
        TestAspects.SIMPLE_RULE);
    scratch.file(
        "a/BUILD",
        "rule_class_transition(",
        "   name = 'rule_class',",
        ")",
        "simple(name='sim')");
    ConfiguredTarget target =
        Iterables.getOnlyElement(update("//a:sim").getTargetsToBuild());
    assertThat(getConfiguration(target).getCpu()).isNotEqualTo("SET BY PATCH");
  }

  @Test
  public void ruleTransitionFactoryUsesNonconfigurableAttributesToGenerateTransition()
      throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
        USES_RULE_TRANSITION_FACTORY_RULE);
    useConfiguration("--test_filter=SET ON COMMAND LINE: original and best");
    scratch.file(
        "a/BUILD",
        "attribute_transition(",
        "   name='top',",
        "   without_transition=':factory',",
        ")",
        "uses_rule_transition_factory(",
        "   name='factory',",
        "   sets_test_filter_to='funkiest',",
        ")");
    List<ConfiguredTarget> deps = getConfiguredDeps("//a:top", "without_transition");
    BuildConfiguration config = getConfiguration(Iterables.getOnlyElement(deps));
    assertThat(config.getFragment(TestConfiguration.class).getTestFilter())
        .isEqualTo("SET BY PATCH FACTORY: funkiest");
  }

  @Test
  public void ruleTransitionFactoryCanReturnNullToCauseNoTransition() throws Exception {
    setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE,
        USES_RULE_TRANSITION_FACTORY_RULE);
    useConfiguration("--test_filter=SET ON COMMAND LINE: original and best");
    scratch.file(
        "a/BUILD",
        "attribute_transition(",
        "   name='top',",
        "   without_transition=':factory',",
        ")",
        "uses_rule_transition_factory(",
        "   name='factory',",
        "   sets_test_filter_to='',",
        ")");
    List<ConfiguredTarget> deps = getConfiguredDeps("//a:top", "without_transition");
    BuildConfiguration config = getConfiguration(Iterables.getOnlyElement(deps));
    assertThat(config.getFragment(TestConfiguration.class).getTestFilter())
        .isEqualTo("SET ON COMMAND LINE: original and best");
  }

  @Test
  public void topLevelRuleTransitionFactoryUsesNonconfigurableAttributes() throws Exception {
    setRulesAvailableInTests(
        TestAspects.BASE_RULE, TEST_BASE_RULE, USES_RULE_TRANSITION_FACTORY_RULE);
    useConfiguration("--test_filter=SET ON COMMAND LINE: original and best");
    scratch.file(
        "a/BUILD",
        "uses_rule_transition_factory(",
        "   name='factory',",
        "   sets_test_filter_to='Maximum Dance',",
        ")");
    ConfiguredTarget target = Iterables.getOnlyElement(update("//a:factory").getTargetsToBuild());
    assertThat(getConfiguration(target).getFragment(TestConfiguration.class).getTestFilter())
        .isEqualTo("SET BY PATCH FACTORY: Maximum Dance");
  }

  @Test
  public void topLevelRuleTransitionFactoryCanReturnNullInTesting() throws Exception {
    setRulesAvailableInTests(
        TestAspects.BASE_RULE, TEST_BASE_RULE, USES_RULE_TRANSITION_FACTORY_RULE);
    useConfiguration("--test_filter=SET ON COMMAND LINE: original and best");
    scratch.file(
        "a/BUILD",
        "uses_rule_transition_factory(",
        "   name='factory',",
        "   sets_test_filter_to='',",
        ")");
    update("@//a:factory");
    ConfiguredTarget target = getView().getConfiguredTargetForTesting(
        reporter,
        Label.parseAbsoluteUnchecked("@//a:factory"),
        getTargetConfiguration());
    assertThat(getConfiguration(target).getFragment(TestConfiguration.class).getTestFilter())
        .isEqualTo("SET ON COMMAND LINE: original and best");
  }

  /**
   * Returns a custom {@link PatchTransition} with the given value added to {@link
   * TestConfiguration.TestOptions#testFilter}.
   */
  private static PatchTransition newPatchTransition(final String value) {
    return new PatchTransition() {
      @Override
      public BuildOptions patch(BuildOptions options) {
        BuildOptions toOptions = options.clone();
        TestConfiguration.TestOptions baseOptions =
            toOptions.get(TestConfiguration.TestOptions.class);
        baseOptions.testFilter = nullToEmpty(baseOptions.testFilter) + value;
        return toOptions;
      }
    };
  }

  /**
   * Returns a custom {@link SplitTransition} that splits {@link
   * TestConfiguration.TestOptions#testFilter} down two paths: {@code += prefix + "1"} and {@code +=
   * prefix + "2"}.
   */
  private static SplitTransition newSplitTransition(final String prefix) {
    return buildOptions -> {
      ImmutableList.Builder<BuildOptions> result = ImmutableList.builder();
      for (int index = 1; index <= 2; index++) {
        BuildOptions toOptions = buildOptions.clone();
        TestConfiguration.TestOptions baseOptions =
            toOptions.get(TestConfiguration.TestOptions.class);
        baseOptions.testFilter =
            (baseOptions.testFilter == null ? "" : baseOptions.testFilter) + prefix + index;
        result.add(toOptions);
      }
      return result.build();
    };
  }

  /**
   * Returns the value of {@link TestConfiguration.TestOptions#testFilter} for a transition
   * applied over the target configuration.
   */
  private List<String> getTestFilterOptionValue(ConfigurationTransition transition)
      throws Exception {
    ImmutableList.Builder<String> outValues = ImmutableList.builder();
    for (BuildOptions toOptions :
        ConfigurationResolver.applyTransition(
            getTargetConfiguration().getOptions(),
            transition,
            ruleClassProvider.getAllFragments(),
            ruleClassProvider,
            false,
            ImmutableMap.of(),
            ImmutableMap.of())) {
      outValues.add(toOptions.get(TestConfiguration.TestOptions.class).testFilter);
    }
    return outValues.build();
  }

  @Test
  public void composedStraightTransitions() throws Exception {
    update(); // Creates the target configuration.
    assertThat(
            getTestFilterOptionValue(
                ComposingTransition.of(newPatchTransition("foo"), newPatchTransition("bar"))))
        .containsExactly("foobar");
  }

  @Test
  public void composedStraightTransitionThenSplitTransition() throws Exception {
    update(); // Creates the target configuration.
    assertThat(
            getTestFilterOptionValue(
                ComposingTransition.of(newPatchTransition("foo"), newSplitTransition("split"))))
        .containsExactly("foosplit1", "foosplit2");
  }

  @Test
  public void composedSplitTransitionThenStraightTransition() throws Exception {
    update(); // Creates the target configuration.
    assertThat(
            getTestFilterOptionValue(
                ComposingTransition.of(newSplitTransition("split"), newPatchTransition("foo"))))
        .containsExactly("split1foo", "split2foo");
  }

  @Test
  public void composedSplitTransitions() throws Exception {
    update(); // Creates the target configuration.
    assertThat(
            getTestFilterOptionValue(
                ComposingTransition.of(newSplitTransition("s"), newSplitTransition("t"))))
        .containsExactly("s1t1", "s1t2", "s2t1", "s2t2");
  }

}
