3c298a3725
Bug: 181070625 Test: m nothing Change-Id: I0b7c8613fcb7bc4e96908e391f1e46a9168f2507
863 lines
22 KiB
Go
863 lines
22 KiB
Go
package android
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/blueprint"
|
|
)
|
|
|
|
var licensesTests = []struct {
|
|
name string
|
|
fs map[string][]byte
|
|
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) {
|
|
ctx, errs := testLicenses(buildDir, test.fs)
|
|
|
|
CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
|
|
|
|
if test.effectiveLicenses != nil {
|
|
checkEffectiveLicenses(t, ctx, test.effectiveLicenses)
|
|
}
|
|
|
|
if test.effectivePackage != nil {
|
|
checkEffectivePackage(t, ctx, test.effectivePackage)
|
|
}
|
|
|
|
if test.effectiveNotices != nil {
|
|
checkEffectiveNotices(t, ctx, test.effectiveNotices)
|
|
}
|
|
|
|
if test.effectiveKinds != nil {
|
|
checkEffectiveKinds(t, ctx, test.effectiveKinds)
|
|
}
|
|
|
|
if test.effectiveConditions != nil {
|
|
checkEffectiveConditions(t, ctx, test.effectiveConditions)
|
|
}
|
|
|
|
if test.effectiveInheritedLicenses != nil {
|
|
checkEffectiveInheritedLicenses(t, ctx, test.effectiveInheritedLicenses)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func checkEffectiveLicenses(t *testing.T, ctx *TestContext, effectiveLicenses map[string][]string) {
|
|
actualLicenses := make(map[string][]string)
|
|
ctx.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, ctx *TestContext, effectiveInheritedLicenses map[string][]string) {
|
|
actualLicenses := make(map[string][]string)
|
|
ctx.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
|
|
}
|
|
ctx.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, ctx *TestContext, effectivePackage map[string]string) {
|
|
actualPackage := make(map[string]string)
|
|
ctx.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, ctx *TestContext, effectiveNotices map[string][]string) {
|
|
actualNotices := make(map[string][]string)
|
|
ctx.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
|
|
})
|
|
|
|
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, ctx *TestContext, effectiveKinds map[string][]string) {
|
|
actualKinds := make(map[string][]string)
|
|
ctx.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, ctx *TestContext, effectiveConditions map[string][]string) {
|
|
actualConditions := make(map[string][]string)
|
|
ctx.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
|
|
}
|
|
|
|
func testLicenses(buildDir string, fs map[string][]byte) (*TestContext, []error) {
|
|
|
|
// Create a new config per test as licenses information is stored in the config.
|
|
env := make(map[string]string)
|
|
env["ANDROID_REQUIRE_LICENSES"] = "1"
|
|
config := TestArchConfig(buildDir, env, "", fs)
|
|
|
|
ctx := NewTestArchContext(config)
|
|
ctx.RegisterModuleType("mock_bad_module", newMockLicensesBadModule)
|
|
ctx.RegisterModuleType("mock_library", newMockLicensesLibraryModule)
|
|
ctx.RegisterModuleType("mock_defaults", defaultsLicensesFactory)
|
|
|
|
// Order of the following method calls is significant.
|
|
RegisterPackageBuildComponents(ctx)
|
|
registerTestPrebuiltBuildComponents(ctx)
|
|
RegisterLicenseKindBuildComponents(ctx)
|
|
RegisterLicenseBuildComponents(ctx)
|
|
ctx.PreArchMutators(RegisterVisibilityRuleChecker)
|
|
ctx.PreArchMutators(RegisterLicensesPackageMapper)
|
|
ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
|
|
ctx.PreArchMutators(RegisterLicensesPropertyGatherer)
|
|
ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
|
|
ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
|
|
ctx.PostDepsMutators(RegisterLicensesDependencyChecker)
|
|
ctx.Register()
|
|
|
|
_, errs := ctx.ParseBlueprintsFiles(".")
|
|
if len(errs) > 0 {
|
|
return ctx, errs
|
|
}
|
|
|
|
_, errs = ctx.PrepareBuildActions(config)
|
|
return ctx, errs
|
|
}
|
|
|
|
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
|
|
}
|