1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318 |
- package android
- import (
- "reflect"
- "testing"
- "github.com/google/blueprint"
- )
- var visibilityTests = []struct {
- name string
- fs map[string][]byte
- expectedErrors []string
- effectiveVisibility map[qualifiedModuleName][]string
- }{
- {
- name: "invalid visibility: empty list",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: [],
- }`),
- },
- expectedErrors: []string{`visibility: must contain at least one visibility rule`},
- },
- {
- name: "invalid visibility: empty rule",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: [""],
- }`),
- },
- expectedErrors: []string{`visibility: invalid visibility pattern ""`},
- },
- {
- name: "invalid visibility: unqualified",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["target"],
- }`),
- },
- expectedErrors: []string{`visibility: invalid visibility pattern "target"`},
- },
- {
- name: "invalid visibility: empty namespace",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//"],
- }`),
- },
- expectedErrors: []string{`visibility: invalid visibility pattern "//"`},
- },
- {
- name: "invalid visibility: empty module",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: [":"],
- }`),
- },
- expectedErrors: []string{`visibility: invalid visibility pattern ":"`},
- },
- {
- name: "invalid visibility: empty namespace and module",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//:"],
- }`),
- },
- expectedErrors: []string{`visibility: invalid visibility pattern "//:"`},
- },
- {
- name: "//visibility:unknown",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//visibility:unknown"],
- }`),
- },
- expectedErrors: []string{`unrecognized visibility rule "//visibility:unknown"`},
- },
- {
- name: "//visibility:xxx mixed",
- fs: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//visibility:public"],
- }
-
- mock_library {
- name: "libsamepackage",
- deps: ["libexample"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "other/Blueprints": []byte(`
- mock_library {
- name: "libother",
- deps: ["libexample"],
- }`),
- },
- },
- {
- // Verify that //visibility:private allows the module to be referenced from the current
- // directory only.
- name: "//visibility:private",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//visibility:private"],
- }
-
- mock_library {
- name: "libsamepackage",
- deps: ["libexample"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "other/Blueprints": []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__",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: [":__pkg__"],
- }
-
- mock_library {
- name: "libsamepackage",
- deps: ["libexample"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "other/Blueprints": []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 //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: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//top/nested"],
- }
-
- mock_library {
- name: "libsamepackage",
- deps: ["libexample"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "top/nested/again/Blueprints": []byte(`
- mock_library {
- name: "libnestedagain",
- deps: ["libexample"],
- }`),
- "peak/Blueprints": []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 :__subpackages__ allows the module to be referenced from the current directory
- // and sub directories but nowhere else.
- name: ":__subpackages__",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: [":__subpackages__"],
- }
-
- mock_library {
- name: "libsamepackage",
- deps: ["libexample"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "peak/other/Blueprints": []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__",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//top/nested:__subpackages__", "//other"],
- }
-
- mock_library {
- name: "libsamepackage",
- deps: ["libexample"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "top/other/Blueprints": []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", "//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: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//top/nested", "//peak:__subpackages__"],
- }
-
- mock_library {
- name: "libsamepackage",
- deps: ["libexample"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "peak/other/Blueprints": []byte(`
- mock_library {
- name: "libother",
- deps: ["libexample"],
- }`),
- },
- },
- {
- // Verify that //vendor... cannot be used outside vendor apart from //vendor:__subpackages__
- name: `//vendor`,
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_library {
- name: "libexample",
- visibility: ["//vendor:__subpackages__"],
- }
-
- mock_library {
- name: "libsamepackage",
- visibility: ["//vendor/apps/AcmeSettings"],
- }`),
- "vendor/Blueprints": []byte(`
- mock_library {
- name: "libvendorexample",
- deps: ["libexample"],
- visibility: ["//vendor/nested"],
- }`),
- "vendor/nested/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "other/Blueprints": []byte(`
- mock_library {
- name: "libother",
- deps: ["libexample"],
- }`),
- "outsider/Blueprints": []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",
- fs: map[string][]byte{
- "top/Blueprints": []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/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "other/Blueprints": []byte(`
- mock_library {
- name: "libother",
- deps: ["libexample"],
- }`),
- "outsider/Blueprints": []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:public mixed with other in defaults",
- fs: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_defaults {
- name: "libexample_defaults",
- visibility: ["//namespace"],
- }
- mock_library {
- name: "libexample",
- visibility: ["//visibility:public"],
- defaults: ["libexample_defaults"],
- }`),
- "outsider/Blueprints": []byte(`
- mock_library {
- name: "liboutsider",
- deps: ["libexample"],
- }`),
- },
- effectiveVisibility: map[qualifiedModuleName][]string{
- qualifiedModuleName{pkg: "top", name: "libexample"}: {"//visibility:public"},
- },
- },
- {
- name: "//visibility:public mixed with other from different defaults 1",
- fs: map[string][]byte{
- "top/Blueprints": []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/Blueprints": []byte(`
- mock_library {
- name: "liboutsider",
- deps: ["libexample"],
- }`),
- },
- },
- {
- name: "//visibility:public mixed with other from different defaults 2",
- fs: map[string][]byte{
- "top/Blueprints": []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/Blueprints": []byte(`
- mock_library {
- name: "liboutsider",
- deps: ["libexample"],
- }`),
- },
- },
- {
- name: "//visibility:private in defaults",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_defaults {
- name: "libexample_defaults",
- visibility: ["//visibility:private"],
- }
- mock_library {
- name: "libexample",
- defaults: ["libexample_defaults"],
- }
- mock_library {
- name: "libsamepackage",
- deps: ["libexample"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "other/Blueprints": []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 mixed with other in defaults",
- fs: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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/Blueprints": []byte(`
- mock_library {
- name: "libother",
- deps: ["libexample"],
- }`),
- },
- },
- {
- name: "//visibility:override discards //visibility:public",
- fs: map[string][]byte{
- "top/Blueprints": []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/Blueprints": []byte(`
- mock_library {
- name: "libother",
- deps: ["libexample"],
- }`),
- "namespace/Blueprints": []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 discards defaults supplied rules",
- fs: map[string][]byte{
- "top/Blueprints": []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/Blueprints": []byte(`
- mock_library {
- name: "libother",
- deps: ["libexample"],
- }`),
- "namespace/Blueprints": []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",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_defaults {
- name: "libexample_defaults",
- visibility: ["//visibility:public"],
- }
- mock_library {
- name: "libexample",
- visibility: ["//visibility:override", "//visibility:private"],
- defaults: ["libexample_defaults"],
- }`),
- "namespace/Blueprints": []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:private with //visibility:public",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_defaults {
- name: "libexample_defaults",
- visibility: ["//visibility:private"],
- }
- mock_library {
- name: "libexample",
- visibility: ["//visibility:override", "//visibility:public"],
- defaults: ["libexample_defaults"],
- }`),
- "namespace/Blueprints": []byte(`
- mock_library {
- name: "libnamespace",
- deps: ["libexample"],
- }`),
- },
- },
- {
- name: "//visibility:private mixed with itself",
- fs: map[string][]byte{
- "top/Blueprints": []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/Blueprints": []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`,
- },
- },
- // Defaults module's defaults_visibility tests
- {
- name: "defaults_visibility invalid",
- fs: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []byte(`
- package {
- default_visibility: ["//visibility:private"],
- }
- mock_defaults {
- name: "top_defaults",
- defaults_visibility: ["//visibility:public"],
- }`),
- "outsider/Blueprints": []byte(`
- mock_library {
- name: "liboutsider",
- defaults: ["top_defaults"],
- }`),
- },
- },
- // Package default_visibility tests
- {
- name: "package default_visibility property is checked",
- fs: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []byte(`
- package {
- default_visibility: ["//visibility:private"],
- }
- mock_library {
- name: "libexample",
- }`),
- "outsider/Blueprints": []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",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- package {
- default_visibility: ["//visibility:public"],
- }
- mock_library {
- name: "libexample",
- visibility: ["//visibility:private"],
- }`),
- "outsider/Blueprints": []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 private does not override visibility public",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- package {
- default_visibility: ["//visibility:private"],
- }
- mock_library {
- name: "libexample",
- visibility: ["//visibility:public"],
- }`),
- "outsider/Blueprints": []byte(`
- mock_library {
- name: "liboutsider",
- deps: ["libexample"],
- }`),
- },
- },
- {
- name: "package default_visibility :__subpackages__",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- package {
- default_visibility: [":__subpackages__"],
- }
- mock_library {
- name: "libexample",
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "outsider/Blueprints": []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 inherited to subpackages",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- package {
- default_visibility: ["//outsider"],
- }
- mock_library {
- name: "libexample",
- visibility: [":__subpackages__"],
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libexample"],
- }`),
- "outsider/Blueprints": []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",
- fs: map[string][]byte{
- "top/Blueprints": []byte(`
- package {
- default_visibility: ["//visibility:private"],
- }`),
- "top/nested/Blueprints": []byte(`
- package {
- default_visibility: ["//outsider"],
- }
- mock_library {
- name: "libnested",
- }`),
- "top/other/Blueprints": []byte(`
- mock_library {
- name: "libother",
- }`),
- "outsider/Blueprints": []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: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
- fs: map[string][]byte{
- "prebuilts/Blueprints": []byte(`
- prebuilt {
- name: "module",
- visibility: ["//top/other"],
- }`),
- "top/sources/source_file": nil,
- "top/sources/Blueprints": []byte(`
- source {
- name: "module",
- visibility: ["//top/other"],
- }`),
- "top/other/source_file": nil,
- "top/other/Blueprints": []byte(`
- source {
- name: "other",
- deps: [":module"],
- }`),
- },
- },
- {
- name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
- fs: map[string][]byte{
- "prebuilts/Blueprints": []byte(`
- prebuilt {
- name: "module",
- visibility: ["//top/other"],
- prefer: true,
- }`),
- "top/sources/source_file": nil,
- "top/sources/Blueprints": []byte(`
- source {
- name: "module",
- visibility: ["//top/other"],
- }`),
- "top/other/source_file": nil,
- "top/other/Blueprints": []byte(`
- source {
- name: "other",
- deps: [":module"],
- }`),
- },
- },
- {
- name: "ensure visibility properties are checked for correctness",
- fs: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []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: map[string][]byte{
- "top/Blueprints": []byte(`
- mock_parent {
- name: "parent",
- visibility: ["//top/nested"],
- child: {
- name: "libchild",
- visibility: ["//top/other"],
- },
- }`),
- "top/nested/Blueprints": []byte(`
- mock_library {
- name: "libnested",
- deps: ["libchild"],
- }`),
- "top/other/Blueprints": []byte(`
- mock_library {
- name: "libother",
- deps: ["libchild"],
- }`),
- },
- },
- }
- func TestVisibility(t *testing.T) {
- for _, test := range visibilityTests {
- t.Run(test.name, func(t *testing.T) {
- ctx, errs := testVisibility(buildDir, test.fs)
- CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
- if test.effectiveVisibility != nil {
- checkEffectiveVisibility(t, ctx, test.effectiveVisibility)
- }
- })
- }
- }
- func checkEffectiveVisibility(t *testing.T, ctx *TestContext, effectiveVisibility map[qualifiedModuleName][]string) {
- for moduleName, expectedRules := range effectiveVisibility {
- rule := effectiveVisibilityRules(ctx.config, moduleName)
- stringRules := rule.Strings()
- if !reflect.DeepEqual(expectedRules, stringRules) {
- t.Errorf("effective rules mismatch: expected %q, found %q", expectedRules, stringRules)
- }
- }
- }
- func testVisibility(buildDir string, fs map[string][]byte) (*TestContext, []error) {
- // Create a new config per test as visibility information is stored in the config.
- config := TestArchConfig(buildDir, nil, "", fs)
- ctx := NewTestArchContext()
- ctx.RegisterModuleType("mock_library", newMockLibraryModule)
- ctx.RegisterModuleType("mock_parent", newMockParentFactory)
- ctx.RegisterModuleType("mock_defaults", defaultsFactory)
- // Order of the following method calls is significant.
- RegisterPackageBuildComponents(ctx)
- registerTestPrebuiltBuildComponents(ctx)
- ctx.PreArchMutators(RegisterVisibilityRuleChecker)
- ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
- ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
- ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
- ctx.Register(config)
- _, errs := ctx.ParseBlueprintsFiles(".")
- if len(errs) > 0 {
- return ctx, errs
- }
- _, errs = ctx.PrepareBuildActions(config)
- return ctx, errs
- }
- 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)
- }
- })
- }
|