blob: 32b3a197724776238e178dacba33925473d6e2c6 [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
Paul Duffin32299982023-01-09 14:02:06 +000056var prepareForSoongConfigTestModule = FixtureRegisterWithContext(func(ctx RegistrationContext) {
57 ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
58 ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
59})
60
Colin Cross9d34f352019-11-22 16:03:51 -080061func TestSoongConfigModule(t *testing.T) {
62 configBp := `
63 soong_config_module_type {
Liz Kammerdbd48092020-09-21 22:24:17 +000064 name: "acme_test",
65 module_type: "test",
Colin Cross9d34f352019-11-22 16:03:51 -080066 config_namespace: "acme",
Liz Kammer432bd592020-12-16 12:42:02 -080067 variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
Liz Kammerbdce0df2021-10-15 13:34:27 -040068 bool_variables: ["feature2", "unused_feature", "always_true"],
Liz Kammer432bd592020-12-16 12:42:02 -080069 value_variables: ["size", "unused_size"],
Liz Kammerdbd48092020-09-21 22:24:17 +000070 properties: ["cflags", "srcs", "defaults"],
Colin Cross9d34f352019-11-22 16:03:51 -080071 }
72
73 soong_config_string_variable {
74 name: "board",
Liz Kammer432bd592020-12-16 12:42:02 -080075 values: ["soc_a", "soc_b", "soc_c", "soc_d"],
76 }
77
78 soong_config_string_variable {
79 name: "unused_string_var",
80 values: ["a", "b"],
Colin Cross9d34f352019-11-22 16:03:51 -080081 }
82
83 soong_config_bool_variable {
84 name: "feature1",
85 }
86
87 soong_config_bool_variable {
Colin Cross3beeb1e2020-02-05 16:27:47 -080088 name: "FEATURE3",
Colin Cross9d34f352019-11-22 16:03:51 -080089 }
90 `
91
92 importBp := `
93 soong_config_module_type_import {
94 from: "SoongConfig.bp",
Liz Kammerdbd48092020-09-21 22:24:17 +000095 module_types: ["acme_test"],
Colin Cross9d34f352019-11-22 16:03:51 -080096 }
97 `
98
99 bp := `
Liz Kammerdbd48092020-09-21 22:24:17 +0000100 test_defaults {
101 name: "foo_defaults",
102 cflags: ["DEFAULT"],
103 }
104
105 acme_test {
Colin Cross9d34f352019-11-22 16:03:51 -0800106 name: "foo",
107 cflags: ["-DGENERIC"],
Liz Kammerdbd48092020-09-21 22:24:17 +0000108 defaults: ["foo_defaults"],
Colin Cross9d34f352019-11-22 16:03:51 -0800109 soong_config_variables: {
110 board: {
111 soc_a: {
112 cflags: ["-DSOC_A"],
113 },
114 soc_b: {
115 cflags: ["-DSOC_B"],
116 },
Liz Kammer432bd592020-12-16 12:42:02 -0800117 soc_c: {},
118 conditions_default: {
119 cflags: ["-DSOC_CONDITIONS_DEFAULT"],
120 },
Colin Cross9d34f352019-11-22 16:03:51 -0800121 },
Dan Willemsenb0935db2020-03-23 19:42:18 -0700122 size: {
123 cflags: ["-DSIZE=%s"],
Liz Kammer432bd592020-12-16 12:42:02 -0800124 conditions_default: {
125 cflags: ["-DSIZE=CONDITIONS_DEFAULT"],
126 },
Dan Willemsenb0935db2020-03-23 19:42:18 -0700127 },
Colin Cross9d34f352019-11-22 16:03:51 -0800128 feature1: {
Liz Kammer432bd592020-12-16 12:42:02 -0800129 conditions_default: {
130 cflags: ["-DF1_CONDITIONS_DEFAULT"],
131 },
Colin Cross9d34f352019-11-22 16:03:51 -0800132 cflags: ["-DFEATURE1"],
133 },
134 feature2: {
135 cflags: ["-DFEATURE2"],
Liz Kammer432bd592020-12-16 12:42:02 -0800136 conditions_default: {
137 cflags: ["-DF2_CONDITIONS_DEFAULT"],
138 },
Colin Cross9d34f352019-11-22 16:03:51 -0800139 },
Colin Cross3beeb1e2020-02-05 16:27:47 -0800140 FEATURE3: {
Colin Cross9d34f352019-11-22 16:03:51 -0800141 cflags: ["-DFEATURE3"],
142 },
143 },
144 }
Liz Kammerdbd48092020-09-21 22:24:17 +0000145
146 test_defaults {
147 name: "foo_defaults_a",
148 cflags: ["DEFAULT_A"],
149 }
150
151 test_defaults {
152 name: "foo_defaults_b",
153 cflags: ["DEFAULT_B"],
154 }
155
Liz Kammerbdce0df2021-10-15 13:34:27 -0400156 test_defaults {
157 name: "foo_defaults_always_true",
158 cflags: ["DEFAULT_ALWAYS_TRUE"],
159 }
160
Liz Kammerdbd48092020-09-21 22:24:17 +0000161 acme_test {
162 name: "foo_with_defaults",
163 cflags: ["-DGENERIC"],
164 defaults: ["foo_defaults"],
165 soong_config_variables: {
166 board: {
167 soc_a: {
168 cflags: ["-DSOC_A"],
169 defaults: ["foo_defaults_a"],
170 },
171 soc_b: {
172 cflags: ["-DSOC_B"],
173 defaults: ["foo_defaults_b"],
174 },
Liz Kammer432bd592020-12-16 12:42:02 -0800175 soc_c: {},
Liz Kammerdbd48092020-09-21 22:24:17 +0000176 },
177 size: {
178 cflags: ["-DSIZE=%s"],
179 },
180 feature1: {
181 cflags: ["-DFEATURE1"],
182 },
183 feature2: {
184 cflags: ["-DFEATURE2"],
185 },
186 FEATURE3: {
187 cflags: ["-DFEATURE3"],
188 },
Liz Kammerbdce0df2021-10-15 13:34:27 -0400189 always_true: {
190 defaults: ["foo_defaults_always_true"],
191 conditions_default: {
192 // verify that conditions_default is skipped if the
193 // soong config variable is true by specifying a
194 // non-existent module in conditions_default
195 defaults: ["//nonexistent:defaults"],
196 }
197 },
Liz Kammerdbd48092020-09-21 22:24:17 +0000198 },
199 }
Colin Cross9d34f352019-11-22 16:03:51 -0800200 `
201
Paul Duffin791302b2021-03-16 22:45:14 +0000202 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
203 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
204 variables.VendorVars = vars
205 })
206 }
207
208 run := func(t *testing.T, bp string, fs MockFS) {
Liz Kammer432bd592020-12-16 12:42:02 -0800209 testCases := []struct {
210 name string
Paul Duffin791302b2021-03-16 22:45:14 +0000211 preparer FixturePreparer
Liz Kammer432bd592020-12-16 12:42:02 -0800212 fooExpectedFlags []string
213 fooDefaultsExpectedFlags []string
214 }{
215 {
216 name: "withValues",
Paul Duffin791302b2021-03-16 22:45:14 +0000217 preparer: fixtureForVendorVars(map[string]map[string]string{
218 "acme": {
Liz Kammer432bd592020-12-16 12:42:02 -0800219 "board": "soc_a",
220 "size": "42",
221 "feature1": "true",
222 "feature2": "false",
223 // FEATURE3 unset
224 "unused_feature": "true", // unused
225 "unused_size": "1", // unused
226 "unused_string_var": "a", // unused
Liz Kammerbdce0df2021-10-15 13:34:27 -0400227 "always_true": "true",
Liz Kammer432bd592020-12-16 12:42:02 -0800228 },
229 }),
230 fooExpectedFlags: []string{
231 "DEFAULT",
232 "-DGENERIC",
233 "-DF2_CONDITIONS_DEFAULT",
234 "-DSIZE=42",
235 "-DSOC_A",
236 "-DFEATURE1",
237 },
238 fooDefaultsExpectedFlags: []string{
239 "DEFAULT_A",
Liz Kammerbdce0df2021-10-15 13:34:27 -0400240 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800241 "DEFAULT",
242 "-DGENERIC",
243 "-DSIZE=42",
244 "-DSOC_A",
245 "-DFEATURE1",
246 },
247 },
248 {
249 name: "empty_prop_for_string_var",
Paul Duffin791302b2021-03-16 22:45:14 +0000250 preparer: fixtureForVendorVars(map[string]map[string]string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400251 "acme": {
252 "board": "soc_c",
253 "always_true": "true",
254 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800255 fooExpectedFlags: []string{
256 "DEFAULT",
257 "-DGENERIC",
258 "-DF2_CONDITIONS_DEFAULT",
259 "-DSIZE=CONDITIONS_DEFAULT",
260 "-DF1_CONDITIONS_DEFAULT",
261 },
262 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400263 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800264 "DEFAULT",
265 "-DGENERIC",
266 },
267 },
268 {
269 name: "unused_string_var",
Paul Duffin791302b2021-03-16 22:45:14 +0000270 preparer: fixtureForVendorVars(map[string]map[string]string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400271 "acme": {
272 "board": "soc_d",
273 "always_true": "true",
274 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800275 fooExpectedFlags: []string{
276 "DEFAULT",
277 "-DGENERIC",
278 "-DF2_CONDITIONS_DEFAULT",
279 "-DSIZE=CONDITIONS_DEFAULT",
280 "-DSOC_CONDITIONS_DEFAULT", // foo does not contain a prop "soc_d", so we use the default
281 "-DF1_CONDITIONS_DEFAULT",
282 },
283 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400284 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800285 "DEFAULT",
286 "-DGENERIC",
287 },
288 },
Colin Cross9d34f352019-11-22 16:03:51 -0800289
Liz Kammer432bd592020-12-16 12:42:02 -0800290 {
Liz Kammerbdce0df2021-10-15 13:34:27 -0400291 name: "conditions_default",
292 preparer: fixtureForVendorVars(map[string]map[string]string{
293 "acme": {
294 "always_true": "true",
295 }}),
Liz Kammer432bd592020-12-16 12:42:02 -0800296 fooExpectedFlags: []string{
297 "DEFAULT",
298 "-DGENERIC",
299 "-DF2_CONDITIONS_DEFAULT",
300 "-DSIZE=CONDITIONS_DEFAULT",
301 "-DSOC_CONDITIONS_DEFAULT",
302 "-DF1_CONDITIONS_DEFAULT",
303 },
304 fooDefaultsExpectedFlags: []string{
Liz Kammerbdce0df2021-10-15 13:34:27 -0400305 "DEFAULT_ALWAYS_TRUE",
Liz Kammer432bd592020-12-16 12:42:02 -0800306 "DEFAULT",
307 "-DGENERIC",
308 },
Colin Cross9d34f352019-11-22 16:03:51 -0800309 },
310 }
311
Liz Kammer432bd592020-12-16 12:42:02 -0800312 for _, tc := range testCases {
Paul Duffin791302b2021-03-16 22:45:14 +0000313 t.Run(tc.name, func(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000314 result := GroupFixturePreparers(
Paul Duffin791302b2021-03-16 22:45:14 +0000315 tc.preparer,
316 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000317 PrepareForTestWithSoongConfigModuleBuildComponents,
318 prepareForSoongConfigTestModule,
Paul Duffin791302b2021-03-16 22:45:14 +0000319 fs.AddToFixture(),
320 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000321 ).RunTest(t)
Colin Cross9d34f352019-11-22 16:03:51 -0800322
Paul Duffin791302b2021-03-16 22:45:14 +0000323 foo := result.ModuleForTests("foo", "").Module().(*soongConfigTestModule)
324 AssertDeepEquals(t, "foo cflags", tc.fooExpectedFlags, foo.props.Cflags)
Colin Cross9d34f352019-11-22 16:03:51 -0800325
Paul Duffin791302b2021-03-16 22:45:14 +0000326 fooDefaults := result.ModuleForTests("foo_with_defaults", "").Module().(*soongConfigTestModule)
327 AssertDeepEquals(t, "foo_with_defaults cflags", tc.fooDefaultsExpectedFlags, fooDefaults.props.Cflags)
328 })
Liz Kammerdbd48092020-09-21 22:24:17 +0000329 }
Colin Cross9d34f352019-11-22 16:03:51 -0800330 }
331
332 t.Run("single file", func(t *testing.T) {
333 run(t, configBp+bp, nil)
334 })
335
336 t.Run("import", func(t *testing.T) {
337 run(t, importBp+bp, map[string][]byte{
338 "SoongConfig.bp": []byte(configBp),
339 })
340 })
341}
Liz Kammer432bd592020-12-16 12:42:02 -0800342
Liz Kammer0fc1e132021-07-15 12:34:59 -0400343func TestNonExistentPropertyInSoongConfigModule(t *testing.T) {
344 bp := `
345 soong_config_module_type {
346 name: "acme_test",
347 module_type: "test",
348 config_namespace: "acme",
349 bool_variables: ["feature1"],
350 properties: ["made_up_property"],
351 }
352
353 acme_test {
354 name: "foo",
355 cflags: ["-DGENERIC"],
356 soong_config_variables: {
357 feature1: {
358 made_up_property: true,
359 },
360 },
361 }
362 `
363
364 fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
365 return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
366 variables.VendorVars = vars
367 })
368 }
369
370 GroupFixturePreparers(
371 fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
372 PrepareForTestWithDefaults,
Paul Duffin32299982023-01-09 14:02:06 +0000373 PrepareForTestWithSoongConfigModuleBuildComponents,
374 prepareForSoongConfigTestModule,
Liz Kammer0fc1e132021-07-15 12:34:59 -0400375 FixtureWithRootAndroidBp(bp),
376 ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
377 // TODO(b/171232169): improve the error message for non-existent properties
378 `unrecognized property "soong_config_variables`,
379 })).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
Liz Kammer432bd592020-12-16 12:42:02 -0800416func testConfigWithVendorVars(buildDir, bp string, fs map[string][]byte, vendorVars map[string]map[string]string) Config {
417 config := TestConfig(buildDir, nil, bp, fs)
418
419 config.TestProductVariables.VendorVars = vendorVars
420
421 return config
422}