blob: 4757999ff45c66a90bd4052004fb4dec511a4465 [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;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000028import com.google.devtools.build.lib.cmdline.Label;
29import com.google.devtools.build.lib.cmdline.PackageIdentifier;
Klaus Aehlig777b30d2017-02-24 16:30:15 +000030import com.google.devtools.build.lib.events.Reporter;
Googler7b2cb352019-04-09 14:01:44 -070031import com.google.devtools.build.lib.packages.PackageFactory;
adonovan240bdea2020-09-03 15:24:12 -070032import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
ajurkowskid74b0ec2020-04-13 10:58:21 -070033import com.google.devtools.build.lib.pkgcache.PackageOptions;
nharmatae4eb23f2017-12-05 09:27:45 -080034import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
35import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
36import com.google.devtools.build.lib.testutil.FoundationTestCase;
michajlob0b312f2020-03-25 12:30:22 -070037import com.google.devtools.build.lib.testutil.SkyframeExecutorTestHelper;
nharmatae4eb23f2017-12-05 09:27:45 -080038import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
Eric Fellheimere040fe92015-11-09 23:54:46 +000039import com.google.devtools.build.lib.vfs.PathFragment;
tomluee6a6862018-01-17 14:36:26 -080040import com.google.devtools.build.lib.vfs.Root;
Googler10028672018-10-25 12:14:34 -070041import com.google.devtools.build.skyframe.EvaluationContext;
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;
jhorvitzdd1d8412020-08-01 05:59:14 -070048import java.util.Optional;
nharmatae4eb23f2017-12-05 09:27:45 -080049import java.util.UUID;
50import org.junit.Before;
Florian Weikert92b22362015-12-03 10:17:18 +000051import org.junit.Test;
52import org.junit.runner.RunWith;
53import org.junit.runners.JUnit4;
54
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000055/** Tests for {@link PrepareDepsOfPatternsFunction}. */
Florian Weikert92b22362015-12-03 10:17:18 +000056@RunWith(JUnit4.class)
nharmatae4eb23f2017-12-05 09:27:45 -080057public class PrepareDepsOfPatternsFunctionSmartNegationTest extends FoundationTestCase {
58 private SkyframeExecutor skyframeExecutor;
kkress1847a012020-06-24 12:30:11 -070059 private static final String ADDITIONAL_IGNORED_PACKAGE_PREFIXES_FILE_PATH_STRING =
60 "config/ignored.txt";
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000061
62 private static SkyKey getKeyForLabel(Label label) {
63 // Note that these tests used to look for TargetMarker SkyKeys before TargetMarker was
64 // inlined in TransitiveTraversalFunction. Because TargetMarker is now inlined, it doesn't
65 // appear in the graph. Instead, these tests now look for TransitiveTraversal keys.
66 return TransitiveTraversalValue.key(label);
67 }
68
nharmatae4eb23f2017-12-05 09:27:45 -080069 @Before
70 public void setUp() throws Exception {
71 BlazeDirectories directories =
72 new BlazeDirectories(
Klaus Aehligc2499c42018-02-27 05:47:21 -080073 new ServerDirectories(
74 getScratch().dir("/install"),
75 getScratch().dir("/output"),
76 getScratch().dir("/user_root")),
nharmatae4eb23f2017-12-05 09:27:45 -080077 rootDirectory,
cushon849df362018-05-14 01:51:45 -070078 /* defaultSystemJavabase= */ null,
nharmatae4eb23f2017-12-05 09:27:45 -080079 AnalysisMock.get().getProductName());
mjhalupka5d7fa7b2018-03-22 13:37:38 -070080 ConfiguredRuleClassProvider ruleClassProvider = AnalysisMock.get().createRuleClassProvider();
Googler7b2cb352019-04-09 14:01:44 -070081
82 PackageFactory pkgFactory =
83 AnalysisMock.get()
84 .getPackageFactoryBuilderForTesting(directories)
85 .build(ruleClassProvider, fileSystem);
nharmatae4eb23f2017-12-05 09:27:45 -080086 skyframeExecutor =
Googler7b2cb352019-04-09 14:01:44 -070087 BazelSkyframeExecutorConstants.newBazelSkyframeExecutorBuilder()
88 .setPkgFactory(pkgFactory)
89 .setFileSystem(fileSystem)
90 .setDirectories(directories)
91 .setActionKeyContext(new ActionKeyContext())
Googler7b2cb352019-04-09 14:01:44 -070092 .setExtraSkyFunctions(AnalysisMock.get().getSkyFunctions(directories))
kkress1847a012020-06-24 12:30:11 -070093 .setIgnoredPackagePrefixesFunction(
94 new IgnoredPackagePrefixesFunction(
95 PathFragment.create(ADDITIONAL_IGNORED_PACKAGE_PREFIXES_FILE_PATH_STRING)))
Googler7b2cb352019-04-09 14:01:44 -070096 .build();
michajlob0b312f2020-03-25 12:30:22 -070097 SkyframeExecutorTestHelper.process(skyframeExecutor);
nharmatae4eb23f2017-12-05 09:27:45 -080098 skyframeExecutor.preparePackageLoading(
99 new PathPackageLocator(
100 outputBase,
tomluee6a6862018-01-17 14:36:26 -0800101 ImmutableList.of(Root.fromPath(rootDirectory)),
nharmatae4eb23f2017-12-05 09:27:45 -0800102 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
ajurkowskid74b0ec2020-04-13 10:58:21 -0700103 Options.getDefaults(PackageOptions.class),
adonovan240bdea2020-09-03 15:24:12 -0700104 Options.getDefaults(BuildLanguageOptions.class),
nharmatae4eb23f2017-12-05 09:27:45 -0800105 UUID.randomUUID(),
jhorvitz1e803ab2021-05-06 10:22:28 -0700106 ImmutableMap.of(),
nharmatae4eb23f2017-12-05 09:27:45 -0800107 new TimestampGranularityMonitor(null));
jhorvitzdd1d8412020-08-01 05:59:14 -0700108 skyframeExecutor.setActionEnv(ImmutableMap.of());
Klaus Aehlig93fe20c2018-06-14 05:48:46 -0700109 skyframeExecutor.injectExtraPrecomputedValues(
110 ImmutableList.of(
111 PrecomputedValue.injected(
jhorvitzdd1d8412020-08-01 05:59:14 -0700112 RepositoryDelegatorFunction.RESOLVED_FILE_INSTEAD_OF_WORKSPACE, Optional.empty()),
Klaus Aehlig8eb47482018-09-17 09:14:58 -0700113 PrecomputedValue.injected(
jhorvitzdd1d8412020-08-01 05:59:14 -0700114 RepositoryDelegatorFunction.REPOSITORY_OVERRIDES, ImmutableMap.of()),
Klaus Aehlig93fe20c2018-06-14 05:48:46 -0700115 PrecomputedValue.injected(
116 RepositoryDelegatorFunction.DEPENDENCY_FOR_UNCONDITIONAL_FETCHING,
117 RepositoryDelegatorFunction.DONT_FETCH_UNCONDITIONALLY)));
kkress1847a012020-06-24 12:30:11 -0700118 scratch.file(ADDITIONAL_IGNORED_PACKAGE_PREFIXES_FILE_PATH_STRING);
nharmatae4eb23f2017-12-05 09:27:45 -0800119 }
120
Florian Weikert92b22362015-12-03 10:17:18 +0000121 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000122 public void testRecursiveEvaluationFailsOnBadBuildFile() throws Exception {
Brian Silvermand7d6d622016-03-17 09:53:39 +0000123 // Given a well-formed package "@//foo" and a malformed package "@//foo/foo",
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000124 createFooAndFooFoo();
125
126 // Given a target pattern sequence consisting of a recursive pattern for "//foo/...",
127 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...");
128
129 // When PrepareDepsOfPatternsFunction completes evaluation (with no error because it was
130 // recovered from),
131 WalkableGraph walkableGraph =
132 getGraphFromPatternsEvaluation(
133 patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
134
Brian Silvermand7d6d622016-03-17 09:53:39 +0000135 // Then the graph contains package values for "@//foo" and "@//foo/foo",
lberkiaea56b32017-05-30 12:35:33 +0200136 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo")), walkableGraph)).isTrue();
137 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo/foo")), walkableGraph))
138 .isTrue();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000139
Brian Silvermand7d6d622016-03-17 09:53:39 +0000140 // But the graph does not contain a value for the target "@//foo/foo:foofoo".
lberkiaea56b32017-05-30 12:35:33 +0200141 assertThat(exists(getKeyForLabel(Label.create("@//foo/foo", "foofoo")), walkableGraph))
142 .isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000143 }
144
Florian Weikert92b22362015-12-03 10:17:18 +0000145 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000146 public void testNegativePatternBlocksPatternEvaluation() throws Exception {
147 // Given a well-formed package "//foo" and a malformed package "//foo/foo",
148 createFooAndFooFoo();
149
150 // Given a target pattern sequence consisting of a recursive pattern for "//foo/..." followed
151 // by a negative pattern for the malformed package,
152 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...", "-//foo/foo/...");
153
Eric Fellheimere040fe92015-11-09 23:54:46 +0000154 assertSkipsFoo(patternSequence);
155 }
156
Florian Weikert92b22362015-12-03 10:17:18 +0000157 @Test
kkress1847a012020-06-24 12:30:11 -0700158 public void testIgnoredPatternBlocksPatternEvaluation() throws Exception {
Eric Fellheimere040fe92015-11-09 23:54:46 +0000159 // Given a well-formed package "//foo" and a malformed package "//foo/foo",
160 createFooAndFooFoo();
161
162 // Given a target pattern sequence consisting of a recursive pattern for "//foo/...",
163 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...");
164
kkress1847a012020-06-24 12:30:11 -0700165 // and an ignored entry for the malformed package,
166 scratch.overwriteFile(ADDITIONAL_IGNORED_PACKAGE_PREFIXES_FILE_PATH_STRING, "foo/foo");
Eric Fellheimere040fe92015-11-09 23:54:46 +0000167
168 assertSkipsFoo(patternSequence);
169 }
170
171 private void assertSkipsFoo(ImmutableList<String> patternSequence) throws Exception {
172
173
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000174 // When PrepareDepsOfPatternsFunction completes evaluation (successfully),
175 WalkableGraph walkableGraph =
176 getGraphFromPatternsEvaluation(
177 patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
178
Brian Silvermand7d6d622016-03-17 09:53:39 +0000179 // Then the graph contains a package value for "@//foo",
lberkiaea56b32017-05-30 12:35:33 +0200180 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo")), walkableGraph)).isTrue();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000181
Brian Silvermand7d6d622016-03-17 09:53:39 +0000182 // But no package value for "@//foo/foo",
lberkiaea56b32017-05-30 12:35:33 +0200183 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo/foo")), walkableGraph))
184 .isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000185
Brian Silvermand7d6d622016-03-17 09:53:39 +0000186 // And the graph does not contain a value for the target "@//foo/foo:foofoo".
187 Label label = Label.create("@//foo/foo", "foofoo");
lberkiaea56b32017-05-30 12:35:33 +0200188 assertThat(exists(getKeyForLabel(label), walkableGraph)).isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000189 }
190
Florian Weikert92b22362015-12-03 10:17:18 +0000191 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000192 public void testNegativeNonTBDPatternsAreSkippedWithWarnings() throws Exception {
193 // Given a target pattern sequence with a negative non-TBD pattern,
194 ImmutableList<String> patternSequence = ImmutableList.of("-//foo/bar");
195
196 // When PrepareDepsOfPatternsFunction completes evaluation,
197 getGraphFromPatternsEvaluation(patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
198
199 // Then a event is published that says that negative non-TBD patterns are skipped.
200 assertContainsEvent(
shreyax432b2532019-01-23 11:16:07 -0800201 "Skipping '-//foo/bar, excludedSubdirs=[], filteringPolicy=[]': Negative target patterns of"
202 + " types other than \"targets below directory\" are not permitted.");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000203 }
204
205 // Helpers:
206
207 private WalkableGraph getGraphFromPatternsEvaluation(
208 ImmutableList<String> patternSequence, boolean successExpected, boolean keepGoing)
209 throws InterruptedException {
janakra3652a32020-09-10 12:05:20 -0700210 SkyKey independentTarget =
211 PrepareDepsOfPatternsValue.key(patternSequence, PathFragment.EMPTY_FRAGMENT);
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000212 ImmutableList<SkyKey> singletonTargetPattern = ImmutableList.of(independentTarget);
213
214 // When PrepareDepsOfPatternsFunction completes evaluation,
Googler10028672018-10-25 12:14:34 -0700215 EvaluationContext evaluationContext =
216 EvaluationContext.newBuilder()
217 .setKeepGoing(keepGoing)
218 .setNumThreads(100)
michajlo7a485be2020-07-30 11:08:46 -0700219 .setEventHandler(new Reporter(new EventBus(), eventCollector))
Googler10028672018-10-25 12:14:34 -0700220 .build();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000221 EvaluationResult<SkyValue> evaluationResult =
Googler0592f3f2019-07-12 09:00:46 -0700222 skyframeExecutor.getDriver().evaluate(singletonTargetPattern, evaluationContext);
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}