blob: dc31d07c99db7eac22a178c0e5810ff069fcb8b2 [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) {
Colin Crossaa255532020-07-03 13:18:24 -0700235 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800236 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}
Colin Crossaa255532020-07-03 13:18:24 -0700272 actualValues := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800273 if !reflect.DeepEqual(actualValues, expectedValues) {
274 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
275 actualValues, expectedValues)
276 }
277 }
278}
279
280func TestAndroidAppImport_ArchVariants(t *testing.T) {
281 // The test config's target arch is ARM64.
282 testCases := []struct {
283 name string
284 bp string
285 expected string
286 }{
287 {
288 name: "matching arch",
289 bp: `
290 android_app_import {
291 name: "foo",
292 apk: "prebuilts/apk/app.apk",
293 arch: {
294 arm64: {
295 apk: "prebuilts/apk/app_arm64.apk",
296 },
297 },
298 presigned: true,
299 dex_preopt: {
300 enabled: true,
301 },
302 }
303 `,
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000304 expected: "verify_uses_libraries/apk/app_arm64.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800305 },
306 {
307 name: "no matching arch",
308 bp: `
309 android_app_import {
310 name: "foo",
311 apk: "prebuilts/apk/app.apk",
312 arch: {
313 arm: {
314 apk: "prebuilts/apk/app_arm.apk",
315 },
316 },
317 presigned: true,
318 dex_preopt: {
319 enabled: true,
320 },
321 }
322 `,
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000323 expected: "verify_uses_libraries/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800324 },
325 {
326 name: "no matching arch without default",
327 bp: `
328 android_app_import {
329 name: "foo",
330 arch: {
331 arm: {
332 apk: "prebuilts/apk/app_arm.apk",
333 },
334 },
335 presigned: true,
336 dex_preopt: {
337 enabled: true,
338 },
339 }
340 `,
341 expected: "",
342 },
343 }
344
345 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
346 for _, test := range testCases {
347 ctx, _ := testJava(t, test.bp)
348
349 variant := ctx.ModuleForTests("foo", "android_common")
350 if test.expected == "" {
351 if variant.Module().Enabled() {
352 t.Error("module should have been disabled, but wasn't")
353 }
354 continue
355 }
356 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
357 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
358 if len(matches) != 2 {
359 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
360 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000361 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800362 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
363 }
364 }
365}
366
367func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
368 ctx, _ := testJava(t, `
369 android_app {
370 name: "foo",
371 srcs: ["a.java"],
372 enabled: false,
373 }
374
375 android_app_import {
376 name: "foo",
377 apk: "prebuilts/apk/app.apk",
378 certificate: "platform",
379 prefer: true,
380 }
381 `)
382
383 variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
384 a := variant.Module().(*AndroidAppImport)
385 // The prebuilt module should still be enabled and active even if the source-based counterpart
386 // is disabled.
387 if !a.prebuilt.UsePrebuilt() {
388 t.Errorf("prebuilt foo module is not active")
389 }
390 if !a.Enabled() {
391 t.Errorf("prebuilt foo module is disabled")
392 }
393}
394
Bill Peckhama036da92021-01-08 16:09:09 -0800395func TestAndroidAppImport_frameworkRes(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700396 ctx, _ := testJava(t, `
Bill Peckhama036da92021-01-08 16:09:09 -0800397 android_app_import {
398 name: "framework-res",
399 certificate: "platform",
400 apk: "package-res.apk",
401 prefer: true,
402 export_package_resources: true,
403 // Disable dexpreopt and verify_uses_libraries check as the app
404 // contains no Java code to be dexpreopted.
405 enforce_uses_libs: false,
406 dex_preopt: {
407 enabled: false,
408 },
409 }
410 `)
411
412 mod := ctx.ModuleForTests("prebuilt_framework-res", "android_common").Module()
413 a := mod.(*AndroidAppImport)
414
415 if !a.preprocessed {
416 t.Errorf("prebuilt framework-res is not preprocessed")
417 }
418
419 expectedInstallPath := buildDir + "/target/product/test_device/system/framework/framework-res.apk"
420
421 if a.dexpreopter.installPath.String() != expectedInstallPath {
422 t.Errorf("prebuilt framework-res installed to incorrect location, actual: %s, expected: %s", a.dexpreopter.installPath, expectedInstallPath)
423
424 }
425
Colin Crossaa255532020-07-03 13:18:24 -0700426 entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
Bill Peckhama036da92021-01-08 16:09:09 -0800427
428 expectedPath := "."
429 // From apk property above, in the root of the source tree.
430 expectedPrebuiltModuleFile := "package-res.apk"
431 // Verify that the apk is preprocessed: The export package is the same
432 // as the prebuilt.
433 expectedSoongResourceExportPackage := expectedPrebuiltModuleFile
434
435 actualPath := entries.EntryMap["LOCAL_PATH"]
436 actualPrebuiltModuleFile := entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"]
437 actualSoongResourceExportPackage := entries.EntryMap["LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE"]
438
439 if len(actualPath) != 1 {
440 t.Errorf("LOCAL_PATH incorrect len %d", len(actualPath))
441 } else if actualPath[0] != expectedPath {
442 t.Errorf("LOCAL_PATH mismatch, actual: %s, expected: %s", actualPath[0], expectedPath)
443 }
444
445 if len(actualPrebuiltModuleFile) != 1 {
446 t.Errorf("LOCAL_PREBUILT_MODULE_FILE incorrect len %d", len(actualPrebuiltModuleFile))
447 } else if actualPrebuiltModuleFile[0] != expectedPrebuiltModuleFile {
448 t.Errorf("LOCAL_PREBUILT_MODULE_FILE mismatch, actual: %s, expected: %s", actualPrebuiltModuleFile[0], expectedPrebuiltModuleFile)
449 }
450
451 if len(actualSoongResourceExportPackage) != 1 {
452 t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE incorrect len %d", len(actualSoongResourceExportPackage))
453 } else if actualSoongResourceExportPackage[0] != expectedSoongResourceExportPackage {
454 t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE mismatch, actual: %s, expected: %s", actualSoongResourceExportPackage[0], expectedSoongResourceExportPackage)
455 }
456}
457
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800458func TestAndroidTestImport(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700459 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800460 android_test_import {
461 name: "foo",
462 apk: "prebuilts/apk/app.apk",
463 presigned: true,
464 data: [
465 "testdata/data",
466 ],
467 }
468 `)
469
470 test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
471
472 // Check android mks.
Colin Crossaa255532020-07-03 13:18:24 -0700473 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800474 expected := []string{"tests"}
475 actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
476 if !reflect.DeepEqual(expected, actual) {
477 t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
478 }
479 expected = []string{"testdata/data:testdata/data"}
480 actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
481 if !reflect.DeepEqual(expected, actual) {
482 t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
483 }
484}
485
486func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
487 ctx, _ := testJava(t, `
488 android_test_import {
489 name: "foo",
490 apk: "prebuilts/apk/app.apk",
491 certificate: "cert/new_cert",
492 data: [
493 "testdata/data",
494 ],
495 }
496
497 android_test_import {
498 name: "foo_presigned",
499 apk: "prebuilts/apk/app.apk",
500 presigned: true,
501 data: [
502 "testdata/data",
503 ],
504 }
505 `)
506
507 variant := ctx.ModuleForTests("foo", "android_common")
508 jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
509 if !strings.HasPrefix(jniRule, "if (zipinfo") {
510 t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
511 }
512
513 variant = ctx.ModuleForTests("foo_presigned", "android_common")
514 jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
515 if jniRule != android.Cp.String() {
516 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
517 }
518 if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
519 t.Errorf("Presigned test apk should be aligned")
520 }
521}
522
523func TestAndroidTestImport_Preprocessed(t *testing.T) {
524 ctx, _ := testJava(t, `
525 android_test_import {
526 name: "foo",
527 apk: "prebuilts/apk/app.apk",
528 presigned: true,
529 preprocessed: true,
530 }
531
532 android_test_import {
533 name: "foo_cert",
534 apk: "prebuilts/apk/app.apk",
535 certificate: "cert/new_cert",
536 preprocessed: true,
537 }
538 `)
539
540 testModules := []string{"foo", "foo_cert"}
541 for _, m := range testModules {
542 apkName := m + ".apk"
543 variant := ctx.ModuleForTests(m, "android_common")
544 jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
545 if jniRule != android.Cp.String() {
546 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
547 }
548
549 // Make sure signing and aligning were skipped.
550 if variant.MaybeOutput("signed/"+apkName).Rule != nil {
551 t.Errorf("signing rule shouldn't be included for preprocessed.")
552 }
553 if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
554 t.Errorf("aligning rule shouldn't be for preprocessed")
555 }
556 }
557}