1// Copyright 2019 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package java 16 17import ( 18 "fmt" 19 "reflect" 20 "regexp" 21 "sort" 22 "strings" 23 "testing" 24 25 "android/soong/android" 26 "android/soong/cc" 27 "android/soong/dexpreopt" 28 29 "github.com/google/blueprint" 30) 31 32const defaultJavaDir = "default/java" 33const testDefaultUpdatableModuleVersion = "340090000" 34 35// Test fixture preparer that will register most java build components. 36// 37// Singletons and mutators should only be added here if they are needed for a majority of java 38// module types, otherwise they should be added under a separate preparer to allow them to be 39// selected only when needed to reduce test execution time. 40// 41// Module types do not have much of an overhead unless they are used so this should include as many 42// module types as possible. The exceptions are those module types that require mutators and/or 43// singletons in order to function in which case they should be kept together in a separate 44// preparer. 45var PrepareForTestWithJavaBuildComponents = android.GroupFixturePreparers( 46 // Make sure that mutators and module types, e.g. prebuilt mutators available. 47 android.PrepareForTestWithAndroidBuildComponents, 48 // Make java build components available to the test. 49 android.FixtureRegisterWithContext(registerRequiredBuildComponentsForTest), 50 android.FixtureRegisterWithContext(registerJavaPluginBuildComponents), 51 // Additional files needed in tests that disallow non-existent source files. 52 // This includes files that are needed by all, or at least most, instances of a java module type. 53 android.MockFS{ 54 // Needed for linter used by java_library. 55 "build/soong/java/lint_defaults.txt": nil, 56 // Needed for java components that invoke Metalava. 57 "build/soong/java/metalava/Android.bp": []byte(`filegroup {name: "metalava-config-files"}`), 58 // Needed for apps that do not provide their own. 59 "build/make/target/product/security": nil, 60 // Required to generate Java used-by API coverage 61 "build/soong/scripts/gen_java_usedby_apex.sh": nil, 62 // Needed for the global lint checks provided from frameworks/base 63 "prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar": nil, 64 }.AddToFixture(), 65 android.PrepareForTestWithBuildFlag("RELEASE_DEFAULT_UPDATABLE_MODULE_VERSION", testDefaultUpdatableModuleVersion), 66) 67 68var prepareForTestWithFrameworkDeps = android.GroupFixturePreparers( 69 // The java default module definitions. 70 android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", gatherRequiredDepsForTest()), 71 // Additional files needed when test disallows non-existent source. 72 android.MockFS{ 73 // Needed for framework-res 74 defaultJavaDir + "/AndroidManifest.xml": nil, 75 // Needed for framework 76 defaultJavaDir + "/framework/aidl": nil, 77 // Needed for various deps defined in GatherRequiredDepsForTest() 78 defaultJavaDir + "/a.java": nil, 79 defaultJavaDir + "/api/current.txt": nil, 80 defaultJavaDir + "/api/removed.txt": nil, 81 defaultJavaDir + "/api/system-current.txt": nil, 82 defaultJavaDir + "/api/system-removed.txt": nil, 83 defaultJavaDir + "/api/test-current.txt": nil, 84 defaultJavaDir + "/api/test-removed.txt": nil, 85 defaultJavaDir + "/api/module-lib-current.txt": nil, 86 defaultJavaDir + "/api/module-lib-removed.txt": nil, 87 defaultJavaDir + "/api/system-server-current.txt": nil, 88 defaultJavaDir + "/api/system-server-removed.txt": nil, 89 90 // Needed for R8 rules on apps 91 "build/make/core/proguard.flags": nil, 92 "build/make/core/proguard_basic_keeps.flags": nil, 93 "prebuilts/cmdline-tools/shrinker.xml": nil, 94 }.AddToFixture(), 95) 96 97var prepareForTestWithJavaDefaultModulesBase = android.GroupFixturePreparers( 98 // Make sure that all the module types used in the defaults are registered. 99 PrepareForTestWithJavaBuildComponents, 100 prepareForTestWithFrameworkDeps, 101 // Add dexpreopt compat libs (android.test.base, etc.) and a fake dex2oatd module. 102 dexpreopt.PrepareForTestWithDexpreoptCompatLibs, 103) 104 105// Test fixture preparer that will define default java modules, e.g. standard prebuilt modules. 106var PrepareForTestWithJavaDefaultModules = android.GroupFixturePreparers( 107 prepareForTestWithJavaDefaultModulesBase, 108 dexpreopt.FixtureDisableDexpreoptBootImages(true), 109 dexpreopt.FixtureDisableDexpreopt(true), 110) 111 112// Provides everything needed by dexpreopt. 113var PrepareForTestWithDexpreopt = android.GroupFixturePreparers( 114 prepareForTestWithJavaDefaultModulesBase, 115 dexpreopt.PrepareForTestWithFakeDex2oatd, 116 dexpreopt.PrepareForTestByEnablingDexpreopt, 117) 118 119// Provides everything needed by dexpreopt except the fake_tool_binary for dex2oatd. 120var PrepareForTestWithDexpreoptWithoutFakeDex2oatd = android.GroupFixturePreparers( 121 prepareForTestWithJavaDefaultModulesBase, 122 dexpreopt.PrepareForTestByEnablingDexpreopt, 123) 124 125// Prepare a fixture to use all java module types, mutators and singletons fully. 126// 127// This should only be used by tests that want to run with as much of the build enabled as possible. 128var PrepareForIntegrationTestWithJava = android.GroupFixturePreparers( 129 cc.PrepareForIntegrationTestWithCc, 130 PrepareForTestWithJavaDefaultModules, 131) 132 133// Prepare a fixture with the standard files required by a java_sdk_library module. 134var PrepareForTestWithJavaSdkLibraryFiles = android.FixtureMergeMockFs(android.MockFS{ 135 "api/current.txt": nil, 136 "api/removed.txt": nil, 137 "api/system-current.txt": nil, 138 "api/system-removed.txt": nil, 139 "api/test-current.txt": nil, 140 "api/test-removed.txt": nil, 141 "api/module-lib-current.txt": nil, 142 "api/module-lib-removed.txt": nil, 143 "api/system-server-current.txt": nil, 144 "api/system-server-removed.txt": nil, 145}) 146 147// FixtureWithLastReleaseApis creates a preparer that creates prebuilt versions of the specified 148// modules for the `last` API release. By `last` it just means last in the list of supplied versions 149// and as this only provides one version it can be any value. 150// 151// This uses FixtureWithPrebuiltApis under the covers so the limitations of that apply to this. 152func FixtureWithLastReleaseApis(moduleNames ...string) android.FixturePreparer { 153 return FixtureWithPrebuiltApis(map[string][]string{ 154 "30": moduleNames, 155 }) 156} 157 158// PrepareForTestWithPrebuiltsOfCurrentApi is a preparer that creates prebuilt versions of the 159// standard modules for the current version. 160// 161// This uses FixtureWithPrebuiltApis under the covers so the limitations of that apply to this. 162var PrepareForTestWithPrebuiltsOfCurrentApi = FixtureWithPrebuiltApis(map[string][]string{ 163 "current": {}, 164 // Can't have current on its own as it adds a prebuilt_apis module but doesn't add any 165 // .txt files which causes the prebuilt_apis module to fail. 166 "30": {}, 167}) 168 169var prepareForTestWithFrameworkJacocoInstrumentation = android.GroupFixturePreparers( 170 android.FixtureMergeEnv(map[string]string{ 171 "EMMA_INSTRUMENT_FRAMEWORK": "true", 172 }), 173 PrepareForTestWithJacocoInstrumentation, 174) 175 176// PrepareForTestWithJacocoInstrumentation creates a mock jacocoagent library that can be 177// depended on as part of the build process for instrumented Java modules. 178var PrepareForTestWithJacocoInstrumentation = android.GroupFixturePreparers( 179 android.FixtureMergeEnv(map[string]string{ 180 "EMMA_INSTRUMENT": "true", 181 }), 182 android.FixtureAddFile("jacocoagent/Test.java", nil), 183 android.FixtureAddFile("jacocoagent/Android.bp", []byte(` 184 java_library { 185 name: "jacocoagent", 186 host_supported: true, 187 srcs: ["Test.java"], 188 sdk_version: "current", 189 apex_available: [ 190 "//apex_available:anyapex", 191 "//apex_available:platform", 192 ], 193 compile_dex: true, 194 } 195 `)), 196) 197 198// FixtureWithPrebuiltApis creates a preparer that will define prebuilt api modules for the 199// specified releases and modules. 200// 201// The supplied map keys are the releases, e.g. current, 29, 30, etc. The values are a list of 202// modules for that release. Due to limitations in the prebuilt_apis module which this preparer 203// uses the set of releases must include at least one numbered release, i.e. it cannot just include 204// "current". 205// 206// This defines a file in the mock file system in a predefined location (prebuilts/sdk/Android.bp) 207// and so only one instance of this can be used in each fixture. 208func FixtureWithPrebuiltApis(release2Modules map[string][]string) android.FixturePreparer { 209 return FixtureWithPrebuiltApisAndExtensions(release2Modules, nil) 210} 211 212func FixtureWithPrebuiltApisAndExtensions(apiLevel2Modules map[string][]string, extensionLevel2Modules map[string][]string) android.FixturePreparer { 213 mockFS := android.MockFS{} 214 path := "prebuilts/sdk/Android.bp" 215 216 bp := fmt.Sprintf(` 217 prebuilt_apis { 218 name: "sdk", 219 api_dirs: ["%s"], 220 extensions_dir: "extensions", 221 imports_sdk_version: "none", 222 imports_compile_dex: true, 223 } 224 `, strings.Join(android.SortedKeys(apiLevel2Modules), `", "`)) 225 226 for release, modules := range apiLevel2Modules { 227 mockFS.Merge(prebuiltApisFilesForModules([]string{release}, modules)) 228 } 229 if extensionLevel2Modules != nil { 230 for release, modules := range extensionLevel2Modules { 231 mockFS.Merge(prebuiltExtensionApiFiles([]string{release}, modules)) 232 } 233 } 234 return android.GroupFixturePreparers( 235 android.FixtureAddTextFile(path, bp), 236 android.FixtureMergeMockFs(mockFS), 237 ) 238} 239 240func FixtureWithPrebuiltIncrementalApis(apiLevel2Modules map[string][]string) android.FixturePreparer { 241 mockFS := android.MockFS{} 242 path := "prebuilts/sdk/Android.bp" 243 244 bp := fmt.Sprintf(` 245 prebuilt_apis { 246 name: "sdk", 247 api_dirs: ["%s"], 248 allow_incremental_platform_api: true, 249 imports_sdk_version: "none", 250 imports_compile_dex: true, 251 } 252 `, strings.Join(android.SortedKeys(apiLevel2Modules), `", "`)) 253 254 for release, modules := range apiLevel2Modules { 255 mockFS.Merge(prebuiltApisFilesForModules([]string{release}, modules)) 256 } 257 return android.GroupFixturePreparers( 258 android.FixtureAddTextFile(path, bp), 259 android.FixtureMergeMockFs(mockFS), 260 ) 261} 262 263func prebuiltApisFilesForModules(apiLevels []string, modules []string) map[string][]byte { 264 libs := append([]string{"android"}, modules...) 265 266 fs := make(map[string][]byte) 267 for _, level := range apiLevels { 268 apiLevel := android.ApiLevelForTest(level) 269 for _, sdkKind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkModule, android.SdkSystemServer, android.SdkTest} { 270 // A core-for-system-modules file must only be created for the sdk kind that supports it. 271 if sdkKind == systemModuleKind(sdkKind, apiLevel) { 272 fs[fmt.Sprintf("prebuilts/sdk/%s/%s/core-for-system-modules.jar", level, sdkKind)] = nil 273 } 274 275 for _, lib := range libs { 276 // Create a jar file for every library. 277 fs[fmt.Sprintf("prebuilts/sdk/%s/%s/%s.jar", level, sdkKind, lib)] = nil 278 279 // No finalized API files for "current" 280 if level != "current" { 281 fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s.txt", level, sdkKind, lib)] = nil 282 fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s-removed.txt", level, sdkKind, lib)] = nil 283 } 284 } 285 } 286 if level == "current" { 287 fs["prebuilts/sdk/current/core/android.jar"] = nil 288 } 289 fs[fmt.Sprintf("prebuilts/sdk/%s/public/framework.aidl", level)] = nil 290 } 291 return fs 292} 293 294func prebuiltExtensionApiFiles(extensionLevels []string, modules []string) map[string][]byte { 295 fs := make(map[string][]byte) 296 for _, level := range extensionLevels { 297 for _, sdkKind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkModule, android.SdkSystemServer} { 298 for _, lib := range modules { 299 fs[fmt.Sprintf("prebuilts/sdk/extensions/%s/%s/api/%s.txt", level, sdkKind, lib)] = nil 300 fs[fmt.Sprintf("prebuilts/sdk/extensions/%s/%s/api/%s-removed.txt", level, sdkKind, lib)] = nil 301 } 302 } 303 } 304 return fs 305} 306 307// FixtureConfigureBootJars configures the boot jars in both the dexpreopt.GlobalConfig and 308// Config.productVariables structs. As a side effect that enables dexpreopt. 309func FixtureConfigureBootJars(bootJars ...string) android.FixturePreparer { 310 artBootJars := []string{} 311 for _, j := range bootJars { 312 artApex := false 313 for _, artApexName := range artApexNames { 314 if strings.HasPrefix(j, artApexName+":") { 315 artApex = true 316 break 317 } 318 } 319 if artApex { 320 artBootJars = append(artBootJars, j) 321 } 322 } 323 return android.GroupFixturePreparers( 324 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 325 variables.BootJars = android.CreateTestConfiguredJarList(bootJars) 326 }), 327 dexpreopt.FixtureSetBootJars(bootJars...), 328 dexpreopt.FixtureSetArtBootJars(artBootJars...), 329 330 // Add a fake dex2oatd module. 331 dexpreopt.PrepareForTestWithFakeDex2oatd, 332 ) 333} 334 335// FixtureConfigureApexBootJars configures the apex boot jars in both the 336// dexpreopt.GlobalConfig and Config.productVariables structs. As a side effect that enables 337// dexpreopt. 338func FixtureConfigureApexBootJars(bootJars ...string) android.FixturePreparer { 339 return android.GroupFixturePreparers( 340 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 341 variables.ApexBootJars = android.CreateTestConfiguredJarList(bootJars) 342 }), 343 dexpreopt.FixtureSetApexBootJars(bootJars...), 344 345 // Add a fake dex2oatd module. 346 dexpreopt.PrepareForTestWithFakeDex2oatd, 347 ) 348} 349 350// FixtureUseLegacyCorePlatformApi prepares the fixture by setting the exception list of those 351// modules that are allowed to use the legacy core platform API to be the ones supplied. 352func FixtureUseLegacyCorePlatformApi(moduleNames ...string) android.FixturePreparer { 353 lookup := make(map[string]struct{}) 354 for _, moduleName := range moduleNames { 355 lookup[moduleName] = struct{}{} 356 } 357 return android.FixtureModifyConfig(func(config android.Config) { 358 // Try and set the legacyCorePlatformApiLookup in the config, the returned value will be the 359 // actual value that is set. 360 cached := config.Once(legacyCorePlatformApiLookupKey, func() interface{} { 361 return lookup 362 }) 363 // Make sure that the cached value is the one we need. 364 if !reflect.DeepEqual(cached, lookup) { 365 panic(fmt.Errorf("attempting to set legacyCorePlatformApiLookupKey to %q but it has already been set to %q", lookup, cached)) 366 } 367 }) 368} 369 370// registerRequiredBuildComponentsForTest registers the build components used by 371// PrepareForTestWithJavaDefaultModules. 372// 373// As functionality is moved out of here into separate FixturePreparer instances they should also 374// be moved into GatherRequiredDepsForTest for use by tests that have not yet switched to use test 375// fixtures. 376func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) { 377 RegisterAARBuildComponents(ctx) 378 RegisterAppBuildComponents(ctx) 379 RegisterAppImportBuildComponents(ctx) 380 RegisterAppSetBuildComponents(ctx) 381 registerBootclasspathBuildComponents(ctx) 382 registerBootclasspathFragmentBuildComponents(ctx) 383 RegisterDexpreoptBootJarsComponents(ctx) 384 RegisterDocsBuildComponents(ctx) 385 RegisterGenRuleBuildComponents(ctx) 386 registerJavaBuildComponents(ctx) 387 registerPlatformBootclasspathBuildComponents(ctx) 388 RegisterPrebuiltApisBuildComponents(ctx) 389 RegisterRuntimeResourceOverlayBuildComponents(ctx) 390 RegisterSdkLibraryBuildComponents(ctx) 391 RegisterStubsBuildComponents(ctx) 392 RegisterSystemModulesBuildComponents(ctx) 393 registerSystemserverClasspathBuildComponents(ctx) 394 android.RegisterApexContributionsBuildComponents(ctx) 395} 396 397// gatherRequiredDepsForTest gathers the module definitions used by 398// PrepareForTestWithJavaDefaultModules. 399// 400// As functionality is moved out of here into separate FixturePreparer instances they should also 401// be moved into GatherRequiredDepsForTest for use by tests that have not yet switched to use test 402// fixtures. 403func gatherRequiredDepsForTest() string { 404 var bp string 405 406 extraModules := []string{ 407 "core-lambda-stubs", 408 "ext", 409 "android_stubs_current", 410 "android_system_stubs_current", 411 "android_test_stubs_current", 412 "android_module_lib_stubs_current", 413 "android_system_server_stubs_current", 414 "core.current.stubs", 415 "legacy.core.platform.api.stubs", 416 "stable.core.platform.api.stubs", 417 "android_stubs_current_exportable", 418 "android_system_stubs_current_exportable", 419 "android_test_stubs_current_exportable", 420 "android_module_lib_stubs_current_exportable", 421 "android_system_server_stubs_current_exportable", 422 "core.current.stubs.exportable", 423 "legacy.core.platform.api.stubs.exportable", 424 "kotlin-stdlib", 425 "kotlin-stdlib-jdk7", 426 "kotlin-stdlib-jdk8", 427 "kotlin-annotations", 428 "stub-annotations", 429 "aconfig-annotations-lib", 430 "aconfig_storage_stub", 431 "unsupportedappusage", 432 } 433 434 for _, extra := range extraModules { 435 bp += fmt.Sprintf(` 436 java_library { 437 name: "%s", 438 srcs: ["a.java"], 439 sdk_version: "none", 440 system_modules: "stable-core-platform-api-stubs-system-modules", 441 compile_dex: true, 442 is_stubs_module: true, 443 } 444 `, extra) 445 } 446 447 type droidstubsStruct struct { 448 name string 449 apiSurface string 450 apiFile string 451 removedFile string 452 } 453 454 var publicDroidstubs = droidstubsStruct{ 455 name: "api-stubs-docs-non-updatable", 456 apiSurface: "public", 457 apiFile: "api/current.txt", 458 removedFile: "api/removed.txt", 459 } 460 var systemDroidstubs = droidstubsStruct{ 461 name: "system-api-stubs-docs-non-updatable", 462 apiSurface: "system", 463 apiFile: "api/system-current.txt", 464 removedFile: "api/system-removed.txt", 465 } 466 var testDroidstubs = droidstubsStruct{ 467 name: "test-api-stubs-docs-non-updatable", 468 apiSurface: "test", 469 apiFile: "api/test-current.txt", 470 removedFile: "api/test-removed.txt", 471 } 472 var moduleLibDroidstubs = droidstubsStruct{ 473 name: "module-lib-api-stubs-docs-non-updatable", 474 apiSurface: "module-lib", 475 apiFile: "api/module-lib-current.txt", 476 removedFile: "api/module-lib-removed.txt", 477 } 478 var systemServerDroidstubs = droidstubsStruct{ 479 // This module does not exist but is named this way for consistency 480 name: "system-server-api-stubs-docs-non-updatable", 481 apiSurface: "system-server", 482 apiFile: "api/system-server-current.txt", 483 removedFile: "api/system-server-removed.txt", 484 } 485 var droidstubsStructs = []droidstubsStruct{ 486 publicDroidstubs, 487 systemDroidstubs, 488 testDroidstubs, 489 moduleLibDroidstubs, 490 systemServerDroidstubs, 491 } 492 493 extraApiLibraryModules := map[string]droidstubsStruct{ 494 "android_stubs_current.from-text": publicDroidstubs, 495 "android_system_stubs_current.from-text": systemDroidstubs, 496 "android_test_stubs_current.from-text": testDroidstubs, 497 "android_module_lib_stubs_current.from-text": moduleLibDroidstubs, 498 "android_module_lib_stubs_current_full.from-text": moduleLibDroidstubs, 499 "android_system_server_stubs_current.from-text": systemServerDroidstubs, 500 "core.current.stubs.from-text": publicDroidstubs, 501 "legacy.core.platform.api.stubs.from-text": publicDroidstubs, 502 "stable.core.platform.api.stubs.from-text": publicDroidstubs, 503 "core-lambda-stubs.from-text": publicDroidstubs, 504 "android-non-updatable.stubs.test_module_lib": moduleLibDroidstubs, 505 } 506 507 for _, droidstubs := range droidstubsStructs { 508 bp += fmt.Sprintf(` 509 droidstubs { 510 name: "%s", 511 api_surface: "%s", 512 check_api: { 513 current: { 514 api_file: "%s", 515 removed_api_file: "%s", 516 } 517 } 518 } 519 `, 520 droidstubs.name, 521 droidstubs.apiSurface, 522 droidstubs.apiFile, 523 droidstubs.removedFile, 524 ) 525 } 526 527 for libName, droidstubs := range extraApiLibraryModules { 528 bp += fmt.Sprintf(` 529 java_api_library { 530 name: "%s", 531 api_contributions: ["%s"], 532 stubs_type: "everything", 533 sdk_version: "none", 534 system_modules: "none", 535 } 536 `, libName, droidstubs.name+".api.contribution") 537 } 538 539 bp += ` 540 java_library { 541 name: "framework", 542 srcs: ["a.java"], 543 sdk_version: "none", 544 system_modules: "stable-core-platform-api-stubs-system-modules", 545 aidl: { 546 export_include_dirs: ["framework/aidl"], 547 }, 548 compile_dex: true, 549 } 550 java_library { 551 name: "framework-minus-apex", 552 srcs: ["a.java"], 553 sdk_version: "none", 554 system_modules: "stable-core-platform-api-stubs-system-modules", 555 aidl: { 556 export_include_dirs: ["framework/aidl"], 557 }, 558 compile_dex: true, 559 } 560 561 android_app { 562 name: "framework-res", 563 sdk_version: "core_platform", 564 }` 565 566 systemModules := []string{ 567 "core-public-stubs-system-modules", 568 "core-module-lib-stubs-system-modules", 569 "legacy-core-platform-api-stubs-system-modules", 570 "stable-core-platform-api-stubs-system-modules", 571 "core-public-stubs-system-modules.from-text", 572 "core-module-lib-stubs-system-modules.from-text", 573 "legacy-core-platform-api-stubs-system-modules.from-text", 574 "stable-core-platform-api-stubs-system-modules.from-text", 575 } 576 577 for _, extra := range systemModules { 578 bp += fmt.Sprintf(` 579 java_system_modules { 580 name: "%[1]s", 581 libs: ["%[1]s-lib"], 582 } 583 java_library { 584 name: "%[1]s-lib", 585 sdk_version: "none", 586 system_modules: "none", 587 srcs: ["a.java"], 588 } 589 `, extra) 590 } 591 592 // Make sure that the dex_bootjars singleton module is instantiated for the tests. 593 bp += ` 594 dex_bootjars { 595 name: "dex_bootjars", 596 } 597` 598 599 bp += ` 600 all_apex_contributions { 601 name: "all_apex_contributions", 602 } 603` 604 return bp 605} 606 607func getModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string) []string { 608 t.Helper() 609 module := ctx.ModuleForTests(name, variant).Module() 610 deps := []string{} 611 ctx.VisitDirectDeps(module, func(m blueprint.Module) { 612 deps = append(deps, m.Name()) 613 }) 614 sort.Strings(deps) 615 616 return deps 617} 618 619// CheckModuleDependencies checks if the expected dependencies of the module are 620// identical to the actual dependencies. 621func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) { 622 deps := getModuleDependencies(t, ctx, name, variant) 623 624 if actual := deps; !reflect.DeepEqual(expected, actual) { 625 t.Errorf("expected %#q, found %#q", expected, actual) 626 } 627} 628 629// CheckModuleHasDependency returns true if the module depends on the expected dependency. 630func CheckModuleHasDependency(t *testing.T, ctx *android.TestContext, name, variant string, expected string) bool { 631 for _, dep := range getModuleDependencies(t, ctx, name, variant) { 632 if dep == expected { 633 return true 634 } 635 } 636 return false 637} 638 639// CheckModuleHasDependency returns true if the module depends on the expected dependency. 640func CheckModuleHasDependencyWithTag(t *testing.T, ctx *android.TestContext, name, variant string, desiredTag blueprint.DependencyTag, expected string) bool { 641 module := ctx.ModuleForTests(name, variant).Module() 642 found := false 643 ctx.VisitDirectDepsWithTags(module, func(m blueprint.Module, tag blueprint.DependencyTag) { 644 if tag == desiredTag && m.Name() == expected { 645 found = true 646 } 647 }) 648 return found 649} 650 651// CheckPlatformBootclasspathModules returns the apex:module pair for the modules depended upon by 652// the platform-bootclasspath module. 653func CheckPlatformBootclasspathModules(t *testing.T, result *android.TestResult, name string, expected []string) { 654 t.Helper() 655 platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule) 656 pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.configuredModules) 657 android.AssertDeepEquals(t, fmt.Sprintf("%s modules", "platform-bootclasspath"), expected, pairs) 658} 659 660func CheckClasspathFragmentProtoContentInfoProvider(t *testing.T, result *android.TestResult, generated bool, contents, outputFilename, installDir string) { 661 t.Helper() 662 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule) 663 info, _ := android.OtherModuleProvider(result, p, ClasspathFragmentProtoContentInfoProvider) 664 665 android.AssertBoolEquals(t, "classpath proto generated", generated, info.ClasspathFragmentProtoGenerated) 666 android.AssertStringEquals(t, "classpath proto contents", contents, info.ClasspathFragmentProtoContents.String()) 667 android.AssertStringEquals(t, "output filepath", outputFilename, info.ClasspathFragmentProtoOutput.Base()) 668 android.AssertPathRelativeToTopEquals(t, "install filepath", installDir, info.ClasspathFragmentProtoInstallDir) 669} 670 671// ApexNamePairsFromModules returns the apex:module pair for the supplied modules. 672func ApexNamePairsFromModules(ctx *android.TestContext, modules []android.Module) []string { 673 pairs := []string{} 674 for _, module := range modules { 675 pairs = append(pairs, apexNamePairFromModule(ctx, module)) 676 } 677 return pairs 678} 679 680func apexNamePairFromModule(ctx *android.TestContext, module android.Module) string { 681 name := module.Name() 682 var apex string 683 apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider) 684 if apexInfo.IsForPlatform() { 685 apex = "platform" 686 } else { 687 apex = apexInfo.InApexVariants[0] 688 } 689 690 return fmt.Sprintf("%s:%s", apex, name) 691} 692 693// CheckPlatformBootclasspathFragments returns the apex:module pair for the fragments depended upon 694// by the platform-bootclasspath module. 695func CheckPlatformBootclasspathFragments(t *testing.T, result *android.TestResult, name string, expected []string) { 696 t.Helper() 697 platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule) 698 pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.fragments) 699 android.AssertDeepEquals(t, fmt.Sprintf("%s fragments", "platform-bootclasspath"), expected, pairs) 700} 701 702func CheckHiddenAPIRuleInputs(t *testing.T, message string, expected string, hiddenAPIRule android.TestingBuildParams) { 703 t.Helper() 704 inputs := android.Paths{} 705 if hiddenAPIRule.Input != nil { 706 inputs = append(inputs, hiddenAPIRule.Input) 707 } 708 inputs = append(inputs, hiddenAPIRule.Inputs...) 709 inputs = append(inputs, hiddenAPIRule.Implicits...) 710 inputs = android.SortedUniquePaths(inputs) 711 actual := strings.TrimSpace(strings.Join(inputs.RelativeToTop().Strings(), "\n")) 712 re := regexp.MustCompile(`\n\s+`) 713 expected = strings.TrimSpace(re.ReplaceAllString(expected, "\n")) 714 if actual != expected { 715 t.Errorf("Expected hiddenapi rule inputs - %s:\n%s\nactual inputs:\n%s", message, expected, actual) 716 } 717} 718 719// Check that the merged file create by platform_compat_config_singleton has the correct inputs. 720func CheckMergedCompatConfigInputs(t *testing.T, result *android.TestResult, message string, expectedPaths ...string) { 721 sourceGlobalCompatConfig := result.SingletonForTests("platform_compat_config_singleton") 722 allOutputs := sourceGlobalCompatConfig.AllOutputs() 723 android.AssertIntEquals(t, message+": output len", 1, len(allOutputs)) 724 output := sourceGlobalCompatConfig.Output(allOutputs[0]) 725 android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits) 726} 727 728// Register the fake APEX mutator to `android.InitRegistrationContext` as if the real mutator exists 729// at runtime. This must be called in `init()` of a test if the test is going to use the fake APEX 730// mutator. Otherwise, we will be missing the runtime mutator because "soong-apex" is not a 731// dependency, which will cause an inconsistency between testing and runtime mutators. 732func RegisterFakeRuntimeApexMutator() { 733 registerFakeApexMutator(android.InitRegistrationContext) 734} 735 736var PrepareForTestWithFakeApexMutator = android.GroupFixturePreparers( 737 android.FixtureRegisterWithContext(registerFakeApexMutator), 738) 739 740func registerFakeApexMutator(ctx android.RegistrationContext) { 741 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { 742 ctx.Transition("apex", &fakeApexMutator{}) 743 }) 744} 745 746type apexModuleBase interface { 747 ApexAvailable() []string 748} 749 750var _ apexModuleBase = (*Library)(nil) 751var _ apexModuleBase = (*SdkLibrary)(nil) 752 753// A fake APEX mutator that creates a platform variant and an APEX variant for modules with 754// `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex", 755// which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for 756// testing without dealing with all the complexities in the real mutator. 757type fakeApexMutator struct{} 758 759func (f *fakeApexMutator) Split(ctx android.BaseModuleContext) []string { 760 switch ctx.Module().(type) { 761 case *Library, *SdkLibrary: 762 return []string{"", "apex1000"} 763 } 764 return []string{""} 765} 766 767func (f *fakeApexMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { 768 return sourceVariation 769} 770 771func (f *fakeApexMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { 772 return incomingVariation 773} 774 775func (f *fakeApexMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { 776 if variation != "" { 777 apexInfo := android.ApexInfo{ 778 ApexVariationName: "apex1000", 779 } 780 android.SetProvider(ctx, android.ApexInfoProvider, apexInfo) 781 } 782} 783 784// Applies the given modifier on the boot image config with the given name. 785func FixtureModifyBootImageConfig(name string, configModifier func(*bootImageConfig)) android.FixturePreparer { 786 return android.FixtureModifyConfig(func(androidConfig android.Config) { 787 pathCtx := android.PathContextForTesting(androidConfig) 788 config := genBootImageConfigRaw(pathCtx) 789 configModifier(config[name]) 790 }) 791} 792 793// Sets the value of `installDir` of the boot image config with the given name. 794func FixtureSetBootImageInstallDirOnDevice(name string, installDir string) android.FixturePreparer { 795 return FixtureModifyBootImageConfig(name, func(config *bootImageConfig) { 796 config.installDir = installDir 797 }) 798} 799 800var PrepareForTestWithTransitiveClasspathEnabled = android.PrepareForTestWithBuildFlag("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH", "true") 801