Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  visibility_test.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

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"],
    }`),
  },
 },
 {
  name: "any_system_partition visibility works",
  fs: MockFS{
   "top/Android.bp": []byte(`
    android_filesystem {
     name: "foo",
     deps: ["bar"],
    }`),
   "top/nested/Android.bp": []byte(`
    package(default_visibility=["//visibility:private"])
    mock_library {
     name: "bar",
     visibility: ["//visibility:any_system_partition"],
    }`),
  },
 },
 {
  name: "any_system_partition visibility works with the other visibility",
  fs: MockFS{
   "top/Android.bp": []byte(`
    android_filesystem {
     name: "foo",
     deps: ["bar"],
    }`),
   "top2/Android.bp": []byte(``),
   "top/nested/Android.bp": []byte(`
    package(default_visibility=["//visibility:private"])
    mock_library {
     name: "bar",
     visibility: [
      "//top2",
      "//visibility:any_system_partition"
     ],
    }`),
  },
 },
 {
  name: "any_system_partition visibility doesn't work for non-partitions",
  fs: MockFS{
   "top/Android.bp": []byte(`
    mock_library {
     name: "foo",
     deps: ["bar"],
    }`),
   "top/nested/Android.bp": []byte(`
    mock_library {
     name: "bar",
     visibility: ["//visibility:any_system_partition"],
    }`),
  },
  expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
 },
 {
  name: "any_system_partition visibility doesn't work for vendor partitions",
  fs: MockFS{
   "top/Android.bp": []byte(`
    android_filesystem {
     name: "foo",
     partition_type: "vendor",
     deps: ["bar"],
    }`),
   "top/nested/Android.bp": []byte(`
    package(default_visibility=["//visibility:private"])
    mock_library {
     name: "bar",
     visibility: ["//visibility:any_system_partition"],
    }`),
  },
  expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
 },
 {
  name: "Vendor modules are visible to any vendor partition by default",
  fs: MockFS{
   "top/Android.bp": []byte(`
    android_filesystem {
     name: "foo",
     partition_type: "vendor",
     deps: ["bar"],
    }`),
   "top/nested/Android.bp": []byte(`
    package(default_visibility=["//visibility:private"])
    mock_library {
     name: "bar",
     vendor: true,
    }`),
  },
 },
 {
  name: "Not visible to vendor partitions when using any_system_partiton, even if vendor: true",
  fs: MockFS{
   "top/Android.bp": []byte(`
    android_filesystem {
     name: "foo",
     partition_type: "vendor",
     deps: ["bar"],
    }`),
   "top/nested/Android.bp": []byte(`
    package(default_visibility=["//visibility:private"])
    mock_library {
     name: "bar",
     vendor: true,
     visibility: ["//visibility:any_system_partition"],
    }`),
  },
  expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
 },
 {
  name: "unknown any_partition specs throw errors",
  fs: MockFS{
   "top/nested/Android.bp": []byte(`
    package(default_visibility=["//visibility:private"])
    mock_library {
     name: "bar",
     visibility: ["//visibility:any_unknown_partition"],
    }`),
  },
  expectedErrors: []string{`unrecognized visibility rule "//visibility:any_unknown_partition"`},
 },
}

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,
    PrepareForTestWithHostTools("textnotice"),

    // Additional test specific preparers.
    FixtureRegisterWithContext(func(ctx RegistrationContext) {
     ctx.RegisterModuleType("mock_library", newMockLibraryModule)
     ctx.RegisterModuleType("mock_parent", newMockParentFactory)
     ctx.RegisterModuleType("mock_defaults", defaultsFactory)
     ctx.RegisterModuleType("android_filesystem", newMockFilesystemModule)
    }),
    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 mockFilesystemModuleProperties struct {
 Partition_type    *string
 Deps              []string
 Is_auto_generated *bool
}

type mockFilesystemModule struct {
 ModuleBase
 properties mockFilesystemModuleProperties
}

func (j *mockFilesystemModule) DepsMutator(ctx BottomUpMutatorContext) {
 ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...)
}

func (p *mockFilesystemModule) GenerateAndroidBuildActions(ctx ModuleContext) {
 SetProvider(ctx, PartitionTypeInfoProvider, PartitionTypeInfo{
  PartitionType: p.PartitionType(),
 })
}

func (p *mockFilesystemModule) PartitionType() string {
 if p.properties.Partition_type == nil {
  return "system"
 }
 return *p.properties.Partition_type
}

func newMockFilesystemModule() Module {
 m := &mockFilesystemModule{}
 m.AddProperties(&m.properties)
 InitAndroidArchModule(m, DeviceSupported, MultilibCommon)
 return m
}

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)
  }
 })
}

[Dauer der Verarbeitung: 0.43 Sekunden, vorverarbeitet 2026-06-28]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik