From eabaedd520f8b25573c831693d064e5916245746 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 6 Feb 2020 17:01:55 -0800 Subject: Fix product variables in defaults modules Product variables structs are generated at runtime to contain only the properties that apply to the current module. Defaults modules always contained all product variable properties. Defaults modules apply their properties to the target module using proptools.PrependProperties, which prepends structs that have matching types. Filtered property structs had a different type and were dropped. Even after adding filtering to the defaults product variable properties, defaults modules may contain more property structs than the target module they are applied to, so the product variables struct for the defaults module could contain more fields than the product variables struct for the target module. Use proptools.PrependMatchingProperties when applying defaults of product variables instead, which will apply matching properties across types. Test: defaults_test.go Test: variable_test.go Change-Id: I281bdefef92053457a3b7b65383493a4e7d999df --- android/variable_test.go | 111 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) (limited to 'android/variable_test.go') diff --git a/android/variable_test.go b/android/variable_test.go index cde2b1ac9..9cafedd50 100644 --- a/android/variable_test.go +++ b/android/variable_test.go @@ -171,7 +171,7 @@ func TestProductVariables(t *testing.T) { Foo []string }{})) ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { - ctx.BottomUp("variable", variableMutator).Parallel() + ctx.BottomUp("variable", VariableMutator).Parallel() }) // Test that a module can use one product variable even if it doesn't have all the properties @@ -209,6 +209,115 @@ func TestProductVariables(t *testing.T) { FailIfErrored(t, errs) } +var testProductVariableDefaultsProperties = struct { + Product_variables struct { + Eng struct { + Foo []string + Bar []string + } + } +}{} + +type productVariablesDefaultsTestProperties struct { + Foo []string +} + +type productVariablesDefaultsTestProperties2 struct { + Foo []string + Bar []string +} + +type productVariablesDefaultsTestModule struct { + ModuleBase + DefaultableModuleBase + properties productVariablesDefaultsTestProperties +} + +func (d *productVariablesDefaultsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { + ctx.Build(pctx, BuildParams{ + Rule: Touch, + Output: PathForModuleOut(ctx, "out"), + }) +} + +func productVariablesDefaultsTestModuleFactory() Module { + module := &productVariablesDefaultsTestModule{} + module.AddProperties(&module.properties) + module.variableProperties = testProductVariableDefaultsProperties + InitAndroidModule(module) + InitDefaultableModule(module) + return module +} + +type productVariablesDefaultsTestDefaults struct { + ModuleBase + DefaultsModuleBase +} + +func productVariablesDefaultsTestDefaultsFactory() Module { + defaults := &productVariablesDefaultsTestDefaults{} + defaults.AddProperties(&productVariablesDefaultsTestProperties{}) + defaults.AddProperties(&productVariablesDefaultsTestProperties2{}) + defaults.variableProperties = testProductVariableDefaultsProperties + InitDefaultsModule(defaults) + return defaults +} + +// Test a defaults module that supports more product variable properties than the target module. +func TestProductVariablesDefaults(t *testing.T) { + bp := ` + defaults { + name: "defaults", + product_variables: { + eng: { + foo: ["product_variable_defaults"], + bar: ["product_variable_defaults"], + }, + }, + foo: ["defaults"], + bar: ["defaults"], + } + + test { + name: "foo", + defaults: ["defaults"], + foo: ["module"], + product_variables: { + eng: { + foo: ["product_variable_module"], + }, + }, + } + ` + + config := TestConfig(buildDir, nil, bp, nil) + config.TestProductVariables.Eng = boolPtr(true) + + ctx := NewTestContext() + + ctx.RegisterModuleType("test", productVariablesDefaultsTestModuleFactory) + ctx.RegisterModuleType("defaults", productVariablesDefaultsTestDefaultsFactory) + + ctx.PreArchMutators(RegisterDefaultsPreArchMutators) + ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { + ctx.BottomUp("variable", VariableMutator).Parallel() + }) + + ctx.Register(config) + + _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) + FailIfErrored(t, errs) + _, errs = ctx.PrepareBuildActions(config) + FailIfErrored(t, errs) + + foo := ctx.ModuleForTests("foo", "").Module().(*productVariablesDefaultsTestModule) + + want := []string{"defaults", "module", "product_variable_defaults", "product_variable_module"} + if g, w := foo.properties.Foo, want; !reflect.DeepEqual(g, w) { + t.Errorf("expected foo %q, got %q", w, g) + } +} + func BenchmarkSliceToTypeArray(b *testing.B) { for _, n := range []int{1, 2, 4, 8, 100} { var propStructs []interface{} -- cgit v1.2.3-59-g8ed1b