blob: a6b2c51c67a2cca735c6c3693aa27dce82dab273 [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"
Inseob Kim81b00a82023-05-15 18:06:31 +090019 "path/filepath"
Colin Cross9d34f352019-11-22 16:03:51 -080020 "testing"
21)
22
Liz Kammerdbd48092020-09-21 22:24:17 +000023type soongConfigTestDefaultsModule struct {
24 ModuleBase
25 DefaultsModuleBase
26}
27
28func soongConfigTestDefaultsModuleFactory() Module {
29 m := &soongConfigTestDefaultsModule{}
30 m.AddProperties(&soongConfigTestModuleProperties{})
31 InitDefaultsModule(m)
32 return m
33}
34
Colin Cross9d34f352019-11-22 16:03:51 -080035type soongConfigTestModule struct {
36 ModuleBase
Liz Kammerdbd48092020-09-21 22:24:17 +000037 DefaultableModuleBase
Inseob Kim81b00a82023-05-15 18:06:31 +090038 props soongConfigTestModuleProperties
39 outputPath ModuleOutPath
Colin Cross9d34f352019-11-22 16:03:51 -080040}
41
42type soongConfigTestModuleProperties struct {
43 Cflags []string
44}
45
46func soongConfigTestModuleFactory() Module {
47 m := &soongConfigTestModule{}
48 m.AddProperties(&m.props)
49 InitAndroidModule(m)
Liz Kammerdbd48092020-09-21 22:24:17 +000050 InitDefaultableModule(m)
Colin Cross9d34f352019-11-22 16:03:51 -080051 return m
52}
53
Inseob Kim81b00a82023-05-15 18:06:31 +090054func (t *soongConfigTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
55 t.outputPath = PathForModuleOut(ctx, "test")
56}
Colin Cross9d34f352019-11-22 16:03:51 -080057
Paul Duffin32299982023-01-09 14:02:06 +000058var prepareForSoongConfigTestModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
59 ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
60 ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
61})
62
Colin Cross9d34f352019-11-22 16:03:51 -080063func TestSoongConfigModule(t *testing.T) {
64 configBp := `
65 soong_config_module_type {
Liz Kammerdbd48092020-09-21 22:24:17 +000066 name: "acme_test",
67 module_type: "test",
Colin Cross9d34f352019-11-22 16:03:51 -080068 config_namespace: "acme",
Liz Kammer432bd592020-12-16 12:42:02 -080069 variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
Liz Kammerbdce0df2021-10-15 13:34:27 -040070 bool_variables: ["feature2", "unused_feature", "always_true"],
Liz Kammer432bd592020-12-16 12:42:02 -080071 value_variables: ["size", "unused_size"],
Liz Kammerdbd48092020-09-21 22:24:17 +000072 properties: ["cflags", "srcs", "defaults"],
Colin Cross9d34f352019-11-22 16:03:51 -080073 }
74
75 soong_config_string_variable {
76 name: "board",
Liz Kammer432bd592020-12-16 12:42:02 -080077 values: ["soc_a", "soc_b", "soc_c", "soc_d"],
78 }
79
80 soong_config_string_variable {
81 name: "unused_string_var",
82 values: ["a", "b"],
Colin Cross9d34f352019-11-22 16:03:51 -080083 }
84
85 soong_config_bool_variable {
86 name: "feature1",
87 }
88
89 soong_config_bool_variable {
Colin Cross3beeb1e2020-02-05 16:27:47 -080090 name: "FEATURE3",
Colin Cross9d34f352019-11-22 16:03:51 -080091 }
92 `
93
94 importBp := `
95 soong_config_module_type_import {
96 from: "SoongConfig.bp",
Liz Kammerdbd48092020-09-21 22:24:17 +000097 module_types: ["acme_test"],
Colin Cross9d34f352019-11-22 16:03:51 -080098 }
99 `
100
101 bp := `
Liz Kammerdbd48092020-09-21 22:24:17 +0000102 test_defaults {
103 name: "foo_defaults",
104 cflags: ["DEFAULT"],
105 }
106
107 acme_test {
Colin Cross9d34f352019-11-22 16:03:51 -0800108 name: "foo",
109 cflags: ["-DGENERIC"],
Liz Kammerdbd48092020-09-21 22:24:17 +0000110 defaults: ["foo_defaults"],
Colin Cross9d34f352019-11-22 16:03:51 -0800111 soong_config_variables: {
112 board: {
113 soc_a: {
114 cflags: ["-DSOC_A"],
115 },
116 soc_b: {
117 cflags: ["-DSOC_B"],
118 },
Liz Kammer432bd592020-12-16 12:42:02 -0800119 soc_c: {},
120 conditions_default: {
121 cflags: ["-DSOC_CONDITIONS_DEFAULT"],
122 },
Colin Cross9d34f352019-11-22 16:03:51 -0800123 },
Dan Willemsenb0935db2020-03-23 19:42:18 -0700124 size: {
125 cflags: ["-DSIZE=%s"],
Liz Kammer432bd592020-12-16 12:42:02 -0800126 conditions_default: {
127 cflags: ["-DSIZE=CONDITIONS_DEFAULT"],
128 },
Dan Willemsenb0935db2020-03-23 19:42:18 -0700129 },
Colin Cross9d34f352019-11-22 16:03:51 -0800130 feature1: {
Liz Kammer432bd592020-12-16 12:42:02 -0800131 conditions_default: {
132 cflags: ["-DF1_CONDITIONS_DEFAULT"],
133 },
Colin Cross9d34f352019-11-22 16:03:51 -0800134 cflags: ["-DFEATURE1"],
135 },
136 feature2: {
137 cflags: ["-DFEATURE2"],
Liz Kammer432bd592020-12-16 12:42:02 -0800138 conditions_default: {
139 cflags: ["-DF2_CONDITIONS_DEFAULT"],
140 },
Colin Cross9d34f352019-11-22 16:03:51 -0800141 },
Colin Cross3beeb1e2020-02-05 16:27:47 -0800142 FEATURE3: {
Colin Cross9d34f352019-11-22 16:03:51 -0800143 cflags: ["-DFEATURE3"],
144 },
145 },
146 }
Liz Kammerdbd48092020-09-21 22:24:17 +0000147
148 test_defaults {
149 name: "foo_defaults_a",
150 cflags: ["DEFAULT_A"],
151 }
152
153 test_defaults {
154 name: "foo_defaults_b",
155 cflags: ["DEFAULT_B"],
156 }
157
Liz Kammerbdce0df2021-10-15 13:34:27 -0400158 test_defaults {
159 name: "foo_defaults_always_true",
160 cflags: ["DEFAULT_ALWAYS_TRUE"],
161 }
162
Liz Kammerdbd48092020-09-21 22:24:17 +0000163 acme_test {
164 name: "foo_with_defaults",
165 cflags: ["-DGENERIC"],
166 defaults: ["foo_defaults"],
167 soong_config_variables: {
168 board: {
169 soc_a: {
170 cflags: ["-DSOC_A"],
171 defaults: ["foo_defaults_a"],
172 },
173 soc_b: {
174 cflags: ["-DSOC_B"],
175 defaults: ["foo_defaults_b"],
176 },
Liz Kammer432bd592020-12-16 12:42:02 -0800177 soc_c: {},
Liz Kammerdbd48092020-09-21 22:24:17 +0000178 },
179 size: {
180 cflags: ["-DSIZE=%s"],
181 },
182 feature1: {
183 cflags: ["-DFEATURE1"],
184 },
185 feature2: {
186 cflags: ["-DFEATURE2"],
187 },
188 FEATURE3: {
189 cflags: ["-DFEATURE3"],
190 },
Liz Kammerbdce0df2021-10-15 13:34:27 -0400191 always_true: {
192 defaults: ["foo_defaults_always_true"],
193 conditions_default: {
194 // verify that conditions_default is skipped if the
195 // soong config variable is true by specifying a
196 // non-existent module in conditions_default
197 defaults: ["//nonexistent:defaults"],
198 }
199 },
Liz Kammerdbd48092020-09-21 22:24:17 +0000200 },
201 }
Colin Cross9d34f352019-11-22 16:03:51 -0800202 `
203
Paul Duffin791302b2021-03-16 22:45:14 +0000204 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
205 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
206 variables.VendorVars = vars
207 })
208 }
209
210 run := func(t *testing.T, bp string, fs MockFS) {
Liz Kammer432bd592020-12-16 12:42:02 -0800211 testCases := []struct {
212 name string
Paul Duffin791302b2021-03-16 22:45:14 +0000213 preparer FixturePreparer
Liz Kammer432bd592020-12-16 12:42:02 -0800214 fooExpectedFlags []string
215 fooDefaultsExpectedFlags []string
216 }{
217 {
218 name: "withValues",
Paul Duffin791302b2021-03-16 22:45:14 +0000219 preparer: fixtureForVendorVars(map[string]map[string]string{
220 "acme": {
Liz Kammer432bd592020-12-16 12:42:02 -0800221 "board": "soc_a",
222 "size": "42",
223 "feature1": "true",
224 "feature2": "false",
225 // FEATURE3 unset
226 "unused_feature": "true", // unused
227 "unused_size": "1", // unused
228 "unused_string_var": "a", // unused
Liz Kammerbdce0df2021-10-15 13:34:27 -0400229 "always_true": "true",
Liz Kammer432bd592020-12-16 12:42:02 -0800230 },
231 }),
232 fooExpectedFlags: []string{
233 "DEFAULT",
234 "-DGENERIC",
235 "-DF2_CONDITIONS_DEFAULT",
236 "-DSIZE=42",
237 "-DSOC_A",
238 "-DFEATURE1",
239 },
240 fooDefaultsExpectedFlags: []string{
241 "DEFAULT_A",
Liz Kammerbdce0df2021-10-15 13:34:27 -0400242 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800243 "DEFAULT",
244 "-DGENERIC",
245 "-DSIZE=42",
246 "-DSOC_A",
247 "-DFEATURE1",
248 },
249 },
250 {
251 name: "empty_prop_for_string_var",
Paul Duffin791302b2021-03-16 22:45:14 +0000252 preparer: fixtureForVendorVars(map[string]map[string]string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400253 "acme": {
254 "board": "soc_c",
255 "always_true": "true",
256 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800257 fooExpectedFlags: []string{
258 "DEFAULT",
259 "-DGENERIC",
260 "-DF2_CONDITIONS_DEFAULT",
261 "-DSIZE=CONDITIONS_DEFAULT",
262 "-DF1_CONDITIONS_DEFAULT",
263 },
264 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400265 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800266 "DEFAULT",
267 "-DGENERIC",
268 },
269 },
270 {
271 name: "unused_string_var",
Paul Duffin791302b2021-03-16 22:45:14 +0000272 preparer: fixtureForVendorVars(map[string]map[string]string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400273 "acme": {
274 "board": "soc_d",
275 "always_true": "true",
276 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800277 fooExpectedFlags: []string{
278 "DEFAULT",
279 "-DGENERIC",
280 "-DF2_CONDITIONS_DEFAULT",
281 "-DSIZE=CONDITIONS_DEFAULT",
282 "-DSOC_CONDITIONS_DEFAULT", // foo does not contain a prop "soc_d", so we use the default
283 "-DF1_CONDITIONS_DEFAULT",
284 },
285 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400286 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800287 "DEFAULT",
288 "-DGENERIC",
289 },
290 },
Colin Cross9d34f352019-11-22 16:03:51 -0800291
Liz Kammer432bd592020-12-16 12:42:02 -0800292 {
Liz Kammerbdce0df2021-10-15 13:34:27 -0400293 name: "conditions_default",
294 preparer: fixtureForVendorVars(map[string]map[string]string{
295 "acme": {
296 "always_true": "true",
297 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800298 fooExpectedFlags: []string{
299 "DEFAULT",
300 "-DGENERIC",
301 "-DF2_CONDITIONS_DEFAULT",
302 "-DSIZE=CONDITIONS_DEFAULT",
303 "-DSOC_CONDITIONS_DEFAULT",
304 "-DF1_CONDITIONS_DEFAULT",
305 },
306 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400307 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800308 "DEFAULT",
309 "-DGENERIC",
310 },
Colin Cross9d34f352019-11-22 16:03:51 -0800311 },
312 }
313
Liz Kammer432bd592020-12-16 12:42:02 -0800314 for _, tc := range testCases {
Paul Duffin791302b2021-03-16 22:45:14 +0000315 t.Run(tc.name, func(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000316 result := GroupFixturePreparers(
Paul Duffin791302b2021-03-16 22:45:14 +0000317 tc.preparer,
318 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000319 PrepareForTestWithSoongConfigModuleBuildComponents,
320 prepareForSoongConfigTestModule,
Paul Duffin791302b2021-03-16 22:45:14 +0000321 fs.AddToFixture(),
322 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000323 ).RunTest(t)
Colin Cross9d34f352019-11-22 16:03:51 -0800324
Paul Duffin791302b2021-03-16 22:45:14 +0000325 foo := result.ModuleForTests("foo", "").Module().(*soongConfigTestModule)
326 AssertDeepEquals(t, "foo cflags", tc.fooExpectedFlags, foo.props.Cflags)
Colin Cross9d34f352019-11-22 16:03:51 -0800327
Paul Duffin791302b2021-03-16 22:45:14 +0000328 fooDefaults := result.ModuleForTests("foo_with_defaults", "").Module().(*soongConfigTestModule)
329 AssertDeepEquals(t, "foo_with_defaults cflags", tc.fooDefaultsExpectedFlags, fooDefaults.props.Cflags)
330 })
Liz Kammerdbd48092020-09-21 22:24:17 +0000331 }
Colin Cross9d34f352019-11-22 16:03:51 -0800332 }
333
334 t.Run("single file", func(t *testing.T) {
335 run(t, configBp+bp, nil)
336 })
337
338 t.Run("import", func(t *testing.T) {
339 run(t, importBp+bp, map[string][]byte{
340 "SoongConfig.bp": []byte(configBp),
341 })
342 })
343}
Liz Kammer432bd592020-12-16 12:42:02 -0800344
Liz Kammer0fc1e132021-07-15 12:34:59 -0400345func TestNonExistentPropertyInSoongConfigModule(t *testing.T) {
346 bp := `
347 soong_config_module_type {
348 name: "acme_test",
349 module_type: "test",
350 config_namespace: "acme",
351 bool_variables: ["feature1"],
352 properties: ["made_up_property"],
353 }
354
355 acme_test {
356 name: "foo",
357 cflags: ["-DGENERIC"],
358 soong_config_variables: {
359 feature1: {
360 made_up_property: true,
361 },
362 },
363 }
364 `
365
366 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
367 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
368 variables.VendorVars = vars
369 })
370 }
371
372 GroupFixturePreparers(
373 fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
374 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000375 PrepareForTestWithSoongConfigModuleBuildComponents,
376 prepareForSoongConfigTestModule,
Liz Kammer0fc1e132021-07-15 12:34:59 -0400377 FixtureWithRootAndroidBp(bp),
378 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
Zi Wangfe152e32023-10-30 14:42:44 -0700379 `unrecognized property "soong_config_variables.feature1.made_up_property`,
Liz Kammer0fc1e132021-07-15 12:34:59 -0400380 })).RunTest(t)
381}
382
Liz Kammer72beb342022-02-03 08:42:10 -0500383func TestDuplicateStringValueInSoongConfigStringVariable(t *testing.T) {
384 bp := `
385 soong_config_string_variable {
386 name: "board",
387 values: ["soc_a", "soc_b", "soc_c", "soc_a"],
388 }
389
390 soong_config_module_type {
391 name: "acme_test",
392 module_type: "test",
393 config_namespace: "acme",
394 variables: ["board"],
395 properties: ["cflags", "srcs", "defaults"],
396 }
397 `
398
399 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
400 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
401 variables.VendorVars = vars
402 })
403 }
404
405 GroupFixturePreparers(
406 fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
407 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000408 PrepareForTestWithSoongConfigModuleBuildComponents,
409 prepareForSoongConfigTestModule,
Liz Kammer72beb342022-02-03 08:42:10 -0500410 FixtureWithRootAndroidBp(bp),
411 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
412 // TODO(b/171232169): improve the error message for non-existent properties
413 `Android.bp: soong_config_string_variable: values property error: duplicate value: "soc_a"`,
414 })).RunTest(t)
415}
416
Paul Duffinf1e6a042023-01-09 15:43:29 +0000417type soongConfigTestSingletonModule struct {
418 SingletonModuleBase
419 props soongConfigTestSingletonModuleProperties
420}
Liz Kammer432bd592020-12-16 12:42:02 -0800421
Paul Duffinf1e6a042023-01-09 15:43:29 +0000422type soongConfigTestSingletonModuleProperties struct {
423 Fragments []struct {
424 Apex string
425 Module string
426 }
427}
Liz Kammer432bd592020-12-16 12:42:02 -0800428
Paul Duffinf1e6a042023-01-09 15:43:29 +0000429func soongConfigTestSingletonModuleFactory() SingletonModule {
430 m := &soongConfigTestSingletonModule{}
431 m.AddProperties(&m.props)
432 InitAndroidModule(m)
433 return m
434}
435
436func (t *soongConfigTestSingletonModule) GenerateAndroidBuildActions(ModuleContext) {}
437
438func (t *soongConfigTestSingletonModule) GenerateSingletonBuildActions(SingletonContext) {}
439
440var prepareForSoongConfigTestSingletonModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
441 ctx.RegisterSingletonModuleType("test_singleton", soongConfigTestSingletonModuleFactory)
442})
443
444func TestSoongConfigModuleSingletonModule(t *testing.T) {
445 bp := `
446 soong_config_module_type {
447 name: "acme_test_singleton",
448 module_type: "test_singleton",
449 config_namespace: "acme",
450 bool_variables: ["coyote"],
451 properties: ["fragments"],
452 }
453
454 acme_test_singleton {
455 name: "wiley",
456 fragments: [
457 {
458 apex: "com.android.acme",
459 module: "road-runner",
460 },
461 ],
462 soong_config_variables: {
463 coyote: {
464 fragments: [
465 {
466 apex: "com.android.acme",
467 module: "wiley",
468 },
469 ],
470 },
471 },
472 }
473 `
474
475 for _, test := range []struct {
476 coyote bool
477 expectedFragments string
478 }{
479 {
480 coyote: false,
481 expectedFragments: "[{Apex:com.android.acme Module:road-runner}]",
482 },
483 {
484 coyote: true,
485 expectedFragments: "[{Apex:com.android.acme Module:road-runner} {Apex:com.android.acme Module:wiley}]",
486 },
487 } {
488 t.Run(fmt.Sprintf("coyote:%t", test.coyote), func(t *testing.T) {
Paul Duffine8b47682023-01-09 15:42:57 +0000489 result := GroupFixturePreparers(
Paul Duffinf1e6a042023-01-09 15:43:29 +0000490 PrepareForTestWithSoongConfigModuleBuildComponents,
491 prepareForSoongConfigTestSingletonModule,
492 FixtureWithRootAndroidBp(bp),
493 FixtureModifyProductVariables(func(variables FixtureProductVariables) {
494 variables.VendorVars = map[string]map[string]string{
495 "acme": {
496 "coyote": fmt.Sprintf("%t", test.coyote),
497 },
498 }
499 }),
Paul Duffine8b47682023-01-09 15:42:57 +0000500 ).RunTest(t)
501
502 // Make sure that the singleton was created.
503 result.SingletonForTests("test_singleton")
504 m := result.ModuleForTests("wiley", "").module.(*soongConfigTestSingletonModule)
505 AssertStringEquals(t, "fragments", test.expectedFragments, fmt.Sprintf("%+v", m.props.Fragments))
Paul Duffinf1e6a042023-01-09 15:43:29 +0000506 })
507 }
Liz Kammer432bd592020-12-16 12:42:02 -0800508}
Inseob Kim81b00a82023-05-15 18:06:31 +0900509
510func TestSoongConfigModuleTrace(t *testing.T) {
511 bp := `
512 soong_config_module_type {
513 name: "acme_test",
514 module_type: "test",
515 config_namespace: "acme",
516 variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
517 bool_variables: ["feature2", "unused_feature", "always_true"],
518 value_variables: ["size", "unused_size"],
519 properties: ["cflags", "srcs", "defaults"],
520 }
521
522 soong_config_module_type {
523 name: "acme_test_defaults",
524 module_type: "test_defaults",
525 config_namespace: "acme",
526 variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
527 bool_variables: ["feature2", "unused_feature", "always_true"],
528 value_variables: ["size", "unused_size"],
529 properties: ["cflags", "srcs", "defaults"],
530 }
531
532 soong_config_string_variable {
533 name: "board",
534 values: ["soc_a", "soc_b", "soc_c"],
535 }
536
537 soong_config_string_variable {
538 name: "unused_string_var",
539 values: ["a", "b"],
540 }
541
542 soong_config_bool_variable {
543 name: "feature1",
544 }
545
546 soong_config_bool_variable {
547 name: "FEATURE3",
548 }
549
550 test_defaults {
551 name: "test_defaults",
552 cflags: ["DEFAULT"],
553 }
554
555 test {
556 name: "normal",
557 defaults: ["test_defaults"],
558 }
559
560 acme_test {
561 name: "board_1",
562 defaults: ["test_defaults"],
563 soong_config_variables: {
564 board: {
565 soc_a: {
566 cflags: ["-DSOC_A"],
567 },
568 },
569 },
570 }
571
572 acme_test {
573 name: "board_2",
574 defaults: ["test_defaults"],
575 soong_config_variables: {
576 board: {
577 soc_a: {
578 cflags: ["-DSOC_A"],
579 },
580 },
581 },
582 }
583
584 acme_test {
585 name: "size",
586 defaults: ["test_defaults"],
587 soong_config_variables: {
588 size: {
589 cflags: ["-DSIZE=%s"],
590 },
591 },
592 }
593
594 acme_test {
595 name: "board_and_size",
596 defaults: ["test_defaults"],
597 soong_config_variables: {
598 board: {
599 soc_a: {
600 cflags: ["-DSOC_A"],
601 },
602 },
603 size: {
604 cflags: ["-DSIZE=%s"],
605 },
606 },
607 }
608
609 acme_test_defaults {
610 name: "board_defaults",
611 soong_config_variables: {
612 board: {
613 soc_a: {
614 cflags: ["-DSOC_A"],
615 },
616 },
617 },
618 }
619
620 acme_test_defaults {
621 name: "size_defaults",
622 soong_config_variables: {
623 size: {
624 cflags: ["-DSIZE=%s"],
625 },
626 },
627 }
628
629 test {
630 name: "board_and_size_with_defaults",
631 defaults: ["board_defaults", "size_defaults"],
632 }
633 `
634
635 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
636 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
637 variables.VendorVars = vars
638 })
639 }
640
641 preparer := fixtureForVendorVars(map[string]map[string]string{
642 "acme": {
643 "board": "soc_a",
644 "size": "42",
645 "feature1": "true",
646 "feature2": "false",
647 // FEATURE3 unset
648 "unused_feature": "true", // unused
649 "unused_size": "1", // unused
650 "unused_string_var": "a", // unused
651 "always_true": "true",
652 },
653 })
654
655 t.Run("soong config trace hash", func(t *testing.T) {
656 result := GroupFixturePreparers(
657 preparer,
658 PrepareForTestWithDefaults,
659 PrepareForTestWithSoongConfigModuleBuildComponents,
660 prepareForSoongConfigTestModule,
661 FixtureRegisterWithContext(func(ctx RegistrationContext) {
662 ctx.FinalDepsMutators(registerSoongConfigTraceMutator)
663 }),
664 FixtureWithRootAndroidBp(bp),
665 ).RunTest(t)
666
667 // Hashes of modules not using soong config should be empty
668 normal := result.ModuleForTests("normal", "").Module().(*soongConfigTestModule)
669 AssertDeepEquals(t, "normal hash", normal.base().commonProperties.SoongConfigTraceHash, "")
670 AssertDeepEquals(t, "normal hash out", normal.outputPath.RelativeToTop().String(), "out/soong/.intermediates/normal/test")
671
672 board1 := result.ModuleForTests("board_1", "").Module().(*soongConfigTestModule)
673 board2 := result.ModuleForTests("board_2", "").Module().(*soongConfigTestModule)
674 size := result.ModuleForTests("size", "").Module().(*soongConfigTestModule)
675
676 // Trace mutator sets soong config trace hash correctly
677 board1Hash := board1.base().commonProperties.SoongConfigTrace.hash()
678 board1Output := board1.outputPath.RelativeToTop().String()
679 AssertDeepEquals(t, "board hash calc", board1Hash, board1.base().commonProperties.SoongConfigTraceHash)
680 AssertDeepEquals(t, "board hash path", board1Output, filepath.Join("out/soong/.intermediates/board_1", board1Hash, "test"))
681
682 sizeHash := size.base().commonProperties.SoongConfigTrace.hash()
683 sizeOutput := size.outputPath.RelativeToTop().String()
684 AssertDeepEquals(t, "size hash calc", sizeHash, size.base().commonProperties.SoongConfigTraceHash)
685 AssertDeepEquals(t, "size hash path", sizeOutput, filepath.Join("out/soong/.intermediates/size", sizeHash, "test"))
686
687 // Trace should be identical for modules using the same set of variables
688 AssertDeepEquals(t, "board trace", board1.base().commonProperties.SoongConfigTrace, board2.base().commonProperties.SoongConfigTrace)
689 AssertDeepEquals(t, "board hash", board1.base().commonProperties.SoongConfigTraceHash, board2.base().commonProperties.SoongConfigTraceHash)
690
691 // Trace hash should be different for different sets of soong variables
692 AssertBoolEquals(t, "board hash not equal to size hash", board1.base().commonProperties.SoongConfigTraceHash == size.commonProperties.SoongConfigTraceHash, false)
693
694 boardSize := result.ModuleForTests("board_and_size", "").Module().(*soongConfigTestModule)
695 boardSizeDefaults := result.ModuleForTests("board_and_size_with_defaults", "").Module()
696
697 // Trace should propagate
698 AssertDeepEquals(t, "board_size hash calc", boardSize.base().commonProperties.SoongConfigTrace.hash(), boardSize.base().commonProperties.SoongConfigTraceHash)
699 AssertDeepEquals(t, "board_size trace", boardSize.base().commonProperties.SoongConfigTrace, boardSizeDefaults.base().commonProperties.SoongConfigTrace)
700 AssertDeepEquals(t, "board_size hash", boardSize.base().commonProperties.SoongConfigTraceHash, boardSizeDefaults.base().commonProperties.SoongConfigTraceHash)
701 })
702}