blob: 56efe4907e97966889d2573e0f6e0a0ab5c62e9a [file] [log] [blame]
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +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.skyframe;
15
16import static com.google.common.truth.Truth.assertThat;
Janak Ramakrishnan112840b2016-12-29 21:49:56 +000017import static com.google.devtools.build.skyframe.WalkableGraphUtils.exists;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000018
tomlua155b532017-11-08 20:12:47 +010019import com.google.common.base.Preconditions;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000020import com.google.common.collect.ImmutableList;
nharmatae4eb23f2017-12-05 09:27:45 -080021import com.google.common.collect.ImmutableMap;
Klaus Aehlig777b30d2017-02-24 16:30:15 +000022import com.google.common.eventbus.EventBus;
nharmatae4eb23f2017-12-05 09:27:45 -080023import com.google.devtools.build.lib.actions.ActionKeyContext;
24import com.google.devtools.build.lib.analysis.BlazeDirectories;
mjhalupka5d7fa7b2018-03-22 13:37:38 -070025import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
nharmatae4eb23f2017-12-05 09:27:45 -080026import com.google.devtools.build.lib.analysis.ServerDirectories;
27import com.google.devtools.build.lib.analysis.util.AnalysisMock;
mjhalupka5d7fa7b2018-03-22 13:37:38 -070028import com.google.devtools.build.lib.analysis.util.DefaultBuildOptionsForTesting;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000029import com.google.devtools.build.lib.cmdline.Label;
30import com.google.devtools.build.lib.cmdline.PackageIdentifier;
nharmatae4eb23f2017-12-05 09:27:45 -080031import com.google.devtools.build.lib.cmdline.RepositoryName;
Klaus Aehlig777b30d2017-02-24 16:30:15 +000032import com.google.devtools.build.lib.events.Reporter;
nharmatae4eb23f2017-12-05 09:27:45 -080033import com.google.devtools.build.lib.packages.SkylarkSemanticsOptions;
34import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
35import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
36import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
37import com.google.devtools.build.lib.testutil.FoundationTestCase;
38import com.google.devtools.build.lib.testutil.TestConstants;
39import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
Eric Fellheimere040fe92015-11-09 23:54:46 +000040import com.google.devtools.build.lib.vfs.PathFragment;
tomluee6a6862018-01-17 14:36:26 -080041import com.google.devtools.build.lib.vfs.Root;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000042import com.google.devtools.build.skyframe.EvaluationResult;
43import com.google.devtools.build.skyframe.SkyKey;
44import com.google.devtools.build.skyframe.SkyValue;
45import com.google.devtools.build.skyframe.WalkableGraph;
nharmatae4eb23f2017-12-05 09:27:45 -080046import com.google.devtools.common.options.Options;
Janak Ramakrishnan112840b2016-12-29 21:49:56 +000047import java.io.IOException;
nharmatae4eb23f2017-12-05 09:27:45 -080048import java.util.UUID;
49import org.junit.Before;
Florian Weikert92b22362015-12-03 10:17:18 +000050import org.junit.Test;
51import org.junit.runner.RunWith;
52import org.junit.runners.JUnit4;
53
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000054/** Tests for {@link PrepareDepsOfPatternsFunction}. */
Florian Weikert92b22362015-12-03 10:17:18 +000055@RunWith(JUnit4.class)
nharmatae4eb23f2017-12-05 09:27:45 -080056public class PrepareDepsOfPatternsFunctionSmartNegationTest extends FoundationTestCase {
57 private SkyframeExecutor skyframeExecutor;
58 private static final String ADDITIONAL_BLACKLISTED_PACKAGE_PREFIXES_FILE_PATH_STRING =
59 "config/blacklist.txt";
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000060
61 private static SkyKey getKeyForLabel(Label label) {
62 // Note that these tests used to look for TargetMarker SkyKeys before TargetMarker was
63 // inlined in TransitiveTraversalFunction. Because TargetMarker is now inlined, it doesn't
64 // appear in the graph. Instead, these tests now look for TransitiveTraversal keys.
65 return TransitiveTraversalValue.key(label);
66 }
67
nharmatae4eb23f2017-12-05 09:27:45 -080068 @Before
69 public void setUp() throws Exception {
70 BlazeDirectories directories =
71 new BlazeDirectories(
Klaus Aehligc2499c42018-02-27 05:47:21 -080072 new ServerDirectories(
73 getScratch().dir("/install"),
74 getScratch().dir("/output"),
75 getScratch().dir("/user_root")),
nharmatae4eb23f2017-12-05 09:27:45 -080076 rootDirectory,
cushon849df362018-05-14 01:51:45 -070077 /* defaultSystemJavabase= */ null,
nharmatae4eb23f2017-12-05 09:27:45 -080078 AnalysisMock.get().getProductName());
mjhalupka5d7fa7b2018-03-22 13:37:38 -070079 ConfiguredRuleClassProvider ruleClassProvider = AnalysisMock.get().createRuleClassProvider();
nharmatae4eb23f2017-12-05 09:27:45 -080080 skyframeExecutor =
81 SequencedSkyframeExecutor.create(
82 AnalysisMock.get()
83 .getPackageFactoryBuilderForTesting(directories)
nharmatae57e9a32018-04-02 15:10:24 -070084 .build(ruleClassProvider),
nharmatae4eb23f2017-12-05 09:27:45 -080085 fileSystem,
86 directories,
87 new ActionKeyContext(),
88 /*workspaceStatusActionFactory=*/ null,
89 AnalysisMock.get().createRuleClassProvider().getBuildInfoFactories(),
90 ImmutableList.of(),
91 AnalysisMock.get().getSkyFunctions(directories),
92 ImmutableList.of(),
93 BazelSkyframeExecutorConstants.HARDCODED_BLACKLISTED_PACKAGE_PREFIXES,
94 PathFragment.create(ADDITIONAL_BLACKLISTED_PACKAGE_PREFIXES_FILE_PATH_STRING),
95 BazelSkyframeExecutorConstants.CROSS_REPOSITORY_LABEL_VIOLATION_STRATEGY,
96 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY,
mjhalupka5d7fa7b2018-03-22 13:37:38 -070097 BazelSkyframeExecutorConstants.ACTION_ON_IO_EXCEPTION_READING_BUILD_FILE,
98 DefaultBuildOptionsForTesting.getDefaultBuildOptionsForTest(ruleClassProvider));
nharmatae4eb23f2017-12-05 09:27:45 -080099 TestConstants.processSkyframeExecutorForTesting(skyframeExecutor);
100 skyframeExecutor.preparePackageLoading(
101 new PathPackageLocator(
102 outputBase,
tomluee6a6862018-01-17 14:36:26 -0800103 ImmutableList.of(Root.fromPath(rootDirectory)),
nharmatae4eb23f2017-12-05 09:27:45 -0800104 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
105 Options.getDefaults(PackageCacheOptions.class),
106 Options.getDefaults(SkylarkSemanticsOptions.class),
nharmatae4eb23f2017-12-05 09:27:45 -0800107 UUID.randomUUID(),
108 ImmutableMap.<String, String>of(),
nharmatae4eb23f2017-12-05 09:27:45 -0800109 new TimestampGranularityMonitor(null));
juliexxia651797f2018-08-01 11:45:13 -0700110 skyframeExecutor.setActionEnv(ImmutableMap.<String, String>of());
Klaus Aehlig93fe20c2018-06-14 05:48:46 -0700111 skyframeExecutor.injectExtraPrecomputedValues(
112 ImmutableList.of(
113 PrecomputedValue.injected(
114 RepositoryDelegatorFunction.REPOSITORY_OVERRIDES,
115 ImmutableMap.<RepositoryName, PathFragment>of()),
116 PrecomputedValue.injected(
117 RepositoryDelegatorFunction.DEPENDENCY_FOR_UNCONDITIONAL_FETCHING,
118 RepositoryDelegatorFunction.DONT_FETCH_UNCONDITIONALLY)));
nharmatae4eb23f2017-12-05 09:27:45 -0800119 scratch.file(ADDITIONAL_BLACKLISTED_PACKAGE_PREFIXES_FILE_PATH_STRING);
120 }
121
Florian Weikert92b22362015-12-03 10:17:18 +0000122 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000123 public void testRecursiveEvaluationFailsOnBadBuildFile() throws Exception {
Brian Silvermand7d6d622016-03-17 09:53:39 +0000124 // Given a well-formed package "@//foo" and a malformed package "@//foo/foo",
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000125 createFooAndFooFoo();
126
127 // Given a target pattern sequence consisting of a recursive pattern for "//foo/...",
128 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...");
129
130 // When PrepareDepsOfPatternsFunction completes evaluation (with no error because it was
131 // recovered from),
132 WalkableGraph walkableGraph =
133 getGraphFromPatternsEvaluation(
134 patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
135
Brian Silvermand7d6d622016-03-17 09:53:39 +0000136 // Then the graph contains package values for "@//foo" and "@//foo/foo",
lberkiaea56b32017-05-30 12:35:33 +0200137 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo")), walkableGraph)).isTrue();
138 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo/foo")), walkableGraph))
139 .isTrue();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000140
Brian Silvermand7d6d622016-03-17 09:53:39 +0000141 // But the graph does not contain a value for the target "@//foo/foo:foofoo".
lberkiaea56b32017-05-30 12:35:33 +0200142 assertThat(exists(getKeyForLabel(Label.create("@//foo/foo", "foofoo")), walkableGraph))
143 .isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000144 }
145
Florian Weikert92b22362015-12-03 10:17:18 +0000146 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000147 public void testNegativePatternBlocksPatternEvaluation() throws Exception {
148 // Given a well-formed package "//foo" and a malformed package "//foo/foo",
149 createFooAndFooFoo();
150
151 // Given a target pattern sequence consisting of a recursive pattern for "//foo/..." followed
152 // by a negative pattern for the malformed package,
153 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...", "-//foo/foo/...");
154
Eric Fellheimere040fe92015-11-09 23:54:46 +0000155 assertSkipsFoo(patternSequence);
156 }
157
Florian Weikert92b22362015-12-03 10:17:18 +0000158 @Test
Eric Fellheimere040fe92015-11-09 23:54:46 +0000159 public void testBlacklistPatternBlocksPatternEvaluation() throws Exception {
160 // Given a well-formed package "//foo" and a malformed package "//foo/foo",
161 createFooAndFooFoo();
162
163 // Given a target pattern sequence consisting of a recursive pattern for "//foo/...",
164 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...");
165
166 // and a blacklist for the malformed package,
nharmatae4eb23f2017-12-05 09:27:45 -0800167 scratch.overwriteFile(ADDITIONAL_BLACKLISTED_PACKAGE_PREFIXES_FILE_PATH_STRING, "foo/foo");
Eric Fellheimere040fe92015-11-09 23:54:46 +0000168
169 assertSkipsFoo(patternSequence);
170 }
171
172 private void assertSkipsFoo(ImmutableList<String> patternSequence) throws Exception {
173
174
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000175 // When PrepareDepsOfPatternsFunction completes evaluation (successfully),
176 WalkableGraph walkableGraph =
177 getGraphFromPatternsEvaluation(
178 patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
179
Brian Silvermand7d6d622016-03-17 09:53:39 +0000180 // Then the graph contains a package value for "@//foo",
lberkiaea56b32017-05-30 12:35:33 +0200181 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo")), walkableGraph)).isTrue();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000182
Brian Silvermand7d6d622016-03-17 09:53:39 +0000183 // But no package value for "@//foo/foo",
lberkiaea56b32017-05-30 12:35:33 +0200184 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo/foo")), walkableGraph))
185 .isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000186
Brian Silvermand7d6d622016-03-17 09:53:39 +0000187 // And the graph does not contain a value for the target "@//foo/foo:foofoo".
188 Label label = Label.create("@//foo/foo", "foofoo");
lberkiaea56b32017-05-30 12:35:33 +0200189 assertThat(exists(getKeyForLabel(label), walkableGraph)).isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000190 }
191
Florian Weikert92b22362015-12-03 10:17:18 +0000192 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000193 public void testNegativeNonTBDPatternsAreSkippedWithWarnings() throws Exception {
194 // Given a target pattern sequence with a negative non-TBD pattern,
195 ImmutableList<String> patternSequence = ImmutableList.of("-//foo/bar");
196
197 // When PrepareDepsOfPatternsFunction completes evaluation,
198 getGraphFromPatternsEvaluation(patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
199
200 // Then a event is published that says that negative non-TBD patterns are skipped.
201 assertContainsEvent(
202 "Skipping '-//foo/bar': Negative target patterns of types other than \"targets below "
203 + "directory\" are not permitted.");
204 }
205
206 // Helpers:
207
208 private WalkableGraph getGraphFromPatternsEvaluation(
209 ImmutableList<String> patternSequence, boolean successExpected, boolean keepGoing)
210 throws InterruptedException {
211 SkyKey independentTarget = PrepareDepsOfPatternsValue.key(patternSequence, "");
212 ImmutableList<SkyKey> singletonTargetPattern = ImmutableList.of(independentTarget);
213
214 // When PrepareDepsOfPatternsFunction completes evaluation,
215 EvaluationResult<SkyValue> evaluationResult =
nharmatae4eb23f2017-12-05 09:27:45 -0800216 skyframeExecutor
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000217 .getDriverForTesting()
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000218 .evaluate(
219 singletonTargetPattern,
220 keepGoing,
nharmatae4eb23f2017-12-05 09:27:45 -0800221 /*numThreads=*/ 100,
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000222 new Reporter(new EventBus(), eventCollector));
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000223 // The evaluation has no errors if success was expected.
224 assertThat(evaluationResult.hasError()).isNotEqualTo(successExpected);
225 return Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
226 }
227
228 private void createFooAndFooFoo() throws IOException {
229 scratch.file(
230 "foo/BUILD", "genrule(name = 'foo',", " outs = ['out.txt'],", " cmd = 'touch $@')");
231 scratch.file(
232 "foo/foo/BUILD", "genrule(name = 'foofoo',", " This isn't even remotely grammatical.)");
233 }
234}