From 9cadd78bce65f9b2fbcc22c2db1be2fc83bcc797 Mon Sep 17 00:00:00 2001 From: John Cater Date: Thu, 15 Jun 2017 17:11:20 +0200 Subject: Add more methods to ExternalPackageUtil to load all rules of a specific rule class. Change-Id: Iaa830658a62de661f16e100d24b2d1a3e66af638 PiperOrigin-RevId: 159104714 --- src/test/java/com/google/devtools/build/lib/BUILD | 24 ++ .../google/devtools/build/lib/rules/AliasTest.java | 11 +- .../build/lib/rules/ExternalPackageUtilTest.java | 301 +++++++++++++++++++++ .../build/lib/rules/ToolchainTypeTest.java | 7 +- 4 files changed, 334 insertions(+), 9 deletions(-) create mode 100644 src/test/java/com/google/devtools/build/lib/rules/ExternalPackageUtilTest.java (limited to 'src/test/java/com') diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index 92c9ee2429..7a6fa64457 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -1223,6 +1223,30 @@ java_test( ], ) +java_test( + name = "rules-tests", + srcs = glob(["rules/*.java"]), + test_class = "com.google.devtools.build.lib.AllTests", + deps = [ + ":actions_testutil", + ":analysis_testutil", + "//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:events", + "//src/main/java/com/google/devtools/build/lib:io", + "//src/main/java/com/google/devtools/build/lib:packages-internal", + "//src/main/java/com/google/devtools/build/lib:proto-rules", + "//src/main/java/com/google/devtools/build/lib/actions", + "//src/main/java/com/google/devtools/build/lib/rules/cpp", + "//src/main/java/com/google/devtools/build/skyframe", + "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", + "//third_party:auto_value", + "//third_party:guava", + "//third_party:junit4", + "//third_party:truth", + ], +) + java_binary( name = "MockSubprocess", srcs = ["windows/MockSubprocess.java"], diff --git a/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java b/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java index 4b456a358c..029998968f 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java @@ -26,14 +26,13 @@ import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.packages.License.LicenseType; import com.google.devtools.build.lib.rules.cpp.CppCompilationContext; - -import org.junit.Test; - import java.util.Set; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit tests for the alias rule. - */ +/** Unit tests for the alias rule. */ +@RunWith(JUnit4.class) public class AliasTest extends BuildViewTestCase { @Test public void smoke() throws Exception { diff --git a/src/test/java/com/google/devtools/build/lib/rules/ExternalPackageUtilTest.java b/src/test/java/com/google/devtools/build/lib/rules/ExternalPackageUtilTest.java new file mode 100644 index 0000000000..27c2e775c6 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/ExternalPackageUtilTest.java @@ -0,0 +1,301 @@ +// 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.rules; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.analysis.BlazeDirectories; +import com.google.devtools.build.lib.analysis.util.AnalysisMock; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.events.NullEventHandler; +import com.google.devtools.build.lib.packages.PackageFactory; +import com.google.devtools.build.lib.packages.PackageFactory.EnvironmentExtension; +import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.packages.RuleClassProvider; +import com.google.devtools.build.lib.pkgcache.PathPackageLocator; +import com.google.devtools.build.lib.skyframe.ExternalFilesHelper; +import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction; +import com.google.devtools.build.lib.skyframe.ExternalPackageFunction; +import com.google.devtools.build.lib.skyframe.FileFunction; +import com.google.devtools.build.lib.skyframe.FileStateFunction; +import com.google.devtools.build.lib.skyframe.LocalRepositoryLookupFunction; +import com.google.devtools.build.lib.skyframe.PackageLookupFunction; +import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy; +import com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName; +import com.google.devtools.build.lib.skyframe.PrecomputedValue; +import com.google.devtools.build.lib.skyframe.SkyFunctions; +import com.google.devtools.build.lib.skyframe.SkyframeExecutor; +import com.google.devtools.build.lib.skyframe.WorkspaceASTFunction; +import com.google.devtools.build.lib.skyframe.WorkspaceFileFunction; +import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; +import com.google.devtools.build.skyframe.EvaluationResult; +import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator; +import com.google.devtools.build.skyframe.LegacySkyKey; +import com.google.devtools.build.skyframe.MemoizingEvaluator; +import com.google.devtools.build.skyframe.RecordingDifferencer; +import com.google.devtools.build.skyframe.SequentialBuildDriver; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyFunctionException; +import com.google.devtools.build.skyframe.SkyFunctionName; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ExternalPackageUtil}. */ +@RunWith(JUnit4.class) +public class ExternalPackageUtilTest extends BuildViewTestCase { + + private SequentialBuildDriver driver; + + @Before + public void createEnvironment() { + AnalysisMock analysisMock = AnalysisMock.get(); + AtomicReference pkgLocator = + new AtomicReference<>(new PathPackageLocator(outputBase, ImmutableList.of(rootDirectory))); + AtomicReference> deletedPackages = + new AtomicReference<>(ImmutableSet.of()); + BlazeDirectories directories = + new BlazeDirectories( + rootDirectory, outputBase, rootDirectory, analysisMock.getProductName()); + ExternalFilesHelper externalFilesHelper = + new ExternalFilesHelper( + pkgLocator, + ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS, + directories); + + Map skyFunctions = new HashMap<>(); + skyFunctions.put( + SkyFunctions.PACKAGE_LOOKUP, + new PackageLookupFunction( + deletedPackages, + CrossRepositoryLabelViolationStrategy.ERROR, + ImmutableList.of(BuildFileName.BUILD_DOT_BAZEL, BuildFileName.BUILD))); + skyFunctions.put( + SkyFunctions.FILE_STATE, + new FileStateFunction( + new AtomicReference(), externalFilesHelper)); + skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator)); + RuleClassProvider ruleClassProvider = analysisMock.createRuleClassProvider(); + skyFunctions.put(SkyFunctions.WORKSPACE_AST, new WorkspaceASTFunction(ruleClassProvider)); + skyFunctions.put( + SkyFunctions.WORKSPACE_FILE, + new WorkspaceFileFunction( + ruleClassProvider, + analysisMock + .getPackageFactoryBuilderForTesting() + .setEnvironmentExtensions( + ImmutableList.of( + new PackageFactory.EmptyEnvironmentExtension())) + .build(ruleClassProvider, scratch.getFileSystem()), + directories)); + skyFunctions.put(SkyFunctions.EXTERNAL_PACKAGE, new ExternalPackageFunction()); + skyFunctions.put(SkyFunctions.LOCAL_REPOSITORY_LOOKUP, new LocalRepositoryLookupFunction()); + + // Helper Skyfunctions to call ExternalPackageUtil. + skyFunctions.put(GET_RULE_BY_NAME_FUNCTION, new GetRuleByNameFunction()); + skyFunctions.put(GET_RULE_BY_RULE_CLASS_FUNCTION, new GetRuleByRuleClassFunction()); + + RecordingDifferencer differencer = new RecordingDifferencer(); + MemoizingEvaluator evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer); + driver = new SequentialBuildDriver(evaluator); + PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); + } + + @Test + public void getRuleByName() throws Exception { + scratch.overwriteFile("WORKSPACE", "http_archive(name = 'foo', url = 'http://foo')"); + invalidatePackages(false); + + SkyKey key = getRuleByNameKey("foo"); + EvaluationResult result = getRuleByName(key); + + assertThatEvaluationResult(result).hasNoError(); + + Rule rule = result.get(key).rule(); + assertThat(rule).isNotNull(); + assertThat(rule.getName()).isEqualTo("foo"); + } + + @Test + public void getRuleByName_missing() throws Exception { + scratch.overwriteFile("WORKSPACE", "http_archive(name = 'foo', url = 'http://foo')"); + invalidatePackages(false); + + SkyKey key = getRuleByNameKey("bar"); + EvaluationResult result = getRuleByName(key); + + assertThatEvaluationResult(result) + .hasErrorEntryForKeyThat(key) + .hasExceptionThat() + .hasMessageThat() + .contains("The rule named 'bar' could not be resolved"); + } + + @Test + public void getRuleByRuleClass() throws Exception { + scratch.overwriteFile( + "WORKSPACE", + "http_archive(name = 'foo', url = 'http://foo')", + "http_archive(name = 'bar', url = 'http://bar')"); + invalidatePackages(false); + + SkyKey key = getRuleByRuleClassKey("http_archive"); + EvaluationResult result = getRuleByRuleClass(key); + + assertThatEvaluationResult(result).hasNoError(); + + List rules = result.get(key).rules(); + assertThat(rules).isNotNull(); + assertThat(rules).hasSize(2); + + Set names = new HashSet<>(); + for (Rule rule : rules) { + names.add(rule.getName()); + } + + assertThat(names).containsExactly("foo", "bar"); + } + + @Test + public void getRuleByRuleClass_none() throws Exception { + scratch.overwriteFile( + "WORKSPACE", + "http_archive(name = 'foo', url = 'http://foo')", + "http_archive(name = 'bar', url = 'http://bar')"); + invalidatePackages(false); + + SkyKey key = getRuleByRuleClassKey("new_git_repository"); + EvaluationResult result = getRuleByRuleClass(key); + + assertThatEvaluationResult(result).hasNoError(); + + List rules = result.get(key).rules(); + assertThat(rules).isNotNull(); + assertThat(rules).isEmpty(); + } + + // HELPER SKYFUNCTIONS + + // GetRuleByName. + SkyKey getRuleByNameKey(String ruleName) { + return LegacySkyKey.create(GET_RULE_BY_NAME_FUNCTION, ruleName); + } + + EvaluationResult getRuleByName(SkyKey key) throws InterruptedException { + return driver.evaluate( + ImmutableList.of(key), + false, + SkyframeExecutor.DEFAULT_THREAD_COUNT, + NullEventHandler.INSTANCE); + } + + private static final SkyFunctionName GET_RULE_BY_NAME_FUNCTION = + SkyFunctionName.create("GET_RULE_BY_NAME"); + + @AutoValue + abstract static class GetRuleByNameValue implements SkyValue { + abstract Rule rule(); + + static GetRuleByNameValue create(Rule rule) { + return new AutoValue_ExternalPackageUtilTest_GetRuleByNameValue(rule); + } + } + + private static final class GetRuleByNameFunction implements SkyFunction { + + @Nullable + @Override + public SkyValue compute(SkyKey skyKey, Environment env) + throws SkyFunctionException, InterruptedException { + String ruleName = (String) skyKey.argument(); + + Rule rule = ExternalPackageUtil.getRuleByName(ruleName, env); + if (rule == null) { + return null; + } + return GetRuleByNameValue.create(rule); + } + + @Nullable + @Override + public String extractTag(SkyKey skyKey) { + return null; + } + } + + // GetRuleByRuleClass. + SkyKey getRuleByRuleClassKey(String ruleClass) { + return LegacySkyKey.create(GET_RULE_BY_RULE_CLASS_FUNCTION, ruleClass); + } + + EvaluationResult getRuleByRuleClass(SkyKey key) + throws InterruptedException { + return driver.evaluate( + ImmutableList.of(key), + false, + SkyframeExecutor.DEFAULT_THREAD_COUNT, + NullEventHandler.INSTANCE); + } + + private static final SkyFunctionName GET_RULE_BY_RULE_CLASS_FUNCTION = + SkyFunctionName.create("GET_RULE_BY_RULE_CLASS"); + + @AutoValue + abstract static class GetRuleByRuleClassValue implements SkyValue { + abstract ImmutableList rules(); + + static GetRuleByRuleClassValue create(Iterable rules) { + return new AutoValue_ExternalPackageUtilTest_GetRuleByRuleClassValue( + ImmutableList.copyOf(rules)); + } + } + + private static final class GetRuleByRuleClassFunction implements SkyFunction { + + @Nullable + @Override + public SkyValue compute(SkyKey skyKey, Environment env) + throws SkyFunctionException, InterruptedException { + String ruleName = (String) skyKey.argument(); + + List rules = ExternalPackageUtil.getRuleByRuleClass(ruleName, env); + if (rules == null) { + return null; + } + return GetRuleByRuleClassValue.create(rules); + } + + @Nullable + @Override + public String extractTag(SkyKey skyKey) { + return null; + } + } +} diff --git a/src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java b/src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java index e9cbf36307..a4990af350 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java @@ -18,10 +18,11 @@ import static com.google.common.truth.Truth.assertThat; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; -/** - * Unit tests for the {@code toolchain_type} rule. - */ +/** Unit tests for the {@code toolchain_type} rule. */ +@RunWith(JUnit4.class) public class ToolchainTypeTest extends BuildViewTestCase { @Test public void testSmoke() throws Exception { -- cgit v1.2.3