1// Copyright 2021 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 filesystem 16 17import ( 18 "os" 19 "strings" 20 "testing" 21 22 "android/soong/android" 23 "android/soong/bpf" 24 "android/soong/cc" 25 "android/soong/etc" 26 "android/soong/java" 27 "android/soong/phony" 28 29 "github.com/google/blueprint/proptools" 30) 31 32func TestMain(m *testing.M) { 33 os.Exit(m.Run()) 34} 35 36var fixture = android.GroupFixturePreparers( 37 android.PrepareForIntegrationTestWithAndroid, 38 android.PrepareForTestWithAndroidBuildComponents, 39 bpf.PrepareForTestWithBpf, 40 cc.PrepareForIntegrationTestWithCc, 41 etc.PrepareForTestWithPrebuiltEtc, 42 java.PrepareForTestWithJavaBuildComponents, 43 java.PrepareForTestWithJavaDefaultModules, 44 phony.PrepareForTestWithPhony, 45 PrepareForTestWithFilesystemBuildComponents, 46) 47 48func TestFileSystemDeps(t *testing.T) { 49 result := fixture.RunTestWithBp(t, ` 50 android_filesystem { 51 name: "myfilesystem", 52 multilib: { 53 common: { 54 deps: [ 55 "bpf.o", 56 "phony", 57 ], 58 }, 59 lib32: { 60 deps: [ 61 "foo", 62 "libbar", 63 ], 64 }, 65 lib64: { 66 deps: [ 67 "libbar", 68 ], 69 }, 70 }, 71 compile_multilib: "both", 72 } 73 74 bpf { 75 name: "bpf.o", 76 srcs: ["bpf.c"], 77 } 78 79 cc_binary { 80 name: "foo", 81 compile_multilib: "prefer32", 82 } 83 84 cc_library { 85 name: "libbar", 86 required: ["libbaz"], 87 target: { 88 platform: { 89 required: ["lib_platform_only"], 90 }, 91 }, 92 } 93 94 cc_library { 95 name: "libbaz", 96 } 97 98 cc_library { 99 name: "lib_platform_only", 100 } 101 102 phony { 103 name: "phony", 104 required: [ 105 "libquz", 106 "myapp", 107 ], 108 } 109 110 cc_library { 111 name: "libquz", 112 } 113 114 android_app { 115 name: "myapp", 116 platform_apis: true, 117 installable: true, 118 } 119 `) 120 121 // produces "myfilesystem.img" 122 result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img") 123 124 fs := result.ModuleForTests("myfilesystem", "android_common").Module().(*filesystem) 125 expected := []string{ 126 "app/myapp/myapp.apk", 127 "bin/foo", 128 "lib/libbar.so", 129 "lib64/libbar.so", 130 "lib64/libbaz.so", 131 "lib64/libquz.so", 132 "lib64/lib_platform_only.so", 133 "etc/bpf/bpf.o", 134 } 135 for _, e := range expected { 136 android.AssertStringListContains(t, "missing entry", fs.entries, e) 137 } 138} 139 140func TestIncludeMakeBuiltFiles(t *testing.T) { 141 result := fixture.RunTestWithBp(t, ` 142 android_filesystem { 143 name: "myfilesystem", 144 include_make_built_files: "system", 145 } 146 `) 147 148 output := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img") 149 150 stampFile := "out/target/product/test_device/obj/PACKAGING/system_intermediates/staging_dir.stamp" 151 fileListFile := "out/target/product/test_device/obj/PACKAGING/system_intermediates/file_list.txt" 152 android.AssertStringListContains(t, "deps of filesystem must include the staging dir stamp file", output.Implicits.Strings(), stampFile) 153 android.AssertStringListContains(t, "deps of filesystem must include the staging dir file list", output.Implicits.Strings(), fileListFile) 154} 155 156func TestFileSystemFillsLinkerConfigWithStubLibs(t *testing.T) { 157 result := fixture.RunTestWithBp(t, ` 158 android_system_image { 159 name: "myfilesystem", 160 base_dir: "system", 161 deps: [ 162 "libfoo", 163 "libbar", 164 ], 165 linker_config: { 166 gen_linker_config: true, 167 linker_config_srcs: ["linker.config.json"], 168 }, 169 } 170 171 cc_library { 172 name: "libfoo", 173 stubs: { 174 symbol_file: "libfoo.map.txt", 175 }, 176 } 177 178 cc_library { 179 name: "libbar", 180 } 181 `) 182 183 module := result.ModuleForTests("myfilesystem", "android_common") 184 output := module.Output("out/soong/.intermediates/myfilesystem/android_common/root/system/etc/linker.config.pb") 185 186 fullCommand := output.RuleParams.Command 187 startIndex := strings.Index(fullCommand, "conv_linker_config") 188 linkerConfigCommand := fullCommand[startIndex:] 189 190 android.AssertStringDoesContain(t, "linker.config.pb should have libfoo", 191 linkerConfigCommand, "libfoo.so") 192 android.AssertStringDoesNotContain(t, "linker.config.pb should not have libbar", 193 linkerConfigCommand, "libbar.so") 194} 195 196func registerComponent(ctx android.RegistrationContext) { 197 ctx.RegisterModuleType("component", componentFactory) 198} 199 200func componentFactory() android.Module { 201 m := &component{} 202 m.AddProperties(&m.properties) 203 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) 204 return m 205} 206 207type component struct { 208 android.ModuleBase 209 properties struct { 210 Install_copy_in_data []string 211 } 212} 213 214func (c *component) GenerateAndroidBuildActions(ctx android.ModuleContext) { 215 output := android.PathForModuleOut(ctx, c.Name()) 216 dir := android.PathForModuleInstall(ctx, "components") 217 ctx.InstallFile(dir, c.Name(), output) 218 219 dataDir := android.PathForModuleInPartitionInstall(ctx, "data", "components") 220 for _, d := range c.properties.Install_copy_in_data { 221 ctx.InstallFile(dataDir, d, output) 222 } 223} 224 225func TestFileSystemGathersItemsOnlyInSystemPartition(t *testing.T) { 226 f := android.GroupFixturePreparers(fixture, android.FixtureRegisterWithContext(registerComponent)) 227 result := f.RunTestWithBp(t, ` 228 android_system_image { 229 name: "myfilesystem", 230 multilib: { 231 common: { 232 deps: ["foo"], 233 }, 234 }, 235 linker_config: { 236 gen_linker_config: true, 237 linker_config_srcs: ["linker.config.json"], 238 }, 239 } 240 component { 241 name: "foo", 242 install_copy_in_data: ["bar"], 243 } 244 `) 245 246 module := result.ModuleForTests("myfilesystem", "android_common").Module().(*systemImage) 247 android.AssertDeepEquals(t, "entries should have foo and not bar", []string{"components/foo", "etc/linker.config.pb"}, module.entries) 248} 249 250func TestAvbGenVbmetaImage(t *testing.T) { 251 result := fixture.RunTestWithBp(t, ` 252 avb_gen_vbmeta_image { 253 name: "input_hashdesc", 254 src: "input.img", 255 partition_name: "input_partition_name", 256 salt: "2222", 257 }`) 258 cmd := result.ModuleForTests("input_hashdesc", "android_arm64_armv8-a").Rule("avbGenVbmetaImage").RuleParams.Command 259 android.AssertStringDoesContain(t, "Can't find correct --partition_name argument", 260 cmd, "--partition_name input_partition_name") 261 android.AssertStringDoesContain(t, "Can't find --do_not_append_vbmeta_image", 262 cmd, "--do_not_append_vbmeta_image") 263 android.AssertStringDoesContain(t, "Can't find --output_vbmeta_image", 264 cmd, "--output_vbmeta_image ") 265 android.AssertStringDoesContain(t, "Can't find --salt argument", 266 cmd, "--salt 2222") 267} 268 269func TestAvbAddHashFooter(t *testing.T) { 270 result := fixture.RunTestWithBp(t, ` 271 avb_gen_vbmeta_image { 272 name: "input_hashdesc", 273 src: "input.img", 274 partition_name: "input", 275 salt: "2222", 276 } 277 278 avb_add_hash_footer { 279 name: "myfooter", 280 src: "input.img", 281 filename: "output.img", 282 partition_name: "mypartition", 283 private_key: "mykey", 284 salt: "1111", 285 props: [ 286 { 287 name: "prop1", 288 value: "value1", 289 }, 290 { 291 name: "prop2", 292 file: "value_file", 293 }, 294 ], 295 include_descriptors_from_images: ["input_hashdesc"], 296 } 297 `) 298 cmd := result.ModuleForTests("myfooter", "android_arm64_armv8-a").Rule("avbAddHashFooter").RuleParams.Command 299 android.AssertStringDoesContain(t, "Can't find correct --partition_name argument", 300 cmd, "--partition_name mypartition") 301 android.AssertStringDoesContain(t, "Can't find correct --key argument", 302 cmd, "--key mykey") 303 android.AssertStringDoesContain(t, "Can't find --salt argument", 304 cmd, "--salt 1111") 305 android.AssertStringDoesContain(t, "Can't find --prop argument", 306 cmd, "--prop 'prop1:value1'") 307 android.AssertStringDoesContain(t, "Can't find --prop_from_file argument", 308 cmd, "--prop_from_file 'prop2:value_file'") 309 android.AssertStringDoesContain(t, "Can't find --include_descriptors_from_image", 310 cmd, "--include_descriptors_from_image ") 311} 312 313func TestFileSystemWithCoverageVariants(t *testing.T) { 314 context := android.GroupFixturePreparers( 315 fixture, 316 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 317 variables.GcovCoverage = proptools.BoolPtr(true) 318 variables.Native_coverage = proptools.BoolPtr(true) 319 }), 320 ) 321 322 result := context.RunTestWithBp(t, ` 323 prebuilt_etc { 324 name: "prebuilt", 325 src: ":myfilesystem", 326 } 327 328 android_system_image { 329 name: "myfilesystem", 330 deps: [ 331 "libfoo", 332 ], 333 linker_config: { 334 gen_linker_config: true, 335 linker_config_srcs: ["linker.config.json"], 336 }, 337 } 338 339 cc_library { 340 name: "libfoo", 341 shared_libs: [ 342 "libbar", 343 ], 344 stl: "none", 345 } 346 347 cc_library { 348 name: "libbar", 349 stl: "none", 350 } 351 `) 352 353 filesystem := result.ModuleForTests("myfilesystem", "android_common_cov") 354 inputs := filesystem.Output("myfilesystem.img").Implicits 355 android.AssertStringListContains(t, "filesystem should have libfoo(cov)", 356 inputs.Strings(), 357 "out/soong/.intermediates/libfoo/android_arm64_armv8-a_shared_cov/libfoo.so") 358 android.AssertStringListContains(t, "filesystem should have libbar(cov)", 359 inputs.Strings(), 360 "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared_cov/libbar.so") 361 362 filesystemOutput := filesystem.Output("myfilesystem.img").Output 363 prebuiltInput := result.ModuleForTests("prebuilt", "android_arm64_armv8-a").Rule("Cp").Input 364 if filesystemOutput != prebuiltInput { 365 t.Error("prebuilt should use cov variant of filesystem") 366 } 367} 368 369func TestSystemImageDefaults(t *testing.T) { 370 result := fixture.RunTestWithBp(t, ` 371 android_filesystem_defaults { 372 name: "defaults", 373 multilib: { 374 common: { 375 deps: [ 376 "phony", 377 ], 378 }, 379 lib64: { 380 deps: [ 381 "libbar", 382 ], 383 }, 384 }, 385 compile_multilib: "both", 386 } 387 388 android_system_image { 389 name: "system", 390 defaults: ["defaults"], 391 multilib: { 392 lib32: { 393 deps: [ 394 "foo", 395 "libbar", 396 ], 397 }, 398 }, 399 } 400 401 cc_binary { 402 name: "foo", 403 compile_multilib: "prefer32", 404 } 405 406 cc_library { 407 name: "libbar", 408 required: ["libbaz"], 409 } 410 411 cc_library { 412 name: "libbaz", 413 } 414 415 phony { 416 name: "phony", 417 required: ["libquz"], 418 } 419 420 cc_library { 421 name: "libquz", 422 } 423 `) 424 425 fs := result.ModuleForTests("system", "android_common").Module().(*systemImage) 426 expected := []string{ 427 "bin/foo", 428 "lib/libbar.so", 429 "lib64/libbar.so", 430 "lib64/libbaz.so", 431 "lib64/libquz.so", 432 } 433 for _, e := range expected { 434 android.AssertStringListContains(t, "missing entry", fs.entries, e) 435 } 436} 437 438func TestInconsistentPartitionTypesInDefaults(t *testing.T) { 439 fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern( 440 "doesn't match with the partition type")). 441 RunTestWithBp(t, ` 442 android_filesystem_defaults { 443 name: "system_ext_def", 444 partition_type: "system_ext", 445 } 446 447 android_filesystem_defaults { 448 name: "system_def", 449 partition_type: "system", 450 defaults: ["system_ext_def"], 451 } 452 453 android_system_image { 454 name: "system", 455 defaults: ["system_def"], 456 } 457 `) 458} 459 460func TestPreventDuplicatedEntries(t *testing.T) { 461 fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern( 462 "packaging conflict at")). 463 RunTestWithBp(t, ` 464 android_filesystem { 465 name: "fs", 466 deps: [ 467 "foo", 468 "foo_dup", 469 ], 470 } 471 472 cc_binary { 473 name: "foo", 474 } 475 476 cc_binary { 477 name: "foo_dup", 478 stem: "foo", 479 } 480 `) 481} 482 483func TestTrackPhonyAsRequiredDep(t *testing.T) { 484 result := fixture.RunTestWithBp(t, ` 485 android_filesystem { 486 name: "fs", 487 deps: ["foo"], 488 } 489 490 cc_binary { 491 name: "foo", 492 required: ["phony"], 493 } 494 495 phony { 496 name: "phony", 497 required: ["libbar"], 498 } 499 500 cc_library { 501 name: "libbar", 502 } 503 `) 504 505 fs := result.ModuleForTests("fs", "android_common").Module().(*filesystem) 506 expected := []string{ 507 "bin/foo", 508 "lib64/libbar.so", 509 } 510 for _, e := range expected { 511 android.AssertStringListContains(t, "missing entry", fs.entries, e) 512 } 513} 514 515func TestFilterOutUnsupportedArches(t *testing.T) { 516 result := fixture.RunTestWithBp(t, ` 517 android_filesystem { 518 name: "fs_64_only", 519 deps: ["foo"], 520 } 521 522 android_filesystem { 523 name: "fs_64_32", 524 compile_multilib: "both", 525 deps: ["foo"], 526 } 527 528 cc_binary { 529 name: "foo", 530 required: ["phony"], 531 } 532 533 phony { 534 name: "phony", 535 required: [ 536 "libbar", 537 "app", 538 ], 539 } 540 541 cc_library { 542 name: "libbar", 543 } 544 545 android_app { 546 name: "app", 547 srcs: ["a.java"], 548 platform_apis: true, 549 } 550 `) 551 testcases := []struct { 552 fsName string 553 expected []string 554 unexpected []string 555 }{ 556 { 557 fsName: "fs_64_only", 558 expected: []string{"app/app/app.apk", "bin/foo", "lib64/libbar.so"}, 559 unexpected: []string{"lib/libbar.so"}, 560 }, 561 { 562 fsName: "fs_64_32", 563 expected: []string{"app/app/app.apk", "bin/foo", "lib64/libbar.so", "lib/libbar.so"}, 564 unexpected: []string{}, 565 }, 566 } 567 for _, c := range testcases { 568 fs := result.ModuleForTests(c.fsName, "android_common").Module().(*filesystem) 569 for _, e := range c.expected { 570 android.AssertStringListContains(t, "missing entry", fs.entries, e) 571 } 572 for _, e := range c.unexpected { 573 android.AssertStringListDoesNotContain(t, "unexpected entry", fs.entries, e) 574 } 575 } 576} 577 578func TestErofsPartition(t *testing.T) { 579 result := fixture.RunTestWithBp(t, ` 580 android_filesystem { 581 name: "erofs_partition", 582 type: "erofs", 583 erofs: { 584 compressor: "lz4hc,9", 585 compress_hints: "compress_hints.txt", 586 }, 587 deps: ["binfoo"], 588 } 589 590 cc_binary { 591 name: "binfoo", 592 } 593 `) 594 595 partition := result.ModuleForTests("erofs_partition", "android_common") 596 buildImageConfig := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("prop_pre_processing")) 597 android.AssertStringDoesContain(t, "erofs fs type", buildImageConfig, "fs_type=erofs") 598 android.AssertStringDoesContain(t, "erofs fs type compress algorithm", buildImageConfig, "erofs_default_compressor=lz4hc,9") 599 android.AssertStringDoesContain(t, "erofs fs type compress hint", buildImageConfig, "erofs_default_compress_hints=compress_hints.txt") 600 android.AssertStringDoesContain(t, "erofs fs type sparse", buildImageConfig, "erofs_sparse_flag=-s") 601} 602 603func TestF2fsPartition(t *testing.T) { 604 result := fixture.RunTestWithBp(t, ` 605 android_filesystem { 606 name: "f2fs_partition", 607 type: "f2fs", 608 } 609 `) 610 611 partition := result.ModuleForTests("f2fs_partition", "android_common") 612 buildImageConfig := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("prop_pre_processing")) 613 android.AssertStringDoesContain(t, "f2fs fs type", buildImageConfig, "fs_type=f2fs") 614 android.AssertStringDoesContain(t, "f2fs fs type sparse", buildImageConfig, "f2fs_sparse_flag=-S") 615} 616 617func TestFsTypesPropertyError(t *testing.T) { 618 fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern( 619 "erofs: erofs is non-empty, but FS type is f2fs\n. Please delete erofs properties if this partition should use f2fs\n")). 620 RunTestWithBp(t, ` 621 android_filesystem { 622 name: "f2fs_partition", 623 type: "f2fs", 624 erofs: { 625 compressor: "lz4hc,9", 626 compress_hints: "compress_hints.txt", 627 }, 628 } 629 `) 630} 631 632// If a system_ext/ module depends on system/ module, the dependency should *not* 633// be installed in system_ext/ 634func TestDoNotPackageCrossPartitionDependencies(t *testing.T) { 635 t.Skip() // TODO (spandandas): Re-enable this 636 result := fixture.RunTestWithBp(t, ` 637 android_filesystem { 638 name: "myfilesystem", 639 deps: ["binfoo"], 640 partition_type: "system_ext", 641 } 642 643 cc_binary { 644 name: "binfoo", 645 shared_libs: ["libfoo"], 646 system_ext_specific: true, 647 } 648 cc_library_shared { 649 name: "libfoo", // installed in system/ 650 } 651 `) 652 653 partition := result.ModuleForTests("myfilesystem", "android_common") 654 fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList")) 655 android.AssertDeepEquals(t, "filesystem with dependencies on different partition", "bin/binfoo\n", fileList) 656} 657 658// If a cc_library is listed in `deps`, and it has a shared and static variant, then the shared variant 659// should be installed. 660func TestUseSharedVariationOfNativeLib(t *testing.T) { 661 result := fixture.RunTestWithBp(t, ` 662 android_filesystem { 663 name: "myfilesystem", 664 deps: ["libfoo"], 665 } 666 // cc_library will create a static and shared variant. 667 cc_library { 668 name: "libfoo", 669 } 670 `) 671 672 partition := result.ModuleForTests("myfilesystem", "android_common") 673 fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList")) 674 android.AssertDeepEquals(t, "cc_library listed in deps", 675 "lib64/bootstrap/libc.so\nlib64/bootstrap/libdl.so\nlib64/bootstrap/libm.so\nlib64/libc++.so\nlib64/libc.so\nlib64/libdl.so\nlib64/libfoo.so\nlib64/libm.so\n", 676 fileList) 677} 678 679// binfoo1 overrides binbar. transitive deps of binbar should not be installed. 680func TestDoNotInstallTransitiveDepOfOverriddenModule(t *testing.T) { 681 result := fixture.RunTestWithBp(t, ` 682android_filesystem { 683 name: "myfilesystem", 684 deps: ["binfoo1", "libfoo2", "binbar"], 685} 686cc_binary { 687 name: "binfoo1", 688 shared_libs: ["libfoo"], 689 overrides: ["binbar"], 690} 691cc_library { 692 name: "libfoo", 693} 694cc_library { 695 name: "libfoo2", 696 overrides: ["libfoo"], 697} 698// binbar gets overridden by binfoo1 699// therefore, libbar should not be installed 700cc_binary { 701 name: "binbar", 702 shared_libs: ["libbar"] 703} 704cc_library { 705 name: "libbar", 706} 707 `) 708 709 partition := result.ModuleForTests("myfilesystem", "android_common") 710 fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList")) 711 android.AssertDeepEquals(t, "Shared library dep of overridden binary should not be installed", 712 "bin/binfoo1\nlib64/bootstrap/libc.so\nlib64/bootstrap/libdl.so\nlib64/bootstrap/libm.so\nlib64/libc++.so\nlib64/libc.so\nlib64/libdl.so\nlib64/libfoo2.so\nlib64/libm.so\n", 713 fileList) 714} 715 716func TestInstallLinkerConfigFile(t *testing.T) { 717 result := fixture.RunTestWithBp(t, ` 718android_filesystem { 719 name: "myfilesystem", 720 deps: ["libfoo_has_no_stubs", "libfoo_has_stubs"], 721 linker_config: { 722 gen_linker_config: true, 723 linker_config_srcs: ["linker.config.json"], 724 }, 725 partition_type: "vendor", 726} 727cc_library { 728 name: "libfoo_has_no_stubs", 729 vendor: true, 730} 731cc_library { 732 name: "libfoo_has_stubs", 733 stubs: {symbol_file: "libfoo.map.txt"}, 734 vendor: true, 735} 736 `) 737 738 linkerConfigCmd := result.ModuleForTests("myfilesystem", "android_common").Rule("build_filesystem_image").RuleParams.Command 739 android.AssertStringDoesContain(t, "Could not find linker.config.json file in cmd", linkerConfigCmd, "conv_linker_config proto --force -s linker.config.json") 740 android.AssertStringDoesContain(t, "Could not find stub in `provideLibs`", linkerConfigCmd, "--key provideLibs --value libfoo_has_stubs.so") 741} 742 743// override_android_* modules implicitly override their base module. 744// If both of these are listed in `deps`, the base module should not be installed. 745func TestOverrideModulesInDeps(t *testing.T) { 746 result := fixture.RunTestWithBp(t, ` 747 android_filesystem { 748 name: "myfilesystem", 749 deps: ["myapp", "myoverrideapp"], 750 } 751 752 android_app { 753 name: "myapp", 754 platform_apis: true, 755 } 756 override_android_app { 757 name: "myoverrideapp", 758 base: "myapp", 759 } 760 `) 761 762 partition := result.ModuleForTests("myfilesystem", "android_common") 763 fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList")) 764 android.AssertStringEquals(t, "filesystem with override app", "app/myoverrideapp/myoverrideapp.apk\n", fileList) 765} 766 767func TestRamdiskPartitionSetsDevNodes(t *testing.T) { 768 result := android.GroupFixturePreparers( 769 fixture, 770 android.FixtureMergeMockFs(android.MockFS{ 771 "ramdisk_node_list": nil, 772 }), 773 ).RunTestWithBp(t, ` 774 android_filesystem { 775 name: "ramdisk_filesystem", 776 partition_name: "ramdisk", 777 } 778 filegroup { 779 name: "ramdisk_node_list", 780 srcs: ["ramdisk_node_list"], 781 } 782 `) 783 784 android.AssertBoolEquals( 785 t, 786 "Generated ramdisk image expected to depend on \"ramdisk_node_list\" module", 787 true, 788 java.CheckModuleHasDependency(t, result.TestContext, "ramdisk_filesystem", "android_common", "ramdisk_node_list"), 789 ) 790} 791