diff options
author | Ulf Adams <ulfjack@google.com> | 2015-05-04 12:05:57 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2015-05-04 17:51:54 +0000 |
commit | b313a9750d77ea4ccd3cb591131e2311486cb11a (patch) | |
tree | 990b298339cae32fe0fce5649c3669de3cb1966b /src/test/java/com/google/devtools/build/lib/analysis | |
parent | 208df987a0d5a27370691f93b34a5f70f6982cbe (diff) |
Open source a few more analysis tests.
--
MOS_MIGRATED_REVID=92715161
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/analysis')
6 files changed, 734 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/ConfiguredAttributeMapperTest.java b/src/test/java/com/google/devtools/build/lib/analysis/ConfiguredAttributeMapperTest.java new file mode 100644 index 0000000000..3a854c5f42 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/ConfiguredAttributeMapperTest.java @@ -0,0 +1,196 @@ +// Copyright 2015 Google Inc. 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.devtools.build.lib.testutil.MoreAsserts.assertSameContents; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.analysis.config.CompilationMode; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.AttributeMap; +import com.google.devtools.build.lib.packages.Type; +import com.google.devtools.build.lib.syntax.Label; + +import java.util.ArrayList; +import java.util.List; + +/** + * Unit tests for {@link ConfiguredAttributeMapper}. + * + * <p>This is distinct from {@link + * com.google.devtools.build.lib.analysis.select.ConfiguredAttributeMapperCommonTest} because the + * latter needs to inherit from {@link + * com.google.devtools.build.lib.analysis.select.AbstractAttributeMapperTest} to run tests common to + * all attribute mappers. + */ +public class ConfiguredAttributeMapperTest extends BuildViewTestCase { + + /** + * Returns a ConfiguredAttributeMapper bound to the given rule with the target configuration. + */ + private ConfiguredAttributeMapper getMapper(String label) throws Exception { + return ConfiguredAttributeMapper.of( + (RuleConfiguredTarget) getConfiguredTarget(label)); + } + + private void writeConfigRules() throws Exception { + scratch.file("conditions/BUILD", + "config_setting(", + " name = 'a',", + " values = {'compilation_mode': 'opt'})", + "config_setting(", + " name = 'b',", + " values = {'compilation_mode': 'dbg'})"); + } + + /** + * Tests that {@link ConfiguredAttributeMapper#get} only gets the configuration-appropriate + * value. + */ + public void testGetAttribute() throws Exception { + writeConfigRules(); + scratch.file("a/BUILD", + "genrule(", + " name = 'gen',", + " srcs = [],", + " outs = ['out'],", + " cmd = select({", + " '//conditions:a': 'a command',", + " '//conditions:b': 'b command',", + " '" + Type.Selector.DEFAULT_CONDITION_KEY + "': 'default command',", + " }))"); + + useConfiguration("-c", "opt"); + assertEquals("a command", getMapper("//a:gen").get("cmd", Type.STRING)); + + useConfiguration("-c", "dbg"); + assertEquals("b command", getMapper("//a:gen").get("cmd", Type.STRING)); + + useConfiguration("-c", "fastbuild"); + assertEquals("default command", getMapper("//a:gen").get("cmd", Type.STRING)); + } + + /** + * Tests that label visitation only travels down configuration-appropriate paths. + */ + public void testLabelVisitation() throws Exception { + writeConfigRules(); + scratch.file("a/BUILD", + "sh_binary(", + " name = 'bin',", + " srcs = ['bin.sh'],", + " deps = select({", + " '//conditions:a': [':adep'],", + " '//conditions:b': [':bdep'],", + " '" + Type.Selector.DEFAULT_CONDITION_KEY + "': [':defaultdep'],", + " }))", + "sh_library(", + " name = 'adep',", + " srcs = ['adep.sh'])", + "sh_library(", + " name = 'bdep',", + " srcs = ['bdep.sh'])", + "sh_library(", + " name = 'defaultdep',", + " srcs = ['defaultdep.sh'])"); + + final List<Label> visitedLabels = new ArrayList<>(); + AttributeMap.AcceptsLabelAttribute testVisitor = + new AttributeMap.AcceptsLabelAttribute() { + @Override + public void acceptLabelAttribute(Label label, Attribute attribute) { + if (label.toString().contains("//a:")) { // Ignore implicit common dependencies. + visitedLabels.add(label); + } + } + }; + + final Label binSrc = Label.parseAbsolute("//a:bin.sh"); + + useConfiguration("-c", "opt"); + getMapper("//a:bin").visitLabels(testVisitor); + assertSameContents(ImmutableList.of(binSrc, Label.parseAbsolute("//a:adep")), visitedLabels); + + visitedLabels.clear(); + useConfiguration("-c", "dbg"); + getMapper("//a:bin").visitLabels(testVisitor); + assertSameContents(ImmutableList.of(binSrc, Label.parseAbsolute("//a:bdep")), visitedLabels); + + visitedLabels.clear(); + useConfiguration("-c", "fastbuild"); + getMapper("//a:bin").visitLabels(testVisitor); + assertSameContents( + ImmutableList.of(binSrc, Label.parseAbsolute("//a:defaultdep")), visitedLabels); + } + + /** + * Tests that for configurable attributes where the *values* are evaluated in different + * configurations, the configuration checking still uses the original configuration. + */ + public void testConfigurationTransitions() throws Exception { + writeConfigRules(); + scratch.file("a/BUILD", + "genrule(", + " name = 'gen',", + " srcs = [],", + " outs = ['out'],", + " cmd = 'nothing',", + " tools = select({", + " '//conditions:a': [':adep'],", + " '//conditions:b': [':bdep'],", + " '" + Type.Selector.DEFAULT_CONDITION_KEY + "': [':defaultdep'],", + " }))", + "sh_binary(", + " name = 'adep',", + " srcs = ['adep.sh'])", + "sh_binary(", + " name = 'bdep',", + " srcs = ['bdep.sh'])", + "sh_binary(", + " name = 'defaultdep',", + " srcs = ['defaultdep.sh'])"); + useConfiguration("-c", "dbg"); + + // Target configuration is in dbg mode, so we should match //conditions:b: + assertSameContents( + ImmutableList.of(Label.parseAbsolute("//a:bdep")), + getMapper("//a:gen").get("tools", Type.LABEL_LIST)); + + // Verify the "tools" dep uses a different configuration that's not also in "dbg": + assertEquals(Attribute.ConfigurationTransition.HOST, + getTarget("//a:gen").getAssociatedRule().getRuleClassObject() + .getAttributeByName("tools").getConfigurationTransition()); + assertEquals(CompilationMode.OPT, getHostConfiguration().getCompilationMode()); + } + + public void testConcatenatedSelects() throws Exception { + scratch.file("hello/BUILD", + "config_setting(name = 'a', values = {'define': 'foo=a'})", + "config_setting(name = 'b', values = {'define': 'foo=b'})", + "config_setting(name = 'c', values = {'define': 'bar=c'})", + "config_setting(name = 'd', values = {'define': 'bar=d'})", + "genrule(", + " name = 'gen',", + " srcs = select({':a': ['a.in'], ':b': ['b.in']})", + " + select({':c': ['c.in'], ':d': ['d.in']}),", + " outs = ['out'],", + " cmd = 'nothing',", + ")"); + useConfiguration("--define", "foo=a", "--define", "bar=d"); + assertSameContents( + ImmutableList.of(Label.parseAbsolute("//hello:a.in"), Label.parseAbsolute("//hello:d.in")), + getMapper("//hello:gen").get("srcs", Type.LABEL_LIST)); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/analysis/select/AbstractAttributeMapperTest.java b/src/test/java/com/google/devtools/build/lib/analysis/select/AbstractAttributeMapperTest.java new file mode 100644 index 0000000000..f15d1a6a6c --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/select/AbstractAttributeMapperTest.java @@ -0,0 +1,146 @@ +// Copyright 2015 Google Inc. 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.select; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.devtools.build.lib.events.util.EventCollectionApparatus; +import com.google.devtools.build.lib.packages.AbstractAttributeMapper; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.AttributeContainer; +import com.google.devtools.build.lib.packages.AttributeMap; +import com.google.devtools.build.lib.packages.Package; +import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.Type; +import com.google.devtools.build.lib.packages.util.PackageFactoryApparatus; +import com.google.devtools.build.lib.syntax.Label; +import com.google.devtools.build.lib.testutil.FoundationTestCase; +import com.google.devtools.build.lib.testutil.MoreAsserts; +import com.google.devtools.build.lib.testutil.Scratch; +import com.google.devtools.build.lib.vfs.Path; + +import java.util.List; + +/** + * Unit tests for {@link AbstractAttributeMapper}. + */ +public class AbstractAttributeMapperTest extends FoundationTestCase { + + private Package pkg; + protected Rule rule; + protected AbstractAttributeMapper mapper; + + private static class TestMapper extends AbstractAttributeMapper { + public TestMapper(Package pkg, RuleClass ruleClass, Label ruleLabel, + AttributeContainer attributes) { + super(pkg, ruleClass, ruleLabel, attributes); + } + } + + protected Rule createRule(String pkgPath, String ruleName, String... ruleDef) throws Exception { + Scratch scratch = new Scratch(); + EventCollectionApparatus events = new EventCollectionApparatus(); + PackageFactoryApparatus packages = new PackageFactoryApparatus(events, scratch); + + Path buildFile = scratch.file(pkgPath + "/BUILD", ruleDef); + pkg = packages.createPackage(pkgPath, buildFile); + return pkg.getRule(ruleName); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + rule = createRule("x", "myrule", + "cc_binary(name = 'myrule',", + " srcs = ['a', 'b', 'c'])"); + RuleClass ruleClass = rule.getRuleClassObject(); + mapper = new TestMapper(pkg, ruleClass, rule.getLabel(), rule.getAttributeContainer()); + } + + public void testRuleProperties() throws Exception { + assertEquals(rule.getName(), mapper.getName()); + assertEquals(rule.getLabel(), mapper.getLabel()); + } + + public void testPackageDefaultProperties() throws Exception { + assertEquals(pkg.getDefaultHdrsCheck(), mapper.getPackageDefaultHdrsCheck()); + assertEquals(pkg.getDefaultTestOnly(), mapper.getPackageDefaultTestOnly()); + assertEquals(pkg.getDefaultDeprecation(), mapper.getPackageDefaultDeprecation()); + } + + public void testAttributeTypeChecking() throws Exception { + // Good typing: + mapper.get("srcs", Type.LABEL_LIST); + + // Bad typing: + try { + mapper.get("srcs", Type.BOOLEAN); + fail("Expected type mismatch to trigger an exception"); + } catch (IllegalArgumentException e) { + // Expected. + } + + // Unknown attribute: + try { + mapper.get("nonsense", Type.BOOLEAN); + fail("Expected non-existent type to trigger an exception"); + } catch (IllegalArgumentException e) { + // Expected. + } + } + + public void testGetAttributeType() throws Exception { + assertEquals(Type.LABEL_LIST, mapper.getAttributeType("srcs")); + assertNull(mapper.getAttributeType("nonsense")); + } + + public void testGetAttributeDefinition() { + assertEquals("srcs", mapper.getAttributeDefinition("srcs").getName()); + assertNull(mapper.getAttributeDefinition("nonsense")); + } + + public void testIsAttributeExplicitlySpecified() throws Exception { + assertTrue(mapper.isAttributeValueExplicitlySpecified("srcs")); + assertFalse(mapper.isAttributeValueExplicitlySpecified("deps")); + assertFalse(mapper.isAttributeValueExplicitlySpecified("nonsense")); + } + + protected static class VisitationRecorder implements AttributeMap.AcceptsLabelAttribute { + public List<String> labelsVisited = Lists.newArrayList(); + @Override + public void acceptLabelAttribute(Label label, Attribute attribute) { + if (attribute.getName().equals("srcs")) { + labelsVisited.add(label.toString()); + } + } + } + + public void testVisitation() throws Exception { + VisitationRecorder recorder = new VisitationRecorder(); + mapper.visitLabels(recorder); + MoreAsserts.assertSameContents( + ImmutableList.of("//x:a", "//x:b", "//x:c"), recorder.labelsVisited); + } + + public void testComputedDefault() throws Exception { + // Should return a valid ComputedDefault instance since this is a computed default: + assertThat(mapper.getComputedDefault("$stl", Type.LABEL)) + .isInstanceOf(Attribute.ComputedDefault.class); + // Should return null since this *isn't* a computed default: + assertNull(mapper.getComputedDefault("srcs", Type.LABEL_LIST)); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/analysis/select/AggregatingAttributeMapperTest.java b/src/test/java/com/google/devtools/build/lib/analysis/select/AggregatingAttributeMapperTest.java new file mode 100644 index 0000000000..e894939f62 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/select/AggregatingAttributeMapperTest.java @@ -0,0 +1,155 @@ +// Copyright 2015 Google Inc. 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.select; + +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertSameContents; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.packages.AggregatingAttributeMapper; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.packages.Type; +import com.google.devtools.build.lib.syntax.Label; +import com.google.devtools.build.lib.testutil.TestConstants; + +/** + * Unit tests for {@link AggregatingAttributeMapper}. + */ +public class AggregatingAttributeMapperTest extends AbstractAttributeMapperTest { + + @Override + public void setUp() throws Exception { + super.setUp(); + // Run AbstractAttributeMapper tests through an AggregatingAttributeMapper. + mapper = AggregatingAttributeMapper.of(rule); + } + + /** + * Tests that {@link AggregatingAttributeMapper#visitAttribute} returns an + * attribute's sole value when declared directly (i.e. not as a configurable dict). + */ + public void testGetPossibleValuesDirectAttribute() throws Exception { + Rule rule = createRule("a", "myrule", + "sh_binary(name = 'myrule',", + " srcs = ['a.sh'])"); + assertSameContents( + ImmutableList.of(ImmutableList.of(Label.create("a", "a.sh"))), + AggregatingAttributeMapper.of(rule).visitAttribute("srcs", Type.LABEL_LIST)); + } + + /** + * Tests that {@link AggregatingAttributeMapper#visitAttribute} returns + * every possible value that a configurable attribute can resolve to. + */ + public void testGetPossibleValuesConfigurableAttribute() throws Exception { + Rule rule = createRule("a", "myrule", + "sh_binary(name = 'myrule',", + " srcs = select({", + " '//conditions:a': ['a.sh'],", + " '//conditions:b': ['b.sh'],", + " '" + Type.Selector.DEFAULT_CONDITION_KEY + "': ['default.sh'],", + " }))"); + assertSameContents( + ImmutableList.of( + ImmutableList.of(Label.create("a", "a.sh")), + ImmutableList.of(Label.create("a", "b.sh")), + ImmutableList.of(Label.create("a", "default.sh"))), + AggregatingAttributeMapper.of(rule).visitAttribute("srcs", Type.LABEL_LIST)); + } + + public void testGetPossibleValuesWithConcatenatedSelects() throws Exception { + Rule rule = createRule("a", "myrule", + "sh_binary(name = 'myrule',", + " srcs = select({", + " '//conditions:a1': ['a1.sh'],", + " '//conditions:b1': ['b1.sh']})", + " + select({", + " '//conditions:a2': ['a2.sh'],", + " '//conditions:b2': ['b2.sh']})", + " )"); + assertSameContents( + ImmutableList.of( + ImmutableList.of(Label.create("a", "a1.sh"), Label.create("a", "a2.sh")), + ImmutableList.of(Label.create("a", "a1.sh"), Label.create("a", "b2.sh")), + ImmutableList.of(Label.create("a", "b1.sh"), Label.create("a", "a2.sh")), + ImmutableList.of(Label.create("a", "b1.sh"), Label.create("a", "b2.sh"))), + AggregatingAttributeMapper.of(rule).visitAttribute("srcs", Type.LABEL_LIST)); + } + + /** + * Tests that, on rule visitation, {@link AggregatingAttributeMapper} visits *every* possible + * value in a configurable attribute (including configuration key labels). + */ + public void testVisitationConfigurableAttribute() throws Exception { + Rule rule = createRule("a", "myrule", + "sh_binary(name = 'myrule',", + " srcs = select({", + " '//conditions:a': ['a.sh'],", + " '//conditions:b': ['b.sh'],", + " '" + Type.Selector.DEFAULT_CONDITION_KEY + "': ['default.sh'],", + " }))"); + + VisitationRecorder recorder = new VisitationRecorder(); + AggregatingAttributeMapper.of(rule).visitLabels(recorder); + assertSameContents( + ImmutableList.of( + "//a:a.sh", "//a:b.sh", "//a:default.sh", "//conditions:a", "//conditions:b"), + recorder.labelsVisited); + } + + public void testGetReachableLabels() throws Exception { + Rule rule = createRule("x", "main", + "cc_binary(", + " name = 'main',", + " srcs = select({", + " '//conditions:a': ['a.cc'],", + " '//conditions:b': ['b.cc']})", + " + ", + " ['always.cc']", + " + ", + " select({", + " '//conditions:c': ['c.cc'],", + " '//conditions:d': ['d.cc'],", + " '" + Type.Selector.DEFAULT_CONDITION_KEY + "': ['default.cc'],", + " }))"); + + ImmutableList<Label> valueLabels = ImmutableList.of( + Label.create("x", "a.cc"), Label.create("x", "b.cc"), Label.create("x", "always.cc"), + Label.create("x", "c.cc"), Label.create("x", "d.cc"), Label.create("x", "default.cc")); + ImmutableList<Label> keyLabels = ImmutableList.of( + Label.create("conditions", "a"), Label.create("conditions", "b"), + Label.create("conditions", "c"), Label.create("conditions", "d")); + + AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule); + assertSameContents( + Iterables.concat(valueLabels, keyLabels), + mapper.getReachableLabels("srcs", true)); + assertSameContents(valueLabels, mapper.getReachableLabels("srcs", false)); + } + + public void testDuplicateCheckOnNullValues() throws Exception { + if (TestConstants.THIS_IS_BAZEL) { + return; + } + Rule rule = createRule("x", "main", + "java_binary(", + " name = 'main',", + " srcs = ['main.java'])"); + AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule); + Attribute launcherAttribute = mapper.getAttributeDefinition("launcher"); + assertNull(mapper.get(launcherAttribute.getName(), launcherAttribute.getType())); + assertSameContents(ImmutableList.of(), mapper.checkForDuplicateLabels(launcherAttribute)); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/analysis/select/ConfiguredAttributeMapperCommonTest.java b/src/test/java/com/google/devtools/build/lib/analysis/select/ConfiguredAttributeMapperCommonTest.java new file mode 100644 index 0000000000..041cdbe362 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/select/ConfiguredAttributeMapperCommonTest.java @@ -0,0 +1,36 @@ +// Copyright 2015 Google Inc. 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.select; + +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.analysis.ConfiguredAttributeMapper; +import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider; +import com.google.devtools.build.lib.packages.AbstractAttributeMapper; + +/** + * Tests that {@link ConfiguredAttributeMapper} fulfills all behavior expected + * of {@link AbstractAttributeMapper}. + * + * <p>This is distinct from {@link + * com.google.devtools.build.lib.analysis.ConfiguredAttributeMapperTest} because the latter needs to + * inherit from {@link com.google.devtools.build.lib.analysis.util.BuildViewTestCase} to run tests + * with build configurations. + */ +public class ConfiguredAttributeMapperCommonTest extends AbstractAttributeMapperTest { + @Override + public void setUp() throws Exception { + super.setUp(); + mapper = ConfiguredAttributeMapper.of(rule, ImmutableSet.<ConfigMatchingProvider>of()); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/analysis/select/NonconfigurableAttributeMapperTest.java b/src/test/java/com/google/devtools/build/lib/analysis/select/NonconfigurableAttributeMapperTest.java new file mode 100644 index 0000000000..01ef88d58e --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/select/NonconfigurableAttributeMapperTest.java @@ -0,0 +1,52 @@ +// Copyright 2015 Google Inc. 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.select; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; +import com.google.devtools.build.lib.packages.Type; + +/** + * Unit tests for {@link NonconfigurableAttributeMapper}. + */ +public class NonconfigurableAttributeMapperTest extends AbstractAttributeMapperTest { + + @Override + public void setUp() throws Exception { + super.setUp(); + rule = createRule("x", "myrule", + "cc_binary(", + " name = 'myrule',", + " srcs = ['a', 'b', 'c'],", + " linkstatic = 1,", + " deprecation = \"this rule is deprecated!\")"); + } + + public void testGetNonconfigurableAttribute() throws Exception { + assertEquals("this rule is deprecated!", + NonconfigurableAttributeMapper.of(rule).get("deprecation", Type.STRING)); + } + + public void testGetConfigurableAttribute() throws Exception { + try { + NonconfigurableAttributeMapper.of(rule).get("linkstatic", Type.BOOLEAN); + fail("Expected NonconfigurableAttributeMapper to fail on a configurable attribute type"); + } catch (IllegalStateException e) { + // Expected outcome. + assertThat(e).hasMessage( + "Attribute 'linkstatic' is potentially configurable - not allowed here"); + } + } +} diff --git a/src/test/java/com/google/devtools/build/lib/analysis/select/RawAttributeMapperTest.java b/src/test/java/com/google/devtools/build/lib/analysis/select/RawAttributeMapperTest.java new file mode 100644 index 0000000000..b1c02d4281 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/select/RawAttributeMapperTest.java @@ -0,0 +1,149 @@ +// Copyright 2015 Google Inc. 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.select; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.devtools.build.lib.testutil.MoreAsserts.assertSameContents; + +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.AttributeMap; +import com.google.devtools.build.lib.packages.RawAttributeMapper; +import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.packages.Type; +import com.google.devtools.build.lib.syntax.Label; + +import java.util.List; + +/** + * Unit tests for {@link RawAttributeMapper}. + */ +public class RawAttributeMapperTest extends AbstractAttributeMapperTest { + + @Override + public void setUp() throws Exception { + super.setUp(); + // Run AbstractAttributeMapper tests through a RawAttributeMapper. + mapper = RawAttributeMapper.of(rule); + } + + private Rule setupGenRule() throws Exception { + return createRule("x", "myrule", + "sh_binary(", + " name = 'myrule',", + " srcs = select({", + " '//conditions:a': ['a.sh'],", + " '//conditions:b': ['b.sh'],", + " '" + Type.Selector.DEFAULT_CONDITION_KEY + "': ['default.sh'],", + " }),", + " data = [ ':data_a', ':data_b' ])"); + } + + public void testGetAttribute() throws Exception { + RawAttributeMapper rawMapper = RawAttributeMapper.of(setupGenRule()); + List<Label> value = rawMapper.get("data", Type.LABEL_LIST); + assertNotNull(value); + assertThat(value).containsExactly(Label.create("x", "data_a"), Label.create("x", "data_b")); + + // Configurable attribute: trying to directly access from a RawAttributeMapper throws a + // type mismatch exception. + try { + rawMapper.get("srcs", Type.LABEL_LIST); + fail("Expected srcs lookup to fail since the returned type is a SelectorList and not a list"); + } catch (IllegalArgumentException e) { + assertThat(e.getCause().getMessage()) + .contains("SelectorList cannot be cast to java.util.List"); + } + } + + @Override + public void testGetAttributeType() throws Exception { + RawAttributeMapper rawMapper = RawAttributeMapper.of(setupGenRule()); + assertEquals(Type.LABEL_LIST, rawMapper.getAttributeType("data")); // not configurable + assertEquals(Type.LABEL_LIST, rawMapper.getAttributeType("srcs")); // configurable + } + + public void testConfigurabilityCheck() throws Exception { + RawAttributeMapper rawMapper = RawAttributeMapper.of(setupGenRule()); + assertFalse(rawMapper.isConfigurable("data", Type.LABEL_LIST)); + assertTrue(rawMapper.isConfigurable("srcs", Type.LABEL_LIST)); + } + + /** + * Tests that RawAttributeMapper can't handle label visitation with configurable attributes. + */ + public void testVisitLabels() throws Exception { + RawAttributeMapper rawMapper = RawAttributeMapper.of(setupGenRule()); + try { + rawMapper.visitLabels(new AttributeMap.AcceptsLabelAttribute() { + @Override + public void acceptLabelAttribute(Label label, Attribute attribute) { + // Nothing to do. + } + }); + fail("Expected label visitation to fail since one attribute is configurable"); + } catch (IllegalArgumentException e) { + assertThat(e.getCause().getMessage()) + .contains("SelectorList cannot be cast to java.util.List"); + } + } + + public void testGetConfigurabilityKeys() throws Exception { + RawAttributeMapper rawMapper = RawAttributeMapper.of(setupGenRule()); + assertSameContents( + ImmutableSet.of( + Label.parseAbsolute("//conditions:a"), + Label.parseAbsolute("//conditions:b"), + Label.parseAbsolute("//conditions:default")), + rawMapper.getConfigurabilityKeys("srcs", Type.LABEL_LIST)); + assertThat(rawMapper.getConfigurabilityKeys("data", Type.LABEL_LIST)).isEmpty(); + } + + public void testGetMergedValues() throws Exception { + Rule rule = createRule("x", "myrule", + "sh_binary(", + " name = 'myrule',", + " srcs = select({", + " '//conditions:a': ['a.sh', 'b.sh'],", + " '//conditions:b': ['b.sh', 'c.sh'],", + " }))"); + RawAttributeMapper rawMapper = RawAttributeMapper.of(rule); + assertThat(rawMapper.getMergedValues("srcs", Type.LABEL_LIST)).containsExactly( + Label.parseAbsolute("//x:a.sh"), + Label.parseAbsolute("//x:b.sh"), + Label.parseAbsolute("//x:c.sh")) + .inOrder(); + } + + public void testMergedValuesWithConcatenatedSelects() throws Exception { + Rule rule = createRule("x", "myrule", + "sh_binary(", + " name = 'myrule',", + " srcs = select({", + " '//conditions:a1': ['a1.sh'],", + " '//conditions:b1': ['b1.sh', 'another_b1.sh']})", + " + select({", + " '//conditions:a2': ['a2.sh'],", + " '//conditions:b2': ['b2.sh']})", + " )"); + RawAttributeMapper rawMapper = RawAttributeMapper.of(rule); + assertThat(rawMapper.getMergedValues("srcs", Type.LABEL_LIST)).containsExactly( + Label.parseAbsolute("//x:a1.sh"), + Label.parseAbsolute("//x:b1.sh"), + Label.parseAbsolute("//x:another_b1.sh"), + Label.parseAbsolute("//x:a2.sh"), + Label.parseAbsolute("//x:b2.sh")) + .inOrder(); + } +} |