blob: 1626ebf41b0ad76f7c2fc52471b85950bc285059 [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
lberkiaea56b32017-05-30 12:35:33 +020016import static com.google.common.truth.Truth.assertThat;
wyva8176452021-09-02 05:38:18 -070017import static com.google.devtools.build.lib.bazel.bzlmod.BzlmodTestUtil.createModuleKey;
nharmatad86b5092018-10-16 15:50:21 -070018import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult;
michajlo660d17f2020-03-27 09:01:57 -070019import static org.junit.Assert.assertThrows;
Florian Weikert92b22362015-12-03 10:17:18 +000020import static org.junit.Assert.fail;
21
Lukacs Berkid3262d12015-10-30 14:33:51 +000022import com.google.common.collect.ImmutableList;
Klaus Aehlig6f33a1c2016-09-13 16:46:10 +000023import com.google.common.collect.ImmutableMap;
Florian Weikertcca703a2015-12-07 09:56:38 +000024import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
philwo3bcb9f62017-09-06 12:52:21 +020025import com.google.devtools.build.lib.clock.BlazeClock;
wyv4858cbf2022-05-04 13:56:45 -070026import com.google.devtools.build.lib.cmdline.BazelModuleContext;
John Fielda97e17f2015-11-13 02:19:52 +000027import com.google.devtools.build.lib.cmdline.Label;
Googler91978392023-03-16 12:41:23 -070028import com.google.devtools.build.lib.packages.RuleVisibility;
adonovan240bdea2020-09-03 15:24:12 -070029import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
ajurkowskid74b0ec2020-04-13 10:58:21 -070030import com.google.devtools.build.lib.pkgcache.PackageOptions;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000031import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
Googler4e220922023-01-12 06:33:22 -080032import com.google.devtools.build.lib.runtime.QuiescingExecutorsImpl;
brandjon771a0292020-05-26 12:04:16 -070033import com.google.devtools.build.lib.skyframe.BzlLoadFunction.BzlLoadFailedException;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000034import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
Ulf Adamsc73051c62016-03-23 09:18:13 +000035import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
janakr97c0bd12020-09-08 13:19:03 -070036import com.google.devtools.build.lib.vfs.DigestHashFunction;
nharmatadc1d9dc2020-04-18 16:53:28 -070037import com.google.devtools.build.lib.vfs.FileStatus;
38import com.google.devtools.build.lib.vfs.FileSystem;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000039import com.google.devtools.build.lib.vfs.Path;
dannark4e42c322018-11-08 19:32:04 -080040import com.google.devtools.build.lib.vfs.PathFragment;
tomluee6a6862018-01-17 14:36:26 -080041import com.google.devtools.build.lib.vfs.Root;
dannark4e42c322018-11-08 19:32:04 -080042import com.google.devtools.build.lib.vfs.RootedPath;
nharmatadc1d9dc2020-04-18 16:53:28 -070043import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000044import com.google.devtools.build.skyframe.ErrorInfo;
45import com.google.devtools.build.skyframe.EvaluationResult;
46import com.google.devtools.build.skyframe.SkyKey;
Janak Ramakrishnan326c6982016-09-27 14:58:26 +000047import com.google.devtools.common.options.Options;
nharmatadc1d9dc2020-04-18 16:53:28 -070048import java.io.IOException;
49import java.io.InputStream;
Klaus Aehlig6f33a1c2016-09-13 16:46:10 +000050import java.util.UUID;
nharmatadc1d9dc2020-04-18 16:53:28 -070051import javax.annotation.Nullable;
adonovan3ed7ed52020-09-30 12:03:28 -070052import net.starlark.java.eval.StarlarkInt;
Florian Weikert92b22362015-12-03 10:17:18 +000053import org.junit.Before;
54import org.junit.Test;
55import org.junit.runner.RunWith;
56import org.junit.runners.JUnit4;
57
brandjon771a0292020-05-26 12:04:16 -070058/** Tests for BzlLoadFunction. */
Florian Weikert92b22362015-12-03 10:17:18 +000059@RunWith(JUnit4.class)
brandjon771a0292020-05-26 12:04:16 -070060public class BzlLoadFunctionTest extends BuildViewTestCase {
wyva8176452021-09-02 05:38:18 -070061
nharmatadc1d9dc2020-04-18 16:53:28 -070062 @Override
63 protected FileSystem createFileSystem() {
64 return new CustomInMemoryFs();
65 }
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000066
Florian Weikert92b22362015-12-03 10:17:18 +000067 @Before
laurentlbdd612a82018-10-16 19:42:48 -070068 public final void preparePackageLoading() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000069 Path alternativeRoot = scratch.dir("/root_2");
ajurkowskid74b0ec2020-04-13 10:58:21 -070070 PackageOptions packageOptions = Options.getDefaults(PackageOptions.class);
Googler91978392023-03-16 12:41:23 -070071 packageOptions.defaultVisibility = RuleVisibility.PUBLIC;
ajurkowskid74b0ec2020-04-13 10:58:21 -070072 packageOptions.showLoadingProgress = true;
73 packageOptions.globbingThreads = 7;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000074 getSkyframeExecutor()
75 .preparePackageLoading(
John Catere0d1d0e2017-11-28 20:47:41 -080076 new PathPackageLocator(
77 outputBase,
tomluee6a6862018-01-17 14:36:26 -080078 ImmutableList.of(Root.fromPath(rootDirectory), Root.fromPath(alternativeRoot)),
John Catere0d1d0e2017-11-28 20:47:41 -080079 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
ajurkowskid74b0ec2020-04-13 10:58:21 -070080 packageOptions,
adonovan240bdea2020-09-03 15:24:12 -070081 Options.getDefaults(BuildLanguageOptions.class),
Ulf Adamsc73051c62016-03-23 09:18:13 +000082 UUID.randomUUID(),
Googlerb3da9fb2022-10-05 07:43:12 -070083 ImmutableMap.of(),
Googler4e220922023-01-12 06:33:22 -080084 QuiescingExecutorsImpl.forTesting(),
Ulf Adamsc73051c62016-03-23 09:18:13 +000085 new TimestampGranularityMonitor(BlazeClock.instance()));
Googlerb3da9fb2022-10-05 07:43:12 -070086 skyframeExecutor.setActionEnv(ImmutableMap.of());
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000087 }
88
Florian Weikert92b22362015-12-03 10:17:18 +000089 @Test
brandjon771a0292020-05-26 12:04:16 -070090 public void testBzlLoadLabels() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000091 scratch.file("pkg1/BUILD");
92 scratch.file("pkg1/ext.bzl");
John Field1ea7fc32015-12-22 19:37:19 +000093 checkSuccessfulLookup("//pkg1:ext.bzl");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000094
95 scratch.file("pkg2/BUILD");
96 scratch.file("pkg2/dir/ext.bzl");
John Field1ea7fc32015-12-22 19:37:19 +000097 checkSuccessfulLookup("//pkg2:dir/ext.bzl");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000098
99 scratch.file("dir/pkg3/BUILD");
100 scratch.file("dir/pkg3/dir/ext.bzl");
John Field1ea7fc32015-12-22 19:37:19 +0000101 checkSuccessfulLookup("//dir/pkg3:dir/ext.bzl");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000102 }
103
Florian Weikert92b22362015-12-03 10:17:18 +0000104 @Test
brandjon771a0292020-05-26 12:04:16 -0700105 public void testBzlLoadLabelsAlternativeRoot() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000106 scratch.file("/root_2/pkg4/BUILD");
107 scratch.file("/root_2/pkg4/ext.bzl");
John Field1ea7fc32015-12-22 19:37:19 +0000108 checkSuccessfulLookup("//pkg4:ext.bzl");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000109 }
110
Florian Weikert92b22362015-12-03 10:17:18 +0000111 @Test
brandjon771a0292020-05-26 12:04:16 -0700112 public void testBzlLoadLabelsMultipleBuildFiles() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000113 scratch.file("dir1/BUILD");
114 scratch.file("dir1/dir2/BUILD");
115 scratch.file("dir1/dir2/ext.bzl");
John Field1ea7fc32015-12-22 19:37:19 +0000116 checkSuccessfulLookup("//dir1/dir2:ext.bzl");
117 }
118
119 @Test
gregce1cd84ec2020-04-09 15:45:19 -0700120 public void testLoadFromStarlarkFileInRemoteRepo() throws Exception {
laurentlbdd612a82018-10-16 19:42:48 -0700121 scratch.overwriteFile(
122 "WORKSPACE",
John Field1ea7fc32015-12-22 19:37:19 +0000123 "local_repository(",
124 " name = 'a_remote_repo',",
125 " path = '/a_remote_repo'",
126 ")");
John Catere6843922017-04-20 16:10:11 +0200127 scratch.file("/a_remote_repo/WORKSPACE");
John Field1ea7fc32015-12-22 19:37:19 +0000128 scratch.file("/a_remote_repo/remote_pkg/BUILD");
laurentlbdd612a82018-10-16 19:42:48 -0700129 scratch.file("/a_remote_repo/remote_pkg/ext1.bzl", "load(':ext2.bzl', 'CONST')");
130 scratch.file("/a_remote_repo/remote_pkg/ext2.bzl", "CONST = 17");
John Field1ea7fc32015-12-22 19:37:19 +0000131 checkSuccessfulLookup("@a_remote_repo//remote_pkg:ext1.bzl");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000132 }
133
Florian Weikert92b22362015-12-03 10:17:18 +0000134 @Test
nharmata11642e92018-10-09 19:26:14 -0700135 public void testLoadRelativeLabel() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000136 scratch.file("pkg/BUILD");
137 scratch.file("pkg/ext1.bzl", "a = 1");
laurentlb7cf1c692017-12-04 05:44:54 -0800138 scratch.file("pkg/ext2.bzl", "load(':ext1.bzl', 'a')");
nharmata11642e92018-10-09 19:26:14 -0700139 checkSuccessfulLookup("//pkg:ext2.bzl");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000140 }
141
Florian Weikert92b22362015-12-03 10:17:18 +0000142 @Test
nharmata11642e92018-10-09 19:26:14 -0700143 public void testLoadAbsoluteLabel() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000144 scratch.file("pkg2/BUILD");
145 scratch.file("pkg3/BUILD");
146 scratch.file("pkg2/ext.bzl", "b = 1");
laurentlb7cf1c692017-12-04 05:44:54 -0800147 scratch.file("pkg3/ext.bzl", "load('//pkg2:ext.bzl', 'b')");
nharmata11642e92018-10-09 19:26:14 -0700148 checkSuccessfulLookup("//pkg3:ext.bzl");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000149 }
150
Florian Weikert92b22362015-12-03 10:17:18 +0000151 @Test
nharmata11642e92018-10-09 19:26:14 -0700152 public void testLoadFromSameAbsoluteLabelTwice() throws Exception {
John Field81e093e2015-11-13 21:25:41 +0000153 scratch.file("pkg1/BUILD");
154 scratch.file("pkg2/BUILD");
155 scratch.file("pkg1/ext.bzl", "a = 1", "b = 2");
laurentlb7cf1c692017-12-04 05:44:54 -0800156 scratch.file("pkg2/ext.bzl", "load('//pkg1:ext.bzl', 'a')", "load('//pkg1:ext.bzl', 'b')");
nharmata11642e92018-10-09 19:26:14 -0700157 checkSuccessfulLookup("//pkg2:ext.bzl");
John Field81e093e2015-11-13 21:25:41 +0000158 }
159
Florian Weikert92b22362015-12-03 10:17:18 +0000160 @Test
nharmata11642e92018-10-09 19:26:14 -0700161 public void testLoadFromSameRelativeLabelTwice() throws Exception {
John Field81e093e2015-11-13 21:25:41 +0000162 scratch.file("pkg/BUILD");
163 scratch.file("pkg/ext1.bzl", "a = 1", "b = 2");
laurentlb7cf1c692017-12-04 05:44:54 -0800164 scratch.file("pkg/ext2.bzl", "load(':ext1.bzl', 'a')", "load(':ext1.bzl', 'b')");
nharmata11642e92018-10-09 19:26:14 -0700165 checkSuccessfulLookup("//pkg:ext2.bzl");
John Field3b58a1c2015-11-17 21:21:34 +0000166 }
167
Florian Weikert92b22362015-12-03 10:17:18 +0000168 @Test
nharmata11642e92018-10-09 19:26:14 -0700169 public void testLoadFromRelativeLabelInSubdir() throws Exception {
John Field3b58a1c2015-11-17 21:21:34 +0000170 scratch.file("pkg/BUILD");
171 scratch.file("pkg/subdir/ext1.bzl", "a = 1");
laurentlb7cf1c692017-12-04 05:44:54 -0800172 scratch.file("pkg/subdir/ext2.bzl", "load(':subdir/ext1.bzl', 'a')");
nharmata11642e92018-10-09 19:26:14 -0700173 checkSuccessfulLookup("//pkg:subdir/ext2.bzl");
John Field81e093e2015-11-13 21:25:41 +0000174 }
175
Googlera0cd3552023-05-01 13:43:28 -0700176 @Test
177 public void testLoadBadExtension_sclDisabled() throws Exception {
178 setBuildLanguageOptions("--experimental_enable_scl_dialect=false");
179
180 scratch.file("pkg/BUILD");
181 scratch.file("pkg/ext.bzl", "load(':foo.garbage', 'a')");
182 reporter.removeHandler(failFastHandler);
183 checkFailingLookup("//pkg:ext.bzl", "has invalid load statements");
184 assertContainsEvent("The label must reference a file with extension \".bzl\"");
185 assertDoesNotContainEvent(".scl");
186 }
187
188 @Test
189 public void testLoadBadExtension_sclEnabled() throws Exception {
190 setBuildLanguageOptions("--experimental_enable_scl_dialect=true");
191
192 scratch.file("pkg/BUILD");
193 scratch.file("pkg/ext.bzl", "load(':foo.garbage', 'a')");
194 reporter.removeHandler(failFastHandler);
195 checkFailingLookup("//pkg:ext.bzl", "has invalid load statements");
196 assertContainsEvent("The label must reference a file with extension \".bzl\" or \".scl\"");
197 }
198
199 @Test
200 public void testLoadingSclRequiresExperimentalFlag() throws Exception {
201 setBuildLanguageOptions("--experimental_enable_scl_dialect=false");
202
203 scratch.file("pkg/BUILD");
204 scratch.file("pkg/ext.scl");
205 reporter.removeHandler(failFastHandler);
206 checkFailingLookup(
207 "//pkg:ext.scl", "loading .scl files requires setting --experimental_enable_scl_dialect");
208 }
209
210 @Test
211 public void testCanLoadScl() throws Exception {
212 setBuildLanguageOptions("--experimental_enable_scl_dialect=true");
213
214 scratch.file("pkg/BUILD");
215 scratch.file("pkg/ext.scl");
216 checkSuccessfulLookup("//pkg:ext.scl");
217 }
218
219 @Test
220 public void testCanLoadSclFromBzlAndScl() throws Exception {
221 setBuildLanguageOptions("--experimental_enable_scl_dialect=true");
222
223 scratch.file("pkg/BUILD");
224 scratch.file("pkg/ext1.scl", "a = 1");
225 // Can use relative load label syntax from ext2a.bzl, but not from ext2b.scl.
226 scratch.file("pkg/ext2a.bzl", "load(':ext1.scl', 'a')");
227 scratch.file("pkg/ext2b.scl", "load('//pkg:ext1.scl', 'a')");
228
229 checkSuccessfulLookup("//pkg:ext2a.bzl");
230 checkSuccessfulLookup("//pkg:ext2b.scl");
231 }
232
233 @Test
234 public void testSclCannotLoadNonSclFiles() throws Exception {
235 setBuildLanguageOptions("--experimental_enable_scl_dialect=true");
236
237 scratch.file("pkg/BUILD");
238 scratch.file("pkg/ext1a.bzl", "a = 1");
239 scratch.file("pkg/ext1a.garbage", "a = 1");
240 // Cannot use relative label.
241 scratch.file("pkg/ext2a.scl", "load('//pkg:ext1a.bzl', 'a')");
242 scratch.file("pkg/ext2b.scl", "load('//pkg:ext1b.garbage', 'a')");
243
244 reporter.removeHandler(failFastHandler);
245 checkFailingLookup("//pkg:ext2a.scl", "has invalid load statements");
246 assertContainsEvent(
247 "The label must reference a file with extension \".scl\" (.scl files cannot load .bzl"
248 + " files)");
249 eventCollector.clear();
250 checkFailingLookup("//pkg:ext2b.scl", "has invalid load statements");
251 assertContainsEvent("The label must reference a file with extension \".scl\"");
252 assertDoesNotContainEvent(".bzl");
253 }
254
255 @Test
256 public void testSclCanOnlyLoadLabelsRelativeToDefaultRepoRoot() throws Exception {
257 setBuildLanguageOptions("--experimental_enable_scl_dialect=true");
258
259 scratch.file("pkg/BUILD");
260 scratch.file("pkg/ext1.scl", "load(':foo.scl', 'a')");
261 scratch.file("pkg/ext2.scl", "load('@repo//:foo.scl', 'a')");
262
263 reporter.removeHandler(failFastHandler);
264 checkFailingLookup("//pkg:ext1.scl", "has invalid load statements");
265 assertContainsEvent("in .scl files, load labels must begin with \"//\"");
266 eventCollector.clear();
267 checkFailingLookup("//pkg:ext2.scl", "has invalid load statements");
268 assertContainsEvent("in .scl files, load labels must begin with \"//\"");
269 }
270
Googlera67200c2023-05-22 12:16:29 -0700271 @Test
272 public void testSclSupportsStructAndVisibility() throws Exception {
273 setBuildLanguageOptions("--experimental_enable_scl_dialect=true");
274
275 scratch.file("pkg/BUILD");
276 scratch.file(
277 "pkg/ext1.scl", //
278 "visibility('private')",
279 "a = struct()");
280 scratch.file(
281 "pkg/ext2.scl", //
282 "load('//pkg:ext1.scl', 'a')");
283 scratch.file("pkg2/BUILD");
284 scratch.file(
285 "pkg2/ext3.scl", //
286 "load('//pkg:ext1.scl', 'a')");
287
288 checkSuccessfulLookup("//pkg:ext2.scl");
289 reporter.removeHandler(failFastHandler);
290 checkFailingLookup(
291 "//pkg2:ext3.scl", "module //pkg2:ext3.scl contains .bzl load visibility violations");
292 }
293
294 @Test
295 public void testSclDoesNotSupportOtherBazelSymbols() throws Exception {
296 setBuildLanguageOptions("--experimental_enable_scl_dialect=true");
297
298 scratch.file("pkg/BUILD");
299 scratch.file(
300 "pkg/ext.scl", //
301 "a = depset([])");
302
303 reporter.removeHandler(failFastHandler);
304 checkFailingLookup("//pkg:ext.scl", "compilation of module 'pkg/ext.scl' failed");
305 assertContainsEvent("name 'depset' is not defined");
306 }
307
Googler00994542023-05-23 06:42:51 -0700308 @Test
309 public void testSclDisallowsNonAsciiStringLiterals() throws Exception {
310 setBuildLanguageOptions("--experimental_enable_scl_dialect=true");
311
312 scratch.file("pkg/BUILD");
313 scratch.file(
314 "pkg/ext1.bzl", //
315 "'x\377z'"); // xÿz
316 scratch.file(
317 "pkg/ext2.scl", //
318 "'x\377z'");
319
320 checkSuccessfulLookup("//pkg:ext1.bzl");
321 reporter.removeHandler(failFastHandler);
322 checkFailingLookup("//pkg:ext2.scl", "compilation of module 'pkg/ext2.scl' failed");
323 assertContainsEvent("string literal contains non-ASCII character");
324 }
325
brandjon771a0292020-05-26 12:04:16 -0700326 private EvaluationResult<BzlLoadValue> get(SkyKey skyKey) throws Exception {
327 EvaluationResult<BzlLoadValue> result =
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000328 SkyframeExecutorTestUtils.evaluate(
brandjon771a0292020-05-26 12:04:16 -0700329 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000330 if (result.hasError()) {
brandjon771a0292020-05-26 12:04:16 -0700331 fail(result.getError(skyKey).getException().getMessage());
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000332 }
333 return result;
334 }
335
ajurkowskie2982912020-04-09 10:32:08 -0700336 private static SkyKey key(String label) {
Googler08463dc2023-01-20 08:02:19 -0800337 return BzlLoadValue.keyForBuild(Label.parseCanonicalUnchecked(label));
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000338 }
339
Googler24a49412022-07-01 13:01:25 -0700340 /** Loads a .bzl with the given label and asserts success. */
John Field1ea7fc32015-12-22 19:37:19 +0000341 private void checkSuccessfulLookup(String label) throws Exception {
brandjon771a0292020-05-26 12:04:16 -0700342 SkyKey skyKey = key(label);
343 EvaluationResult<BzlLoadValue> result = get(skyKey);
Googler24a49412022-07-01 13:01:25 -0700344 // Ensure that the file has been processed by checking its Module for the label field.
adonovan39e42d12020-07-09 09:16:58 -0700345 assertThat(label)
346 .isEqualTo(BazelModuleContext.of(result.get(skyKey).getModule()).label().toString());
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000347 }
348
Googler24a49412022-07-01 13:01:25 -0700349 /* Loads a .bzl with the given label and asserts BzlLoadFailedException with the given message. */
350 private void checkFailingLookup(String label, String expectedMessage)
351 throws InterruptedException {
352 SkyKey skyKey = key(label);
353 EvaluationResult<BzlLoadValue> result =
354 SkyframeExecutorTestUtils.evaluate(
355 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
356 assertThat(result.hasError()).isTrue();
357 assertThatEvaluationResult(result)
358 .hasErrorEntryForKeyThat(skyKey)
359 .hasExceptionThat()
360 .isInstanceOf(BzlLoadFailedException.class);
361 assertThatEvaluationResult(result)
362 .hasErrorEntryForKeyThat(skyKey)
363 .hasExceptionThat()
364 .hasMessageThat()
365 .contains(expectedMessage);
366 }
367
Florian Weikert92b22362015-12-03 10:17:18 +0000368 @Test
brandjon771a0292020-05-26 12:04:16 -0700369 public void testBzlLoadNoBuildFile() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000370 scratch.file("pkg/ext.bzl", "");
brandjon771a0292020-05-26 12:04:16 -0700371 SkyKey skyKey = key("//pkg:ext.bzl");
372 EvaluationResult<BzlLoadValue> result =
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000373 SkyframeExecutorTestUtils.evaluate(
brandjon771a0292020-05-26 12:04:16 -0700374 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
lberkiaea56b32017-05-30 12:35:33 +0200375 assertThat(result.hasError()).isTrue();
brandjon771a0292020-05-26 12:04:16 -0700376 ErrorInfo errorInfo = result.getError(skyKey);
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000377 String errorMessage = errorInfo.getException().getMessage();
lberkiaea56b32017-05-30 12:35:33 +0200378 assertThat(errorMessage)
laurentlb3f791e762019-03-26 08:01:28 -0700379 .contains(
380 "Every .bzl file must have a corresponding package, but '//pkg:ext.bzl' does not");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000381 }
John Fielda97e17f2015-11-13 02:19:52 +0000382
Florian Weikert92b22362015-12-03 10:17:18 +0000383 @Test
brandjon771a0292020-05-26 12:04:16 -0700384 public void testBzlLoadNoBuildFileForLoad() throws Exception {
John Field110b0652015-11-13 21:56:42 +0000385 scratch.file("pkg2/BUILD");
386 scratch.file("pkg1/ext.bzl", "a = 1");
laurentlb7cf1c692017-12-04 05:44:54 -0800387 scratch.file("pkg2/ext.bzl", "load('//pkg1:ext.bzl', 'a')");
brandjon771a0292020-05-26 12:04:16 -0700388 SkyKey skyKey = key("//pkg:ext.bzl");
389 EvaluationResult<BzlLoadValue> result =
John Field110b0652015-11-13 21:56:42 +0000390 SkyframeExecutorTestUtils.evaluate(
brandjon771a0292020-05-26 12:04:16 -0700391 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
lberkiaea56b32017-05-30 12:35:33 +0200392 assertThat(result.hasError()).isTrue();
brandjon771a0292020-05-26 12:04:16 -0700393 ErrorInfo errorInfo = result.getError(skyKey);
John Field110b0652015-11-13 21:56:42 +0000394 String errorMessage = errorInfo.getException().getMessage();
laurentlb3f791e762019-03-26 08:01:28 -0700395 assertThat(errorMessage).contains("Every .bzl file must have a corresponding package");
John Field110b0652015-11-13 21:56:42 +0000396 }
397
Florian Weikert92b22362015-12-03 10:17:18 +0000398 @Test
brandjon771a0292020-05-26 12:04:16 -0700399 public void testBzlLoadFilenameWithControlChars() throws Exception {
John Fielda97e17f2015-11-13 02:19:52 +0000400 scratch.file("pkg/BUILD", "");
laurentlb7cf1c692017-12-04 05:44:54 -0800401 scratch.file("pkg/ext.bzl", "load('//pkg:oops\u0000.bzl', 'a')");
brandjon771a0292020-05-26 12:04:16 -0700402 SkyKey skyKey = key("//pkg:ext.bzl");
jcater83130f42019-04-30 14:29:28 -0700403 AssertionError e =
404 assertThrows(
405 AssertionError.class,
jcaterc8b01882019-05-03 05:51:05 -0700406 () ->
407 SkyframeExecutorTestUtils.evaluate(
brandjon771a0292020-05-26 12:04:16 -0700408 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter));
jcater83130f42019-04-30 14:29:28 -0700409 String errorMessage = e.getMessage();
410 assertThat(errorMessage)
411 .contains(
412 "invalid target name 'oops<?>.bzl': "
413 + "target names may not contain non-printable characters: '\\x00'");
John Fielda97e17f2015-11-13 02:19:52 +0000414 }
John Fieldbcb1bea2016-01-16 19:05:56 +0000415
416 @Test
Damien Martin-Guillerez6f07b792016-02-10 13:29:46 +0000417 public void testLoadFromExternalRepoInWorkspaceFileAllowed() throws Exception {
dannark4e42c322018-11-08 19:32:04 -0800418 Path p =
419 scratch.overwriteFile(
420 "WORKSPACE",
421 "local_repository(",
422 " name = 'a_remote_repo',",
423 " path = '/a_remote_repo'",
424 ")");
John Catere6843922017-04-20 16:10:11 +0200425 scratch.file("/a_remote_repo/WORKSPACE");
John Fieldbcb1bea2016-01-16 19:05:56 +0000426 scratch.file("/a_remote_repo/remote_pkg/BUILD");
laurentlbdd612a82018-10-16 19:42:48 -0700427 scratch.file("/a_remote_repo/remote_pkg/ext.bzl", "CONST = 17");
John Fieldbcb1bea2016-01-16 19:05:56 +0000428
dannark4e42c322018-11-08 19:32:04 -0800429 RootedPath rootedPath =
430 RootedPath.toRootedPath(
431 Root.fromPath(p.getParentDirectory()), PathFragment.create("WORKSPACE"));
432
brandjon771a0292020-05-26 12:04:16 -0700433 SkyKey skyKey =
brandjonb28a76b2020-05-26 12:53:22 -0700434 BzlLoadValue.keyForWorkspace(
Googler08463dc2023-01-20 08:02:19 -0800435 Label.parseCanonicalUnchecked("@a_remote_repo//remote_pkg:ext.bzl"),
dannark4e42c322018-11-08 19:32:04 -0800436 /* inWorkspace= */
437 /* workspaceChunk= */ 0,
438 rootedPath);
brandjon771a0292020-05-26 12:04:16 -0700439 EvaluationResult<BzlLoadValue> result =
John Fieldbcb1bea2016-01-16 19:05:56 +0000440 SkyframeExecutorTestUtils.evaluate(
brandjon771a0292020-05-26 12:04:16 -0700441 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
John Fieldbcb1bea2016-01-16 19:05:56 +0000442
lberkiaea56b32017-05-30 12:35:33 +0200443 assertThat(result.hasError()).isFalse();
John Fieldbcb1bea2016-01-16 19:05:56 +0000444 }
nharmatad86b5092018-10-16 15:50:21 -0700445
446 @Test
brandjon24912642020-05-27 11:28:45 -0700447 public void testLoadFromSubdirInSamePackageIsOk() throws Exception {
nharmatad86b5092018-10-16 15:50:21 -0700448 scratch.file("a/BUILD");
449 scratch.file("a/a.bzl", "load('//a:b/b.bzl', 'b')");
450 scratch.file("a/b/b.bzl", "b = 42");
451
452 checkSuccessfulLookup("//a:a.bzl");
453 }
454
455 @Test
brandjon24912642020-05-27 11:28:45 -0700456 public void testLoadMustRespectPackageBoundary_ofSubpkg() throws Exception {
nharmatad86b5092018-10-16 15:50:21 -0700457 scratch.file("a/BUILD");
458 scratch.file("a/a.bzl", "load('//a:b/b.bzl', 'b')");
459 scratch.file("a/b/BUILD", "");
460 scratch.file("a/b/b.bzl", "b = 42");
Googler24a49412022-07-01 13:01:25 -0700461 checkFailingLookup(
Googler83439e62019-09-24 12:11:30 -0700462 "//a:a.bzl",
463 "Label '//a:b/b.bzl' is invalid because 'a/b' is a subpackage; perhaps you meant to"
464 + " put the colon here: '//a/b:b.bzl'?");
465 }
nharmatad86b5092018-10-16 15:50:21 -0700466
Googler83439e62019-09-24 12:11:30 -0700467 @Test
brandjon24912642020-05-27 11:28:45 -0700468 public void testLoadMustRespectPackageBoundary_ofSubpkg_relative() throws Exception {
Googler83439e62019-09-24 12:11:30 -0700469 scratch.file("a/BUILD");
470 scratch.file("a/a.bzl", "load('b/b.bzl', 'b')");
471 scratch.file("a/b/BUILD", "");
472 scratch.file("a/b/b.bzl", "b = 42");
Googler24a49412022-07-01 13:01:25 -0700473 checkFailingLookup(
Googler83439e62019-09-24 12:11:30 -0700474 "//a:a.bzl",
475 "Label '//a:b/b.bzl' is invalid because 'a/b' is a subpackage; perhaps you meant to"
476 + " put the colon here: '//a/b:b.bzl'?");
nharmatad86b5092018-10-16 15:50:21 -0700477 }
478
479 @Test
brandjon24912642020-05-27 11:28:45 -0700480 public void testLoadMustRespectPackageBoundary_ofIndirectSubpkg() throws Exception {
nharmatad86b5092018-10-16 15:50:21 -0700481 scratch.file("a/BUILD");
482 scratch.file("a/a.bzl", "load('//a/b:c/c.bzl', 'c')");
483 scratch.file("a/b/BUILD", "");
484 scratch.file("a/b/c/BUILD", "");
485 scratch.file("a/b/c/c.bzl", "c = 42");
Googler24a49412022-07-01 13:01:25 -0700486 checkFailingLookup(
Googler83439e62019-09-24 12:11:30 -0700487 "//a:a.bzl",
488 "Label '//a/b:c/c.bzl' is invalid because 'a/b/c' is a subpackage; perhaps you meant"
489 + " to put the colon here: '//a/b/c:c.bzl'?");
nharmatad86b5092018-10-16 15:50:21 -0700490 }
491
492 @Test
brandjon24912642020-05-27 11:28:45 -0700493 public void testLoadMustRespectPackageBoundary_ofParentPkg() throws Exception {
nharmatad86b5092018-10-16 15:50:21 -0700494 scratch.file("a/b/BUILD");
495 scratch.file("a/b/b.bzl", "load('//a/c:c/c.bzl', 'c')");
496 scratch.file("a/BUILD");
497 scratch.file("a/c/c/c.bzl", "c = 42");
Googler24a49412022-07-01 13:01:25 -0700498 checkFailingLookup(
Googler83439e62019-09-24 12:11:30 -0700499 "//a/b:b.bzl",
500 "Label '//a/c:c/c.bzl' is invalid because 'a/c' is not a package; perhaps you meant to "
501 + "put the colon here: '//a:c/c/c.bzl'?");
502 }
nharmatad86b5092018-10-16 15:50:21 -0700503
Googler24a49412022-07-01 13:01:25 -0700504 @Test
505 public void testBzlVisibility_disabledWithoutFlag() throws Exception {
506 setBuildLanguageOptions("--experimental_bzl_visibility=false");
507
508 scratch.file("a/BUILD");
509 scratch.file(
510 "a/foo.bzl", //
511 "load(\"//b:bar.bzl\", \"x\")");
512 scratch.file("b/BUILD");
513 scratch.file(
514 "b/bar.bzl", //
515 "visibility(\"private\")",
516 "x = 1");
517
518 reporter.removeHandler(failFastHandler);
519 checkFailingLookup("//a:foo.bzl", "initialization of module 'b/bar.bzl' failed");
520 assertContainsEvent("Use of `visibility()` requires --experimental_bzl_visibility");
521 }
522
523 @Test
Googler24a49412022-07-01 13:01:25 -0700524 public void testBzlVisibility_publicExplicit() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700525 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler24a49412022-07-01 13:01:25 -0700526
527 scratch.file("a/BUILD");
528 scratch.file(
529 "a/foo.bzl", //
530 "load(\"//b:bar.bzl\", \"x\")");
531 scratch.file("b/BUILD");
532 scratch.file(
533 "b/bar.bzl", //
534 "visibility(\"public\")",
535 "x = 1");
536
537 checkSuccessfulLookup("//a:foo.bzl");
538 assertNoEvents();
539 }
540
541 @Test
542 public void testBzlVisibility_publicImplicit() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700543 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler24a49412022-07-01 13:01:25 -0700544
545 scratch.file("a/BUILD");
546 scratch.file(
547 "a/foo.bzl", //
548 "load(\"//b:bar.bzl\", \"x\")");
549 scratch.file("b/BUILD");
550 scratch.file(
551 "b/bar.bzl",
552 // No visibility() declaration, defaults to public.
553 "x = 1");
554
555 checkSuccessfulLookup("//a:foo.bzl");
556 assertNoEvents();
557 }
558
559 @Test
560 public void testBzlVisibility_privateSamePackage() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700561 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler24a49412022-07-01 13:01:25 -0700562
563 scratch.file("a/BUILD");
564 scratch.file(
565 "a/foo.bzl", //
566 "load(\"//a:bar.bzl\", \"x\")");
567 scratch.file(
568 "a/bar.bzl", //
Googlerfaea4a12022-08-24 07:39:57 -0700569 "visibility(\"private\")",
Googler24a49412022-07-01 13:01:25 -0700570 "x = 1");
571
572 checkSuccessfulLookup("//a:foo.bzl");
573 assertNoEvents();
574 }
575
576 @Test
577 public void testBzlVisibility_privateDifferentPackage() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700578 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler24a49412022-07-01 13:01:25 -0700579
580 scratch.file("a/BUILD");
581 scratch.file(
582 "a/foo.bzl", //
583 "load(\"//b:bar.bzl\", \"x\")");
584 scratch.file("b/BUILD");
585 scratch.file(
586 "b/bar.bzl", //
587 "visibility(\"private\")",
588 "x = 1");
589
590 reporter.removeHandler(failFastHandler);
591 checkFailingLookup(
Googler27f0f0f2022-10-21 15:04:57 -0700592 "//a:foo.bzl", "module //a:foo.bzl contains .bzl load visibility violations");
Googler24a49412022-07-01 13:01:25 -0700593 assertContainsEvent("Starlark file //b:bar.bzl is not visible for loading from package //a.");
594 }
595
596 @Test
Googler535a0ce2022-10-06 11:33:12 -0700597 public void testBzlVisibility_emptyListMeansPrivate() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700598 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler535a0ce2022-10-06 11:33:12 -0700599
600 scratch.file("a/BUILD");
601 scratch.file(
602 "a/foo.bzl", //
603 "load(\"//b:bar.bzl\", \"x\")");
604 scratch.file("b/BUILD");
605 scratch.file(
606 "b/bar.bzl", //
607 "visibility([])",
608 "x = 1");
609
610 reporter.removeHandler(failFastHandler);
611 checkFailingLookup(
Googler27f0f0f2022-10-21 15:04:57 -0700612 "//a:foo.bzl", "module //a:foo.bzl contains .bzl load visibility violations");
Googler535a0ce2022-10-06 11:33:12 -0700613 assertContainsEvent("Starlark file //b:bar.bzl is not visible for loading from package //a.");
614 }
615
616 @Test
Googler14739882022-10-06 10:22:52 -0700617 public void testBzlVisibility_publicListElement() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700618 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler14739882022-10-06 10:22:52 -0700619
620 scratch.file("a/BUILD");
621 scratch.file(
622 "a/foo.bzl", //
623 "load(\"//b:bar.bzl\", \"x\")");
624 scratch.file("b/BUILD");
625 scratch.file(
626 "b/bar.bzl", //
627 // Tests "public" as a list item, and alongside other list items.
628 "visibility([\"public\", \"//c\"])",
629 "x = 1");
630
631 checkSuccessfulLookup("//a:foo.bzl");
632 assertNoEvents();
633 }
634
635 @Test
636 public void testBzlVisibility_privateListElement() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700637 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler14739882022-10-06 10:22:52 -0700638
639 scratch.file("a1/BUILD");
640 scratch.file(
641 "a1/foo.bzl", //
642 "load(\"//b:bar.bzl\", \"x\")");
643 scratch.file("a2/BUILD");
644 scratch.file(
645 "a2/foo.bzl", //
646 "load(\"//b:bar.bzl\", \"x\")");
647 scratch.file("b/BUILD");
648 scratch.file(
649 "b/bar.bzl", //
650 // Tests "private" as a list item, and alongside other list items.
651 "visibility([\"private\", \"//a1\"])",
652 "x = 1");
653
654 checkSuccessfulLookup("//a1:foo.bzl");
655 assertNoEvents();
656 reporter.removeHandler(failFastHandler);
657 checkFailingLookup(
Googler27f0f0f2022-10-21 15:04:57 -0700658 "//a2:foo.bzl", "module //a2:foo.bzl contains .bzl load visibility violations");
Googler14739882022-10-06 10:22:52 -0700659 assertContainsEvent("Starlark file //b:bar.bzl is not visible for loading from package //a2.");
660 }
661
662 @Test
Googler24a49412022-07-01 13:01:25 -0700663 public void testBzlVisibility_failureInDependency() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700664 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler24a49412022-07-01 13:01:25 -0700665
666 scratch.file("a/BUILD");
667 scratch.file(
668 "a/foo.bzl", //
669 "load(\"//b:bar.bzl\", \"x\")");
670 scratch.file("b/BUILD");
671 scratch.file(
672 "b/bar.bzl", //
673 "load(\"//c:baz.bzl\", \"y\")",
674 "visibility(\"public\")",
675 "x = y");
676 scratch.file("c/BUILD");
677 scratch.file(
678 "c/baz.bzl", //
679 "visibility(\"private\")",
680 "y = 1");
681
682 reporter.removeHandler(failFastHandler);
683 checkFailingLookup(
684 "//a:foo.bzl",
Googler27f0f0f2022-10-21 15:04:57 -0700685 "at /workspace/a/foo.bzl:1:6: module //b:bar.bzl contains .bzl load visibility violations");
Googler24a49412022-07-01 13:01:25 -0700686 assertContainsEvent("Starlark file //c:baz.bzl is not visible for loading from package //b.");
687 }
688
689 @Test
Googler32d56b62022-10-06 12:06:11 -0700690 public void testBzlVisibility_cannotBeSetInFunction() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700691 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler24a49412022-07-01 13:01:25 -0700692
Googler24a49412022-07-01 13:01:25 -0700693 scratch.file("a/BUILD");
694 scratch.file(
695 "a/foo.bzl", //
Googler24a49412022-07-01 13:01:25 -0700696 "def helper():",
Googler32d56b62022-10-06 12:06:11 -0700697 " visibility(\"public\")",
698 "helper()");
Googler24a49412022-07-01 13:01:25 -0700699
700 reporter.removeHandler(failFastHandler);
Googler32d56b62022-10-06 12:06:11 -0700701 checkFailingLookup("//a:foo.bzl", "initialization of module 'a/foo.bzl' failed");
Googler27f0f0f2022-10-21 15:04:57 -0700702 assertContainsEvent("load visibility may only be set at the top level");
Googler24a49412022-07-01 13:01:25 -0700703 }
704
705 @Test
706 public void testBzlVisibility_cannotBeSetTwice() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700707 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler24a49412022-07-01 13:01:25 -0700708
709 scratch.file("a/BUILD");
710 scratch.file(
711 "a/foo.bzl", //
712 "visibility(\"public\")",
713 "visibility(\"public\")");
714
715 reporter.removeHandler(failFastHandler);
716 checkFailingLookup("//a:foo.bzl", "initialization of module 'a/foo.bzl' failed");
Googler27f0f0f2022-10-21 15:04:57 -0700717 assertContainsEvent("load visibility may not be set more than once");
nharmatad86b5092018-10-16 15:50:21 -0700718 }
dannark4e42c322018-11-08 19:32:04 -0800719
720 @Test
Googler01523382022-07-01 18:08:41 -0700721 public void testBzlVisibility_enumeratedPackages() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700722 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler01523382022-07-01 18:08:41 -0700723
724 scratch.file("a1/BUILD");
725 scratch.file(
726 "a1/foo1.bzl", //
727 "load(\"//b:bar.bzl\", \"x\")");
728 scratch.file("a2/BUILD");
729 scratch.file(
730 "a2/foo2.bzl", //
731 "load(\"//b:bar.bzl\", \"x\")");
732 scratch.file("b/BUILD");
733 scratch.file(
734 "b/bar.bzl", //
735 "visibility([\"//a1\"])",
736 "x = 1");
737
738 checkSuccessfulLookup("//a1:foo1.bzl");
739 assertNoEvents();
740
741 reporter.removeHandler(failFastHandler);
742 checkFailingLookup(
Googler27f0f0f2022-10-21 15:04:57 -0700743 "//a2:foo2.bzl", "module //a2:foo2.bzl contains .bzl load visibility violations");
Googler01523382022-07-01 18:08:41 -0700744 assertContainsEvent("Starlark file //b:bar.bzl is not visible for loading from package //a2.");
745 }
746
747 @Test
Googler535a0ce2022-10-06 11:33:12 -0700748 public void testBzlVisibility_singleEnumeratedPackageAsString() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700749 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler535a0ce2022-10-06 11:33:12 -0700750
751 scratch.file("a1/BUILD");
752 scratch.file(
753 "a1/foo1.bzl", //
754 "load(\"//b:bar.bzl\", \"x\")");
755 scratch.file("a2/BUILD");
756 scratch.file(
757 "a2/foo2.bzl", //
758 "load(\"//b:bar.bzl\", \"x\")");
759 scratch.file("b/BUILD");
760 scratch.file(
761 "b/bar.bzl", //
762 // Note: "//a1", not ["//a1"]
763 "visibility(\"//a1\")",
764 "x = 1");
765
766 checkSuccessfulLookup("//a1:foo1.bzl");
767 assertNoEvents();
768
769 reporter.removeHandler(failFastHandler);
770 checkFailingLookup(
Googler27f0f0f2022-10-21 15:04:57 -0700771 "//a2:foo2.bzl", "module //a2:foo2.bzl contains .bzl load visibility violations");
Googler535a0ce2022-10-06 11:33:12 -0700772 assertContainsEvent("Starlark file //b:bar.bzl is not visible for loading from package //a2.");
773 }
774
775 @Test
Googler01523382022-07-01 18:08:41 -0700776 public void testBzlVisibility_enumeratedPackagesMultipleRepos() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700777 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler01523382022-07-01 18:08:41 -0700778
779 // @repo//pkg:foo1.bzl and @//pkg:foo2.bzl both try to access @repo//lib:bar.bzl. Test that when
780 // bar.bzl declares a visibility allowing "//pkg", it means @repo//pkg and *not* @//pkg.
781 scratch.overwriteFile(
782 "WORKSPACE", //
783 "local_repository(",
784 " name = 'repo',",
785 " path = 'repo'",
786 ")");
787 scratch.file("repo/WORKSPACE");
788 scratch.file("repo/pkg/BUILD");
789 scratch.file(
790 "repo/pkg/foo1.bzl", //
791 "load(\"//lib:bar.bzl\", \"x\")");
792 scratch.file("repo/lib/BUILD");
793 scratch.file(
794 "repo/lib/bar.bzl", //
795 "visibility([\"//pkg\"])",
796 "x = 1");
797 scratch.file("pkg/BUILD");
798 scratch.file(
799 "pkg/foo2.bzl", //
800 "load(\"@repo//lib:bar.bzl\", \"x\")");
801
802 checkSuccessfulLookup("@repo//pkg:foo1.bzl");
803 assertNoEvents();
804
805 reporter.removeHandler(failFastHandler);
806 checkFailingLookup(
Googler27f0f0f2022-10-21 15:04:57 -0700807 "//pkg:foo2.bzl", "module //pkg:foo2.bzl contains .bzl load visibility violations");
Googler01523382022-07-01 18:08:41 -0700808 assertContainsEvent(
809 "Starlark file @repo//lib:bar.bzl is not visible for loading from package //pkg.");
810 }
811
Googler14739882022-10-06 10:22:52 -0700812 // TODO(#16365): This test case can be deleted once --incompatible_package_group_has_public_syntax
813 // is deleted (not just flipped).
814 @Test
815 public void testBzlVisibility_canUsePublicPrivate_regardlessOfFlag() throws Exception {
816 setBuildLanguageOptions(
817 "--experimental_bzl_visibility=true",
Googler14739882022-10-06 10:22:52 -0700818 // Test that we can use "public" and "private" visibility for .bzl files even when the
819 // incompatible flag is disabled.
820 "--incompatible_package_group_has_public_syntax=false");
821
822 scratch.file("a/BUILD");
823 scratch.file(
824 "a/foo1.bzl", //
825 "visibility(\"public\")");
826 scratch.file(
827 "a/foo2.bzl", //
828 "visibility(\"private\")");
829
830 checkSuccessfulLookup("//a:foo1.bzl");
831 checkSuccessfulLookup("//a:foo2.bzl");
832 assertNoEvents();
833 }
834
835 // TODO(#16324): Once --incompatible_fix_package_group_reporoot_syntax is deleted (not just
836 // flipped), this test case will be redundant with tests for //... in PackageGroupTest. At that
837 // point we'll just delete this test case.
838 @Test
839 public void testBzlVisibility_repoRootSubpackagesIsNotPublic_regardlessOfFlag() throws Exception {
840 setBuildLanguageOptions(
841 "--experimental_bzl_visibility=true",
Googler14739882022-10-06 10:22:52 -0700842 // Test that we get the fixed behavior even when the incompatible flag is disabled.
843 "--incompatible_fix_package_group_reporoot_syntax=false");
844
845 scratch.overwriteFile(
846 "WORKSPACE", //
847 "local_repository(",
848 " name = 'repo',",
849 " path = 'repo'",
850 ")");
851 scratch.file("repo/WORKSPACE");
852 scratch.file("repo/a/BUILD");
853 scratch.file(
854 "repo/a/foo.bzl", //
855 "load(\"@//b:bar.bzl\", \"x\")");
856 scratch.file("b/BUILD");
857 scratch.file(
858 "b/bar.bzl", //
859 "visibility([\"//...\"])",
860 "x = 1");
861
862 reporter.removeHandler(failFastHandler);
863 checkFailingLookup(
Googler27f0f0f2022-10-21 15:04:57 -0700864 "@repo//a:foo.bzl", "module @repo//a:foo.bzl contains .bzl load visibility violations");
Googler14739882022-10-06 10:22:52 -0700865 assertContainsEvent(
866 "Starlark file //b:bar.bzl is not visible for loading from package @repo//a.");
867 }
868
Googler01523382022-07-01 18:08:41 -0700869 @Test
Googlerfaea4a12022-08-24 07:39:57 -0700870 public void testBzlVisibility_disallowsSubpackagesWithoutWildcard() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700871 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googlerfaea4a12022-08-24 07:39:57 -0700872
873 scratch.file("a/BUILD");
874 scratch.file(
875 "a/foo1.bzl", //
876 "load(\"//b:bar.bzl\", \"x\")");
877 scratch.file("a/subpkg/BUILD");
878 scratch.file(
879 "a/subpkg/foo2.bzl", //
880 "load(\"//b:bar.bzl\", \"x\")");
881 scratch.file("b/BUILD");
882 scratch.file(
883 "b/bar.bzl", //
884 "visibility([\"//a\"])",
885 "x = 1");
886
887 checkSuccessfulLookup("//a:foo1.bzl");
888 assertNoEvents();
889
890 reporter.removeHandler(failFastHandler);
891 checkFailingLookup(
892 "//a/subpkg:foo2.bzl",
Googler27f0f0f2022-10-21 15:04:57 -0700893 "module //a/subpkg:foo2.bzl contains .bzl load visibility violations");
Googlerfaea4a12022-08-24 07:39:57 -0700894 assertContainsEvent(
895 "Starlark file //b:bar.bzl is not visible for loading from package //a/subpkg.");
896 }
897
898 @Test
899 public void testBzlVisibility_allowsSubpackagesWithWildcard() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700900 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googlerfaea4a12022-08-24 07:39:57 -0700901
902 scratch.file("a/BUILD");
903 scratch.file(
904 "a/foo1.bzl", //
905 "load(\"//b:bar.bzl\", \"x\")");
906 scratch.file("a/subpkg/BUILD");
907 scratch.file(
908 "a/subpkg/foo2.bzl", //
909 "load(\"//b:bar.bzl\", \"x\")");
910 scratch.file("b/BUILD");
911 scratch.file(
912 "b/bar.bzl", //
913 "visibility([\"//a/...\"])",
914 "x = 1");
915
916 checkSuccessfulLookup("//a:foo1.bzl");
917 assertNoEvents();
918
919 checkSuccessfulLookup("//a/subpkg:foo2.bzl");
920 assertNoEvents();
921 }
922
923 @Test
Googler01523382022-07-01 18:08:41 -0700924 public void testBzlVisibility_invalid_badType() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700925 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler01523382022-07-01 18:08:41 -0700926
927 scratch.file("a/BUILD");
928 scratch.file(
929 "a/foo.bzl", //
930 "visibility(123)");
931
932 reporter.removeHandler(failFastHandler);
933 checkFailingLookup("//a:foo.bzl", "initialization of module 'a/foo.bzl' failed");
Googler27f0f0f2022-10-21 15:04:57 -0700934 assertContainsEvent("Invalid visibility: got 'int', want string or list of strings");
Googler01523382022-07-01 18:08:41 -0700935 }
936
937 @Test
938 public void testBzlVisibility_invalid_badElementType() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700939 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler01523382022-07-01 18:08:41 -0700940
941 scratch.file("a/BUILD");
942 scratch.file(
943 "a/foo.bzl", //
944 "visibility([\"//a\", 123])");
945
946 reporter.removeHandler(failFastHandler);
947 checkFailingLookup("//a:foo.bzl", "initialization of module 'a/foo.bzl' failed");
Fabian Meumertzheimd624ea82022-10-11 04:53:01 -0700948 assertContainsEvent("at index 1 of visibility list, got element of type int, want string");
Googler01523382022-07-01 18:08:41 -0700949 }
950
951 @Test
952 public void testBzlVisibility_invalid_packageOutsideRepo() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700953 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler01523382022-07-01 18:08:41 -0700954
955 scratch.file("a/BUILD");
956 scratch.file(
957 "a/foo.bzl", //
958 "visibility([\"@repo//b\"])");
959
960 reporter.removeHandler(failFastHandler);
961 checkFailingLookup("//a:foo.bzl", "initialization of module 'a/foo.bzl' failed");
Googlerfaea4a12022-08-24 07:39:57 -0700962 assertContainsEvent("invalid package name '@repo//b': must start with '//'");
Googler01523382022-07-01 18:08:41 -0700963 }
964
965 @Test
Googler535a0ce2022-10-06 11:33:12 -0700966 public void testBzlVisibility_invalid_negationNotSupported() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700967 setBuildLanguageOptions("--experimental_bzl_visibility=true");
Googler535a0ce2022-10-06 11:33:12 -0700968
969 scratch.file("a/BUILD");
970 scratch.file(
971 "a/foo.bzl", //
972 "visibility([\"-//a\"])");
973
974 reporter.removeHandler(failFastHandler);
975 checkFailingLookup("//a:foo.bzl", "initialization of module 'a/foo.bzl' failed");
976 assertContainsEvent("Cannot use negative package patterns here");
977 }
978
979 @Test
Googler84761042022-10-06 12:43:04 -0700980 public void testBzlVisibility_errorsDemotedToWarningWhenBreakGlassFlagIsSet() throws Exception {
Googlere42e5c62022-10-18 17:48:39 -0700981 setBuildLanguageOptions("--experimental_bzl_visibility=true", "--check_bzl_visibility=false");
Googler84761042022-10-06 12:43:04 -0700982
983 scratch.file("a/BUILD");
984 scratch.file(
985 "a/foo.bzl", //
986 "load(\"//b:bar.bzl\", \"x\")");
987 scratch.file("b/BUILD");
988 scratch.file(
989 "b/bar.bzl", //
990 "visibility(\"private\")",
991 "x = 1");
992
993 checkSuccessfulLookup("//a:foo.bzl");
994 assertContainsEvent("Starlark file //b:bar.bzl is not visible for loading from package //a.");
995 assertContainsEvent("Continuing because --nocheck_bzl_visibility is active");
996 }
997
998 @Test
brandjon24912642020-05-27 11:28:45 -0700999 public void testLoadFromNonExistentRepository_producesMeaningfulError() throws Exception {
Googler06eb1bb2019-02-26 15:33:15 -08001000 scratch.file("BUILD", "load(\"@repository//dir:file.bzl\", \"foo\")");
1001
brandjon771a0292020-05-26 12:04:16 -07001002 SkyKey skyKey = key("@repository//dir:file.bzl");
1003 EvaluationResult<BzlLoadValue> result =
Googler06eb1bb2019-02-26 15:33:15 -08001004 SkyframeExecutorTestUtils.evaluate(
brandjon771a0292020-05-26 12:04:16 -07001005 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
Googler06eb1bb2019-02-26 15:33:15 -08001006 assertThat(result.hasError()).isTrue();
1007 assertThatEvaluationResult(result)
brandjon771a0292020-05-26 12:04:16 -07001008 .hasErrorEntryForKeyThat(skyKey)
Googler06eb1bb2019-02-26 15:33:15 -08001009 .hasExceptionThat()
brandjon771a0292020-05-26 12:04:16 -07001010 .isInstanceOf(BzlLoadFailedException.class);
Googler06eb1bb2019-02-26 15:33:15 -08001011 assertThatEvaluationResult(result)
brandjon771a0292020-05-26 12:04:16 -07001012 .hasErrorEntryForKeyThat(skyKey)
Googler06eb1bb2019-02-26 15:33:15 -08001013 .hasExceptionThat()
1014 .hasMessageThat()
1015 .contains(
1016 "Unable to find package for @repository//dir:file.bzl: The repository '@repository' "
pcloudy87dbf7d2021-09-02 09:22:20 -07001017 + "could not be resolved: Repository '@repository' is not defined.");
Googler06eb1bb2019-02-26 15:33:15 -08001018 }
1019
1020 @Test
dannark4e42c322018-11-08 19:32:04 -08001021 public void testLoadBzlFileFromWorkspaceWithRemapping() throws Exception {
dannark4e42c322018-11-08 19:32:04 -08001022 Path p =
1023 scratch.overwriteFile(
1024 "WORKSPACE",
1025 "local_repository(",
1026 " name = 'y',",
1027 " path = '/y'",
1028 ")",
1029 "local_repository(",
1030 " name = 'a',",
1031 " path = '/a',",
1032 " repo_mapping = {'@x' : '@y'}",
1033 ")",
1034 "load('@a//:a.bzl', 'a_symbol')");
1035
1036 scratch.file("/y/WORKSPACE");
1037 scratch.file("/y/BUILD");
1038 scratch.file("/y/y.bzl", "y_symbol = 5");
1039
1040 scratch.file("/a/WORKSPACE");
1041 scratch.file("/a/BUILD");
1042 scratch.file("/a/a.bzl", "load('@x//:y.bzl', 'y_symbol')", "a_symbol = y_symbol");
1043
1044 Root root = Root.fromPath(p.getParentDirectory());
1045 RootedPath rootedPath = RootedPath.toRootedPath(root, PathFragment.create("WORKSPACE"));
1046
brandjon771a0292020-05-26 12:04:16 -07001047 SkyKey skyKey =
Googler08463dc2023-01-20 08:02:19 -08001048 BzlLoadValue.keyForWorkspace(Label.parseCanonicalUnchecked("@a//:a.bzl"), 1, rootedPath);
dannark4e42c322018-11-08 19:32:04 -08001049
brandjon771a0292020-05-26 12:04:16 -07001050 EvaluationResult<BzlLoadValue> result =
dannark4e42c322018-11-08 19:32:04 -08001051 SkyframeExecutorTestUtils.evaluate(
brandjon771a0292020-05-26 12:04:16 -07001052 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
dannark4e42c322018-11-08 19:32:04 -08001053
adonovan3ed7ed52020-09-30 12:03:28 -07001054 assertThat(result.get(skyKey).getModule().getGlobals())
1055 .containsEntry("a_symbol", StarlarkInt.of(5));
dannark4e42c322018-11-08 19:32:04 -08001056 }
nharmatadc1d9dc2020-04-18 16:53:28 -07001057
1058 @Test
wyva8176452021-09-02 05:38:18 -07001059 public void testLoadBzlFileFromBzlmod() throws Exception {
Googlerd51144c2023-10-13 03:20:20 -07001060 setBuildLanguageOptions("--experimental_enable_scl_dialect");
wyva8176452021-09-02 05:38:18 -07001061 scratch.overwriteFile("MODULE.bazel", "bazel_dep(name='foo',version='1.0')");
1062 registry
1063 .addModule(
1064 createModuleKey("foo", "1.0"),
1065 "module(name='foo',version='1.0')",
1066 "bazel_dep(name='bar',version='2.0',repo_name='bar_alias')")
1067 .addModule(createModuleKey("bar", "2.0"), "module(name='bar',version='2.0')");
Googler7f9de9e2022-08-25 03:25:02 -07001068 Path fooDir = moduleRoot.getRelative("foo~1.0");
wyva8176452021-09-02 05:38:18 -07001069 scratch.file(fooDir.getRelative("WORKSPACE").getPathString());
1070 scratch.file(fooDir.getRelative("BUILD").getPathString());
1071 scratch.file(
1072 fooDir.getRelative("test.bzl").getPathString(),
Googlera0cd3552023-05-01 13:43:28 -07001073 // Also test that bzlmod .bzl files can load .scl files.
1074 "load('@bar_alias//:test.scl', 'haha')",
wyva8176452021-09-02 05:38:18 -07001075 "hoho = haha");
Googler7f9de9e2022-08-25 03:25:02 -07001076 Path barDir = moduleRoot.getRelative("bar~2.0");
wyva8176452021-09-02 05:38:18 -07001077 scratch.file(barDir.getRelative("WORKSPACE").getPathString());
1078 scratch.file(barDir.getRelative("BUILD").getPathString());
Googlera0cd3552023-05-01 13:43:28 -07001079 scratch.file(barDir.getRelative("test.scl").getPathString(), "haha = 5");
wyva8176452021-09-02 05:38:18 -07001080
Googler34a4f132022-07-12 08:42:20 -07001081 SkyKey skyKey = BzlLoadValue.keyForBzlmod(Label.parseCanonical("@@foo~1.0//:test.bzl"));
wyva8176452021-09-02 05:38:18 -07001082 EvaluationResult<BzlLoadValue> result =
1083 SkyframeExecutorTestUtils.evaluate(
1084 getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
1085
1086 assertThatEvaluationResult(result).hasNoError();
1087 assertThat(result.get(skyKey).getModule().getGlobals())
1088 .containsEntry("hoho", StarlarkInt.of(5));
1089 // Note that we're not testing the case of a non-registry override using @bazel_tools here, but
1090 // that is incredibly hard to set up in a unit test. So we should just rely on integration tests
1091 // for that.
1092 }
1093
1094 @Test
brandjon6c63b8f2021-02-01 10:17:42 -08001095 public void testBuiltinsInjectionFailure() throws Exception {
1096 setBuildLanguageOptions("--experimental_builtins_bzl_path=tools/builtins_staging");
1097 scratch.file(
1098 "tools/builtins_staging/exports.bzl",
1099 "1 // 0 # <-- dynamic error",
1100 "exported_toplevels = {}",
1101 "exported_rules = {}",
1102 "exported_to_java = {}");
1103 scratch.file("pkg/BUILD");
1104 scratch.file("pkg/foo.bzl");
1105 reporter.removeHandler(failFastHandler);
1106
1107 SkyKey key = key("//pkg:foo.bzl");
1108 EvaluationResult<BzlLoadValue> result =
1109 SkyframeExecutorTestUtils.evaluate(
1110 getSkyframeExecutor(), key, /*keepGoing=*/ false, reporter);
1111
1112 assertContainsEvent(
1113 "File \"/workspace/tools/builtins_staging/exports.bzl\", line 1, column 3, in <toplevel>");
1114 assertContainsEvent("Error: integer division by zero");
1115 Exception ex = result.getError(key).getException();
1116 assertThat(ex)
1117 .hasMessageThat()
1118 .contains(
1119 "Internal error while loading Starlark builtins for //pkg:foo.bzl: Failed to load"
1120 + " builtins sources: initialization of module 'exports.bzl' (internal) failed");
1121 }
1122
1123 @Test
brandjon9db98c42020-08-24 08:43:55 -07001124 public void testErrorReadingBzlFileIsTransientWhenUsingASTInlining() throws Exception {
nharmatadc1d9dc2020-04-18 16:53:28 -07001125 CustomInMemoryFs fs = (CustomInMemoryFs) fileSystem;
1126 scratch.file("a/BUILD");
1127 fs.badPathForRead = scratch.file("a/a1.bzl", "doesntmatter");
1128
1129 SkyKey key = key("//a:a1.bzl");
brandjon771a0292020-05-26 12:04:16 -07001130 EvaluationResult<BzlLoadValue> result =
nharmatadc1d9dc2020-04-18 16:53:28 -07001131 SkyframeExecutorTestUtils.evaluate(
1132 getSkyframeExecutor(), key, /*keepGoing=*/ false, reporter);
1133 assertThatEvaluationResult(result).hasErrorEntryForKeyThat(key).isTransient();
1134 }
1135
1136 @Test
1137 public void testErrorReadingOtherBzlFileIsPersistentFromPerspectiveOfParent() throws Exception {
1138 CustomInMemoryFs fs = (CustomInMemoryFs) fileSystem;
1139 scratch.file("a/BUILD");
1140 scratch.file("a/a1.bzl", "load('//a:a2.bzl', 'a2')");
1141 fs.badPathForRead = scratch.file("a/a2.bzl", "doesntmatter");
1142
1143 SkyKey key = key("//a:a1.bzl");
brandjon771a0292020-05-26 12:04:16 -07001144 EvaluationResult<BzlLoadValue> result =
nharmatadc1d9dc2020-04-18 16:53:28 -07001145 SkyframeExecutorTestUtils.evaluate(
1146 getSkyframeExecutor(), key, /*keepGoing=*/ false, reporter);
1147 assertThatEvaluationResult(result).hasErrorEntryForKeyThat(key).isNotTransient();
1148 }
1149
1150 @Test
1151 public void testErrorStatingBzlFileInFileStateFunctionIsPersistent() throws Exception {
1152 CustomInMemoryFs fs = (CustomInMemoryFs) fileSystem;
1153 scratch.file("a/BUILD");
1154 fs.badPathForStat = scratch.file("a/a1.bzl", "doesntmatter");
1155
1156 SkyKey key = key("//a:a1.bzl");
brandjon771a0292020-05-26 12:04:16 -07001157 EvaluationResult<BzlLoadValue> result =
nharmatadc1d9dc2020-04-18 16:53:28 -07001158 SkyframeExecutorTestUtils.evaluate(
1159 getSkyframeExecutor(), key, /*keepGoing=*/ false, reporter);
1160 assertThatEvaluationResult(result).hasErrorEntryForKeyThat(key).isNotTransient();
1161 }
1162
1163 private static class CustomInMemoryFs extends InMemoryFileSystem {
1164 @Nullable private Path badPathForStat;
1165 @Nullable private Path badPathForRead;
1166
janakr97c0bd12020-09-08 13:19:03 -07001167 CustomInMemoryFs() {
1168 super(DigestHashFunction.SHA256);
1169 }
1170
nharmatadc1d9dc2020-04-18 16:53:28 -07001171 @Override
ajurkowski8883c612021-03-08 08:12:37 -08001172 public FileStatus statIfFound(PathFragment path, boolean followSymlinks) throws IOException {
1173 if (badPathForStat != null && badPathForStat.asFragment().equals(path)) {
nharmatadc1d9dc2020-04-18 16:53:28 -07001174 throw new IOException("bad");
1175 }
1176 return super.statIfFound(path, followSymlinks);
1177 }
1178
1179 @Override
Googlerf0693472022-07-21 15:10:20 -07001180 protected synchronized InputStream getInputStream(PathFragment path) throws IOException {
ajurkowski8883c612021-03-08 08:12:37 -08001181 if (badPathForRead != null && badPathForRead.asFragment().equals(path)) {
nharmatadc1d9dc2020-04-18 16:53:28 -07001182 throw new IOException("bad");
1183 }
1184 return super.getInputStream(path);
1185 }
1186 }
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +00001187}