blob: 41dd3d4796af546ba167071f24dedb00fca15a00 [file] [log] [blame]
Ronald Braunsteinfce43162024-02-02 12:37:20 -08001// Copyright 2024 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.
14package tradefed_modules
15
16import (
17 "android/soong/android"
18 "android/soong/java"
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +000019 "strconv"
Ronald Braunsteinfce43162024-02-02 12:37:20 -080020 "strings"
21 "testing"
22)
23
24const bp = `
25 android_app {
26 name: "foo",
27 srcs: ["a.java"],
28 sdk_version: "current",
29 }
30
31 android_test_helper_app {
32 name: "HelperApp",
33 srcs: ["helper.java"],
34 }
35
36 android_test {
37 name: "base",
38 sdk_version: "current",
39 data: [":HelperApp", "data/testfile"],
40 }
41
42 test_module_config {
43 name: "derived_test",
44 base: "base",
45 exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
46 include_annotations: ["android.platform.test.annotations.LargeTest"],
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +000047 test_suites: ["general-tests"],
Ronald Braunsteinfce43162024-02-02 12:37:20 -080048 }
49
50`
51
52// Ensure we create files needed and set the AndroidMkEntries needed
53func TestModuleConfigAndroidTest(t *testing.T) {
54
55 ctx := android.GroupFixturePreparers(
56 java.PrepareForTestWithJavaDefaultModules,
57 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
58 ).RunTestWithBp(t, bp)
59
60 derived := ctx.ModuleForTests("derived_test", "android_common")
61 // Assert there are rules to create these files.
62 derived.Output("test_module_config.manifest")
63 derived.Output("test_config_fixer/derived_test.config")
64
65 // Ensure some basic rules exist.
66 ctx.ModuleForTests("base", "android_common").Output("package-res.apk")
67 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
68
69 // Ensure some entries from base are there, specifically support files for data and helper apps.
70 assertEntryPairValues(t, entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"], []string{"HelperApp.apk", "data/testfile"})
71
72 // And some new derived entries are there.
73 android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE_TAGS"], []string{"tests"})
74
75 // And ones we override
76 android.AssertArrayString(t, "", entries.EntryMap["LOCAL_SOONG_JNI_LIBS_SYMBOLS"], []string{""})
77
78 android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "derived_test/android_common/test_config_fixer/derived_test.config")
79}
80
81// Make sure we call test-config-fixer with the right args.
82func TestModuleConfigOptions(t *testing.T) {
83
84 ctx := android.GroupFixturePreparers(
85 java.PrepareForTestWithJavaDefaultModules,
86 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
87 ).RunTestWithBp(t, bp)
88
89 // Check that we generate a rule to make a new AndroidTest.xml/Module.config file.
90 derived := ctx.ModuleForTests("derived_test", "android_common")
91 rule_cmd := derived.Rule("fix_test_config").RuleParams.Command
92 android.AssertStringDoesContain(t, "Bad FixConfig rule inputs", rule_cmd,
93 `--test-file-name=derived_test.apk --orig-test-file-name=base.apk --test-runner-options='[{"Name":"exclude-filter","Key":"","Value":"android.test.example.devcodelab.DevCodelabTest#testHelloFail"},{"Name":"include-annotation","Key":"","Value":"android.platform.test.annotations.LargeTest"}]'`)
94}
95
96// Ensure we error for a base we don't support.
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +000097func TestModuleConfigWithHostBaseShouldFailWithExplicitMessage(t *testing.T) {
Ronald Braunsteinfce43162024-02-02 12:37:20 -080098 badBp := `
99 java_test_host {
100 name: "base",
101 srcs: ["a.java"],
102 }
103
104 test_module_config {
105 name: "derived_test",
106 base: "base",
107 exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
108 include_annotations: ["android.platform.test.annotations.LargeTest"],
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000109 test_suites: ["general-tests"],
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800110 }`
111
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000112 android.GroupFixturePreparers(
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800113 java.PrepareForTestWithJavaDefaultModules,
114 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
115 ).ExtendWithErrorHandler(
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000116 android.FixtureExpectsAtLeastOneErrorMatchingPattern("'java_test_host' module used as base, but 'android_test' expected")).
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800117 RunTestWithBp(t, badBp)
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000118}
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800119
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000120func TestModuleConfigBadBaseShouldFailWithGeneralMessage(t *testing.T) {
121 badBp := `
122 java_library {
123 name: "base",
124 srcs: ["a.java"],
125 }
126
127 test_module_config {
128 name: "derived_test",
129 base: "base",
130 exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
131 include_annotations: ["android.platform.test.annotations.LargeTest"],
132 test_suites: ["general-tests"],
133 }`
134
135 android.GroupFixturePreparers(
136 java.PrepareForTestWithJavaDefaultModules,
137 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
138 ).ExtendWithErrorHandler(
139 android.FixtureExpectsOneErrorPattern("'base' module used as base but it is not a 'android_test' module.")).
140 RunTestWithBp(t, badBp)
141}
142
143func TestModuleConfigNoBaseShouldFail(t *testing.T) {
144 badBp := `
145 java_library {
146 name: "base",
147 srcs: ["a.java"],
148 }
149
150 test_module_config {
151 name: "derived_test",
152 exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
153 include_annotations: ["android.platform.test.annotations.LargeTest"],
154 test_suites: ["general-tests"],
155 }`
156
157 android.GroupFixturePreparers(
158 java.PrepareForTestWithJavaDefaultModules,
159 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
160 ).ExtendWithErrorHandler(
161 android.FixtureExpectsOneErrorPattern("'base' field must be set to a 'android_test' module.")).
162 RunTestWithBp(t, badBp)
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800163}
164
165// Ensure we error for a base we don't support.
166func TestModuleConfigNoFiltersOrAnnotationsShouldFail(t *testing.T) {
167 badBp := `
168 android_test {
169 name: "base",
170 sdk_version: "current",
171 srcs: ["a.java"],
172 }
173
174 test_module_config {
175 name: "derived_test",
176 base: "base",
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000177 test_suites: ["general-tests"],
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800178 }`
179
180 ctx := android.GroupFixturePreparers(
181 java.PrepareForTestWithJavaDefaultModules,
182 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
183 ).ExtendWithErrorHandler(
184 android.FixtureExpectsAtLeastOneErrorMatchingPattern("Test options must be given")).
185 RunTestWithBp(t, badBp)
186
187 ctx.ModuleForTests("derived_test", "android_common")
188}
189
190func TestModuleConfigMultipleDerivedTestsWriteDistinctMakeEntries(t *testing.T) {
191 multiBp := `
192 android_test {
193 name: "base",
194 sdk_version: "current",
195 srcs: ["a.java"],
196 }
197
198 test_module_config {
199 name: "derived_test",
200 base: "base",
201 include_annotations: ["android.platform.test.annotations.LargeTest"],
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000202 test_suites: ["general-tests"],
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800203 }
204
205 test_module_config {
206 name: "another_derived_test",
207 base: "base",
208 include_annotations: ["android.platform.test.annotations.LargeTest"],
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000209 test_suites: ["general-tests"],
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800210 }`
211
212 ctx := android.GroupFixturePreparers(
213 java.PrepareForTestWithJavaDefaultModules,
214 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
215 ).RunTestWithBp(t, multiBp)
216
217 {
218 derived := ctx.ModuleForTests("derived_test", "android_common")
219 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
220 // All these should be the same in both derived tests
221 assertEntryPairValues(t, entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"], []string{"HelperApp.apk", "data/testfile"})
222 android.AssertArrayString(t, "", entries.EntryMap["LOCAL_SOONG_JNI_LIBS_SYMBOLS"], []string{""})
223 // Except this one, which points to the updated tradefed xml file.
224 android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "derived_test/android_common/test_config_fixer/derived_test.config")
225 // And this one, the module name.
226 android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE"], []string{"derived_test"})
227 }
228
229 {
230 derived := ctx.ModuleForTests("another_derived_test", "android_common")
231 entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, derived.Module())[0]
232 // All these should be the same in both derived tests
233 assertEntryPairValues(t, entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"], []string{"HelperApp.apk", "data/testfile"})
234 android.AssertArrayString(t, "", entries.EntryMap["LOCAL_SOONG_JNI_LIBS_SYMBOLS"], []string{""})
235 // Except this one, which points to the updated tradefed xml file.
236 android.AssertStringMatches(t, "", entries.EntryMap["LOCAL_FULL_TEST_CONFIG"][0], "another_derived_test/android_common/test_config_fixer/another_derived_test.config")
237 // And this one, the module name.
238 android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE"], []string{"another_derived_test"})
239 }
240}
241
Ronald Braunstein1a6e7c02024-03-14 21:14:39 +0000242// Test_module_config_host rule is allowed to depend on java_test_host
243func TestModuleConfigHostBasics(t *testing.T) {
244 bp := `
245 java_test_host {
246 name: "base",
247 srcs: ["a.java"],
248 test_suites: ["suiteA", "general-tests", "suiteB"],
249 }
250
251 test_module_config_host {
252 name: "derived_test",
253 base: "base",
254 exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
255 include_annotations: ["android.platform.test.annotations.LargeTest"],
256 test_suites: ["general-tests"],
257 }`
258
259 ctx := android.GroupFixturePreparers(
260 java.PrepareForTestWithJavaDefaultModules,
261 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
262 ).RunTestWithBp(t, bp)
263
264 variant := ctx.Config.BuildOS.String() + "_common"
265 derived := ctx.ModuleForTests("derived_test", variant)
266 mod := derived.Module().(*testModuleConfigHostModule)
267 allEntries := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)
268 entries := allEntries[0]
269 android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE"], []string{"derived_test"})
270
271 if !mod.Host() {
272 t.Errorf("host bit is not set for a java_test_host module.")
273 }
274 actualData, _ := strconv.ParseBool(entries.EntryMap["LOCAL_IS_UNIT_TEST"][0])
275 android.AssertBoolEquals(t, "LOCAL_IS_UNIT_TEST", true, actualData)
276
277}
278
279// When you pass an 'android_test' as base, the warning message is a bit obscure,
280// talking about variants, but it is something. Ideally we could do better.
281func TestModuleConfigHostBadBaseShouldFailWithVariantWarning(t *testing.T) {
282 badBp := `
283 android_test {
284 name: "base",
285 sdk_version: "current",
286 srcs: ["a.java"],
287 }
288
289 test_module_config_host {
290 name: "derived_test",
291 base: "base",
292 exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
293 include_annotations: ["android.platform.test.annotations.LargeTest"],
294 }`
295
296 android.GroupFixturePreparers(
297 java.PrepareForTestWithJavaDefaultModules,
298 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
299 ).ExtendWithErrorHandler(
300 android.FixtureExpectsAtLeastOneErrorMatchingPattern("missing variant")).
301 RunTestWithBp(t, badBp)
302}
303
304func TestModuleConfigHostNeedsATestSuite(t *testing.T) {
305 badBp := `
306 java_test_host {
307 name: "base",
308 srcs: ["a.java"],
309 }
310
311 test_module_config_host {
312 name: "derived_test",
313 base: "base",
314 exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
315 include_annotations: ["android.platform.test.annotations.LargeTest"],
316 }`
317
318 android.GroupFixturePreparers(
319 java.PrepareForTestWithJavaDefaultModules,
320 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
321 ).ExtendWithErrorHandler(
322 android.FixtureExpectsAtLeastOneErrorMatchingPattern("At least one test-suite must be set")).
323 RunTestWithBp(t, badBp)
324}
325
326func TestModuleConfigHostDuplicateTestSuitesGiveErrors(t *testing.T) {
327 badBp := `
328 java_test_host {
329 name: "base",
330 srcs: ["a.java"],
331 test_suites: ["general-tests", "some-compat"],
332 }
333
334 test_module_config_host {
335 name: "derived_test",
336 base: "base",
337 exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
338 include_annotations: ["android.platform.test.annotations.LargeTest"],
339 test_suites: ["general-tests", "some-compat"],
340 }`
341
342 android.GroupFixturePreparers(
343 java.PrepareForTestWithJavaDefaultModules,
344 android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
345 ).ExtendWithErrorHandler(
346 android.FixtureExpectsAtLeastOneErrorMatchingPattern("TestSuite some-compat exists in the base")).
347 RunTestWithBp(t, badBp)
348}
349
Ronald Braunsteinfce43162024-02-02 12:37:20 -0800350// Use for situations where the entries map contains pairs: [srcPath:installedPath1, srcPath2:installedPath2]
351// and we want to compare the RHS of the pairs, i.e. installedPath1, installedPath2
352func assertEntryPairValues(t *testing.T, actual []string, expected []string) {
353 for i, e := range actual {
354 parts := strings.Split(e, ":")
355 if len(parts) != 2 {
356 t.Errorf("Expected entry to have a value delimited by :, received: %s", e)
357 return
358 }
359 android.AssertStringEquals(t, "", parts[1], expected[i])
360 }
361}