blob: 344d23b55ecff6b4633290296d62e1c6a04ada3f [file] [log] [blame]
Jaewoong Jungf9b44652020-12-21 12:29:12 -08001// Copyright 2020 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 java
16
17import (
18 "reflect"
19 "regexp"
20 "strings"
21 "testing"
22
23 "github.com/google/blueprint/proptools"
24
25 "android/soong/android"
26)
27
28func TestAndroidAppImport(t *testing.T) {
29 ctx, _ := testJava(t, `
30 android_app_import {
31 name: "foo",
32 apk: "prebuilts/apk/app.apk",
33 certificate: "platform",
34 dex_preopt: {
35 enabled: true,
36 },
37 }
38 `)
39
40 variant := ctx.ModuleForTests("foo", "android_common")
41
42 // Check dexpreopt outputs.
43 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
44 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
45 t.Errorf("can't find dexpreopt outputs")
46 }
47
48 // Check cert signing flag.
49 signedApk := variant.Output("signed/foo.apk")
50 signingFlag := signedApk.Args["certificates"]
51 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
52 if expected != signingFlag {
53 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
54 }
55}
56
57func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
58 ctx, _ := testJava(t, `
59 android_app_import {
60 name: "foo",
61 apk: "prebuilts/apk/app.apk",
62 certificate: "platform",
63 dex_preopt: {
64 enabled: false,
65 },
66 }
67 `)
68
69 variant := ctx.ModuleForTests("foo", "android_common")
70
71 // Check dexpreopt outputs. They shouldn't exist.
72 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil ||
73 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil {
74 t.Errorf("dexpreopt shouldn't have run.")
75 }
76}
77
78func TestAndroidAppImport_Presigned(t *testing.T) {
79 ctx, _ := testJava(t, `
80 android_app_import {
81 name: "foo",
82 apk: "prebuilts/apk/app.apk",
83 presigned: true,
84 dex_preopt: {
85 enabled: true,
86 },
87 }
88 `)
89
90 variant := ctx.ModuleForTests("foo", "android_common")
91
92 // Check dexpreopt outputs.
93 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
94 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
95 t.Errorf("can't find dexpreopt outputs")
96 }
97 // Make sure signing was skipped and aligning was done.
98 if variant.MaybeOutput("signed/foo.apk").Rule != nil {
99 t.Errorf("signing rule shouldn't be included.")
100 }
101 if variant.MaybeOutput("zip-aligned/foo.apk").Rule == nil {
102 t.Errorf("can't find aligning rule")
103 }
104}
105
106func TestAndroidAppImport_SigningLineage(t *testing.T) {
107 ctx, _ := testJava(t, `
108 android_app_import {
109 name: "foo",
110 apk: "prebuilts/apk/app.apk",
111 certificate: "platform",
112 lineage: "lineage.bin",
113 }
114 `)
115
116 variant := ctx.ModuleForTests("foo", "android_common")
117
118 // Check cert signing lineage flag.
119 signedApk := variant.Output("signed/foo.apk")
120 signingFlag := signedApk.Args["flags"]
121 expected := "--lineage lineage.bin"
122 if expected != signingFlag {
123 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
124 }
125}
126
127func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
128 ctx, _ := testJava(t, `
129 android_app_import {
130 name: "foo",
131 apk: "prebuilts/apk/app.apk",
132 default_dev_cert: true,
133 dex_preopt: {
134 enabled: true,
135 },
136 }
137 `)
138
139 variant := ctx.ModuleForTests("foo", "android_common")
140
141 // Check dexpreopt outputs.
142 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
143 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
144 t.Errorf("can't find dexpreopt outputs")
145 }
146
147 // Check cert signing flag.
148 signedApk := variant.Output("signed/foo.apk")
149 signingFlag := signedApk.Args["certificates"]
150 expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8"
151 if expected != signingFlag {
152 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
153 }
154}
155
156func TestAndroidAppImport_DpiVariants(t *testing.T) {
157 bp := `
158 android_app_import {
159 name: "foo",
160 apk: "prebuilts/apk/app.apk",
161 dpi_variants: {
162 xhdpi: {
163 apk: "prebuilts/apk/app_xhdpi.apk",
164 },
165 xxhdpi: {
166 apk: "prebuilts/apk/app_xxhdpi.apk",
167 },
168 },
169 presigned: true,
170 dex_preopt: {
171 enabled: true,
172 },
173 }
174 `
175 testCases := []struct {
176 name string
177 aaptPreferredConfig *string
178 aaptPrebuiltDPI []string
179 expected string
180 }{
181 {
182 name: "no preferred",
183 aaptPreferredConfig: nil,
184 aaptPrebuiltDPI: []string{},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000185 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800186 },
187 {
188 name: "AAPTPreferredConfig matches",
189 aaptPreferredConfig: proptools.StringPtr("xhdpi"),
190 aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000191 expected: "verify_uses_libraries/apk/app_xhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800192 },
193 {
194 name: "AAPTPrebuiltDPI matches",
195 aaptPreferredConfig: proptools.StringPtr("mdpi"),
196 aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000197 expected: "verify_uses_libraries/apk/app_xxhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800198 },
199 {
200 name: "non-first AAPTPrebuiltDPI matches",
201 aaptPreferredConfig: proptools.StringPtr("mdpi"),
202 aaptPrebuiltDPI: []string{"ldpi", "xhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000203 expected: "verify_uses_libraries/apk/app_xhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800204 },
205 {
206 name: "no matches",
207 aaptPreferredConfig: proptools.StringPtr("mdpi"),
208 aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"},
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000209 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800210 },
211 }
212
213 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
214 for _, test := range testCases {
215 config := testAppConfig(nil, bp, nil)
216 config.TestProductVariables.AAPTPreferredConfig = test.aaptPreferredConfig
217 config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
218 ctx := testContext(config)
219
220 run(t, ctx, config)
221
222 variant := ctx.ModuleForTests("foo", "android_common")
223 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
224 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
225 if len(matches) != 2 {
226 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
227 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000228 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800229 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
230 }
231 }
232}
233
234func TestAndroidAppImport_Filename(t *testing.T) {
235 ctx, config := testJava(t, `
236 android_app_import {
237 name: "foo",
238 apk: "prebuilts/apk/app.apk",
239 presigned: true,
240 }
241
242 android_app_import {
243 name: "bar",
244 apk: "prebuilts/apk/app.apk",
245 presigned: true,
246 filename: "bar_sample.apk"
247 }
248 `)
249
250 testCases := []struct {
251 name string
252 expected string
253 }{
254 {
255 name: "foo",
256 expected: "foo.apk",
257 },
258 {
259 name: "bar",
260 expected: "bar_sample.apk",
261 },
262 }
263
264 for _, test := range testCases {
265 variant := ctx.ModuleForTests(test.name, "android_common")
266 if variant.MaybeOutput(test.expected).Rule == nil {
267 t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
268 }
269
270 a := variant.Module().(*AndroidAppImport)
271 expectedValues := []string{test.expected}
272 actualValues := android.AndroidMkEntriesForTest(
273 t, config, "", a)[0].EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
274 if !reflect.DeepEqual(actualValues, expectedValues) {
275 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
276 actualValues, expectedValues)
277 }
278 }
279}
280
281func TestAndroidAppImport_ArchVariants(t *testing.T) {
282 // The test config's target arch is ARM64.
283 testCases := []struct {
284 name string
285 bp string
286 expected string
287 }{
288 {
289 name: "matching arch",
290 bp: `
291 android_app_import {
292 name: "foo",
293 apk: "prebuilts/apk/app.apk",
294 arch: {
295 arm64: {
296 apk: "prebuilts/apk/app_arm64.apk",
297 },
298 },
299 presigned: true,
300 dex_preopt: {
301 enabled: true,
302 },
303 }
304 `,
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000305 expected: "verify_uses_libraries/apk/app_arm64.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800306 },
307 {
308 name: "no matching arch",
309 bp: `
310 android_app_import {
311 name: "foo",
312 apk: "prebuilts/apk/app.apk",
313 arch: {
314 arm: {
315 apk: "prebuilts/apk/app_arm.apk",
316 },
317 },
318 presigned: true,
319 dex_preopt: {
320 enabled: true,
321 },
322 }
323 `,
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000324 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800325 },
326 {
327 name: "no matching arch without default",
328 bp: `
329 android_app_import {
330 name: "foo",
331 arch: {
332 arm: {
333 apk: "prebuilts/apk/app_arm.apk",
334 },
335 },
336 presigned: true,
337 dex_preopt: {
338 enabled: true,
339 },
340 }
341 `,
342 expected: "",
343 },
344 }
345
346 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
347 for _, test := range testCases {
348 ctx, _ := testJava(t, test.bp)
349
350 variant := ctx.ModuleForTests("foo", "android_common")
351 if test.expected == "" {
352 if variant.Module().Enabled() {
353 t.Error("module should have been disabled, but wasn't")
354 }
355 continue
356 }
357 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
358 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
359 if len(matches) != 2 {
360 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
361 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000362 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800363 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
364 }
365 }
366}
367
368func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
369 ctx, _ := testJava(t, `
370 android_app {
371 name: "foo",
372 srcs: ["a.java"],
373 enabled: false,
374 }
375
376 android_app_import {
377 name: "foo",
378 apk: "prebuilts/apk/app.apk",
379 certificate: "platform",
380 prefer: true,
381 }
382 `)
383
384 variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
385 a := variant.Module().(*AndroidAppImport)
386 // The prebuilt module should still be enabled and active even if the source-based counterpart
387 // is disabled.
388 if !a.prebuilt.UsePrebuilt() {
389 t.Errorf("prebuilt foo module is not active")
390 }
391 if !a.Enabled() {
392 t.Errorf("prebuilt foo module is disabled")
393 }
394}
395
396func TestAndroidTestImport(t *testing.T) {
397 ctx, config := testJava(t, `
398 android_test_import {
399 name: "foo",
400 apk: "prebuilts/apk/app.apk",
401 presigned: true,
402 data: [
403 "testdata/data",
404 ],
405 }
406 `)
407
408 test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
409
410 // Check android mks.
411 entries := android.AndroidMkEntriesForTest(t, config, "", test)[0]
412 expected := []string{"tests"}
413 actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
414 if !reflect.DeepEqual(expected, actual) {
415 t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
416 }
417 expected = []string{"testdata/data:testdata/data"}
418 actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
419 if !reflect.DeepEqual(expected, actual) {
420 t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
421 }
422}
423
424func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
425 ctx, _ := testJava(t, `
426 android_test_import {
427 name: "foo",
428 apk: "prebuilts/apk/app.apk",
429 certificate: "cert/new_cert",
430 data: [
431 "testdata/data",
432 ],
433 }
434
435 android_test_import {
436 name: "foo_presigned",
437 apk: "prebuilts/apk/app.apk",
438 presigned: true,
439 data: [
440 "testdata/data",
441 ],
442 }
443 `)
444
445 variant := ctx.ModuleForTests("foo", "android_common")
446 jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
447 if !strings.HasPrefix(jniRule, "if (zipinfo") {
448 t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
449 }
450
451 variant = ctx.ModuleForTests("foo_presigned", "android_common")
452 jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
453 if jniRule != android.Cp.String() {
454 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
455 }
456 if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
457 t.Errorf("Presigned test apk should be aligned")
458 }
459}
460
461func TestAndroidTestImport_Preprocessed(t *testing.T) {
462 ctx, _ := testJava(t, `
463 android_test_import {
464 name: "foo",
465 apk: "prebuilts/apk/app.apk",
466 presigned: true,
467 preprocessed: true,
468 }
469
470 android_test_import {
471 name: "foo_cert",
472 apk: "prebuilts/apk/app.apk",
473 certificate: "cert/new_cert",
474 preprocessed: true,
475 }
476 `)
477
478 testModules := []string{"foo", "foo_cert"}
479 for _, m := range testModules {
480 apkName := m + ".apk"
481 variant := ctx.ModuleForTests(m, "android_common")
482 jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
483 if jniRule != android.Cp.String() {
484 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
485 }
486
487 // Make sure signing and aligning were skipped.
488 if variant.MaybeOutput("signed/"+apkName).Rule != nil {
489 t.Errorf("signing rule shouldn't be included for preprocessed.")
490 }
491 if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
492 t.Errorf("aligning rule shouldn't be for preprocessed")
493 }
494 }
495}