1// Copyright 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 rust 16 17import ( 18 "fmt" 19 "path/filepath" 20 "reflect" 21 "strings" 22 "testing" 23 24 "android/soong/android" 25 "android/soong/cc" 26) 27 28func TestVendorSnapshotCapture(t *testing.T) { 29 bp := ` 30 rust_ffi { 31 name: "libffivendor_available", 32 crate_name: "ffivendor_available", 33 srcs: ["lib.rs"], 34 vendor_available: true, 35 include_dirs: ["rust_headers/"], 36 } 37 38 rust_ffi { 39 name: "libffivendor", 40 crate_name: "ffivendor", 41 srcs: ["lib.rs"], 42 vendor: true, 43 include_dirs: ["rust_headers/"], 44 } 45 46 rust_library { 47 name: "librustvendor_available", 48 crate_name: "rustvendor_available", 49 srcs: ["lib.rs"], 50 vendor_available: true, 51 include_dirs: ["rust_headers/"], 52 } 53 54 rust_library_rlib { 55 name: "librustvendor", 56 crate_name: "rustvendor", 57 srcs: ["lib.rs"], 58 vendor: true, 59 include_dirs: ["rust_headers/"], 60 } 61 62 rust_binary { 63 name: "vendor_available_bin", 64 vendor_available: true, 65 srcs: ["srcs/lib.rs"], 66 } 67 68 rust_binary { 69 name: "vendor_bin", 70 vendor: true, 71 srcs: ["srcs/lib.rs"], 72 } 73 ` 74 skipTestIfOsNotSupported(t) 75 result := android.GroupFixturePreparers( 76 prepareForRustTest, 77 rustMockedFiles.AddToFixture(), 78 android.FixtureModifyProductVariables( 79 func(variables android.FixtureProductVariables) { 80 variables.DeviceVndkVersion = StringPtr("current") 81 variables.Platform_vndk_version = StringPtr("29") 82 }, 83 ), 84 ).RunTestWithBp(t, bp) 85 ctx := result.TestContext 86 87 // Check Vendor snapshot output. 88 89 snapshotDir := "vendor-snapshot" 90 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 91 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") 92 var jsonFiles []string 93 for _, arch := range [][]string{ 94 []string{"arm64", "armv8-a"}, 95 []string{"arm", "armv7-a-neon"}, 96 } { 97 archType := arch[0] 98 archVariant := arch[1] 99 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 100 101 // For shared libraries, only non-VNDK vendor_available modules are captured 102 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant) 103 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 104 cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.so", sharedDir, sharedVariant) 105 jsonFiles = append(jsonFiles, 106 filepath.Join(sharedDir, "libffivendor_available.so.json")) 107 108 // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured. 109 staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant) 110 staticDir := filepath.Join(snapshotVariantPath, archDir, "static") 111 cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.a", staticDir, staticVariant) 112 cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor", "libffivendor.a", staticDir, staticVariant) 113 jsonFiles = append(jsonFiles, 114 filepath.Join(staticDir, "libffivendor_available.a.json")) 115 jsonFiles = append(jsonFiles, 116 filepath.Join(staticDir, "libffivendor.a.json")) 117 118 // For rlib libraries, all vendor:true and vendor_available modules (including VNDK) are captured. 119 rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant) 120 rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib") 121 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib", rlibDir, rlibVariant) 122 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor", "librustvendor.rlib", rlibDir, rlibVariant) 123 jsonFiles = append(jsonFiles, 124 filepath.Join(rlibDir, "librustvendor_available.rlib.json")) 125 jsonFiles = append(jsonFiles, 126 filepath.Join(rlibDir, "librustvendor.rlib.json")) 127 128 // For binary executables, all vendor:true and vendor_available modules are captured. 129 if archType == "arm64" { 130 binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant) 131 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") 132 cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant) 133 cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant) 134 jsonFiles = append(jsonFiles, 135 filepath.Join(binaryDir, "vendor_available_bin.json")) 136 jsonFiles = append(jsonFiles, 137 filepath.Join(binaryDir, "vendor_bin.json")) 138 } 139 } 140 141 for _, jsonFile := range jsonFiles { 142 // verify all json files exist 143 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 144 t.Errorf("%q expected but not found; #%v", jsonFile, jsonFiles) 145 } 146 } 147 148 // fake snapshot should have all outputs in the normal snapshot. 149 fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot") 150 151 for _, output := range snapshotSingleton.AllOutputs() { 152 fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1) 153 if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil { 154 t.Errorf("%q expected but not found", fakeOutput) 155 } 156 } 157} 158 159func TestVendorSnapshotDirected(t *testing.T) { 160 bp := ` 161 rust_ffi_shared { 162 name: "libffivendor_available", 163 crate_name: "ffivendor_available", 164 srcs: ["lib.rs"], 165 vendor_available: true, 166 } 167 168 rust_library { 169 name: "librustvendor_available", 170 crate_name: "rustvendor_available", 171 srcs: ["lib.rs"], 172 vendor_available: true, 173 } 174 175 rust_ffi_shared { 176 name: "libffivendor_exclude", 177 crate_name: "ffivendor_exclude", 178 srcs: ["lib.rs"], 179 vendor_available: true, 180 } 181 182 rust_library { 183 name: "librustvendor_exclude", 184 crate_name: "rustvendor_exclude", 185 srcs: ["lib.rs"], 186 vendor_available: true, 187 } 188` 189 ctx := testRustVndk(t, bp) 190 ctx.Config().TestProductVariables.VendorSnapshotModules = make(map[string]bool) 191 ctx.Config().TestProductVariables.VendorSnapshotModules["librustvendor_available"] = true 192 ctx.Config().TestProductVariables.VendorSnapshotModules["libffivendor_available"] = true 193 ctx.Config().TestProductVariables.DirectedVendorSnapshot = true 194 195 // Check Vendor snapshot output. 196 197 snapshotDir := "vendor-snapshot" 198 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 199 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") 200 201 var includeJsonFiles []string 202 203 for _, arch := range [][]string{ 204 []string{"arm64", "armv8-a"}, 205 []string{"arm", "armv7-a-neon"}, 206 } { 207 archType := arch[0] 208 archVariant := arch[1] 209 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 210 211 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant) 212 rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant) 213 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 214 rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib") 215 216 // Included modules 217 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib", rlibDir, rlibVariant) 218 cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.so", sharedDir, sharedVariant) 219 includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_available.rlib.json")) 220 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libffivendor_available.so.json")) 221 222 // Excluded modules. Modules not included in the directed vendor snapshot 223 // are still include as fake modules. 224 cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.rlib", rlibDir, rlibVariant) 225 cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "libffivendor_exclude", "libffivendor_exclude.so", sharedDir, sharedVariant) 226 includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_exclude.rlib.json")) 227 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libffivendor_exclude.so.json")) 228 } 229 230 // Verify that each json file for an included module has a rule. 231 for _, jsonFile := range includeJsonFiles { 232 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 233 t.Errorf("include json file %q not found", jsonFile) 234 } 235 } 236} 237 238func TestVendorSnapshotExclude(t *testing.T) { 239 240 // This test verifies that the exclude_from_vendor_snapshot property 241 // makes its way from the Android.bp source file into the module data 242 // structure. It also verifies that modules are correctly included or 243 // excluded in the vendor snapshot based on their path (framework or 244 // vendor) and the exclude_from_vendor_snapshot property. 245 246 frameworkBp := ` 247 rust_ffi_shared { 248 name: "libinclude", 249 crate_name: "include", 250 srcs: ["include.rs"], 251 vendor_available: true, 252 } 253 254 rust_ffi_shared { 255 name: "libexclude", 256 crate_name: "exclude", 257 srcs: ["exclude.rs"], 258 vendor: true, 259 exclude_from_vendor_snapshot: true, 260 } 261 262 rust_ffi_shared { 263 name: "libavailable_exclude", 264 crate_name: "available_exclude", 265 srcs: ["lib.rs"], 266 vendor_available: true, 267 exclude_from_vendor_snapshot: true, 268 } 269 270 rust_library { 271 name: "librust_include", 272 crate_name: "rust_include", 273 srcs: ["include.rs"], 274 vendor_available: true, 275 } 276 277 rust_library_rlib { 278 name: "librust_exclude", 279 crate_name: "rust_exclude", 280 srcs: ["exclude.rs"], 281 vendor: true, 282 exclude_from_vendor_snapshot: true, 283 } 284 285 rust_library { 286 name: "librust_available_exclude", 287 crate_name: "rust_available_exclude", 288 srcs: ["lib.rs"], 289 vendor_available: true, 290 exclude_from_vendor_snapshot: true, 291 } 292 ` 293 294 mockFS := map[string][]byte{ 295 "framework/Android.bp": []byte(frameworkBp), 296 "framework/include.rs": nil, 297 "framework/exclude.rs": nil, 298 } 299 300 ctx := testRustVndkFs(t, "", mockFS) 301 302 // Test an include and exclude framework module. 303 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, sharedVendorVariant) 304 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, sharedVendorVariant) 305 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, sharedVendorVariant) 306 307 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_include", false, rlibVendorVariant) 308 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_exclude", true, rlibVendorVariant) 309 cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_available_exclude", true, rlibVendorVariant) 310 311 // Verify the content of the vendor snapshot. 312 313 snapshotDir := "vendor-snapshot" 314 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 315 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") 316 317 var includeJsonFiles []string 318 var excludeJsonFiles []string 319 320 for _, arch := range [][]string{ 321 []string{"arm64", "armv8-a"}, 322 []string{"arm", "armv7-a-neon"}, 323 } { 324 archType := arch[0] 325 archVariant := arch[1] 326 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 327 328 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant) 329 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 330 rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant) 331 rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib") 332 333 // Included modules 334 cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant) 335 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json")) 336 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librust_include", "librust_include.rlib", rlibDir, rlibVariant) 337 includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librust_include.rlib.json")) 338 339 // Excluded modules 340 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant) 341 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json")) 342 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant) 343 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json")) 344 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_exclude", "librust_exclude.rlib", rlibDir, rlibVariant) 345 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_exclude.rlib.json")) 346 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_available_exclude", "librust_available_exclude.rlib", rlibDir, rlibVariant) 347 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_available_exclude.rlib.json")) 348 } 349 350 // Verify that each json file for an included module has a rule. 351 for _, jsonFile := range includeJsonFiles { 352 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 353 t.Errorf("include json file %q not found", jsonFile) 354 } 355 } 356 357 // Verify that each json file for an excluded module has no rule. 358 for _, jsonFile := range excludeJsonFiles { 359 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { 360 t.Errorf("exclude json file %q found", jsonFile) 361 } 362 } 363} 364 365func TestVendorSnapshotUse(t *testing.T) { 366 frameworkBp := ` 367 cc_library { 368 name: "libvndk", 369 vendor_available: true, 370 product_available: true, 371 vndk: { 372 enabled: true, 373 }, 374 nocrt: true, 375 } 376 377 cc_library { 378 name: "libvendor", 379 vendor: true, 380 nocrt: true, 381 no_libcrt: true, 382 stl: "none", 383 system_shared_libs: [], 384 } 385 386 cc_library { 387 name: "libvendor_available", 388 vendor_available: true, 389 nocrt: true, 390 no_libcrt: true, 391 stl: "none", 392 system_shared_libs: [], 393 } 394 395 cc_library { 396 name: "lib32", 397 vendor: true, 398 nocrt: true, 399 no_libcrt: true, 400 stl: "none", 401 system_shared_libs: [], 402 compile_multilib: "32", 403 } 404 405 cc_library { 406 name: "lib64", 407 vendor: true, 408 nocrt: true, 409 no_libcrt: true, 410 stl: "none", 411 system_shared_libs: [], 412 compile_multilib: "64", 413 } 414 415 rust_binary { 416 name: "bin", 417 vendor: true, 418 srcs: ["bin.rs"], 419 } 420 421 rust_binary { 422 name: "bin32", 423 vendor: true, 424 compile_multilib: "32", 425 srcs: ["bin.rs"], 426 } 427 428 rust_library { 429 name: "librust_vendor_available", 430 crate_name: "rust_vendor", 431 vendor_available: true, 432 srcs: ["client.rs"], 433 } 434 435` 436 437 vndkBp := ` 438 vndk_prebuilt_shared { 439 name: "libvndk", 440 version: "30", 441 target_arch: "arm64", 442 vendor_available: true, 443 product_available: true, 444 vndk: { 445 enabled: true, 446 }, 447 arch: { 448 arm64: { 449 srcs: ["libvndk.so"], 450 export_include_dirs: ["include/libvndk"], 451 }, 452 arm: { 453 srcs: ["libvndk.so"], 454 export_include_dirs: ["include/libvndk"], 455 }, 456 }, 457 } 458 459 // old snapshot module which has to be ignored 460 vndk_prebuilt_shared { 461 name: "libvndk", 462 version: "26", 463 target_arch: "arm64", 464 vendor_available: true, 465 product_available: true, 466 vndk: { 467 enabled: true, 468 }, 469 arch: { 470 arm64: { 471 srcs: ["libvndk.so"], 472 export_include_dirs: ["include/libvndk"], 473 }, 474 arm: { 475 srcs: ["libvndk.so"], 476 export_include_dirs: ["include/libvndk"], 477 }, 478 }, 479 } 480 481 // different arch snapshot which has to be ignored 482 vndk_prebuilt_shared { 483 name: "libvndk", 484 version: "30", 485 target_arch: "arm", 486 vendor_available: true, 487 product_available: true, 488 vndk: { 489 enabled: true, 490 }, 491 arch: { 492 arm: { 493 srcs: ["libvndk.so"], 494 export_include_dirs: ["include/libvndk"], 495 }, 496 }, 497 } 498` 499 500 vendorProprietaryBp := ` 501 cc_library { 502 name: "libvendor_without_snapshot", 503 vendor: true, 504 nocrt: true, 505 no_libcrt: true, 506 stl: "none", 507 system_shared_libs: [], 508 } 509 510 rust_ffi_shared { 511 name: "libclient", 512 crate_name: "client", 513 vendor: true, 514 shared_libs: ["libvndk", "libvendor_available"], 515 static_libs: ["libvendor", "libvendor_without_snapshot"], 516 rustlibs: ["librust_vendor_available"], 517 arch: { 518 arm64: { 519 shared_libs: ["lib64"], 520 }, 521 arm: { 522 shared_libs: ["lib32"], 523 }, 524 }, 525 srcs: ["client.rs"], 526 } 527 528 rust_library_rlib { 529 name: "libclient_rust", 530 crate_name: "client_rust", 531 vendor: true, 532 shared_libs: ["libvndk", "libvendor_available"], 533 static_libs: ["libvendor", "libvendor_without_snapshot"], 534 rustlibs: ["librust_vendor_available"], 535 arch: { 536 arm64: { 537 shared_libs: ["lib64"], 538 }, 539 arm: { 540 shared_libs: ["lib32"], 541 }, 542 }, 543 srcs: ["client.rs"], 544 } 545 546 rust_binary { 547 name: "bin_without_snapshot", 548 vendor: true, 549 static_libs: ["libvndk"], 550 srcs: ["bin.rs"], 551 rustlibs: ["librust_vendor_available"], 552 } 553 554 vendor_snapshot { 555 name: "vendor_snapshot", 556 version: "30", 557 arch: { 558 arm64: { 559 vndk_libs: [ 560 "libvndk", 561 ], 562 static_libs: [ 563 "libvendor", 564 "libvndk", 565 "libclang_rt.builtins", 566 "note_memtag_heap_sync", 567 ], 568 shared_libs: [ 569 "libvendor_available", 570 "lib64", 571 ], 572 rlibs: [ 573 "libstd", 574 "librust_vendor_available", 575 ], 576 binaries: [ 577 "bin", 578 ], 579 objects: [ 580 "crtend_so", 581 "crtbegin_so", 582 "crtbegin_dynamic", 583 "crtend_android" 584 ], 585 }, 586 arm: { 587 vndk_libs: [ 588 "libvndk", 589 ], 590 static_libs: [ 591 "libvendor", 592 "libvndk", 593 "libclang_rt.builtins", 594 ], 595 shared_libs: [ 596 "libvendor_available", 597 "lib32", 598 ], 599 rlibs: [ 600 "libstd", 601 "librust_vendor_available", 602 ], 603 binaries: [ 604 "bin32", 605 ], 606 objects: [ 607 "crtend_so", 608 "crtbegin_so", 609 "crtbegin_dynamic", 610 "crtend_android" 611 ], 612 613 }, 614 } 615 } 616 617 vendor_snapshot_object { 618 name: "crtend_so", 619 version: "30", 620 target_arch: "arm64", 621 vendor: true, 622 stl: "none", 623 crt: true, 624 arch: { 625 arm64: { 626 src: "crtend_so.o", 627 }, 628 arm: { 629 src: "crtend_so.o", 630 }, 631 }, 632 } 633 634 vendor_snapshot_object { 635 name: "crtbegin_so", 636 version: "30", 637 target_arch: "arm64", 638 vendor: true, 639 stl: "none", 640 crt: true, 641 arch: { 642 arm64: { 643 src: "crtbegin_so.o", 644 }, 645 arm: { 646 src: "crtbegin_so.o", 647 }, 648 }, 649 } 650 651 vendor_snapshot_rlib { 652 name: "libstd", 653 version: "30", 654 target_arch: "arm64", 655 vendor: true, 656 sysroot: true, 657 arch: { 658 arm64: { 659 src: "libstd.rlib", 660 }, 661 arm: { 662 src: "libstd.rlib", 663 }, 664 }, 665 } 666 667 vendor_snapshot_rlib { 668 name: "librust_vendor_available", 669 version: "30", 670 target_arch: "arm64", 671 vendor: true, 672 arch: { 673 arm64: { 674 src: "librust_vendor_available.rlib", 675 }, 676 arm: { 677 src: "librust_vendor_available.rlib", 678 }, 679 }, 680 } 681 682 vendor_snapshot_object { 683 name: "crtend_android", 684 version: "30", 685 target_arch: "arm64", 686 vendor: true, 687 stl: "none", 688 crt: true, 689 arch: { 690 arm64: { 691 src: "crtend_so.o", 692 }, 693 arm: { 694 src: "crtend_so.o", 695 }, 696 }, 697 } 698 699 vendor_snapshot_object { 700 name: "crtbegin_dynamic", 701 version: "30", 702 target_arch: "arm64", 703 vendor: true, 704 stl: "none", 705 crt: true, 706 arch: { 707 arm64: { 708 src: "crtbegin_so.o", 709 }, 710 arm: { 711 src: "crtbegin_so.o", 712 }, 713 }, 714 } 715 716 vendor_snapshot_static { 717 name: "libvndk", 718 version: "30", 719 target_arch: "arm64", 720 compile_multilib: "both", 721 vendor: true, 722 arch: { 723 arm64: { 724 src: "libvndk.a", 725 }, 726 arm: { 727 src: "libvndk.a", 728 }, 729 }, 730 shared_libs: ["libvndk"], 731 export_shared_lib_headers: ["libvndk"], 732 } 733 734 vendor_snapshot_static { 735 name: "libclang_rt.builtins", 736 version: "30", 737 target_arch: "arm64", 738 vendor: true, 739 arch: { 740 arm: { 741 src: "libclang_rt.builtins-arm-android.a", 742 }, 743 arm64: { 744 src: "libclang_rt.builtins-aarch64-android.a", 745 }, 746 }, 747 } 748 749 vendor_snapshot_shared { 750 name: "lib32", 751 version: "30", 752 target_arch: "arm64", 753 compile_multilib: "32", 754 vendor: true, 755 arch: { 756 arm: { 757 src: "lib32.so", 758 }, 759 }, 760 } 761 762 vendor_snapshot_shared { 763 name: "lib64", 764 version: "30", 765 target_arch: "arm64", 766 compile_multilib: "64", 767 vendor: true, 768 arch: { 769 arm64: { 770 src: "lib64.so", 771 }, 772 }, 773 } 774 vendor_snapshot_shared { 775 name: "liblog", 776 version: "30", 777 target_arch: "arm64", 778 compile_multilib: "64", 779 vendor: true, 780 arch: { 781 arm64: { 782 src: "liblog.so", 783 }, 784 }, 785 } 786 787 vendor_snapshot_static { 788 name: "libvendor", 789 version: "30", 790 target_arch: "arm64", 791 compile_multilib: "both", 792 vendor: true, 793 arch: { 794 arm64: { 795 src: "libvendor.a", 796 export_include_dirs: ["include/libvendor"], 797 }, 798 arm: { 799 src: "libvendor.a", 800 export_include_dirs: ["include/libvendor"], 801 }, 802 }, 803 } 804 805 vendor_snapshot_shared { 806 name: "libvendor_available", 807 version: "30", 808 target_arch: "arm64", 809 compile_multilib: "both", 810 vendor: true, 811 arch: { 812 arm64: { 813 src: "libvendor_available.so", 814 export_include_dirs: ["include/libvendor"], 815 }, 816 arm: { 817 src: "libvendor_available.so", 818 export_include_dirs: ["include/libvendor"], 819 }, 820 }, 821 } 822 823 vendor_snapshot_binary { 824 name: "bin", 825 version: "30", 826 target_arch: "arm64", 827 compile_multilib: "64", 828 vendor: true, 829 arch: { 830 arm64: { 831 src: "bin", 832 }, 833 }, 834 } 835 836 vendor_snapshot_binary { 837 name: "bin32", 838 version: "30", 839 target_arch: "arm64", 840 compile_multilib: "32", 841 vendor: true, 842 arch: { 843 arm: { 844 src: "bin32", 845 }, 846 }, 847 } 848 849 // Test sanitizers use the snapshot libraries 850 rust_binary { 851 name: "memtag_binary", 852 srcs: ["vendor/bin.rs"], 853 vendor: true, 854 compile_multilib: "64", 855 sanitize: { 856 memtag_heap: true, 857 diag: { 858 memtag_heap: true, 859 } 860 }, 861 } 862 863 // old snapshot module which has to be ignored 864 vendor_snapshot_binary { 865 name: "bin", 866 version: "26", 867 target_arch: "arm64", 868 compile_multilib: "first", 869 vendor: true, 870 arch: { 871 arm64: { 872 src: "bin", 873 }, 874 }, 875 } 876 877 // different arch snapshot which has to be ignored 878 vendor_snapshot_binary { 879 name: "bin", 880 version: "30", 881 target_arch: "arm", 882 compile_multilib: "first", 883 vendor: true, 884 arch: { 885 arm64: { 886 src: "bin", 887 }, 888 }, 889 } 890 891 vendor_snapshot_static { 892 name: "note_memtag_heap_sync", 893 vendor: true, 894 target_arch: "arm64", 895 version: "30", 896 arch: { 897 arm64: { 898 src: "note_memtag_heap_sync.a", 899 }, 900 }, 901 } 902 903` 904 905 mockFS := android.MockFS{ 906 "framework/Android.bp": []byte(frameworkBp), 907 "framework/bin.rs": nil, 908 "note_memtag_heap_sync.a": nil, 909 "vendor/Android.bp": []byte(vendorProprietaryBp), 910 "vendor/bin": nil, 911 "vendor/bin32": nil, 912 "vendor/bin.rs": nil, 913 "vendor/client.rs": nil, 914 "vendor/include/libvndk/a.h": nil, 915 "vendor/include/libvendor/b.h": nil, 916 "vendor/libvndk.a": nil, 917 "vendor/libvendor.a": nil, 918 "vendor/libvendor.so": nil, 919 "vendor/lib32.so": nil, 920 "vendor/lib64.so": nil, 921 "vendor/liblog.so": nil, 922 "vendor/libstd.rlib": nil, 923 "vendor/librust_vendor_available.rlib": nil, 924 "vendor/crtbegin_so.o": nil, 925 "vendor/crtend_so.o": nil, 926 "vendor/libclang_rt.builtins-aarch64-android.a": nil, 927 "vendor/libclang_rt.builtins-arm-android.a": nil, 928 "vndk/Android.bp": []byte(vndkBp), 929 "vndk/include/libvndk/a.h": nil, 930 "vndk/libvndk.so": nil, 931 } 932 933 sharedVariant := "android_vendor.30_arm64_armv8-a_shared" 934 rlibVariant := "android_vendor.30_arm64_armv8-a_rlib_rlib-std" 935 staticVariant := "android_vendor.30_arm64_armv8-a_static" 936 binaryVariant := "android_vendor.30_arm64_armv8-a" 937 938 shared32Variant := "android_vendor.30_arm_armv7-a-neon_shared" 939 binary32Variant := "android_vendor.30_arm_armv7-a-neon" 940 941 ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31") 942 943 // libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot 944 libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustLink").Args["linkFlags"] 945 for _, input := range [][]string{ 946 []string{sharedVariant, "libvndk.vndk.30.arm64"}, 947 []string{staticVariant, "libvendor.vendor_static.30.arm64"}, 948 []string{staticVariant, "libvendor_without_snapshot"}, 949 } { 950 outputPaths := cc.GetOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */) 951 if !strings.Contains(libclientLdFlags, outputPaths[0].String()) { 952 t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags) 953 } 954 } 955 956 libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs 957 if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib64", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) { 958 t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g) 959 } 960 961 libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs 962 if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot", "libclang_rt.builtins.vendor"}; !reflect.DeepEqual(g, w) { 963 t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g) 964 } 965 966 libclientAndroidMkRlibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkRlibs 967 if g, w := libclientAndroidMkRlibs, []string{"librust_vendor_available.vendor.rlib-std", "libstd.vendor"}; !reflect.DeepEqual(g, w) { 968 t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g) 969 } 970 971 libclientAndroidMkDylibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkDylibs 972 if len(libclientAndroidMkDylibs) > 0 { 973 t.Errorf("wanted libclient libclientAndroidMkDylibs [], got %q", libclientAndroidMkDylibs) 974 } 975 976 libclient32AndroidMkSharedLibs := ctx.ModuleForTests("libclient", shared32Variant).Module().(*Module).Properties.AndroidMkSharedLibs 977 if g, w := libclient32AndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib32", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) { 978 t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g) 979 } 980 981 libclientRustAndroidMkRlibs := ctx.ModuleForTests("libclient_rust", rlibVariant).Module().(*Module).Properties.AndroidMkRlibs 982 if g, w := libclientRustAndroidMkRlibs, []string{"librust_vendor_available.vendor.rlib-std", "libstd.vendor"}; !reflect.DeepEqual(g, w) { 983 t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g) 984 } 985 986 // rust vendor snapshot must have ".vendor" suffix in AndroidMk 987 librustVendorAvailableSnapshotModule := ctx.ModuleForTests("librust_vendor_available.vendor_rlib.30.arm64", rlibVariant).Module() 988 librustVendorSnapshotMkName := android.AndroidMkEntriesForTest(t, ctx, librustVendorAvailableSnapshotModule)[0].EntryMap["LOCAL_MODULE"][0] 989 expectedRustVendorSnapshotName := "librust_vendor_available.vendor.rlib-std" 990 if librustVendorSnapshotMkName != expectedRustVendorSnapshotName { 991 t.Errorf("Unexpected rust vendor snapshot name in AndroidMk: %q, expected: %q\n", librustVendorSnapshotMkName, expectedRustVendorSnapshotName) 992 } 993 994 rustVendorBinModule := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Module() 995 rustVendorBinMkRlibName := android.AndroidMkEntriesForTest(t, ctx, rustVendorBinModule)[0].EntryMap["LOCAL_RLIB_LIBRARIES"][0] 996 if rustVendorBinMkRlibName != expectedRustVendorSnapshotName { 997 t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkRlibName, expectedRustVendorSnapshotName) 998 } 999 1000 binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustLink").Args["linkFlags"] 1001 libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"}) 1002 if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) { 1003 t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v", 1004 libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags) 1005 } 1006 1007 // bin is installed by bin.vendor_binary.30.arm64 1008 ctx.ModuleForTests("bin.vendor_binary.30.arm64", binaryVariant).Output("bin") 1009 1010 // bin32 is installed by bin32.vendor_binary.30.arm64 1011 ctx.ModuleForTests("bin32.vendor_binary.30.arm64", binary32Variant).Output("bin32") 1012 1013 // bin_without_snapshot is installed by bin_without_snapshot 1014 ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot") 1015 1016 // libvendor, libvendor_available and bin don't have vendor.30 variant 1017 libvendorVariants := ctx.ModuleVariantsForTests("libvendor") 1018 if android.InList(sharedVariant, libvendorVariants) { 1019 t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant) 1020 } 1021 1022 libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available") 1023 if android.InList(sharedVariant, libvendorAvailableVariants) { 1024 t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant) 1025 } 1026 1027 binVariants := ctx.ModuleVariantsForTests("bin") 1028 if android.InList(binaryVariant, binVariants) { 1029 t.Errorf("bin must not have variant %#v, but it does", sharedVariant) 1030 } 1031 1032 memtagStaticLibs := ctx.ModuleForTests("memtag_binary", "android_vendor.30_arm64_armv8-a").Module().(*Module).Properties.AndroidMkStaticLibs 1033 if g, w := memtagStaticLibs, []string{"libclang_rt.builtins.vendor", "note_memtag_heap_sync.vendor"}; !reflect.DeepEqual(g, w) { 1034 t.Errorf("wanted memtag_binary AndroidMkStaticLibs %q, got %q", w, g) 1035 } 1036} 1037 1038func TestRecoverySnapshotCapture(t *testing.T) { 1039 bp := ` 1040 rust_ffi { 1041 name: "librecovery", 1042 recovery: true, 1043 srcs: ["foo.rs"], 1044 crate_name: "recovery", 1045 } 1046 1047 rust_ffi { 1048 name: "librecovery_available", 1049 recovery_available: true, 1050 srcs: ["foo.rs"], 1051 crate_name: "recovery_available", 1052 } 1053 1054 rust_library_rlib { 1055 name: "librecovery_rlib", 1056 recovery: true, 1057 srcs: ["foo.rs"], 1058 crate_name: "recovery_rlib", 1059 } 1060 1061 rust_library_rlib { 1062 name: "librecovery_available_rlib", 1063 recovery_available: true, 1064 srcs: ["foo.rs"], 1065 crate_name: "recovery_available_rlib", 1066 } 1067 1068 rust_binary { 1069 name: "recovery_bin", 1070 recovery: true, 1071 srcs: ["foo.rs"], 1072 } 1073 1074 rust_binary { 1075 name: "recovery_available_bin", 1076 recovery_available: true, 1077 srcs: ["foo.rs"], 1078 } 1079 1080` 1081 // Check Recovery snapshot output. 1082 1083 ctx := testRustRecoveryFsVersions(t, bp, rustMockedFiles, "", "29", "current") 1084 snapshotDir := "recovery-snapshot" 1085 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 1086 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") 1087 1088 var jsonFiles []string 1089 1090 for _, arch := range [][]string{ 1091 []string{"arm64", "armv8-a"}, 1092 } { 1093 archType := arch[0] 1094 archVariant := arch[1] 1095 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 1096 1097 // For shared libraries, all recovery:true and recovery_available modules are captured. 1098 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) 1099 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 1100 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) 1101 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant) 1102 jsonFiles = append(jsonFiles, 1103 filepath.Join(sharedDir, "librecovery.so.json"), 1104 filepath.Join(sharedDir, "librecovery_available.so.json")) 1105 1106 // For static libraries, all recovery:true and recovery_available modules are captured. 1107 staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant) 1108 staticDir := filepath.Join(snapshotVariantPath, archDir, "static") 1109 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant) 1110 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant) 1111 jsonFiles = append(jsonFiles, 1112 filepath.Join(staticDir, "librecovery.a.json"), 1113 filepath.Join(staticDir, "librecovery_available.a.json")) 1114 1115 // For rlib libraries, all recovery:true and recovery_available modules are captured. 1116 rlibVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_rlib-std", archType, archVariant) 1117 rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib") 1118 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_rlib", "librecovery_rlib.rlib", rlibDir, rlibVariant) 1119 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available_rlib", "librecovery_available_rlib.rlib", rlibDir, rlibVariant) 1120 jsonFiles = append(jsonFiles, 1121 filepath.Join(rlibDir, "librecovery_rlib.rlib.json"), 1122 filepath.Join(rlibDir, "librecovery_available_rlib.rlib.json")) 1123 1124 // For binary executables, all recovery:true and recovery_available modules are captured. 1125 if archType == "arm64" { 1126 binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant) 1127 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") 1128 cc.CheckSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant) 1129 cc.CheckSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant) 1130 jsonFiles = append(jsonFiles, 1131 filepath.Join(binaryDir, "recovery_bin.json"), 1132 filepath.Join(binaryDir, "recovery_available_bin.json")) 1133 } 1134 } 1135 1136 for _, jsonFile := range jsonFiles { 1137 // verify all json files exist 1138 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 1139 t.Errorf("%q expected but not found", jsonFile) 1140 } 1141 } 1142} 1143 1144func TestRecoverySnapshotExclude(t *testing.T) { 1145 // This test verifies that the exclude_from_recovery_snapshot property 1146 // makes its way from the Android.bp source file into the module data 1147 // structure. It also verifies that modules are correctly included or 1148 // excluded in the recovery snapshot based on their path (framework or 1149 // vendor) and the exclude_from_recovery_snapshot property. 1150 1151 frameworkBp := ` 1152 rust_ffi_shared { 1153 name: "libinclude", 1154 srcs: ["src/include.rs"], 1155 recovery_available: true, 1156 crate_name: "include", 1157 } 1158 rust_ffi_shared { 1159 name: "libexclude", 1160 srcs: ["src/exclude.rs"], 1161 recovery: true, 1162 exclude_from_recovery_snapshot: true, 1163 crate_name: "exclude", 1164 } 1165 rust_ffi_shared { 1166 name: "libavailable_exclude", 1167 srcs: ["src/exclude.rs"], 1168 recovery_available: true, 1169 exclude_from_recovery_snapshot: true, 1170 crate_name: "available_exclude", 1171 } 1172 rust_library_rlib { 1173 name: "libinclude_rlib", 1174 srcs: ["src/include.rs"], 1175 recovery_available: true, 1176 crate_name: "include_rlib", 1177 } 1178 rust_library_rlib { 1179 name: "libexclude_rlib", 1180 srcs: ["src/exclude.rs"], 1181 recovery: true, 1182 exclude_from_recovery_snapshot: true, 1183 crate_name: "exclude_rlib", 1184 } 1185 rust_library_rlib { 1186 name: "libavailable_exclude_rlib", 1187 srcs: ["src/exclude.rs"], 1188 recovery_available: true, 1189 exclude_from_recovery_snapshot: true, 1190 crate_name: "available_exclude_rlib", 1191 } 1192 ` 1193 1194 vendorProprietaryBp := ` 1195 rust_ffi_shared { 1196 name: "librecovery", 1197 srcs: ["recovery.rs"], 1198 recovery: true, 1199 crate_name: "recovery", 1200 } 1201 rust_library_rlib { 1202 name: "librecovery_rlib", 1203 srcs: ["recovery.rs"], 1204 recovery: true, 1205 crate_name: "recovery_rlib", 1206 } 1207 ` 1208 1209 mockFS := map[string][]byte{ 1210 "framework/Android.bp": []byte(frameworkBp), 1211 "framework/include.rs": nil, 1212 "framework/exclude.rs": nil, 1213 "device/Android.bp": []byte(vendorProprietaryBp), 1214 "device/recovery.rs": nil, 1215 } 1216 1217 ctx := testRustRecoveryFsVersions(t, "", mockFS, "", "29", "current") 1218 1219 // Test an include and exclude framework module. 1220 cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false, sharedRecoveryVariant) 1221 cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true, sharedRecoveryVariant) 1222 cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true, sharedRecoveryVariant) 1223 cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude_rlib", false, rlibRecoveryVariant) 1224 cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude_rlib", true, rlibRecoveryVariant) 1225 cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude_rlib", true, rlibRecoveryVariant) 1226 1227 // A recovery module is excluded, but by its path not the exclude_from_recovery_snapshot property 1228 // ('device/' and 'vendor/' are default excluded). See snapshot/recovery_snapshot.go for more detail. 1229 cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false, sharedRecoveryVariant) 1230 cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery_rlib", false, rlibRecoveryVariant) 1231 1232 // Verify the content of the recovery snapshot. 1233 1234 snapshotDir := "recovery-snapshot" 1235 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 1236 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") 1237 1238 var includeJsonFiles []string 1239 var excludeJsonFiles []string 1240 1241 for _, arch := range [][]string{ 1242 []string{"arm64", "armv8-a"}, 1243 } { 1244 archType := arch[0] 1245 archVariant := arch[1] 1246 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 1247 1248 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) 1249 rlibVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_rlib-std", archType, archVariant) 1250 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 1251 rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib") 1252 1253 // Included modules 1254 cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant) 1255 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json")) 1256 cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude_rlib", "libinclude_rlib.rlib", rlibDir, rlibVariant) 1257 includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "libinclude_rlib.rlib.json")) 1258 1259 // Excluded modules 1260 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant) 1261 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json")) 1262 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) 1263 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json")) 1264 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant) 1265 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json")) 1266 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude_rlib", "libexclude_rlib.rlib", rlibDir, rlibVariant) 1267 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "libexclude_rlib.rlib.json")) 1268 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librecovery_rlib", "librecovery_rlib.rlib", rlibDir, rlibVariant) 1269 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librecovery_rlib.rlib.json")) 1270 cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude_rlib", "libavailable_exclude_rlib.rlib", rlibDir, rlibVariant) 1271 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "libavailable_exclude_rlib.rlib.json")) 1272 } 1273 1274 // Verify that each json file for an included module has a rule. 1275 for _, jsonFile := range includeJsonFiles { 1276 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 1277 t.Errorf("include json file %q not found", jsonFile) 1278 } 1279 } 1280 1281 // Verify that each json file for an excluded module has no rule. 1282 for _, jsonFile := range excludeJsonFiles { 1283 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { 1284 t.Errorf("exclude json file %q found", jsonFile) 1285 } 1286 } 1287} 1288 1289func TestRecoverySnapshotDirected(t *testing.T) { 1290 bp := ` 1291 rust_ffi_shared { 1292 name: "librecovery", 1293 recovery: true, 1294 crate_name: "recovery", 1295 srcs: ["foo.rs"], 1296 } 1297 1298 rust_ffi_shared { 1299 name: "librecovery_available", 1300 recovery_available: true, 1301 crate_name: "recovery_available", 1302 srcs: ["foo.rs"], 1303 } 1304 1305 rust_library_rlib { 1306 name: "librecovery_rlib", 1307 recovery: true, 1308 crate_name: "recovery", 1309 srcs: ["foo.rs"], 1310 } 1311 1312 rust_library_rlib { 1313 name: "librecovery_available_rlib", 1314 recovery_available: true, 1315 crate_name: "recovery_available", 1316 srcs: ["foo.rs"], 1317 } 1318 1319 /* TODO: Uncomment when Rust supports the "prefer" property for prebuilts 1320 rust_library_rlib { 1321 name: "libfoo_rlib", 1322 recovery: true, 1323 crate_name: "foo", 1324 } 1325 1326 rust_prebuilt_rlib { 1327 name: "libfoo_rlib", 1328 recovery: true, 1329 prefer: true, 1330 srcs: ["libfoo.rlib"], 1331 crate_name: "foo", 1332 } 1333 */ 1334` 1335 ctx := testRustRecoveryFsVersions(t, bp, rustMockedFiles, "current", "29", "current") 1336 ctx.Config().TestProductVariables.RecoverySnapshotModules = make(map[string]bool) 1337 ctx.Config().TestProductVariables.RecoverySnapshotModules["librecovery"] = true 1338 ctx.Config().TestProductVariables.RecoverySnapshotModules["librecovery_rlib"] = true 1339 ctx.Config().TestProductVariables.DirectedRecoverySnapshot = true 1340 1341 // Check recovery snapshot output. 1342 snapshotDir := "recovery-snapshot" 1343 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 1344 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") 1345 1346 var includeJsonFiles []string 1347 1348 for _, arch := range [][]string{ 1349 []string{"arm64", "armv8-a"}, 1350 } { 1351 archType := arch[0] 1352 archVariant := arch[1] 1353 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 1354 1355 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) 1356 rlibVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_rlib-std", archType, archVariant) 1357 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 1358 rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib") 1359 1360 // Included modules 1361 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) 1362 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json")) 1363 cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_rlib", "librecovery_rlib.rlib", rlibDir, rlibVariant) 1364 includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librecovery_rlib.rlib.json")) 1365 1366 // TODO: When Rust supports the "prefer" property for prebuilts, perform this check. 1367 /* 1368 // Check that snapshot captures "prefer: true" prebuilt 1369 cc.CheckSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo_rlib", "libfoo_rlib.rlib", rlibDir, rlibVariant) 1370 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo_rlib.rlib.json")) 1371 */ 1372 1373 // Excluded modules. Modules not included in the directed recovery snapshot 1374 // are still included as fake modules. 1375 cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant) 1376 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery_available.so.json")) 1377 cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available_rlib", "librecovery_available_rlib.rlib", rlibDir, rlibVariant) 1378 includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librecovery_available_rlib.rlib.json")) 1379 } 1380 1381 // Verify that each json file for an included module has a rule. 1382 for _, jsonFile := range includeJsonFiles { 1383 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 1384 t.Errorf("include json file %q not found, %#v", jsonFile, includeJsonFiles) 1385 } 1386 } 1387} 1388