| package android | 
 |  | 
 | import ( | 
 | 	"reflect" | 
 | 	"testing" | 
 |  | 
 | 	"github.com/google/blueprint" | 
 | ) | 
 |  | 
 | var visibilityTests = []struct { | 
 | 	name                string | 
 | 	fs                  MockFS | 
 | 	expectedErrors      []string | 
 | 	effectiveVisibility map[qualifiedModuleName][]string | 
 | }{ | 
 | 	{ | 
 | 		name: "invalid visibility: empty list", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{`visibility: must contain at least one visibility rule`}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "invalid visibility: empty rule", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [""], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{`visibility: invalid visibility pattern ""`}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "invalid visibility: unqualified", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["target"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{`visibility: invalid visibility pattern "target"`}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "invalid visibility: empty namespace", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{`visibility: invalid visibility pattern "//"`}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "invalid visibility: empty module", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [":"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{`visibility: invalid visibility pattern ":"`}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "invalid visibility: empty namespace and module", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//:"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{`visibility: invalid visibility pattern "//:"`}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:unknown", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:unknown"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{`unrecognized visibility rule "//visibility:unknown"`}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:xxx mixed", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:public", "//namespace"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					visibility: ["//visibility:private", "//namespace"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libother": visibility: cannot mix "//visibility:private"` + | 
 | 				` with any other visibility rules`, | 
 | 			`module "libexample": visibility: cannot mix "//visibility:public"` + | 
 | 				` with any other visibility rules`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:legacy_public", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:legacy_public"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libexample": visibility: //visibility:legacy_public must` + | 
 | 				` not be used`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that //visibility:public will allow the module to be referenced from anywhere, e.g. | 
 | 		// the current directory, a nested directory and a directory in a separate tree. | 
 | 		name: "//visibility:public", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that //visibility:private allows the module to be referenced from the current | 
 | 		// directory only. | 
 | 		name: "//visibility:private", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libnested" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 			`module "libother" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that //visibility:private allows the module to be referenced from the current | 
 | 		// directory only. | 
 | 		name: "//visibility:private (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "nested-notice" references "//top:libexample" which is not visible to this` + | 
 | 				` module\nYou may need to add "//top/nested" to its visibility`, | 
 | 			`module "other-notice" references "//top:libexample" which is not visible to this module\n` + | 
 | 				`You may need to add "//other" to its visibility`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that :__pkg__ allows the module to be referenced from the current directory only. | 
 | 		name: ":__pkg__", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [":__pkg__"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libnested" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 			`module "libother" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that :__pkg__ allows the module to be referenced from the current directory only. | 
 | 		name: ":__pkg__ (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [":__pkg__"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "nested-notice" references "//top:libexample" which is not visible to this module`, | 
 | 			`module "other-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that //top/nested allows the module to be referenced from the current directory and | 
 | 		// the top/nested directory only, not a subdirectory of top/nested and not peak directory. | 
 | 		name: "//top/nested", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//top/nested"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/again/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnestedagain", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"peak/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libother" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 			`module "libnestedagain" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that //top/nested allows the module to be referenced from the current directory and | 
 | 		// the top/nested directory only, not a subdirectory of top/nested and not peak directory. | 
 | 		name: "//top/nested (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//top/nested"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/again/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nestedagain-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"peak/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "other-notice" references "//top:libexample" which is not visible to this module`, | 
 | 			`module "nestedagain-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that :__subpackages__ allows the module to be referenced from the current directory | 
 | 		// and sub directories but nowhere else. | 
 | 		name: ":__subpackages__", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [":__subpackages__"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"peak/other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libother" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that :__subpackages__ allows the module to be referenced from the current directory | 
 | 		// and sub directories but nowhere else. | 
 | 		name: ":__subpackages__ (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [":__subpackages__"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"peak/other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "other-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that //top/nested:__subpackages__ allows the module to be referenced from the current | 
 | 		// directory and sub directories but nowhere else. | 
 | 		name: "//top/nested:__subpackages__", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//top/nested:__subpackages__", "//other"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libother" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that //top/nested:__subpackages__ allows the module to be referenced from the current | 
 | 		// directory and sub directories but nowhere else. | 
 | 		name: "//top/nested:__subpackages__ (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//top/nested:__subpackages__", "//other"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "other-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that ["//top/nested", "//peak:__subpackages"] allows the module to be referenced from | 
 | 		// the current directory, top/nested and peak and all its subpackages. | 
 | 		name: `["//top/nested", "//peak:__subpackages__"]`, | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//top/nested", "//peak:__subpackages__"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"peak/other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that ["//top/nested", "//peak:__subpackages"] allows the module to be referenced from | 
 | 		// the current directory, top/nested and peak and all its subpackages. | 
 | 		name: `["//top/nested", "//peak:__subpackages__ (notices)"]`, | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//top/nested", "//peak:__subpackages__"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"peak/other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Verify that //vendor... cannot be used outside vendor apart from //vendor:__subpackages__ | 
 | 		name: `//vendor`, | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//vendor:__subpackages__"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					visibility: ["//vendor/apps/AcmeSettings"], | 
 | 				}`), | 
 | 			"vendor/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libvendorexample", | 
 | 					deps: ["libexample"], | 
 | 					visibility: ["//vendor/nested"], | 
 | 				}`), | 
 | 			"vendor/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libvendornested", | 
 | 					deps: ["libexample", "libvendorexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libsamepackage": visibility: "//vendor/apps/AcmeSettings"` + | 
 | 				` is not allowed. Packages outside //vendor cannot make themselves visible to specific` + | 
 | 				` targets within //vendor, they can only use //vendor:__subpackages__.`, | 
 | 		}, | 
 | 	}, | 
 |  | 
 | 	// Defaults propagation tests | 
 | 	{ | 
 | 		// Check that visibility is the union of the defaults modules. | 
 | 		name: "defaults union, basic", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//other"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//top/nested"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// Check that visibility is the union of the defaults modules. | 
 | 		name: "defaults union, basic (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//other"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//top/nested"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "outsider-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "defaults union, multiple defaults", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_1", | 
 | 					visibility: ["//other"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_2", | 
 | 					visibility: ["//top/nested"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults_1", "libexample_defaults_2"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "defaults union, multiple defaults (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_1", | 
 | 					visibility: ["//other"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_2", | 
 | 					visibility: ["//top/nested"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults_1", "libexample_defaults_2"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "outsider-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:public mixed with other in defaults", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:public", "//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libexample_defaults": visibility: cannot mix "//visibility:public"` + | 
 | 				` with any other visibility rules`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:public overriding defaults", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:public"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		effectiveVisibility: map[qualifiedModuleName][]string{ | 
 | 			qualifiedModuleName{pkg: "top", name: "libexample"}: {"//visibility:public"}, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:public overriding defaults (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:public"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		effectiveVisibility: map[qualifiedModuleName][]string{ | 
 | 			qualifiedModuleName{pkg: "top", name: "libexample"}: {"//visibility:public"}, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:public mixed with other from different defaults 1", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_1", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_2", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults_1", "libexample_defaults_2"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:public mixed with other from different defaults 1", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_1", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_2", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults_1", "libexample_defaults_2"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:public mixed with other from different defaults 2", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_1", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_2", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults_1", "libexample_defaults_2"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:public mixed with other from different defaults 2 (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_1", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_2", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults_1", "libexample_defaults_2"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:private in defaults", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libsamepackage", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libnested" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 			`module "libother" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:private in defaults (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "libexample-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "nested-notice" references "//top:libexample" which is not visible to this module`, | 
 | 			`module "other-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:private mixed with other in defaults", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private", "//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libexample_defaults": visibility: cannot mix "//visibility:private"` + | 
 | 				` with any other visibility rules`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:private overriding defaults", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:private"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libexample": visibility: cannot mix "//visibility:private"` + | 
 | 				` with any other visibility rules`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:private in defaults overridden", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//namespace"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libexample": visibility: cannot mix "//visibility:private"` + | 
 | 				` with any other visibility rules`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:private override //visibility:public", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:private"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libexample": visibility: cannot mix "//visibility:private" with any other visibility rules`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:public override //visibility:private", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:public"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libexample": visibility: cannot mix "//visibility:private" with any other visibility rules`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override must be first in the list", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//other", "//visibility:override", "//namespace"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libexample": visibility: "//visibility:override" may only be used at the start of the visibility rules`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override discards //visibility:private", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					// Make this visibility to //other but not //visibility:private | 
 | 					visibility: ["//visibility:override", "//other"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override discards //visibility:private (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					// Make this visibility to //other but not //visibility:private | 
 | 					visibility: ["//visibility:override", "//other"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override discards //visibility:public", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					// Make this visibility to //other but not //visibility:public | 
 | 					visibility: ["//visibility:override", "//other"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"namespace/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnamespace", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`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`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override discards //visibility:public (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					// Make this visibility to //other but not //visibility:public | 
 | 					visibility: ["//visibility:override", "//other"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"namespace/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "namespace-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "namespace-notice" references "//top:libexample" which is not visible to this module\nYou may need to add "//namespace" to its visibility`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override discards defaults supplied rules", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					// Make this visibility to //other but not //namespace | 
 | 					visibility: ["//visibility:override", "//other"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"namespace/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnamespace", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`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`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override discards defaults supplied rules (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//namespace"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					// Make this visibility to //other but not //namespace | 
 | 					visibility: ["//visibility:override", "//other"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"namespace/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "namespace-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "namespace-notice" references "//top:libexample" which is not visible to this module\nYou may need to add "//namespace" to its visibility`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override can override //visibility:public with //visibility:private", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:override", "//visibility:private"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"namespace/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnamespace", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "libnamespace" variant "android_common": depends on //top:libexample which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override can override //visibility:public with //visibility:private (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:public"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:override", "//visibility:private"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"namespace/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "namespace-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "namespace-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override can override //visibility:private with //visibility:public", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:override", "//visibility:public"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"namespace/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnamespace", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:override can override //visibility:private with //visibility:public (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:override", "//visibility:public"], | 
 | 					defaults: ["libexample_defaults"], | 
 | 				}`), | 
 | 			"namespace/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "namespace-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:private mixed with itself", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_1", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_2", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:private"], | 
 | 					defaults: ["libexample_defaults_1", "libexample_defaults_2"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "//visibility:private mixed with itself (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_1", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "libexample_defaults_2", | 
 | 					visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:private"], | 
 | 					defaults: ["libexample_defaults_1", "libexample_defaults_2"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "outsider-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 |  | 
 | 	// Defaults module's defaults_visibility tests | 
 | 	{ | 
 | 		name: "defaults_visibility invalid", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_defaults { | 
 | 					name: "top_defaults", | 
 | 					defaults_visibility: ["//visibility:invalid"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`defaults_visibility: unrecognized visibility rule "//visibility:invalid"`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "defaults_visibility overrides package default", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:private"], | 
 | 				} | 
 | 				mock_defaults { | 
 | 					name: "top_defaults", | 
 | 					defaults_visibility: ["//visibility:public"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					defaults: ["top_defaults"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 |  | 
 | 	// Package default_visibility tests | 
 | 	{ | 
 | 		name: "package default_visibility property is checked", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:invalid"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{`default_visibility: unrecognized visibility rule "//visibility:invalid"`}, | 
 | 	}, | 
 | 	{ | 
 | 		// This test relies on the default visibility being legacy_public. | 
 | 		name: "package default_visibility property used when no visibility specified", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:private"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		// This test relies on the default visibility being legacy_public. | 
 | 		name: "package default_visibility property used when no visibility specified (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:private"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "outsider-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility public does not override visibility private", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:public"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:private"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility public does not override visibility private (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:public"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:private"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "outsider-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility private does not override visibility public", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:private"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:public"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility private does not override visibility public (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:private"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: ["//visibility:public"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility :__subpackages__", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: [":__subpackages__"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility :__subpackages__ (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: [":__subpackages__"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "outsider-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility inherited to subpackages", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//outsider"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [":__subpackages__"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libexample", "libnested"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "liboutsider" variant "android_common": depends on //top:libexample which is not` + | 
 | 				` visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility inherited to subpackages (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//outsider"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libexample", | 
 | 					visibility: [":__subpackages__"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libexample"], | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libexample"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libexample", "libnested"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "outsider-notice" references "//top:libexample" which is not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility inherited to subpackages", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:private"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//outsider"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 				}`), | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "liboutsider", | 
 | 					deps: ["libother", "libnested"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "liboutsider" variant "android_common": depends on //top/other:libother which is` + | 
 | 				` not visible to this module`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "package default_visibility inherited to subpackages (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//visibility:private"], | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				package { | 
 | 					default_visibility: ["//outsider"], | 
 | 				} | 
 |  | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 				}`), | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 				} | 
 |  | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libother"], | 
 | 				}`), | 
 | 			"outsider/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "outsider-notice", | 
 | 					for: ["libother", "libnested"], | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "outsider-notice" references "//top/other:libother" which is not visible to this` + | 
 | 				` module\nYou may need to add "//outsider" to its visibility`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)", | 
 | 		fs: MockFS{ | 
 | 			"prebuilts/Android.bp": []byte(` | 
 | 				prebuilt { | 
 | 					name: "module", | 
 | 					visibility: ["//top/other"], | 
 | 				}`), | 
 | 			"top/sources/source_file": nil, | 
 | 			"top/sources/Android.bp": []byte(` | 
 | 				source { | 
 | 					name: "module", | 
 | 					visibility: ["//top/other"], | 
 | 				}`), | 
 | 			"top/other/source_file": nil, | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				source { | 
 | 					name: "other", | 
 | 					deps: [":module"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred) (notices)", | 
 | 		fs: MockFS{ | 
 | 			"prebuilts/Android.bp": []byte(` | 
 | 				prebuilt { | 
 | 					name: "module", | 
 | 					visibility: ["//top/other"], | 
 | 				}`), | 
 | 			"top/sources/source_file": nil, | 
 | 			"top/sources/Android.bp": []byte(` | 
 | 				source { | 
 | 					name: "module", | 
 | 					visibility: ["//top/other"], | 
 | 				}`), | 
 | 			"top/other/source_file": nil, | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["module"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)", | 
 | 		fs: MockFS{ | 
 | 			"prebuilts/Android.bp": []byte(` | 
 | 				prebuilt { | 
 | 					name: "module", | 
 | 					visibility: ["//top/other"], | 
 | 					prefer: true, | 
 | 				}`), | 
 | 			"top/sources/source_file": nil, | 
 | 			"top/sources/Android.bp": []byte(` | 
 | 				source { | 
 | 					name: "module", | 
 | 					visibility: ["//top/other"], | 
 | 				}`), | 
 | 			"top/other/source_file": nil, | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				source { | 
 | 					name: "other", | 
 | 					deps: [":module"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred) (notices)", | 
 | 		fs: MockFS{ | 
 | 			"prebuilts/Android.bp": []byte(` | 
 | 				prebuilt { | 
 | 					name: "module", | 
 | 					visibility: ["//top/other"], | 
 | 					prefer: true, | 
 | 				}`), | 
 | 			"top/sources/source_file": nil, | 
 | 			"top/sources/Android.bp": []byte(` | 
 | 				source { | 
 | 					name: "module", | 
 | 					visibility: ["//top/other"], | 
 | 				}`), | 
 | 			"top/other/source_file": nil, | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["module"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "ensure visibility properties are checked for correctness", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_parent { | 
 | 					name: "parent", | 
 | 					visibility: ["//top/nested"], | 
 | 					child: { | 
 | 						name: "libchild", | 
 | 						visibility: ["top/other"], | 
 | 					}, | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			`module "parent": child.visibility: invalid visibility pattern "top/other"`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "invalid visibility added to child detected during gather phase", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_parent { | 
 | 					name: "parent", | 
 | 					visibility: ["//top/nested"], | 
 | 					child: { | 
 | 						name: "libchild", | 
 | 						invalid_visibility: ["top/other"], | 
 | 					}, | 
 | 				}`), | 
 | 		}, | 
 | 		expectedErrors: []string{ | 
 | 			// That this error is reported against the child not the parent shows it was | 
 | 			// not being detected in the parent which is correct as invalid_visibility is | 
 | 			// purposely not added to the list of visibility properties to check, and was | 
 | 			// in fact detected in the child in the gather phase. Contrast this error message | 
 | 			// with the preceding one. | 
 | 			`module "libchild" \(created by module "parent"\): visibility: invalid visibility pattern "top/other"`, | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "automatic visibility inheritance enabled", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_parent { | 
 | 					name: "parent", | 
 | 					visibility: ["//top/nested"], | 
 | 					child: { | 
 | 						name: "libchild", | 
 | 						visibility: ["//top/other"], | 
 | 					}, | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libnested", | 
 | 					deps: ["libchild"], | 
 | 				}`), | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				mock_library { | 
 | 					name: "libother", | 
 | 					deps: ["libchild"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | 	{ | 
 | 		name: "automatic visibility inheritance enabled (notices)", | 
 | 		fs: MockFS{ | 
 | 			"top/Android.bp": []byte(` | 
 | 				mock_parent { | 
 | 					name: "parent", | 
 | 					visibility: ["//top/nested"], | 
 | 					child: { | 
 | 						name: "libchild", | 
 | 						visibility: ["//top/other"], | 
 | 					}, | 
 | 				}`), | 
 | 			"top/nested/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "nested-notice", | 
 | 					for: ["libchild"], | 
 | 				}`), | 
 | 			"top/other/Android.bp": []byte(` | 
 | 				gen_notice { | 
 | 					name: "other-notice", | 
 | 					for: ["libchild"], | 
 | 				}`), | 
 | 		}, | 
 | 	}, | 
 | } | 
 |  | 
 | func TestVisibility(t *testing.T) { | 
 | 	for _, test := range visibilityTests { | 
 | 		t.Run(test.name, func(t *testing.T) { | 
 | 			result := GroupFixturePreparers( | 
 | 				// General preparers in alphabetical order as test infrastructure will enforce correct | 
 | 				// registration order. | 
 | 				PrepareForTestWithArchMutator, | 
 | 				PrepareForTestWithDefaults, | 
 | 				PrepareForTestWithGenNotice, | 
 | 				PrepareForTestWithOverrides, | 
 | 				PrepareForTestWithPackageModule, | 
 | 				PrepareForTestWithPrebuilts, | 
 | 				PrepareForTestWithVisibility, | 
 |  | 
 | 				// Additional test specific preparers. | 
 | 				FixtureRegisterWithContext(func(ctx RegistrationContext) { | 
 | 					ctx.RegisterModuleType("mock_library", newMockLibraryModule) | 
 | 					ctx.RegisterModuleType("mock_parent", newMockParentFactory) | 
 | 					ctx.RegisterModuleType("mock_defaults", defaultsFactory) | 
 | 				}), | 
 | 				prepareForTestWithFakePrebuiltModules, | 
 | 				// Add additional files to the mock filesystem | 
 | 				test.fs.AddToFixture(), | 
 | 			). | 
 | 				ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)). | 
 | 				RunTest(t) | 
 |  | 
 | 			if test.effectiveVisibility != nil { | 
 | 				checkEffectiveVisibility(t, result, test.effectiveVisibility) | 
 | 			} | 
 | 		}) | 
 | 	} | 
 | } | 
 |  | 
 | func checkEffectiveVisibility(t *testing.T, result *TestResult, effectiveVisibility map[qualifiedModuleName][]string) { | 
 | 	for moduleName, expectedRules := range effectiveVisibility { | 
 | 		rule := effectiveVisibilityRules(result.Config, moduleName) | 
 | 		stringRules := rule.Strings() | 
 | 		AssertDeepEquals(t, "effective rules mismatch", expectedRules, stringRules) | 
 | 	} | 
 | } | 
 |  | 
 | type mockLibraryProperties struct { | 
 | 	Deps []string | 
 | } | 
 |  | 
 | type mockLibraryModule struct { | 
 | 	ModuleBase | 
 | 	DefaultableModuleBase | 
 | 	properties mockLibraryProperties | 
 | } | 
 |  | 
 | func newMockLibraryModule() Module { | 
 | 	m := &mockLibraryModule{} | 
 | 	m.AddProperties(&m.properties) | 
 | 	InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon) | 
 | 	InitDefaultableModule(m) | 
 | 	return m | 
 | } | 
 |  | 
 | type dependencyTag struct { | 
 | 	blueprint.BaseDependencyTag | 
 | 	name string | 
 | } | 
 |  | 
 | func (j *mockLibraryModule) DepsMutator(ctx BottomUpMutatorContext) { | 
 | 	ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...) | 
 | } | 
 |  | 
 | func (p *mockLibraryModule) GenerateAndroidBuildActions(ModuleContext) { | 
 | } | 
 |  | 
 | type mockDefaults struct { | 
 | 	ModuleBase | 
 | 	DefaultsModuleBase | 
 | } | 
 |  | 
 | func defaultsFactory() Module { | 
 | 	m := &mockDefaults{} | 
 | 	InitDefaultsModule(m) | 
 | 	return m | 
 | } | 
 |  | 
 | type mockParentProperties struct { | 
 | 	Child struct { | 
 | 		Name *string | 
 |  | 
 | 		// Visibility to pass to the child module. | 
 | 		Visibility []string | 
 |  | 
 | 		// Purposely not validated visibility to pass to the child. | 
 | 		Invalid_visibility []string | 
 | 	} | 
 | } | 
 |  | 
 | type mockParent struct { | 
 | 	ModuleBase | 
 | 	DefaultableModuleBase | 
 | 	properties mockParentProperties | 
 | } | 
 |  | 
 | func (p *mockParent) GenerateAndroidBuildActions(ModuleContext) { | 
 | } | 
 |  | 
 | func newMockParentFactory() Module { | 
 | 	m := &mockParent{} | 
 | 	m.AddProperties(&m.properties) | 
 | 	InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon) | 
 | 	InitDefaultableModule(m) | 
 | 	AddVisibilityProperty(m, "child.visibility", &m.properties.Child.Visibility) | 
 |  | 
 | 	m.SetDefaultableHook(func(ctx DefaultableHookContext) { | 
 | 		visibility := m.properties.Child.Visibility | 
 | 		visibility = append(visibility, m.properties.Child.Invalid_visibility...) | 
 | 		ctx.CreateModule(newMockLibraryModule, &struct { | 
 | 			Name       *string | 
 | 			Visibility []string | 
 | 		}{m.properties.Child.Name, visibility}) | 
 | 	}) | 
 | 	return m | 
 | } | 
 |  | 
 | func testVisibilityRuleSet(t *testing.T, rules, extra, expected []string) { | 
 | 	t.Helper() | 
 | 	set := &visibilityRuleSet{rules} | 
 | 	err := set.Widen(extra) | 
 | 	if err != nil { | 
 | 		t.Error(err) | 
 | 		return | 
 | 	} | 
 | 	actual := set.Strings() | 
 | 	if !reflect.DeepEqual(actual, expected) { | 
 | 		t.Errorf("mismatching rules after extend: expected %#v, actual %#v", expected, actual) | 
 | 	} | 
 | } | 
 |  | 
 | func TestVisibilityRuleSet(t *testing.T) { | 
 | 	t.Run("extend empty", func(t *testing.T) { | 
 | 		testVisibilityRuleSet(t, nil, []string{"//foo"}, []string{"//foo"}) | 
 | 	}) | 
 | 	t.Run("extend", func(t *testing.T) { | 
 | 		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar"}, []string{"//bar", "//foo"}) | 
 | 	}) | 
 | 	t.Run("extend duplicate", func(t *testing.T) { | 
 | 		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar", "//foo"}, []string{"//bar", "//foo"}) | 
 | 	}) | 
 | 	t.Run("extend public", func(t *testing.T) { | 
 | 		testVisibilityRuleSet(t, []string{"//visibility:public"}, []string{"//foo"}, []string{"//visibility:public"}) | 
 | 	}) | 
 | 	t.Run("extend private", func(t *testing.T) { | 
 | 		testVisibilityRuleSet(t, []string{"//visibility:private"}, []string{"//foo"}, []string{"//foo"}) | 
 | 	}) | 
 | 	t.Run("extend with public", func(t *testing.T) { | 
 | 		testVisibilityRuleSet(t, []string{"//foo"}, []string{"//visibility:public"}, []string{"//visibility:public"}) | 
 | 	}) | 
 | 	t.Run("extend with private", func(t *testing.T) { | 
 | 		t.Helper() | 
 | 		set := &visibilityRuleSet{[]string{"//foo"}} | 
 | 		err := set.Widen([]string{"//visibility:private"}) | 
 | 		expectedError := `"//visibility:private" does not widen the visibility` | 
 | 		if err == nil { | 
 | 			t.Errorf("missing error") | 
 | 		} else if err.Error() != expectedError { | 
 | 			t.Errorf("expected error %q found error %q", expectedError, err) | 
 | 		} | 
 | 	}) | 
 | } |