799962789a
Previously, there was no way to prevent a module from overriding a value provided by a defaults. That made it difficult to ensure consistency across modules, e.g. for modules that use framework-module-defaults. This change adds the protected_properties property to defaults modules which allows a default module to list those properties that should not be changed by a module applying those defaults. Properties can either be listed explicitly by name, or it can just be a single "*" in which case all properties that are set on the defaults will be protected. Bug: 230841626 Test: m nothing Change-Id: Ibb0e482c2856a572437e7818466f41c5493baf33
303 lines
7.2 KiB
Go
303 lines
7.2 KiB
Go
// Copyright 2019 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package android
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
type defaultsTestProperties struct {
|
|
Foo []string
|
|
Bar []string
|
|
Nested struct {
|
|
Fizz *bool
|
|
}
|
|
Other struct {
|
|
Buzz *string
|
|
}
|
|
}
|
|
|
|
type defaultsTestModule struct {
|
|
ModuleBase
|
|
DefaultableModuleBase
|
|
properties defaultsTestProperties
|
|
}
|
|
|
|
func (d *defaultsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|
ctx.Build(pctx, BuildParams{
|
|
Rule: Touch,
|
|
Output: PathForModuleOut(ctx, "out"),
|
|
})
|
|
}
|
|
|
|
func defaultsTestModuleFactory() Module {
|
|
module := &defaultsTestModule{}
|
|
module.AddProperties(&module.properties)
|
|
InitAndroidModule(module)
|
|
InitDefaultableModule(module)
|
|
return module
|
|
}
|
|
|
|
type defaultsTestDefaults struct {
|
|
ModuleBase
|
|
DefaultsModuleBase
|
|
}
|
|
|
|
func defaultsTestDefaultsFactory() Module {
|
|
defaults := &defaultsTestDefaults{}
|
|
defaults.AddProperties(&defaultsTestProperties{})
|
|
InitDefaultsModule(defaults)
|
|
return defaults
|
|
}
|
|
|
|
var prepareForDefaultsTest = GroupFixturePreparers(
|
|
PrepareForTestWithDefaults,
|
|
FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
|
ctx.RegisterModuleType("test", defaultsTestModuleFactory)
|
|
ctx.RegisterModuleType("defaults", defaultsTestDefaultsFactory)
|
|
}),
|
|
)
|
|
|
|
func TestDefaults(t *testing.T) {
|
|
bp := `
|
|
defaults {
|
|
name: "transitive",
|
|
foo: ["transitive"],
|
|
}
|
|
|
|
defaults {
|
|
name: "defaults",
|
|
defaults: ["transitive"],
|
|
foo: ["defaults"],
|
|
}
|
|
|
|
test {
|
|
name: "foo",
|
|
defaults: ["defaults"],
|
|
foo: ["module"],
|
|
}
|
|
`
|
|
|
|
result := GroupFixturePreparers(
|
|
prepareForDefaultsTest,
|
|
FixtureWithRootAndroidBp(bp),
|
|
).RunTest(t)
|
|
|
|
foo := result.Module("foo", "").(*defaultsTestModule)
|
|
|
|
AssertDeepEquals(t, "foo", []string{"transitive", "defaults", "module"}, foo.properties.Foo)
|
|
}
|
|
|
|
func TestDefaultsAllowMissingDependencies(t *testing.T) {
|
|
bp := `
|
|
defaults {
|
|
name: "defaults",
|
|
defaults: ["missing"],
|
|
foo: ["defaults"],
|
|
}
|
|
|
|
test {
|
|
name: "missing_defaults",
|
|
defaults: ["missing"],
|
|
foo: ["module"],
|
|
}
|
|
|
|
test {
|
|
name: "missing_transitive_defaults",
|
|
defaults: ["defaults"],
|
|
foo: ["module"],
|
|
}
|
|
`
|
|
|
|
result := GroupFixturePreparers(
|
|
prepareForDefaultsTest,
|
|
PrepareForTestWithAllowMissingDependencies,
|
|
FixtureWithRootAndroidBp(bp),
|
|
).RunTest(t)
|
|
|
|
missingDefaults := result.ModuleForTests("missing_defaults", "").Output("out")
|
|
missingTransitiveDefaults := result.ModuleForTests("missing_transitive_defaults", "").Output("out")
|
|
|
|
AssertSame(t, "missing_defaults rule", ErrorRule, missingDefaults.Rule)
|
|
|
|
AssertStringEquals(t, "missing_defaults", "module missing_defaults missing dependencies: missing\n", missingDefaults.Args["error"])
|
|
|
|
// TODO: missing transitive defaults is currently not handled
|
|
_ = missingTransitiveDefaults
|
|
}
|
|
|
|
func TestProtectedProperties_ProtectedPropertyNotSet(t *testing.T) {
|
|
bp := `
|
|
defaults {
|
|
name: "transitive",
|
|
protected_properties: ["foo"],
|
|
}
|
|
`
|
|
|
|
GroupFixturePreparers(
|
|
prepareForDefaultsTest,
|
|
FixtureWithRootAndroidBp(bp),
|
|
).ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(
|
|
"module \"transitive\": foo: is not set; protected properties must be explicitly set")).
|
|
RunTest(t)
|
|
}
|
|
|
|
func TestProtectedProperties_ProtectedPropertyNotLeaf(t *testing.T) {
|
|
bp := `
|
|
defaults {
|
|
name: "transitive",
|
|
protected_properties: ["nested"],
|
|
nested: {
|
|
fizz: true,
|
|
},
|
|
}
|
|
`
|
|
|
|
GroupFixturePreparers(
|
|
prepareForDefaultsTest,
|
|
FixtureWithRootAndroidBp(bp),
|
|
).ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(
|
|
`\Qmodule "transitive": nested: property is not supported by this module type "defaults"\E`)).
|
|
RunTest(t)
|
|
}
|
|
|
|
// TestProtectedProperties_ApplyDefaults makes sure that the protected_properties property has
|
|
// defaults applied.
|
|
func TestProtectedProperties_HasDefaultsApplied(t *testing.T) {
|
|
|
|
bp := `
|
|
defaults {
|
|
name: "transitive",
|
|
protected_properties: ["foo"],
|
|
foo: ["transitive"],
|
|
}
|
|
|
|
defaults {
|
|
name: "defaults",
|
|
defaults: ["transitive"],
|
|
protected_properties: ["bar"],
|
|
bar: ["defaults"],
|
|
}
|
|
`
|
|
|
|
result := GroupFixturePreparers(
|
|
prepareForDefaultsTest,
|
|
FixtureWithRootAndroidBp(bp),
|
|
).RunTest(t)
|
|
|
|
defaults := result.Module("defaults", "").(DefaultsModule)
|
|
AssertDeepEquals(t, "defaults protected properties", []string{"foo", "bar"}, defaults.protectedProperties())
|
|
}
|
|
|
|
// TestProtectedProperties_ProtectAllProperties makes sure that protected_properties: ["*"] protects
|
|
// all properties.
|
|
func TestProtectedProperties_ProtectAllProperties(t *testing.T) {
|
|
|
|
bp := `
|
|
defaults {
|
|
name: "transitive",
|
|
protected_properties: ["other.buzz"],
|
|
other: {
|
|
buzz: "transitive",
|
|
},
|
|
}
|
|
|
|
defaults {
|
|
name: "defaults",
|
|
defaults: ["transitive"],
|
|
visibility: ["//visibility:private"],
|
|
protected_properties: ["*"],
|
|
foo: ["other"],
|
|
bar: ["defaults"],
|
|
nested: {
|
|
fizz: true,
|
|
}
|
|
}
|
|
`
|
|
|
|
result := GroupFixturePreparers(
|
|
prepareForDefaultsTest,
|
|
FixtureWithRootAndroidBp(bp),
|
|
).RunTest(t)
|
|
|
|
defaults := result.Module("defaults", "").(DefaultsModule)
|
|
AssertDeepEquals(t, "defaults protected properties", []string{"other.buzz", "bar", "foo", "nested.fizz"},
|
|
defaults.protectedProperties())
|
|
}
|
|
|
|
func TestProtectedProperties_DetectedOverride(t *testing.T) {
|
|
bp := `
|
|
defaults {
|
|
name: "defaults",
|
|
protected_properties: ["foo", "nested.fizz"],
|
|
foo: ["defaults"],
|
|
nested: {
|
|
fizz: true,
|
|
},
|
|
}
|
|
|
|
test {
|
|
name: "foo",
|
|
defaults: ["defaults"],
|
|
foo: ["module"],
|
|
nested: {
|
|
fizz: false,
|
|
},
|
|
}
|
|
`
|
|
|
|
GroupFixturePreparers(
|
|
prepareForDefaultsTest,
|
|
FixtureWithRootAndroidBp(bp),
|
|
).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(
|
|
[]string{
|
|
`\Qmodule "foo": attempts to append ["module"] to protected property "foo"'s value of ["defaults"] defined in module "defaults"\E`,
|
|
`\Qmodule "foo": attempts to override protected property "nested.fizz" defined in module "defaults" with a different value (override true with false) so removing the property may necessitate other changes.\E`,
|
|
})).RunTest(t)
|
|
}
|
|
|
|
func TestProtectedProperties_DefaultsConflict(t *testing.T) {
|
|
bp := `
|
|
defaults {
|
|
name: "defaults1",
|
|
protected_properties: ["other.buzz"],
|
|
other: {
|
|
buzz: "value",
|
|
},
|
|
}
|
|
|
|
defaults {
|
|
name: "defaults2",
|
|
protected_properties: ["other.buzz"],
|
|
other: {
|
|
buzz: "another",
|
|
},
|
|
}
|
|
|
|
test {
|
|
name: "foo",
|
|
defaults: ["defaults1", "defaults2"],
|
|
}
|
|
`
|
|
|
|
GroupFixturePreparers(
|
|
prepareForDefaultsTest,
|
|
FixtureWithRootAndroidBp(bp),
|
|
).ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(
|
|
`\Qmodule "foo": has conflicting default values for protected property "other.buzz":
|
|
defaults module "defaults1" provides value "value"
|
|
defaults module "defaults2" provides value "another"\E`,
|
|
)).RunTest(t)
|
|
}
|