blob: 2b35fa1495f92fb52cbb5d1709c12bd606b5d015 [file] [log] [blame]
Kristina Chodorow335f0672015-11-16 23:19:13 +00001// Copyright 2015 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.skyframe;
16
Florian Weikert92b22362015-12-03 10:17:18 +000017import static org.junit.Assert.assertEquals;
18import static org.junit.Assert.assertFalse;
19import static org.junit.Assert.assertNotNull;
20import static org.junit.Assert.assertTrue;
21
Kristina Chodorow335f0672015-11-16 23:19:13 +000022import com.google.common.collect.ImmutableList;
23import com.google.common.collect.ImmutableSet;
24import com.google.common.testing.EqualsTester;
25import com.google.devtools.build.lib.analysis.BlazeDirectories;
Ulf Adams015aad92016-07-13 16:49:40 +000026import com.google.devtools.build.lib.analysis.util.AnalysisMock;
Kristina Chodorow335f0672015-11-16 23:19:13 +000027import com.google.devtools.build.lib.bazel.rules.BazelRulesModule;
28import com.google.devtools.build.lib.cmdline.PackageIdentifier;
29import com.google.devtools.build.lib.events.NullEventHandler;
Kristina Chodorow335f0672015-11-16 23:19:13 +000030import com.google.devtools.build.lib.packages.RuleClassProvider;
31import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
32import com.google.devtools.build.lib.skyframe.PackageLookupValue.ErrorReason;
Florian Weikertcca703a2015-12-07 09:56:38 +000033import com.google.devtools.build.lib.testutil.FoundationTestCase;
Kristina Chodorow335f0672015-11-16 23:19:13 +000034import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
35import com.google.devtools.build.lib.vfs.Path;
36import com.google.devtools.build.lib.vfs.PathFragment;
37import com.google.devtools.build.lib.vfs.RootedPath;
38import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
39import com.google.devtools.build.skyframe.MemoizingEvaluator;
40import com.google.devtools.build.skyframe.RecordingDifferencer;
41import com.google.devtools.build.skyframe.SequentialBuildDriver;
42import com.google.devtools.build.skyframe.SkyFunction;
43import com.google.devtools.build.skyframe.SkyFunctionName;
44import com.google.devtools.build.skyframe.SkyKey;
45
Florian Weikert92b22362015-12-03 10:17:18 +000046import org.junit.Before;
47import org.junit.Test;
48import org.junit.runner.RunWith;
49import org.junit.runners.JUnit4;
50
Kristina Chodorow335f0672015-11-16 23:19:13 +000051import java.util.HashMap;
52import java.util.Map;
53import java.util.UUID;
54import java.util.concurrent.atomic.AtomicReference;
55
56/**
57 * Tests for {@link PackageLookupFunction}.
58 */
Florian Weikert92b22362015-12-03 10:17:18 +000059@RunWith(JUnit4.class)
Florian Weikertcca703a2015-12-07 09:56:38 +000060public class PackageLookupFunctionTest extends FoundationTestCase {
Kristina Chodorow335f0672015-11-16 23:19:13 +000061 private AtomicReference<ImmutableSet<PackageIdentifier>> deletedPackages;
62 private MemoizingEvaluator evaluator;
63 private SequentialBuildDriver driver;
64 private RecordingDifferencer differencer;
65
Florian Weikert92b22362015-12-03 10:17:18 +000066 @Before
67 public final void setUp() throws Exception {
Kristina Chodorow335f0672015-11-16 23:19:13 +000068 Path emptyPackagePath = rootDirectory.getRelative("somewhere/else");
69 scratch.file("parentpackage/BUILD");
70
Ulf Adams015aad92016-07-13 16:49:40 +000071 AnalysisMock analysisMock = AnalysisMock.get();
Kristina Chodorow335f0672015-11-16 23:19:13 +000072 AtomicReference<PathPackageLocator> pkgLocator = new AtomicReference<>(
73 new PathPackageLocator(outputBase, ImmutableList.of(emptyPackagePath, rootDirectory)));
74 deletedPackages = new AtomicReference<>(ImmutableSet.<PackageIdentifier>of());
Ulf Adams015aad92016-07-13 16:49:40 +000075 BlazeDirectories directories =
76 new BlazeDirectories(
77 rootDirectory, outputBase, rootDirectory, analysisMock.getProductName());
Kristina Chodorow5a2936f2016-04-22 17:02:19 +000078 ExternalFilesHelper externalFilesHelper = new ExternalFilesHelper(
79 pkgLocator, false, directories);
Kristina Chodorow335f0672015-11-16 23:19:13 +000080
81 Map<SkyFunctionName, SkyFunction> skyFunctions = new HashMap<>();
82 skyFunctions.put(SkyFunctions.PACKAGE_LOOKUP,
83 new PackageLookupFunction(deletedPackages));
84 skyFunctions.put(
85 SkyFunctions.PACKAGE,
86 new PackageFunction(null, null, null, null, null, null, null));
Ulf Adamsc73051c62016-03-23 09:18:13 +000087 skyFunctions.put(SkyFunctions.FILE_STATE, new FileStateFunction(
88 new AtomicReference<TimestampGranularityMonitor>(), externalFilesHelper));
Kristina Chodorowf9fdc8d2015-12-08 12:49:31 +000089 skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator));
Kristina Chodorow335f0672015-11-16 23:19:13 +000090 skyFunctions.put(SkyFunctions.BLACKLISTED_PACKAGE_PREFIXES,
91 new BlacklistedPackagePrefixesFunction());
Ulf Adams015aad92016-07-13 16:49:40 +000092 RuleClassProvider ruleClassProvider = analysisMock.createRuleClassProvider();
93 skyFunctions.put(SkyFunctions.WORKSPACE_AST, new WorkspaceASTFunction(ruleClassProvider));
Kristina Chodorow335f0672015-11-16 23:19:13 +000094 skyFunctions.put(
95 SkyFunctions.WORKSPACE_FILE,
96 new WorkspaceFileFunction(
97 ruleClassProvider,
Ulf Adams015aad92016-07-13 16:49:40 +000098 analysisMock
99 .getPackageFactoryForTesting()
100 .create(
101 ruleClassProvider,
102 new BazelRulesModule().getPackageEnvironmentExtension(),
103 scratch.getFileSystem()),
Kristina Chodorow335f0672015-11-16 23:19:13 +0000104 directories));
Damien Martin-Guillerezbc8b5e02016-02-05 22:09:09 +0000105 skyFunctions.put(SkyFunctions.EXTERNAL_PACKAGE, new ExternalPackageFunction());
Kristina Chodorow335f0672015-11-16 23:19:13 +0000106 differencer = new RecordingDifferencer();
107 evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer);
108 driver = new SequentialBuildDriver(evaluator);
109 PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID());
110 PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get());
111 PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(
112 differencer, PathFragment.EMPTY_FRAGMENT);
113 }
114
115 private PackageLookupValue lookupPackage(String packageName) throws InterruptedException {
Brian Silvermand7d6d622016-03-17 09:53:39 +0000116 return lookupPackage(PackageIdentifier.createInMainRepo(packageName));
Kristina Chodorow335f0672015-11-16 23:19:13 +0000117 }
118
119 private PackageLookupValue lookupPackage(PackageIdentifier packageId)
120 throws InterruptedException {
121 SkyKey key = PackageLookupValue.key(packageId);
122 return driver.<PackageLookupValue>evaluate(
123 ImmutableList.of(key), false, SkyframeExecutor.DEFAULT_THREAD_COUNT,
124 NullEventHandler.INSTANCE).get(key);
125 }
126
Florian Weikert92b22362015-12-03 10:17:18 +0000127 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000128 public void testNoBuildFile() throws Exception {
129 scratch.file("parentpackage/nobuildfile/foo.txt");
130 PackageLookupValue packageLookupValue = lookupPackage("parentpackage/nobuildfile");
131 assertFalse(packageLookupValue.packageExists());
132 assertEquals(ErrorReason.NO_BUILD_FILE, packageLookupValue.getErrorReason());
133 assertNotNull(packageLookupValue.getErrorMsg());
134 }
135
Florian Weikert92b22362015-12-03 10:17:18 +0000136 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000137 public void testNoBuildFileAndNoParentPackage() throws Exception {
138 scratch.file("noparentpackage/foo.txt");
139 PackageLookupValue packageLookupValue = lookupPackage("noparentpackage");
140 assertFalse(packageLookupValue.packageExists());
141 assertEquals(ErrorReason.NO_BUILD_FILE, packageLookupValue.getErrorReason());
142 assertNotNull(packageLookupValue.getErrorMsg());
143 }
144
Florian Weikert92b22362015-12-03 10:17:18 +0000145 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000146 public void testDeletedPackage() throws Exception {
147 scratch.file("parentpackage/deletedpackage/BUILD");
148 deletedPackages.set(ImmutableSet.of(
Brian Silvermand7d6d622016-03-17 09:53:39 +0000149 PackageIdentifier.createInMainRepo("parentpackage/deletedpackage")));
Kristina Chodorow335f0672015-11-16 23:19:13 +0000150 PackageLookupValue packageLookupValue = lookupPackage("parentpackage/deletedpackage");
151 assertFalse(packageLookupValue.packageExists());
152 assertEquals(ErrorReason.DELETED_PACKAGE, packageLookupValue.getErrorReason());
153 assertNotNull(packageLookupValue.getErrorMsg());
154 }
155
156
Florian Weikert92b22362015-12-03 10:17:18 +0000157 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000158 public void testBlacklistedPackage() throws Exception {
159 scratch.file("blacklisted/subdir/BUILD");
160 scratch.file("blacklisted/BUILD");
161 PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(differencer,
162 new PathFragment("config/blacklisted.txt"));
163 Path blacklist = scratch.file("config/blacklisted.txt", "blacklisted");
164
165 ImmutableSet<String> pkgs = ImmutableSet.of("blacklisted/subdir", "blacklisted");
166 for (String pkg : pkgs) {
167 PackageLookupValue packageLookupValue = lookupPackage(pkg);
168 assertFalse(packageLookupValue.packageExists());
169 assertEquals(ErrorReason.DELETED_PACKAGE, packageLookupValue.getErrorReason());
170 assertNotNull(packageLookupValue.getErrorMsg());
171 }
172
173 scratch.overwriteFile("config/blacklisted.txt", "not_blacklisted");
174 RootedPath rootedBlacklist = RootedPath.toRootedPath(
175 blacklist.getParentDirectory().getParentDirectory(),
176 new PathFragment("config/blacklisted.txt"));
177 differencer.invalidate(ImmutableSet.of(FileStateValue.key(rootedBlacklist)));
178 for (String pkg : pkgs) {
179 PackageLookupValue packageLookupValue = lookupPackage(pkg);
180 assertTrue(packageLookupValue.packageExists());
181 }
182 }
183
Florian Weikert92b22362015-12-03 10:17:18 +0000184 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000185 public void testInvalidPackageName() throws Exception {
186 scratch.file("parentpackage/invalidpackagename%42/BUILD");
187 PackageLookupValue packageLookupValue = lookupPackage("parentpackage/invalidpackagename%42");
188 assertFalse(packageLookupValue.packageExists());
189 assertEquals(ErrorReason.INVALID_PACKAGE_NAME,
190 packageLookupValue.getErrorReason());
191 assertNotNull(packageLookupValue.getErrorMsg());
192 }
193
Florian Weikert92b22362015-12-03 10:17:18 +0000194 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000195 public void testDirectoryNamedBuild() throws Exception {
196 scratch.dir("parentpackage/isdirectory/BUILD");
197 PackageLookupValue packageLookupValue = lookupPackage("parentpackage/isdirectory");
198 assertFalse(packageLookupValue.packageExists());
199 assertEquals(ErrorReason.NO_BUILD_FILE,
200 packageLookupValue.getErrorReason());
201 assertNotNull(packageLookupValue.getErrorMsg());
202 }
203
Florian Weikert92b22362015-12-03 10:17:18 +0000204 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000205 public void testEverythingIsGood() throws Exception {
206 scratch.file("parentpackage/everythinggood/BUILD");
207 PackageLookupValue packageLookupValue = lookupPackage("parentpackage/everythinggood");
208 assertTrue(packageLookupValue.packageExists());
209 assertEquals(rootDirectory, packageLookupValue.getRoot());
210 }
211
Florian Weikert92b22362015-12-03 10:17:18 +0000212 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000213 public void testEmptyPackageName() throws Exception {
214 scratch.file("BUILD");
215 PackageLookupValue packageLookupValue = lookupPackage("");
216 assertTrue(packageLookupValue.packageExists());
217 assertEquals(rootDirectory, packageLookupValue.getRoot());
218 }
219
Florian Weikert92b22362015-12-03 10:17:18 +0000220 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000221 public void testWorkspaceLookup() throws Exception {
222 scratch.overwriteFile("WORKSPACE");
Brian Silvermand7d6d622016-03-17 09:53:39 +0000223 PackageLookupValue packageLookupValue = lookupPackage(
224 PackageIdentifier.createInMainRepo("external"));
Kristina Chodorow335f0672015-11-16 23:19:13 +0000225 assertTrue(packageLookupValue.packageExists());
226 assertEquals(rootDirectory, packageLookupValue.getRoot());
227 }
Nathan Harmata87a59802016-05-23 20:57:11 +0000228
Florian Weikert92b22362015-12-03 10:17:18 +0000229 @Test
Kristina Chodorow335f0672015-11-16 23:19:13 +0000230 public void testPackageLookupValueHashCodeAndEqualsContract() throws Exception {
231 Path root1 = rootDirectory.getRelative("root1");
232 Path root2 = rootDirectory.getRelative("root2");
233 // Our (seeming) duplication of parameters here is intentional. Some of the subclasses of
234 // PackageLookupValue are supposed to have reference equality semantics, and some are supposed
235 // to have logical equality semantics.
236 new EqualsTester()
237 .addEqualityGroup(PackageLookupValue.success(root1), PackageLookupValue.success(root1))
238 .addEqualityGroup(PackageLookupValue.success(root2), PackageLookupValue.success(root2))
239 .addEqualityGroup(
240 PackageLookupValue.NO_BUILD_FILE_VALUE, PackageLookupValue.NO_BUILD_FILE_VALUE)
241 .addEqualityGroup(
242 PackageLookupValue.DELETED_PACKAGE_VALUE, PackageLookupValue.DELETED_PACKAGE_VALUE)
243 .addEqualityGroup(PackageLookupValue.invalidPackageName("nope1"),
244 PackageLookupValue.invalidPackageName("nope1"))
245 .addEqualityGroup(PackageLookupValue.invalidPackageName("nope2"),
246 PackageLookupValue.invalidPackageName("nope2"))
247 .testEquals();
248 }
249}