aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/packages/RuleFactoryTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/packages/RuleFactoryTest.java')
-rw-r--r--src/test/java/com/google/devtools/build/lib/packages/RuleFactoryTest.java245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RuleFactoryTest.java b/src/test/java/com/google/devtools/build/lib/packages/RuleFactoryTest.java
new file mode 100644
index 0000000000..a495ea026f
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/packages/RuleFactoryTest.java
@@ -0,0 +1,245 @@
+// Copyright 2015 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.packages;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.events.Reporter;
+import com.google.devtools.build.lib.packages.util.PackageLoadingTestCase;
+import com.google.devtools.build.lib.syntax.Type;
+import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+import com.google.devtools.build.lib.vfs.Path;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RuleFactoryTest extends PackageLoadingTestCase {
+
+ private ConfiguredRuleClassProvider provider = TestRuleClassProvider.getRuleClassProvider();
+ private RuleFactory ruleFactory = new RuleFactory(provider);
+
+ public static final Location LOCATION_42 = Location.fromFileAndOffsets(null, 42, 42);
+
+ public void testCreateRule() throws Exception {
+ Path myPkgPath = scratch.resolve("/foo/workspace/mypkg/BUILD");
+ Package.Builder pkgBuilder =
+ new Package.Builder(PackageIdentifier.createInDefaultRepo("mypkg"), "TESTING")
+ .setFilename(myPkgPath)
+ .setMakeEnv(new MakeEnvironment.Builder());
+
+ Map<String, Object> attributeValues = new HashMap<>();
+ attributeValues.put("name", "foo");
+ attributeValues.put("alwayslink", true);
+
+ Rule rule =
+ RuleFactory.createAndAddRule(
+ pkgBuilder,
+ provider.getRuleClassMap().get("cc_library"),
+ attributeValues,
+ new Reporter(),
+ /*ast=*/ null,
+ LOCATION_42,
+ /*env=*/ null);
+
+ assertSame(rule, rule.getAssociatedRule());
+
+ // pkg.getRules() = [rule]
+ Package pkg = pkgBuilder.build();
+ assertThat(Sets.newHashSet(pkg.getTargets(Rule.class))).hasSize(1);
+ assertEquals(rule, pkg.getTargets(Rule.class).iterator().next());
+
+ assertSame(rule, pkg.getTarget("foo"));
+
+ assertEquals(Label.parseAbsolute("//mypkg:foo"), rule.getLabel());
+ assertEquals("foo", rule.getName());
+
+ assertEquals("cc_library", rule.getRuleClass());
+ assertEquals("cc_library rule", rule.getTargetKind());
+ assertEquals(42, rule.getLocation().getStartOffset());
+ assertNull(rule.getSyntaxTree());
+ assertFalse(rule.containsErrors());
+
+ // Attr with explicitly-supplied value:
+ AttributeMap attributes = RawAttributeMapper.of(rule);
+ assertTrue(attributes.get("alwayslink", Type.BOOLEAN));
+ try {
+ attributes.get("alwayslink", Type.STRING); // type error: boolean, not string!
+ fail();
+ } catch (Exception e) {
+ /* Class of exception and error message are not specified by API. */
+ }
+ try {
+ attributes.get("nosuchattr", Type.STRING); // no such attribute
+ fail();
+ } catch (Exception e) {
+ /* Class of exception and error message are not specified by API. */
+ }
+
+ // Attrs with default values:
+ // cc_library linkstatic default=0 according to build encyc.
+ assertFalse(attributes.get("linkstatic", Type.BOOLEAN));
+ assertFalse(attributes.get("testonly", Type.BOOLEAN));
+ assertThat(attributes.get("srcs", BuildType.LABEL_LIST)).isEmpty();
+ }
+
+ public void testCreateWorkspaceRule() throws Exception {
+ Path myPkgPath = scratch.resolve("/foo/workspace/WORKSPACE");
+ Package.Builder pkgBuilder = Package.newExternalPackageBuilder(myPkgPath, "TESTING");
+
+ Map<String, Object> attributeValues = new HashMap<>();
+ attributeValues.put("name", "foo");
+ attributeValues.put("actual", "//foo:bar");
+
+ Rule rule =
+ RuleFactory.createAndAddRule(
+ pkgBuilder,
+ provider.getRuleClassMap().get("bind"),
+ attributeValues,
+ new Reporter(),
+ /*ast=*/ null,
+ Location.fromFileAndOffsets(myPkgPath.asFragment(), 42, 42),
+ /*env=*/ null);
+ assertFalse(rule.containsErrors());
+ }
+
+ public void testWorkspaceRuleFailsInBuildFile() throws Exception {
+ Path myPkgPath = scratch.resolve("/foo/workspace/mypkg/BUILD");
+ Package.Builder pkgBuilder =
+ new Package.Builder(PackageIdentifier.createInDefaultRepo("mypkg"), "TESTING")
+ .setFilename(myPkgPath)
+ .setMakeEnv(new MakeEnvironment.Builder());
+
+ Map<String, Object> attributeValues = new HashMap<>();
+ attributeValues.put("name", "foo");
+ attributeValues.put("actual", "//bar:baz");
+
+ try {
+ RuleFactory.createAndAddRule(
+ pkgBuilder,
+ provider.getRuleClassMap().get("bind"),
+ attributeValues,
+ new Reporter(),
+ /*ast=*/ null,
+ LOCATION_42,
+ /*env=*/ null);
+ fail();
+ } catch (RuleFactory.InvalidRuleException e) {
+ assertThat(e.getMessage()).contains("must be in the WORKSPACE file");
+ }
+ }
+
+ public void testBuildRuleFailsInWorkspaceFile() throws Exception {
+ Path myPkgPath = scratch.resolve("/foo/workspace/WORKSPACE");
+ Package.Builder pkgBuilder =
+ new Package.Builder(PackageIdentifier.createInDefaultRepo("mypkg"), "TESTING")
+ .setFilename(myPkgPath)
+ .setMakeEnv(new MakeEnvironment.Builder());
+
+ Map<String, Object> attributeValues = new HashMap<>();
+ attributeValues.put("name", "foo");
+ attributeValues.put("alwayslink", true);
+
+ try {
+ RuleFactory.createAndAddRule(
+ pkgBuilder,
+ provider.getRuleClassMap().get("cc_library"),
+ attributeValues,
+ new Reporter(),
+ /*ast=*/ null,
+ Location.fromFileAndOffsets(myPkgPath.asFragment(), 42, 42),
+ /*env=*/ null);
+ fail();
+ } catch (RuleFactory.InvalidRuleException e) {
+ assertThat(e.getMessage()).contains("cannot be in the WORKSPACE file");
+ }
+ }
+
+ private void assertAttr(RuleClass ruleClass, String attrName, Type<?> type) throws Exception {
+ assertTrue(
+ "Rule class '"
+ + ruleClass.getName()
+ + "' should have attribute '"
+ + attrName
+ + "' of type '"
+ + type
+ + "'",
+ ruleClass.hasAttr(attrName, type));
+ }
+
+ public void testOutputFileNotEqualDot() throws Exception {
+ Path myPkgPath = scratch.resolve("/foo");
+ Package.Builder pkgBuilder =
+ new Package.Builder(PackageIdentifier.createInDefaultRepo("mypkg"), "TESTING")
+ .setFilename(myPkgPath)
+ .setMakeEnv(new MakeEnvironment.Builder());
+
+ Map<String, Object> attributeValues = new HashMap<>();
+ attributeValues.put("outs", Lists.newArrayList("."));
+ attributeValues.put("name", "some");
+ try {
+ RuleFactory.createAndAddRule(
+ pkgBuilder,
+ provider.getRuleClassMap().get("genrule"),
+ attributeValues,
+ new Reporter(),
+ /*ast=*/ null,
+ Location.fromFileAndOffsets(myPkgPath.asFragment(), 42, 42),
+ /*env=*/ null);
+ fail();
+ } catch (RuleFactory.InvalidRuleException e) {
+ assertTrue(e.getMessage(), e.getMessage().contains("output file name can't be equal '.'"));
+ }
+ }
+
+ /**
+ * Tests mandatory attribute definitions for test rules.
+ */
+ // TODO(ulfjack): Remove this check when we switch over to the builder
+ // pattern, which will always guarantee that these attributes are present.
+ public void testTestRules() throws Exception {
+ Path myPkgPath = scratch.resolve("/foo/workspace/mypkg/BUILD");
+ Package pkg =
+ new Package.Builder(PackageIdentifier.createInDefaultRepo("mypkg"), "TESTING")
+ .setFilename(myPkgPath)
+ .setMakeEnv(new MakeEnvironment.Builder())
+ .build();
+
+ for (String name : ruleFactory.getRuleClassNames()) {
+ // Create rule instance directly so we'll avoid mandatory attribute check yet will be able
+ // to use TargetUtils.isTestRule() method to identify test rules.
+ RuleClass ruleClass = ruleFactory.getRuleClass(name);
+ Rule rule =
+ new Rule(
+ pkg,
+ pkg.createLabel("myrule"),
+ ruleClass,
+ null,
+ Location.fromFile(myPkgPath),
+ new AttributeContainer(ruleClass));
+ if (TargetUtils.isTestRule(rule)) {
+ assertAttr(ruleClass, "tags", Type.STRING_LIST);
+ assertAttr(ruleClass, "size", Type.STRING);
+ assertAttr(ruleClass, "flaky", Type.BOOLEAN);
+ assertAttr(ruleClass, "shard_count", Type.INTEGER);
+ assertAttr(ruleClass, "local", Type.BOOLEAN);
+ }
+ }
+ }
+}