blob: 8f6c75fa9b6ff02d3a69bc0706e8071b2f217989 [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 (
Ulya Trafimovich55f72d72021-09-01 14:13:57 +010018 "fmt"
Jaewoong Jungf9b44652020-12-21 12:29:12 -080019 "reflect"
20 "regexp"
21 "strings"
22 "testing"
23
24 "github.com/google/blueprint/proptools"
25
26 "android/soong/android"
27)
28
29func TestAndroidAppImport(t *testing.T) {
30 ctx, _ := testJava(t, `
31 android_app_import {
32 name: "foo",
33 apk: "prebuilts/apk/app.apk",
34 certificate: "platform",
35 dex_preopt: {
36 enabled: true,
37 },
38 }
39 `)
40
41 variant := ctx.ModuleForTests("foo", "android_common")
42
43 // Check dexpreopt outputs.
44 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
45 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
46 t.Errorf("can't find dexpreopt outputs")
47 }
48
49 // Check cert signing flag.
50 signedApk := variant.Output("signed/foo.apk")
51 signingFlag := signedApk.Args["certificates"]
52 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
53 if expected != signingFlag {
54 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
55 }
Wei Li340ee8e2022-03-18 17:33:24 -070056 rule := variant.Rule("genProvenanceMetaData")
57 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
58 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
59 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
60 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -080061}
62
63func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
64 ctx, _ := testJava(t, `
65 android_app_import {
66 name: "foo",
67 apk: "prebuilts/apk/app.apk",
68 certificate: "platform",
69 dex_preopt: {
70 enabled: false,
71 },
72 }
73 `)
74
75 variant := ctx.ModuleForTests("foo", "android_common")
76
77 // Check dexpreopt outputs. They shouldn't exist.
78 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil ||
79 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil {
80 t.Errorf("dexpreopt shouldn't have run.")
81 }
Wei Li340ee8e2022-03-18 17:33:24 -070082
83 rule := variant.Rule("genProvenanceMetaData")
84 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
85 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
86 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
87 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -080088}
89
90func TestAndroidAppImport_Presigned(t *testing.T) {
91 ctx, _ := testJava(t, `
92 android_app_import {
93 name: "foo",
94 apk: "prebuilts/apk/app.apk",
95 presigned: true,
96 dex_preopt: {
97 enabled: true,
98 },
99 }
100 `)
101
102 variant := ctx.ModuleForTests("foo", "android_common")
103
104 // Check dexpreopt outputs.
105 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
106 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
107 t.Errorf("can't find dexpreopt outputs")
108 }
109 // Make sure signing was skipped and aligning was done.
110 if variant.MaybeOutput("signed/foo.apk").Rule != nil {
111 t.Errorf("signing rule shouldn't be included.")
112 }
113 if variant.MaybeOutput("zip-aligned/foo.apk").Rule == nil {
114 t.Errorf("can't find aligning rule")
115 }
Wei Li340ee8e2022-03-18 17:33:24 -0700116
117 rule := variant.Rule("genProvenanceMetaData")
118 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
119 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
120 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
121 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800122}
123
124func TestAndroidAppImport_SigningLineage(t *testing.T) {
125 ctx, _ := testJava(t, `
126 android_app_import {
127 name: "foo",
128 apk: "prebuilts/apk/app.apk",
129 certificate: "platform",
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800130 additional_certificates: [":additional_certificate"],
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800131 lineage: "lineage.bin",
132 }
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800133
134 android_app_certificate {
135 name: "additional_certificate",
136 certificate: "cert/additional_cert",
137 }
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800138 `)
139
140 variant := ctx.ModuleForTests("foo", "android_common")
141
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800142 signedApk := variant.Output("signed/foo.apk")
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800143 // Check certificates
144 certificatesFlag := signedApk.Args["certificates"]
145 expected := "build/make/target/product/security/platform.x509.pem " +
146 "build/make/target/product/security/platform.pk8 " +
147 "cert/additional_cert.x509.pem cert/additional_cert.pk8"
148 if expected != certificatesFlag {
149 t.Errorf("Incorrect certificates flags, expected: %q, got: %q", expected, certificatesFlag)
150 }
151 // Check cert signing lineage flag.
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800152 signingFlag := signedApk.Args["flags"]
Jaewoong Jung25ae8de2021-03-08 17:37:46 -0800153 expected = "--lineage lineage.bin"
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800154 if expected != signingFlag {
155 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
156 }
Wei Li340ee8e2022-03-18 17:33:24 -0700157
158 rule := variant.Rule("genProvenanceMetaData")
159 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
160 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
161 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
162 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800163}
164
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800165func TestAndroidAppImport_SigningLineageFilegroup(t *testing.T) {
166 ctx, _ := testJava(t, `
167 android_app_import {
168 name: "foo",
169 apk: "prebuilts/apk/app.apk",
170 certificate: "platform",
171 lineage: ":lineage_bin",
172 }
173
174 filegroup {
175 name: "lineage_bin",
176 srcs: ["lineage.bin"],
177 }
178 `)
179
180 variant := ctx.ModuleForTests("foo", "android_common")
181
182 signedApk := variant.Output("signed/foo.apk")
183 // Check cert signing lineage flag.
184 signingFlag := signedApk.Args["flags"]
185 expected := "--lineage lineage.bin"
186 if expected != signingFlag {
187 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
188 }
Wei Li340ee8e2022-03-18 17:33:24 -0700189
190 rule := variant.Rule("genProvenanceMetaData")
191 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
192 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
193 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
194 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
Jaewoong Jung1c1b6e62021-03-09 15:02:31 -0800195}
196
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800197func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
198 ctx, _ := testJava(t, `
199 android_app_import {
200 name: "foo",
201 apk: "prebuilts/apk/app.apk",
202 default_dev_cert: true,
203 dex_preopt: {
204 enabled: true,
205 },
206 }
207 `)
208
209 variant := ctx.ModuleForTests("foo", "android_common")
210
211 // Check dexpreopt outputs.
212 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
213 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
214 t.Errorf("can't find dexpreopt outputs")
215 }
216
217 // Check cert signing flag.
218 signedApk := variant.Output("signed/foo.apk")
219 signingFlag := signedApk.Args["certificates"]
220 expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8"
221 if expected != signingFlag {
222 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
223 }
Wei Li340ee8e2022-03-18 17:33:24 -0700224
225 rule := variant.Rule("genProvenanceMetaData")
226 android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
227 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
228 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
229 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800230}
231
232func TestAndroidAppImport_DpiVariants(t *testing.T) {
233 bp := `
234 android_app_import {
235 name: "foo",
236 apk: "prebuilts/apk/app.apk",
237 dpi_variants: {
238 xhdpi: {
239 apk: "prebuilts/apk/app_xhdpi.apk",
240 },
241 xxhdpi: {
242 apk: "prebuilts/apk/app_xxhdpi.apk",
243 },
244 },
245 presigned: true,
246 dex_preopt: {
247 enabled: true,
248 },
249 }
250 `
251 testCases := []struct {
Wei Li340ee8e2022-03-18 17:33:24 -0700252 name string
253 aaptPreferredConfig *string
254 aaptPrebuiltDPI []string
255 expected string
256 expectedProvenanceMetaDataArtifactPath string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800257 }{
258 {
Wei Li340ee8e2022-03-18 17:33:24 -0700259 name: "no preferred",
260 aaptPreferredConfig: nil,
261 aaptPrebuiltDPI: []string{},
262 expected: "verify_uses_libraries/apk/app.apk",
263 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800264 },
265 {
Wei Li340ee8e2022-03-18 17:33:24 -0700266 name: "AAPTPreferredConfig matches",
267 aaptPreferredConfig: proptools.StringPtr("xhdpi"),
268 aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"},
269 expected: "verify_uses_libraries/apk/app_xhdpi.apk",
270 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app_xhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800271 },
272 {
Wei Li340ee8e2022-03-18 17:33:24 -0700273 name: "AAPTPrebuiltDPI matches",
274 aaptPreferredConfig: proptools.StringPtr("mdpi"),
275 aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"},
276 expected: "verify_uses_libraries/apk/app_xxhdpi.apk",
277 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app_xxhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800278 },
279 {
Wei Li340ee8e2022-03-18 17:33:24 -0700280 name: "non-first AAPTPrebuiltDPI matches",
281 aaptPreferredConfig: proptools.StringPtr("mdpi"),
282 aaptPrebuiltDPI: []string{"ldpi", "xhdpi"},
283 expected: "verify_uses_libraries/apk/app_xhdpi.apk",
284 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app_xhdpi.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800285 },
286 {
Wei Li340ee8e2022-03-18 17:33:24 -0700287 name: "no matches",
288 aaptPreferredConfig: proptools.StringPtr("mdpi"),
289 aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"},
290 expected: "verify_uses_libraries/apk/app.apk",
291 expectedProvenanceMetaDataArtifactPath: "prebuilts/apk/app.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800292 },
293 }
294
295 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
296 for _, test := range testCases {
Paul Duffinfb8bc952021-03-22 17:31:52 +0000297 result := android.GroupFixturePreparers(
298 PrepareForTestWithJavaDefaultModules,
299 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
300 variables.AAPTPreferredConfig = test.aaptPreferredConfig
301 variables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
302 }),
303 ).RunTestWithBp(t, bp)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800304
Paul Duffinfb8bc952021-03-22 17:31:52 +0000305 variant := result.ModuleForTests("foo", "android_common")
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800306 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
307 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
308 if len(matches) != 2 {
309 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
310 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000311 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800312 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
313 }
Wei Li340ee8e2022-03-18 17:33:24 -0700314
315 provenanceMetaDataRule := variant.Rule("genProvenanceMetaData")
316 android.AssertStringEquals(t, "Invalid input", test.expectedProvenanceMetaDataArtifactPath, provenanceMetaDataRule.Inputs[0].String())
317 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", provenanceMetaDataRule.Output.String())
318 android.AssertStringEquals(t, "Invalid args", "foo", provenanceMetaDataRule.Args["module_name"])
319 android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", provenanceMetaDataRule.Args["install_path"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800320 }
321}
322
323func TestAndroidAppImport_Filename(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700324 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800325 android_app_import {
326 name: "foo",
327 apk: "prebuilts/apk/app.apk",
328 presigned: true,
329 }
330
331 android_app_import {
332 name: "bar",
333 apk: "prebuilts/apk/app.apk",
334 presigned: true,
335 filename: "bar_sample.apk"
336 }
337 `)
338
339 testCases := []struct {
Wei Li340ee8e2022-03-18 17:33:24 -0700340 name string
341 expected string
342 onDevice string
343 expectedArtifactPath string
344 expectedMetaDataPath string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800345 }{
346 {
Wei Li340ee8e2022-03-18 17:33:24 -0700347 name: "foo",
348 expected: "foo.apk",
349 onDevice: "/system/app/foo/foo.apk",
350 expectedArtifactPath: "prebuilts/apk/app.apk",
351 expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800352 },
353 {
Wei Li340ee8e2022-03-18 17:33:24 -0700354 name: "bar",
355 expected: "bar_sample.apk",
356 onDevice: "/system/app/bar/bar_sample.apk",
357 expectedArtifactPath: "prebuilts/apk/app.apk",
358 expectedMetaDataPath: "out/soong/.intermediates/provenance_metadata/bar/provenance_metadata.textproto",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800359 },
360 }
361
362 for _, test := range testCases {
363 variant := ctx.ModuleForTests(test.name, "android_common")
364 if variant.MaybeOutput(test.expected).Rule == nil {
365 t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
366 }
367
368 a := variant.Module().(*AndroidAppImport)
369 expectedValues := []string{test.expected}
Colin Crossaa255532020-07-03 13:18:24 -0700370 actualValues := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800371 if !reflect.DeepEqual(actualValues, expectedValues) {
372 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
373 actualValues, expectedValues)
374 }
Wei Li340ee8e2022-03-18 17:33:24 -0700375 rule := variant.Rule("genProvenanceMetaData")
376 android.AssertStringEquals(t, "Invalid input", test.expectedArtifactPath, rule.Inputs[0].String())
377 android.AssertStringEquals(t, "Invalid output", test.expectedMetaDataPath, rule.Output.String())
378 android.AssertStringEquals(t, "Invalid args", test.name, rule.Args["module_name"])
379 android.AssertStringEquals(t, "Invalid args", test.onDevice, rule.Args["install_path"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800380 }
381}
382
383func TestAndroidAppImport_ArchVariants(t *testing.T) {
384 // The test config's target arch is ARM64.
385 testCases := []struct {
Wei Li340ee8e2022-03-18 17:33:24 -0700386 name string
387 bp string
388 expected string
389 artifactPath string
390 metaDataPath string
391 installPath string
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800392 }{
393 {
394 name: "matching arch",
395 bp: `
396 android_app_import {
397 name: "foo",
398 apk: "prebuilts/apk/app.apk",
399 arch: {
400 arm64: {
401 apk: "prebuilts/apk/app_arm64.apk",
402 },
403 },
404 presigned: true,
405 dex_preopt: {
406 enabled: true,
407 },
408 }
409 `,
Wei Li340ee8e2022-03-18 17:33:24 -0700410 expected: "verify_uses_libraries/apk/app_arm64.apk",
411 artifactPath: "prebuilts/apk/app_arm64.apk",
412 installPath: "/system/app/foo/foo.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800413 },
414 {
415 name: "no matching arch",
416 bp: `
417 android_app_import {
418 name: "foo",
419 apk: "prebuilts/apk/app.apk",
420 arch: {
421 arm: {
422 apk: "prebuilts/apk/app_arm.apk",
423 },
424 },
425 presigned: true,
426 dex_preopt: {
427 enabled: true,
428 },
429 }
430 `,
Wei Li340ee8e2022-03-18 17:33:24 -0700431 expected: "verify_uses_libraries/apk/app.apk",
432 artifactPath: "prebuilts/apk/app.apk",
433 installPath: "/system/app/foo/foo.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800434 },
435 {
436 name: "no matching arch without default",
437 bp: `
438 android_app_import {
439 name: "foo",
440 arch: {
441 arm: {
442 apk: "prebuilts/apk/app_arm.apk",
443 },
444 },
445 presigned: true,
446 dex_preopt: {
447 enabled: true,
448 },
449 }
450 `,
Wei Li340ee8e2022-03-18 17:33:24 -0700451 expected: "",
452 artifactPath: "prebuilts/apk/app_arm.apk",
453 installPath: "/system/app/foo/foo.apk",
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800454 },
455 }
456
457 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
458 for _, test := range testCases {
459 ctx, _ := testJava(t, test.bp)
460
461 variant := ctx.ModuleForTests("foo", "android_common")
462 if test.expected == "" {
463 if variant.Module().Enabled() {
464 t.Error("module should have been disabled, but wasn't")
465 }
Wei Li340ee8e2022-03-18 17:33:24 -0700466 rule := variant.MaybeRule("genProvenanceMetaData")
467 android.AssertDeepEquals(t, "Provenance metadata is not empty", android.TestingBuildParams{}, rule)
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800468 continue
469 }
470 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
471 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
472 if len(matches) != 2 {
473 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
474 }
Ulya Trafimovich22890c42021-01-05 12:04:17 +0000475 if strings.HasSuffix(matches[1], test.expected) {
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800476 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
477 }
Wei Li340ee8e2022-03-18 17:33:24 -0700478 rule := variant.Rule("genProvenanceMetaData")
479 android.AssertStringEquals(t, "Invalid input", test.artifactPath, rule.Inputs[0].String())
480 android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
481 android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
482 android.AssertStringEquals(t, "Invalid args", test.installPath, rule.Args["install_path"])
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800483 }
484}
485
486func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) {
487 ctx, _ := testJava(t, `
488 android_app {
489 name: "foo",
490 srcs: ["a.java"],
491 enabled: false,
492 }
493
494 android_app_import {
495 name: "foo",
496 apk: "prebuilts/apk/app.apk",
497 certificate: "platform",
498 prefer: true,
499 }
500 `)
501
502 variant := ctx.ModuleForTests("prebuilt_foo", "android_common")
503 a := variant.Module().(*AndroidAppImport)
504 // The prebuilt module should still be enabled and active even if the source-based counterpart
505 // is disabled.
506 if !a.prebuilt.UsePrebuilt() {
507 t.Errorf("prebuilt foo module is not active")
508 }
509 if !a.Enabled() {
510 t.Errorf("prebuilt foo module is disabled")
511 }
512}
513
Bill Peckhama036da92021-01-08 16:09:09 -0800514func TestAndroidAppImport_frameworkRes(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700515 ctx, _ := testJava(t, `
Bill Peckhama036da92021-01-08 16:09:09 -0800516 android_app_import {
517 name: "framework-res",
518 certificate: "platform",
519 apk: "package-res.apk",
520 prefer: true,
521 export_package_resources: true,
522 // Disable dexpreopt and verify_uses_libraries check as the app
523 // contains no Java code to be dexpreopted.
524 enforce_uses_libs: false,
525 dex_preopt: {
526 enabled: false,
527 },
528 }
529 `)
530
531 mod := ctx.ModuleForTests("prebuilt_framework-res", "android_common").Module()
532 a := mod.(*AndroidAppImport)
533
534 if !a.preprocessed {
535 t.Errorf("prebuilt framework-res is not preprocessed")
536 }
537
Paul Duffinfb8bc952021-03-22 17:31:52 +0000538 expectedInstallPath := "out/soong/target/product/test_device/system/framework/framework-res.apk"
Bill Peckhama036da92021-01-08 16:09:09 -0800539
Paul Duffinfb8bc952021-03-22 17:31:52 +0000540 android.AssertPathRelativeToTopEquals(t, "prebuilt framework-res install location", expectedInstallPath, a.dexpreopter.installPath)
Bill Peckhama036da92021-01-08 16:09:09 -0800541
Colin Crossaa255532020-07-03 13:18:24 -0700542 entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
Bill Peckhama036da92021-01-08 16:09:09 -0800543
544 expectedPath := "."
545 // From apk property above, in the root of the source tree.
546 expectedPrebuiltModuleFile := "package-res.apk"
547 // Verify that the apk is preprocessed: The export package is the same
548 // as the prebuilt.
549 expectedSoongResourceExportPackage := expectedPrebuiltModuleFile
550
551 actualPath := entries.EntryMap["LOCAL_PATH"]
552 actualPrebuiltModuleFile := entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"]
553 actualSoongResourceExportPackage := entries.EntryMap["LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE"]
554
555 if len(actualPath) != 1 {
556 t.Errorf("LOCAL_PATH incorrect len %d", len(actualPath))
557 } else if actualPath[0] != expectedPath {
558 t.Errorf("LOCAL_PATH mismatch, actual: %s, expected: %s", actualPath[0], expectedPath)
559 }
560
561 if len(actualPrebuiltModuleFile) != 1 {
562 t.Errorf("LOCAL_PREBUILT_MODULE_FILE incorrect len %d", len(actualPrebuiltModuleFile))
563 } else if actualPrebuiltModuleFile[0] != expectedPrebuiltModuleFile {
564 t.Errorf("LOCAL_PREBUILT_MODULE_FILE mismatch, actual: %s, expected: %s", actualPrebuiltModuleFile[0], expectedPrebuiltModuleFile)
565 }
566
567 if len(actualSoongResourceExportPackage) != 1 {
568 t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE incorrect len %d", len(actualSoongResourceExportPackage))
569 } else if actualSoongResourceExportPackage[0] != expectedSoongResourceExportPackage {
570 t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE mismatch, actual: %s, expected: %s", actualSoongResourceExportPackage[0], expectedSoongResourceExportPackage)
571 }
572}
573
Spandan Dasd1fac642021-05-18 17:01:41 +0000574func TestAndroidAppImport_relativeInstallPath(t *testing.T) {
575 bp := `
576 android_app_import {
577 name: "no_relative_install_path",
578 apk: "prebuilts/apk/app.apk",
579 presigned: true,
580 }
581
582 android_app_import {
583 name: "relative_install_path",
584 apk: "prebuilts/apk/app.apk",
585 presigned: true,
586 relative_install_path: "my/path",
587 }
588
589 android_app_import {
590 name: "framework-res",
591 apk: "prebuilts/apk/app.apk",
592 presigned: true,
593 prefer: true,
594 }
595
596 android_app_import {
597 name: "privileged_relative_install_path",
598 apk: "prebuilts/apk/app.apk",
599 presigned: true,
600 privileged: true,
601 relative_install_path: "my/path"
602 }
603 `
604 testCases := []struct {
605 name string
606 expectedInstallPath string
607 errorMessage string
608 }{
609 {
610 name: "no_relative_install_path",
611 expectedInstallPath: "out/soong/target/product/test_device/system/app/no_relative_install_path/no_relative_install_path.apk",
612 errorMessage: "Install path is not correct when relative_install_path is missing",
613 },
614 {
615 name: "relative_install_path",
616 expectedInstallPath: "out/soong/target/product/test_device/system/app/my/path/relative_install_path/relative_install_path.apk",
617 errorMessage: "Install path is not correct for app when relative_install_path is present",
618 },
619 {
620 name: "prebuilt_framework-res",
621 expectedInstallPath: "out/soong/target/product/test_device/system/framework/framework-res.apk",
622 errorMessage: "Install path is not correct for framework-res",
623 },
624 {
625 name: "privileged_relative_install_path",
626 expectedInstallPath: "out/soong/target/product/test_device/system/priv-app/my/path/privileged_relative_install_path/privileged_relative_install_path.apk",
627 errorMessage: "Install path is not correct for privileged app when relative_install_path is present",
628 },
629 }
630 for _, testCase := range testCases {
631 ctx, _ := testJava(t, bp)
632 mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*AndroidAppImport)
633 android.AssertPathRelativeToTopEquals(t, testCase.errorMessage, testCase.expectedInstallPath, mod.installPath)
634 }
635}
636
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800637func TestAndroidTestImport(t *testing.T) {
Colin Crossaa255532020-07-03 13:18:24 -0700638 ctx, _ := testJava(t, `
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800639 android_test_import {
640 name: "foo",
641 apk: "prebuilts/apk/app.apk",
642 presigned: true,
643 data: [
644 "testdata/data",
645 ],
646 }
647 `)
648
649 test := ctx.ModuleForTests("foo", "android_common").Module().(*AndroidTestImport)
650
651 // Check android mks.
Colin Crossaa255532020-07-03 13:18:24 -0700652 entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
Jaewoong Jungf9b44652020-12-21 12:29:12 -0800653 expected := []string{"tests"}
654 actual := entries.EntryMap["LOCAL_MODULE_TAGS"]
655 if !reflect.DeepEqual(expected, actual) {
656 t.Errorf("Unexpected module tags - expected: %q, actual: %q", expected, actual)
657 }
658 expected = []string{"testdata/data:testdata/data"}
659 actual = entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
660 if !reflect.DeepEqual(expected, actual) {
661 t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
662 }
663}
664
665func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
666 ctx, _ := testJava(t, `
667 android_test_import {
668 name: "foo",
669 apk: "prebuilts/apk/app.apk",
670 certificate: "cert/new_cert",
671 data: [
672 "testdata/data",
673 ],
674 }
675
676 android_test_import {
677 name: "foo_presigned",
678 apk: "prebuilts/apk/app.apk",
679 presigned: true,
680 data: [
681 "testdata/data",
682 ],
683 }
684 `)
685
686 variant := ctx.ModuleForTests("foo", "android_common")
687 jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
688 if !strings.HasPrefix(jniRule, "if (zipinfo") {
689 t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
690 }
691
692 variant = ctx.ModuleForTests("foo_presigned", "android_common")
693 jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
694 if jniRule != android.Cp.String() {
695 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
696 }
697 if variant.MaybeOutput("zip-aligned/foo_presigned.apk").Rule == nil {
698 t.Errorf("Presigned test apk should be aligned")
699 }
700}
701
702func TestAndroidTestImport_Preprocessed(t *testing.T) {
703 ctx, _ := testJava(t, `
704 android_test_import {
705 name: "foo",
706 apk: "prebuilts/apk/app.apk",
707 presigned: true,
708 preprocessed: true,
709 }
710
711 android_test_import {
712 name: "foo_cert",
713 apk: "prebuilts/apk/app.apk",
714 certificate: "cert/new_cert",
715 preprocessed: true,
716 }
717 `)
718
719 testModules := []string{"foo", "foo_cert"}
720 for _, m := range testModules {
721 apkName := m + ".apk"
722 variant := ctx.ModuleForTests(m, "android_common")
723 jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
724 if jniRule != android.Cp.String() {
725 t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
726 }
727
728 // Make sure signing and aligning were skipped.
729 if variant.MaybeOutput("signed/"+apkName).Rule != nil {
730 t.Errorf("signing rule shouldn't be included for preprocessed.")
731 }
732 if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
733 t.Errorf("aligning rule shouldn't be for preprocessed")
734 }
735 }
736}
Ulya Trafimovich55f72d72021-09-01 14:13:57 +0100737
738func TestAndroidTestImport_UncompressDex(t *testing.T) {
739 testCases := []struct {
740 name string
741 bp string
742 }{
743 {
744 name: "normal",
745 bp: `
746 android_app_import {
747 name: "foo",
748 presigned: true,
749 apk: "prebuilts/apk/app.apk",
750 }
751 `,
752 },
753 {
754 name: "privileged",
755 bp: `
756 android_app_import {
757 name: "foo",
758 presigned: true,
759 privileged: true,
760 apk: "prebuilts/apk/app.apk",
761 }
762 `,
763 },
764 }
765
766 test := func(t *testing.T, bp string, unbundled bool, dontUncompressPrivAppDexs bool) {
767 t.Helper()
768
769 result := android.GroupFixturePreparers(
770 prepareForJavaTest,
771 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
772 if unbundled {
773 variables.Unbundled_build = proptools.BoolPtr(true)
774 }
775 variables.UncompressPrivAppDex = proptools.BoolPtr(!dontUncompressPrivAppDexs)
776 }),
777 ).RunTestWithBp(t, bp)
778
779 foo := result.ModuleForTests("foo", "android_common")
780 actual := foo.MaybeRule("uncompress-dex").Rule != nil
781
782 expect := !unbundled
783 if strings.Contains(bp, "privileged: true") {
784 if dontUncompressPrivAppDexs {
Ulya Trafimovich0061c0d2021-09-01 15:40:38 +0100785 expect = false
Ulya Trafimovich55f72d72021-09-01 14:13:57 +0100786 } else {
Ulya Trafimovich0061c0d2021-09-01 15:40:38 +0100787 // TODO(b/194504107): shouldn't priv-apps be always uncompressed unless
788 // DONT_UNCOMPRESS_PRIV_APPS_DEXS is true (regardless of unbundling)?
Ulya Trafimovich55f72d72021-09-01 14:13:57 +0100789 // expect = true
790 }
791 }
792
793 android.AssertBoolEquals(t, "uncompress dex", expect, actual)
794 }
795
796 for _, unbundled := range []bool{false, true} {
797 for _, dontUncompressPrivAppDexs := range []bool{false, true} {
798 for _, tt := range testCases {
799 name := fmt.Sprintf("%s,unbundled:%t,dontUncompressPrivAppDexs:%t",
800 tt.name, unbundled, dontUncompressPrivAppDexs)
801 t.Run(name, func(t *testing.T) {
802 test(t, tt.bp, unbundled, dontUncompressPrivAppDexs)
803 })
804 }
805 }
806 }
807}