aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar Dmitry Lomov <dslomov@google.com>2016-11-18 15:14:56 +0000
committerGravatar Dmitry Lomov <dslomov@google.com>2016-11-21 19:34:38 +0000
commit8f45b7c71394f07227e507fddf736bcf6d5b0097 (patch)
tree80b4eccd7033f63b0aa50bd735437305a1fcd1d3 /src/test/java/com/google/devtools/build/lib
parentbd9576a7b092114b02118c2d08c2d6ef60806858 (diff)
Implement 'output_groups' provider.
This behavior - that 'output_groups' is a provider available on targets and aspects - has been accidental, but people already depend on it. This CL keeps that behavior, while fixing the bug that two aspects could not both provide output groups. -- MOS_MIGRATED_REVID=139578378
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib')
-rw-r--r--src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java146
-rw-r--r--src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java44
2 files changed, 189 insertions, 1 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
index 53da165256..5f0933017e 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
@@ -296,7 +296,6 @@ public class SkylarkAspectsTest extends AnalysisTestCase {
"",
"MyAspect = aspect(",
" implementation=_impl,",
- " attr_aspects=['deps'],",
")");
scratch.file(
"test/BUILD",
@@ -321,6 +320,50 @@ public class SkylarkAspectsTest extends AnalysisTestCase {
}
@Test
+ public void testAspectWithOutputGroupsAsList() throws Exception {
+ scratch.file(
+ "test/aspect.bzl",
+ "def _impl(target, ctx):",
+ " g = target.output_group('_hidden_top_level" + INTERNAL_SUFFIX + "')",
+ " return struct(output_groups = { 'my_result' : [ f for f in g] })",
+ "",
+ "MyAspect = aspect(",
+ " implementation=_impl,",
+ ")");
+ scratch.file(
+ "test/BUILD",
+ "java_library(",
+ " name = 'xxx',",
+ " srcs = ['A.java'],",
+ ")");
+
+ AnalysisResult analysisResult =
+ update(ImmutableList.of("test/aspect.bzl%MyAspect"), "//test:xxx");
+ assertThat(
+ transform(
+ analysisResult.getTargetsToBuild(),
+ new Function<ConfiguredTarget, String>() {
+ @Nullable
+ @Override
+ public String apply(ConfiguredTarget configuredTarget) {
+ return configuredTarget.getLabel().toString();
+ }
+ }))
+ .containsExactly("//test:xxx");
+ AspectValue aspectValue = analysisResult.getAspects().iterator().next();
+ OutputGroupProvider outputGroupProvider =
+ aspectValue.getConfiguredAspect().getProvider(OutputGroupProvider.class);
+ assertThat(outputGroupProvider).isNotNull();
+ NestedSet<Artifact> names = outputGroupProvider.getOutputGroup("my_result");
+ assertThat(names).isNotEmpty();
+ NestedSet<Artifact> expectedSet = getConfiguredTarget("//test:xxx")
+ .getProvider(OutputGroupProvider.class)
+ .getOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL);
+ assertThat(names).containsExactlyElementsIn(expectedSet);
+ }
+
+
+ @Test
public void testAspectsFromSkylarkRules() throws Exception {
scratch.file(
"test/aspect.bzl",
@@ -617,6 +660,107 @@ public class SkylarkAspectsTest extends AnalysisTestCase {
}
@Test
+ public void outputGroupsFromTwoAspects() throws Exception {
+ scratch.file(
+ "test/aspect.bzl",
+ "def _a1_impl(target, ctx):",
+ " f = ctx.new_file(target.label.name + '_a1.txt')",
+ " ctx.file_action(f, 'f')",
+ " return struct(output_groups = { 'a1_group' : set([f]) })",
+ "",
+ "a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])",
+ "def _rule_impl(ctx):",
+ " if not ctx.attr.dep:",
+ " return struct()",
+ " og = {k:ctx.attr.dep.output_groups[k] for k in ctx.attr.dep.output_groups}",
+ " return struct(output_groups = og)",
+ "my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })",
+ "def _a2_impl(target, ctx):",
+ " g = ctx.new_file(target.label.name + '_a2.txt')",
+ " ctx.file_action(g, 'f')",
+ " return struct(output_groups = { 'a2_group' : set([g]) })",
+ "",
+ "a2 = aspect(implementation=_a2_impl, attr_aspects = ['dep'])",
+ "my_rule2 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a2]) })"
+ );
+ scratch.file(
+ "test/BUILD",
+ "load(':aspect.bzl', 'my_rule1', 'my_rule2')",
+ "my_rule1(name = 'base')",
+ "my_rule1(name = 'xxx', dep = ':base')",
+ "my_rule2(name = 'yyy', dep = ':xxx')"
+ );
+
+
+ AnalysisResult analysisResult = update("//test:yyy");
+ OutputGroupProvider outputGroupProvider =
+ Iterables
+ .getOnlyElement(analysisResult.getTargetsToBuild())
+ .getProvider(OutputGroupProvider.class);
+ assertThat(getOutputGroupContents(outputGroupProvider, "a1_group"))
+ .containsExactly("test/base_a1.txt");
+ assertThat(getOutputGroupContents(outputGroupProvider, "a2_group"))
+ .containsExactly("test/xxx_a2.txt");
+ }
+
+ @Test
+ public void duplicateOutputGroupsFromTwoAspects() throws Exception {
+ scratch.file(
+ "test/aspect.bzl",
+ "def _a1_impl(target, ctx):",
+ " f = ctx.new_file(target.label.name + '_a1.txt')",
+ " ctx.file_action(f, 'f')",
+ " return struct(output_groups = { 'a1_group' : set([f]) })",
+ "",
+ "a1 = aspect(implementation=_a1_impl, attr_aspects = ['dep'])",
+ "def _rule_impl(ctx):",
+ " if not ctx.attr.dep:",
+ " return struct()",
+ " og = {k:ctx.attr.dep.output_groups[k] for k in ctx.attr.dep.output_groups}",
+ " return struct(output_groups = og)",
+ "my_rule1 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a1]) })",
+ "def _a2_impl(target, ctx):",
+ " g = ctx.new_file(target.label.name + '_a2.txt')",
+ " ctx.file_action(g, 'f')",
+ " return struct(output_groups = { 'a1_group' : set([g]) })",
+ "",
+ "a2 = aspect(implementation=_a2_impl, attr_aspects = ['dep'])",
+ "my_rule2 = rule(_rule_impl, attrs = { 'dep' : attr.label(aspects = [a2]) })"
+ );
+ scratch.file(
+ "test/BUILD",
+ "load(':aspect.bzl', 'my_rule1', 'my_rule2')",
+ "my_rule1(name = 'base')",
+ "my_rule1(name = 'xxx', dep = ':base')",
+ "my_rule2(name = 'yyy', dep = ':xxx')"
+ );
+
+
+ reporter.removeHandler(failFastHandler);
+ try {
+ AnalysisResult analysisResult = update("//test:yyy");
+ assertThat(analysisResult.hasError()).isTrue();
+ assertThat(keepGoing()).isTrue();
+ } catch (ViewCreationFailedException e) {
+ // expected.
+ }
+ assertContainsEvent("ERROR /workspace/test/BUILD:3:1: Output group a1_group provided twice");
+ }
+
+
+ private static Iterable<String> getOutputGroupContents(OutputGroupProvider outputGroupProvider,
+ String groupName) {
+ return Iterables.transform(outputGroupProvider.getOutputGroup(groupName),
+ new Function<Artifact, String>() {
+ @Override
+ public String apply(Artifact artifact) {
+ return artifact.getRootRelativePathString();
+ }
+ });
+ }
+
+
+ @Test
public void duplicateSkylarkProviders() throws Exception {
scratch.file(
"test/aspect.bzl",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
index f8c326fa99..9e2d5502f8 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
@@ -43,6 +43,7 @@ import com.google.devtools.build.lib.skyframe.PackageFunction;
import com.google.devtools.build.lib.skyframe.SkyFunctions;
import com.google.devtools.build.lib.skyframe.SkylarkImportLookupFunction;
import com.google.devtools.build.lib.syntax.Runtime;
+import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
@@ -188,6 +189,49 @@ public class SkylarkIntegrationTest extends BuildViewTestCase {
}
@Test
+ public void testOutputGroupsAsDictionary() throws Exception {
+ scratch.file(
+ "test/skylark/extension.bzl",
+ "def _impl(ctx):",
+ " f = ctx.attr.dep.output_groups['_hidden_top_level" + INTERNAL_SUFFIX + "']",
+ " has_key1 = '_hidden_top_level" + INTERNAL_SUFFIX + "' in ctx.attr.dep.output_groups",
+ " has_key2 = 'foobar' in ctx.attr.dep.output_groups",
+ " all_keys = [k for k in ctx.attr.dep.output_groups]",
+ " return struct(result = f, ",
+ " has_key1 = has_key1,",
+ " has_key2 = has_key2,",
+ " all_keys = all_keys,",
+ " output_groups = { 'my_group' : f })",
+ "my_rule = rule(implementation = _impl,",
+ " attrs = { 'dep' : attr.label() })");
+ scratch.file(
+ "test/skylark/BUILD",
+ "load('/test/skylark/extension', 'my_rule')",
+ "cc_binary(name = 'lib', data = ['a.txt'])",
+ "my_rule(name='my', dep = ':lib')");
+ NestedSet<Artifact> hiddenTopLevelArtifacts =
+ getConfiguredTarget("//test/skylark:lib")
+ .getProvider(OutputGroupProvider.class)
+ .getOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL);
+ ConfiguredTarget myTarget = getConfiguredTarget("//test/skylark:my");
+ SkylarkProviders skylarkProviders = myTarget
+ .getProvider(SkylarkProviders.class);
+ SkylarkNestedSet result = (SkylarkNestedSet) skylarkProviders.getValue("result");
+ assertThat(result.getSet(Artifact.class)).containsExactlyElementsIn(hiddenTopLevelArtifacts);
+ assertThat(myTarget.getProvider(OutputGroupProvider.class).getOutputGroup("my_group"))
+ .containsExactlyElementsIn(hiddenTopLevelArtifacts);
+ assertThat(skylarkProviders.getValue("has_key1")).isEqualTo(Boolean.TRUE);
+ assertThat(skylarkProviders.getValue("has_key2")).isEqualTo(Boolean.FALSE);
+ assertThat((SkylarkList) skylarkProviders.getValue("all_keys"))
+ .containsExactly(
+ "_hidden_top_level" + INTERNAL_SUFFIX,
+ "compilation_prerequisites" + INTERNAL_SUFFIX,
+ "files_to_compile" + INTERNAL_SUFFIX,
+ "temp_files" + INTERNAL_SUFFIX);
+ }
+
+
+ @Test
public void testOutputGroupsWithList() throws Exception {
scratch.file(
"test/skylark/extension.bzl",