blob: ceb8e45a5dbba3d214990359a578ba2edb33c443 [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 (
Colin Cross9d34f352019-11-22 16:03:51 -080018 "testing"
19)
20
Liz Kammerdbd48092020-09-21 22:24:17 +000021type soongConfigTestDefaultsModuleProperties struct {
22}
23
24type soongConfigTestDefaultsModule struct {
25 ModuleBase
26 DefaultsModuleBase
27}
28
29func soongConfigTestDefaultsModuleFactory() Module {
30 m := &soongConfigTestDefaultsModule{}
31 m.AddProperties(&soongConfigTestModuleProperties{})
32 InitDefaultsModule(m)
33 return m
34}
35
Colin Cross9d34f352019-11-22 16:03:51 -080036type soongConfigTestModule struct {
37 ModuleBase
Liz Kammerdbd48092020-09-21 22:24:17 +000038 DefaultableModuleBase
Colin Cross9d34f352019-11-22 16:03:51 -080039 props soongConfigTestModuleProperties
40}
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
54func (t soongConfigTestModule) GenerateAndroidBuildActions(ModuleContext) {}
55
56func TestSoongConfigModule(t *testing.T) {
57 configBp := `
58 soong_config_module_type {
Liz Kammerdbd48092020-09-21 22:24:17 +000059 name: "acme_test",
60 module_type: "test",
Colin Cross9d34f352019-11-22 16:03:51 -080061 config_namespace: "acme",
Liz Kammer432bd592020-12-16 12:42:02 -080062 variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
Liz Kammerbdce0df2021-10-15 13:34:27 -040063 bool_variables: ["feature2", "unused_feature", "always_true"],
Liz Kammer432bd592020-12-16 12:42:02 -080064 value_variables: ["size", "unused_size"],
Liz Kammerdbd48092020-09-21 22:24:17 +000065 properties: ["cflags", "srcs", "defaults"],
Colin Cross9d34f352019-11-22 16:03:51 -080066 }
67
68 soong_config_string_variable {
69 name: "board",
Liz Kammer432bd592020-12-16 12:42:02 -080070 values: ["soc_a", "soc_b", "soc_c", "soc_d"],
71 }
72
73 soong_config_string_variable {
74 name: "unused_string_var",
75 values: ["a", "b"],
Colin Cross9d34f352019-11-22 16:03:51 -080076 }
77
78 soong_config_bool_variable {
79 name: "feature1",
80 }
81
82 soong_config_bool_variable {
Colin Cross3beeb1e2020-02-05 16:27:47 -080083 name: "FEATURE3",
Colin Cross9d34f352019-11-22 16:03:51 -080084 }
85 `
86
87 importBp := `
88 soong_config_module_type_import {
89 from: "SoongConfig.bp",
Liz Kammerdbd48092020-09-21 22:24:17 +000090 module_types: ["acme_test"],
Colin Cross9d34f352019-11-22 16:03:51 -080091 }
92 `
93
94 bp := `
Liz Kammerdbd48092020-09-21 22:24:17 +000095 test_defaults {
96 name: "foo_defaults",
97 cflags: ["DEFAULT"],
98 }
99
100 acme_test {
Colin Cross9d34f352019-11-22 16:03:51 -0800101 name: "foo",
102 cflags: ["-DGENERIC"],
Liz Kammerdbd48092020-09-21 22:24:17 +0000103 defaults: ["foo_defaults"],
Colin Cross9d34f352019-11-22 16:03:51 -0800104 soong_config_variables: {
105 board: {
106 soc_a: {
107 cflags: ["-DSOC_A"],
108 },
109 soc_b: {
110 cflags: ["-DSOC_B"],
111 },
Liz Kammer432bd592020-12-16 12:42:02 -0800112 soc_c: {},
113 conditions_default: {
114 cflags: ["-DSOC_CONDITIONS_DEFAULT"],
115 },
Colin Cross9d34f352019-11-22 16:03:51 -0800116 },
Dan Willemsenb0935db2020-03-23 19:42:18 -0700117 size: {
118 cflags: ["-DSIZE=%s"],
Liz Kammer432bd592020-12-16 12:42:02 -0800119 conditions_default: {
120 cflags: ["-DSIZE=CONDITIONS_DEFAULT"],
121 },
Dan Willemsenb0935db2020-03-23 19:42:18 -0700122 },
Colin Cross9d34f352019-11-22 16:03:51 -0800123 feature1: {
Liz Kammer432bd592020-12-16 12:42:02 -0800124 conditions_default: {
125 cflags: ["-DF1_CONDITIONS_DEFAULT"],
126 },
Colin Cross9d34f352019-11-22 16:03:51 -0800127 cflags: ["-DFEATURE1"],
128 },
129 feature2: {
130 cflags: ["-DFEATURE2"],
Liz Kammer432bd592020-12-16 12:42:02 -0800131 conditions_default: {
132 cflags: ["-DF2_CONDITIONS_DEFAULT"],
133 },
Colin Cross9d34f352019-11-22 16:03:51 -0800134 },
Colin Cross3beeb1e2020-02-05 16:27:47 -0800135 FEATURE3: {
Colin Cross9d34f352019-11-22 16:03:51 -0800136 cflags: ["-DFEATURE3"],
137 },
138 },
139 }
Liz Kammerdbd48092020-09-21 22:24:17 +0000140
141 test_defaults {
142 name: "foo_defaults_a",
143 cflags: ["DEFAULT_A"],
144 }
145
146 test_defaults {
147 name: "foo_defaults_b",
148 cflags: ["DEFAULT_B"],
149 }
150
Liz Kammerbdce0df2021-10-15 13:34:27 -0400151 test_defaults {
152 name: "foo_defaults_always_true",
153 cflags: ["DEFAULT_ALWAYS_TRUE"],
154 }
155
Liz Kammerdbd48092020-09-21 22:24:17 +0000156 acme_test {
157 name: "foo_with_defaults",
158 cflags: ["-DGENERIC"],
159 defaults: ["foo_defaults"],
160 soong_config_variables: {
161 board: {
162 soc_a: {
163 cflags: ["-DSOC_A"],
164 defaults: ["foo_defaults_a"],
165 },
166 soc_b: {
167 cflags: ["-DSOC_B"],
168 defaults: ["foo_defaults_b"],
169 },
Liz Kammer432bd592020-12-16 12:42:02 -0800170 soc_c: {},
Liz Kammerdbd48092020-09-21 22:24:17 +0000171 },
172 size: {
173 cflags: ["-DSIZE=%s"],
174 },
175 feature1: {
176 cflags: ["-DFEATURE1"],
177 },
178 feature2: {
179 cflags: ["-DFEATURE2"],
180 },
181 FEATURE3: {
182 cflags: ["-DFEATURE3"],
183 },
Liz Kammerbdce0df2021-10-15 13:34:27 -0400184 always_true: {
185 defaults: ["foo_defaults_always_true"],
186 conditions_default: {
187 // verify that conditions_default is skipped if the
188 // soong config variable is true by specifying a
189 // non-existent module in conditions_default
190 defaults: ["//nonexistent:defaults"],
191 }
192 },
Liz Kammerdbd48092020-09-21 22:24:17 +0000193 },
194 }
Colin Cross9d34f352019-11-22 16:03:51 -0800195 `
196
Paul Duffin791302b2021-03-16 22:45:14 +0000197 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
198 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
199 variables.VendorVars = vars
200 })
201 }
202
203 run := func(t *testing.T, bp string, fs MockFS) {
Liz Kammer432bd592020-12-16 12:42:02 -0800204 testCases := []struct {
205 name string
Paul Duffin791302b2021-03-16 22:45:14 +0000206 preparer FixturePreparer
Liz Kammer432bd592020-12-16 12:42:02 -0800207 fooExpectedFlags []string
208 fooDefaultsExpectedFlags []string
209 }{
210 {
211 name: "withValues",
Paul Duffin791302b2021-03-16 22:45:14 +0000212 preparer: fixtureForVendorVars(map[string]map[string]string{
213 "acme": {
Liz Kammer432bd592020-12-16 12:42:02 -0800214 "board": "soc_a",
215 "size": "42",
216 "feature1": "true",
217 "feature2": "false",
218 // FEATURE3 unset
219 "unused_feature": "true", // unused
220 "unused_size": "1", // unused
221 "unused_string_var": "a", // unused
Liz Kammerbdce0df2021-10-15 13:34:27 -0400222 "always_true": "true",
Liz Kammer432bd592020-12-16 12:42:02 -0800223 },
224 }),
225 fooExpectedFlags: []string{
226 "DEFAULT",
227 "-DGENERIC",
228 "-DF2_CONDITIONS_DEFAULT",
229 "-DSIZE=42",
230 "-DSOC_A",
231 "-DFEATURE1",
232 },
233 fooDefaultsExpectedFlags: []string{
234 "DEFAULT_A",
Liz Kammerbdce0df2021-10-15 13:34:27 -0400235 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800236 "DEFAULT",
237 "-DGENERIC",
238 "-DSIZE=42",
239 "-DSOC_A",
240 "-DFEATURE1",
241 },
242 },
243 {
244 name: "empty_prop_for_string_var",
Paul Duffin791302b2021-03-16 22:45:14 +0000245 preparer: fixtureForVendorVars(map[string]map[string]string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400246 "acme": {
247 "board": "soc_c",
248 "always_true": "true",
249 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800250 fooExpectedFlags: []string{
251 "DEFAULT",
252 "-DGENERIC",
253 "-DF2_CONDITIONS_DEFAULT",
254 "-DSIZE=CONDITIONS_DEFAULT",
255 "-DF1_CONDITIONS_DEFAULT",
256 },
257 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400258 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800259 "DEFAULT",
260 "-DGENERIC",
261 },
262 },
263 {
264 name: "unused_string_var",
Paul Duffin791302b2021-03-16 22:45:14 +0000265 preparer: fixtureForVendorVars(map[string]map[string]string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400266 "acme": {
267 "board": "soc_d",
268 "always_true": "true",
269 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800270 fooExpectedFlags: []string{
271 "DEFAULT",
272 "-DGENERIC",
273 "-DF2_CONDITIONS_DEFAULT",
274 "-DSIZE=CONDITIONS_DEFAULT",
275 "-DSOC_CONDITIONS_DEFAULT", // foo does not contain a prop "soc_d", so we use the default
276 "-DF1_CONDITIONS_DEFAULT",
277 },
278 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400279 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800280 "DEFAULT",
281 "-DGENERIC",
282 },
283 },
Colin Cross9d34f352019-11-22 16:03:51 -0800284
Liz Kammer432bd592020-12-16 12:42:02 -0800285 {
Liz Kammerbdce0df2021-10-15 13:34:27 -0400286 name: "conditions_default",
287 preparer: fixtureForVendorVars(map[string]map[string]string{
288 "acme": {
289 "always_true": "true",
290 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800291 fooExpectedFlags: []string{
292 "DEFAULT",
293 "-DGENERIC",
294 "-DF2_CONDITIONS_DEFAULT",
295 "-DSIZE=CONDITIONS_DEFAULT",
296 "-DSOC_CONDITIONS_DEFAULT",
297 "-DF1_CONDITIONS_DEFAULT",
298 },
299 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400300 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800301 "DEFAULT",
302 "-DGENERIC",
303 },
Colin Cross9d34f352019-11-22 16:03:51 -0800304 },
305 }
306
Liz Kammer432bd592020-12-16 12:42:02 -0800307 for _, tc := range testCases {
Paul Duffin791302b2021-03-16 22:45:14 +0000308 t.Run(tc.name, func(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000309 result := GroupFixturePreparers(
Paul Duffin791302b2021-03-16 22:45:14 +0000310 tc.preparer,
311 PrepareForTestWithDefaults,
312 FixtureRegisterWithContext(func(ctx RegistrationContext) {
Jingwen Chena47f28d2021-11-02 16:43:57 +0000313 ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
314 ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
315 ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
316 ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
Paul Duffin791302b2021-03-16 22:45:14 +0000317 ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
318 ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
319 }),
320 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,
374 FixtureRegisterWithContext(func(ctx RegistrationContext) {
Jingwen Chena47f28d2021-11-02 16:43:57 +0000375 ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
376 ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
377 ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
378 ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
Liz Kammer0fc1e132021-07-15 12:34:59 -0400379 ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
380 ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
381 }),
382 FixtureWithRootAndroidBp(bp),
383 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
384 // TODO(b/171232169): improve the error message for non-existent properties
385 `unrecognized property "soong_config_variables`,
386 })).RunTest(t)
387}
388
Liz Kammer72beb342022-02-03 08:42:10 -0500389func TestDuplicateStringValueInSoongConfigStringVariable(t *testing.T) {
390 bp := `
391 soong_config_string_variable {
392 name: "board",
393 values: ["soc_a", "soc_b", "soc_c", "soc_a"],
394 }
395
396 soong_config_module_type {
397 name: "acme_test",
398 module_type: "test",
399 config_namespace: "acme",
400 variables: ["board"],
401 properties: ["cflags", "srcs", "defaults"],
402 }
403 `
404
405 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
406 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
407 variables.VendorVars = vars
408 })
409 }
410
411 GroupFixturePreparers(
412 fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
413 PrepareForTestWithDefaults,
414 FixtureRegisterWithContext(func(ctx RegistrationContext) {
415 ctx.RegisterModuleType("soong_config_module_type_import", SoongConfigModuleTypeImportFactory)
416 ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
417 ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
418 ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
419 ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
420 ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
421 }),
422 FixtureWithRootAndroidBp(bp),
423 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
424 // TODO(b/171232169): improve the error message for non-existent properties
425 `Android.bp: soong_config_string_variable: values property error: duplicate value: "soc_a"`,
426 })).RunTest(t)
427}
428
Liz Kammer432bd592020-12-16 12:42:02 -0800429func testConfigWithVendorVars(buildDir, bp string, fs map[string][]byte, vendorVars map[string]map[string]string) Config {
430 config := TestConfig(buildDir, nil, bp, fs)
431
432 config.TestProductVariables.VendorVars = vendorVars
433
434 return config
435}