blob: 79bdeb82973420b55a06badf704b5e6c33d138b5 [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{
379 // TODO(b/171232169): improve the error message for non-existent properties
380 `unrecognized property "soong_config_variables`,
381 })).RunTest(t)
382}
383
Liz Kammer72beb342022-02-03 08:42:10 -0500384func TestDuplicateStringValueInSoongConfigStringVariable(t *testing.T) {
385 bp := `
386 soong_config_string_variable {
387 name: "board",
388 values: ["soc_a", "soc_b", "soc_c", "soc_a"],
389 }
390
391 soong_config_module_type {
392 name: "acme_test",
393 module_type: "test",
394 config_namespace: "acme",
395 variables: ["board"],
396 properties: ["cflags", "srcs", "defaults"],
397 }
398 `
399
400 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
401 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
402 variables.VendorVars = vars
403 })
404 }
405
406 GroupFixturePreparers(
407 fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
408 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000409 PrepareForTestWithSoongConfigModuleBuildComponents,
410 prepareForSoongConfigTestModule,
Liz Kammer72beb342022-02-03 08:42:10 -0500411 FixtureWithRootAndroidBp(bp),
412 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
413 // TODO(b/171232169): improve the error message for non-existent properties
414 `Android.bp: soong_config_string_variable: values property error: duplicate value: "soc_a"`,
415 })).RunTest(t)
416}
417
Paul Duffinf1e6a042023-01-09 15:43:29 +0000418type soongConfigTestSingletonModule struct {
419 SingletonModuleBase
420 props soongConfigTestSingletonModuleProperties
421}
Liz Kammer432bd592020-12-16 12:42:02 -0800422
Paul Duffinf1e6a042023-01-09 15:43:29 +0000423type soongConfigTestSingletonModuleProperties struct {
424 Fragments []struct {
425 Apex string
426 Module string
427 }
428}
Liz Kammer432bd592020-12-16 12:42:02 -0800429
Paul Duffinf1e6a042023-01-09 15:43:29 +0000430func soongConfigTestSingletonModuleFactory() SingletonModule {
431 m := &soongConfigTestSingletonModule{}
432 m.AddProperties(&m.props)
433 InitAndroidModule(m)
434 return m
435}
436
437func (t *soongConfigTestSingletonModule) GenerateAndroidBuildActions(ModuleContext) {}
438
439func (t *soongConfigTestSingletonModule) GenerateSingletonBuildActions(SingletonContext) {}
440
441var prepareForSoongConfigTestSingletonModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
442 ctx.RegisterSingletonModuleType("test_singleton", soongConfigTestSingletonModuleFactory)
443})
444
445func TestSoongConfigModuleSingletonModule(t *testing.T) {
446 bp := `
447 soong_config_module_type {
448 name: "acme_test_singleton",
449 module_type: "test_singleton",
450 config_namespace: "acme",
451 bool_variables: ["coyote"],
452 properties: ["fragments"],
453 }
454
455 acme_test_singleton {
456 name: "wiley",
457 fragments: [
458 {
459 apex: "com.android.acme",
460 module: "road-runner",
461 },
462 ],
463 soong_config_variables: {
464 coyote: {
465 fragments: [
466 {
467 apex: "com.android.acme",
468 module: "wiley",
469 },
470 ],
471 },
472 },
473 }
474 `
475
476 for _, test := range []struct {
477 coyote bool
478 expectedFragments string
479 }{
480 {
481 coyote: false,
482 expectedFragments: "[{Apex:com.android.acme Module:road-runner}]",
483 },
484 {
485 coyote: true,
486 expectedFragments: "[{Apex:com.android.acme Module:road-runner} {Apex:com.android.acme Module:wiley}]",
487 },
488 } {
489 t.Run(fmt.Sprintf("coyote:%t", test.coyote), func(t *testing.T) {
Paul Duffine8b47682023-01-09 15:42:57 +0000490 result := GroupFixturePreparers(
Paul Duffinf1e6a042023-01-09 15:43:29 +0000491 PrepareForTestWithSoongConfigModuleBuildComponents,
492 prepareForSoongConfigTestSingletonModule,
493 FixtureWithRootAndroidBp(bp),
494 FixtureModifyProductVariables(func(variables FixtureProductVariables) {
495 variables.VendorVars = map[string]map[string]string{
496 "acme": {
497 "coyote": fmt.Sprintf("%t", test.coyote),
498 },
499 }
500 }),
Paul Duffine8b47682023-01-09 15:42:57 +0000501 ).RunTest(t)
502
503 // Make sure that the singleton was created.
504 result.SingletonForTests("test_singleton")
505 m := result.ModuleForTests("wiley", "").module.(*soongConfigTestSingletonModule)
506 AssertStringEquals(t, "fragments", test.expectedFragments, fmt.Sprintf("%+v", m.props.Fragments))
Paul Duffinf1e6a042023-01-09 15:43:29 +0000507 })
508 }
Liz Kammer432bd592020-12-16 12:42:02 -0800509}
Inseob Kim81b00a82023-05-15 18:06:31 +0900510
511func TestSoongConfigModuleTrace(t *testing.T) {
512 bp := `
513 soong_config_module_type {
514 name: "acme_test",
515 module_type: "test",
516 config_namespace: "acme",
517 variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
518 bool_variables: ["feature2", "unused_feature", "always_true"],
519 value_variables: ["size", "unused_size"],
520 properties: ["cflags", "srcs", "defaults"],
521 }
522
523 soong_config_module_type {
524 name: "acme_test_defaults",
525 module_type: "test_defaults",
526 config_namespace: "acme",
527 variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
528 bool_variables: ["feature2", "unused_feature", "always_true"],
529 value_variables: ["size", "unused_size"],
530 properties: ["cflags", "srcs", "defaults"],
531 }
532
533 soong_config_string_variable {
534 name: "board",
535 values: ["soc_a", "soc_b", "soc_c"],
536 }
537
538 soong_config_string_variable {
539 name: "unused_string_var",
540 values: ["a", "b"],
541 }
542
543 soong_config_bool_variable {
544 name: "feature1",
545 }
546
547 soong_config_bool_variable {
548 name: "FEATURE3",
549 }
550
551 test_defaults {
552 name: "test_defaults",
553 cflags: ["DEFAULT"],
554 }
555
556 test {
557 name: "normal",
558 defaults: ["test_defaults"],
559 }
560
561 acme_test {
562 name: "board_1",
563 defaults: ["test_defaults"],
564 soong_config_variables: {
565 board: {
566 soc_a: {
567 cflags: ["-DSOC_A"],
568 },
569 },
570 },
571 }
572
573 acme_test {
574 name: "board_2",
575 defaults: ["test_defaults"],
576 soong_config_variables: {
577 board: {
578 soc_a: {
579 cflags: ["-DSOC_A"],
580 },
581 },
582 },
583 }
584
585 acme_test {
586 name: "size",
587 defaults: ["test_defaults"],
588 soong_config_variables: {
589 size: {
590 cflags: ["-DSIZE=%s"],
591 },
592 },
593 }
594
595 acme_test {
596 name: "board_and_size",
597 defaults: ["test_defaults"],
598 soong_config_variables: {
599 board: {
600 soc_a: {
601 cflags: ["-DSOC_A"],
602 },
603 },
604 size: {
605 cflags: ["-DSIZE=%s"],
606 },
607 },
608 }
609
610 acme_test_defaults {
611 name: "board_defaults",
612 soong_config_variables: {
613 board: {
614 soc_a: {
615 cflags: ["-DSOC_A"],
616 },
617 },
618 },
619 }
620
621 acme_test_defaults {
622 name: "size_defaults",
623 soong_config_variables: {
624 size: {
625 cflags: ["-DSIZE=%s"],
626 },
627 },
628 }
629
630 test {
631 name: "board_and_size_with_defaults",
632 defaults: ["board_defaults", "size_defaults"],
633 }
634 `
635
636 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
637 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
638 variables.VendorVars = vars
639 })
640 }
641
642 preparer := fixtureForVendorVars(map[string]map[string]string{
643 "acme": {
644 "board": "soc_a",
645 "size": "42",
646 "feature1": "true",
647 "feature2": "false",
648 // FEATURE3 unset
649 "unused_feature": "true", // unused
650 "unused_size": "1", // unused
651 "unused_string_var": "a", // unused
652 "always_true": "true",
653 },
654 })
655
656 t.Run("soong config trace hash", func(t *testing.T) {
657 result := GroupFixturePreparers(
658 preparer,
659 PrepareForTestWithDefaults,
660 PrepareForTestWithSoongConfigModuleBuildComponents,
661 prepareForSoongConfigTestModule,
662 FixtureRegisterWithContext(func(ctx RegistrationContext) {
663 ctx.FinalDepsMutators(registerSoongConfigTraceMutator)
664 }),
665 FixtureWithRootAndroidBp(bp),
666 ).RunTest(t)
667
668 // Hashes of modules not using soong config should be empty
669 normal := result.ModuleForTests("normal", "").Module().(*soongConfigTestModule)
670 AssertDeepEquals(t, "normal hash", normal.base().commonProperties.SoongConfigTraceHash, "")
671 AssertDeepEquals(t, "normal hash out", normal.outputPath.RelativeToTop().String(), "out/soong/.intermediates/normal/test")
672
673 board1 := result.ModuleForTests("board_1", "").Module().(*soongConfigTestModule)
674 board2 := result.ModuleForTests("board_2", "").Module().(*soongConfigTestModule)
675 size := result.ModuleForTests("size", "").Module().(*soongConfigTestModule)
676
677 // Trace mutator sets soong config trace hash correctly
678 board1Hash := board1.base().commonProperties.SoongConfigTrace.hash()
679 board1Output := board1.outputPath.RelativeToTop().String()
680 AssertDeepEquals(t, "board hash calc", board1Hash, board1.base().commonProperties.SoongConfigTraceHash)
681 AssertDeepEquals(t, "board hash path", board1Output, filepath.Join("out/soong/.intermediates/board_1", board1Hash, "test"))
682
683 sizeHash := size.base().commonProperties.SoongConfigTrace.hash()
684 sizeOutput := size.outputPath.RelativeToTop().String()
685 AssertDeepEquals(t, "size hash calc", sizeHash, size.base().commonProperties.SoongConfigTraceHash)
686 AssertDeepEquals(t, "size hash path", sizeOutput, filepath.Join("out/soong/.intermediates/size", sizeHash, "test"))
687
688 // Trace should be identical for modules using the same set of variables
689 AssertDeepEquals(t, "board trace", board1.base().commonProperties.SoongConfigTrace, board2.base().commonProperties.SoongConfigTrace)
690 AssertDeepEquals(t, "board hash", board1.base().commonProperties.SoongConfigTraceHash, board2.base().commonProperties.SoongConfigTraceHash)
691
692 // Trace hash should be different for different sets of soong variables
693 AssertBoolEquals(t, "board hash not equal to size hash", board1.base().commonProperties.SoongConfigTraceHash == size.commonProperties.SoongConfigTraceHash, false)
694
695 boardSize := result.ModuleForTests("board_and_size", "").Module().(*soongConfigTestModule)
696 boardSizeDefaults := result.ModuleForTests("board_and_size_with_defaults", "").Module()
697
698 // Trace should propagate
699 AssertDeepEquals(t, "board_size hash calc", boardSize.base().commonProperties.SoongConfigTrace.hash(), boardSize.base().commonProperties.SoongConfigTraceHash)
700 AssertDeepEquals(t, "board_size trace", boardSize.base().commonProperties.SoongConfigTrace, boardSizeDefaults.base().commonProperties.SoongConfigTrace)
701 AssertDeepEquals(t, "board_size hash", boardSize.base().commonProperties.SoongConfigTraceHash, boardSizeDefaults.base().commonProperties.SoongConfigTraceHash)
702 })
703}