blob: 928bca609073b1a8d0611eb0a442031fb1e0de08 [file] [log] [blame]
Colin Cross7e0eaf12017-05-05 16:16:24 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18 "reflect"
Colin Cross18c46802019-09-24 22:19:02 -070019 "strconv"
Colin Cross7e0eaf12017-05-05 16:16:24 -070020 "testing"
Colin Cross18c46802019-09-24 22:19:02 -070021
22 "github.com/google/blueprint/proptools"
Colin Cross7e0eaf12017-05-05 16:16:24 -070023)
24
25type printfIntoPropertyTestCase struct {
26 in string
27 val interface{}
28 out string
29 err bool
30}
31
32var printfIntoPropertyTestCases = []printfIntoPropertyTestCase{
33 {
34 in: "%d",
35 val: 0,
36 out: "0",
37 },
38 {
39 in: "%d",
40 val: 1,
41 out: "1",
42 },
43 {
44 in: "%d",
45 val: 2,
46 out: "2",
47 },
48 {
49 in: "%d",
50 val: false,
51 out: "0",
52 },
53 {
54 in: "%d",
55 val: true,
56 out: "1",
57 },
58 {
59 in: "%d",
60 val: -1,
61 out: "-1",
62 },
63
64 {
65 in: "-DA=%d",
66 val: 1,
67 out: "-DA=1",
68 },
69 {
70 in: "-DA=%du",
71 val: 1,
72 out: "-DA=1u",
73 },
74 {
75 in: "-DA=%s",
76 val: "abc",
77 out: "-DA=abc",
78 },
79 {
80 in: `-DA="%s"`,
81 val: "abc",
82 out: `-DA="abc"`,
83 },
84
85 {
86 in: "%%",
87 err: true,
88 },
89 {
90 in: "%d%s",
91 err: true,
92 },
93 {
94 in: "%d,%s",
95 err: true,
96 },
97 {
98 in: "%d",
99 val: "",
100 err: true,
101 },
102 {
103 in: "%d",
104 val: 1.5,
105 err: true,
106 },
107 {
108 in: "%f",
109 val: 1.5,
110 err: true,
111 },
112}
113
114func TestPrintfIntoProperty(t *testing.T) {
115 for _, testCase := range printfIntoPropertyTestCases {
116 s := testCase.in
117 v := reflect.ValueOf(&s).Elem()
118 err := printfIntoProperty(v, testCase.val)
119 if err != nil && !testCase.err {
120 t.Errorf("unexpected error %s", err)
121 } else if err == nil && testCase.err {
122 t.Errorf("expected error")
123 } else if err == nil && v.String() != testCase.out {
124 t.Errorf("expected %q got %q", testCase.out, v.String())
125 }
126 }
127}
Colin Cross18c46802019-09-24 22:19:02 -0700128
129type testProductVariableModule struct {
130 ModuleBase
131}
132
133func (m *testProductVariableModule) GenerateAndroidBuildActions(ctx ModuleContext) {
134}
135
136var testProductVariableProperties = struct {
137 Product_variables struct {
138 Eng struct {
139 Srcs []string
140 Cflags []string
141 }
142 }
143}{}
144
145func testProductVariableModuleFactoryFactory(props interface{}) func() Module {
146 return func() Module {
147 m := &testProductVariableModule{}
148 clonedProps := proptools.CloneProperties(reflect.ValueOf(props)).Interface()
149 m.AddProperties(clonedProps)
150
Colin Cross9d34f352019-11-22 16:03:51 -0800151 // Set a default soongConfigVariableProperties, this will be used as the input to the property struct filter
Colin Cross18c46802019-09-24 22:19:02 -0700152 // for this test module.
153 m.variableProperties = testProductVariableProperties
154 InitAndroidModule(m)
155 return m
156 }
157}
158
159func TestProductVariables(t *testing.T) {
Colin Cross18c46802019-09-24 22:19:02 -0700160 // Test that a module can use one product variable even if it doesn't have all the properties
161 // supported by that product variable.
162 bp := `
163 module1 {
164 name: "foo",
165 product_variables: {
166 eng: {
167 srcs: ["foo.c"],
168 },
169 },
170 }
171 module2 {
172 name: "bar",
173 product_variables: {
174 eng: {
175 cflags: ["-DBAR"],
176 },
177 },
178 }
179
180 module3 {
181 name: "baz",
182 }
183 `
Colin Cross18c46802019-09-24 22:19:02 -0700184
Paul Duffin30ac3e72021-03-20 00:36:14 +0000185 GroupFixturePreparers(
Paul Duffin4bb2b212021-03-16 23:36:24 +0000186 FixtureModifyProductVariables(func(variables FixtureProductVariables) {
187 variables.Eng = proptools.BoolPtr(true)
188 }),
189 FixtureRegisterWithContext(func(ctx RegistrationContext) {
190 // A module type that has a srcs property but not a cflags property.
191 ctx.RegisterModuleType("module1", testProductVariableModuleFactoryFactory(&struct {
192 Srcs []string
193 }{}))
194 // A module type that has a cflags property but not a srcs property.
195 ctx.RegisterModuleType("module2", testProductVariableModuleFactoryFactory(&struct {
196 Cflags []string
197 }{}))
198 // A module type that does not have any properties that match product_variables.
199 ctx.RegisterModuleType("module3", testProductVariableModuleFactoryFactory(&struct {
200 Foo []string
201 }{}))
202 ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
203 ctx.BottomUp("variable", VariableMutator).Parallel()
204 })
205 }),
206 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000207 ).RunTest(t)
Colin Cross18c46802019-09-24 22:19:02 -0700208}
209
Colin Crosseabaedd2020-02-06 17:01:55 -0800210var testProductVariableDefaultsProperties = struct {
211 Product_variables struct {
212 Eng struct {
213 Foo []string
214 Bar []string
215 }
216 }
217}{}
218
219type productVariablesDefaultsTestProperties struct {
220 Foo []string
221}
222
223type productVariablesDefaultsTestProperties2 struct {
224 Foo []string
225 Bar []string
226}
227
228type productVariablesDefaultsTestModule struct {
229 ModuleBase
230 DefaultableModuleBase
231 properties productVariablesDefaultsTestProperties
232}
233
234func (d *productVariablesDefaultsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
235 ctx.Build(pctx, BuildParams{
236 Rule: Touch,
237 Output: PathForModuleOut(ctx, "out"),
238 })
239}
240
241func productVariablesDefaultsTestModuleFactory() Module {
242 module := &productVariablesDefaultsTestModule{}
243 module.AddProperties(&module.properties)
244 module.variableProperties = testProductVariableDefaultsProperties
245 InitAndroidModule(module)
246 InitDefaultableModule(module)
247 return module
248}
249
250type productVariablesDefaultsTestDefaults struct {
251 ModuleBase
252 DefaultsModuleBase
253}
254
255func productVariablesDefaultsTestDefaultsFactory() Module {
256 defaults := &productVariablesDefaultsTestDefaults{}
257 defaults.AddProperties(&productVariablesDefaultsTestProperties{})
258 defaults.AddProperties(&productVariablesDefaultsTestProperties2{})
259 defaults.variableProperties = testProductVariableDefaultsProperties
260 InitDefaultsModule(defaults)
261 return defaults
262}
263
264// Test a defaults module that supports more product variable properties than the target module.
265func TestProductVariablesDefaults(t *testing.T) {
266 bp := `
267 defaults {
268 name: "defaults",
269 product_variables: {
270 eng: {
271 foo: ["product_variable_defaults"],
272 bar: ["product_variable_defaults"],
273 },
274 },
275 foo: ["defaults"],
276 bar: ["defaults"],
277 }
278
279 test {
280 name: "foo",
281 defaults: ["defaults"],
282 foo: ["module"],
283 product_variables: {
284 eng: {
285 foo: ["product_variable_module"],
286 },
287 },
288 }
289 `
290
Paul Duffin30ac3e72021-03-20 00:36:14 +0000291 result := GroupFixturePreparers(
Paul Duffin4bb2b212021-03-16 23:36:24 +0000292 FixtureModifyProductVariables(func(variables FixtureProductVariables) {
293 variables.Eng = boolPtr(true)
294 }),
295 PrepareForTestWithDefaults,
296 PrepareForTestWithVariables,
297 FixtureRegisterWithContext(func(ctx RegistrationContext) {
298 ctx.RegisterModuleType("test", productVariablesDefaultsTestModuleFactory)
299 ctx.RegisterModuleType("defaults", productVariablesDefaultsTestDefaultsFactory)
300 }),
301 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000302 ).RunTest(t)
Colin Crosseabaedd2020-02-06 17:01:55 -0800303
Paul Duffin4bb2b212021-03-16 23:36:24 +0000304 foo := result.ModuleForTests("foo", "").Module().(*productVariablesDefaultsTestModule)
Colin Crosseabaedd2020-02-06 17:01:55 -0800305
306 want := []string{"defaults", "module", "product_variable_defaults", "product_variable_module"}
Paul Duffin4bb2b212021-03-16 23:36:24 +0000307 AssertDeepEquals(t, "foo", want, foo.properties.Foo)
Colin Crosseabaedd2020-02-06 17:01:55 -0800308}
309
Colin Cross18c46802019-09-24 22:19:02 -0700310func BenchmarkSliceToTypeArray(b *testing.B) {
311 for _, n := range []int{1, 2, 4, 8, 100} {
312 var propStructs []interface{}
313 for i := 0; i < n; i++ {
314 propStructs = append(propStructs, &struct {
315 A *string
316 B string
317 }{})
318
319 }
320 b.Run(strconv.Itoa(n), func(b *testing.B) {
321 for i := 0; i < b.N; i++ {
322 _ = sliceToTypeArray(propStructs)
323 }
324 })
325 }
326}