blob: b307d09db3ffed34f2c6649cbaecc7a2be66cbd8 [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,
77 AnalysisMock.get().getProductName());
mjhalupka5d7fa7b2018-03-22 13:37:38 -070078 ConfiguredRuleClassProvider ruleClassProvider = AnalysisMock.get().createRuleClassProvider();
nharmatae4eb23f2017-12-05 09:27:45 -080079 skyframeExecutor =
80 SequencedSkyframeExecutor.create(
81 AnalysisMock.get()
82 .getPackageFactoryBuilderForTesting(directories)
nharmatae57e9a32018-04-02 15:10:24 -070083 .build(ruleClassProvider),
nharmatae4eb23f2017-12-05 09:27:45 -080084 fileSystem,
85 directories,
86 new ActionKeyContext(),
87 /*workspaceStatusActionFactory=*/ null,
88 AnalysisMock.get().createRuleClassProvider().getBuildInfoFactories(),
89 ImmutableList.of(),
90 AnalysisMock.get().getSkyFunctions(directories),
91 ImmutableList.of(),
92 BazelSkyframeExecutorConstants.HARDCODED_BLACKLISTED_PACKAGE_PREFIXES,
93 PathFragment.create(ADDITIONAL_BLACKLISTED_PACKAGE_PREFIXES_FILE_PATH_STRING),
94 BazelSkyframeExecutorConstants.CROSS_REPOSITORY_LABEL_VIOLATION_STRATEGY,
95 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY,
mjhalupka5d7fa7b2018-03-22 13:37:38 -070096 BazelSkyframeExecutorConstants.ACTION_ON_IO_EXCEPTION_READING_BUILD_FILE,
97 DefaultBuildOptionsForTesting.getDefaultBuildOptionsForTest(ruleClassProvider));
nharmatae4eb23f2017-12-05 09:27:45 -080098 TestConstants.processSkyframeExecutorForTesting(skyframeExecutor);
99 skyframeExecutor.preparePackageLoading(
100 new PathPackageLocator(
101 outputBase,
tomluee6a6862018-01-17 14:36:26 -0800102 ImmutableList.of(Root.fromPath(rootDirectory)),
nharmatae4eb23f2017-12-05 09:27:45 -0800103 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
104 Options.getDefaults(PackageCacheOptions.class),
105 Options.getDefaults(SkylarkSemanticsOptions.class),
106 AnalysisMock.get().getDefaultsPackageContent(),
107 UUID.randomUUID(),
108 ImmutableMap.<String, String>of(),
109 ImmutableMap.<String, String>of(),
110 new TimestampGranularityMonitor(null));
111 skyframeExecutor.injectExtraPrecomputedValues(ImmutableList.of(PrecomputedValue.injected(
112 RepositoryDelegatorFunction.REPOSITORY_OVERRIDES,
113 ImmutableMap.<RepositoryName, PathFragment>of())));
114 scratch.file(ADDITIONAL_BLACKLISTED_PACKAGE_PREFIXES_FILE_PATH_STRING);
115 }
116
Florian Weikert92b22362015-12-03 10:17:18 +0000117 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000118 public void testRecursiveEvaluationFailsOnBadBuildFile() throws Exception {
Brian Silvermand7d6d622016-03-17 09:53:39 +0000119 // Given a well-formed package "@//foo" and a malformed package "@//foo/foo",
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000120 createFooAndFooFoo();
121
122 // Given a target pattern sequence consisting of a recursive pattern for "//foo/...",
123 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...");
124
125 // When PrepareDepsOfPatternsFunction completes evaluation (with no error because it was
126 // recovered from),
127 WalkableGraph walkableGraph =
128 getGraphFromPatternsEvaluation(
129 patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
130
Brian Silvermand7d6d622016-03-17 09:53:39 +0000131 // Then the graph contains package values for "@//foo" and "@//foo/foo",
lberkiaea56b32017-05-30 12:35:33 +0200132 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo")), walkableGraph)).isTrue();
133 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo/foo")), walkableGraph))
134 .isTrue();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000135
Brian Silvermand7d6d622016-03-17 09:53:39 +0000136 // But the graph does not contain a value for the target "@//foo/foo:foofoo".
lberkiaea56b32017-05-30 12:35:33 +0200137 assertThat(exists(getKeyForLabel(Label.create("@//foo/foo", "foofoo")), walkableGraph))
138 .isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000139 }
140
Florian Weikert92b22362015-12-03 10:17:18 +0000141 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000142 public void testNegativePatternBlocksPatternEvaluation() throws Exception {
143 // Given a well-formed package "//foo" and a malformed package "//foo/foo",
144 createFooAndFooFoo();
145
146 // Given a target pattern sequence consisting of a recursive pattern for "//foo/..." followed
147 // by a negative pattern for the malformed package,
148 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...", "-//foo/foo/...");
149
Eric Fellheimere040fe92015-11-09 23:54:46 +0000150 assertSkipsFoo(patternSequence);
151 }
152
Florian Weikert92b22362015-12-03 10:17:18 +0000153 @Test
Eric Fellheimere040fe92015-11-09 23:54:46 +0000154 public void testBlacklistPatternBlocksPatternEvaluation() throws Exception {
155 // Given a well-formed package "//foo" and a malformed package "//foo/foo",
156 createFooAndFooFoo();
157
158 // Given a target pattern sequence consisting of a recursive pattern for "//foo/...",
159 ImmutableList<String> patternSequence = ImmutableList.of("//foo/...");
160
161 // and a blacklist for the malformed package,
nharmatae4eb23f2017-12-05 09:27:45 -0800162 scratch.overwriteFile(ADDITIONAL_BLACKLISTED_PACKAGE_PREFIXES_FILE_PATH_STRING, "foo/foo");
Eric Fellheimere040fe92015-11-09 23:54:46 +0000163
164 assertSkipsFoo(patternSequence);
165 }
166
167 private void assertSkipsFoo(ImmutableList<String> patternSequence) throws Exception {
168
169
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000170 // When PrepareDepsOfPatternsFunction completes evaluation (successfully),
171 WalkableGraph walkableGraph =
172 getGraphFromPatternsEvaluation(
173 patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
174
Brian Silvermand7d6d622016-03-17 09:53:39 +0000175 // Then the graph contains a package value for "@//foo",
lberkiaea56b32017-05-30 12:35:33 +0200176 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo")), walkableGraph)).isTrue();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000177
Brian Silvermand7d6d622016-03-17 09:53:39 +0000178 // But no package value for "@//foo/foo",
lberkiaea56b32017-05-30 12:35:33 +0200179 assertThat(exists(PackageValue.key(PackageIdentifier.parse("@//foo/foo")), walkableGraph))
180 .isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000181
Brian Silvermand7d6d622016-03-17 09:53:39 +0000182 // And the graph does not contain a value for the target "@//foo/foo:foofoo".
183 Label label = Label.create("@//foo/foo", "foofoo");
lberkiaea56b32017-05-30 12:35:33 +0200184 assertThat(exists(getKeyForLabel(label), walkableGraph)).isFalse();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000185 }
186
Florian Weikert92b22362015-12-03 10:17:18 +0000187 @Test
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000188 public void testNegativeNonTBDPatternsAreSkippedWithWarnings() throws Exception {
189 // Given a target pattern sequence with a negative non-TBD pattern,
190 ImmutableList<String> patternSequence = ImmutableList.of("-//foo/bar");
191
192 // When PrepareDepsOfPatternsFunction completes evaluation,
193 getGraphFromPatternsEvaluation(patternSequence, /*successExpected=*/ true, /*keepGoing=*/ true);
194
195 // Then a event is published that says that negative non-TBD patterns are skipped.
196 assertContainsEvent(
197 "Skipping '-//foo/bar': Negative target patterns of types other than \"targets below "
198 + "directory\" are not permitted.");
199 }
200
201 // Helpers:
202
203 private WalkableGraph getGraphFromPatternsEvaluation(
204 ImmutableList<String> patternSequence, boolean successExpected, boolean keepGoing)
205 throws InterruptedException {
206 SkyKey independentTarget = PrepareDepsOfPatternsValue.key(patternSequence, "");
207 ImmutableList<SkyKey> singletonTargetPattern = ImmutableList.of(independentTarget);
208
209 // When PrepareDepsOfPatternsFunction completes evaluation,
210 EvaluationResult<SkyValue> evaluationResult =
nharmatae4eb23f2017-12-05 09:27:45 -0800211 skyframeExecutor
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000212 .getDriverForTesting()
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000213 .evaluate(
214 singletonTargetPattern,
215 keepGoing,
nharmatae4eb23f2017-12-05 09:27:45 -0800216 /*numThreads=*/ 100,
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000217 new Reporter(new EventBus(), eventCollector));
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000218 // The evaluation has no errors if success was expected.
219 assertThat(evaluationResult.hasError()).isNotEqualTo(successExpected);
220 return Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
221 }
222
223 private void createFooAndFooFoo() throws IOException {
224 scratch.file(
225 "foo/BUILD", "genrule(name = 'foo',", " outs = ['out.txt'],", " cmd = 'touch $@')");
226 scratch.file(
227 "foo/foo/BUILD", "genrule(name = 'foofoo',", " This isn't even remotely grammatical.)");
228 }
229}