diff options
author | 2017-07-26 15:43:59 +0200 | |
---|---|---|
committer | 2017-07-26 16:22:28 +0200 | |
commit | b344e2c5a97b0eeacb796db20bb894f21283d358 (patch) | |
tree | f9c10b7fcf10bba3ce6f5a3b2da9fd45397451f3 /src/test/java/com | |
parent | 2f8b1e519ccc4ead62be57d245d559029265a9a7 (diff) |
Package whitelisting: New implementation for feature whitelisting
This builds on top of mstaib's idea to use package groups to whitelist
projects which can use certain features in the analysis phase. Instead of using configurations and a flag, this way of implementing whitelists requires using two helper methods, one that adds an implicit attribute to every rule that has functionality that must be whitelisted and a different method to check whether a given package is whitelisted to use that feature.
RELNOTES:none
PiperOrigin-RevId: 163200890
Diffstat (limited to 'src/test/java/com')
4 files changed, 288 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/BUILD b/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/BUILD new file mode 100644 index 0000000000..cd09c6531f --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/BUILD @@ -0,0 +1,34 @@ +# Description: +# Tests for whitelisting mechanism for rolling out and deprecating pieces of Bazel functionality. + +licenses(["notice"]) # Apache 2.0 + +filegroup( + name = "srcs", + srcs = glob( + ["**"], + ), + visibility = ["//src/test/java/com/google/devtools/build/lib:__pkg__"], +) + +java_test( + name = "WhitelistingTests", + srcs = glob(["*.java"]), + test_class = "com.google.devtools.build.lib.AllTests", + deps = [ + "//src/main/java/com/google/devtools/build/lib:build-base", + "//src/main/java/com/google/devtools/build/lib:collect", + "//src/main/java/com/google/devtools/build/lib:packages-internal", + "//src/main/java/com/google/devtools/build/lib:util", + "//src/main/java/com/google/devtools/build/lib/analysis/whitelisting", + "//src/main/java/com/google/devtools/build/lib/cmdline", + "//src/main/java/com/google/devtools/common/options", + "//src/test/java/com/google/devtools/build/lib:analysis_testutil", + "//src/test/java/com/google/devtools/build/lib:packages_testutil", + "//src/test/java/com/google/devtools/build/lib:test_runner", + "//third_party:guava", + "//third_party:guava-testlib", + "//third_party:junit4", + "//third_party:truth", + ], +) diff --git a/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistCachingTest.java b/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistCachingTest.java new file mode 100644 index 0000000000..164e6f60d3 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistCachingTest.java @@ -0,0 +1,65 @@ +// 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.analysis.whitelisting; + +import static org.junit.Assert.fail; + +import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; +import com.google.devtools.build.lib.analysis.ViewCreationFailedException; +import com.google.devtools.build.lib.analysis.util.AnalysisCachingTestBase; +import com.google.devtools.build.lib.testutil.TestRuleClassProvider; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests that whitelists are invalidated after change. */ +@RunWith(JUnit4.class) +public final class WhitelistCachingTest extends AnalysisCachingTestBase { + + @Before + public void addDummyRule() throws Exception { + ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder(); + TestRuleClassProvider.addStandardRules(builder); + builder.addRuleDefinition(new WhitelistDummyRule()); + useRuleClassProvider(builder.build()); + } + + @Test + public void testStillCorrectAfterChangesToWhitelist() throws Exception { + scratch.file("whitelist/BUILD", "package_group(name='whitelist', packages=[])"); + scratch.file("x/BUILD", "rule_with_whitelist(name='x')"); + + reporter.removeHandler(failFastHandler); + try { + update("//x:x"); + fail(); + } catch (ViewCreationFailedException e) { + // expected + } + assertContainsEvent("Dummy is not available."); + eventCollector.clear(); + reporter.addHandler(failFastHandler); + scratch.overwriteFile( + "whitelist/BUILD", + "package_group(", + " name='whitelist',", + " packages=[", + " '//...'", + " ])"); + update("//x:x"); + assertNoEvents(); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistDummyRule.java b/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistDummyRule.java new file mode 100644 index 0000000000..e91cf9a739 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistDummyRule.java @@ -0,0 +1,61 @@ +// 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.analysis.whitelisting; + +import com.google.devtools.build.lib.analysis.BaseRuleClasses; +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; +import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.RuleDefinition; +import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; +import com.google.devtools.build.lib.analysis.RunfilesProvider; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.collect.nestedset.Order; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.RuleClass.Builder; +import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; + +/** Definition of a test rule that uses whitelists. */ +public final class WhitelistDummyRule implements RuleDefinition, RuleConfiguredTargetFactory { + + @Override + public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { + return builder + .add( + Whitelist.getAttributeFromWhitelistName("dummy", env.getLabel("//whitelist:whitelist"))) + .build(); + } + + @Override + public Metadata getMetadata() { + return RuleDefinition.Metadata.builder() + .name("rule_with_whitelist") + .ancestors(BaseRuleClasses.RuleBase.class) + .factoryClass(WhitelistDummyRule.class) + .build(); + } + + @Override + public ConfiguredTarget create(RuleContext ruleContext) + throws InterruptedException, RuleErrorException { + if (!Whitelist.isAvailable(ruleContext, "dummy")) { + ruleContext.ruleError("Dummy is not available."); + } + return new RuleConfiguredTargetBuilder(ruleContext) + .setFilesToBuild(NestedSetBuilder.emptySet(Order.STABLE_ORDER)) + .addProvider(RunfilesProvider.EMPTY) + .build(); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistTest.java b/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistTest.java new file mode 100644 index 0000000000..cc874077ac --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/analysis/whitelisting/WhitelistTest.java @@ -0,0 +1,128 @@ +// 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.analysis.whitelisting; + +import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.testutil.TestRuleClassProvider; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for the Whitelist methods. */ +@RunWith(JUnit4.class) +public final class WhitelistTest extends BuildViewTestCase { + + @Override + protected ConfiguredRuleClassProvider getRuleClassProvider() { + ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder(); + TestRuleClassProvider.addStandardRules(builder); + return builder.addRuleDefinition(new WhitelistDummyRule()).build(); + } + + @Test + public void testDirectPackage() throws Exception { + scratch.file( + "whitelist/BUILD", + "package_group(", + " name='whitelist',", + " packages=[", + " '//direct',", + " ])"); + scratch.file("direct/BUILD", "rule_with_whitelist(name='x')"); + getConfiguredTarget("//direct:x"); + assertNoEvents(); + } + + @Test + public void testRecursivePackage() throws Exception { + scratch.file( + "whitelist/BUILD", + "package_group(", + " name='whitelist',", + " packages=[", + " '//recursive/...',", + " ])"); + scratch.file("recursive/x/BUILD", "rule_with_whitelist(name='y')"); + getConfiguredTarget("//recursive/x:y"); + assertNoEvents(); + } + + @Test + public void testAbsentPackage() throws Exception { + scratch.file( + "whitelist/BUILD", + "package_group(", + " name='whitelist',", + " packages=[", + " '//somethingelse/...',", + " ])"); + checkError("absent", "x", "Dummy is not available.", "rule_with_whitelist(name='x')"); + } + + @Test + public void testCatchAll() throws Exception { + scratch.file( + "whitelist/BUILD", + "package_group(", + " name='whitelist',", + " packages=[", + " '//...',", + " ])"); + scratch.file("notingroup/BUILD", "rule_with_whitelist(name='x')"); + getConfiguredTarget("//notingroup:x"); + assertNoEvents(); + } + + @Test + public void testEmptyPackageGroup() throws Exception { + scratch.file("whitelist/BUILD", "package_group(name='whitelist', packages=[])"); + checkError("x", "x", "Dummy is not available.", "rule_with_whitelist(name='x')"); + } + + @Test + public void testNonExistentPackageGroup() throws Exception { + checkError( + "x", + "x", + "every rule of type rule_with_whitelist implicitly depends upon the target" + + " '//whitelist:whitelist', but this target could not be found because of: no such" + + " package 'whitelist': BUILD file not found on package path", + "rule_with_whitelist(name='x')"); + } + + @Test + public void testIncludes() throws Exception { + scratch.file( + "subwhitelist/BUILD", + "package_group(", + " name='whitelist',", + " packages=[", + " '//x',", + " ])"); + scratch.file( + "whitelist/BUILD", + "package_group(", + " name='whitelist',", + " includes=[", + " '//subwhitelist:whitelist',", + " ],", + " packages=[", + " ])"); + scratch.file("x/BUILD", "rule_with_whitelist(", "name='x'", ")"); + getConfiguredTarget("//x:x"); + assertNoEvents(); + } +} |