xref: /aosp_15_r20/build/soong/android/visibility_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1package android
2
3import (
4	"reflect"
5	"testing"
6
7	"github.com/google/blueprint"
8)
9
10var visibilityTests = []struct {
11	name                string
12	fs                  MockFS
13	expectedErrors      []string
14	effectiveVisibility map[qualifiedModuleName][]string
15}{
16	{
17		name: "invalid visibility: empty list",
18		fs: MockFS{
19			"top/Android.bp": []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",
29		fs: MockFS{
30			"top/Android.bp": []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",
40		fs: MockFS{
41			"top/Android.bp": []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",
51		fs: MockFS{
52			"top/Android.bp": []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",
62		fs: MockFS{
63			"top/Android.bp": []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",
73		fs: MockFS{
74			"top/Android.bp": []byte(`
75				mock_library {
76					name: "libexample",
77					visibility: ["//:"],
78				}`),
79		},
80		expectedErrors: []string{`visibility: invalid visibility pattern "//:"`},
81	},
82	{
83		name: "//visibility:unknown",
84		fs: MockFS{
85			"top/Android.bp": []byte(`
86				mock_library {
87					name: "libexample",
88					visibility: ["//visibility:unknown"],
89				}`),
90		},
91		expectedErrors: []string{`unrecognized visibility rule "//visibility:unknown"`},
92	},
93	{
94		name: "//visibility:xxx mixed",
95		fs: MockFS{
96			"top/Android.bp": []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{
108			`module "libother": visibility: cannot mix "//visibility:private"` +
109				` with any other visibility rules`,
110			`module "libexample": visibility: cannot mix "//visibility:public"` +
111				` with any other visibility rules`,
112		},
113	},
114	{
115		name: "//visibility:legacy_public",
116		fs: MockFS{
117			"top/Android.bp": []byte(`
118				mock_library {
119					name: "libexample",
120					visibility: ["//visibility:legacy_public"],
121				}`),
122		},
123		expectedErrors: []string{
124			`module "libexample": visibility: //visibility:legacy_public must` +
125				` 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",
132		fs: MockFS{
133			"top/Android.bp": []byte(`
134				mock_library {
135					name: "libexample",
136					visibility: ["//visibility:public"],
137				}
138
139				mock_library {
140					name: "libsamepackage",
141					deps: ["libexample"],
142				}
143
144				gen_notice {
145					name: "libexample-notice",
146					for: ["libexample"],
147				}`),
148			"top/nested/Android.bp": []byte(`
149				mock_library {
150					name: "libnested",
151					deps: ["libexample"],
152				}
153
154				gen_notice {
155					name: "nested-notice",
156					for: ["libexample"],
157				}`),
158			"other/Android.bp": []byte(`
159				mock_library {
160					name: "libother",
161					deps: ["libexample"],
162				}
163
164				gen_notice {
165					name: "other-notice",
166					for: ["libexample"],
167				}`),
168		},
169	},
170	{
171		// Verify that //visibility:private allows the module to be referenced from the current
172		// directory only.
173		name: "//visibility:private",
174		fs: MockFS{
175			"top/Android.bp": []byte(`
176				mock_library {
177					name: "libexample",
178					visibility: ["//visibility:private"],
179				}
180
181				mock_library {
182					name: "libsamepackage",
183					deps: ["libexample"],
184				}`),
185			"top/nested/Android.bp": []byte(`
186				mock_library {
187					name: "libnested",
188					deps: ["libexample"],
189				}`),
190			"other/Android.bp": []byte(`
191				mock_library {
192					name: "libother",
193					deps: ["libexample"],
194				}`),
195		},
196		expectedErrors: []string{
197			`module "libnested" variant "android_common": depends on //top:libexample which is not` +
198				` visible to this module`,
199			`module "libother" variant "android_common": depends on //top:libexample which is not` +
200				` visible to this module`,
201		},
202	},
203	{
204		// Verify that //visibility:private allows the module to be referenced from the current
205		// directory only.
206		name: "//visibility:private (notices)",
207		fs: MockFS{
208			"top/Android.bp": []byte(`
209				mock_library {
210					name: "libexample",
211					visibility: ["//visibility:private"],
212				}
213
214				mock_library {
215					name: "libsamepackage",
216					deps: ["libexample"],
217				}
218
219				gen_notice {
220					name: "libexample-notice",
221					for: ["libexample"],
222				}`),
223			"top/nested/Android.bp": []byte(`
224				gen_notice {
225					name: "nested-notice",
226					for: ["libexample"],
227				}`),
228			"other/Android.bp": []byte(`
229				gen_notice {
230					name: "other-notice",
231					for: ["libexample"],
232				}`),
233		},
234		expectedErrors: []string{
235			`module "nested-notice" references "//top:libexample" which is not visible to this` +
236				` module\nYou may need to add "//top/nested" to its visibility`,
237			`module "other-notice" references "//top:libexample" which is not visible to this module\n` +
238				`You may need to add "//other" to its visibility`,
239		},
240	},
241	{
242		// Verify that :__pkg__ allows the module to be referenced from the current directory only.
243		name: ":__pkg__",
244		fs: MockFS{
245			"top/Android.bp": []byte(`
246				mock_library {
247					name: "libexample",
248					visibility: [":__pkg__"],
249				}
250
251				mock_library {
252					name: "libsamepackage",
253					deps: ["libexample"],
254				}`),
255			"top/nested/Android.bp": []byte(`
256				mock_library {
257					name: "libnested",
258					deps: ["libexample"],
259				}`),
260			"other/Android.bp": []byte(`
261				mock_library {
262					name: "libother",
263					deps: ["libexample"],
264				}`),
265		},
266		expectedErrors: []string{
267			`module "libnested" variant "android_common": depends on //top:libexample which is not` +
268				` visible to this module`,
269			`module "libother" variant "android_common": depends on //top:libexample which is not` +
270				` visible to this module`,
271		},
272	},
273	{
274		// Verify that :__pkg__ allows the module to be referenced from the current directory only.
275		name: ":__pkg__ (notices)",
276		fs: MockFS{
277			"top/Android.bp": []byte(`
278				mock_library {
279					name: "libexample",
280					visibility: [":__pkg__"],
281				}
282
283				gen_notice {
284					name: "libexample-notice",
285					for: ["libexample"],
286				}`),
287			"top/nested/Android.bp": []byte(`
288				gen_notice {
289					name: "nested-notice",
290					for: ["libexample"],
291				}`),
292			"other/Android.bp": []byte(`
293				gen_notice {
294					name: "other-notice",
295					for: ["libexample"],
296				}`),
297		},
298		expectedErrors: []string{
299			`module "nested-notice" references "//top:libexample" which is not visible to this module`,
300			`module "other-notice" references "//top:libexample" which is not visible to this module`,
301		},
302	},
303	{
304		// Verify that //top/nested allows the module to be referenced from the current directory and
305		// the top/nested directory only, not a subdirectory of top/nested and not peak directory.
306		name: "//top/nested",
307		fs: MockFS{
308			"top/Android.bp": []byte(`
309				mock_library {
310					name: "libexample",
311					visibility: ["//top/nested"],
312				}
313
314				mock_library {
315					name: "libsamepackage",
316					deps: ["libexample"],
317				}`),
318			"top/nested/Android.bp": []byte(`
319				mock_library {
320					name: "libnested",
321					deps: ["libexample"],
322				}`),
323			"top/nested/again/Android.bp": []byte(`
324				mock_library {
325					name: "libnestedagain",
326					deps: ["libexample"],
327				}`),
328			"peak/Android.bp": []byte(`
329				mock_library {
330					name: "libother",
331					deps: ["libexample"],
332				}`),
333		},
334		expectedErrors: []string{
335			`module "libother" variant "android_common": depends on //top:libexample which is not` +
336				` visible to this module`,
337			`module "libnestedagain" variant "android_common": depends on //top:libexample which is not` +
338				` visible to this module`,
339		},
340	},
341	{
342		// Verify that //top/nested allows the module to be referenced from the current directory and
343		// the top/nested directory only, not a subdirectory of top/nested and not peak directory.
344		name: "//top/nested (notices)",
345		fs: MockFS{
346			"top/Android.bp": []byte(`
347				mock_library {
348					name: "libexample",
349					visibility: ["//top/nested"],
350				}
351
352				gen_notice {
353					name: "libexample-notice",
354					for: ["libexample"],
355				}`),
356			"top/nested/Android.bp": []byte(`
357				gen_notice {
358					name: "nested-notice",
359					for: ["libexample"],
360				}`),
361			"top/nested/again/Android.bp": []byte(`
362				gen_notice {
363					name: "nestedagain-notice",
364					for: ["libexample"],
365				}`),
366			"peak/Android.bp": []byte(`
367				gen_notice {
368					name: "other-notice",
369					for: ["libexample"],
370				}`),
371		},
372		expectedErrors: []string{
373			`module "other-notice" references "//top:libexample" which is not visible to this module`,
374			`module "nestedagain-notice" references "//top:libexample" which is not visible to this module`,
375		},
376	},
377	{
378		// Verify that :__subpackages__ allows the module to be referenced from the current directory
379		// and sub directories but nowhere else.
380		name: ":__subpackages__",
381		fs: MockFS{
382			"top/Android.bp": []byte(`
383				mock_library {
384					name: "libexample",
385					visibility: [":__subpackages__"],
386				}
387
388				mock_library {
389					name: "libsamepackage",
390					deps: ["libexample"],
391				}`),
392			"top/nested/Android.bp": []byte(`
393				mock_library {
394					name: "libnested",
395					deps: ["libexample"],
396				}`),
397			"peak/other/Android.bp": []byte(`
398				mock_library {
399					name: "libother",
400					deps: ["libexample"],
401				}`),
402		},
403		expectedErrors: []string{
404			`module "libother" variant "android_common": depends on //top:libexample which is not` +
405				` visible to this module`,
406		},
407	},
408	{
409		// Verify that :__subpackages__ allows the module to be referenced from the current directory
410		// and sub directories but nowhere else.
411		name: ":__subpackages__ (notices)",
412		fs: MockFS{
413			"top/Android.bp": []byte(`
414				mock_library {
415					name: "libexample",
416					visibility: [":__subpackages__"],
417				}
418
419				gen_notice {
420					name: "libexample-notice",
421					for: ["libexample"],
422				}`),
423			"top/nested/Android.bp": []byte(`
424				gen_notice {
425					name: "nested-notice",
426					for: ["libexample"],
427				}`),
428			"peak/other/Android.bp": []byte(`
429				gen_notice {
430					name: "other-notice",
431					for: ["libexample"],
432				}`),
433		},
434		expectedErrors: []string{
435			`module "other-notice" references "//top:libexample" which is not visible to this module`,
436		},
437	},
438	{
439		// Verify that //top/nested:__subpackages__ allows the module to be referenced from the current
440		// directory and sub directories but nowhere else.
441		name: "//top/nested:__subpackages__",
442		fs: MockFS{
443			"top/Android.bp": []byte(`
444				mock_library {
445					name: "libexample",
446					visibility: ["//top/nested:__subpackages__", "//other"],
447				}
448
449				mock_library {
450					name: "libsamepackage",
451					deps: ["libexample"],
452				}`),
453			"top/nested/Android.bp": []byte(`
454				mock_library {
455					name: "libnested",
456					deps: ["libexample"],
457				}`),
458			"top/other/Android.bp": []byte(`
459				mock_library {
460					name: "libother",
461					deps: ["libexample"],
462				}`),
463		},
464		expectedErrors: []string{
465			`module "libother" variant "android_common": depends on //top:libexample which is not` +
466				` visible to this module`,
467		},
468	},
469	{
470		// Verify that //top/nested:__subpackages__ allows the module to be referenced from the current
471		// directory and sub directories but nowhere else.
472		name: "//top/nested:__subpackages__ (notices)",
473		fs: MockFS{
474			"top/Android.bp": []byte(`
475				mock_library {
476					name: "libexample",
477					visibility: ["//top/nested:__subpackages__", "//other"],
478				}
479
480				gen_notice {
481					name: "libexample-notice",
482					for: ["libexample"],
483				}`),
484			"top/nested/Android.bp": []byte(`
485				gen_notice {
486					name: "nested-notice",
487					for: ["libexample"],
488				}`),
489			"top/other/Android.bp": []byte(`
490				gen_notice {
491					name: "other-notice",
492					for: ["libexample"],
493				}`),
494		},
495		expectedErrors: []string{
496			`module "other-notice" references "//top:libexample" which is not visible to this module`,
497		},
498	},
499	{
500		// Verify that ["//top/nested", "//peak:__subpackages"] allows the module to be referenced from
501		// the current directory, top/nested and peak and all its subpackages.
502		name: `["//top/nested", "//peak:__subpackages__"]`,
503		fs: MockFS{
504			"top/Android.bp": []byte(`
505				mock_library {
506					name: "libexample",
507					visibility: ["//top/nested", "//peak:__subpackages__"],
508				}
509
510				mock_library {
511					name: "libsamepackage",
512					deps: ["libexample"],
513				}`),
514			"top/nested/Android.bp": []byte(`
515				mock_library {
516					name: "libnested",
517					deps: ["libexample"],
518				}`),
519			"peak/other/Android.bp": []byte(`
520				mock_library {
521					name: "libother",
522					deps: ["libexample"],
523				}`),
524		},
525	},
526	{
527		// Verify that ["//top/nested", "//peak:__subpackages"] allows the module to be referenced from
528		// the current directory, top/nested and peak and all its subpackages.
529		name: `["//top/nested", "//peak:__subpackages__ (notices)"]`,
530		fs: MockFS{
531			"top/Android.bp": []byte(`
532				mock_library {
533					name: "libexample",
534					visibility: ["//top/nested", "//peak:__subpackages__"],
535				}
536
537				gen_notice {
538					name: "libexample-notice",
539					for: ["libexample"],
540				}`),
541			"top/nested/Android.bp": []byte(`
542				gen_notice {
543					name: "nested-notice",
544					for: ["libexample"],
545				}`),
546			"peak/other/Android.bp": []byte(`
547				gen_notice {
548					name: "other-notice",
549					for: ["libexample"],
550				}`),
551		},
552	},
553	{
554		// Verify that //vendor... cannot be used outside vendor apart from //vendor:__subpackages__
555		name: `//vendor`,
556		fs: MockFS{
557			"top/Android.bp": []byte(`
558				mock_library {
559					name: "libexample",
560					visibility: ["//vendor:__subpackages__"],
561				}
562
563				mock_library {
564					name: "libsamepackage",
565					visibility: ["//vendor/apps/AcmeSettings"],
566				}`),
567			"vendor/Android.bp": []byte(`
568				mock_library {
569					name: "libvendorexample",
570					deps: ["libexample"],
571					visibility: ["//vendor/nested"],
572				}`),
573			"vendor/nested/Android.bp": []byte(`
574				mock_library {
575					name: "libvendornested",
576					deps: ["libexample", "libvendorexample"],
577				}`),
578		},
579		expectedErrors: []string{
580			`module "libsamepackage": visibility: "//vendor/apps/AcmeSettings"` +
581				` is not allowed. Packages outside //vendor cannot make themselves visible to specific` +
582				` targets within //vendor, they can only use //vendor:__subpackages__.`,
583		},
584	},
585
586	// Defaults propagation tests
587	{
588		// Check that visibility is the union of the defaults modules.
589		name: "defaults union, basic",
590		fs: MockFS{
591			"top/Android.bp": []byte(`
592				mock_defaults {
593					name: "libexample_defaults",
594					visibility: ["//other"],
595				}
596				mock_library {
597					name: "libexample",
598					visibility: ["//top/nested"],
599					defaults: ["libexample_defaults"],
600				}
601				mock_library {
602					name: "libsamepackage",
603					deps: ["libexample"],
604				}`),
605			"top/nested/Android.bp": []byte(`
606				mock_library {
607					name: "libnested",
608					deps: ["libexample"],
609				}`),
610			"other/Android.bp": []byte(`
611				mock_library {
612					name: "libother",
613					deps: ["libexample"],
614				}`),
615			"outsider/Android.bp": []byte(`
616				mock_library {
617					name: "liboutsider",
618					deps: ["libexample"],
619				}`),
620		},
621		expectedErrors: []string{
622			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
623				` visible to this module`,
624		},
625	},
626	{
627		// Check that visibility is the union of the defaults modules.
628		name: "defaults union, basic (notices)",
629		fs: MockFS{
630			"top/Android.bp": []byte(`
631				mock_defaults {
632					name: "libexample_defaults",
633					visibility: ["//other"],
634				}
635				mock_library {
636					name: "libexample",
637					visibility: ["//top/nested"],
638					defaults: ["libexample_defaults"],
639				}
640
641				gen_notice {
642					name: "libexample-notice",
643					for: ["libexample"],
644				}`),
645			"top/nested/Android.bp": []byte(`
646				gen_notice {
647					name: "nested-notice",
648					for: ["libexample"],
649				}`),
650			"other/Android.bp": []byte(`
651				gen_notice {
652					name: "other-notice",
653					for: ["libexample"],
654				}`),
655			"outsider/Android.bp": []byte(`
656				gen_notice {
657					name: "outsider-notice",
658					for: ["libexample"],
659				}`),
660		},
661		expectedErrors: []string{
662			`module "outsider-notice" references "//top:libexample" which is not visible to this module`,
663		},
664	},
665	{
666		name: "defaults union, multiple defaults",
667		fs: MockFS{
668			"top/Android.bp": []byte(`
669				mock_defaults {
670					name: "libexample_defaults_1",
671					visibility: ["//other"],
672				}
673				mock_defaults {
674					name: "libexample_defaults_2",
675					visibility: ["//top/nested"],
676				}
677				mock_library {
678					name: "libexample",
679					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
680				}
681				mock_library {
682					name: "libsamepackage",
683					deps: ["libexample"],
684				}`),
685			"top/nested/Android.bp": []byte(`
686				mock_library {
687					name: "libnested",
688					deps: ["libexample"],
689				}`),
690			"other/Android.bp": []byte(`
691				mock_library {
692					name: "libother",
693					deps: ["libexample"],
694				}`),
695			"outsider/Android.bp": []byte(`
696				mock_library {
697					name: "liboutsider",
698					deps: ["libexample"],
699				}`),
700		},
701		expectedErrors: []string{
702			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
703				` visible to this module`,
704		},
705	},
706	{
707		name: "defaults union, multiple defaults (notices)",
708		fs: MockFS{
709			"top/Android.bp": []byte(`
710				mock_defaults {
711					name: "libexample_defaults_1",
712					visibility: ["//other"],
713				}
714				mock_defaults {
715					name: "libexample_defaults_2",
716					visibility: ["//top/nested"],
717				}
718				mock_library {
719					name: "libexample",
720					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
721				}
722
723				gen_notice {
724					name: "libexample-notice",
725					for: ["libexample"],
726				}`),
727			"top/nested/Android.bp": []byte(`
728				gen_notice {
729					name: "nested-notice",
730					for: ["libexample"],
731				}`),
732			"other/Android.bp": []byte(`
733				gen_notice {
734					name: "other-notice",
735					for: ["libexample"],
736				}`),
737			"outsider/Android.bp": []byte(`
738				gen_notice {
739					name: "outsider-notice",
740					for: ["libexample"],
741				}`),
742		},
743		expectedErrors: []string{
744			`module "outsider-notice" references "//top:libexample" which is not visible to this module`,
745		},
746	},
747	{
748		name: "//visibility:public mixed with other in defaults",
749		fs: MockFS{
750			"top/Android.bp": []byte(`
751				mock_defaults {
752					name: "libexample_defaults",
753					visibility: ["//visibility:public", "//namespace"],
754				}
755				mock_library {
756					name: "libexample",
757					defaults: ["libexample_defaults"],
758				}`),
759		},
760		expectedErrors: []string{
761			`module "libexample_defaults": visibility: cannot mix "//visibility:public"` +
762				` with any other visibility rules`,
763		},
764	},
765	{
766		name: "//visibility:public overriding defaults",
767		fs: MockFS{
768			"top/Android.bp": []byte(`
769				mock_defaults {
770					name: "libexample_defaults",
771					visibility: ["//namespace"],
772				}
773				mock_library {
774					name: "libexample",
775					visibility: ["//visibility:public"],
776					defaults: ["libexample_defaults"],
777				}`),
778			"outsider/Android.bp": []byte(`
779				mock_library {
780					name: "liboutsider",
781					deps: ["libexample"],
782				}`),
783		},
784		effectiveVisibility: map[qualifiedModuleName][]string{
785			qualifiedModuleName{pkg: "top", name: "libexample"}: {"//visibility:public"},
786		},
787	},
788	{
789		name: "//visibility:public overriding defaults (notices)",
790		fs: MockFS{
791			"top/Android.bp": []byte(`
792				mock_defaults {
793					name: "libexample_defaults",
794					visibility: ["//namespace"],
795				}
796				mock_library {
797					name: "libexample",
798					visibility: ["//visibility:public"],
799					defaults: ["libexample_defaults"],
800				}`),
801			"outsider/Android.bp": []byte(`
802				gen_notice {
803					name: "outsider-notice",
804					for: ["libexample"],
805				}`),
806		},
807		effectiveVisibility: map[qualifiedModuleName][]string{
808			qualifiedModuleName{pkg: "top", name: "libexample"}: {"//visibility:public"},
809		},
810	},
811	{
812		name: "//visibility:public mixed with other from different defaults 1",
813		fs: MockFS{
814			"top/Android.bp": []byte(`
815				mock_defaults {
816					name: "libexample_defaults_1",
817					visibility: ["//namespace"],
818				}
819				mock_defaults {
820					name: "libexample_defaults_2",
821					visibility: ["//visibility:public"],
822				}
823				mock_library {
824					name: "libexample",
825					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
826				}`),
827			"outsider/Android.bp": []byte(`
828				mock_library {
829					name: "liboutsider",
830					deps: ["libexample"],
831				}`),
832		},
833	},
834	{
835		name: "//visibility:public mixed with other from different defaults 1",
836		fs: MockFS{
837			"top/Android.bp": []byte(`
838				mock_defaults {
839					name: "libexample_defaults_1",
840					visibility: ["//namespace"],
841				}
842				mock_defaults {
843					name: "libexample_defaults_2",
844					visibility: ["//visibility:public"],
845				}
846				mock_library {
847					name: "libexample",
848					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
849				}
850
851				gen_notice {
852					name: "libexample-notice",
853					for: ["libexample"],
854				}`),
855			"outsider/Android.bp": []byte(`
856				gen_notice {
857					name: "outsider-notice",
858					for: ["libexample"],
859				}`),
860		},
861	},
862	{
863		name: "//visibility:public mixed with other from different defaults 2",
864		fs: MockFS{
865			"top/Android.bp": []byte(`
866				mock_defaults {
867					name: "libexample_defaults_1",
868					visibility: ["//visibility:public"],
869				}
870				mock_defaults {
871					name: "libexample_defaults_2",
872					visibility: ["//namespace"],
873				}
874				mock_library {
875					name: "libexample",
876					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
877				}`),
878			"outsider/Android.bp": []byte(`
879				mock_library {
880					name: "liboutsider",
881					deps: ["libexample"],
882				}`),
883		},
884	},
885	{
886		name: "//visibility:public mixed with other from different defaults 2 (notices)",
887		fs: MockFS{
888			"top/Android.bp": []byte(`
889				mock_defaults {
890					name: "libexample_defaults_1",
891					visibility: ["//visibility:public"],
892				}
893				mock_defaults {
894					name: "libexample_defaults_2",
895					visibility: ["//namespace"],
896				}
897				mock_library {
898					name: "libexample",
899					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
900				}`),
901			"outsider/Android.bp": []byte(`
902				gen_notice {
903					name: "outsider-notice",
904					for: ["libexample"],
905				}`),
906		},
907	},
908	{
909		name: "//visibility:private in defaults",
910		fs: MockFS{
911			"top/Android.bp": []byte(`
912				mock_defaults {
913					name: "libexample_defaults",
914					visibility: ["//visibility:private"],
915				}
916				mock_library {
917					name: "libexample",
918					defaults: ["libexample_defaults"],
919				}
920				mock_library {
921					name: "libsamepackage",
922					deps: ["libexample"],
923				}`),
924			"top/nested/Android.bp": []byte(`
925				mock_library {
926					name: "libnested",
927					deps: ["libexample"],
928				}`),
929			"other/Android.bp": []byte(`
930				mock_library {
931					name: "libother",
932					deps: ["libexample"],
933				}`),
934		},
935		expectedErrors: []string{
936			`module "libnested" variant "android_common": depends on //top:libexample which is not` +
937				` visible to this module`,
938			`module "libother" variant "android_common": depends on //top:libexample which is not` +
939				` visible to this module`,
940		},
941	},
942	{
943		name: "//visibility:private in defaults (notices)",
944		fs: MockFS{
945			"top/Android.bp": []byte(`
946				mock_defaults {
947					name: "libexample_defaults",
948					visibility: ["//visibility:private"],
949				}
950				mock_library {
951					name: "libexample",
952					defaults: ["libexample_defaults"],
953				}
954
955				gen_notice {
956					name: "libexample-notice",
957					for: ["libexample"],
958				}`),
959			"top/nested/Android.bp": []byte(`
960				gen_notice {
961					name: "nested-notice",
962					for: ["libexample"],
963				}`),
964			"other/Android.bp": []byte(`
965				gen_notice {
966					name: "other-notice",
967					for: ["libexample"],
968				}`),
969		},
970		expectedErrors: []string{
971			`module "nested-notice" references "//top:libexample" which is not visible to this module`,
972			`module "other-notice" references "//top:libexample" which is not visible to this module`,
973		},
974	},
975	{
976		name: "//visibility:private mixed with other in defaults",
977		fs: MockFS{
978			"top/Android.bp": []byte(`
979				mock_defaults {
980					name: "libexample_defaults",
981					visibility: ["//visibility:private", "//namespace"],
982				}
983				mock_library {
984					name: "libexample",
985					defaults: ["libexample_defaults"],
986				}`),
987		},
988		expectedErrors: []string{
989			`module "libexample_defaults": visibility: cannot mix "//visibility:private"` +
990				` with any other visibility rules`,
991		},
992	},
993	{
994		name: "//visibility:private overriding defaults",
995		fs: MockFS{
996			"top/Android.bp": []byte(`
997				mock_defaults {
998					name: "libexample_defaults",
999					visibility: ["//namespace"],
1000				}
1001				mock_library {
1002					name: "libexample",
1003					visibility: ["//visibility:private"],
1004					defaults: ["libexample_defaults"],
1005				}`),
1006		},
1007		expectedErrors: []string{
1008			`module "libexample": visibility: cannot mix "//visibility:private"` +
1009				` with any other visibility rules`,
1010		},
1011	},
1012	{
1013		name: "//visibility:private in defaults overridden",
1014		fs: MockFS{
1015			"top/Android.bp": []byte(`
1016				mock_defaults {
1017					name: "libexample_defaults",
1018					visibility: ["//visibility:private"],
1019				}
1020				mock_library {
1021					name: "libexample",
1022					visibility: ["//namespace"],
1023					defaults: ["libexample_defaults"],
1024				}`),
1025		},
1026		expectedErrors: []string{
1027			`module "libexample": visibility: cannot mix "//visibility:private"` +
1028				` with any other visibility rules`,
1029		},
1030	},
1031	{
1032		name: "//visibility:private override //visibility:public",
1033		fs: MockFS{
1034			"top/Android.bp": []byte(`
1035				mock_defaults {
1036					name: "libexample_defaults",
1037					visibility: ["//visibility:public"],
1038				}
1039				mock_library {
1040					name: "libexample",
1041					visibility: ["//visibility:private"],
1042					defaults: ["libexample_defaults"],
1043				}`),
1044		},
1045		expectedErrors: []string{
1046			`module "libexample": visibility: cannot mix "//visibility:private" with any other visibility rules`,
1047		},
1048	},
1049	{
1050		name: "//visibility:public override //visibility:private",
1051		fs: MockFS{
1052			"top/Android.bp": []byte(`
1053				mock_defaults {
1054					name: "libexample_defaults",
1055					visibility: ["//visibility:private"],
1056				}
1057				mock_library {
1058					name: "libexample",
1059					visibility: ["//visibility:public"],
1060					defaults: ["libexample_defaults"],
1061				}`),
1062		},
1063		expectedErrors: []string{
1064			`module "libexample": visibility: cannot mix "//visibility:private" with any other visibility rules`,
1065		},
1066	},
1067	{
1068		name: "//visibility:override must be first in the list",
1069		fs: MockFS{
1070			"top/Android.bp": []byte(`
1071				mock_library {
1072					name: "libexample",
1073					visibility: ["//other", "//visibility:override", "//namespace"],
1074				}`),
1075		},
1076		expectedErrors: []string{
1077			`module "libexample": visibility: "//visibility:override" may only be used at the start of the visibility rules`,
1078		},
1079	},
1080	{
1081		name: "//visibility:override discards //visibility:private",
1082		fs: MockFS{
1083			"top/Android.bp": []byte(`
1084				mock_defaults {
1085					name: "libexample_defaults",
1086					visibility: ["//visibility:private"],
1087				}
1088				mock_library {
1089					name: "libexample",
1090					// Make this visibility to //other but not //visibility:private
1091					visibility: ["//visibility:override", "//other"],
1092					defaults: ["libexample_defaults"],
1093				}`),
1094			"other/Android.bp": []byte(`
1095				mock_library {
1096					name: "libother",
1097					deps: ["libexample"],
1098				}`),
1099		},
1100	},
1101	{
1102		name: "//visibility:override discards //visibility:private (notices)",
1103		fs: MockFS{
1104			"top/Android.bp": []byte(`
1105				mock_defaults {
1106					name: "libexample_defaults",
1107					visibility: ["//visibility:private"],
1108				}
1109				mock_library {
1110					name: "libexample",
1111					// Make this visibility to //other but not //visibility:private
1112					visibility: ["//visibility:override", "//other"],
1113					defaults: ["libexample_defaults"],
1114				}`),
1115			"other/Android.bp": []byte(`
1116				gen_notice {
1117					name: "other-notice",
1118					for: ["libexample"],
1119				}`),
1120		},
1121	},
1122	{
1123		name: "//visibility:override discards //visibility:public",
1124		fs: MockFS{
1125			"top/Android.bp": []byte(`
1126				mock_defaults {
1127					name: "libexample_defaults",
1128					visibility: ["//visibility:public"],
1129				}
1130				mock_library {
1131					name: "libexample",
1132					// Make this visibility to //other but not //visibility:public
1133					visibility: ["//visibility:override", "//other"],
1134					defaults: ["libexample_defaults"],
1135				}`),
1136			"other/Android.bp": []byte(`
1137				mock_library {
1138					name: "libother",
1139					deps: ["libexample"],
1140				}`),
1141			"namespace/Android.bp": []byte(`
1142				mock_library {
1143					name: "libnamespace",
1144					deps: ["libexample"],
1145				}`),
1146		},
1147		expectedErrors: []string{
1148			`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`,
1149		},
1150	},
1151	{
1152		name: "//visibility:override discards //visibility:public (notices)",
1153		fs: MockFS{
1154			"top/Android.bp": []byte(`
1155				mock_defaults {
1156					name: "libexample_defaults",
1157					visibility: ["//visibility:public"],
1158				}
1159				mock_library {
1160					name: "libexample",
1161					// Make this visibility to //other but not //visibility:public
1162					visibility: ["//visibility:override", "//other"],
1163					defaults: ["libexample_defaults"],
1164				}`),
1165			"other/Android.bp": []byte(`
1166				gen_notice {
1167					name: "other-notice",
1168					for: ["libexample"],
1169				}`),
1170			"namespace/Android.bp": []byte(`
1171				gen_notice {
1172					name: "namespace-notice",
1173					for: ["libexample"],
1174				}`),
1175		},
1176		expectedErrors: []string{
1177			`module "namespace-notice" references "//top:libexample" which is not visible to this module\nYou may need to add "//namespace" to its visibility`,
1178		},
1179	},
1180	{
1181		name: "//visibility:override discards defaults supplied rules",
1182		fs: MockFS{
1183			"top/Android.bp": []byte(`
1184				mock_defaults {
1185					name: "libexample_defaults",
1186					visibility: ["//namespace"],
1187				}
1188				mock_library {
1189					name: "libexample",
1190					// Make this visibility to //other but not //namespace
1191					visibility: ["//visibility:override", "//other"],
1192					defaults: ["libexample_defaults"],
1193				}`),
1194			"other/Android.bp": []byte(`
1195				mock_library {
1196					name: "libother",
1197					deps: ["libexample"],
1198				}`),
1199			"namespace/Android.bp": []byte(`
1200				mock_library {
1201					name: "libnamespace",
1202					deps: ["libexample"],
1203				}`),
1204		},
1205		expectedErrors: []string{
1206			`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`,
1207		},
1208	},
1209	{
1210		name: "//visibility:override discards defaults supplied rules (notices)",
1211		fs: MockFS{
1212			"top/Android.bp": []byte(`
1213				mock_defaults {
1214					name: "libexample_defaults",
1215					visibility: ["//namespace"],
1216				}
1217				mock_library {
1218					name: "libexample",
1219					// Make this visibility to //other but not //namespace
1220					visibility: ["//visibility:override", "//other"],
1221					defaults: ["libexample_defaults"],
1222				}`),
1223			"other/Android.bp": []byte(`
1224				gen_notice {
1225					name: "other-notice",
1226					for: ["libexample"],
1227				}`),
1228			"namespace/Android.bp": []byte(`
1229				gen_notice {
1230					name: "namespace-notice",
1231					for: ["libexample"],
1232				}`),
1233		},
1234		expectedErrors: []string{
1235			`module "namespace-notice" references "//top:libexample" which is not visible to this module\nYou may need to add "//namespace" to its visibility`,
1236		},
1237	},
1238	{
1239		name: "//visibility:override can override //visibility:public with //visibility:private",
1240		fs: MockFS{
1241			"top/Android.bp": []byte(`
1242				mock_defaults {
1243					name: "libexample_defaults",
1244					visibility: ["//visibility:public"],
1245				}
1246				mock_library {
1247					name: "libexample",
1248					visibility: ["//visibility:override", "//visibility:private"],
1249					defaults: ["libexample_defaults"],
1250				}`),
1251			"namespace/Android.bp": []byte(`
1252				mock_library {
1253					name: "libnamespace",
1254					deps: ["libexample"],
1255				}`),
1256		},
1257		expectedErrors: []string{
1258			`module "libnamespace" variant "android_common": depends on //top:libexample which is not visible to this module`,
1259		},
1260	},
1261	{
1262		name: "//visibility:override can override //visibility:public with //visibility:private (notices)",
1263		fs: MockFS{
1264			"top/Android.bp": []byte(`
1265				mock_defaults {
1266					name: "libexample_defaults",
1267					visibility: ["//visibility:public"],
1268				}
1269				mock_library {
1270					name: "libexample",
1271					visibility: ["//visibility:override", "//visibility:private"],
1272					defaults: ["libexample_defaults"],
1273				}`),
1274			"namespace/Android.bp": []byte(`
1275				gen_notice {
1276					name: "namespace-notice",
1277					for: ["libexample"],
1278				}`),
1279		},
1280		expectedErrors: []string{
1281			`module "namespace-notice" references "//top:libexample" which is not visible to this module`,
1282		},
1283	},
1284	{
1285		name: "//visibility:override can override //visibility:private with //visibility:public",
1286		fs: MockFS{
1287			"top/Android.bp": []byte(`
1288				mock_defaults {
1289					name: "libexample_defaults",
1290					visibility: ["//visibility:private"],
1291				}
1292				mock_library {
1293					name: "libexample",
1294					visibility: ["//visibility:override", "//visibility:public"],
1295					defaults: ["libexample_defaults"],
1296				}`),
1297			"namespace/Android.bp": []byte(`
1298				mock_library {
1299					name: "libnamespace",
1300					deps: ["libexample"],
1301				}`),
1302		},
1303	},
1304	{
1305		name: "//visibility:override can override //visibility:private with //visibility:public (notices)",
1306		fs: MockFS{
1307			"top/Android.bp": []byte(`
1308				mock_defaults {
1309					name: "libexample_defaults",
1310					visibility: ["//visibility:private"],
1311				}
1312				mock_library {
1313					name: "libexample",
1314					visibility: ["//visibility:override", "//visibility:public"],
1315					defaults: ["libexample_defaults"],
1316				}`),
1317			"namespace/Android.bp": []byte(`
1318				gen_notice {
1319					name: "namespace-notice",
1320					for: ["libexample"],
1321				}`),
1322		},
1323	},
1324	{
1325		name: "//visibility:private mixed with itself",
1326		fs: MockFS{
1327			"top/Android.bp": []byte(`
1328				mock_defaults {
1329					name: "libexample_defaults_1",
1330					visibility: ["//visibility:private"],
1331				}
1332				mock_defaults {
1333					name: "libexample_defaults_2",
1334					visibility: ["//visibility:private"],
1335				}
1336				mock_library {
1337					name: "libexample",
1338					visibility: ["//visibility:private"],
1339					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
1340				}`),
1341			"outsider/Android.bp": []byte(`
1342				mock_library {
1343					name: "liboutsider",
1344					deps: ["libexample"],
1345				}`),
1346		},
1347		expectedErrors: []string{
1348			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
1349				` visible to this module`,
1350		},
1351	},
1352	{
1353		name: "//visibility:private mixed with itself (notices)",
1354		fs: MockFS{
1355			"top/Android.bp": []byte(`
1356				mock_defaults {
1357					name: "libexample_defaults_1",
1358					visibility: ["//visibility:private"],
1359				}
1360				mock_defaults {
1361					name: "libexample_defaults_2",
1362					visibility: ["//visibility:private"],
1363				}
1364				mock_library {
1365					name: "libexample",
1366					visibility: ["//visibility:private"],
1367					defaults: ["libexample_defaults_1", "libexample_defaults_2"],
1368				}`),
1369			"outsider/Android.bp": []byte(`
1370				gen_notice {
1371					name: "outsider-notice",
1372					for: ["libexample"],
1373				}`),
1374		},
1375		expectedErrors: []string{
1376			`module "outsider-notice" references "//top:libexample" which is not visible to this module`,
1377		},
1378	},
1379
1380	// Defaults module's defaults_visibility tests
1381	{
1382		name: "defaults_visibility invalid",
1383		fs: MockFS{
1384			"top/Android.bp": []byte(`
1385				mock_defaults {
1386					name: "top_defaults",
1387					defaults_visibility: ["//visibility:invalid"],
1388				}`),
1389		},
1390		expectedErrors: []string{
1391			`defaults_visibility: unrecognized visibility rule "//visibility:invalid"`,
1392		},
1393	},
1394	{
1395		name: "defaults_visibility overrides package default",
1396		fs: MockFS{
1397			"top/Android.bp": []byte(`
1398				package {
1399					default_visibility: ["//visibility:private"],
1400				}
1401				mock_defaults {
1402					name: "top_defaults",
1403					defaults_visibility: ["//visibility:public"],
1404				}`),
1405			"outsider/Android.bp": []byte(`
1406				mock_library {
1407					name: "liboutsider",
1408					defaults: ["top_defaults"],
1409				}`),
1410		},
1411	},
1412
1413	// Package default_visibility tests
1414	{
1415		name: "package default_visibility property is checked",
1416		fs: MockFS{
1417			"top/Android.bp": []byte(`
1418				package {
1419					default_visibility: ["//visibility:invalid"],
1420				}`),
1421		},
1422		expectedErrors: []string{`default_visibility: unrecognized visibility rule "//visibility:invalid"`},
1423	},
1424	{
1425		// This test relies on the default visibility being legacy_public.
1426		name: "package default_visibility property used when no visibility specified",
1427		fs: MockFS{
1428			"top/Android.bp": []byte(`
1429				package {
1430					default_visibility: ["//visibility:private"],
1431				}
1432
1433				mock_library {
1434					name: "libexample",
1435				}`),
1436			"outsider/Android.bp": []byte(`
1437				mock_library {
1438					name: "liboutsider",
1439					deps: ["libexample"],
1440				}`),
1441		},
1442		expectedErrors: []string{
1443			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
1444				` visible to this module`,
1445		},
1446	},
1447	{
1448		// This test relies on the default visibility being legacy_public.
1449		name: "package default_visibility property used when no visibility specified (notices)",
1450		fs: MockFS{
1451			"top/Android.bp": []byte(`
1452				package {
1453					default_visibility: ["//visibility:private"],
1454				}
1455
1456				mock_library {
1457					name: "libexample",
1458				}`),
1459			"outsider/Android.bp": []byte(`
1460				gen_notice {
1461					name: "outsider-notice",
1462					for: ["libexample"],
1463				}`),
1464		},
1465		expectedErrors: []string{
1466			`module "outsider-notice" references "//top:libexample" which is not visible to this module`,
1467		},
1468	},
1469	{
1470		name: "package default_visibility public does not override visibility private",
1471		fs: MockFS{
1472			"top/Android.bp": []byte(`
1473				package {
1474					default_visibility: ["//visibility:public"],
1475				}
1476
1477				mock_library {
1478					name: "libexample",
1479					visibility: ["//visibility:private"],
1480				}`),
1481			"outsider/Android.bp": []byte(`
1482				mock_library {
1483					name: "liboutsider",
1484					deps: ["libexample"],
1485				}`),
1486		},
1487		expectedErrors: []string{
1488			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
1489				` visible to this module`,
1490		},
1491	},
1492	{
1493		name: "package default_visibility public does not override visibility private (notices)",
1494		fs: MockFS{
1495			"top/Android.bp": []byte(`
1496				package {
1497					default_visibility: ["//visibility:public"],
1498				}
1499
1500				mock_library {
1501					name: "libexample",
1502					visibility: ["//visibility:private"],
1503				}`),
1504			"outsider/Android.bp": []byte(`
1505				gen_notice {
1506					name: "outsider-notice",
1507					for: ["libexample"],
1508				}`),
1509		},
1510		expectedErrors: []string{
1511			`module "outsider-notice" references "//top:libexample" which is not visible to this module`,
1512		},
1513	},
1514	{
1515		name: "package default_visibility private does not override visibility public",
1516		fs: MockFS{
1517			"top/Android.bp": []byte(`
1518				package {
1519					default_visibility: ["//visibility:private"],
1520				}
1521
1522				mock_library {
1523					name: "libexample",
1524					visibility: ["//visibility:public"],
1525				}`),
1526			"outsider/Android.bp": []byte(`
1527				mock_library {
1528					name: "liboutsider",
1529					deps: ["libexample"],
1530				}`),
1531		},
1532	},
1533	{
1534		name: "package default_visibility private does not override visibility public (notices)",
1535		fs: MockFS{
1536			"top/Android.bp": []byte(`
1537				package {
1538					default_visibility: ["//visibility:private"],
1539				}
1540
1541				mock_library {
1542					name: "libexample",
1543					visibility: ["//visibility:public"],
1544				}`),
1545			"outsider/Android.bp": []byte(`
1546				gen_notice {
1547					name: "outsider-notice",
1548					for: ["libexample"],
1549				}`),
1550		},
1551	},
1552	{
1553		name: "package default_visibility :__subpackages__",
1554		fs: MockFS{
1555			"top/Android.bp": []byte(`
1556				package {
1557					default_visibility: [":__subpackages__"],
1558				}
1559
1560				mock_library {
1561					name: "libexample",
1562				}`),
1563			"top/nested/Android.bp": []byte(`
1564				mock_library {
1565					name: "libnested",
1566					deps: ["libexample"],
1567				}`),
1568			"outsider/Android.bp": []byte(`
1569				mock_library {
1570					name: "liboutsider",
1571					deps: ["libexample"],
1572				}`),
1573		},
1574		expectedErrors: []string{
1575			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
1576				` visible to this module`,
1577		},
1578	},
1579	{
1580		name: "package default_visibility :__subpackages__ (notices)",
1581		fs: MockFS{
1582			"top/Android.bp": []byte(`
1583				package {
1584					default_visibility: [":__subpackages__"],
1585				}
1586
1587				mock_library {
1588					name: "libexample",
1589				}`),
1590			"top/nested/Android.bp": []byte(`
1591				gen_notice {
1592					name: "nested-notice",
1593					for: ["libexample"],
1594				}`),
1595			"outsider/Android.bp": []byte(`
1596				gen_notice {
1597					name: "outsider-notice",
1598					for: ["libexample"],
1599				}`),
1600		},
1601		expectedErrors: []string{
1602			`module "outsider-notice" references "//top:libexample" which is not visible to this module`,
1603		},
1604	},
1605	{
1606		name: "package default_visibility inherited to subpackages",
1607		fs: MockFS{
1608			"top/Android.bp": []byte(`
1609				package {
1610					default_visibility: ["//outsider"],
1611				}
1612
1613				mock_library {
1614					name: "libexample",
1615					visibility: [":__subpackages__"],
1616				}`),
1617			"top/nested/Android.bp": []byte(`
1618				mock_library {
1619					name: "libnested",
1620					deps: ["libexample"],
1621				}`),
1622			"outsider/Android.bp": []byte(`
1623				mock_library {
1624					name: "liboutsider",
1625					deps: ["libexample", "libnested"],
1626				}`),
1627		},
1628		expectedErrors: []string{
1629			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` +
1630				` visible to this module`,
1631		},
1632	},
1633	{
1634		name: "package default_visibility inherited to subpackages (notices)",
1635		fs: MockFS{
1636			"top/Android.bp": []byte(`
1637				package {
1638					default_visibility: ["//outsider"],
1639				}
1640
1641				mock_library {
1642					name: "libexample",
1643					visibility: [":__subpackages__"],
1644				}`),
1645			"top/nested/Android.bp": []byte(`
1646				mock_library {
1647					name: "libnested",
1648					deps: ["libexample"],
1649				}
1650
1651				gen_notice {
1652					name: "nested-notice",
1653					for: ["libexample"],
1654				}`),
1655			"outsider/Android.bp": []byte(`
1656				gen_notice {
1657					name: "outsider-notice",
1658					for: ["libexample", "libnested"],
1659				}`),
1660		},
1661		expectedErrors: []string{
1662			`module "outsider-notice" references "//top:libexample" which is not visible to this module`,
1663		},
1664	},
1665	{
1666		name: "package default_visibility inherited to subpackages",
1667		fs: MockFS{
1668			"top/Android.bp": []byte(`
1669				package {
1670					default_visibility: ["//visibility:private"],
1671				}`),
1672			"top/nested/Android.bp": []byte(`
1673				package {
1674					default_visibility: ["//outsider"],
1675				}
1676
1677				mock_library {
1678					name: "libnested",
1679				}`),
1680			"top/other/Android.bp": []byte(`
1681				mock_library {
1682					name: "libother",
1683				}`),
1684			"outsider/Android.bp": []byte(`
1685				mock_library {
1686					name: "liboutsider",
1687					deps: ["libother", "libnested"],
1688				}`),
1689		},
1690		expectedErrors: []string{
1691			`module "liboutsider" variant "android_common": depends on //top/other:libother which is` +
1692				` not visible to this module`,
1693		},
1694	},
1695	{
1696		name: "package default_visibility inherited to subpackages (notices)",
1697		fs: MockFS{
1698			"top/Android.bp": []byte(`
1699				package {
1700					default_visibility: ["//visibility:private"],
1701				}`),
1702			"top/nested/Android.bp": []byte(`
1703				package {
1704					default_visibility: ["//outsider"],
1705				}
1706
1707				mock_library {
1708					name: "libnested",
1709				}`),
1710			"top/other/Android.bp": []byte(`
1711				mock_library {
1712					name: "libother",
1713				}
1714
1715				gen_notice {
1716					name: "other-notice",
1717					for: ["libother"],
1718				}`),
1719			"outsider/Android.bp": []byte(`
1720				gen_notice {
1721					name: "outsider-notice",
1722					for: ["libother", "libnested"],
1723				}`),
1724		},
1725		expectedErrors: []string{
1726			`module "outsider-notice" references "//top/other:libother" which is not visible to this` +
1727				` module\nYou may need to add "//outsider" to its visibility`,
1728		},
1729	},
1730	{
1731		name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
1732		fs: MockFS{
1733			"prebuilts/Android.bp": []byte(`
1734				prebuilt {
1735					name: "module",
1736					visibility: ["//top/other"],
1737				}`),
1738			"top/sources/source_file": nil,
1739			"top/sources/Android.bp": []byte(`
1740				source {
1741					name: "module",
1742					visibility: ["//top/other"],
1743				}`),
1744			"top/other/source_file": nil,
1745			"top/other/Android.bp": []byte(`
1746				source {
1747					name: "other",
1748					deps: [":module"],
1749				}`),
1750		},
1751	},
1752	{
1753		name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred) (notices)",
1754		fs: MockFS{
1755			"prebuilts/Android.bp": []byte(`
1756				prebuilt {
1757					name: "module",
1758					visibility: ["//top/other"],
1759				}`),
1760			"top/sources/source_file": nil,
1761			"top/sources/Android.bp": []byte(`
1762				source {
1763					name: "module",
1764					visibility: ["//top/other"],
1765				}`),
1766			"top/other/source_file": nil,
1767			"top/other/Android.bp": []byte(`
1768				gen_notice {
1769					name: "other-notice",
1770					for: ["module"],
1771				}`),
1772		},
1773	},
1774	{
1775		name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
1776		fs: MockFS{
1777			"prebuilts/Android.bp": []byte(`
1778				prebuilt {
1779					name: "module",
1780					visibility: ["//top/other"],
1781					prefer: true,
1782				}`),
1783			"top/sources/source_file": nil,
1784			"top/sources/Android.bp": []byte(`
1785				source {
1786					name: "module",
1787					visibility: ["//top/other"],
1788				}`),
1789			"top/other/source_file": nil,
1790			"top/other/Android.bp": []byte(`
1791				source {
1792					name: "other",
1793					deps: [":module"],
1794				}`),
1795		},
1796	},
1797	{
1798		name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred) (notices)",
1799		fs: MockFS{
1800			"prebuilts/Android.bp": []byte(`
1801				prebuilt {
1802					name: "module",
1803					visibility: ["//top/other"],
1804					prefer: true,
1805				}`),
1806			"top/sources/source_file": nil,
1807			"top/sources/Android.bp": []byte(`
1808				source {
1809					name: "module",
1810					visibility: ["//top/other"],
1811				}`),
1812			"top/other/source_file": nil,
1813			"top/other/Android.bp": []byte(`
1814				gen_notice {
1815					name: "other-notice",
1816					for: ["module"],
1817				}`),
1818		},
1819	},
1820	{
1821		name: "ensure visibility properties are checked for correctness",
1822		fs: MockFS{
1823			"top/Android.bp": []byte(`
1824				mock_parent {
1825					name: "parent",
1826					visibility: ["//top/nested"],
1827					child: {
1828						name: "libchild",
1829						visibility: ["top/other"],
1830					},
1831				}`),
1832		},
1833		expectedErrors: []string{
1834			`module "parent": child.visibility: invalid visibility pattern "top/other"`,
1835		},
1836	},
1837	{
1838		name: "invalid visibility added to child detected during gather phase",
1839		fs: MockFS{
1840			"top/Android.bp": []byte(`
1841				mock_parent {
1842					name: "parent",
1843					visibility: ["//top/nested"],
1844					child: {
1845						name: "libchild",
1846						invalid_visibility: ["top/other"],
1847					},
1848				}`),
1849		},
1850		expectedErrors: []string{
1851			// That this error is reported against the child not the parent shows it was
1852			// not being detected in the parent which is correct as invalid_visibility is
1853			// purposely not added to the list of visibility properties to check, and was
1854			// in fact detected in the child in the gather phase. Contrast this error message
1855			// with the preceding one.
1856			`module "libchild" \(created by module "parent"\): visibility: invalid visibility pattern "top/other"`,
1857		},
1858	},
1859	{
1860		name: "automatic visibility inheritance enabled",
1861		fs: MockFS{
1862			"top/Android.bp": []byte(`
1863				mock_parent {
1864					name: "parent",
1865					visibility: ["//top/nested"],
1866					child: {
1867						name: "libchild",
1868						visibility: ["//top/other"],
1869					},
1870				}`),
1871			"top/nested/Android.bp": []byte(`
1872				mock_library {
1873					name: "libnested",
1874					deps: ["libchild"],
1875				}`),
1876			"top/other/Android.bp": []byte(`
1877				mock_library {
1878					name: "libother",
1879					deps: ["libchild"],
1880				}`),
1881		},
1882	},
1883	{
1884		name: "automatic visibility inheritance enabled (notices)",
1885		fs: MockFS{
1886			"top/Android.bp": []byte(`
1887				mock_parent {
1888					name: "parent",
1889					visibility: ["//top/nested"],
1890					child: {
1891						name: "libchild",
1892						visibility: ["//top/other"],
1893					},
1894				}`),
1895			"top/nested/Android.bp": []byte(`
1896				gen_notice {
1897					name: "nested-notice",
1898					for: ["libchild"],
1899				}`),
1900			"top/other/Android.bp": []byte(`
1901				gen_notice {
1902					name: "other-notice",
1903					for: ["libchild"],
1904				}`),
1905		},
1906	},
1907	{
1908		name: "any_system_partition visibility works",
1909		fs: MockFS{
1910			"top/Android.bp": []byte(`
1911				android_filesystem {
1912					name: "foo",
1913					deps: ["bar"],
1914				}`),
1915			"top/nested/Android.bp": []byte(`
1916				package(default_visibility=["//visibility:private"])
1917				mock_library {
1918					name: "bar",
1919					visibility: ["//visibility:any_system_partition"],
1920				}`),
1921		},
1922	},
1923	{
1924		name: "any_system_partition visibility works with the other visibility",
1925		fs: MockFS{
1926			"top/Android.bp": []byte(`
1927				android_filesystem {
1928					name: "foo",
1929					deps: ["bar"],
1930				}`),
1931			"top2/Android.bp": []byte(``),
1932			"top/nested/Android.bp": []byte(`
1933				package(default_visibility=["//visibility:private"])
1934				mock_library {
1935					name: "bar",
1936					visibility: [
1937						"//top2",
1938						"//visibility:any_system_partition"
1939					],
1940				}`),
1941		},
1942	},
1943	{
1944		name: "any_system_partition visibility doesn't work for non-partitions",
1945		fs: MockFS{
1946			"top/Android.bp": []byte(`
1947				mock_library {
1948					name: "foo",
1949					deps: ["bar"],
1950				}`),
1951			"top/nested/Android.bp": []byte(`
1952				mock_library {
1953					name: "bar",
1954					visibility: ["//visibility:any_system_partition"],
1955				}`),
1956		},
1957		expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
1958	},
1959	{
1960		name: "any_system_partition visibility doesn't work for vendor partitions",
1961		fs: MockFS{
1962			"top/Android.bp": []byte(`
1963				android_filesystem {
1964					name: "foo",
1965					partition_type: "vendor",
1966					deps: ["bar"],
1967				}`),
1968			"top/nested/Android.bp": []byte(`
1969				package(default_visibility=["//visibility:private"])
1970				mock_library {
1971					name: "bar",
1972					visibility: ["//visibility:any_system_partition"],
1973				}`),
1974		},
1975		expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
1976	},
1977	{
1978		name: "Vendor modules are visible to any vendor partition by default",
1979		fs: MockFS{
1980			"top/Android.bp": []byte(`
1981				android_filesystem {
1982					name: "foo",
1983					partition_type: "vendor",
1984					deps: ["bar"],
1985				}`),
1986			"top/nested/Android.bp": []byte(`
1987				package(default_visibility=["//visibility:private"])
1988				mock_library {
1989					name: "bar",
1990					vendor: true,
1991				}`),
1992		},
1993	},
1994	{
1995		name: "Not visible to vendor partitions when using any_system_partiton, even if vendor: true",
1996		fs: MockFS{
1997			"top/Android.bp": []byte(`
1998				android_filesystem {
1999					name: "foo",
2000					partition_type: "vendor",
2001					deps: ["bar"],
2002				}`),
2003			"top/nested/Android.bp": []byte(`
2004				package(default_visibility=["//visibility:private"])
2005				mock_library {
2006					name: "bar",
2007					vendor: true,
2008					visibility: ["//visibility:any_system_partition"],
2009				}`),
2010		},
2011		expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
2012	},
2013	{
2014		name: "unknown any_partition specs throw errors",
2015		fs: MockFS{
2016			"top/nested/Android.bp": []byte(`
2017				package(default_visibility=["//visibility:private"])
2018				mock_library {
2019					name: "bar",
2020					visibility: ["//visibility:any_unknown_partition"],
2021				}`),
2022		},
2023		expectedErrors: []string{`unrecognized visibility rule "//visibility:any_unknown_partition"`},
2024	},
2025}
2026
2027func TestVisibility(t *testing.T) {
2028	for _, test := range visibilityTests {
2029		t.Run(test.name, func(t *testing.T) {
2030			result := GroupFixturePreparers(
2031				// General preparers in alphabetical order as test infrastructure will enforce correct
2032				// registration order.
2033				PrepareForTestWithArchMutator,
2034				PrepareForTestWithDefaults,
2035				PrepareForTestWithGenNotice,
2036				PrepareForTestWithOverrides,
2037				PrepareForTestWithPackageModule,
2038				PrepareForTestWithPrebuilts,
2039				PrepareForTestWithVisibility,
2040
2041				// Additional test specific preparers.
2042				FixtureRegisterWithContext(func(ctx RegistrationContext) {
2043					ctx.RegisterModuleType("mock_library", newMockLibraryModule)
2044					ctx.RegisterModuleType("mock_parent", newMockParentFactory)
2045					ctx.RegisterModuleType("mock_defaults", defaultsFactory)
2046					ctx.RegisterModuleType("android_filesystem", newMockFilesystemModule)
2047				}),
2048				prepareForTestWithFakePrebuiltModules,
2049				// Add additional files to the mock filesystem
2050				test.fs.AddToFixture(),
2051			).
2052				ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
2053				RunTest(t)
2054
2055			if test.effectiveVisibility != nil {
2056				checkEffectiveVisibility(t, result, test.effectiveVisibility)
2057			}
2058		})
2059	}
2060}
2061
2062func checkEffectiveVisibility(t *testing.T, result *TestResult, effectiveVisibility map[qualifiedModuleName][]string) {
2063	for moduleName, expectedRules := range effectiveVisibility {
2064		rule := effectiveVisibilityRules(result.Config, moduleName)
2065		stringRules := rule.Strings()
2066		AssertDeepEquals(t, "effective rules mismatch", expectedRules, stringRules)
2067	}
2068}
2069
2070type mockLibraryProperties struct {
2071	Deps []string
2072}
2073
2074type mockLibraryModule struct {
2075	ModuleBase
2076	DefaultableModuleBase
2077	properties mockLibraryProperties
2078}
2079
2080func newMockLibraryModule() Module {
2081	m := &mockLibraryModule{}
2082	m.AddProperties(&m.properties)
2083	InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
2084	InitDefaultableModule(m)
2085	return m
2086}
2087
2088type dependencyTag struct {
2089	blueprint.BaseDependencyTag
2090	name string
2091}
2092
2093func (j *mockLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
2094	ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...)
2095}
2096
2097func (p *mockLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
2098}
2099
2100type mockFilesystemModuleProperties struct {
2101	Partition_type    *string
2102	Deps              []string
2103	Is_auto_generated *bool
2104}
2105
2106type mockFilesystemModule struct {
2107	ModuleBase
2108	properties mockFilesystemModuleProperties
2109}
2110
2111func (j *mockFilesystemModule) DepsMutator(ctx BottomUpMutatorContext) {
2112	ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...)
2113}
2114
2115func (p *mockFilesystemModule) GenerateAndroidBuildActions(ModuleContext) {
2116}
2117
2118func (p *mockFilesystemModule) PartitionType() string {
2119	if p.properties.Partition_type == nil {
2120		return "system"
2121	}
2122	return *p.properties.Partition_type
2123}
2124
2125func newMockFilesystemModule() Module {
2126	m := &mockFilesystemModule{}
2127	m.AddProperties(&m.properties)
2128	InitAndroidArchModule(m, DeviceSupported, MultilibCommon)
2129	return m
2130}
2131
2132type mockDefaults struct {
2133	ModuleBase
2134	DefaultsModuleBase
2135}
2136
2137func defaultsFactory() Module {
2138	m := &mockDefaults{}
2139	InitDefaultsModule(m)
2140	return m
2141}
2142
2143type mockParentProperties struct {
2144	Child struct {
2145		Name *string
2146
2147		// Visibility to pass to the child module.
2148		Visibility []string
2149
2150		// Purposely not validated visibility to pass to the child.
2151		Invalid_visibility []string
2152	}
2153}
2154
2155type mockParent struct {
2156	ModuleBase
2157	DefaultableModuleBase
2158	properties mockParentProperties
2159}
2160
2161func (p *mockParent) GenerateAndroidBuildActions(ModuleContext) {
2162}
2163
2164func newMockParentFactory() Module {
2165	m := &mockParent{}
2166	m.AddProperties(&m.properties)
2167	InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
2168	InitDefaultableModule(m)
2169	AddVisibilityProperty(m, "child.visibility", &m.properties.Child.Visibility)
2170
2171	m.SetDefaultableHook(func(ctx DefaultableHookContext) {
2172		visibility := m.properties.Child.Visibility
2173		visibility = append(visibility, m.properties.Child.Invalid_visibility...)
2174		ctx.CreateModule(newMockLibraryModule, &struct {
2175			Name       *string
2176			Visibility []string
2177		}{m.properties.Child.Name, visibility})
2178	})
2179	return m
2180}
2181
2182func testVisibilityRuleSet(t *testing.T, rules, extra, expected []string) {
2183	t.Helper()
2184	set := &visibilityRuleSet{rules}
2185	err := set.Widen(extra)
2186	if err != nil {
2187		t.Error(err)
2188		return
2189	}
2190	actual := set.Strings()
2191	if !reflect.DeepEqual(actual, expected) {
2192		t.Errorf("mismatching rules after extend: expected %#v, actual %#v", expected, actual)
2193	}
2194}
2195
2196func TestVisibilityRuleSet(t *testing.T) {
2197	t.Run("extend empty", func(t *testing.T) {
2198		testVisibilityRuleSet(t, nil, []string{"//foo"}, []string{"//foo"})
2199	})
2200	t.Run("extend", func(t *testing.T) {
2201		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar"}, []string{"//bar", "//foo"})
2202	})
2203	t.Run("extend duplicate", func(t *testing.T) {
2204		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar", "//foo"}, []string{"//bar", "//foo"})
2205	})
2206	t.Run("extend public", func(t *testing.T) {
2207		testVisibilityRuleSet(t, []string{"//visibility:public"}, []string{"//foo"}, []string{"//visibility:public"})
2208	})
2209	t.Run("extend private", func(t *testing.T) {
2210		testVisibilityRuleSet(t, []string{"//visibility:private"}, []string{"//foo"}, []string{"//foo"})
2211	})
2212	t.Run("extend with public", func(t *testing.T) {
2213		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//visibility:public"}, []string{"//visibility:public"})
2214	})
2215	t.Run("extend with private", func(t *testing.T) {
2216		t.Helper()
2217		set := &visibilityRuleSet{[]string{"//foo"}}
2218		err := set.Widen([]string{"//visibility:private"})
2219		expectedError := `"//visibility:private" does not widen the visibility`
2220		if err == nil {
2221			t.Errorf("missing error")
2222		} else if err.Error() != expectedError {
2223			t.Errorf("expected error %q found error %q", expectedError, err)
2224		}
2225	})
2226}
2227