blob: f78e49e3f5edca3b0f921dc9fb50bb1cac974e8c [file] [log] [blame]
Ulf Adams5d058c42015-12-09 16:22:01 +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.
14package com.google.devtools.build.lib.pkgcache;
15
16import static com.google.common.truth.Truth.assertThat;
Ulf Adams5d058c42015-12-09 16:22:01 +000017import static org.junit.Assert.fail;
18
19import com.google.common.base.Joiner;
tomlua155b532017-11-08 20:12:47 +010020import com.google.common.base.Preconditions;
Ulf Adams5d058c42015-12-09 16:22:01 +000021import com.google.common.collect.ImmutableList;
22import com.google.common.collect.ImmutableMap;
Klaus Aehlig777b30d2017-02-24 16:30:15 +000023import com.google.common.eventbus.EventBus;
tomlu3d1a1942017-11-29 14:01:21 -080024import com.google.devtools.build.lib.actions.ActionKeyContext;
Ulf Adams5d058c42015-12-09 16:22:01 +000025import com.google.devtools.build.lib.analysis.BlazeDirectories;
janakr3b63a4e2017-09-14 09:55:40 +020026import com.google.devtools.build.lib.analysis.ServerDirectories;
philwo3bcb9f62017-09-06 12:52:21 +020027import com.google.devtools.build.lib.clock.BlazeClock;
Ulf Adams5d058c42015-12-09 16:22:01 +000028import com.google.devtools.build.lib.cmdline.Label;
29import com.google.devtools.build.lib.events.Reporter;
30import com.google.devtools.build.lib.packages.ConstantRuleVisibility;
31import com.google.devtools.build.lib.packages.NoSuchPackageException;
32import com.google.devtools.build.lib.packages.NoSuchTargetException;
33import com.google.devtools.build.lib.packages.NoSuchThingException;
34import com.google.devtools.build.lib.packages.Package;
Ulf Adams5d058c42015-12-09 16:22:01 +000035import com.google.devtools.build.lib.packages.Rule;
brandjon674ab862017-10-06 23:17:33 +020036import com.google.devtools.build.lib.packages.SkylarkSemanticsOptions;
Ulf Adams5d058c42015-12-09 16:22:01 +000037import com.google.devtools.build.lib.packages.Target;
Ulf Adams015aad92016-07-13 16:49:40 +000038import com.google.devtools.build.lib.packages.util.LoadingMock;
janakr5e606e62017-07-19 22:40:20 +020039import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants;
Ulf Adams5d058c42015-12-09 16:22:01 +000040import com.google.devtools.build.lib.skyframe.DiffAwareness;
Ulf Adams5d058c42015-12-09 16:22:01 +000041import com.google.devtools.build.lib.skyframe.SequencedSkyframeExecutor;
42import com.google.devtools.build.lib.skyframe.SkyValueDirtinessChecker;
43import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
44import com.google.devtools.build.lib.syntax.GlobList;
45import com.google.devtools.build.lib.testutil.ManualClock;
janakr150858b2017-07-25 00:04:53 +020046import com.google.devtools.build.lib.testutil.TestConstants;
Ulf Adams5d058c42015-12-09 16:22:01 +000047import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
48import com.google.devtools.build.lib.vfs.Dirent;
49import com.google.devtools.build.lib.vfs.FileStatus;
50import com.google.devtools.build.lib.vfs.FileSystem;
51import com.google.devtools.build.lib.vfs.FileSystemUtils;
52import com.google.devtools.build.lib.vfs.ModifiedFileSet;
53import com.google.devtools.build.lib.vfs.Path;
54import com.google.devtools.build.lib.vfs.PathFragment;
55import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
56import com.google.devtools.build.skyframe.SkyFunction;
57import com.google.devtools.build.skyframe.SkyFunctionName;
Janak Ramakrishnan326c6982016-09-27 14:58:26 +000058import com.google.devtools.common.options.Options;
Ulf Adamsde14ade2016-10-14 14:20:31 +000059import com.google.devtools.common.options.OptionsClassProvider;
Ulf Adams5d058c42015-12-09 16:22:01 +000060import java.io.FileNotFoundException;
61import java.io.IOException;
62import java.util.ArrayList;
63import java.util.Collection;
64import java.util.List;
65import java.util.UUID;
Ulf Adams5d058c42015-12-09 16:22:01 +000066import javax.annotation.Nullable;
Klaus Aehlig6f33a1c2016-09-13 16:46:10 +000067import org.junit.Before;
68import org.junit.Test;
69import org.junit.runner.RunWith;
70import org.junit.runners.JUnit4;
Ulf Adams5d058c42015-12-09 16:22:01 +000071
72/**
73 * Tests for incremental loading; these cover both normal operation and diff awareness, for which a
74 * list of modified / added / removed files is available.
75 */
76@RunWith(JUnit4.class)
77public class IncrementalLoadingTest {
78 protected PackageCacheTester tester;
79
80 private Path throwOnReaddir = null;
81 private Path throwOnStat = null;
82
83 @Before
84 public final void createTester() throws Exception {
85 ManualClock clock = new ManualClock();
86 FileSystem fs =
87 new InMemoryFileSystem(clock) {
88 @Override
89 public Collection<Dirent> readdir(Path path, boolean followSymlinks) throws IOException {
90 if (path.equals(throwOnReaddir)) {
91 throw new FileNotFoundException(path.getPathString());
92 }
93 return super.readdir(path, followSymlinks);
94 }
95
96 @Nullable
97 @Override
98 public FileStatus stat(Path path, boolean followSymlinks) throws IOException {
99 if (path.equals(throwOnStat)) {
100 throw new IOException("bork " + path.getPathString());
101 }
102 return super.stat(path, followSymlinks);
103 }
104 };
105 tester = createTester(fs, clock);
106 }
107
108 protected PackageCacheTester createTester(FileSystem fs, ManualClock clock) throws Exception {
laurentlb2e1b9042017-04-12 00:17:47 +0000109 return new PackageCacheTester(fs, clock);
Ulf Adams5d058c42015-12-09 16:22:01 +0000110 }
111
112 @Test
113 public void testNoChange() throws Exception {
114 tester.addFile("base/BUILD",
115 "filegroup(name = 'hello', srcs = ['foo.txt'])");
116 tester.sync();
117 Target oldTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200118 assertThat(oldTarget).isNotNull();
Ulf Adams5d058c42015-12-09 16:22:01 +0000119
120 tester.sync();
121 Target newTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200122 assertThat(newTarget).isSameAs(oldTarget);
Ulf Adams5d058c42015-12-09 16:22:01 +0000123 }
124
125 @Test
126 public void testModifyBuildFile() throws Exception {
127 tester.addFile("base/BUILD", "filegroup(name = 'hello', srcs = ['foo.txt'])");
128 tester.sync();
129 Target oldTarget = tester.getTarget("//base:hello");
130
131 tester.modifyFile("base/BUILD", "filegroup(name = 'hello', srcs = ['bar.txt'])");
132 tester.sync();
133 Target newTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200134 assertThat(newTarget).isNotSameAs(oldTarget);
Ulf Adams5d058c42015-12-09 16:22:01 +0000135 }
136
137 @Test
138 public void testModifyNonBuildFile() throws Exception {
139 tester.addFile("base/BUILD", "filegroup(name = 'hello', srcs = ['foo.txt'])");
140 tester.addFile("base/foo.txt", "nothing");
141 tester.sync();
142 Target oldTarget = tester.getTarget("//base:hello");
143
144 tester.modifyFile("base/foo.txt", "other");
145 tester.sync();
146 Target newTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200147 assertThat(newTarget).isSameAs(oldTarget);
Ulf Adams5d058c42015-12-09 16:22:01 +0000148 }
149
150 @Test
151 public void testRemoveNonBuildFile() throws Exception {
152 tester.addFile("base/BUILD", "filegroup(name = 'hello', srcs = ['foo.txt'])");
153 tester.addFile("base/foo.txt", "nothing");
154 tester.sync();
155 Target oldTarget = tester.getTarget("//base:hello");
156
157 tester.removeFile("base/foo.txt");
158 tester.sync();
159 Target newTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200160 assertThat(newTarget).isSameAs(oldTarget);
Ulf Adams5d058c42015-12-09 16:22:01 +0000161 }
162
163 @Test
164 public void testModifySymlinkedFileSamePackage() throws Exception {
165 tester.addSymlink("base/BUILD", "mybuild");
166 tester.addFile("base/mybuild", "filegroup(name = 'hello', srcs = ['foo.txt'])");
167 tester.sync();
168 Target oldTarget = tester.getTarget("//base:hello");
169 tester.modifyFile("base/mybuild", "filegroup(name = 'hello', srcs = ['bar.txt'])");
170 tester.sync();
171 Target newTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200172 assertThat(newTarget).isNotSameAs(oldTarget);
Ulf Adams5d058c42015-12-09 16:22:01 +0000173 }
174
175 @Test
176 public void testModifySymlinkedFileDifferentPackage() throws Exception {
177 tester.addSymlink("base/BUILD", "../other/BUILD");
178 tester.addFile("other/BUILD", "filegroup(name = 'hello', srcs = ['foo.txt'])");
179 tester.sync();
180 Target oldTarget = tester.getTarget("//base:hello");
181
182 tester.modifyFile("other/BUILD", "filegroup(name = 'hello', srcs = ['bar.txt'])");
183 tester.sync();
184 Target newTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200185 assertThat(newTarget).isNotSameAs(oldTarget);
Ulf Adams5d058c42015-12-09 16:22:01 +0000186 }
187
188 @Test
189 public void testBUILDSymlinkModifiedThenChanges() throws Exception {
190 // We need to ensure that the timestamps of "one" and "two" are different, because Blaze
191 // currently does not recognize changes to symlinks if the timestamps of the old and the new
192 // file pointed to by the symlink are the same.
193 tester.addFile("one", "filegroup(name='a', srcs=['1'])");
194 tester.sync();
195
196 tester.addFile("two", "filegroup(name='a', srcs=['2'])");
197 tester.addSymlink("oldlink", "one");
198 tester.addSymlink("newlink", "one");
199 tester.addSymlink("a/BUILD", "../oldlink");
200 tester.sync();
201 Target a1 = tester.getTarget("//a:a");
202
203 tester.modifySymlink("a/BUILD", "../newlink");
204 tester.sync();
205
206 tester.getTarget("//a:a");
207
208 tester.modifySymlink("newlink", "two");
209 tester.sync();
210
211 Target a3 = tester.getTarget("//a:a");
lberkiaea56b32017-05-30 12:35:33 +0200212 assertThat(a3).isNotSameAs(a1);
Ulf Adams5d058c42015-12-09 16:22:01 +0000213 }
214
215 @Test
216 public void testBUILDFileIsExternalSymlinkAndChanges() throws Exception {
217 tester.addFile("/nonroot/file", "filegroup(name='a', srcs=['file'])");
218 tester.addSymlink("a/BUILD", "/nonroot/file");
219 tester.sync();
220
221 Target a1 = tester.getTarget("//a:a");
222 tester.modifyFile("/nonroot/file", "filegroup(name='a', srcs=['file2'])");
223 tester.sync();
224
225 Target a2 = tester.getTarget("//a:a");
226 tester.sync();
227
lberkiaea56b32017-05-30 12:35:33 +0200228 assertThat(a2).isNotSameAs(a1);
Ulf Adams5d058c42015-12-09 16:22:01 +0000229 }
230
231 @Test
232 public void testLabelWithTwoSegmentsAndTotalInvalidation() throws Exception {
233 tester.addFile("a/BUILD", "filegroup(name='fg', srcs=['b/c'])");
234 tester.addFile("a/b/BUILD");
235 tester.sync();
236
237 Target fg1 = tester.getTarget("//a:fg");
238 tester.everythingModified();
239 tester.sync();
240
241 Target fg2 = tester.getTarget("//a:fg");
lberkiaea56b32017-05-30 12:35:33 +0200242 assertThat(fg2).isSameAs(fg1);
Ulf Adams5d058c42015-12-09 16:22:01 +0000243 }
244
245 @Test
246 public void testAddGlobFile() throws Exception {
247 tester.addFile("base/BUILD", "filegroup(name = 'hello', srcs = glob(['*.txt']))");
248 tester.addFile("base/foo.txt", "nothing");
249 tester.sync();
250 Target oldTarget = tester.getTarget("//base:hello");
251
252 tester.addFile("base/bar.txt", "also nothing");
253 tester.sync();
254 Target newTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200255 assertThat(newTarget).isNotSameAs(oldTarget);
Ulf Adams5d058c42015-12-09 16:22:01 +0000256 }
257
258 @Test
259 public void testRemoveGlobFile() throws Exception {
260 tester.addFile("base/BUILD", "filegroup(name = 'hello', srcs = glob(['*.txt']))");
261 tester.addFile("base/foo.txt", "nothing");
262 tester.addFile("base/bar.txt", "also nothing");
263 tester.sync();
264 Target oldTarget = tester.getTarget("//base:hello");
265
266 tester.removeFile("base/bar.txt");
267 tester.sync();
268 Target newTarget = tester.getTarget("//base:hello");
lberkiaea56b32017-05-30 12:35:33 +0200269 assertThat(newTarget).isNotSameAs(oldTarget);
Ulf Adams5d058c42015-12-09 16:22:01 +0000270 }
271
272 @Test
273 public void testPackageNotInLastBuildReplaced() throws Exception {
274 tester.addFile("a/BUILD", "filegroup(name='a', srcs=['bad.sh'])");
275 tester.sync();
276 Target a1 = tester.getTarget("//a:a");
277
278 tester.addFile("b/BUILD", "filegroup(name='b', srcs=['b.sh'])");
279 tester.modifyFile("a/BUILD", "filegroup(name='a', srcs=['good.sh'])");
280 tester.sync();
281 tester.getTarget("//b:b");
282
283 tester.sync();
284 Target a2 = tester.getTarget("//a:a");
lberkiaea56b32017-05-30 12:35:33 +0200285 assertThat(a2).isNotSameAs(a1);
Ulf Adams5d058c42015-12-09 16:22:01 +0000286 }
287
288 @Test
289 public void testBrokenSymlinkAddedThenFixed() throws Exception {
290 tester.addFile("a/BUILD", "filegroup(name='a', srcs=glob(['**']))");
291 tester.sync();
292 Target a1 = tester.getTarget("//a:a");
293
294 tester.addSymlink("a/b", "../c");
295 tester.sync();
296 tester.getTarget("//a:a");
297
298 tester.addFile("c");
299 tester.sync();
300 Target a3 = tester.getTarget("//a:a");
lberkiaea56b32017-05-30 12:35:33 +0200301 assertThat(a3).isNotSameAs(a1);
Ulf Adams5d058c42015-12-09 16:22:01 +0000302 }
303
304 @Test
305 public void testBuildFileWithSyntaxError() throws Exception {
306 tester.addFile("a/BUILD", "sh_library(xyz='a')");
307 tester.sync();
308 try {
309 tester.getTarget("//a:a");
310 fail();
311 } catch (NoSuchThingException e) {
312 // Expected
313 }
314
315 tester.modifyFile("a/BUILD", "sh_library(name='a')");
316 tester.sync();
317 tester.getTarget("//a:a");
318 }
319
320 @Test
321 public void testSymlinkedBuildFileWithSyntaxError() throws Exception {
322 tester.addFile("a/BUILD.real", "sh_library(xyz='a')");
323 tester.addSymlink("a/BUILD", "BUILD.real");
324 tester.sync();
325 try {
326 tester.getTarget("//a:a");
327 fail();
328 } catch (NoSuchThingException e) {
329 // Expected
330 }
331 tester.modifyFile("a/BUILD.real", "sh_library(name='a')");
332 tester.sync();
333 tester.getTarget("//a:a");
334 }
335
336 @Test
337 public void testTransientErrorsInGlobbing() throws Exception {
338 Path buildFile = tester.addFile("e/BUILD", "sh_library(name = 'e', data = glob(['*.txt']))");
339 Path parentDir = buildFile.getParentDirectory();
340 tester.addFile("e/data.txt");
341 throwOnReaddir = parentDir;
342 tester.sync();
janakr28adce52017-07-13 19:55:32 +0200343 try {
344 tester.getTarget("//e:e");
brandjon674ab862017-10-06 23:17:33 +0200345 fail("Expected exception");
janakr28adce52017-07-13 19:55:32 +0200346 } catch (NoSuchPackageException expected) {
347 }
Ulf Adams5d058c42015-12-09 16:22:01 +0000348 throwOnReaddir = null;
349 tester.sync();
janakr28adce52017-07-13 19:55:32 +0200350 Target target = tester.getTarget("//e:e");
Ulf Adams5d058c42015-12-09 16:22:01 +0000351 assertThat(((Rule) target).containsErrors()).isFalse();
janakr28adce52017-07-13 19:55:32 +0200352 GlobList<?> globList = (GlobList<?>) ((Rule) target).getAttributeContainer().getAttr("data");
Ulf Adams5d058c42015-12-09 16:22:01 +0000353 assertThat(globList).containsExactly(Label.parseAbsolute("//e:data.txt"));
354 }
355
356 @Test
357 public void testIrrelevantFileInSubdirDoesntReloadPackage() throws Exception {
358 tester.addFile("pkg/BUILD", "sh_library(name = 'pkg', srcs = glob(['**/*.sh']))");
359 tester.addFile("pkg/pkg.sh", "#!/bin/bash");
360 tester.addFile("pkg/bar/bar.sh", "#!/bin/bash");
361 Package pkg = tester.getTarget("//pkg:pkg").getPackage();
362
363 // Write file in directory to force reload of top-level glob.
364 tester.addFile("pkg/irrelevant_file");
365 tester.addFile("pkg/bar/irrelevant_file"); // Subglob is also reloaded.
lberkiaea56b32017-05-30 12:35:33 +0200366 assertThat(tester.getTarget("//pkg:pkg").getPackage()).isSameAs(pkg);
Ulf Adams5d058c42015-12-09 16:22:01 +0000367 }
368
369 @Test
370 public void testMissingPackages() throws Exception {
371 tester.sync();
372
373 try {
374 tester.getTarget("//a:a");
375 fail();
376 } catch (NoSuchThingException e) {
377 // expected
378 }
379
380 tester.addFile("a/BUILD", "sh_library(name='a')");
381 tester.sync();
382 tester.getTarget("//a:a");
383 }
384
Lukacs Berkide2183d2015-12-16 11:25:36 +0000385 @Test
386 public void testChangedExternalFile() throws Exception {
387 tester.addFile("a/BUILD",
laurentlb5ddd8042017-11-30 12:03:31 -0800388 "load('//a:b.bzl', 'b')",
Lukacs Berkide2183d2015-12-16 11:25:36 +0000389 "b()");
390
391 tester.addFile("/b.bzl",
392 "def b():",
393 " pass");
394 tester.addSymlink("a/b.bzl", "/b.bzl");
395 tester.sync();
396 tester.getTarget("//a:BUILD");
397 tester.modifyFile("/b.bzl", "ERROR ERROR");
398 tester.sync();
399
400 try {
401 tester.getTarget("//a:BUILD");
402 fail();
403 } catch (NoSuchThingException e) {
404 // expected
405 }
406 }
407
408
Ulf Adams5d058c42015-12-09 16:22:01 +0000409 static class PackageCacheTester {
Lukacs Berkide2183d2015-12-16 11:25:36 +0000410 private class ManualDiffAwareness implements DiffAwareness {
411 private View lastView;
412 private View currentView;
413
414 @Override
Ulf Adamsde14ade2016-10-14 14:20:31 +0000415 public View getCurrentView(OptionsClassProvider options) {
Lukacs Berkide2183d2015-12-16 11:25:36 +0000416 lastView = currentView;
417 currentView = new View() {};
418 return currentView;
419 }
420
421 @Override
422 public ModifiedFileSet getDiff(View oldView, View newView) {
423 if (oldView == lastView && newView == currentView) {
424 return Preconditions.checkNotNull(modifiedFileSet);
425 } else {
426 return ModifiedFileSet.EVERYTHING_MODIFIED;
427 }
428 }
429
430 @Override
431 public String name() {
432 return "PackageCacheTester.DiffAwareness";
433 }
434
435 @Override
436 public void close() {
437 }
438 }
439
440 private class ManualDiffAwarenessFactory implements DiffAwareness.Factory {
441 @Nullable
442 @Override
443 public DiffAwareness maybeCreate(Path pathEntry) {
444 return pathEntry == workspace ? new ManualDiffAwareness() : null;
445 }
446 }
447
Ulf Adams5d058c42015-12-09 16:22:01 +0000448 private final ManualClock clock;
449 private final Path workspace;
450 private final Path outputBase;
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000451 private final Reporter reporter = new Reporter(new EventBus());
Ulf Adams5d058c42015-12-09 16:22:01 +0000452 private final SkyframeExecutor skyframeExecutor;
453 private final List<Path> changes = new ArrayList<>();
454 private boolean everythingModified = false;
Lukacs Berkide2183d2015-12-16 11:25:36 +0000455 private ModifiedFileSet modifiedFileSet;
tomlu3d1a1942017-11-29 14:01:21 -0800456 private final ActionKeyContext actionKeyContext = new ActionKeyContext();
Ulf Adams5d058c42015-12-09 16:22:01 +0000457
laurentlb2e1b9042017-04-12 00:17:47 +0000458 public PackageCacheTester(FileSystem fs, ManualClock clock) throws IOException {
Ulf Adams5d058c42015-12-09 16:22:01 +0000459 this.clock = clock;
460 workspace = fs.getPath("/workspace");
461 workspace.createDirectory();
462 outputBase = fs.getPath("/output_base");
463 outputBase.createDirectory();
464 addFile("WORKSPACE");
465
Ulf Adams015aad92016-07-13 16:49:40 +0000466 LoadingMock loadingMock = LoadingMock.get();
janakr52d05e82017-09-22 13:27:14 -0400467 BlazeDirectories directories =
468 new BlazeDirectories(
469 new ServerDirectories(fs.getPath("/install"), fs.getPath("/output")),
470 workspace,
471 loadingMock.getProductName());
Ulf Adams5d058c42015-12-09 16:22:01 +0000472 skyframeExecutor =
janakr5e606e62017-07-19 22:40:20 +0200473 SequencedSkyframeExecutor.create(
Ulf Adams015aad92016-07-13 16:49:40 +0000474 loadingMock
janakr52d05e82017-09-22 13:27:14 -0400475 .getPackageFactoryBuilderForTesting(directories)
nharmatad922e652017-05-17 20:29:19 +0200476 .build(loadingMock.createRuleClassProvider(), fs),
tomluf903eb52017-10-27 12:12:11 -0400477 fs,
janakr52d05e82017-09-22 13:27:14 -0400478 directories,
tomlu3d1a1942017-11-29 14:01:21 -0800479 actionKeyContext,
Ulf Adams5d058c42015-12-09 16:22:01 +0000480 null, /* workspaceStatusActionFactory */
Ulf Adams015aad92016-07-13 16:49:40 +0000481 loadingMock.createRuleClassProvider().getBuildInfoFactories(),
Lukacs Berkide2183d2015-12-16 11:25:36 +0000482 ImmutableList.of(new ManualDiffAwarenessFactory()),
Ulf Adams5d058c42015-12-09 16:22:01 +0000483 ImmutableMap.<SkyFunctionName, SkyFunction>of(),
Luis Fernando Pino Duquebe102182016-05-23 14:03:55 +0000484 ImmutableList.<SkyValueDirtinessChecker>of(),
nharmatae4eb23f2017-12-05 09:27:45 -0800485 BazelSkyframeExecutorConstants.HARDCODED_BLACKLISTED_PACKAGE_PREFIXES,
486 BazelSkyframeExecutorConstants.ADDITIONAL_BLACKLISTED_PACKAGE_PREFIXES_FILE,
janakr5e606e62017-07-19 22:40:20 +0200487 BazelSkyframeExecutorConstants.CROSS_REPOSITORY_LABEL_VIOLATION_STRATEGY,
488 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY,
489 BazelSkyframeExecutorConstants.ACTION_ON_IO_EXCEPTION_READING_BUILD_FILE);
janakr150858b2017-07-25 00:04:53 +0200490 TestConstants.processSkyframeExecutorForTesting(skyframeExecutor);
Janak Ramakrishnan326c6982016-09-27 14:58:26 +0000491 PackageCacheOptions packageCacheOptions = Options.getDefaults(PackageCacheOptions.class);
492 packageCacheOptions.defaultVisibility = ConstantRuleVisibility.PUBLIC;
493 packageCacheOptions.showLoadingProgress = true;
494 packageCacheOptions.globbingThreads = 7;
Ulf Adams5d058c42015-12-09 16:22:01 +0000495 skyframeExecutor.preparePackageLoading(
John Catere0d1d0e2017-11-28 20:47:41 -0800496 new PathPackageLocator(
497 outputBase,
498 ImmutableList.of(workspace),
499 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
Janak Ramakrishnan326c6982016-09-27 14:58:26 +0000500 packageCacheOptions,
brandjon7dc34162017-04-27 18:34:33 +0200501 Options.getDefaults(SkylarkSemanticsOptions.class),
Janak Ramakrishnan326c6982016-09-27 14:58:26 +0000502 "",
503 UUID.randomUUID(),
504 ImmutableMap.<String, String>of(),
Damien Martin-Guillerez777f3af2017-02-08 17:22:02 +0000505 ImmutableMap.<String, String>of(),
Klaus Aehlig6f33a1c2016-09-13 16:46:10 +0000506 new TimestampGranularityMonitor(BlazeClock.instance()));
Ulf Adams5d058c42015-12-09 16:22:01 +0000507 }
508
509 Path addFile(String fileName, String... content) throws IOException {
510 Path buildFile = workspace.getRelative(fileName);
511 Preconditions.checkState(!buildFile.exists());
512 Path currentPath = buildFile;
513
514 // Add the new file and all the directories that will be created by
515 // createDirectoryAndParents()
516 while (!currentPath.exists()) {
517 changes.add(currentPath);
518 currentPath = currentPath.getParentDirectory();
519 }
520
521 FileSystemUtils.createDirectoryAndParents(buildFile.getParentDirectory());
522 FileSystemUtils.writeContentAsLatin1(buildFile, Joiner.on('\n').join(content));
523 return buildFile;
524 }
525
526 void addSymlink(String fileName, String target) throws IOException {
527 Path path = workspace.getRelative(fileName);
528 Preconditions.checkState(!path.exists());
529 FileSystemUtils.createDirectoryAndParents(path.getParentDirectory());
nharmatab4060b62017-04-04 17:11:39 +0000530 path.createSymbolicLink(PathFragment.create(target));
Ulf Adams5d058c42015-12-09 16:22:01 +0000531 changes.add(path);
532 }
533
534 void removeFile(String fileName) throws IOException {
535 Path path = workspace.getRelative(fileName);
536 Preconditions.checkState(path.delete());
537 changes.add(path);
538 }
539
540 void modifyFile(String fileName, String... content) throws IOException {
541 Path path = workspace.getRelative(fileName);
542 Preconditions.checkState(path.exists());
543 Preconditions.checkState(path.delete());
544 FileSystemUtils.writeContentAsLatin1(path, Joiner.on('\n').join(content));
545 changes.add(path);
546 }
547
548 void modifySymlink(String fileName, String newTarget) throws IOException {
549 Path symlink = workspace.getRelative(fileName);
550 Preconditions.checkState(symlink.exists());
551 symlink.delete();
nharmatab4060b62017-04-04 17:11:39 +0000552 symlink.createSymbolicLink(PathFragment.create(newTarget));
Ulf Adams5d058c42015-12-09 16:22:01 +0000553 changes.add(symlink);
554 }
555
556 void everythingModified() {
557 everythingModified = true;
558 }
559
560 private ModifiedFileSet getModifiedFileSet() {
561 if (everythingModified) {
562 everythingModified = false;
563 return ModifiedFileSet.EVERYTHING_MODIFIED;
564 }
565
566 ModifiedFileSet.Builder builder = ModifiedFileSet.builder();
567 for (Path path : changes) {
568 if (!path.startsWith(workspace)) {
569 continue;
570 }
571
572 PathFragment workspacePath = path.relativeTo(workspace);
573 builder.modify(workspacePath);
574 }
575 return builder.build();
576 }
577
578 void sync() throws InterruptedException {
579 clock.advanceMillis(1);
580
Lukacs Berkide2183d2015-12-16 11:25:36 +0000581 modifiedFileSet = getModifiedFileSet();
Janak Ramakrishnan326c6982016-09-27 14:58:26 +0000582 PackageCacheOptions packageCacheOptions = Options.getDefaults(PackageCacheOptions.class);
583 packageCacheOptions.defaultVisibility = ConstantRuleVisibility.PUBLIC;
584 packageCacheOptions.showLoadingProgress = true;
585 packageCacheOptions.globbingThreads = 7;
Ulf Adams5d058c42015-12-09 16:22:01 +0000586 skyframeExecutor.preparePackageLoading(
John Catere0d1d0e2017-11-28 20:47:41 -0800587 new PathPackageLocator(
588 outputBase,
589 ImmutableList.of(workspace),
590 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
Janak Ramakrishnan326c6982016-09-27 14:58:26 +0000591 packageCacheOptions,
brandjon7dc34162017-04-27 18:34:33 +0200592 Options.getDefaults(SkylarkSemanticsOptions.class),
Janak Ramakrishnan326c6982016-09-27 14:58:26 +0000593 "",
594 UUID.randomUUID(),
595 ImmutableMap.<String, String>of(),
Damien Martin-Guillerez777f3af2017-02-08 17:22:02 +0000596 ImmutableMap.<String, String>of(),
Klaus Aehlig6f33a1c2016-09-13 16:46:10 +0000597 new TimestampGranularityMonitor(BlazeClock.instance()));
Ulf Adams5d058c42015-12-09 16:22:01 +0000598 skyframeExecutor.invalidateFilesUnderPathForTesting(
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000599 new Reporter(new EventBus()), modifiedFileSet, workspace);
600 ((SequencedSkyframeExecutor) skyframeExecutor).handleDiffs(new Reporter(new EventBus()));
Ulf Adams5d058c42015-12-09 16:22:01 +0000601
602 changes.clear();
603 }
604
605 Target getTarget(String targetName)
606 throws NoSuchPackageException, NoSuchTargetException, InterruptedException {
607 Label label = Label.parseAbsoluteUnchecked(targetName);
608 return skyframeExecutor.getPackageManager().getTarget(reporter, label);
609 }
610 }
611}