Open source skyframe tests
--
MOS_MIGRATED_REVID=107983315
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
new file mode 100644
index 0000000..dfc1c44
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java
@@ -0,0 +1,231 @@
+// 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.skyframe;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.EqualsTester;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
+import com.google.devtools.build.lib.bazel.rules.BazelRulesModule;
+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.RuleClassProvider;
+import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
+import com.google.devtools.build.lib.skyframe.PackageLookupValue.ErrorReason;
+import com.google.devtools.build.lib.testutil.FoundationTestCase;
+import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
+import com.google.devtools.build.lib.util.BlazeClock;
+import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.lib.vfs.RootedPath;
+import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
+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.SkyFunctionName;
+import com.google.devtools.build.skyframe.SkyKey;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Tests for {@link PackageLookupFunction}.
+ */
+public class PackageLookupFunctionTest extends FoundationTestCase {
+ private AtomicReference<ImmutableSet<PackageIdentifier>> deletedPackages;
+ private MemoizingEvaluator evaluator;
+ private SequentialBuildDriver driver;
+ private RecordingDifferencer differencer;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ Path emptyPackagePath = rootDirectory.getRelative("somewhere/else");
+ scratch.file("parentpackage/BUILD");
+
+ AtomicReference<PathPackageLocator> pkgLocator = new AtomicReference<>(
+ new PathPackageLocator(outputBase, ImmutableList.of(emptyPackagePath, rootDirectory)));
+ deletedPackages = new AtomicReference<>(ImmutableSet.<PackageIdentifier>of());
+ ExternalFilesHelper externalFilesHelper = new ExternalFilesHelper(pkgLocator);
+ TimestampGranularityMonitor tsgm = new TimestampGranularityMonitor(BlazeClock.instance());
+ BlazeDirectories directories = new BlazeDirectories(rootDirectory, outputBase, rootDirectory);
+
+ Map<SkyFunctionName, SkyFunction> skyFunctions = new HashMap<>();
+ skyFunctions.put(SkyFunctions.PACKAGE_LOOKUP,
+ new PackageLookupFunction(deletedPackages));
+ skyFunctions.put(
+ SkyFunctions.PACKAGE,
+ new PackageFunction(null, null, null, null, null, null, null));
+ skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction(tsgm, externalFilesHelper));
+ skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator, tsgm, externalFilesHelper));
+ skyFunctions.put(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES,
+ new BlacklistedPackagePrefixesFunction());
+ RuleClassProvider ruleClassProvider = TestRuleClassProvider.getRuleClassProvider();
+ skyFunctions.put(
+ SkyFunctions.WORKSPACE_FILE,
+ new WorkspaceFileFunction(
+ ruleClassProvider,
+ new PackageFactory(
+ ruleClassProvider, new BazelRulesModule().getPackageEnvironmentExtension()),
+ directories));
+ differencer = new RecordingDifferencer();
+ evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer);
+ driver = new SequentialBuildDriver(evaluator);
+ PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID());
+ PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get());
+ PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(
+ differencer, PathFragment.EMPTY_FRAGMENT);
+ }
+
+ private PackageLookupValue lookupPackage(String packageName) throws InterruptedException {
+ return lookupPackage(PackageIdentifier.createInDefaultRepo(packageName));
+ }
+
+ private PackageLookupValue lookupPackage(PackageIdentifier packageId)
+ throws InterruptedException {
+ SkyKey key = PackageLookupValue.key(packageId);
+ return driver.<PackageLookupValue>evaluate(
+ ImmutableList.of(key), false, SkyframeExecutor.DEFAULT_THREAD_COUNT,
+ NullEventHandler.INSTANCE).get(key);
+ }
+
+ public void testNoBuildFile() throws Exception {
+ scratch.file("parentpackage/nobuildfile/foo.txt");
+ PackageLookupValue packageLookupValue = lookupPackage("parentpackage/nobuildfile");
+ assertFalse(packageLookupValue.packageExists());
+ assertEquals(ErrorReason.NO_BUILD_FILE, packageLookupValue.getErrorReason());
+ assertNotNull(packageLookupValue.getErrorMsg());
+ }
+
+ public void testNoBuildFileAndNoParentPackage() throws Exception {
+ scratch.file("noparentpackage/foo.txt");
+ PackageLookupValue packageLookupValue = lookupPackage("noparentpackage");
+ assertFalse(packageLookupValue.packageExists());
+ assertEquals(ErrorReason.NO_BUILD_FILE, packageLookupValue.getErrorReason());
+ assertNotNull(packageLookupValue.getErrorMsg());
+ }
+
+ public void testDeletedPackage() throws Exception {
+ scratch.file("parentpackage/deletedpackage/BUILD");
+ deletedPackages.set(ImmutableSet.of(
+ PackageIdentifier.createInDefaultRepo("parentpackage/deletedpackage")));
+ PackageLookupValue packageLookupValue = lookupPackage("parentpackage/deletedpackage");
+ assertFalse(packageLookupValue.packageExists());
+ assertEquals(ErrorReason.DELETED_PACKAGE, packageLookupValue.getErrorReason());
+ assertNotNull(packageLookupValue.getErrorMsg());
+ }
+
+
+ public void testBlacklistedPackage() throws Exception {
+ scratch.file("blacklisted/subdir/BUILD");
+ scratch.file("blacklisted/BUILD");
+ PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(differencer,
+ new PathFragment("config/blacklisted.txt"));
+ Path blacklist = scratch.file("config/blacklisted.txt", "blacklisted");
+
+ ImmutableSet<String> pkgs = ImmutableSet.of("blacklisted/subdir", "blacklisted");
+ for (String pkg : pkgs) {
+ PackageLookupValue packageLookupValue = lookupPackage(pkg);
+ assertFalse(packageLookupValue.packageExists());
+ assertEquals(ErrorReason.DELETED_PACKAGE, packageLookupValue.getErrorReason());
+ assertNotNull(packageLookupValue.getErrorMsg());
+ }
+
+ scratch.overwriteFile("config/blacklisted.txt", "not_blacklisted");
+ RootedPath rootedBlacklist = RootedPath.toRootedPath(
+ blacklist.getParentDirectory().getParentDirectory(),
+ new PathFragment("config/blacklisted.txt"));
+ differencer.invalidate(ImmutableSet.of(FileStateValue.key(rootedBlacklist)));
+ for (String pkg : pkgs) {
+ PackageLookupValue packageLookupValue = lookupPackage(pkg);
+ assertTrue(packageLookupValue.packageExists());
+ }
+ }
+
+ public void testInvalidPackageName() throws Exception {
+ scratch.file("parentpackage/invalidpackagename%42/BUILD");
+ PackageLookupValue packageLookupValue = lookupPackage("parentpackage/invalidpackagename%42");
+ assertFalse(packageLookupValue.packageExists());
+ assertEquals(ErrorReason.INVALID_PACKAGE_NAME,
+ packageLookupValue.getErrorReason());
+ assertNotNull(packageLookupValue.getErrorMsg());
+ }
+
+ public void testDirectoryNamedBuild() throws Exception {
+ scratch.dir("parentpackage/isdirectory/BUILD");
+ PackageLookupValue packageLookupValue = lookupPackage("parentpackage/isdirectory");
+ assertFalse(packageLookupValue.packageExists());
+ assertEquals(ErrorReason.NO_BUILD_FILE,
+ packageLookupValue.getErrorReason());
+ assertNotNull(packageLookupValue.getErrorMsg());
+ }
+
+ public void testEverythingIsGood() throws Exception {
+ scratch.file("parentpackage/everythinggood/BUILD");
+ PackageLookupValue packageLookupValue = lookupPackage("parentpackage/everythinggood");
+ assertTrue(packageLookupValue.packageExists());
+ assertEquals(rootDirectory, packageLookupValue.getRoot());
+ }
+
+ public void testEmptyPackageName() throws Exception {
+ scratch.file("BUILD");
+ PackageLookupValue packageLookupValue = lookupPackage("");
+ assertTrue(packageLookupValue.packageExists());
+ assertEquals(rootDirectory, packageLookupValue.getRoot());
+ }
+
+ public void testWorkspaceLookup() throws Exception {
+ scratch.overwriteFile("WORKSPACE");
+ PackageLookupValue packageLookupValue = lookupPackage("external");
+ assertTrue(packageLookupValue.packageExists());
+ assertEquals(rootDirectory, packageLookupValue.getRoot());
+ }
+
+ // TODO(kchodorow): Clean this up (see TODOs in PackageLookupValue).
+ public void testExternalPackageLookupSemantics() {
+ PackageLookupValue existing = PackageLookupValue.workspace(rootDirectory);
+ assertTrue(existing.isExternalPackage());
+ assertTrue(existing.packageExists());
+ PackageLookupValue nonExistent = PackageLookupValue.workspace(rootDirectory.getRelative("x/y"));
+ assertTrue(nonExistent.isExternalPackage());
+ assertFalse(nonExistent.packageExists());
+ }
+
+ public void testPackageLookupValueHashCodeAndEqualsContract() throws Exception {
+ Path root1 = rootDirectory.getRelative("root1");
+ Path root2 = rootDirectory.getRelative("root2");
+ // Our (seeming) duplication of parameters here is intentional. Some of the subclasses of
+ // PackageLookupValue are supposed to have reference equality semantics, and some are supposed
+ // to have logical equality semantics.
+ new EqualsTester()
+ .addEqualityGroup(PackageLookupValue.success(root1), PackageLookupValue.success(root1))
+ .addEqualityGroup(PackageLookupValue.success(root2), PackageLookupValue.success(root2))
+ .addEqualityGroup(
+ PackageLookupValue.NO_BUILD_FILE_VALUE, PackageLookupValue.NO_BUILD_FILE_VALUE)
+ .addEqualityGroup(
+ PackageLookupValue.DELETED_PACKAGE_VALUE, PackageLookupValue.DELETED_PACKAGE_VALUE)
+ .addEqualityGroup(PackageLookupValue.invalidPackageName("nope1"),
+ PackageLookupValue.invalidPackageName("nope1"))
+ .addEqualityGroup(PackageLookupValue.invalidPackageName("nope2"),
+ PackageLookupValue.invalidPackageName("nope2"))
+ .testEquals();
+ }
+}