1// Copyright 2018 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 apex 16 17import ( 18 "io/ioutil" 19 "os" 20 "strings" 21 "testing" 22 23 "github.com/google/blueprint/proptools" 24 25 "android/soong/android" 26 "android/soong/cc" 27 "android/soong/java" 28) 29 30var buildDir string 31 32func testApex(t *testing.T, bp string) *android.TestContext { 33 var config android.Config 34 config, buildDir = setup(t) 35 defer teardown(buildDir) 36 37 ctx := android.NewTestArchContext() 38 ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apexBundleFactory)) 39 ctx.RegisterModuleType("apex_test", android.ModuleFactoryAdaptor(testApexBundleFactory)) 40 ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apexKeyFactory)) 41 ctx.RegisterModuleType("apex_defaults", android.ModuleFactoryAdaptor(defaultsFactory)) 42 ctx.RegisterModuleType("prebuilt_apex", android.ModuleFactoryAdaptor(PrebuiltFactory)) 43 ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) 44 45 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { 46 ctx.TopDown("apex_deps", apexDepsMutator) 47 ctx.BottomUp("apex", apexMutator) 48 ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel() 49 ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel() 50 }) 51 52 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory)) 53 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory)) 54 ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(cc.LibraryHeaderFactory)) 55 ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(cc.BinaryFactory)) 56 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory)) 57 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory)) 58 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory)) 59 ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory)) 60 ctx.RegisterModuleType("sh_binary", android.ModuleFactoryAdaptor(android.ShBinaryFactory)) 61 ctx.RegisterModuleType("android_app_certificate", android.ModuleFactoryAdaptor(java.AndroidAppCertificateFactory)) 62 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory)) 63 ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) { 64 ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel() 65 }) 66 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { 67 ctx.BottomUp("image", cc.ImageMutator).Parallel() 68 ctx.BottomUp("link", cc.LinkageMutator).Parallel() 69 ctx.BottomUp("vndk", cc.VndkMutator).Parallel() 70 ctx.BottomUp("version", cc.VersionMutator).Parallel() 71 ctx.BottomUp("begin", cc.BeginMutator).Parallel() 72 }) 73 74 ctx.Register() 75 76 bp = bp + ` 77 toolchain_library { 78 name: "libcompiler_rt-extras", 79 src: "", 80 vendor_available: true, 81 recovery_available: true, 82 } 83 84 toolchain_library { 85 name: "libatomic", 86 src: "", 87 vendor_available: true, 88 recovery_available: true, 89 } 90 91 toolchain_library { 92 name: "libgcc", 93 src: "", 94 vendor_available: true, 95 recovery_available: true, 96 } 97 98 toolchain_library { 99 name: "libgcc_stripped", 100 src: "", 101 vendor_available: true, 102 recovery_available: true, 103 } 104 105 toolchain_library { 106 name: "libclang_rt.builtins-aarch64-android", 107 src: "", 108 vendor_available: true, 109 recovery_available: true, 110 } 111 112 toolchain_library { 113 name: "libclang_rt.builtins-arm-android", 114 src: "", 115 vendor_available: true, 116 recovery_available: true, 117 } 118 119 cc_object { 120 name: "crtbegin_so", 121 stl: "none", 122 vendor_available: true, 123 recovery_available: true, 124 } 125 126 cc_object { 127 name: "crtend_so", 128 stl: "none", 129 vendor_available: true, 130 recovery_available: true, 131 } 132 133 cc_object { 134 name: "crtbegin_static", 135 stl: "none", 136 } 137 138 cc_object { 139 name: "crtend_android", 140 stl: "none", 141 } 142 143 llndk_library { 144 name: "libc", 145 symbol_file: "", 146 } 147 148 llndk_library { 149 name: "libm", 150 symbol_file: "", 151 } 152 153 llndk_library { 154 name: "libdl", 155 symbol_file: "", 156 } 157 ` 158 159 ctx.MockFileSystem(map[string][]byte{ 160 "Android.bp": []byte(bp), 161 "build/target/product/security": nil, 162 "apex_manifest.json": nil, 163 "AndroidManifest.xml": nil, 164 "system/sepolicy/apex/myapex-file_contexts": nil, 165 "system/sepolicy/apex/myapex_keytest-file_contexts": nil, 166 "system/sepolicy/apex/otherapex-file_contexts": nil, 167 "mylib.cpp": nil, 168 "myprebuilt": nil, 169 "my_include": nil, 170 "vendor/foo/devkeys/test.x509.pem": nil, 171 "vendor/foo/devkeys/test.pk8": nil, 172 "testkey.x509.pem": nil, 173 "testkey.pk8": nil, 174 "testkey.override.x509.pem": nil, 175 "testkey.override.pk8": nil, 176 "vendor/foo/devkeys/testkey.avbpubkey": nil, 177 "vendor/foo/devkeys/testkey.pem": nil, 178 "NOTICE": nil, 179 "custom_notice": nil, 180 "testkey2.avbpubkey": nil, 181 "testkey2.pem": nil, 182 "myapex-arm64.apex": nil, 183 "myapex-arm.apex": nil, 184 "frameworks/base/api/current.txt": nil, 185 }) 186 _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) 187 android.FailIfErrored(t, errs) 188 _, errs = ctx.PrepareBuildActions(config) 189 android.FailIfErrored(t, errs) 190 191 return ctx 192} 193 194func setup(t *testing.T) (config android.Config, buildDir string) { 195 buildDir, err := ioutil.TempDir("", "soong_apex_test") 196 if err != nil { 197 t.Fatal(err) 198 } 199 200 config = android.TestArchConfig(buildDir, nil) 201 config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current") 202 config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test") 203 config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"} 204 config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q") 205 config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false) 206 return 207} 208 209func teardown(buildDir string) { 210 os.RemoveAll(buildDir) 211} 212 213// ensure that 'result' contains 'expected' 214func ensureContains(t *testing.T, result string, expected string) { 215 if !strings.Contains(result, expected) { 216 t.Errorf("%q is not found in %q", expected, result) 217 } 218} 219 220// ensures that 'result' does not contain 'notExpected' 221func ensureNotContains(t *testing.T, result string, notExpected string) { 222 if strings.Contains(result, notExpected) { 223 t.Errorf("%q is found in %q", notExpected, result) 224 } 225} 226 227func ensureListContains(t *testing.T, result []string, expected string) { 228 if !android.InList(expected, result) { 229 t.Errorf("%q is not found in %v", expected, result) 230 } 231} 232 233func ensureListNotContains(t *testing.T, result []string, notExpected string) { 234 if android.InList(notExpected, result) { 235 t.Errorf("%q is found in %v", notExpected, result) 236 } 237} 238 239// Minimal test 240func TestBasicApex(t *testing.T) { 241 ctx := testApex(t, ` 242 apex_defaults { 243 name: "myapex-defaults", 244 manifest: ":myapex.manifest", 245 androidManifest: ":myapex.androidmanifest", 246 key: "myapex.key", 247 native_shared_libs: ["mylib"], 248 multilib: { 249 both: { 250 binaries: ["foo",], 251 } 252 } 253 } 254 255 apex { 256 name: "myapex", 257 defaults: ["myapex-defaults"], 258 } 259 260 apex_key { 261 name: "myapex.key", 262 public_key: "testkey.avbpubkey", 263 private_key: "testkey.pem", 264 } 265 266 filegroup { 267 name: "myapex.manifest", 268 srcs: ["apex_manifest.json"], 269 } 270 271 filegroup { 272 name: "myapex.androidmanifest", 273 srcs: ["AndroidManifest.xml"], 274 } 275 276 cc_library { 277 name: "mylib", 278 srcs: ["mylib.cpp"], 279 shared_libs: ["mylib2"], 280 system_shared_libs: [], 281 stl: "none", 282 } 283 284 cc_binary { 285 name: "foo", 286 srcs: ["mylib.cpp"], 287 compile_multilib: "both", 288 multilib: { 289 lib32: { 290 suffix: "32", 291 }, 292 lib64: { 293 suffix: "64", 294 }, 295 }, 296 symlinks: ["foo_link_"], 297 symlink_preferred_arch: true, 298 system_shared_libs: [], 299 static_executable: true, 300 stl: "none", 301 } 302 303 cc_library { 304 name: "mylib2", 305 srcs: ["mylib.cpp"], 306 system_shared_libs: [], 307 stl: "none", 308 notice: "custom_notice", 309 } 310 `) 311 312 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 313 314 optFlags := apexRule.Args["opt_flags"] 315 ensureContains(t, optFlags, "--pubkey vendor/foo/devkeys/testkey.avbpubkey") 316 // Ensure that the NOTICE output is being packaged as an asset. 317 ensureContains(t, optFlags, "--assets_dir "+buildDir+"/.intermediates/myapex/android_common_myapex/NOTICE") 318 319 copyCmds := apexRule.Args["copy_commands"] 320 321 // Ensure that main rule creates an output 322 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 323 324 // Ensure that apex variant is created for the direct dep 325 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared_myapex") 326 327 // Ensure that apex variant is created for the indirect dep 328 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared_myapex") 329 330 // Ensure that both direct and indirect deps are copied into apex 331 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 332 ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so") 333 334 // Ensure that the platform variant ends with _core_shared 335 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared") 336 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared") 337 338 // Ensure that all symlinks are present. 339 found_foo_link_64 := false 340 found_foo := false 341 for _, cmd := range strings.Split(copyCmds, " && ") { 342 if strings.HasPrefix(cmd, "ln -s foo64") { 343 if strings.HasSuffix(cmd, "bin/foo") { 344 found_foo = true 345 } else if strings.HasSuffix(cmd, "bin/foo_link_64") { 346 found_foo_link_64 = true 347 } 348 } 349 } 350 good := found_foo && found_foo_link_64 351 if !good { 352 t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds) 353 } 354 355 mergeNoticesRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("mergeNoticesRule") 356 noticeInputs := mergeNoticesRule.Inputs.Strings() 357 if len(noticeInputs) != 2 { 358 t.Errorf("number of input notice files: expected = 2, actual = %q", len(noticeInputs)) 359 } 360 ensureListContains(t, noticeInputs, "NOTICE") 361 ensureListContains(t, noticeInputs, "custom_notice") 362} 363 364func TestBasicZipApex(t *testing.T) { 365 ctx := testApex(t, ` 366 apex { 367 name: "myapex", 368 key: "myapex.key", 369 payload_type: "zip", 370 native_shared_libs: ["mylib"], 371 } 372 373 apex_key { 374 name: "myapex.key", 375 public_key: "testkey.avbpubkey", 376 private_key: "testkey.pem", 377 } 378 379 cc_library { 380 name: "mylib", 381 srcs: ["mylib.cpp"], 382 shared_libs: ["mylib2"], 383 system_shared_libs: [], 384 stl: "none", 385 } 386 387 cc_library { 388 name: "mylib2", 389 srcs: ["mylib.cpp"], 390 system_shared_libs: [], 391 stl: "none", 392 } 393 `) 394 395 zipApexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("zipApexRule") 396 copyCmds := zipApexRule.Args["copy_commands"] 397 398 // Ensure that main rule creates an output 399 ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned") 400 401 // Ensure that APEX variant is created for the direct dep 402 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared_myapex") 403 404 // Ensure that APEX variant is created for the indirect dep 405 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared_myapex") 406 407 // Ensure that both direct and indirect deps are copied into apex 408 ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so") 409 ensureContains(t, copyCmds, "image.zipapex/lib64/mylib2.so") 410} 411 412func TestApexWithStubs(t *testing.T) { 413 ctx := testApex(t, ` 414 apex { 415 name: "myapex", 416 key: "myapex.key", 417 native_shared_libs: ["mylib", "mylib3"], 418 } 419 420 apex_key { 421 name: "myapex.key", 422 public_key: "testkey.avbpubkey", 423 private_key: "testkey.pem", 424 } 425 426 cc_library { 427 name: "mylib", 428 srcs: ["mylib.cpp"], 429 shared_libs: ["mylib2", "mylib3"], 430 system_shared_libs: [], 431 stl: "none", 432 } 433 434 cc_library { 435 name: "mylib2", 436 srcs: ["mylib.cpp"], 437 cflags: ["-include mylib.h"], 438 system_shared_libs: [], 439 stl: "none", 440 stubs: { 441 versions: ["1", "2", "3"], 442 }, 443 } 444 445 cc_library { 446 name: "mylib3", 447 srcs: ["mylib.cpp"], 448 shared_libs: ["mylib4"], 449 system_shared_libs: [], 450 stl: "none", 451 stubs: { 452 versions: ["10", "11", "12"], 453 }, 454 } 455 456 cc_library { 457 name: "mylib4", 458 srcs: ["mylib.cpp"], 459 system_shared_libs: [], 460 stl: "none", 461 } 462 `) 463 464 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 465 copyCmds := apexRule.Args["copy_commands"] 466 467 // Ensure that direct non-stubs dep is always included 468 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 469 470 // Ensure that indirect stubs dep is not included 471 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 472 473 // Ensure that direct stubs dep is included 474 ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so") 475 476 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_shared_myapex").Rule("ld").Args["libFlags"] 477 478 // Ensure that mylib is linking with the latest version of stubs for mylib2 479 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_core_shared_3_myapex/mylib2.so") 480 // ... and not linking to the non-stub (impl) variant of mylib2 481 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_core_shared_myapex/mylib2.so") 482 483 // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex) 484 ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_core_shared_myapex/mylib3.so") 485 // .. and not linking to the stubs variant of mylib3 486 ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_core_shared_12_myapex/mylib3.so") 487 488 // Ensure that stubs libs are built without -include flags 489 mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_core_static_myapex").Rule("cc").Args["cFlags"] 490 ensureNotContains(t, mylib2Cflags, "-include ") 491 492 // Ensure that genstub is invoked with --apex 493 ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_core_static_3_myapex").Rule("genStubSrc").Args["flags"]) 494} 495 496func TestApexWithExplicitStubsDependency(t *testing.T) { 497 ctx := testApex(t, ` 498 apex { 499 name: "myapex", 500 key: "myapex.key", 501 native_shared_libs: ["mylib"], 502 } 503 504 apex_key { 505 name: "myapex.key", 506 public_key: "testkey.avbpubkey", 507 private_key: "testkey.pem", 508 } 509 510 cc_library { 511 name: "mylib", 512 srcs: ["mylib.cpp"], 513 shared_libs: ["libfoo#10"], 514 system_shared_libs: [], 515 stl: "none", 516 } 517 518 cc_library { 519 name: "libfoo", 520 srcs: ["mylib.cpp"], 521 shared_libs: ["libbar"], 522 system_shared_libs: [], 523 stl: "none", 524 stubs: { 525 versions: ["10", "20", "30"], 526 }, 527 } 528 529 cc_library { 530 name: "libbar", 531 srcs: ["mylib.cpp"], 532 system_shared_libs: [], 533 stl: "none", 534 } 535 536 `) 537 538 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 539 copyCmds := apexRule.Args["copy_commands"] 540 541 // Ensure that direct non-stubs dep is always included 542 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 543 544 // Ensure that indirect stubs dep is not included 545 ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so") 546 547 // Ensure that dependency of stubs is not included 548 ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so") 549 550 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_shared_myapex").Rule("ld").Args["libFlags"] 551 552 // Ensure that mylib is linking with version 10 of libfoo 553 ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_core_shared_10_myapex/libfoo.so") 554 // ... and not linking to the non-stub (impl) variant of libfoo 555 ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_core_shared_myapex/libfoo.so") 556 557 libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_core_shared_10_myapex").Rule("ld").Args["libFlags"] 558 559 // Ensure that libfoo stubs is not linking to libbar (since it is a stubs) 560 ensureNotContains(t, libFooStubsLdFlags, "libbar.so") 561} 562 563func TestApexWithSystemLibsStubs(t *testing.T) { 564 ctx := testApex(t, ` 565 apex { 566 name: "myapex", 567 key: "myapex.key", 568 native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"], 569 } 570 571 apex_key { 572 name: "myapex.key", 573 public_key: "testkey.avbpubkey", 574 private_key: "testkey.pem", 575 } 576 577 cc_library { 578 name: "mylib", 579 srcs: ["mylib.cpp"], 580 shared_libs: ["libdl#27"], 581 stl: "none", 582 } 583 584 cc_library_shared { 585 name: "mylib_shared", 586 srcs: ["mylib.cpp"], 587 shared_libs: ["libdl#27"], 588 stl: "none", 589 } 590 591 cc_library { 592 name: "libc", 593 no_libgcc: true, 594 nocrt: true, 595 system_shared_libs: [], 596 stl: "none", 597 stubs: { 598 versions: ["27", "28", "29"], 599 }, 600 } 601 602 cc_library { 603 name: "libm", 604 no_libgcc: true, 605 nocrt: true, 606 system_shared_libs: [], 607 stl: "none", 608 stubs: { 609 versions: ["27", "28", "29"], 610 }, 611 } 612 613 cc_library { 614 name: "libdl", 615 no_libgcc: true, 616 nocrt: true, 617 system_shared_libs: [], 618 stl: "none", 619 stubs: { 620 versions: ["27", "28", "29"], 621 }, 622 } 623 624 cc_library { 625 name: "libBootstrap", 626 srcs: ["mylib.cpp"], 627 stl: "none", 628 bootstrap: true, 629 } 630 `) 631 632 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 633 copyCmds := apexRule.Args["copy_commands"] 634 635 // Ensure that mylib, libm, libdl are included. 636 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 637 ensureContains(t, copyCmds, "image.apex/lib64/bionic/libm.so") 638 ensureContains(t, copyCmds, "image.apex/lib64/bionic/libdl.so") 639 640 // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs) 641 ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so") 642 643 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_shared_myapex").Rule("ld").Args["libFlags"] 644 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_myapex").Rule("cc").Args["cFlags"] 645 mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_core_shared_myapex").Rule("cc").Args["cFlags"] 646 647 // For dependency to libc 648 // Ensure that mylib is linking with the latest version of stubs 649 ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_core_shared_29_myapex/libc.so") 650 // ... and not linking to the non-stub (impl) variant 651 ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_core_shared_myapex/libc.so") 652 // ... Cflags from stub is correctly exported to mylib 653 ensureContains(t, mylibCFlags, "__LIBC_API__=29") 654 ensureContains(t, mylibSharedCFlags, "__LIBC_API__=29") 655 656 // For dependency to libm 657 // Ensure that mylib is linking with the non-stub (impl) variant 658 ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_core_shared_myapex/libm.so") 659 // ... and not linking to the stub variant 660 ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_core_shared_29_myapex/libm.so") 661 // ... and is not compiling with the stub 662 ensureNotContains(t, mylibCFlags, "__LIBM_API__=29") 663 ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29") 664 665 // For dependency to libdl 666 // Ensure that mylib is linking with the specified version of stubs 667 ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_core_shared_27_myapex/libdl.so") 668 // ... and not linking to the other versions of stubs 669 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_core_shared_28_myapex/libdl.so") 670 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_core_shared_29_myapex/libdl.so") 671 // ... and not linking to the non-stub (impl) variant 672 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_core_shared_myapex/libdl.so") 673 // ... Cflags from stub is correctly exported to mylib 674 ensureContains(t, mylibCFlags, "__LIBDL_API__=27") 675 ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27") 676 677 // Ensure that libBootstrap is depending on the platform variant of bionic libs 678 libFlags := ctx.ModuleForTests("libBootstrap", "android_arm64_armv8-a_core_shared").Rule("ld").Args["libFlags"] 679 ensureContains(t, libFlags, "libc/android_arm64_armv8-a_core_shared/libc.so") 680 ensureContains(t, libFlags, "libm/android_arm64_armv8-a_core_shared/libm.so") 681 ensureContains(t, libFlags, "libdl/android_arm64_armv8-a_core_shared/libdl.so") 682} 683 684func TestFilesInSubDir(t *testing.T) { 685 ctx := testApex(t, ` 686 apex { 687 name: "myapex", 688 key: "myapex.key", 689 native_shared_libs: ["mylib"], 690 binaries: ["mybin"], 691 prebuilts: ["myetc"], 692 compile_multilib: "both", 693 } 694 695 apex_key { 696 name: "myapex.key", 697 public_key: "testkey.avbpubkey", 698 private_key: "testkey.pem", 699 } 700 701 prebuilt_etc { 702 name: "myetc", 703 src: "myprebuilt", 704 sub_dir: "foo/bar", 705 } 706 707 cc_library { 708 name: "mylib", 709 srcs: ["mylib.cpp"], 710 relative_install_path: "foo/bar", 711 system_shared_libs: [], 712 stl: "none", 713 } 714 715 cc_binary { 716 name: "mybin", 717 srcs: ["mylib.cpp"], 718 relative_install_path: "foo/bar", 719 system_shared_libs: [], 720 static_executable: true, 721 stl: "none", 722 } 723 `) 724 725 generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("generateFsConfig") 726 dirs := strings.Split(generateFsRule.Args["exec_paths"], " ") 727 728 // Ensure that the subdirectories are all listed 729 ensureListContains(t, dirs, "etc") 730 ensureListContains(t, dirs, "etc/foo") 731 ensureListContains(t, dirs, "etc/foo/bar") 732 ensureListContains(t, dirs, "lib64") 733 ensureListContains(t, dirs, "lib64/foo") 734 ensureListContains(t, dirs, "lib64/foo/bar") 735 ensureListContains(t, dirs, "lib") 736 ensureListContains(t, dirs, "lib/foo") 737 ensureListContains(t, dirs, "lib/foo/bar") 738 739 ensureListContains(t, dirs, "bin") 740 ensureListContains(t, dirs, "bin/foo") 741 ensureListContains(t, dirs, "bin/foo/bar") 742} 743 744func TestUseVendor(t *testing.T) { 745 ctx := testApex(t, ` 746 apex { 747 name: "myapex", 748 key: "myapex.key", 749 native_shared_libs: ["mylib"], 750 use_vendor: true, 751 } 752 753 apex_key { 754 name: "myapex.key", 755 public_key: "testkey.avbpubkey", 756 private_key: "testkey.pem", 757 } 758 759 cc_library { 760 name: "mylib", 761 srcs: ["mylib.cpp"], 762 shared_libs: ["mylib2"], 763 system_shared_libs: [], 764 vendor_available: true, 765 stl: "none", 766 } 767 768 cc_library { 769 name: "mylib2", 770 srcs: ["mylib.cpp"], 771 system_shared_libs: [], 772 vendor_available: true, 773 stl: "none", 774 } 775 `) 776 777 inputsList := []string{} 778 for _, i := range ctx.ModuleForTests("myapex", "android_common_myapex").Module().BuildParamsForTests() { 779 for _, implicit := range i.Implicits { 780 inputsList = append(inputsList, implicit.String()) 781 } 782 } 783 inputsString := strings.Join(inputsList, " ") 784 785 // ensure that the apex includes vendor variants of the direct and indirect deps 786 ensureContains(t, inputsString, "android_arm64_armv8-a_vendor_shared_myapex/mylib.so") 787 ensureContains(t, inputsString, "android_arm64_armv8-a_vendor_shared_myapex/mylib2.so") 788 789 // ensure that the apex does not include core variants 790 ensureNotContains(t, inputsString, "android_arm64_armv8-a_core_shared_myapex/mylib.so") 791 ensureNotContains(t, inputsString, "android_arm64_armv8-a_core_shared_myapex/mylib2.so") 792} 793 794func TestStaticLinking(t *testing.T) { 795 ctx := testApex(t, ` 796 apex { 797 name: "myapex", 798 key: "myapex.key", 799 native_shared_libs: ["mylib"], 800 } 801 802 apex_key { 803 name: "myapex.key", 804 public_key: "testkey.avbpubkey", 805 private_key: "testkey.pem", 806 } 807 808 cc_library { 809 name: "mylib", 810 srcs: ["mylib.cpp"], 811 system_shared_libs: [], 812 stl: "none", 813 stubs: { 814 versions: ["1", "2", "3"], 815 }, 816 } 817 818 cc_binary { 819 name: "not_in_apex", 820 srcs: ["mylib.cpp"], 821 static_libs: ["mylib"], 822 static_executable: true, 823 system_shared_libs: [], 824 stl: "none", 825 } 826 `) 827 828 ldFlags := ctx.ModuleForTests("not_in_apex", "android_arm64_armv8-a_core").Rule("ld").Args["libFlags"] 829 830 // Ensure that not_in_apex is linking with the static variant of mylib 831 ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_core_static/mylib.a") 832} 833 834func TestKeys(t *testing.T) { 835 ctx := testApex(t, ` 836 apex { 837 name: "myapex_keytest", 838 key: "myapex.key", 839 certificate: ":myapex.certificate", 840 native_shared_libs: ["mylib"], 841 } 842 843 cc_library { 844 name: "mylib", 845 srcs: ["mylib.cpp"], 846 system_shared_libs: [], 847 stl: "none", 848 } 849 850 apex_key { 851 name: "myapex.key", 852 public_key: "testkey.avbpubkey", 853 private_key: "testkey.pem", 854 } 855 856 android_app_certificate { 857 name: "myapex.certificate", 858 certificate: "testkey", 859 } 860 861 android_app_certificate { 862 name: "myapex.certificate.override", 863 certificate: "testkey.override", 864 } 865 866 `) 867 868 // check the APEX keys 869 keys := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey) 870 871 if keys.public_key_file.String() != "vendor/foo/devkeys/testkey.avbpubkey" { 872 t.Errorf("public key %q is not %q", keys.public_key_file.String(), 873 "vendor/foo/devkeys/testkey.avbpubkey") 874 } 875 if keys.private_key_file.String() != "vendor/foo/devkeys/testkey.pem" { 876 t.Errorf("private key %q is not %q", keys.private_key_file.String(), 877 "vendor/foo/devkeys/testkey.pem") 878 } 879 880 // check the APK certs. It should be overridden to myapex.certificate.override 881 certs := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk").Args["certificates"] 882 if certs != "testkey.override.x509.pem testkey.override.pk8" { 883 t.Errorf("cert and private key %q are not %q", certs, 884 "testkey.override.509.pem testkey.override.pk8") 885 } 886} 887 888func TestMacro(t *testing.T) { 889 ctx := testApex(t, ` 890 apex { 891 name: "myapex", 892 key: "myapex.key", 893 native_shared_libs: ["mylib"], 894 } 895 896 apex { 897 name: "otherapex", 898 key: "myapex.key", 899 native_shared_libs: ["mylib"], 900 } 901 902 apex_key { 903 name: "myapex.key", 904 public_key: "testkey.avbpubkey", 905 private_key: "testkey.pem", 906 } 907 908 cc_library { 909 name: "mylib", 910 srcs: ["mylib.cpp"], 911 system_shared_libs: [], 912 stl: "none", 913 } 914 `) 915 916 // non-APEX variant does not have __ANDROID__APEX__ defined 917 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static").Rule("cc").Args["cFlags"] 918 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex") 919 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex") 920 921 // APEX variant has __ANDROID_APEX__=<apexname> defined 922 mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_myapex").Rule("cc").Args["cFlags"] 923 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex") 924 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex") 925 926 // APEX variant has __ANDROID_APEX__=<apexname> defined 927 mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_otherapex").Rule("cc").Args["cFlags"] 928 ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex") 929 ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex") 930} 931 932func TestHeaderLibsDependency(t *testing.T) { 933 ctx := testApex(t, ` 934 apex { 935 name: "myapex", 936 key: "myapex.key", 937 native_shared_libs: ["mylib"], 938 } 939 940 apex_key { 941 name: "myapex.key", 942 public_key: "testkey.avbpubkey", 943 private_key: "testkey.pem", 944 } 945 946 cc_library_headers { 947 name: "mylib_headers", 948 export_include_dirs: ["my_include"], 949 system_shared_libs: [], 950 stl: "none", 951 } 952 953 cc_library { 954 name: "mylib", 955 srcs: ["mylib.cpp"], 956 system_shared_libs: [], 957 stl: "none", 958 header_libs: ["mylib_headers"], 959 export_header_lib_headers: ["mylib_headers"], 960 stubs: { 961 versions: ["1", "2", "3"], 962 }, 963 } 964 965 cc_library { 966 name: "otherlib", 967 srcs: ["mylib.cpp"], 968 system_shared_libs: [], 969 stl: "none", 970 shared_libs: ["mylib"], 971 } 972 `) 973 974 cFlags := ctx.ModuleForTests("otherlib", "android_arm64_armv8-a_core_static").Rule("cc").Args["cFlags"] 975 976 // Ensure that the include path of the header lib is exported to 'otherlib' 977 ensureContains(t, cFlags, "-Imy_include") 978} 979 980func TestNonTestApex(t *testing.T) { 981 ctx := testApex(t, ` 982 apex { 983 name: "myapex", 984 key: "myapex.key", 985 native_shared_libs: ["mylib_common"], 986 } 987 988 apex_key { 989 name: "myapex.key", 990 public_key: "testkey.avbpubkey", 991 private_key: "testkey.pem", 992 } 993 994 cc_library { 995 name: "mylib_common", 996 srcs: ["mylib.cpp"], 997 system_shared_libs: [], 998 stl: "none", 999 } 1000 `) 1001 1002 module := ctx.ModuleForTests("myapex", "android_common_myapex") 1003 apexRule := module.Rule("apexRule") 1004 copyCmds := apexRule.Args["copy_commands"] 1005 1006 if apex, ok := module.Module().(*apexBundle); !ok || apex.testApex { 1007 t.Log("Apex was a test apex!") 1008 t.Fail() 1009 } 1010 // Ensure that main rule creates an output 1011 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 1012 1013 // Ensure that apex variant is created for the direct dep 1014 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_core_shared_myapex") 1015 1016 // Ensure that both direct and indirect deps are copied into apex 1017 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so") 1018 1019 // Ensure that the platform variant ends with _core_shared 1020 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_core_shared") 1021 1022 if !android.InAnyApex("mylib_common") { 1023 t.Log("Found mylib_common not in any apex!") 1024 t.Fail() 1025 } 1026} 1027 1028func TestTestApex(t *testing.T) { 1029 if android.InAnyApex("mylib_common_test") { 1030 t.Fatal("mylib_common_test must not be used in any other tests since this checks that global state is not updated in an illegal way!") 1031 } 1032 ctx := testApex(t, ` 1033 apex_test { 1034 name: "myapex", 1035 key: "myapex.key", 1036 native_shared_libs: ["mylib_common_test"], 1037 } 1038 1039 apex_key { 1040 name: "myapex.key", 1041 public_key: "testkey.avbpubkey", 1042 private_key: "testkey.pem", 1043 } 1044 1045 cc_library { 1046 name: "mylib_common_test", 1047 srcs: ["mylib.cpp"], 1048 system_shared_libs: [], 1049 stl: "none", 1050 } 1051 `) 1052 1053 module := ctx.ModuleForTests("myapex", "android_common_myapex") 1054 apexRule := module.Rule("apexRule") 1055 copyCmds := apexRule.Args["copy_commands"] 1056 1057 if apex, ok := module.Module().(*apexBundle); !ok || !apex.testApex { 1058 t.Log("Apex was not a test apex!") 1059 t.Fail() 1060 } 1061 // Ensure that main rule creates an output 1062 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 1063 1064 // Ensure that apex variant is created for the direct dep 1065 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_core_shared_myapex") 1066 1067 // Ensure that both direct and indirect deps are copied into apex 1068 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so") 1069 1070 // Ensure that the platform variant ends with _core_shared 1071 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_core_shared") 1072 1073 if android.InAnyApex("mylib_common_test") { 1074 t.Log("Found mylib_common_test in some apex!") 1075 t.Fail() 1076 } 1077} 1078 1079func TestApexWithTarget(t *testing.T) { 1080 ctx := testApex(t, ` 1081 apex { 1082 name: "myapex", 1083 key: "myapex.key", 1084 multilib: { 1085 first: { 1086 native_shared_libs: ["mylib_common"], 1087 } 1088 }, 1089 target: { 1090 android: { 1091 multilib: { 1092 first: { 1093 native_shared_libs: ["mylib"], 1094 } 1095 } 1096 }, 1097 host: { 1098 multilib: { 1099 first: { 1100 native_shared_libs: ["mylib2"], 1101 } 1102 } 1103 } 1104 } 1105 } 1106 1107 apex_key { 1108 name: "myapex.key", 1109 public_key: "testkey.avbpubkey", 1110 private_key: "testkey.pem", 1111 } 1112 1113 cc_library { 1114 name: "mylib", 1115 srcs: ["mylib.cpp"], 1116 system_shared_libs: [], 1117 stl: "none", 1118 } 1119 1120 cc_library { 1121 name: "mylib_common", 1122 srcs: ["mylib.cpp"], 1123 system_shared_libs: [], 1124 stl: "none", 1125 compile_multilib: "first", 1126 } 1127 1128 cc_library { 1129 name: "mylib2", 1130 srcs: ["mylib.cpp"], 1131 system_shared_libs: [], 1132 stl: "none", 1133 compile_multilib: "first", 1134 } 1135 `) 1136 1137 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 1138 copyCmds := apexRule.Args["copy_commands"] 1139 1140 // Ensure that main rule creates an output 1141 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned") 1142 1143 // Ensure that apex variant is created for the direct dep 1144 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared_myapex") 1145 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_core_shared_myapex") 1146 ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared_myapex") 1147 1148 // Ensure that both direct and indirect deps are copied into apex 1149 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so") 1150 ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so") 1151 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so") 1152 1153 // Ensure that the platform variant ends with _core_shared 1154 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared") 1155 ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_core_shared") 1156 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared") 1157} 1158 1159func TestApexWithShBinary(t *testing.T) { 1160 ctx := testApex(t, ` 1161 apex { 1162 name: "myapex", 1163 key: "myapex.key", 1164 binaries: ["myscript"], 1165 } 1166 1167 apex_key { 1168 name: "myapex.key", 1169 public_key: "testkey.avbpubkey", 1170 private_key: "testkey.pem", 1171 } 1172 1173 sh_binary { 1174 name: "myscript", 1175 src: "mylib.cpp", 1176 filename: "myscript.sh", 1177 sub_dir: "script", 1178 } 1179 `) 1180 1181 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") 1182 copyCmds := apexRule.Args["copy_commands"] 1183 1184 ensureContains(t, copyCmds, "image.apex/bin/script/myscript.sh") 1185} 1186 1187func TestApexInProductPartition(t *testing.T) { 1188 ctx := testApex(t, ` 1189 apex { 1190 name: "myapex", 1191 key: "myapex.key", 1192 native_shared_libs: ["mylib"], 1193 product_specific: true, 1194 } 1195 1196 apex_key { 1197 name: "myapex.key", 1198 public_key: "testkey.avbpubkey", 1199 private_key: "testkey.pem", 1200 product_specific: true, 1201 } 1202 1203 cc_library { 1204 name: "mylib", 1205 srcs: ["mylib.cpp"], 1206 system_shared_libs: [], 1207 stl: "none", 1208 } 1209 `) 1210 1211 apex := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle) 1212 expected := "target/product/test_device/product/apex" 1213 actual := apex.installDir.RelPathString() 1214 if actual != expected { 1215 t.Errorf("wrong install path. expected %q. actual %q", expected, actual) 1216 } 1217} 1218 1219func TestApexKeyFromOtherModule(t *testing.T) { 1220 ctx := testApex(t, ` 1221 apex_key { 1222 name: "myapex.key", 1223 public_key: ":my.avbpubkey", 1224 private_key: ":my.pem", 1225 product_specific: true, 1226 } 1227 1228 filegroup { 1229 name: "my.avbpubkey", 1230 srcs: ["testkey2.avbpubkey"], 1231 } 1232 1233 filegroup { 1234 name: "my.pem", 1235 srcs: ["testkey2.pem"], 1236 } 1237 `) 1238 1239 apex_key := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey) 1240 expected_pubkey := "testkey2.avbpubkey" 1241 actual_pubkey := apex_key.public_key_file.String() 1242 if actual_pubkey != expected_pubkey { 1243 t.Errorf("wrong public key path. expected %q. actual %q", expected_pubkey, actual_pubkey) 1244 } 1245 expected_privkey := "testkey2.pem" 1246 actual_privkey := apex_key.private_key_file.String() 1247 if actual_privkey != expected_privkey { 1248 t.Errorf("wrong private key path. expected %q. actual %q", expected_privkey, actual_privkey) 1249 } 1250} 1251 1252func TestPrebuilt(t *testing.T) { 1253 ctx := testApex(t, ` 1254 prebuilt_apex { 1255 name: "myapex", 1256 arch: { 1257 arm64: { 1258 src: "myapex-arm64.apex", 1259 }, 1260 arm: { 1261 src: "myapex-arm.apex", 1262 }, 1263 }, 1264 } 1265 `) 1266 1267 prebuilt := ctx.ModuleForTests("myapex", "android_common").Module().(*Prebuilt) 1268 1269 expectedInput := "myapex-arm64.apex" 1270 if prebuilt.inputApex.String() != expectedInput { 1271 t.Errorf("inputApex invalid. expected: %q, actual: %q", expectedInput, prebuilt.inputApex.String()) 1272 } 1273} 1274 1275func TestPrebuiltFilenameOverride(t *testing.T) { 1276 ctx := testApex(t, ` 1277 prebuilt_apex { 1278 name: "myapex", 1279 src: "myapex-arm.apex", 1280 filename: "notmyapex.apex", 1281 } 1282 `) 1283 1284 p := ctx.ModuleForTests("myapex", "android_common").Module().(*Prebuilt) 1285 1286 expected := "notmyapex.apex" 1287 if p.installFilename != expected { 1288 t.Errorf("installFilename invalid. expected: %q, actual: %q", expected, p.installFilename) 1289 } 1290} 1291