blob: 30cdcbf8f9f755e21bf224aea97c32468f477bb6 [file] [log] [blame]
Paul Duffin2e61fa62019-03-28 14:10:57 +00001package android
2
3import (
Paul Duffin44885e22020-02-19 16:10:09 +00004 "reflect"
Paul Duffin2e61fa62019-03-28 14:10:57 +00005 "testing"
Martin Stjernholm8edeb632019-05-21 12:18:38 +01006
7 "github.com/google/blueprint"
Paul Duffin2e61fa62019-03-28 14:10:57 +00008)
9
10var visibilityTests = []struct {
Paul Duffin44885e22020-02-19 16:10:09 +000011 name string
Paul Duffincfd33742021-02-27 11:59:02 +000012 fs MockFS
Paul Duffin44885e22020-02-19 16:10:09 +000013 expectedErrors []string
14 effectiveVisibility map[qualifiedModuleName][]string
Paul Duffin2e61fa62019-03-28 14:10:57 +000015}{
16 {
17 name: "invalid visibility: empty list",
Paul Duffincfd33742021-02-27 11:59:02 +000018 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +000019 "top/Blueprints": []byte(`
20 mock_library {
21 name: "libexample",
22 visibility: [],
23 }`),
24 },
25 expectedErrors: []string{`visibility: must contain at least one visibility rule`},
26 },
27 {
28 name: "invalid visibility: empty rule",
Paul Duffincfd33742021-02-27 11:59:02 +000029 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +000030 "top/Blueprints": []byte(`
31 mock_library {
32 name: "libexample",
33 visibility: [""],
34 }`),
35 },
36 expectedErrors: []string{`visibility: invalid visibility pattern ""`},
37 },
38 {
39 name: "invalid visibility: unqualified",
Paul Duffincfd33742021-02-27 11:59:02 +000040 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +000041 "top/Blueprints": []byte(`
42 mock_library {
43 name: "libexample",
44 visibility: ["target"],
45 }`),
46 },
47 expectedErrors: []string{`visibility: invalid visibility pattern "target"`},
48 },
49 {
50 name: "invalid visibility: empty namespace",
Paul Duffincfd33742021-02-27 11:59:02 +000051 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +000052 "top/Blueprints": []byte(`
53 mock_library {
54 name: "libexample",
55 visibility: ["//"],
56 }`),
57 },
58 expectedErrors: []string{`visibility: invalid visibility pattern "//"`},
59 },
60 {
61 name: "invalid visibility: empty module",
Paul Duffincfd33742021-02-27 11:59:02 +000062 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +000063 "top/Blueprints": []byte(`
64 mock_library {
65 name: "libexample",
66 visibility: [":"],
67 }`),
68 },
69 expectedErrors: []string{`visibility: invalid visibility pattern ":"`},
70 },
71 {
72 name: "invalid visibility: empty namespace and module",
Paul Duffincfd33742021-02-27 11:59:02 +000073 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +000074 "top/Blueprints": []byte(`
75 mock_library {
76 name: "libexample",
77 visibility: ["//:"],
78 }`),
79 },
80 expectedErrors: []string{`visibility: invalid visibility pattern "//:"`},
81 },
82 {
83 name: "//visibility:unknown",
Paul Duffincfd33742021-02-27 11:59:02 +000084 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +000085 "top/Blueprints": []byte(`
86 mock_library {
87 name: "libexample",
88 visibility: ["//visibility:unknown"],
89 }`),
90 },
91 expectedErrors: []string{`unrecognized visibility rule "//visibility:unknown"`},
92 },
93 {
Martin Stjernholm226b20d2019-05-17 22:42:02 +010094 name: "//visibility:xxx mixed",
Paul Duffincfd33742021-02-27 11:59:02 +000095 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +000096 "top/Blueprints": []byte(`
97 mock_library {
98 name: "libexample",
99 visibility: ["//visibility:public", "//namespace"],
100 }
101
102 mock_library {
103 name: "libother",
104 visibility: ["//visibility:private", "//namespace"],
105 }`),
106 },
107 expectedErrors: []string{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100108 `module "libother": visibility: cannot mix "//visibility:private"` +
Paul Duffin2e61fa62019-03-28 14:10:57 +0000109 ` with any other visibility rules`,
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100110 `module "libexample": visibility: cannot mix "//visibility:public"` +
111 ` with any other visibility rules`,
Paul Duffin2e61fa62019-03-28 14:10:57 +0000112 },
113 },
114 {
115 name: "//visibility:legacy_public",
Paul Duffincfd33742021-02-27 11:59:02 +0000116 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000117 "top/Blueprints": []byte(`
118 mock_library {
119 name: "libexample",
120 visibility: ["//visibility:legacy_public"],
121 }`),
122 },
123 expectedErrors: []string{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100124 `module "libexample": visibility: //visibility:legacy_public must` +
Paul Duffin2e61fa62019-03-28 14:10:57 +0000125 ` not be used`,
126 },
127 },
128 {
129 // Verify that //visibility:public will allow the module to be referenced from anywhere, e.g.
130 // the current directory, a nested directory and a directory in a separate tree.
131 name: "//visibility:public",
Paul Duffincfd33742021-02-27 11:59:02 +0000132 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000133 "top/Blueprints": []byte(`
134 mock_library {
135 name: "libexample",
136 visibility: ["//visibility:public"],
137 }
138
139 mock_library {
140 name: "libsamepackage",
141 deps: ["libexample"],
142 }`),
143 "top/nested/Blueprints": []byte(`
144 mock_library {
145 name: "libnested",
146 deps: ["libexample"],
147 }`),
148 "other/Blueprints": []byte(`
149 mock_library {
150 name: "libother",
151 deps: ["libexample"],
152 }`),
153 },
154 },
155 {
Paul Duffin2e61fa62019-03-28 14:10:57 +0000156 // Verify that //visibility:private allows the module to be referenced from the current
157 // directory only.
158 name: "//visibility:private",
Paul Duffincfd33742021-02-27 11:59:02 +0000159 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000160 "top/Blueprints": []byte(`
161 mock_library {
162 name: "libexample",
163 visibility: ["//visibility:private"],
164 }
165
166 mock_library {
167 name: "libsamepackage",
168 deps: ["libexample"],
169 }`),
170 "top/nested/Blueprints": []byte(`
171 mock_library {
172 name: "libnested",
173 deps: ["libexample"],
174 }`),
Martin Stjernholm8edeb632019-05-21 12:18:38 +0100175 "other/Blueprints": []byte(`
176 mock_library {
177 name: "libother",
178 deps: ["libexample"],
179 }`),
Paul Duffin2e61fa62019-03-28 14:10:57 +0000180 },
181 expectedErrors: []string{
182 `module "libnested" variant "android_common": depends on //top:libexample which is not` +
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100183 ` visible to this module`,
Martin Stjernholm8edeb632019-05-21 12:18:38 +0100184 `module "libother" variant "android_common": depends on //top:libexample which is not` +
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100185 ` visible to this module`,
Paul Duffin2e61fa62019-03-28 14:10:57 +0000186 },
187 },
188 {
189 // Verify that :__pkg__ allows the module to be referenced from the current directory only.
190 name: ":__pkg__",
Paul Duffincfd33742021-02-27 11:59:02 +0000191 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000192 "top/Blueprints": []byte(`
193 mock_library {
194 name: "libexample",
195 visibility: [":__pkg__"],
196 }
197
198 mock_library {
199 name: "libsamepackage",
200 deps: ["libexample"],
201 }`),
202 "top/nested/Blueprints": []byte(`
203 mock_library {
204 name: "libnested",
205 deps: ["libexample"],
206 }`),
Martin Stjernholm8edeb632019-05-21 12:18:38 +0100207 "other/Blueprints": []byte(`
208 mock_library {
209 name: "libother",
210 deps: ["libexample"],
211 }`),
Paul Duffin2e61fa62019-03-28 14:10:57 +0000212 },
213 expectedErrors: []string{
214 `module "libnested" variant "android_common": depends on //top:libexample which is not` +
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100215 ` visible to this module`,
Martin Stjernholm8edeb632019-05-21 12:18:38 +0100216 `module "libother" variant "android_common": depends on //top:libexample which is not` +
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100217 ` visible to this module`,
Paul Duffin2e61fa62019-03-28 14:10:57 +0000218 },
219 },
220 {
221 // Verify that //top/nested allows the module to be referenced from the current directory and
222 // the top/nested directory only, not a subdirectory of top/nested and not peak directory.
223 name: "//top/nested",
Paul Duffincfd33742021-02-27 11:59:02 +0000224 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000225 "top/Blueprints": []byte(`
226 mock_library {
227 name: "libexample",
228 visibility: ["//top/nested"],
229 }
230
231 mock_library {
232 name: "libsamepackage",
233 deps: ["libexample"],
234 }`),
235 "top/nested/Blueprints": []byte(`
236 mock_library {
237 name: "libnested",
238 deps: ["libexample"],
239 }`),
240 "top/nested/again/Blueprints": []byte(`
241 mock_library {
242 name: "libnestedagain",
243 deps: ["libexample"],
244 }`),
245 "peak/Blueprints": []byte(`
246 mock_library {
247 name: "libother",
248 deps: ["libexample"],
249 }`),
250 },
251 expectedErrors: []string{
252 `module "libother" variant "android_common": depends on //top:libexample which is not` +
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100253 ` visible to this module`,
Paul Duffin2e61fa62019-03-28 14:10:57 +0000254 `module "libnestedagain" variant "android_common": depends on //top:libexample which is not` +
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100255 ` visible to this module`,
Paul Duffin2e61fa62019-03-28 14:10:57 +0000256 },
257 },
258 {
259 // Verify that :__subpackages__ allows the module to be referenced from the current directory
260 // and sub directories but nowhere else.
261 name: ":__subpackages__",
Paul Duffincfd33742021-02-27 11:59:02 +0000262 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000263 "top/Blueprints": []byte(`
264 mock_library {
265 name: "libexample",
266 visibility: [":__subpackages__"],
267 }
268
269 mock_library {
270 name: "libsamepackage",
271 deps: ["libexample"],
272 }`),
273 "top/nested/Blueprints": []byte(`
274 mock_library {
275 name: "libnested",
276 deps: ["libexample"],
277 }`),
278 "peak/other/Blueprints": []byte(`
279 mock_library {
280 name: "libother",
281 deps: ["libexample"],
282 }`),
283 },
284 expectedErrors: []string{
285 `module "libother" variant "android_common": depends on //top:libexample which is not` +
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100286 ` visible to this module`,
Paul Duffin2e61fa62019-03-28 14:10:57 +0000287 },
288 },
289 {
290 // Verify that //top/nested:__subpackages__ allows the module to be referenced from the current
291 // directory and sub directories but nowhere else.
292 name: "//top/nested:__subpackages__",
Paul Duffincfd33742021-02-27 11:59:02 +0000293 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000294 "top/Blueprints": []byte(`
295 mock_library {
296 name: "libexample",
297 visibility: ["//top/nested:__subpackages__", "//other"],
298 }
299
300 mock_library {
301 name: "libsamepackage",
302 deps: ["libexample"],
303 }`),
304 "top/nested/Blueprints": []byte(`
305 mock_library {
306 name: "libnested",
307 deps: ["libexample"],
308 }`),
309 "top/other/Blueprints": []byte(`
310 mock_library {
311 name: "libother",
312 deps: ["libexample"],
313 }`),
314 },
315 expectedErrors: []string{
316 `module "libother" variant "android_common": depends on //top:libexample which is not` +
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100317 ` visible to this module`,
Paul Duffin2e61fa62019-03-28 14:10:57 +0000318 },
319 },
320 {
321 // Verify that ["//top/nested", "//peak:__subpackages"] allows the module to be referenced from
322 // the current directory, top/nested and peak and all its subpackages.
323 name: `["//top/nested", "//peak:__subpackages__"]`,
Paul Duffincfd33742021-02-27 11:59:02 +0000324 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000325 "top/Blueprints": []byte(`
326 mock_library {
327 name: "libexample",
328 visibility: ["//top/nested", "//peak:__subpackages__"],
329 }
330
331 mock_library {
332 name: "libsamepackage",
333 deps: ["libexample"],
334 }`),
335 "top/nested/Blueprints": []byte(`
336 mock_library {
337 name: "libnested",
338 deps: ["libexample"],
339 }`),
340 "peak/other/Blueprints": []byte(`
341 mock_library {
342 name: "libother",
343 deps: ["libexample"],
344 }`),
345 },
346 },
347 {
348 // Verify that //vendor... cannot be used outside vendor apart from //vendor:__subpackages__
349 name: `//vendor`,
Paul Duffincfd33742021-02-27 11:59:02 +0000350 fs: MockFS{
Paul Duffin2e61fa62019-03-28 14:10:57 +0000351 "top/Blueprints": []byte(`
352 mock_library {
353 name: "libexample",
354 visibility: ["//vendor:__subpackages__"],
355 }
356
357 mock_library {
358 name: "libsamepackage",
359 visibility: ["//vendor/apps/AcmeSettings"],
360 }`),
361 "vendor/Blueprints": []byte(`
362 mock_library {
363 name: "libvendorexample",
364 deps: ["libexample"],
365 visibility: ["//vendor/nested"],
366 }`),
367 "vendor/nested/Blueprints": []byte(`
368 mock_library {
369 name: "libvendornested",
370 deps: ["libexample", "libvendorexample"],
371 }`),
372 },
373 expectedErrors: []string{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100374 `module "libsamepackage": visibility: "//vendor/apps/AcmeSettings"` +
Paul Duffin2e61fa62019-03-28 14:10:57 +0000375 ` is not allowed. Packages outside //vendor cannot make themselves visible to specific` +
376 ` targets within //vendor, they can only use //vendor:__subpackages__.`,
377 },
378 },
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100379
380 // Defaults propagation tests
381 {
382 // Check that visibility is the union of the defaults modules.
383 name: "defaults union, basic",
Paul Duffincfd33742021-02-27 11:59:02 +0000384 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100385 "top/Blueprints": []byte(`
386 mock_defaults {
387 name: "libexample_defaults",
388 visibility: ["//other"],
389 }
390 mock_library {
391 name: "libexample",
392 visibility: ["//top/nested"],
393 defaults: ["libexample_defaults"],
394 }
395 mock_library {
396 name: "libsamepackage",
397 deps: ["libexample"],
398 }`),
399 "top/nested/Blueprints": []byte(`
400 mock_library {
401 name: "libnested",
402 deps: ["libexample"],
403 }`),
404 "other/Blueprints": []byte(`
405 mock_library {
406 name: "libother",
407 deps: ["libexample"],
408 }`),
409 "outsider/Blueprints": []byte(`
410 mock_library {
411 name: "liboutsider",
412 deps: ["libexample"],
413 }`),
414 },
415 expectedErrors: []string{
416 `module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
417 ` visible to this module`,
418 },
419 },
420 {
421 name: "defaults union, multiple defaults",
Paul Duffincfd33742021-02-27 11:59:02 +0000422 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100423 "top/Blueprints": []byte(`
424 mock_defaults {
425 name: "libexample_defaults_1",
426 visibility: ["//other"],
427 }
428 mock_defaults {
429 name: "libexample_defaults_2",
430 visibility: ["//top/nested"],
431 }
432 mock_library {
433 name: "libexample",
434 defaults: ["libexample_defaults_1", "libexample_defaults_2"],
435 }
436 mock_library {
437 name: "libsamepackage",
438 deps: ["libexample"],
439 }`),
440 "top/nested/Blueprints": []byte(`
441 mock_library {
442 name: "libnested",
443 deps: ["libexample"],
444 }`),
445 "other/Blueprints": []byte(`
446 mock_library {
447 name: "libother",
448 deps: ["libexample"],
449 }`),
450 "outsider/Blueprints": []byte(`
451 mock_library {
452 name: "liboutsider",
453 deps: ["libexample"],
454 }`),
455 },
456 expectedErrors: []string{
457 `module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
458 ` visible to this module`,
459 },
460 },
461 {
462 name: "//visibility:public mixed with other in defaults",
Paul Duffincfd33742021-02-27 11:59:02 +0000463 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100464 "top/Blueprints": []byte(`
465 mock_defaults {
466 name: "libexample_defaults",
467 visibility: ["//visibility:public", "//namespace"],
468 }
469 mock_library {
470 name: "libexample",
471 defaults: ["libexample_defaults"],
472 }`),
473 },
474 expectedErrors: []string{
475 `module "libexample_defaults": visibility: cannot mix "//visibility:public"` +
476 ` with any other visibility rules`,
477 },
478 },
479 {
480 name: "//visibility:public overriding defaults",
Paul Duffincfd33742021-02-27 11:59:02 +0000481 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100482 "top/Blueprints": []byte(`
483 mock_defaults {
484 name: "libexample_defaults",
485 visibility: ["//namespace"],
486 }
487 mock_library {
488 name: "libexample",
489 visibility: ["//visibility:public"],
490 defaults: ["libexample_defaults"],
491 }`),
492 "outsider/Blueprints": []byte(`
493 mock_library {
494 name: "liboutsider",
495 deps: ["libexample"],
496 }`),
497 },
Paul Duffin44885e22020-02-19 16:10:09 +0000498 effectiveVisibility: map[qualifiedModuleName][]string{
499 qualifiedModuleName{pkg: "top", name: "libexample"}: {"//visibility:public"},
500 },
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100501 },
502 {
503 name: "//visibility:public mixed with other from different defaults 1",
Paul Duffincfd33742021-02-27 11:59:02 +0000504 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100505 "top/Blueprints": []byte(`
506 mock_defaults {
507 name: "libexample_defaults_1",
508 visibility: ["//namespace"],
509 }
510 mock_defaults {
511 name: "libexample_defaults_2",
512 visibility: ["//visibility:public"],
513 }
514 mock_library {
515 name: "libexample",
516 defaults: ["libexample_defaults_1", "libexample_defaults_2"],
517 }`),
518 "outsider/Blueprints": []byte(`
519 mock_library {
520 name: "liboutsider",
521 deps: ["libexample"],
522 }`),
523 },
524 },
525 {
526 name: "//visibility:public mixed with other from different defaults 2",
Paul Duffincfd33742021-02-27 11:59:02 +0000527 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100528 "top/Blueprints": []byte(`
529 mock_defaults {
530 name: "libexample_defaults_1",
531 visibility: ["//visibility:public"],
532 }
533 mock_defaults {
534 name: "libexample_defaults_2",
535 visibility: ["//namespace"],
536 }
537 mock_library {
538 name: "libexample",
539 defaults: ["libexample_defaults_1", "libexample_defaults_2"],
540 }`),
541 "outsider/Blueprints": []byte(`
542 mock_library {
543 name: "liboutsider",
544 deps: ["libexample"],
545 }`),
546 },
547 },
548 {
549 name: "//visibility:private in defaults",
Paul Duffincfd33742021-02-27 11:59:02 +0000550 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100551 "top/Blueprints": []byte(`
552 mock_defaults {
553 name: "libexample_defaults",
554 visibility: ["//visibility:private"],
555 }
556 mock_library {
557 name: "libexample",
558 defaults: ["libexample_defaults"],
559 }
560 mock_library {
561 name: "libsamepackage",
562 deps: ["libexample"],
563 }`),
564 "top/nested/Blueprints": []byte(`
565 mock_library {
566 name: "libnested",
567 deps: ["libexample"],
568 }`),
569 "other/Blueprints": []byte(`
570 mock_library {
571 name: "libother",
572 deps: ["libexample"],
573 }`),
574 },
575 expectedErrors: []string{
576 `module "libnested" variant "android_common": depends on //top:libexample which is not` +
577 ` visible to this module`,
578 `module "libother" variant "android_common": depends on //top:libexample which is not` +
579 ` visible to this module`,
580 },
581 },
582 {
583 name: "//visibility:private mixed with other in defaults",
Paul Duffincfd33742021-02-27 11:59:02 +0000584 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100585 "top/Blueprints": []byte(`
586 mock_defaults {
587 name: "libexample_defaults",
588 visibility: ["//visibility:private", "//namespace"],
589 }
590 mock_library {
591 name: "libexample",
592 defaults: ["libexample_defaults"],
593 }`),
594 },
595 expectedErrors: []string{
596 `module "libexample_defaults": visibility: cannot mix "//visibility:private"` +
597 ` with any other visibility rules`,
598 },
599 },
600 {
601 name: "//visibility:private overriding defaults",
Paul Duffincfd33742021-02-27 11:59:02 +0000602 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100603 "top/Blueprints": []byte(`
604 mock_defaults {
605 name: "libexample_defaults",
606 visibility: ["//namespace"],
607 }
608 mock_library {
609 name: "libexample",
610 visibility: ["//visibility:private"],
611 defaults: ["libexample_defaults"],
612 }`),
613 },
614 expectedErrors: []string{
615 `module "libexample": visibility: cannot mix "//visibility:private"` +
616 ` with any other visibility rules`,
617 },
618 },
619 {
620 name: "//visibility:private in defaults overridden",
Paul Duffincfd33742021-02-27 11:59:02 +0000621 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100622 "top/Blueprints": []byte(`
623 mock_defaults {
624 name: "libexample_defaults",
625 visibility: ["//visibility:private"],
626 }
627 mock_library {
628 name: "libexample",
629 visibility: ["//namespace"],
630 defaults: ["libexample_defaults"],
631 }`),
632 },
633 expectedErrors: []string{
634 `module "libexample": visibility: cannot mix "//visibility:private"` +
635 ` with any other visibility rules`,
636 },
637 },
638 {
Paul Duffin51084ff2020-05-05 19:19:22 +0100639 name: "//visibility:private override //visibility:public",
Paul Duffincfd33742021-02-27 11:59:02 +0000640 fs: MockFS{
Paul Duffin51084ff2020-05-05 19:19:22 +0100641 "top/Blueprints": []byte(`
642 mock_defaults {
643 name: "libexample_defaults",
644 visibility: ["//visibility:public"],
645 }
646 mock_library {
647 name: "libexample",
648 visibility: ["//visibility:private"],
649 defaults: ["libexample_defaults"],
650 }`),
651 },
652 expectedErrors: []string{
653 `module "libexample": visibility: cannot mix "//visibility:private" with any other visibility rules`,
654 },
655 },
656 {
657 name: "//visibility:public override //visibility:private",
Paul Duffincfd33742021-02-27 11:59:02 +0000658 fs: MockFS{
Paul Duffin51084ff2020-05-05 19:19:22 +0100659 "top/Blueprints": []byte(`
660 mock_defaults {
661 name: "libexample_defaults",
662 visibility: ["//visibility:private"],
663 }
664 mock_library {
665 name: "libexample",
666 visibility: ["//visibility:public"],
667 defaults: ["libexample_defaults"],
668 }`),
669 },
670 expectedErrors: []string{
671 `module "libexample": visibility: cannot mix "//visibility:private" with any other visibility rules`,
672 },
673 },
674 {
675 name: "//visibility:override must be first in the list",
Paul Duffincfd33742021-02-27 11:59:02 +0000676 fs: MockFS{
Paul Duffin51084ff2020-05-05 19:19:22 +0100677 "top/Blueprints": []byte(`
678 mock_library {
679 name: "libexample",
680 visibility: ["//other", "//visibility:override", "//namespace"],
681 }`),
682 },
683 expectedErrors: []string{
684 `module "libexample": visibility: "//visibility:override" may only be used at the start of the visibility rules`,
685 },
686 },
687 {
688 name: "//visibility:override discards //visibility:private",
Paul Duffincfd33742021-02-27 11:59:02 +0000689 fs: MockFS{
Paul Duffin51084ff2020-05-05 19:19:22 +0100690 "top/Blueprints": []byte(`
691 mock_defaults {
692 name: "libexample_defaults",
693 visibility: ["//visibility:private"],
694 }
695 mock_library {
696 name: "libexample",
697 // Make this visibility to //other but not //visibility:private
698 visibility: ["//visibility:override", "//other"],
699 defaults: ["libexample_defaults"],
700 }`),
701 "other/Blueprints": []byte(`
702 mock_library {
703 name: "libother",
704 deps: ["libexample"],
705 }`),
706 },
707 },
708 {
709 name: "//visibility:override discards //visibility:public",
Paul Duffincfd33742021-02-27 11:59:02 +0000710 fs: MockFS{
Paul Duffin51084ff2020-05-05 19:19:22 +0100711 "top/Blueprints": []byte(`
712 mock_defaults {
713 name: "libexample_defaults",
714 visibility: ["//visibility:public"],
715 }
716 mock_library {
717 name: "libexample",
718 // Make this visibility to //other but not //visibility:public
719 visibility: ["//visibility:override", "//other"],
720 defaults: ["libexample_defaults"],
721 }`),
722 "other/Blueprints": []byte(`
723 mock_library {
724 name: "libother",
725 deps: ["libexample"],
726 }`),
727 "namespace/Blueprints": []byte(`
728 mock_library {
729 name: "libnamespace",
730 deps: ["libexample"],
731 }`),
732 },
733 expectedErrors: []string{
Liz Kammere501bb42020-10-15 11:46:38 -0700734 `module "libnamespace" variant "android_common": depends on //top:libexample which is not visible to this module\nYou may need to add "//namespace" to its visibility`,
Paul Duffin51084ff2020-05-05 19:19:22 +0100735 },
736 },
737 {
738 name: "//visibility:override discards defaults supplied rules",
Paul Duffincfd33742021-02-27 11:59:02 +0000739 fs: MockFS{
Paul Duffin51084ff2020-05-05 19:19:22 +0100740 "top/Blueprints": []byte(`
741 mock_defaults {
742 name: "libexample_defaults",
743 visibility: ["//namespace"],
744 }
745 mock_library {
746 name: "libexample",
747 // Make this visibility to //other but not //namespace
748 visibility: ["//visibility:override", "//other"],
749 defaults: ["libexample_defaults"],
750 }`),
751 "other/Blueprints": []byte(`
752 mock_library {
753 name: "libother",
754 deps: ["libexample"],
755 }`),
756 "namespace/Blueprints": []byte(`
757 mock_library {
758 name: "libnamespace",
759 deps: ["libexample"],
760 }`),
761 },
762 expectedErrors: []string{
Liz Kammere501bb42020-10-15 11:46:38 -0700763 `module "libnamespace" variant "android_common": depends on //top:libexample which is not visible to this module\nYou may need to add "//namespace" to its visibility`,
Paul Duffin51084ff2020-05-05 19:19:22 +0100764 },
765 },
766 {
767 name: "//visibility:override can override //visibility:public with //visibility:private",
Paul Duffincfd33742021-02-27 11:59:02 +0000768 fs: MockFS{
Paul Duffin51084ff2020-05-05 19:19:22 +0100769 "top/Blueprints": []byte(`
770 mock_defaults {
771 name: "libexample_defaults",
772 visibility: ["//visibility:public"],
773 }
774 mock_library {
775 name: "libexample",
776 visibility: ["//visibility:override", "//visibility:private"],
777 defaults: ["libexample_defaults"],
778 }`),
779 "namespace/Blueprints": []byte(`
780 mock_library {
781 name: "libnamespace",
782 deps: ["libexample"],
783 }`),
784 },
785 expectedErrors: []string{
786 `module "libnamespace" variant "android_common": depends on //top:libexample which is not visible to this module`,
787 },
788 },
789 {
790 name: "//visibility:override can override //visibility:private with //visibility:public",
Paul Duffincfd33742021-02-27 11:59:02 +0000791 fs: MockFS{
Paul Duffin51084ff2020-05-05 19:19:22 +0100792 "top/Blueprints": []byte(`
793 mock_defaults {
794 name: "libexample_defaults",
795 visibility: ["//visibility:private"],
796 }
797 mock_library {
798 name: "libexample",
799 visibility: ["//visibility:override", "//visibility:public"],
800 defaults: ["libexample_defaults"],
801 }`),
802 "namespace/Blueprints": []byte(`
803 mock_library {
804 name: "libnamespace",
805 deps: ["libexample"],
806 }`),
807 },
808 },
809 {
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100810 name: "//visibility:private mixed with itself",
Paul Duffincfd33742021-02-27 11:59:02 +0000811 fs: MockFS{
Martin Stjernholm226b20d2019-05-17 22:42:02 +0100812 "top/Blueprints": []byte(`
813 mock_defaults {
814 name: "libexample_defaults_1",
815 visibility: ["//visibility:private"],
816 }
817 mock_defaults {
818 name: "libexample_defaults_2",
819 visibility: ["//visibility:private"],
820 }
821 mock_library {
822 name: "libexample",
823 visibility: ["//visibility:private"],
824 defaults: ["libexample_defaults_1", "libexample_defaults_2"],
825 }`),
826 "outsider/Blueprints": []byte(`
827 mock_library {
828 name: "liboutsider",
829 deps: ["libexample"],
830 }`),
831 },
832 expectedErrors: []string{
833 `module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
834 ` visible to this module`,
835 },
836 },
Paul Duffin95d53b52019-07-24 13:45:05 +0100837
838 // Defaults module's defaults_visibility tests
839 {
840 name: "defaults_visibility invalid",
Paul Duffincfd33742021-02-27 11:59:02 +0000841 fs: MockFS{
Paul Duffin95d53b52019-07-24 13:45:05 +0100842 "top/Blueprints": []byte(`
843 mock_defaults {
844 name: "top_defaults",
845 defaults_visibility: ["//visibility:invalid"],
846 }`),
847 },
848 expectedErrors: []string{
849 `defaults_visibility: unrecognized visibility rule "//visibility:invalid"`,
850 },
851 },
852 {
853 name: "defaults_visibility overrides package default",
Paul Duffincfd33742021-02-27 11:59:02 +0000854 fs: MockFS{
Paul Duffin95d53b52019-07-24 13:45:05 +0100855 "top/Blueprints": []byte(`
856 package {
857 default_visibility: ["//visibility:private"],
858 }
859 mock_defaults {
860 name: "top_defaults",
861 defaults_visibility: ["//visibility:public"],
862 }`),
863 "outsider/Blueprints": []byte(`
864 mock_library {
865 name: "liboutsider",
866 defaults: ["top_defaults"],
867 }`),
868 },
869 },
870
Paul Duffine2453c72019-05-31 14:00:04 +0100871 // Package default_visibility tests
872 {
873 name: "package default_visibility property is checked",
Paul Duffincfd33742021-02-27 11:59:02 +0000874 fs: MockFS{
Paul Duffine2453c72019-05-31 14:00:04 +0100875 "top/Blueprints": []byte(`
876 package {
877 default_visibility: ["//visibility:invalid"],
878 }`),
879 },
880 expectedErrors: []string{`default_visibility: unrecognized visibility rule "//visibility:invalid"`},
881 },
882 {
883 // This test relies on the default visibility being legacy_public.
884 name: "package default_visibility property used when no visibility specified",
Paul Duffincfd33742021-02-27 11:59:02 +0000885 fs: MockFS{
Paul Duffine2453c72019-05-31 14:00:04 +0100886 "top/Blueprints": []byte(`
887 package {
888 default_visibility: ["//visibility:private"],
889 }
890
891 mock_library {
892 name: "libexample",
893 }`),
894 "outsider/Blueprints": []byte(`
895 mock_library {
896 name: "liboutsider",
897 deps: ["libexample"],
898 }`),
899 },
900 expectedErrors: []string{
901 `module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
902 ` visible to this module`,
903 },
904 },
905 {
906 name: "package default_visibility public does not override visibility private",
Paul Duffincfd33742021-02-27 11:59:02 +0000907 fs: MockFS{
Paul Duffine2453c72019-05-31 14:00:04 +0100908 "top/Blueprints": []byte(`
909 package {
910 default_visibility: ["//visibility:public"],
911 }
912
913 mock_library {
914 name: "libexample",
915 visibility: ["//visibility:private"],
916 }`),
917 "outsider/Blueprints": []byte(`
918 mock_library {
919 name: "liboutsider",
920 deps: ["libexample"],
921 }`),
922 },
923 expectedErrors: []string{
924 `module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
925 ` visible to this module`,
926 },
927 },
928 {
929 name: "package default_visibility private does not override visibility public",
Paul Duffincfd33742021-02-27 11:59:02 +0000930 fs: MockFS{
Paul Duffine2453c72019-05-31 14:00:04 +0100931 "top/Blueprints": []byte(`
932 package {
933 default_visibility: ["//visibility:private"],
934 }
935
936 mock_library {
937 name: "libexample",
938 visibility: ["//visibility:public"],
939 }`),
940 "outsider/Blueprints": []byte(`
941 mock_library {
942 name: "liboutsider",
943 deps: ["libexample"],
944 }`),
945 },
946 },
947 {
948 name: "package default_visibility :__subpackages__",
Paul Duffincfd33742021-02-27 11:59:02 +0000949 fs: MockFS{
Paul Duffine2453c72019-05-31 14:00:04 +0100950 "top/Blueprints": []byte(`
951 package {
952 default_visibility: [":__subpackages__"],
953 }
954
955 mock_library {
956 name: "libexample",
957 }`),
958 "top/nested/Blueprints": []byte(`
959 mock_library {
960 name: "libnested",
961 deps: ["libexample"],
962 }`),
963 "outsider/Blueprints": []byte(`
964 mock_library {
965 name: "liboutsider",
966 deps: ["libexample"],
967 }`),
968 },
969 expectedErrors: []string{
970 `module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
971 ` visible to this module`,
972 },
973 },
Paul Duffine484f472019-06-20 16:38:08 +0100974 {
975 name: "package default_visibility inherited to subpackages",
Paul Duffincfd33742021-02-27 11:59:02 +0000976 fs: MockFS{
Paul Duffine484f472019-06-20 16:38:08 +0100977 "top/Blueprints": []byte(`
978 package {
979 default_visibility: ["//outsider"],
980 }
981
982 mock_library {
983 name: "libexample",
984 visibility: [":__subpackages__"],
985 }`),
986 "top/nested/Blueprints": []byte(`
987 mock_library {
988 name: "libnested",
989 deps: ["libexample"],
990 }`),
991 "outsider/Blueprints": []byte(`
992 mock_library {
993 name: "liboutsider",
994 deps: ["libexample", "libnested"],
995 }`),
996 },
997 expectedErrors: []string{
998 `module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
999 ` visible to this module`,
1000 },
1001 },
1002 {
1003 name: "package default_visibility inherited to subpackages",
Paul Duffincfd33742021-02-27 11:59:02 +00001004 fs: MockFS{
Paul Duffine484f472019-06-20 16:38:08 +01001005 "top/Blueprints": []byte(`
1006 package {
1007 default_visibility: ["//visibility:private"],
1008 }`),
1009 "top/nested/Blueprints": []byte(`
1010 package {
1011 default_visibility: ["//outsider"],
1012 }
1013
1014 mock_library {
1015 name: "libnested",
1016 }`),
1017 "top/other/Blueprints": []byte(`
1018 mock_library {
1019 name: "libother",
1020 }`),
1021 "outsider/Blueprints": []byte(`
1022 mock_library {
1023 name: "liboutsider",
1024 deps: ["libother", "libnested"],
1025 }`),
1026 },
1027 expectedErrors: []string{
1028 `module "liboutsider" variant "android_common": depends on //top/other:libother which is` +
1029 ` not visible to this module`,
1030 },
1031 },
Paul Duffin78ac5b92020-01-14 12:42:08 +00001032 {
1033 name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
Paul Duffincfd33742021-02-27 11:59:02 +00001034 fs: MockFS{
Paul Duffin78ac5b92020-01-14 12:42:08 +00001035 "prebuilts/Blueprints": []byte(`
1036 prebuilt {
1037 name: "module",
1038 visibility: ["//top/other"],
1039 }`),
1040 "top/sources/source_file": nil,
1041 "top/sources/Blueprints": []byte(`
1042 source {
1043 name: "module",
1044 visibility: ["//top/other"],
1045 }`),
1046 "top/other/source_file": nil,
1047 "top/other/Blueprints": []byte(`
1048 source {
1049 name: "other",
1050 deps: [":module"],
1051 }`),
1052 },
1053 },
1054 {
1055 name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
Paul Duffincfd33742021-02-27 11:59:02 +00001056 fs: MockFS{
Paul Duffin78ac5b92020-01-14 12:42:08 +00001057 "prebuilts/Blueprints": []byte(`
1058 prebuilt {
1059 name: "module",
1060 visibility: ["//top/other"],
1061 prefer: true,
1062 }`),
1063 "top/sources/source_file": nil,
1064 "top/sources/Blueprints": []byte(`
1065 source {
1066 name: "module",
1067 visibility: ["//top/other"],
1068 }`),
1069 "top/other/source_file": nil,
1070 "top/other/Blueprints": []byte(`
1071 source {
1072 name: "other",
1073 deps: [":module"],
1074 }`),
1075 },
1076 },
Paul Duffinafa9fa12020-04-29 16:47:28 +01001077 {
1078 name: "ensure visibility properties are checked for correctness",
Paul Duffincfd33742021-02-27 11:59:02 +00001079 fs: MockFS{
Paul Duffinafa9fa12020-04-29 16:47:28 +01001080 "top/Blueprints": []byte(`
1081 mock_parent {
1082 name: "parent",
1083 visibility: ["//top/nested"],
1084 child: {
1085 name: "libchild",
1086 visibility: ["top/other"],
1087 },
1088 }`),
1089 },
1090 expectedErrors: []string{
1091 `module "parent": child.visibility: invalid visibility pattern "top/other"`,
1092 },
1093 },
1094 {
1095 name: "invalid visibility added to child detected during gather phase",
Paul Duffincfd33742021-02-27 11:59:02 +00001096 fs: MockFS{
Paul Duffinafa9fa12020-04-29 16:47:28 +01001097 "top/Blueprints": []byte(`
1098 mock_parent {
1099 name: "parent",
1100 visibility: ["//top/nested"],
1101 child: {
1102 name: "libchild",
1103 invalid_visibility: ["top/other"],
1104 },
1105 }`),
1106 },
1107 expectedErrors: []string{
1108 // That this error is reported against the child not the parent shows it was
1109 // not being detected in the parent which is correct as invalid_visibility is
1110 // purposely not added to the list of visibility properties to check, and was
1111 // in fact detected in the child in the gather phase. Contrast this error message
1112 // with the preceding one.
1113 `module "libchild" \(created by module "parent"\): visibility: invalid visibility pattern "top/other"`,
1114 },
1115 },
1116 {
1117 name: "automatic visibility inheritance enabled",
Paul Duffincfd33742021-02-27 11:59:02 +00001118 fs: MockFS{
Paul Duffinafa9fa12020-04-29 16:47:28 +01001119 "top/Blueprints": []byte(`
1120 mock_parent {
1121 name: "parent",
1122 visibility: ["//top/nested"],
1123 child: {
1124 name: "libchild",
1125 visibility: ["//top/other"],
1126 },
1127 }`),
1128 "top/nested/Blueprints": []byte(`
1129 mock_library {
1130 name: "libnested",
1131 deps: ["libchild"],
1132 }`),
1133 "top/other/Blueprints": []byte(`
1134 mock_library {
1135 name: "libother",
1136 deps: ["libchild"],
1137 }`),
1138 },
1139 },
Paul Duffin2e61fa62019-03-28 14:10:57 +00001140}
1141
1142func TestVisibility(t *testing.T) {
Paul Duffin2e61fa62019-03-28 14:10:57 +00001143 for _, test := range visibilityTests {
1144 t.Run(test.name, func(t *testing.T) {
Paul Duffincfd33742021-02-27 11:59:02 +00001145 result := emptyTestFixtureFactory.Extend(
1146 FixtureRegisterWithContext(func(ctx RegistrationContext) {
1147 ctx.RegisterModuleType("mock_library", newMockLibraryModule)
1148 ctx.RegisterModuleType("mock_parent", newMockParentFactory)
1149 ctx.RegisterModuleType("mock_defaults", defaultsFactory)
1150 }),
1151 prepareForTestWithFakePrebuiltModules,
1152 PrepareForTestWithPackageModule,
1153 // Order of the following method calls is significant as they register mutators.
1154 PrepareForTestWithArchMutator,
1155 PrepareForTestWithPrebuilts,
1156 PrepareForTestWithOverrides,
1157 PrepareForTestWithVisibilityRuleChecker,
1158 PrepareForTestWithDefaults,
1159 PrepareForTestWithVisibilityRuleGatherer,
1160 PrepareForTestWithVisibilityRuleEnforcer,
1161 // Add additional files to the mock filesystem
1162 test.fs.AddToFixture(),
1163 ).
1164 SetErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
1165 RunTest(t)
Paul Duffin44885e22020-02-19 16:10:09 +00001166
1167 if test.effectiveVisibility != nil {
Paul Duffincfd33742021-02-27 11:59:02 +00001168 checkEffectiveVisibility(result, test.effectiveVisibility)
Paul Duffin44885e22020-02-19 16:10:09 +00001169 }
Paul Duffin2e61fa62019-03-28 14:10:57 +00001170 })
1171 }
1172}
1173
Paul Duffincfd33742021-02-27 11:59:02 +00001174func checkEffectiveVisibility(result *TestResult, effectiveVisibility map[qualifiedModuleName][]string) {
Paul Duffin44885e22020-02-19 16:10:09 +00001175 for moduleName, expectedRules := range effectiveVisibility {
Paul Duffincfd33742021-02-27 11:59:02 +00001176 rule := effectiveVisibilityRules(result.Config, moduleName)
Paul Duffin44885e22020-02-19 16:10:09 +00001177 stringRules := rule.Strings()
Paul Duffincfd33742021-02-27 11:59:02 +00001178 result.AssertDeepEquals("effective rules mismatch", expectedRules, stringRules)
Paul Duffin44885e22020-02-19 16:10:09 +00001179 }
1180}
1181
Paul Duffin2e61fa62019-03-28 14:10:57 +00001182type mockLibraryProperties struct {
1183 Deps []string
1184}
1185
1186type mockLibraryModule struct {
1187 ModuleBase
Martin Stjernholm226b20d2019-05-17 22:42:02 +01001188 DefaultableModuleBase
Paul Duffin2e61fa62019-03-28 14:10:57 +00001189 properties mockLibraryProperties
1190}
1191
1192func newMockLibraryModule() Module {
1193 m := &mockLibraryModule{}
1194 m.AddProperties(&m.properties)
1195 InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
Martin Stjernholm226b20d2019-05-17 22:42:02 +01001196 InitDefaultableModule(m)
Paul Duffin2e61fa62019-03-28 14:10:57 +00001197 return m
1198}
1199
1200type dependencyTag struct {
1201 blueprint.BaseDependencyTag
1202 name string
1203}
1204
1205func (j *mockLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
1206 ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...)
1207}
1208
1209func (p *mockLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
1210}
Martin Stjernholm226b20d2019-05-17 22:42:02 +01001211
1212type mockDefaults struct {
1213 ModuleBase
1214 DefaultsModuleBase
1215}
1216
1217func defaultsFactory() Module {
1218 m := &mockDefaults{}
1219 InitDefaultsModule(m)
1220 return m
1221}
Paul Duffinafa9fa12020-04-29 16:47:28 +01001222
1223type mockParentProperties struct {
1224 Child struct {
1225 Name *string
1226
1227 // Visibility to pass to the child module.
1228 Visibility []string
1229
1230 // Purposely not validated visibility to pass to the child.
1231 Invalid_visibility []string
1232 }
1233}
1234
1235type mockParent struct {
1236 ModuleBase
1237 DefaultableModuleBase
1238 properties mockParentProperties
1239}
1240
1241func (p *mockParent) GenerateAndroidBuildActions(ModuleContext) {
1242}
1243
1244func newMockParentFactory() Module {
1245 m := &mockParent{}
1246 m.AddProperties(&m.properties)
1247 InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
1248 InitDefaultableModule(m)
1249 AddVisibilityProperty(m, "child.visibility", &m.properties.Child.Visibility)
1250
1251 m.SetDefaultableHook(func(ctx DefaultableHookContext) {
1252 visibility := m.properties.Child.Visibility
1253 visibility = append(visibility, m.properties.Child.Invalid_visibility...)
1254 ctx.CreateModule(newMockLibraryModule, &struct {
1255 Name *string
1256 Visibility []string
1257 }{m.properties.Child.Name, visibility})
1258 })
1259 return m
1260}
Paul Duffin157f40f2020-09-29 16:01:08 +01001261
1262func testVisibilityRuleSet(t *testing.T, rules, extra, expected []string) {
1263 t.Helper()
1264 set := &visibilityRuleSet{rules}
1265 err := set.Widen(extra)
1266 if err != nil {
1267 t.Error(err)
1268 return
1269 }
1270 actual := set.Strings()
1271 if !reflect.DeepEqual(actual, expected) {
1272 t.Errorf("mismatching rules after extend: expected %#v, actual %#v", expected, actual)
1273 }
1274}
1275
1276func TestVisibilityRuleSet(t *testing.T) {
1277 t.Run("extend empty", func(t *testing.T) {
1278 testVisibilityRuleSet(t, nil, []string{"//foo"}, []string{"//foo"})
1279 })
1280 t.Run("extend", func(t *testing.T) {
1281 testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar"}, []string{"//bar", "//foo"})
1282 })
1283 t.Run("extend duplicate", func(t *testing.T) {
1284 testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar", "//foo"}, []string{"//bar", "//foo"})
1285 })
1286 t.Run("extend public", func(t *testing.T) {
1287 testVisibilityRuleSet(t, []string{"//visibility:public"}, []string{"//foo"}, []string{"//visibility:public"})
1288 })
1289 t.Run("extend private", func(t *testing.T) {
1290 testVisibilityRuleSet(t, []string{"//visibility:private"}, []string{"//foo"}, []string{"//foo"})
1291 })
1292 t.Run("extend with public", func(t *testing.T) {
1293 testVisibilityRuleSet(t, []string{"//foo"}, []string{"//visibility:public"}, []string{"//visibility:public"})
1294 })
1295 t.Run("extend with private", func(t *testing.T) {
1296 t.Helper()
1297 set := &visibilityRuleSet{[]string{"//foo"}}
1298 err := set.Widen([]string{"//visibility:private"})
1299 expectedError := `"//visibility:private" does not widen the visibility`
1300 if err == nil {
1301 t.Errorf("missing error")
1302 } else if err.Error() != expectedError {
1303 t.Errorf("expected error %q found error %q", expectedError, err)
1304 }
1305 })
1306}