diff options
author | 2018-04-19 14:16:41 -0700 | |
---|---|---|
committer | 2018-04-19 14:18:37 -0700 | |
commit | 4a07a47456d6db3879d768321cbd32a7a769df37 (patch) | |
tree | 6fe66409ec4820632994746de606e53ef28669a8 /src/test/java/com/google/devtools/build | |
parent | b6d8ec02cf8c76b409a467ad3dfdb0b685ef2943 (diff) |
Add the capability to register a trimming RuleTransitionFactory.
This RuleTransitionFactory will be applied to all targets after other
transitions, and is intended to be used to manually trim the configuration
based on tagging of that target. This is a stopgap feature until automatic
trimming of configuration can be implemented.
RELNOTES: None.
PiperOrigin-RevId: 193573013
Diffstat (limited to 'src/test/java/com/google/devtools/build')
3 files changed, 159 insertions, 9 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java b/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java index c4566b6a0e..cc6affd6ee 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/DependencyResolverTest.java @@ -115,7 +115,8 @@ public class DependencyResolverTest extends AnalysisTestCase { ImmutableMap.<Label, ConfigMatchingProvider>of(), /*toolchainLabels=*/ ImmutableSet.of(), DefaultBuildOptionsForDiffing.getDefaultBuildOptionsForFragments( - ruleClassProvider.getConfigurationOptions())); + ruleClassProvider.getConfigurationOptions()), + /*trimmingTransitionFactory=*/ null); } @SafeVarargs diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsTest.java index 9d29af75ec..ba6fa1d05e 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsTest.java @@ -28,6 +28,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.SetMultimap; +import com.google.devtools.build.lib.analysis.AliasProvider; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.Dependency; @@ -220,14 +221,11 @@ public class ConfigurationsForTargetsTest extends AnalysisTestCase { }); } - /** - * Returns the configured deps for a given target, assuming the target uses the target - * configuration. - */ - private Multimap<Attribute, ConfiguredTargetAndData> getConfiguredDeps(String targetLabel) + /** Returns the configured deps for a given target. */ + private Multimap<Attribute, ConfiguredTargetAndData> getConfiguredDeps(ConfiguredTarget target) throws Exception { - update(targetLabel); - SkyKey key = ComputeDependenciesFunction.key(getTarget(targetLabel), getTargetConfiguration()); + String targetLabel = AliasProvider.getDependencyLabel(target).toString(); + SkyKey key = ComputeDependenciesFunction.key(getTarget(targetLabel), getConfiguration(target)); // Must re-enable analysis for Skyframe functions that create configured targets. skyframeExecutor.getSkyframeBuildView().enableAnalysis(true); Object evalResult = SkyframeExecutorTestUtils.evaluate( @@ -245,7 +243,19 @@ public class ConfigurationsForTargetsTest extends AnalysisTestCase { */ protected List<ConfiguredTarget> getConfiguredDeps(String targetLabel, String attrName) throws Exception { - Multimap<Attribute, ConfiguredTargetAndData> allDeps = getConfiguredDeps(targetLabel); + ConfiguredTarget target = Iterables.getOnlyElement(update(targetLabel).getTargetsToBuild()); + return getConfiguredDeps(target, attrName); + } + + /** + * Returns the configured deps for a given configured target under the given attribute. + * + * <p>Throws an exception if the attribute can't be found. + */ + protected List<ConfiguredTarget> getConfiguredDeps(ConfiguredTarget target, String attrName) + throws Exception { + String targetLabel = AliasProvider.getDependencyLabel(target).toString(); + Multimap<Attribute, ConfiguredTargetAndData> allDeps = getConfiguredDeps(target); for (Attribute attribute : allDeps.keySet()) { if (attribute.getName().equals(attrName)) { return ImmutableList.copyOf( diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsWithTrimmedConfigurationsTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsWithTrimmedConfigurationsTest.java index 6ce769d074..a73ed01e4a 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsWithTrimmedConfigurationsTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ConfigurationsForTargetsWithTrimmedConfigurationsTest.java @@ -18,11 +18,13 @@ 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.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; @@ -41,6 +43,7 @@ import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleTransitionFactory; 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; @@ -170,6 +173,141 @@ public class ConfigurationsForTargetsWithTrimmedConfigurationsTest .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 apply(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(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 { + RuleTransitionFactory 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 testRuleClassTransition() throws Exception { setRulesAvailableInTests(TestAspects.BASE_RULE, TEST_BASE_RULE, ATTRIBUTE_TRANSITION_RULE, @@ -430,4 +568,5 @@ public class ConfigurationsForTargetsWithTrimmedConfigurationsTest newSplitTransition("t")))) .containsExactly("s1t1", "s1t2", "s2t1", "s2t2"); } + } |