blob: 21bda3c426d91897a48bd54e7c8007dcc3181593 [file] [log] [blame]
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001// Copyright 2017 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 "android/soong/android"
Colin Crossd09b0b62018-04-18 11:06:47 -070019 "fmt"
Colin Crossa4f08812018-10-02 22:03:40 -070020 "path/filepath"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080021 "reflect"
Colin Crossb69301e2017-12-01 10:48:26 -080022 "sort"
Colin Crossd09b0b62018-04-18 11:06:47 -070023 "strings"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080024 "testing"
25)
26
27var (
28 resourceFiles = []string{
29 "res/layout/layout.xml",
30 "res/values/strings.xml",
31 "res/values-en-rUS/strings.xml",
32 }
33
34 compiledResourceFiles = []string{
35 "aapt2/res/layout_layout.xml.flat",
36 "aapt2/res/values_strings.arsc.flat",
37 "aapt2/res/values-en-rUS_strings.arsc.flat",
38 }
39)
40
Colin Cross527012a2017-11-30 22:56:16 -080041func testAppContext(config android.Config, bp string, fs map[string][]byte) *android.TestContext {
42 appFS := map[string][]byte{}
43 for k, v := range fs {
44 appFS[k] = v
Colin Cross3bc7ffa2017-11-22 16:19:37 -080045 }
46
Colin Cross527012a2017-11-30 22:56:16 -080047 for _, file := range resourceFiles {
48 appFS[file] = nil
49 }
50
51 return testContext(config, bp, appFS)
52}
53
54func testApp(t *testing.T, bp string) *android.TestContext {
55 config := testConfig(nil)
56
57 ctx := testAppContext(config, bp, nil)
58
59 run(t, ctx, config)
60
61 return ctx
Colin Cross3bc7ffa2017-11-22 16:19:37 -080062}
63
64func TestApp(t *testing.T) {
Colin Crossa97c5d32018-03-28 14:58:31 -070065 for _, moduleType := range []string{"android_app", "android_library"} {
66 t.Run(moduleType, func(t *testing.T) {
67 ctx := testApp(t, moduleType+` {
68 name: "foo",
69 srcs: ["a.java"],
70 }
71 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080072
Colin Crossa97c5d32018-03-28 14:58:31 -070073 foo := ctx.ModuleForTests("foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080074
Colin Cross31656952018-05-24 16:11:20 -070075 var expectedLinkImplicits []string
76
77 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
78 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080079
Colin Crossa97c5d32018-03-28 14:58:31 -070080 frameworkRes := ctx.ModuleForTests("framework-res", "android_common")
81 expectedLinkImplicits = append(expectedLinkImplicits,
82 frameworkRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080083
Colin Crossa97c5d32018-03-28 14:58:31 -070084 // Test the mapping from input files to compiled output file names
85 compile := foo.Output(compiledResourceFiles[0])
86 if !reflect.DeepEqual(resourceFiles, compile.Inputs.Strings()) {
87 t.Errorf("expected aapt2 compile inputs expected:\n %#v\n got:\n %#v",
88 resourceFiles, compile.Inputs.Strings())
89 }
Colin Crossb69301e2017-12-01 10:48:26 -080090
Colin Crossa97c5d32018-03-28 14:58:31 -070091 compiledResourceOutputs := compile.Outputs.Strings()
92 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -080093
Colin Crossa97c5d32018-03-28 14:58:31 -070094 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080095
Colin Crossa97c5d32018-03-28 14:58:31 -070096 list := foo.Output("aapt2/res.list")
97 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080098
Colin Crossa97c5d32018-03-28 14:58:31 -070099 // Check that the link rule uses
100 res := ctx.ModuleForTests("foo", "android_common").Output("package-res.apk")
101 if !reflect.DeepEqual(expectedLinkImplicits, res.Implicits.Strings()) {
102 t.Errorf("expected aapt2 link implicits expected:\n %#v\n got:\n %#v",
103 expectedLinkImplicits, res.Implicits.Strings())
104 }
105 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800106 }
107}
Colin Cross890ff552017-11-30 20:13:19 -0800108
109var testEnforceRROTests = []struct {
110 name string
111 enforceRROTargets []string
112 enforceRROExcludedOverlays []string
Anton Hansson0375a4f2019-01-24 14:39:19 +0000113 overlayFiles map[string][]string
114 rroDirs map[string][]string
Colin Cross890ff552017-11-30 20:13:19 -0800115}{
116 {
117 name: "no RRO",
118 enforceRROTargets: nil,
119 enforceRROExcludedOverlays: nil,
Anton Hansson0375a4f2019-01-24 14:39:19 +0000120 overlayFiles: map[string][]string{
121 "foo": []string{
122 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
123 "device/vendor/blah/overlay/foo/res/values/strings.xml",
124 },
125 "bar": []string{
126 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
127 "device/vendor/blah/overlay/bar/res/values/strings.xml",
128 },
Colin Cross890ff552017-11-30 20:13:19 -0800129 },
Anton Hansson0375a4f2019-01-24 14:39:19 +0000130 rroDirs: map[string][]string{
131 "foo": nil,
132 "bar": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800133 },
Colin Cross890ff552017-11-30 20:13:19 -0800134 },
135 {
136 name: "enforce RRO on foo",
137 enforceRROTargets: []string{"foo"},
138 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Anton Hansson0375a4f2019-01-24 14:39:19 +0000139 overlayFiles: map[string][]string{
140 "foo": []string{"device/vendor/blah/static_overlay/foo/res/values/strings.xml"},
141 "bar": []string{
142 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
143 "device/vendor/blah/overlay/bar/res/values/strings.xml",
144 },
Colin Cross890ff552017-11-30 20:13:19 -0800145 },
Anton Hansson0375a4f2019-01-24 14:39:19 +0000146 rroDirs: map[string][]string{
147 "foo": []string{"device/vendor/blah/overlay/foo/res"},
148 "bar": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800149 },
Colin Cross890ff552017-11-30 20:13:19 -0800150 },
151 {
Anton Hansson94c93f32019-01-30 16:03:37 +0000152 name: "enforce RRO on all",
153 enforceRROTargets: []string{"*"},
154 enforceRROExcludedOverlays: []string{
155 // Excluding specific apps/res directories also allowed.
156 "device/vendor/blah/static_overlay/foo",
157 "device/vendor/blah/static_overlay/bar/res",
158 },
Anton Hansson0375a4f2019-01-24 14:39:19 +0000159 overlayFiles: map[string][]string{
160 "foo": []string{"device/vendor/blah/static_overlay/foo/res/values/strings.xml"},
161 "bar": []string{"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
Colin Cross890ff552017-11-30 20:13:19 -0800162 },
Anton Hansson0375a4f2019-01-24 14:39:19 +0000163 rroDirs: map[string][]string{
164 "foo": []string{"device/vendor/blah/overlay/foo/res"},
165 "bar": []string{"device/vendor/blah/overlay/bar/res"},
Colin Cross890ff552017-11-30 20:13:19 -0800166 },
167 },
168}
169
170func TestEnforceRRO(t *testing.T) {
171 resourceOverlays := []string{
172 "device/vendor/blah/overlay",
173 "device/vendor/blah/overlay2",
174 "device/vendor/blah/static_overlay",
175 }
176
177 fs := map[string][]byte{
178 "foo/res/res/values/strings.xml": nil,
179 "bar/res/res/values/strings.xml": nil,
180 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
181 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
182 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
183 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
184 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
185 }
186
187 bp := `
188 android_app {
189 name: "foo",
190 resource_dirs: ["foo/res"],
191 }
192
193 android_app {
194 name: "bar",
195 resource_dirs: ["bar/res"],
196 }
197 `
198
199 for _, testCase := range testEnforceRROTests {
200 t.Run(testCase.name, func(t *testing.T) {
201 config := testConfig(nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700202 config.TestProductVariables.ResourceOverlays = &resourceOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800203 if testCase.enforceRROTargets != nil {
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700204 config.TestProductVariables.EnforceRROTargets = &testCase.enforceRROTargets
Colin Cross890ff552017-11-30 20:13:19 -0800205 }
206 if testCase.enforceRROExcludedOverlays != nil {
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700207 config.TestProductVariables.EnforceRROExcludedOverlays = &testCase.enforceRROExcludedOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800208 }
209
210 ctx := testAppContext(config, bp, fs)
211 run(t, ctx, config)
212
213 getOverlays := func(moduleName string) ([]string, []string) {
214 module := ctx.ModuleForTests(moduleName, "android_common")
Anton Hansson94c93f32019-01-30 16:03:37 +0000215 overlayFile := module.MaybeOutput("aapt2/overlay.list")
Colin Cross890ff552017-11-30 20:13:19 -0800216 var overlayFiles []string
Anton Hansson94c93f32019-01-30 16:03:37 +0000217 if overlayFile.Rule != nil {
218 for _, o := range overlayFile.Inputs.Strings() {
219 overlayFiles = append(overlayFiles, module.Output(o).Inputs.Strings()...)
220 }
Colin Cross890ff552017-11-30 20:13:19 -0800221 }
222
223 rroDirs := module.Module().(*AndroidApp).rroDirs.Strings()
224
225 return overlayFiles, rroDirs
226 }
227
Anton Hansson0375a4f2019-01-24 14:39:19 +0000228 apps := []string{"foo", "bar"}
229 for _, app := range apps {
230 overlayFiles, rroDirs := getOverlays(app)
Colin Cross890ff552017-11-30 20:13:19 -0800231
Anton Hansson0375a4f2019-01-24 14:39:19 +0000232 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[app]) {
233 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
234 app, testCase.overlayFiles[app], overlayFiles)
235 }
236 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[app]) {
237 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
238 app, testCase.rroDirs[app], rroDirs)
239 }
Colin Cross890ff552017-11-30 20:13:19 -0800240 }
Colin Cross890ff552017-11-30 20:13:19 -0800241 })
242 }
243}
Colin Crossd09b0b62018-04-18 11:06:47 -0700244
245func TestAppSdkVersion(t *testing.T) {
246 testCases := []struct {
247 name string
248 sdkVersion string
249 platformSdkInt int
250 platformSdkCodename string
251 platformSdkFinal bool
252 expectedMinSdkVersion string
253 }{
254 {
255 name: "current final SDK",
256 sdkVersion: "current",
257 platformSdkInt: 27,
258 platformSdkCodename: "REL",
259 platformSdkFinal: true,
260 expectedMinSdkVersion: "27",
261 },
262 {
263 name: "current non-final SDK",
264 sdkVersion: "current",
265 platformSdkInt: 27,
266 platformSdkCodename: "OMR1",
267 platformSdkFinal: false,
268 expectedMinSdkVersion: "OMR1",
269 },
270 {
271 name: "default final SDK",
272 sdkVersion: "",
273 platformSdkInt: 27,
274 platformSdkCodename: "REL",
275 platformSdkFinal: true,
276 expectedMinSdkVersion: "27",
277 },
278 {
279 name: "default non-final SDK",
280 sdkVersion: "",
281 platformSdkInt: 27,
282 platformSdkCodename: "OMR1",
283 platformSdkFinal: false,
284 expectedMinSdkVersion: "OMR1",
285 },
286 {
287 name: "14",
288 sdkVersion: "14",
289 expectedMinSdkVersion: "14",
290 },
291 }
292
293 for _, moduleType := range []string{"android_app", "android_library"} {
294 for _, test := range testCases {
295 t.Run(moduleType+" "+test.name, func(t *testing.T) {
296 bp := fmt.Sprintf(`%s {
297 name: "foo",
298 srcs: ["a.java"],
299 sdk_version: "%s",
300 }`, moduleType, test.sdkVersion)
301
302 config := testConfig(nil)
303 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
304 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
305 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
306
307 ctx := testAppContext(config, bp, nil)
308
309 run(t, ctx, config)
310
311 foo := ctx.ModuleForTests("foo", "android_common")
312 link := foo.Output("package-res.apk")
313 linkFlags := strings.Split(link.Args["flags"], " ")
314 min := android.IndexList("--min-sdk-version", linkFlags)
315 target := android.IndexList("--target-sdk-version", linkFlags)
316
317 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
318 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
319 }
320
321 gotMinSdkVersion := linkFlags[min+1]
322 gotTargetSdkVersion := linkFlags[target+1]
323
324 if gotMinSdkVersion != test.expectedMinSdkVersion {
325 t.Errorf("incorrect --min-sdk-version, expected %q got %q",
326 test.expectedMinSdkVersion, gotMinSdkVersion)
327 }
328
329 if gotTargetSdkVersion != test.expectedMinSdkVersion {
330 t.Errorf("incorrect --target-sdk-version, expected %q got %q",
331 test.expectedMinSdkVersion, gotTargetSdkVersion)
332 }
333 })
334 }
335 }
336}
Colin Crossa4f08812018-10-02 22:03:40 -0700337
338func TestJNI(t *testing.T) {
339 ctx := testJava(t, `
340 toolchain_library {
341 name: "libcompiler_rt-extras",
342 src: "",
343 }
344
345 toolchain_library {
346 name: "libatomic",
347 src: "",
348 }
349
350 toolchain_library {
351 name: "libgcc",
352 src: "",
353 }
354
355 toolchain_library {
356 name: "libclang_rt.builtins-aarch64-android",
357 src: "",
358 }
359
360 toolchain_library {
361 name: "libclang_rt.builtins-arm-android",
362 src: "",
363 }
364
365 cc_object {
366 name: "crtbegin_so",
367 stl: "none",
368 }
369
370 cc_object {
371 name: "crtend_so",
372 stl: "none",
373 }
374
375 cc_library {
376 name: "libjni",
377 system_shared_libs: [],
378 stl: "none",
379 }
380
381 android_test {
382 name: "test",
383 no_framework_libs: true,
384 jni_libs: ["libjni"],
385 }
386
387 android_test {
388 name: "test_first",
389 no_framework_libs: true,
390 compile_multilib: "first",
391 jni_libs: ["libjni"],
392 }
393
394 android_test {
395 name: "test_both",
396 no_framework_libs: true,
397 compile_multilib: "both",
398 jni_libs: ["libjni"],
399 }
400
401 android_test {
402 name: "test_32",
403 no_framework_libs: true,
404 compile_multilib: "32",
405 jni_libs: ["libjni"],
406 }
407
408 android_test {
409 name: "test_64",
410 no_framework_libs: true,
411 compile_multilib: "64",
412 jni_libs: ["libjni"],
413 }
414 `)
415
416 // check the existence of the internal modules
417 ctx.ModuleForTests("test", "android_common")
418 ctx.ModuleForTests("test_first", "android_common")
419 ctx.ModuleForTests("test_both", "android_common")
420 ctx.ModuleForTests("test_32", "android_common")
421 ctx.ModuleForTests("test_64", "android_common")
422
423 testCases := []struct {
424 name string
425 abis []string
426 }{
427 {"test", []string{"arm64-v8a"}},
428 {"test_first", []string{"arm64-v8a"}},
429 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
430 {"test_32", []string{"armeabi-v7a"}},
431 {"test_64", []string{"arm64-v8a"}},
432 }
433
434 for _, test := range testCases {
435 t.Run(test.name, func(t *testing.T) {
436 app := ctx.ModuleForTests(test.name, "android_common")
437 jniLibZip := app.Output("jnilibs.zip")
438 var abis []string
439 args := strings.Fields(jniLibZip.Args["jarArgs"])
440 for i := 0; i < len(args); i++ {
441 if args[i] == "-P" {
442 abis = append(abis, filepath.Base(args[i+1]))
443 i++
444 }
445 }
446 if !reflect.DeepEqual(abis, test.abis) {
447 t.Errorf("want abis %v, got %v", test.abis, abis)
448 }
449 })
450 }
451}
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800452
453func TestCertificates(t *testing.T) {
454 testCases := []struct {
455 name string
456 bp string
457 certificateOverride string
458 expected string
459 }{
460 {
461 name: "default",
462 bp: `
463 android_app {
464 name: "foo",
465 srcs: ["a.java"],
466 }
467 `,
468 certificateOverride: "",
469 expected: "build/target/product/security/testkey.x509.pem build/target/product/security/testkey.pk8",
470 },
471 {
472 name: "module certificate property",
473 bp: `
474 android_app {
475 name: "foo",
476 srcs: ["a.java"],
477 certificate: ":new_certificate"
478 }
479
480 android_app_certificate {
481 name: "new_certificate",
482 certificate: "cert/new_cert",
483 }
484 `,
485 certificateOverride: "",
486 expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
487 },
488 {
489 name: "path certificate property",
490 bp: `
491 android_app {
492 name: "foo",
493 srcs: ["a.java"],
494 certificate: "expiredkey"
495 }
496 `,
497 certificateOverride: "",
498 expected: "build/target/product/security/expiredkey.x509.pem build/target/product/security/expiredkey.pk8",
499 },
500 {
501 name: "certificate overrides",
502 bp: `
503 android_app {
504 name: "foo",
505 srcs: ["a.java"],
506 certificate: "expiredkey"
507 }
508
509 android_app_certificate {
510 name: "new_certificate",
511 certificate: "cert/new_cert",
512 }
513 `,
514 certificateOverride: "foo:new_certificate",
515 expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
516 },
517 }
518
519 for _, test := range testCases {
520 t.Run(test.name, func(t *testing.T) {
521 config := testConfig(nil)
522 if test.certificateOverride != "" {
523 config.TestProductVariables.CertificateOverrides = []string{test.certificateOverride}
524 }
525 ctx := testAppContext(config, test.bp, nil)
526
527 run(t, ctx, config)
528 foo := ctx.ModuleForTests("foo", "android_common")
529
530 signapk := foo.Output("foo.apk")
531 signFlags := signapk.Args["certificates"]
532 if test.expected != signFlags {
533 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
534 }
535 })
536 }
537}
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800538
539func TestPackageNameOverride(t *testing.T) {
540 testCases := []struct {
541 name string
542 bp string
543 packageNameOverride string
544 expected []string
545 }{
546 {
547 name: "default",
548 bp: `
549 android_app {
550 name: "foo",
551 srcs: ["a.java"],
552 }
553 `,
554 packageNameOverride: "",
555 expected: []string{
556 buildDir + "/.intermediates/foo/android_common/foo.apk",
557 buildDir + "/target/product/test_device/system/app/foo/foo.apk",
558 },
559 },
560 {
561 name: "overridden",
562 bp: `
563 android_app {
564 name: "foo",
565 srcs: ["a.java"],
566 }
567 `,
568 packageNameOverride: "foo:bar",
569 expected: []string{
570 // The package apk should be still be the original name for test dependencies.
571 buildDir + "/.intermediates/foo/android_common/foo.apk",
572 buildDir + "/target/product/test_device/system/app/bar/bar.apk",
573 },
574 },
575 }
576
577 for _, test := range testCases {
578 t.Run(test.name, func(t *testing.T) {
579 config := testConfig(nil)
580 if test.packageNameOverride != "" {
581 config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
582 }
583 ctx := testAppContext(config, test.bp, nil)
584
585 run(t, ctx, config)
586 foo := ctx.ModuleForTests("foo", "android_common")
587
588 outputs := foo.AllOutputs()
589 outputMap := make(map[string]bool)
590 for _, o := range outputs {
591 outputMap[o] = true
592 }
593 for _, e := range test.expected {
594 if _, exist := outputMap[e]; !exist {
595 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
596 }
597 }
598 })
599 }
600}