1// Copyright (C) 2021 The Android Open Source Project 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 "fmt" 19 "strings" 20 "testing" 21 22 "android/soong/android" 23 "android/soong/dexpreopt" 24 "android/soong/java" 25 26 "github.com/google/blueprint" 27 "github.com/google/blueprint/proptools" 28) 29 30// Contains tests for platform_bootclasspath logic from java/platform_bootclasspath.go that requires 31// apexes. 32 33var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers( 34 java.PrepareForTestWithJavaDefaultModules, 35 PrepareForTestWithApexBuildComponents, 36) 37 38func TestPlatformBootclasspath_Fragments(t *testing.T) { 39 result := android.GroupFixturePreparers( 40 prepareForTestWithPlatformBootclasspath, 41 prepareForTestWithMyapex, 42 java.PrepareForTestWithJavaSdkLibraryFiles, 43 java.FixtureWithLastReleaseApis("foo"), 44 java.FixtureConfigureApexBootJars("myapex:bar"), 45 android.FixtureWithRootAndroidBp(` 46 platform_bootclasspath { 47 name: "platform-bootclasspath", 48 fragments: [ 49 { 50 apex: "myapex", 51 module:"bar-fragment", 52 }, 53 ], 54 hidden_api: { 55 unsupported: [ 56 "unsupported.txt", 57 ], 58 removed: [ 59 "removed.txt", 60 ], 61 max_target_r_low_priority: [ 62 "max-target-r-low-priority.txt", 63 ], 64 max_target_q: [ 65 "max-target-q.txt", 66 ], 67 max_target_p: [ 68 "max-target-p.txt", 69 ], 70 max_target_o_low_priority: [ 71 "max-target-o-low-priority.txt", 72 ], 73 blocked: [ 74 "blocked.txt", 75 ], 76 unsupported_packages: [ 77 "unsupported-packages.txt", 78 ], 79 }, 80 } 81 82 apex { 83 name: "myapex", 84 key: "myapex.key", 85 bootclasspath_fragments: [ 86 "bar-fragment", 87 ], 88 updatable: false, 89 min_sdk_version: "30", // R 90 } 91 92 apex_key { 93 name: "myapex.key", 94 public_key: "testkey.avbpubkey", 95 private_key: "testkey.pem", 96 } 97 98 bootclasspath_fragment { 99 name: "bar-fragment", 100 contents: ["bar"], 101 apex_available: ["myapex"], 102 api: { 103 stub_libs: ["foo"], 104 }, 105 hidden_api: { 106 unsupported: [ 107 "bar-unsupported.txt", 108 ], 109 removed: [ 110 "bar-removed.txt", 111 ], 112 max_target_r_low_priority: [ 113 "bar-max-target-r-low-priority.txt", 114 ], 115 max_target_q: [ 116 "bar-max-target-q.txt", 117 ], 118 max_target_p: [ 119 "bar-max-target-p.txt", 120 ], 121 max_target_o_low_priority: [ 122 "bar-max-target-o-low-priority.txt", 123 ], 124 blocked: [ 125 "bar-blocked.txt", 126 ], 127 unsupported_packages: [ 128 "bar-unsupported-packages.txt", 129 ], 130 split_packages: ["*"], 131 }, 132 } 133 134 java_library { 135 name: "bar", 136 apex_available: ["myapex"], 137 srcs: ["a.java"], 138 system_modules: "none", 139 sdk_version: "none", 140 compile_dex: true, 141 permitted_packages: ["bar"], 142 min_sdk_version: "30", // R 143 } 144 145 java_sdk_library { 146 name: "foo", 147 srcs: ["a.java"], 148 public: { 149 enabled: true, 150 }, 151 compile_dex: true, 152 } 153 `), 154 ).RunTest(t) 155 156 pbcp := result.Module("platform-bootclasspath", "android_common") 157 info, _ := android.SingletonModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider) 158 159 for _, category := range java.HiddenAPIFlagFileCategories { 160 name := category.PropertyName() 161 message := fmt.Sprintf("category %s", name) 162 filename := strings.ReplaceAll(name, "_", "-") 163 expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)} 164 android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category]) 165 } 166 167 android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths) 168 android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/metadata.csv"}, info.MetadataPaths) 169 android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/index.csv"}, info.IndexPaths) 170 171 android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/filtered-stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop()) 172 android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop()) 173} 174 175// TestPlatformBootclasspath_LegacyPrebuiltFragment verifies that the 176// prebuilt_bootclasspath_fragment falls back to using the complete stub-flags/all-flags if the 177// filtered files are not provided. 178// 179// TODO: Remove once all prebuilts use the filtered_... properties. 180func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) { 181 result := android.GroupFixturePreparers( 182 prepareForTestWithPlatformBootclasspath, 183 java.FixtureConfigureApexBootJars("myapex:foo"), 184 java.PrepareForTestWithJavaSdkLibraryFiles, 185 ).RunTestWithBp(t, ` 186 prebuilt_apex { 187 name: "myapex", 188 src: "myapex.apex", 189 exported_bootclasspath_fragments: ["mybootclasspath-fragment"], 190 } 191 192 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred 193 // because AlwaysUsePrebuiltSdks() is true. 194 java_sdk_library_import { 195 name: "foo", 196 prefer: false, 197 shared_library: false, 198 permitted_packages: ["foo"], 199 public: { 200 jars: ["sdk_library/public/foo-stubs.jar"], 201 stub_srcs: ["sdk_library/public/foo_stub_sources"], 202 current_api: "sdk_library/public/foo.txt", 203 removed_api: "sdk_library/public/foo-removed.txt", 204 sdk_version: "current", 205 }, 206 apex_available: ["myapex"], 207 } 208 209 prebuilt_bootclasspath_fragment { 210 name: "mybootclasspath-fragment", 211 apex_available: [ 212 "myapex", 213 ], 214 contents: [ 215 "foo", 216 ], 217 hidden_api: { 218 stub_flags: "prebuilt-stub-flags.csv", 219 annotation_flags: "prebuilt-annotation-flags.csv", 220 metadata: "prebuilt-metadata.csv", 221 index: "prebuilt-index.csv", 222 all_flags: "prebuilt-all-flags.csv", 223 }, 224 } 225 226 platform_bootclasspath { 227 name: "myplatform-bootclasspath", 228 fragments: [ 229 { 230 apex: "myapex", 231 module:"mybootclasspath-fragment", 232 }, 233 ], 234 } 235`, 236 ) 237 238 pbcp := result.Module("myplatform-bootclasspath", "android_common") 239 info, _ := android.SingletonModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider) 240 241 android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop()) 242 android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop()) 243} 244 245func TestPlatformBootclasspathDependencies(t *testing.T) { 246 result := android.GroupFixturePreparers( 247 prepareForTestWithPlatformBootclasspath, 248 prepareForTestWithArtApex, 249 prepareForTestWithMyapex, 250 // Configure some libraries in the art and framework boot images. 251 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"), 252 java.FixtureConfigureApexBootJars("myapex:bar"), 253 java.PrepareForTestWithJavaSdkLibraryFiles, 254 java.FixtureWithLastReleaseApis("foo"), 255 java.PrepareForTestWithDexpreopt, 256 dexpreopt.FixtureDisableDexpreoptBootImages(false), 257 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 258 variables.BuildFlags = map[string]string{ 259 "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true", 260 } 261 }), 262 ).RunTestWithBp(t, ` 263 apex { 264 name: "com.android.art", 265 key: "com.android.art.key", 266 bootclasspath_fragments: [ 267 "art-bootclasspath-fragment", 268 ], 269 updatable: false, 270 } 271 272 apex_key { 273 name: "com.android.art.key", 274 public_key: "com.android.art.avbpubkey", 275 private_key: "com.android.art.pem", 276 } 277 278 bootclasspath_fragment { 279 name: "art-bootclasspath-fragment", 280 image_name: "art", 281 apex_available: [ 282 "com.android.art", 283 ], 284 contents: [ 285 "baz", 286 "quuz", 287 ], 288 hidden_api: { 289 split_packages: ["*"], 290 }, 291 } 292 293 java_library { 294 name: "baz", 295 apex_available: [ 296 "com.android.art", 297 ], 298 srcs: ["b.java"], 299 installable: true, 300 } 301 302 // Add a java_import that is not preferred and so won't have an appropriate apex variant created 303 // for it to make sure that the platform_bootclasspath doesn't try and add a dependency onto it. 304 java_import { 305 name: "baz", 306 apex_available: [ 307 "com.android.art", 308 ], 309 jars: ["b.jar"], 310 } 311 312 java_library { 313 name: "quuz", 314 apex_available: [ 315 "com.android.art", 316 ], 317 srcs: ["b.java"], 318 installable: true, 319 } 320 321 apex { 322 name: "myapex", 323 key: "myapex.key", 324 bootclasspath_fragments: [ 325 "my-bootclasspath-fragment", 326 ], 327 updatable: false, 328 } 329 330 bootclasspath_fragment { 331 name: "my-bootclasspath-fragment", 332 contents: ["bar"], 333 apex_available: ["myapex"], 334 hidden_api: { 335 split_packages: ["*"], 336 }, 337 } 338 339 apex_key { 340 name: "myapex.key", 341 public_key: "testkey.avbpubkey", 342 private_key: "testkey.pem", 343 } 344 345 java_sdk_library { 346 name: "foo", 347 srcs: ["b.java"], 348 } 349 350 java_library { 351 name: "bar", 352 srcs: ["b.java"], 353 installable: true, 354 apex_available: ["myapex"], 355 permitted_packages: ["bar"], 356 } 357 358 platform_bootclasspath { 359 name: "myplatform-bootclasspath", 360 361 fragments: [ 362 { 363 apex: "com.android.art", 364 module: "art-bootclasspath-fragment", 365 }, 366 { 367 apex: "myapex", 368 module: "my-bootclasspath-fragment", 369 }, 370 ], 371 } 372`, 373 ) 374 375 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{ 376 // The configured contents of BootJars. 377 "com.android.art:baz", 378 "com.android.art:quuz", 379 "platform:foo", 380 381 // The configured contents of ApexBootJars. 382 "myapex:bar", 383 }) 384 385 java.CheckPlatformBootclasspathFragments(t, result, "myplatform-bootclasspath", []string{ 386 "com.android.art:art-bootclasspath-fragment", 387 "myapex:my-bootclasspath-fragment", 388 }) 389 390 // Make sure that the myplatform-bootclasspath has the correct dependencies. 391 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ 392 // source vs prebuilt selection metadata module 393 `platform:all_apex_contributions`, 394 395 // The following are stubs. 396 `platform:android_stubs_current_exportable`, 397 `platform:android_system_stubs_current_exportable`, 398 `platform:android_test_stubs_current_exportable`, 399 `platform:legacy.core.platform.api.stubs.exportable`, 400 401 // Needed for generating the boot image. 402 `platform:dex2oatd`, 403 404 // The configured contents of BootJars. 405 `com.android.art:baz`, 406 `com.android.art:quuz`, 407 `platform:foo`, 408 409 // The configured contents of ApexBootJars. 410 `myapex:bar`, 411 412 // The fragments. 413 `com.android.art:art-bootclasspath-fragment`, 414 `myapex:my-bootclasspath-fragment`, 415 }) 416} 417 418// TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when 419// AlwaysUsePrebuiltSdk() returns true. 420func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { 421 result := android.GroupFixturePreparers( 422 prepareForTestWithPlatformBootclasspath, 423 prepareForTestWithMyapex, 424 // Configure two libraries, the first is a java_sdk_library whose prebuilt will be used because 425 // of AlwaysUsePrebuiltsSdk(). The second is a normal library that is unaffected. The order 426 // matters, so that the dependencies resolved by the platform_bootclasspath matches the 427 // configured list. 428 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"), 429 java.PrepareForTestWithJavaSdkLibraryFiles, 430 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 431 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) 432 variables.BuildFlags = map[string]string{ 433 "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true", 434 } 435 }), 436 java.FixtureWithPrebuiltApis(map[string][]string{ 437 "current": {}, 438 "30": {"foo"}, 439 }), 440 ).RunTestWithBp(t, ` 441 apex { 442 name: "myapex", 443 key: "myapex.key", 444 bootclasspath_fragments: [ 445 "mybootclasspath-fragment", 446 ], 447 updatable: false, 448 } 449 450 apex_key { 451 name: "myapex.key", 452 public_key: "testkey.avbpubkey", 453 private_key: "testkey.pem", 454 } 455 456 java_library { 457 name: "bar", 458 srcs: ["b.java"], 459 installable: true, 460 apex_available: ["myapex"], 461 permitted_packages: ["bar"], 462 } 463 464 java_sdk_library { 465 name: "foo", 466 srcs: ["b.java"], 467 shared_library: false, 468 public: { 469 enabled: true, 470 }, 471 apex_available: ["myapex"], 472 permitted_packages: ["foo"], 473 } 474 475 prebuilt_apex { 476 name: "myapex", 477 src: "myapex.apex", 478 exported_bootclasspath_fragments: ["mybootclasspath-fragment"], 479 } 480 481 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred 482 // because AlwaysUsePrebuiltSdks() is true. 483 java_sdk_library_import { 484 name: "foo", 485 prefer: false, 486 shared_library: false, 487 permitted_packages: ["foo"], 488 public: { 489 jars: ["sdk_library/public/foo-stubs.jar"], 490 stub_srcs: ["sdk_library/public/foo_stub_sources"], 491 current_api: "sdk_library/public/foo.txt", 492 removed_api: "sdk_library/public/foo-removed.txt", 493 sdk_version: "current", 494 }, 495 apex_available: ["myapex"], 496 } 497 498 // This always depends on the source foo module, its dependencies are not affected by the 499 // AlwaysUsePrebuiltSdks(). 500 bootclasspath_fragment { 501 name: "mybootclasspath-fragment", 502 apex_available: [ 503 "myapex", 504 ], 505 contents: [ 506 "foo", "bar", 507 ], 508 hidden_api: { 509 split_packages: ["*"], 510 }, 511 } 512 513 prebuilt_bootclasspath_fragment { 514 name: "mybootclasspath-fragment", 515 apex_available: [ 516 "myapex", 517 ], 518 contents: [ 519 "foo", 520 ], 521 hidden_api: { 522 stub_flags: "", 523 annotation_flags: "", 524 metadata: "", 525 index: "", 526 all_flags: "", 527 }, 528 } 529 530 platform_bootclasspath { 531 name: "myplatform-bootclasspath", 532 fragments: [ 533 { 534 apex: "myapex", 535 module:"mybootclasspath-fragment", 536 }, 537 ], 538 } 539`, 540 ) 541 542 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{ 543 // The configured contents of BootJars. 544 "myapex:prebuilt_foo", 545 "myapex:bar", 546 }) 547 548 // Make sure that the myplatform-bootclasspath has the correct dependencies. 549 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ 550 // source vs prebuilt selection metadata module 551 `platform:all_apex_contributions`, 552 553 // The following are stubs. 554 "platform:prebuilt_sdk_public_current_android", 555 "platform:prebuilt_sdk_system_current_android", 556 "platform:prebuilt_sdk_test_current_android", 557 558 // Not a prebuilt as no prebuilt existed when it was added. 559 "platform:legacy.core.platform.api.stubs.exportable", 560 561 // The platform_bootclasspath intentionally adds dependencies on both source and prebuilt 562 // modules when available as it does not know which one will be preferred. 563 "myapex:foo", 564 "myapex:prebuilt_foo", 565 566 // Only a source module exists. 567 "myapex:bar", 568 569 // The fragments. 570 "myapex:mybootclasspath-fragment", 571 "myapex:prebuilt_mybootclasspath-fragment", 572 }) 573} 574 575// CheckModuleDependencies checks the dependencies of the selected module against the expected list. 576// 577// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the 578// name of the apex, or platform is it is not part of an apex and <module> is the module name. 579func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) { 580 t.Helper() 581 module := ctx.ModuleForTests(name, variant).Module() 582 modules := []android.Module{} 583 ctx.VisitDirectDeps(module, func(m blueprint.Module) { 584 modules = append(modules, m.(android.Module)) 585 }) 586 587 pairs := java.ApexNamePairsFromModules(ctx, modules) 588 android.AssertDeepEquals(t, "module dependencies", expected, pairs) 589} 590 591// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in 592// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config 593// by setting generate_classpaths_proto property to false. 594func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) { 595 result := android.GroupFixturePreparers( 596 prepareForTestWithPlatformBootclasspath, 597 prepareForTestWithMyapex, 598 java.FixtureConfigureApexBootJars("myapex:foo"), 599 android.FixtureWithRootAndroidBp(` 600 platform_bootclasspath { 601 name: "platform-bootclasspath", 602 fragments: [ 603 { 604 apex: "myapex", 605 module:"foo-fragment", 606 }, 607 ], 608 } 609 610 apex { 611 name: "myapex", 612 key: "myapex.key", 613 bootclasspath_fragments: ["foo-fragment"], 614 updatable: false, 615 } 616 617 apex_key { 618 name: "myapex.key", 619 public_key: "testkey.avbpubkey", 620 private_key: "testkey.pem", 621 } 622 623 bootclasspath_fragment { 624 name: "foo-fragment", 625 generate_classpaths_proto: false, 626 contents: ["foo"], 627 apex_available: ["myapex"], 628 hidden_api: { 629 split_packages: ["*"], 630 }, 631 } 632 633 java_library { 634 name: "foo", 635 srcs: ["a.java"], 636 system_modules: "none", 637 sdk_version: "none", 638 compile_dex: true, 639 apex_available: ["myapex"], 640 permitted_packages: ["foo"], 641 } 642 `), 643 ).RunTest(t) 644 645 java.CheckClasspathFragmentProtoContentInfoProvider(t, result, 646 true, // proto should be generated 647 "myapex:foo", // apex doesn't generate its own config, so must be in platform_bootclasspath 648 "bootclasspath.pb", 649 "out/soong/target/product/test_device/system/etc/classpaths", 650 ) 651} 652 653func TestBootJarNotInApex(t *testing.T) { 654 android.GroupFixturePreparers( 655 prepareForTestWithPlatformBootclasspath, 656 PrepareForTestWithApexBuildComponents, 657 prepareForTestWithMyapex, 658 java.FixtureConfigureApexBootJars("myapex:foo"), 659 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 660 `dependency "foo" of "myplatform-bootclasspath" missing variant`)). 661 RunTestWithBp(t, ` 662 apex { 663 name: "myapex", 664 key: "myapex.key", 665 updatable: false, 666 } 667 668 apex_key { 669 name: "myapex.key", 670 public_key: "testkey.avbpubkey", 671 private_key: "testkey.pem", 672 } 673 674 java_library { 675 name: "foo", 676 srcs: ["b.java"], 677 installable: true, 678 apex_available: [ 679 "myapex", 680 ], 681 } 682 683 bootclasspath_fragment { 684 name: "not-in-apex-fragment", 685 contents: [ 686 "foo", 687 ], 688 hidden_api: { 689 split_packages: ["*"], 690 }, 691 } 692 693 platform_bootclasspath { 694 name: "myplatform-bootclasspath", 695 } 696 `) 697} 698 699func TestBootFragmentNotInApex(t *testing.T) { 700 android.GroupFixturePreparers( 701 prepareForTestWithPlatformBootclasspath, 702 PrepareForTestWithApexBuildComponents, 703 prepareForTestWithMyapex, 704 java.FixtureConfigureApexBootJars("myapex:foo"), 705 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 706 `library foo.*have no corresponding fragment.*`)).RunTestWithBp(t, ` 707 apex { 708 name: "myapex", 709 key: "myapex.key", 710 java_libs: ["foo"], 711 updatable: false, 712 } 713 714 apex_key { 715 name: "myapex.key", 716 public_key: "testkey.avbpubkey", 717 private_key: "testkey.pem", 718 } 719 720 java_library { 721 name: "foo", 722 srcs: ["b.java"], 723 installable: true, 724 apex_available: ["myapex"], 725 permitted_packages: ["foo"], 726 } 727 728 bootclasspath_fragment { 729 name: "not-in-apex-fragment", 730 contents: ["foo"], 731 hidden_api: { 732 split_packages: ["*"], 733 }, 734 } 735 736 platform_bootclasspath { 737 name: "myplatform-bootclasspath", 738 } 739 `) 740} 741 742func TestNonBootJarInFragment(t *testing.T) { 743 android.GroupFixturePreparers( 744 prepareForTestWithPlatformBootclasspath, 745 PrepareForTestWithApexBuildComponents, 746 prepareForTestWithMyapex, 747 java.FixtureConfigureApexBootJars("myapex:foo"), 748 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( 749 `in contents must also be declared in PRODUCT_APEX_BOOT_JARS`)). 750 RunTestWithBp(t, ` 751 apex { 752 name: "myapex", 753 key: "myapex.key", 754 bootclasspath_fragments: ["apex-fragment"], 755 updatable: false, 756 } 757 758 apex_key { 759 name: "myapex.key", 760 public_key: "testkey.avbpubkey", 761 private_key: "testkey.pem", 762 } 763 764 java_library { 765 name: "foo", 766 srcs: ["b.java"], 767 installable: true, 768 apex_available: ["myapex"], 769 permitted_packages: ["foo"], 770 } 771 772 java_library { 773 name: "bar", 774 srcs: ["b.java"], 775 installable: true, 776 apex_available: ["myapex"], 777 permitted_packages: ["bar"], 778 } 779 780 bootclasspath_fragment { 781 name: "apex-fragment", 782 contents: ["foo", "bar"], 783 apex_available:[ "myapex" ], 784 hidden_api: { 785 split_packages: ["*"], 786 }, 787 } 788 789 platform_bootclasspath { 790 name: "myplatform-bootclasspath", 791 fragments: [{ 792 apex: "myapex", 793 module:"apex-fragment", 794 }], 795 } 796 `) 797} 798 799// Source and prebuilt apex provide different set of boot jars 800func TestNonBootJarMissingInPrebuiltFragment(t *testing.T) { 801 bp := ` 802 apex { 803 name: "myapex", 804 key: "myapex.key", 805 bootclasspath_fragments: ["apex-fragment"], 806 updatable: false, 807 } 808 809 apex_key { 810 name: "myapex.key", 811 public_key: "testkey.avbpubkey", 812 private_key: "testkey.pem", 813 } 814 815 java_library { 816 name: "foo", 817 srcs: ["b.java"], 818 installable: true, 819 apex_available: ["myapex"], 820 permitted_packages: ["foo"], 821 } 822 823 java_library { 824 name: "bar", 825 srcs: ["b.java"], 826 installable: true, 827 apex_available: ["myapex"], 828 permitted_packages: ["bar"], 829 } 830 831 bootclasspath_fragment { 832 name: "apex-fragment", 833 contents: ["foo", "bar"], 834 apex_available:[ "myapex" ], 835 hidden_api: { 836 split_packages: ["*"], 837 }, 838 } 839 840 prebuilt_apex { 841 name: "com.google.android.myapex", // mainline prebuilt selection logic in soong relies on the naming convention com.google.android 842 apex_name: "myapex", 843 source_apex_name: "myapex", 844 src: "myapex.apex", 845 exported_bootclasspath_fragments: ["apex-fragment"], 846 } 847 848 java_import { 849 name: "foo", 850 jars: ["foo.jar"], 851 apex_available: ["myapex"], 852 permitted_packages: ["foo"], 853 } 854 855 prebuilt_bootclasspath_fragment { 856 name: "apex-fragment", 857 contents: ["foo"], // Unlike the source fragment, this is missing bar 858 apex_available:[ "myapex" ], 859 hidden_api: { 860 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 861 metadata: "my-bootclasspath-fragment/metadata.csv", 862 index: "my-bootclasspath-fragment/index.csv", 863 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 864 all_flags: "my-bootclasspath-fragment/all-flags.csv", 865 }, 866 } 867 868 // Another prebuilt apex, but this is not selected during the build. 869 prebuilt_apex { 870 name: "com.google.android.myapex.v2", // mainline prebuilt selection logic in soong relies on the naming convention com.google.android 871 apex_name: "myapex", 872 source_apex_name: "myapex", 873 src: "myapex.apex", 874 exported_bootclasspath_fragments: ["apex-fragment.v2"], 875 } 876 877 java_import { 878 name: "bar", 879 jars: ["bar.jar"], 880 apex_available: ["myapex"], 881 permitted_packages: ["bar"], 882 } 883 884 prebuilt_bootclasspath_fragment { 885 name: "apex-fragment.v2", 886 contents: ["bar"], // Unlike the source fragment, this is missing foo 887 apex_available:[ "myapex" ], 888 hidden_api: { 889 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", 890 metadata: "my-bootclasspath-fragment/metadata.csv", 891 index: "my-bootclasspath-fragment/index.csv", 892 stub_flags: "my-bootclasspath-fragment/stub-flags.csv", 893 all_flags: "my-bootclasspath-fragment/all-flags.csv", 894 }, 895 } 896 897 898 apex_contributions { 899 name: "my_apex_contributions", 900 api_domain: "myapex", 901 contents: [%v], 902 } 903 ` 904 testCases := []struct { 905 desc string 906 configuredBootJars []string 907 apexContributionContents string 908 errorExpected bool 909 }{ 910 { 911 desc: "Source apex is selected, and APEX_BOOT_JARS is correctly configured for source apex builds", 912 configuredBootJars: []string{"myapex:foo", "myapex:bar"}, 913 }, 914 { 915 desc: "Source apex is selected, and APEX_BOOT_JARS is missing bar", 916 configuredBootJars: []string{"myapex:foo"}, 917 errorExpected: true, 918 }, 919 { 920 desc: "Prebuilt apex is selected, and APEX_BOOT_JARS is correctly configured for prebuilt apex build", 921 configuredBootJars: []string{"myapex:foo"}, 922 apexContributionContents: `"prebuilt_com.google.android.myapex"`, 923 }, 924 { 925 desc: "Prebuilt apex is selected, and APEX_BOOT_JARS is missing foo", 926 configuredBootJars: []string{"myapex:bar"}, 927 apexContributionContents: `"prebuilt_com.google.android.myapex"`, 928 errorExpected: true, 929 }, 930 } 931 932 for _, tc := range testCases { 933 fixture := android.GroupFixturePreparers( 934 prepareForTestWithPlatformBootclasspath, 935 PrepareForTestWithApexBuildComponents, 936 prepareForTestWithMyapex, 937 java.FixtureConfigureApexBootJars(tc.configuredBootJars...), 938 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 939 variables.BuildFlags = map[string]string{ 940 "RELEASE_APEX_CONTRIBUTIONS_ART": "my_apex_contributions", 941 } 942 }), 943 ) 944 if tc.errorExpected { 945 fixture = fixture.ExtendWithErrorHandler( 946 android.FixtureExpectsAtLeastOneErrorMatchingPattern(`in contents.*must also be declared in PRODUCT_APEX_BOOT_JARS`), 947 ) 948 } 949 fixture.RunTestWithBp(t, fmt.Sprintf(bp, tc.apexContributionContents)) 950 } 951} 952