ec0836af3a
Effective_license_text contains paths to files that are copied from one module to another and so need to be converted to Paths within the context of the owning module as the paths are relative to the owning module's directory. The previous code did convert the license_text property to paths but converted it back to strings again which was confusing and does not follow the normal pattern. Bug: 181569894 Test: m nothing Change-Id: Iea09ee7f3de1187a2c3e41455ca83b0233d904b2
837 lines
21 KiB
Go
837 lines
21 KiB
Go
package android
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/blueprint"
|
|
)
|
|
|
|
var licensesTests = []struct {
|
|
name string
|
|
fs MockFS
|
|
expectedErrors []string
|
|
effectiveLicenses map[string][]string
|
|
effectiveInheritedLicenses map[string][]string
|
|
effectivePackage map[string]string
|
|
effectiveNotices map[string][]string
|
|
effectiveKinds map[string][]string
|
|
effectiveConditions map[string][]string
|
|
}{
|
|
{
|
|
name: "invalid module type without licenses property",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
mock_bad_module {
|
|
name: "libexample",
|
|
}`),
|
|
},
|
|
expectedErrors: []string{`module type "mock_bad_module" must have an applicable licenses property`},
|
|
},
|
|
{
|
|
name: "license must exist",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
mock_library {
|
|
name: "libexample",
|
|
licenses: ["notice"],
|
|
}`),
|
|
},
|
|
expectedErrors: []string{`"libexample" depends on undefined module "notice"`},
|
|
},
|
|
{
|
|
name: "all good",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
license_kind {
|
|
name: "notice",
|
|
conditions: ["shownotice"],
|
|
}
|
|
|
|
license {
|
|
name: "top_Apache2",
|
|
license_kinds: ["notice"],
|
|
package_name: "topDog",
|
|
license_text: ["LICENSE", "NOTICE"],
|
|
}
|
|
|
|
mock_library {
|
|
name: "libexample1",
|
|
licenses: ["top_Apache2"],
|
|
}`),
|
|
"top/nested/Blueprints": []byte(`
|
|
mock_library {
|
|
name: "libnested",
|
|
licenses: ["top_Apache2"],
|
|
}`),
|
|
"other/Blueprints": []byte(`
|
|
mock_library {
|
|
name: "libother",
|
|
licenses: ["top_Apache2"],
|
|
}`),
|
|
},
|
|
effectiveLicenses: map[string][]string{
|
|
"libexample1": []string{"top_Apache2"},
|
|
"libnested": []string{"top_Apache2"},
|
|
"libother": []string{"top_Apache2"},
|
|
},
|
|
effectiveKinds: map[string][]string{
|
|
"libexample1": []string{"notice"},
|
|
"libnested": []string{"notice"},
|
|
"libother": []string{"notice"},
|
|
},
|
|
effectivePackage: map[string]string{
|
|
"libexample1": "topDog",
|
|
"libnested": "topDog",
|
|
"libother": "topDog",
|
|
},
|
|
effectiveConditions: map[string][]string{
|
|
"libexample1": []string{"shownotice"},
|
|
"libnested": []string{"shownotice"},
|
|
"libother": []string{"shownotice"},
|
|
},
|
|
effectiveNotices: map[string][]string{
|
|
"libexample1": []string{"top/LICENSE", "top/NOTICE"},
|
|
"libnested": []string{"top/LICENSE", "top/NOTICE"},
|
|
"libother": []string{"top/LICENSE", "top/NOTICE"},
|
|
},
|
|
},
|
|
|
|
// Defaults propagation tests
|
|
{
|
|
// Check that licenses is the union of the defaults modules.
|
|
name: "defaults union, basic",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
license_kind {
|
|
name: "top_notice",
|
|
conditions: ["notice"],
|
|
}
|
|
|
|
license {
|
|
name: "top_other",
|
|
license_kinds: ["top_notice"],
|
|
}
|
|
|
|
mock_defaults {
|
|
name: "libexample_defaults",
|
|
licenses: ["top_other"],
|
|
}
|
|
mock_library {
|
|
name: "libexample",
|
|
licenses: ["nested_other"],
|
|
defaults: ["libexample_defaults"],
|
|
}
|
|
mock_library {
|
|
name: "libsamepackage",
|
|
deps: ["libexample"],
|
|
}`),
|
|
"top/nested/Blueprints": []byte(`
|
|
license_kind {
|
|
name: "nested_notice",
|
|
conditions: ["notice"],
|
|
}
|
|
|
|
license {
|
|
name: "nested_other",
|
|
license_kinds: ["nested_notice"],
|
|
}
|
|
|
|
mock_library {
|
|
name: "libnested",
|
|
deps: ["libexample"],
|
|
}`),
|
|
"other/Blueprints": []byte(`
|
|
mock_library {
|
|
name: "libother",
|
|
deps: ["libexample"],
|
|
}`),
|
|
},
|
|
effectiveLicenses: map[string][]string{
|
|
"libexample": []string{"nested_other", "top_other"},
|
|
"libsamepackage": []string{},
|
|
"libnested": []string{},
|
|
"libother": []string{},
|
|
},
|
|
effectiveInheritedLicenses: map[string][]string{
|
|
"libexample": []string{"nested_other", "top_other"},
|
|
"libsamepackage": []string{"nested_other", "top_other"},
|
|
"libnested": []string{"nested_other", "top_other"},
|
|
"libother": []string{"nested_other", "top_other"},
|
|
},
|
|
effectiveKinds: map[string][]string{
|
|
"libexample": []string{"nested_notice", "top_notice"},
|
|
"libsamepackage": []string{},
|
|
"libnested": []string{},
|
|
"libother": []string{},
|
|
},
|
|
effectiveConditions: map[string][]string{
|
|
"libexample": []string{"notice"},
|
|
"libsamepackage": []string{},
|
|
"libnested": []string{},
|
|
"libother": []string{},
|
|
},
|
|
},
|
|
{
|
|
name: "defaults union, multiple defaults",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
license {
|
|
name: "top",
|
|
}
|
|
mock_defaults {
|
|
name: "libexample_defaults_1",
|
|
licenses: ["other"],
|
|
}
|
|
mock_defaults {
|
|
name: "libexample_defaults_2",
|
|
licenses: ["top_nested"],
|
|
}
|
|
mock_library {
|
|
name: "libexample",
|
|
defaults: ["libexample_defaults_1", "libexample_defaults_2"],
|
|
}
|
|
mock_library {
|
|
name: "libsamepackage",
|
|
deps: ["libexample"],
|
|
}`),
|
|
"top/nested/Blueprints": []byte(`
|
|
license {
|
|
name: "top_nested",
|
|
license_text: ["LICENSE.txt"],
|
|
}
|
|
mock_library {
|
|
name: "libnested",
|
|
deps: ["libexample"],
|
|
}`),
|
|
"other/Blueprints": []byte(`
|
|
license {
|
|
name: "other",
|
|
}
|
|
mock_library {
|
|
name: "libother",
|
|
deps: ["libexample"],
|
|
}`),
|
|
"outsider/Blueprints": []byte(`
|
|
mock_library {
|
|
name: "liboutsider",
|
|
deps: ["libexample"],
|
|
}`),
|
|
},
|
|
effectiveLicenses: map[string][]string{
|
|
"libexample": []string{"other", "top_nested"},
|
|
"libsamepackage": []string{},
|
|
"libnested": []string{},
|
|
"libother": []string{},
|
|
"liboutsider": []string{},
|
|
},
|
|
effectiveInheritedLicenses: map[string][]string{
|
|
"libexample": []string{"other", "top_nested"},
|
|
"libsamepackage": []string{"other", "top_nested"},
|
|
"libnested": []string{"other", "top_nested"},
|
|
"libother": []string{"other", "top_nested"},
|
|
"liboutsider": []string{"other", "top_nested"},
|
|
},
|
|
effectiveKinds: map[string][]string{
|
|
"libexample": []string{},
|
|
"libsamepackage": []string{},
|
|
"libnested": []string{},
|
|
"libother": []string{},
|
|
"liboutsider": []string{},
|
|
},
|
|
effectiveNotices: map[string][]string{
|
|
"libexample": []string{"top/nested/LICENSE.txt"},
|
|
"libsamepackage": []string{},
|
|
"libnested": []string{},
|
|
"libother": []string{},
|
|
"liboutsider": []string{},
|
|
},
|
|
},
|
|
|
|
// Defaults module's defaults_licenses tests
|
|
{
|
|
name: "defaults_licenses invalid",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
mock_defaults {
|
|
name: "top_defaults",
|
|
licenses: ["notice"],
|
|
}`),
|
|
},
|
|
expectedErrors: []string{`"top_defaults" depends on undefined module "notice"`},
|
|
},
|
|
{
|
|
name: "defaults_licenses overrides package default",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
package {
|
|
default_applicable_licenses: ["by_exception_only"],
|
|
}
|
|
license {
|
|
name: "by_exception_only",
|
|
}
|
|
license {
|
|
name: "notice",
|
|
}
|
|
mock_defaults {
|
|
name: "top_defaults",
|
|
licenses: ["notice"],
|
|
}
|
|
mock_library {
|
|
name: "libexample",
|
|
}
|
|
mock_library {
|
|
name: "libdefaults",
|
|
defaults: ["top_defaults"],
|
|
}`),
|
|
},
|
|
effectiveLicenses: map[string][]string{
|
|
"libexample": []string{"by_exception_only"},
|
|
"libdefaults": []string{"notice"},
|
|
},
|
|
effectiveInheritedLicenses: map[string][]string{
|
|
"libexample": []string{"by_exception_only"},
|
|
"libdefaults": []string{"notice"},
|
|
},
|
|
},
|
|
|
|
// Package default_applicable_licenses tests
|
|
{
|
|
name: "package default_applicable_licenses must exist",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
package {
|
|
default_applicable_licenses: ["notice"],
|
|
}`),
|
|
},
|
|
expectedErrors: []string{`"//top" depends on undefined module "notice"`},
|
|
},
|
|
{
|
|
// This test relies on the default licenses being legacy_public.
|
|
name: "package default_applicable_licenses property used when no licenses specified",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
package {
|
|
default_applicable_licenses: ["top_notice"],
|
|
}
|
|
|
|
license {
|
|
name: "top_notice",
|
|
}
|
|
mock_library {
|
|
name: "libexample",
|
|
}`),
|
|
"outsider/Blueprints": []byte(`
|
|
mock_library {
|
|
name: "liboutsider",
|
|
deps: ["libexample"],
|
|
}`),
|
|
},
|
|
effectiveLicenses: map[string][]string{
|
|
"libexample": []string{"top_notice"},
|
|
"liboutsider": []string{},
|
|
},
|
|
effectiveInheritedLicenses: map[string][]string{
|
|
"libexample": []string{"top_notice"},
|
|
"liboutsider": []string{"top_notice"},
|
|
},
|
|
},
|
|
{
|
|
name: "package default_applicable_licenses not inherited to subpackages",
|
|
fs: map[string][]byte{
|
|
"top/Blueprints": []byte(`
|
|
package {
|
|
default_applicable_licenses: ["top_notice"],
|
|
}
|
|
license {
|
|
name: "top_notice",
|
|
}
|
|
mock_library {
|
|
name: "libexample",
|
|
}`),
|
|
"top/nested/Blueprints": []byte(`
|
|
package {
|
|
default_applicable_licenses: ["outsider"],
|
|
}
|
|
|
|
mock_library {
|
|
name: "libnested",
|
|
}`),
|
|
"top/other/Blueprints": []byte(`
|
|
mock_library {
|
|
name: "libother",
|
|
}`),
|
|
"outsider/Blueprints": []byte(`
|
|
license {
|
|
name: "outsider",
|
|
}
|
|
mock_library {
|
|
name: "liboutsider",
|
|
deps: ["libexample", "libother", "libnested"],
|
|
}`),
|
|
},
|
|
effectiveLicenses: map[string][]string{
|
|
"libexample": []string{"top_notice"},
|
|
"libnested": []string{"outsider"},
|
|
"libother": []string{},
|
|
"liboutsider": []string{},
|
|
},
|
|
effectiveInheritedLicenses: map[string][]string{
|
|
"libexample": []string{"top_notice"},
|
|
"libnested": []string{"outsider"},
|
|
"libother": []string{},
|
|
"liboutsider": []string{"top_notice", "outsider"},
|
|
},
|
|
},
|
|
{
|
|
name: "verify that prebuilt dependencies are included",
|
|
fs: map[string][]byte{
|
|
"prebuilts/Blueprints": []byte(`
|
|
license {
|
|
name: "prebuilt"
|
|
}
|
|
prebuilt {
|
|
name: "module",
|
|
licenses: ["prebuilt"],
|
|
}`),
|
|
"top/sources/source_file": nil,
|
|
"top/sources/Blueprints": []byte(`
|
|
license {
|
|
name: "top_sources"
|
|
}
|
|
source {
|
|
name: "module",
|
|
licenses: ["top_sources"],
|
|
}`),
|
|
"top/other/source_file": nil,
|
|
"top/other/Blueprints": []byte(`
|
|
source {
|
|
name: "other",
|
|
deps: [":module"],
|
|
}`),
|
|
},
|
|
effectiveLicenses: map[string][]string{
|
|
"other": []string{},
|
|
},
|
|
effectiveInheritedLicenses: map[string][]string{
|
|
"other": []string{"prebuilt", "top_sources"},
|
|
},
|
|
},
|
|
{
|
|
name: "verify that prebuilt dependencies are ignored for licenses reasons (preferred)",
|
|
fs: map[string][]byte{
|
|
"prebuilts/Blueprints": []byte(`
|
|
license {
|
|
name: "prebuilt"
|
|
}
|
|
prebuilt {
|
|
name: "module",
|
|
licenses: ["prebuilt"],
|
|
prefer: true,
|
|
}`),
|
|
"top/sources/source_file": nil,
|
|
"top/sources/Blueprints": []byte(`
|
|
license {
|
|
name: "top_sources"
|
|
}
|
|
source {
|
|
name: "module",
|
|
licenses: ["top_sources"],
|
|
}`),
|
|
"top/other/source_file": nil,
|
|
"top/other/Blueprints": []byte(`
|
|
source {
|
|
name: "other",
|
|
deps: [":module"],
|
|
}`),
|
|
},
|
|
effectiveLicenses: map[string][]string{
|
|
"other": []string{},
|
|
},
|
|
effectiveInheritedLicenses: map[string][]string{
|
|
"module": []string{"prebuilt", "top_sources"},
|
|
"other": []string{"prebuilt", "top_sources"},
|
|
},
|
|
},
|
|
}
|
|
|
|
func TestLicenses(t *testing.T) {
|
|
for _, test := range licensesTests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
// Customize the common license text fixture factory.
|
|
result := GroupFixturePreparers(
|
|
prepareForLicenseTest,
|
|
FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
|
ctx.RegisterModuleType("mock_bad_module", newMockLicensesBadModule)
|
|
ctx.RegisterModuleType("mock_library", newMockLicensesLibraryModule)
|
|
ctx.RegisterModuleType("mock_defaults", defaultsLicensesFactory)
|
|
}),
|
|
test.fs.AddToFixture(),
|
|
).
|
|
ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
|
|
RunTest(t)
|
|
|
|
if test.effectiveLicenses != nil {
|
|
checkEffectiveLicenses(t, result, test.effectiveLicenses)
|
|
}
|
|
|
|
if test.effectivePackage != nil {
|
|
checkEffectivePackage(t, result, test.effectivePackage)
|
|
}
|
|
|
|
if test.effectiveNotices != nil {
|
|
checkEffectiveNotices(t, result, test.effectiveNotices)
|
|
}
|
|
|
|
if test.effectiveKinds != nil {
|
|
checkEffectiveKinds(t, result, test.effectiveKinds)
|
|
}
|
|
|
|
if test.effectiveConditions != nil {
|
|
checkEffectiveConditions(t, result, test.effectiveConditions)
|
|
}
|
|
|
|
if test.effectiveInheritedLicenses != nil {
|
|
checkEffectiveInheritedLicenses(t, result, test.effectiveInheritedLicenses)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func checkEffectiveLicenses(t *testing.T, result *TestResult, effectiveLicenses map[string][]string) {
|
|
actualLicenses := make(map[string][]string)
|
|
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
if _, ok := m.(*licenseModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*licenseKindModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*packageModule); ok {
|
|
return
|
|
}
|
|
module, ok := m.(Module)
|
|
if !ok {
|
|
t.Errorf("%q not a module", m.Name())
|
|
return
|
|
}
|
|
base := module.base()
|
|
if base == nil {
|
|
return
|
|
}
|
|
actualLicenses[m.Name()] = base.commonProperties.Effective_licenses
|
|
})
|
|
|
|
for moduleName, expectedLicenses := range effectiveLicenses {
|
|
licenses, ok := actualLicenses[moduleName]
|
|
if !ok {
|
|
licenses = []string{}
|
|
}
|
|
if !compareUnorderedStringArrays(expectedLicenses, licenses) {
|
|
t.Errorf("effective licenses mismatch for module %q: expected %q, found %q", moduleName, expectedLicenses, licenses)
|
|
}
|
|
}
|
|
}
|
|
|
|
func checkEffectiveInheritedLicenses(t *testing.T, result *TestResult, effectiveInheritedLicenses map[string][]string) {
|
|
actualLicenses := make(map[string][]string)
|
|
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
if _, ok := m.(*licenseModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*licenseKindModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*packageModule); ok {
|
|
return
|
|
}
|
|
module, ok := m.(Module)
|
|
if !ok {
|
|
t.Errorf("%q not a module", m.Name())
|
|
return
|
|
}
|
|
base := module.base()
|
|
if base == nil {
|
|
return
|
|
}
|
|
inherited := make(map[string]bool)
|
|
for _, l := range base.commonProperties.Effective_licenses {
|
|
inherited[l] = true
|
|
}
|
|
result.Context.Context.VisitDepsDepthFirst(m, func(c blueprint.Module) {
|
|
if _, ok := c.(*licenseModule); ok {
|
|
return
|
|
}
|
|
if _, ok := c.(*licenseKindModule); ok {
|
|
return
|
|
}
|
|
if _, ok := c.(*packageModule); ok {
|
|
return
|
|
}
|
|
cmodule, ok := c.(Module)
|
|
if !ok {
|
|
t.Errorf("%q not a module", c.Name())
|
|
return
|
|
}
|
|
cbase := cmodule.base()
|
|
if cbase == nil {
|
|
return
|
|
}
|
|
for _, l := range cbase.commonProperties.Effective_licenses {
|
|
inherited[l] = true
|
|
}
|
|
})
|
|
actualLicenses[m.Name()] = []string{}
|
|
for l := range inherited {
|
|
actualLicenses[m.Name()] = append(actualLicenses[m.Name()], l)
|
|
}
|
|
})
|
|
|
|
for moduleName, expectedInheritedLicenses := range effectiveInheritedLicenses {
|
|
licenses, ok := actualLicenses[moduleName]
|
|
if !ok {
|
|
licenses = []string{}
|
|
}
|
|
if !compareUnorderedStringArrays(expectedInheritedLicenses, licenses) {
|
|
t.Errorf("effective inherited licenses mismatch for module %q: expected %q, found %q", moduleName, expectedInheritedLicenses, licenses)
|
|
}
|
|
}
|
|
}
|
|
|
|
func checkEffectivePackage(t *testing.T, result *TestResult, effectivePackage map[string]string) {
|
|
actualPackage := make(map[string]string)
|
|
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
if _, ok := m.(*licenseModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*licenseKindModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*packageModule); ok {
|
|
return
|
|
}
|
|
module, ok := m.(Module)
|
|
if !ok {
|
|
t.Errorf("%q not a module", m.Name())
|
|
return
|
|
}
|
|
base := module.base()
|
|
if base == nil {
|
|
return
|
|
}
|
|
|
|
if base.commonProperties.Effective_package_name == nil {
|
|
actualPackage[m.Name()] = ""
|
|
} else {
|
|
actualPackage[m.Name()] = *base.commonProperties.Effective_package_name
|
|
}
|
|
})
|
|
|
|
for moduleName, expectedPackage := range effectivePackage {
|
|
packageName, ok := actualPackage[moduleName]
|
|
if !ok {
|
|
packageName = ""
|
|
}
|
|
if expectedPackage != packageName {
|
|
t.Errorf("effective package mismatch for module %q: expected %q, found %q", moduleName, expectedPackage, packageName)
|
|
}
|
|
}
|
|
}
|
|
|
|
func checkEffectiveNotices(t *testing.T, result *TestResult, effectiveNotices map[string][]string) {
|
|
actualNotices := make(map[string][]string)
|
|
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
if _, ok := m.(*licenseModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*licenseKindModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*packageModule); ok {
|
|
return
|
|
}
|
|
module, ok := m.(Module)
|
|
if !ok {
|
|
t.Errorf("%q not a module", m.Name())
|
|
return
|
|
}
|
|
base := module.base()
|
|
if base == nil {
|
|
return
|
|
}
|
|
actualNotices[m.Name()] = base.commonProperties.Effective_license_text.Strings()
|
|
})
|
|
|
|
for moduleName, expectedNotices := range effectiveNotices {
|
|
notices, ok := actualNotices[moduleName]
|
|
if !ok {
|
|
notices = []string{}
|
|
}
|
|
if !compareUnorderedStringArrays(expectedNotices, notices) {
|
|
t.Errorf("effective notice files mismatch for module %q: expected %q, found %q", moduleName, expectedNotices, notices)
|
|
}
|
|
}
|
|
}
|
|
|
|
func checkEffectiveKinds(t *testing.T, result *TestResult, effectiveKinds map[string][]string) {
|
|
actualKinds := make(map[string][]string)
|
|
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
if _, ok := m.(*licenseModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*licenseKindModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*packageModule); ok {
|
|
return
|
|
}
|
|
module, ok := m.(Module)
|
|
if !ok {
|
|
t.Errorf("%q not a module", m.Name())
|
|
return
|
|
}
|
|
base := module.base()
|
|
if base == nil {
|
|
return
|
|
}
|
|
actualKinds[m.Name()] = base.commonProperties.Effective_license_kinds
|
|
})
|
|
|
|
for moduleName, expectedKinds := range effectiveKinds {
|
|
kinds, ok := actualKinds[moduleName]
|
|
if !ok {
|
|
kinds = []string{}
|
|
}
|
|
if !compareUnorderedStringArrays(expectedKinds, kinds) {
|
|
t.Errorf("effective license kinds mismatch for module %q: expected %q, found %q", moduleName, expectedKinds, kinds)
|
|
}
|
|
}
|
|
}
|
|
|
|
func checkEffectiveConditions(t *testing.T, result *TestResult, effectiveConditions map[string][]string) {
|
|
actualConditions := make(map[string][]string)
|
|
result.Context.Context.VisitAllModules(func(m blueprint.Module) {
|
|
if _, ok := m.(*licenseModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*licenseKindModule); ok {
|
|
return
|
|
}
|
|
if _, ok := m.(*packageModule); ok {
|
|
return
|
|
}
|
|
module, ok := m.(Module)
|
|
if !ok {
|
|
t.Errorf("%q not a module", m.Name())
|
|
return
|
|
}
|
|
base := module.base()
|
|
if base == nil {
|
|
return
|
|
}
|
|
actualConditions[m.Name()] = base.commonProperties.Effective_license_conditions
|
|
})
|
|
|
|
for moduleName, expectedConditions := range effectiveConditions {
|
|
conditions, ok := actualConditions[moduleName]
|
|
if !ok {
|
|
conditions = []string{}
|
|
}
|
|
if !compareUnorderedStringArrays(expectedConditions, conditions) {
|
|
t.Errorf("effective license conditions mismatch for module %q: expected %q, found %q", moduleName, expectedConditions, conditions)
|
|
}
|
|
}
|
|
}
|
|
|
|
func compareUnorderedStringArrays(expected, actual []string) bool {
|
|
if len(expected) != len(actual) {
|
|
return false
|
|
}
|
|
s := make(map[string]int)
|
|
for _, v := range expected {
|
|
s[v] += 1
|
|
}
|
|
for _, v := range actual {
|
|
c, ok := s[v]
|
|
if !ok {
|
|
return false
|
|
}
|
|
if c < 1 {
|
|
return false
|
|
}
|
|
s[v] -= 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
type mockLicensesBadProperties struct {
|
|
Visibility []string
|
|
}
|
|
|
|
type mockLicensesBadModule struct {
|
|
ModuleBase
|
|
DefaultableModuleBase
|
|
properties mockLicensesBadProperties
|
|
}
|
|
|
|
func newMockLicensesBadModule() Module {
|
|
m := &mockLicensesBadModule{}
|
|
|
|
base := m.base()
|
|
m.AddProperties(&base.nameProperties, &m.properties)
|
|
|
|
base.generalProperties = m.GetProperties()
|
|
base.customizableProperties = m.GetProperties()
|
|
|
|
// The default_visibility property needs to be checked and parsed by the visibility module during
|
|
// its checking and parsing phases so make it the primary visibility property.
|
|
setPrimaryVisibilityProperty(m, "visibility", &m.properties.Visibility)
|
|
|
|
initAndroidModuleBase(m)
|
|
InitDefaultableModule(m)
|
|
|
|
return m
|
|
}
|
|
|
|
func (m *mockLicensesBadModule) GenerateAndroidBuildActions(ModuleContext) {
|
|
}
|
|
|
|
type mockLicensesLibraryProperties struct {
|
|
Deps []string
|
|
}
|
|
|
|
type mockLicensesLibraryModule struct {
|
|
ModuleBase
|
|
DefaultableModuleBase
|
|
properties mockLicensesLibraryProperties
|
|
}
|
|
|
|
func newMockLicensesLibraryModule() Module {
|
|
m := &mockLicensesLibraryModule{}
|
|
m.AddProperties(&m.properties)
|
|
InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
|
|
InitDefaultableModule(m)
|
|
return m
|
|
}
|
|
|
|
type dependencyLicensesTag struct {
|
|
blueprint.BaseDependencyTag
|
|
name string
|
|
}
|
|
|
|
func (j *mockLicensesLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
|
|
ctx.AddVariationDependencies(nil, dependencyLicensesTag{name: "mockdeps"}, j.properties.Deps...)
|
|
}
|
|
|
|
func (p *mockLicensesLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
|
|
}
|
|
|
|
type mockLicensesDefaults struct {
|
|
ModuleBase
|
|
DefaultsModuleBase
|
|
}
|
|
|
|
func defaultsLicensesFactory() Module {
|
|
m := &mockLicensesDefaults{}
|
|
InitDefaultsModule(m)
|
|
return m
|
|
}
|