blob: 04aafdeee4f93de2d12b183fb8903b3406e1da2d [file] [log] [blame]
Colin Cross9d34f352019-11-22 16:03:51 -08001// Copyright 2019 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 (
Paul Duffinf1e6a042023-01-09 15:43:29 +000018 "fmt"
Colin Cross9d34f352019-11-22 16:03:51 -080019 "testing"
20)
21
Liz Kammerdbd48092020-09-21 22:24:17 +000022type soongConfigTestDefaultsModule struct {
23 ModuleBase
24 DefaultsModuleBase
25}
26
27func soongConfigTestDefaultsModuleFactory() Module {
28 m := &soongConfigTestDefaultsModule{}
29 m.AddProperties(&soongConfigTestModuleProperties{})
30 InitDefaultsModule(m)
31 return m
32}
33
Colin Cross9d34f352019-11-22 16:03:51 -080034type soongConfigTestModule struct {
35 ModuleBase
Liz Kammerdbd48092020-09-21 22:24:17 +000036 DefaultableModuleBase
Inseob Kim81b00a82023-05-15 18:06:31 +090037 props soongConfigTestModuleProperties
38 outputPath ModuleOutPath
Colin Cross9d34f352019-11-22 16:03:51 -080039}
40
41type soongConfigTestModuleProperties struct {
42 Cflags []string
43}
44
45func soongConfigTestModuleFactory() Module {
46 m := &soongConfigTestModule{}
47 m.AddProperties(&m.props)
48 InitAndroidModule(m)
Liz Kammerdbd48092020-09-21 22:24:17 +000049 InitDefaultableModule(m)
Colin Cross9d34f352019-11-22 16:03:51 -080050 return m
51}
52
Inseob Kim81b00a82023-05-15 18:06:31 +090053func (t *soongConfigTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
54 t.outputPath = PathForModuleOut(ctx, "test")
55}
Colin Cross9d34f352019-11-22 16:03:51 -080056
Paul Duffin32299982023-01-09 14:02:06 +000057var prepareForSoongConfigTestModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
58 ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
59 ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
60})
61
Colin Cross9d34f352019-11-22 16:03:51 -080062func TestSoongConfigModule(t *testing.T) {
63 configBp := `
64 soong_config_module_type {
Liz Kammerdbd48092020-09-21 22:24:17 +000065 name: "acme_test",
66 module_type: "test",
Colin Cross9d34f352019-11-22 16:03:51 -080067 config_namespace: "acme",
Liz Kammer432bd592020-12-16 12:42:02 -080068 variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
Liz Kammerbdce0df2021-10-15 13:34:27 -040069 bool_variables: ["feature2", "unused_feature", "always_true"],
Liz Kammer432bd592020-12-16 12:42:02 -080070 value_variables: ["size", "unused_size"],
Liz Kammerdbd48092020-09-21 22:24:17 +000071 properties: ["cflags", "srcs", "defaults"],
Colin Cross9d34f352019-11-22 16:03:51 -080072 }
73
74 soong_config_string_variable {
75 name: "board",
Liz Kammer432bd592020-12-16 12:42:02 -080076 values: ["soc_a", "soc_b", "soc_c", "soc_d"],
77 }
78
79 soong_config_string_variable {
80 name: "unused_string_var",
81 values: ["a", "b"],
Colin Cross9d34f352019-11-22 16:03:51 -080082 }
83
84 soong_config_bool_variable {
85 name: "feature1",
86 }
87
88 soong_config_bool_variable {
Colin Cross3beeb1e2020-02-05 16:27:47 -080089 name: "FEATURE3",
Colin Cross9d34f352019-11-22 16:03:51 -080090 }
91 `
92
93 importBp := `
94 soong_config_module_type_import {
95 from: "SoongConfig.bp",
Liz Kammerdbd48092020-09-21 22:24:17 +000096 module_types: ["acme_test"],
Colin Cross9d34f352019-11-22 16:03:51 -080097 }
98 `
99
100 bp := `
Liz Kammerdbd48092020-09-21 22:24:17 +0000101 test_defaults {
102 name: "foo_defaults",
103 cflags: ["DEFAULT"],
104 }
105
106 acme_test {
Colin Cross9d34f352019-11-22 16:03:51 -0800107 name: "foo",
108 cflags: ["-DGENERIC"],
Liz Kammerdbd48092020-09-21 22:24:17 +0000109 defaults: ["foo_defaults"],
Colin Cross9d34f352019-11-22 16:03:51 -0800110 soong_config_variables: {
111 board: {
112 soc_a: {
113 cflags: ["-DSOC_A"],
114 },
115 soc_b: {
116 cflags: ["-DSOC_B"],
117 },
Liz Kammer432bd592020-12-16 12:42:02 -0800118 soc_c: {},
119 conditions_default: {
120 cflags: ["-DSOC_CONDITIONS_DEFAULT"],
121 },
Colin Cross9d34f352019-11-22 16:03:51 -0800122 },
Dan Willemsenb0935db2020-03-23 19:42:18 -0700123 size: {
124 cflags: ["-DSIZE=%s"],
Liz Kammer432bd592020-12-16 12:42:02 -0800125 conditions_default: {
126 cflags: ["-DSIZE=CONDITIONS_DEFAULT"],
127 },
Dan Willemsenb0935db2020-03-23 19:42:18 -0700128 },
Colin Cross9d34f352019-11-22 16:03:51 -0800129 feature1: {
Liz Kammer432bd592020-12-16 12:42:02 -0800130 conditions_default: {
131 cflags: ["-DF1_CONDITIONS_DEFAULT"],
132 },
Colin Cross9d34f352019-11-22 16:03:51 -0800133 cflags: ["-DFEATURE1"],
134 },
135 feature2: {
136 cflags: ["-DFEATURE2"],
Liz Kammer432bd592020-12-16 12:42:02 -0800137 conditions_default: {
138 cflags: ["-DF2_CONDITIONS_DEFAULT"],
139 },
Colin Cross9d34f352019-11-22 16:03:51 -0800140 },
Colin Cross3beeb1e2020-02-05 16:27:47 -0800141 FEATURE3: {
Colin Cross9d34f352019-11-22 16:03:51 -0800142 cflags: ["-DFEATURE3"],
143 },
144 },
145 }
Liz Kammerdbd48092020-09-21 22:24:17 +0000146
147 test_defaults {
148 name: "foo_defaults_a",
149 cflags: ["DEFAULT_A"],
150 }
151
152 test_defaults {
153 name: "foo_defaults_b",
154 cflags: ["DEFAULT_B"],
155 }
156
Liz Kammerbdce0df2021-10-15 13:34:27 -0400157 test_defaults {
158 name: "foo_defaults_always_true",
159 cflags: ["DEFAULT_ALWAYS_TRUE"],
160 }
161
Liz Kammerdbd48092020-09-21 22:24:17 +0000162 acme_test {
163 name: "foo_with_defaults",
164 cflags: ["-DGENERIC"],
165 defaults: ["foo_defaults"],
166 soong_config_variables: {
167 board: {
168 soc_a: {
169 cflags: ["-DSOC_A"],
170 defaults: ["foo_defaults_a"],
171 },
172 soc_b: {
173 cflags: ["-DSOC_B"],
174 defaults: ["foo_defaults_b"],
175 },
Liz Kammer432bd592020-12-16 12:42:02 -0800176 soc_c: {},
Liz Kammerdbd48092020-09-21 22:24:17 +0000177 },
178 size: {
179 cflags: ["-DSIZE=%s"],
180 },
181 feature1: {
182 cflags: ["-DFEATURE1"],
183 },
184 feature2: {
185 cflags: ["-DFEATURE2"],
186 },
187 FEATURE3: {
188 cflags: ["-DFEATURE3"],
189 },
Liz Kammerbdce0df2021-10-15 13:34:27 -0400190 always_true: {
191 defaults: ["foo_defaults_always_true"],
192 conditions_default: {
193 // verify that conditions_default is skipped if the
194 // soong config variable is true by specifying a
195 // non-existent module in conditions_default
196 defaults: ["//nonexistent:defaults"],
197 }
198 },
Liz Kammerdbd48092020-09-21 22:24:17 +0000199 },
200 }
Colin Cross9d34f352019-11-22 16:03:51 -0800201 `
202
Paul Duffin791302b2021-03-16 22:45:14 +0000203 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
204 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
205 variables.VendorVars = vars
206 })
207 }
208
209 run := func(t *testing.T, bp string, fs MockFS) {
Liz Kammer432bd592020-12-16 12:42:02 -0800210 testCases := []struct {
211 name string
Paul Duffin791302b2021-03-16 22:45:14 +0000212 preparer FixturePreparer
Liz Kammer432bd592020-12-16 12:42:02 -0800213 fooExpectedFlags []string
214 fooDefaultsExpectedFlags []string
215 }{
216 {
217 name: "withValues",
Paul Duffin791302b2021-03-16 22:45:14 +0000218 preparer: fixtureForVendorVars(map[string]map[string]string{
219 "acme": {
Liz Kammer432bd592020-12-16 12:42:02 -0800220 "board": "soc_a",
221 "size": "42",
222 "feature1": "true",
223 "feature2": "false",
224 // FEATURE3 unset
225 "unused_feature": "true", // unused
226 "unused_size": "1", // unused
227 "unused_string_var": "a", // unused
Liz Kammerbdce0df2021-10-15 13:34:27 -0400228 "always_true": "true",
Liz Kammer432bd592020-12-16 12:42:02 -0800229 },
230 }),
231 fooExpectedFlags: []string{
232 "DEFAULT",
233 "-DGENERIC",
234 "-DF2_CONDITIONS_DEFAULT",
235 "-DSIZE=42",
236 "-DSOC_A",
237 "-DFEATURE1",
238 },
239 fooDefaultsExpectedFlags: []string{
240 "DEFAULT_A",
Liz Kammerbdce0df2021-10-15 13:34:27 -0400241 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800242 "DEFAULT",
243 "-DGENERIC",
244 "-DSIZE=42",
245 "-DSOC_A",
246 "-DFEATURE1",
247 },
248 },
249 {
250 name: "empty_prop_for_string_var",
Paul Duffin791302b2021-03-16 22:45:14 +0000251 preparer: fixtureForVendorVars(map[string]map[string]string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400252 "acme": {
253 "board": "soc_c",
254 "always_true": "true",
255 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800256 fooExpectedFlags: []string{
257 "DEFAULT",
258 "-DGENERIC",
259 "-DF2_CONDITIONS_DEFAULT",
260 "-DSIZE=CONDITIONS_DEFAULT",
261 "-DF1_CONDITIONS_DEFAULT",
262 },
263 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400264 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800265 "DEFAULT",
266 "-DGENERIC",
267 },
268 },
269 {
270 name: "unused_string_var",
Paul Duffin791302b2021-03-16 22:45:14 +0000271 preparer: fixtureForVendorVars(map[string]map[string]string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400272 "acme": {
273 "board": "soc_d",
274 "always_true": "true",
275 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800276 fooExpectedFlags: []string{
277 "DEFAULT",
278 "-DGENERIC",
279 "-DF2_CONDITIONS_DEFAULT",
280 "-DSIZE=CONDITIONS_DEFAULT",
281 "-DSOC_CONDITIONS_DEFAULT", // foo does not contain a prop "soc_d", so we use the default
282 "-DF1_CONDITIONS_DEFAULT",
283 },
284 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400285 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800286 "DEFAULT",
287 "-DGENERIC",
288 },
289 },
Colin Cross9d34f352019-11-22 16:03:51 -0800290
Liz Kammer432bd592020-12-16 12:42:02 -0800291 {
Liz Kammerbdce0df2021-10-15 13:34:27 -0400292 name: "conditions_default",
293 preparer: fixtureForVendorVars(map[string]map[string]string{
294 "acme": {
295 "always_true": "true",
296 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800297 fooExpectedFlags: []string{
298 "DEFAULT",
299 "-DGENERIC",
300 "-DF2_CONDITIONS_DEFAULT",
301 "-DSIZE=CONDITIONS_DEFAULT",
302 "-DSOC_CONDITIONS_DEFAULT",
303 "-DF1_CONDITIONS_DEFAULT",
304 },
305 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400306 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800307 "DEFAULT",
308 "-DGENERIC",
309 },
Colin Cross9d34f352019-11-22 16:03:51 -0800310 },
311 }
312
Liz Kammer432bd592020-12-16 12:42:02 -0800313 for _, tc := range testCases {
Paul Duffin791302b2021-03-16 22:45:14 +0000314 t.Run(tc.name, func(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000315 result := GroupFixturePreparers(
Paul Duffin791302b2021-03-16 22:45:14 +0000316 tc.preparer,
317 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000318 PrepareForTestWithSoongConfigModuleBuildComponents,
319 prepareForSoongConfigTestModule,
Paul Duffin791302b2021-03-16 22:45:14 +0000320 fs.AddToFixture(),
321 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000322 ).RunTest(t)
Colin Cross9d34f352019-11-22 16:03:51 -0800323
Paul Duffin791302b2021-03-16 22:45:14 +0000324 foo := result.ModuleForTests("foo", "").Module().(*soongConfigTestModule)
325 AssertDeepEquals(t, "foo cflags", tc.fooExpectedFlags, foo.props.Cflags)
Colin Cross9d34f352019-11-22 16:03:51 -0800326
Paul Duffin791302b2021-03-16 22:45:14 +0000327 fooDefaults := result.ModuleForTests("foo_with_defaults", "").Module().(*soongConfigTestModule)
328 AssertDeepEquals(t, "foo_with_defaults cflags", tc.fooDefaultsExpectedFlags, fooDefaults.props.Cflags)
329 })
Liz Kammerdbd48092020-09-21 22:24:17 +0000330 }
Colin Cross9d34f352019-11-22 16:03:51 -0800331 }
332
333 t.Run("single file", func(t *testing.T) {
334 run(t, configBp+bp, nil)
335 })
336
337 t.Run("import", func(t *testing.T) {
338 run(t, importBp+bp, map[string][]byte{
339 "SoongConfig.bp": []byte(configBp),
340 })
341 })
342}
Liz Kammer432bd592020-12-16 12:42:02 -0800343
Liz Kammer0fc1e132021-07-15 12:34:59 -0400344func TestNonExistentPropertyInSoongConfigModule(t *testing.T) {
345 bp := `
346 soong_config_module_type {
347 name: "acme_test",
348 module_type: "test",
349 config_namespace: "acme",
350 bool_variables: ["feature1"],
351 properties: ["made_up_property"],
352 }
353
354 acme_test {
355 name: "foo",
356 cflags: ["-DGENERIC"],
357 soong_config_variables: {
358 feature1: {
359 made_up_property: true,
360 },
361 },
362 }
363 `
364
365 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
366 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
367 variables.VendorVars = vars
368 })
369 }
370
371 GroupFixturePreparers(
372 fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
373 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000374 PrepareForTestWithSoongConfigModuleBuildComponents,
375 prepareForSoongConfigTestModule,
Liz Kammer0fc1e132021-07-15 12:34:59 -0400376 FixtureWithRootAndroidBp(bp),
377 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
Zi Wangfe152e32023-10-30 14:42:44 -0700378 `unrecognized property "soong_config_variables.feature1.made_up_property`,
Liz Kammer0fc1e132021-07-15 12:34:59 -0400379 })).RunTest(t)
380}
381
Liz Kammer72beb342022-02-03 08:42:10 -0500382func TestDuplicateStringValueInSoongConfigStringVariable(t *testing.T) {
383 bp := `
384 soong_config_string_variable {
385 name: "board",
386 values: ["soc_a", "soc_b", "soc_c", "soc_a"],
387 }
388
389 soong_config_module_type {
390 name: "acme_test",
391 module_type: "test",
392 config_namespace: "acme",
393 variables: ["board"],
394 properties: ["cflags", "srcs", "defaults"],
395 }
396 `
397
398 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
399 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
400 variables.VendorVars = vars
401 })
402 }
403
404 GroupFixturePreparers(
405 fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
406 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000407 PrepareForTestWithSoongConfigModuleBuildComponents,
408 prepareForSoongConfigTestModule,
Liz Kammer72beb342022-02-03 08:42:10 -0500409 FixtureWithRootAndroidBp(bp),
410 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
411 // TODO(b/171232169): improve the error message for non-existent properties
412 `Android.bp: soong_config_string_variable: values property error: duplicate value: "soc_a"`,
413 })).RunTest(t)
414}
415
Paul Duffinf1e6a042023-01-09 15:43:29 +0000416type soongConfigTestSingletonModule struct {
417 SingletonModuleBase
418 props soongConfigTestSingletonModuleProperties
419}
Liz Kammer432bd592020-12-16 12:42:02 -0800420
Paul Duffinf1e6a042023-01-09 15:43:29 +0000421type soongConfigTestSingletonModuleProperties struct {
422 Fragments []struct {
423 Apex string
424 Module string
425 }
426}
Liz Kammer432bd592020-12-16 12:42:02 -0800427
Paul Duffinf1e6a042023-01-09 15:43:29 +0000428func soongConfigTestSingletonModuleFactory() SingletonModule {
429 m := &soongConfigTestSingletonModule{}
430 m.AddProperties(&m.props)
431 InitAndroidModule(m)
432 return m
433}
434
435func (t *soongConfigTestSingletonModule) GenerateAndroidBuildActions(ModuleContext) {}
436
437func (t *soongConfigTestSingletonModule) GenerateSingletonBuildActions(SingletonContext) {}
438
439var prepareForSoongConfigTestSingletonModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
440 ctx.RegisterSingletonModuleType("test_singleton", soongConfigTestSingletonModuleFactory)
441})
442
443func TestSoongConfigModuleSingletonModule(t *testing.T) {
444 bp := `
445 soong_config_module_type {
446 name: "acme_test_singleton",
447 module_type: "test_singleton",
448 config_namespace: "acme",
449 bool_variables: ["coyote"],
450 properties: ["fragments"],
451 }
452
453 acme_test_singleton {
454 name: "wiley",
455 fragments: [
456 {
457 apex: "com.android.acme",
458 module: "road-runner",
459 },
460 ],
461 soong_config_variables: {
462 coyote: {
463 fragments: [
464 {
465 apex: "com.android.acme",
466 module: "wiley",
467 },
468 ],
469 },
470 },
471 }
472 `
473
474 for _, test := range []struct {
475 coyote bool
476 expectedFragments string
477 }{
478 {
479 coyote: false,
480 expectedFragments: "[{Apex:com.android.acme Module:road-runner}]",
481 },
482 {
483 coyote: true,
484 expectedFragments: "[{Apex:com.android.acme Module:road-runner} {Apex:com.android.acme Module:wiley}]",
485 },
486 } {
487 t.Run(fmt.Sprintf("coyote:%t", test.coyote), func(t *testing.T) {
Paul Duffine8b47682023-01-09 15:42:57 +0000488 result := GroupFixturePreparers(
Paul Duffinf1e6a042023-01-09 15:43:29 +0000489 PrepareForTestWithSoongConfigModuleBuildComponents,
490 prepareForSoongConfigTestSingletonModule,
491 FixtureWithRootAndroidBp(bp),
492 FixtureModifyProductVariables(func(variables FixtureProductVariables) {
493 variables.VendorVars = map[string]map[string]string{
494 "acme": {
495 "coyote": fmt.Sprintf("%t", test.coyote),
496 },
497 }
498 }),
Paul Duffine8b47682023-01-09 15:42:57 +0000499 ).RunTest(t)
500
501 // Make sure that the singleton was created.
502 result.SingletonForTests("test_singleton")
503 m := result.ModuleForTests("wiley", "").module.(*soongConfigTestSingletonModule)
504 AssertStringEquals(t, "fragments", test.expectedFragments, fmt.Sprintf("%+v", m.props.Fragments))
Paul Duffinf1e6a042023-01-09 15:43:29 +0000505 })
506 }
Liz Kammer432bd592020-12-16 12:42:02 -0800507}