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" 33 34// Test fixture preparer that will register most java build components. 35// 36// Singletons and mutators should only be added here if they are needed for a majority of java 37// module types, otherwise they should be added under a separate preparer to allow them to be 38// selected only when needed to reduce test execution time. 39// 40// Module types do not have much of an overhead unless they are used so this should include as many 41// module types as possible. The exceptions are those module types that require mutators and/or 42// singletons in order to function in which case they should be kept together in a separate 43// preparer. 44var PrepareForTestWithJavaBuildComponents = android.GroupFixturePreparers( 45 // Make sure that mutators and module types, e.g. prebuilt mutators available. 46 android.PrepareForTestWithAndroidBuildComponents, 47 // Make java build components available to the test. 48 android.FixtureRegisterWithContext(registerRequiredBuildComponentsForTest), 49 android.FixtureRegisterWithContext(registerJavaPluginBuildComponents), 50 // Additional files needed in tests that disallow non-existent source files. 51 // This includes files that are needed by all, or at least most, instances of a java module type. 52 android.MockFS{ 53 // Needed for linter used by java_library. 54 "build/soong/java/lint_defaults.txt": nil, 55 // Needed for apps that do not provide their own. 56 "build/make/target/product/security": nil, 57 }.AddToFixture(), 58) 59 60// Test fixture preparer that will define all default java modules except the 61// fake_tool_binary for dex2oatd. 62var PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd = android.GroupFixturePreparers( 63 // Make sure that all the module types used in the defaults are registered. 64 PrepareForTestWithJavaBuildComponents, 65 // Additional files needed when test disallows non-existent source. 66 android.MockFS{ 67 // Needed for framework-res 68 defaultJavaDir + "/AndroidManifest.xml": nil, 69 // Needed for framework 70 defaultJavaDir + "/framework/aidl": nil, 71 // Needed for various deps defined in GatherRequiredDepsForTest() 72 defaultJavaDir + "/a.java": nil, 73 }.AddToFixture(), 74 // The java default module definitions. 75 android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", gatherRequiredDepsForTest()), 76 // Add dexpreopt compat libs (android.test.base, etc.) and a fake dex2oatd module. 77 dexpreopt.PrepareForTestWithDexpreoptCompatLibs, 78) 79 80// Test fixture preparer that will define default java modules, e.g. standard prebuilt modules. 81var PrepareForTestWithJavaDefaultModules = android.GroupFixturePreparers( 82 PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd, 83 dexpreopt.PrepareForTestWithFakeDex2oatd, 84) 85 86// Provides everything needed by dexpreopt. 87var PrepareForTestWithDexpreopt = android.GroupFixturePreparers( 88 PrepareForTestWithJavaDefaultModules, 89 dexpreopt.PrepareForTestByEnablingDexpreopt, 90) 91 92var PrepareForTestWithOverlayBuildComponents = android.FixtureRegisterWithContext(registerOverlayBuildComponents) 93 94// Prepare a fixture to use all java module types, mutators and singletons fully. 95// 96// This should only be used by tests that want to run with as much of the build enabled as possible. 97var PrepareForIntegrationTestWithJava = android.GroupFixturePreparers( 98 cc.PrepareForIntegrationTestWithCc, 99 PrepareForTestWithJavaDefaultModules, 100) 101 102// Prepare a fixture with the standard files required by a java_sdk_library module. 103var PrepareForTestWithJavaSdkLibraryFiles = android.FixtureMergeMockFs(android.MockFS{ 104 "api/current.txt": nil, 105 "api/removed.txt": nil, 106 "api/system-current.txt": nil, 107 "api/system-removed.txt": nil, 108 "api/test-current.txt": nil, 109 "api/test-removed.txt": nil, 110 "api/module-lib-current.txt": nil, 111 "api/module-lib-removed.txt": nil, 112 "api/system-server-current.txt": nil, 113 "api/system-server-removed.txt": nil, 114}) 115 116// FixtureWithLastReleaseApis creates a preparer that creates prebuilt versions of the specified 117// modules for the `last` API release. By `last` it just means last in the list of supplied versions 118// and as this only provides one version it can be any value. 119// 120// This uses FixtureWithPrebuiltApis under the covers so the limitations of that apply to this. 121func FixtureWithLastReleaseApis(moduleNames ...string) android.FixturePreparer { 122 return FixtureWithPrebuiltApis(map[string][]string{ 123 "30": moduleNames, 124 }) 125} 126 127// PrepareForTestWithPrebuiltsOfCurrentApi is a preparer that creates prebuilt versions of the 128// standard modules for the current version. 129// 130// This uses FixtureWithPrebuiltApis under the covers so the limitations of that apply to this. 131var PrepareForTestWithPrebuiltsOfCurrentApi = FixtureWithPrebuiltApis(map[string][]string{ 132 "current": {}, 133 // Can't have current on its own as it adds a prebuilt_apis module but doesn't add any 134 // .txt files which causes the prebuilt_apis module to fail. 135 "30": {}, 136}) 137 138// FixtureWithPrebuiltApis creates a preparer that will define prebuilt api modules for the 139// specified releases and modules. 140// 141// The supplied map keys are the releases, e.g. current, 29, 30, etc. The values are a list of 142// modules for that release. Due to limitations in the prebuilt_apis module which this preparer 143// uses the set of releases must include at least one numbered release, i.e. it cannot just include 144// "current". 145// 146// This defines a file in the mock file system in a predefined location (prebuilts/sdk/Android.bp) 147// and so only one instance of this can be used in each fixture. 148func FixtureWithPrebuiltApis(release2Modules map[string][]string) android.FixturePreparer { 149 mockFS := android.MockFS{} 150 path := "prebuilts/sdk/Android.bp" 151 152 bp := fmt.Sprintf(` 153 prebuilt_apis { 154 name: "sdk", 155 api_dirs: ["%s"], 156 imports_sdk_version: "none", 157 imports_compile_dex: true, 158 } 159 `, strings.Join(android.SortedStringKeys(release2Modules), `", "`)) 160 161 for release, modules := range release2Modules { 162 libs := append([]string{"android", "core-for-system-modules"}, modules...) 163 mockFS.Merge(prebuiltApisFilesForLibs([]string{release}, libs)) 164 } 165 return android.GroupFixturePreparers( 166 android.FixtureAddTextFile(path, bp), 167 android.FixtureMergeMockFs(mockFS), 168 ) 169} 170 171func prebuiltApisFilesForLibs(apiLevels []string, sdkLibs []string) map[string][]byte { 172 fs := make(map[string][]byte) 173 for _, level := range apiLevels { 174 for _, lib := range sdkLibs { 175 for _, scope := range []string{"public", "system", "module-lib", "system-server", "test"} { 176 fs[fmt.Sprintf("prebuilts/sdk/%s/%s/%s.jar", level, scope, lib)] = nil 177 // No finalized API files for "current" 178 if level != "current" { 179 fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s.txt", level, scope, lib)] = nil 180 fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s-removed.txt", level, scope, lib)] = nil 181 } 182 } 183 } 184 fs[fmt.Sprintf("prebuilts/sdk/%s/public/framework.aidl", level)] = nil 185 } 186 return fs 187} 188 189// FixtureConfigureBootJars configures the boot jars in both the dexpreopt.GlobalConfig and 190// Config.productVariables structs. As a side effect that enables dexpreopt. 191func FixtureConfigureBootJars(bootJars ...string) android.FixturePreparer { 192 artBootJars := []string{} 193 for _, j := range bootJars { 194 artApex := false 195 for _, artApexName := range artApexNames { 196 if strings.HasPrefix(j, artApexName+":") { 197 artApex = true 198 break 199 } 200 } 201 if artApex { 202 artBootJars = append(artBootJars, j) 203 } 204 } 205 return android.GroupFixturePreparers( 206 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 207 variables.BootJars = android.CreateTestConfiguredJarList(bootJars) 208 }), 209 dexpreopt.FixtureSetBootJars(bootJars...), 210 dexpreopt.FixtureSetArtBootJars(artBootJars...), 211 212 // Add a fake dex2oatd module. 213 dexpreopt.PrepareForTestWithFakeDex2oatd, 214 ) 215} 216 217// FixtureConfigureUpdatableBootJars configures the updatable boot jars in both the 218// dexpreopt.GlobalConfig and Config.productVariables structs. As a side effect that enables 219// dexpreopt. 220func FixtureConfigureUpdatableBootJars(bootJars ...string) android.FixturePreparer { 221 return android.GroupFixturePreparers( 222 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 223 variables.UpdatableBootJars = android.CreateTestConfiguredJarList(bootJars) 224 }), 225 dexpreopt.FixtureSetUpdatableBootJars(bootJars...), 226 227 // Add a fake dex2oatd module. 228 dexpreopt.PrepareForTestWithFakeDex2oatd, 229 ) 230} 231 232// registerRequiredBuildComponentsForTest registers the build components used by 233// PrepareForTestWithJavaDefaultModules. 234// 235// As functionality is moved out of here into separate FixturePreparer instances they should also 236// be moved into GatherRequiredDepsForTest for use by tests that have not yet switched to use test 237// fixtures. 238func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) { 239 RegisterAARBuildComponents(ctx) 240 RegisterAppBuildComponents(ctx) 241 RegisterAppImportBuildComponents(ctx) 242 RegisterAppSetBuildComponents(ctx) 243 registerBootclasspathBuildComponents(ctx) 244 registerBootclasspathFragmentBuildComponents(ctx) 245 RegisterDexpreoptBootJarsComponents(ctx) 246 RegisterDocsBuildComponents(ctx) 247 RegisterGenRuleBuildComponents(ctx) 248 registerJavaBuildComponents(ctx) 249 registerPlatformBootclasspathBuildComponents(ctx) 250 RegisterPrebuiltApisBuildComponents(ctx) 251 RegisterRuntimeResourceOverlayBuildComponents(ctx) 252 RegisterSdkLibraryBuildComponents(ctx) 253 RegisterStubsBuildComponents(ctx) 254 RegisterSystemModulesBuildComponents(ctx) 255 registerSystemserverClasspathBuildComponents(ctx) 256 registerLintBuildComponents(ctx) 257} 258 259// gatherRequiredDepsForTest gathers the module definitions used by 260// PrepareForTestWithJavaDefaultModules. 261// 262// As functionality is moved out of here into separate FixturePreparer instances they should also 263// be moved into GatherRequiredDepsForTest for use by tests that have not yet switched to use test 264// fixtures. 265func gatherRequiredDepsForTest() string { 266 var bp string 267 268 extraModules := []string{ 269 "core-lambda-stubs", 270 "ext", 271 "android_stubs_current", 272 "android_system_stubs_current", 273 "android_test_stubs_current", 274 "android_module_lib_stubs_current", 275 "android_system_server_stubs_current", 276 "core.current.stubs", 277 "legacy.core.platform.api.stubs", 278 "stable.core.platform.api.stubs", 279 "kotlin-stdlib", 280 "kotlin-stdlib-jdk7", 281 "kotlin-stdlib-jdk8", 282 "kotlin-annotations", 283 } 284 285 for _, extra := range extraModules { 286 bp += fmt.Sprintf(` 287 java_library { 288 name: "%s", 289 srcs: ["a.java"], 290 sdk_version: "none", 291 system_modules: "stable-core-platform-api-stubs-system-modules", 292 compile_dex: true, 293 } 294 `, extra) 295 } 296 297 bp += ` 298 java_library { 299 name: "framework", 300 srcs: ["a.java"], 301 sdk_version: "none", 302 system_modules: "stable-core-platform-api-stubs-system-modules", 303 aidl: { 304 export_include_dirs: ["framework/aidl"], 305 }, 306 } 307 308 android_app { 309 name: "framework-res", 310 sdk_version: "core_platform", 311 }` 312 313 systemModules := []string{ 314 "core-current-stubs-system-modules", 315 "core-module-lib-stubs-system-modules", 316 "legacy-core-platform-api-stubs-system-modules", 317 "stable-core-platform-api-stubs-system-modules", 318 } 319 320 for _, extra := range systemModules { 321 bp += fmt.Sprintf(` 322 java_system_modules { 323 name: "%[1]s", 324 libs: ["%[1]s-lib"], 325 } 326 java_library { 327 name: "%[1]s-lib", 328 sdk_version: "none", 329 system_modules: "none", 330 } 331 `, extra) 332 } 333 334 // Make sure that the dex_bootjars singleton module is instantiated for the tests. 335 bp += ` 336 dex_bootjars { 337 name: "dex_bootjars", 338 } 339` 340 341 return bp 342} 343 344func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) { 345 t.Helper() 346 module := ctx.ModuleForTests(name, variant).Module() 347 deps := []string{} 348 ctx.VisitDirectDeps(module, func(m blueprint.Module) { 349 deps = append(deps, m.Name()) 350 }) 351 sort.Strings(deps) 352 353 if actual := deps; !reflect.DeepEqual(expected, actual) { 354 t.Errorf("expected %#q, found %#q", expected, actual) 355 } 356} 357 358// CheckPlatformBootclasspathModules returns the apex:module pair for the modules depended upon by 359// the platform-bootclasspath module. 360func CheckPlatformBootclasspathModules(t *testing.T, result *android.TestResult, name string, expected []string) { 361 t.Helper() 362 platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule) 363 pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.configuredModules) 364 android.AssertDeepEquals(t, fmt.Sprintf("%s modules", "platform-bootclasspath"), expected, pairs) 365} 366 367// ApexNamePairsFromModules returns the apex:module pair for the supplied modules. 368func ApexNamePairsFromModules(ctx *android.TestContext, modules []android.Module) []string { 369 pairs := []string{} 370 for _, module := range modules { 371 pairs = append(pairs, apexNamePairFromModule(ctx, module)) 372 } 373 return pairs 374} 375 376func apexNamePairFromModule(ctx *android.TestContext, module android.Module) string { 377 name := module.Name() 378 var apex string 379 apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) 380 if apexInfo.IsForPlatform() { 381 apex = "platform" 382 } else { 383 apex = apexInfo.InApexVariants[0] 384 } 385 386 return fmt.Sprintf("%s:%s", apex, name) 387} 388 389// CheckPlatformBootclasspathFragments returns the apex:module pair for the fragments depended upon 390// by the platform-bootclasspath module. 391func CheckPlatformBootclasspathFragments(t *testing.T, result *android.TestResult, name string, expected []string) { 392 t.Helper() 393 platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule) 394 pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.fragments) 395 android.AssertDeepEquals(t, fmt.Sprintf("%s fragments", "platform-bootclasspath"), expected, pairs) 396} 397 398func CheckHiddenAPIRuleInputs(t *testing.T, message string, expected string, hiddenAPIRule android.TestingBuildParams) { 399 t.Helper() 400 inputs := android.Paths{} 401 if hiddenAPIRule.Input != nil { 402 inputs = append(inputs, hiddenAPIRule.Input) 403 } 404 inputs = append(inputs, hiddenAPIRule.Inputs...) 405 inputs = append(inputs, hiddenAPIRule.Implicits...) 406 inputs = android.SortedUniquePaths(inputs) 407 actual := strings.TrimSpace(strings.Join(inputs.RelativeToTop().Strings(), "\n")) 408 re := regexp.MustCompile(`\n\s+`) 409 expected = strings.TrimSpace(re.ReplaceAllString(expected, "\n")) 410 if actual != expected { 411 t.Errorf("Expected hiddenapi rule inputs - %s:\n%s\nactual inputs:\n%s", message, expected, actual) 412 } 413} 414 415// Check that the merged file create by platform_compat_config_singleton has the correct inputs. 416func CheckMergedCompatConfigInputs(t *testing.T, result *android.TestResult, message string, expectedPaths ...string) { 417 sourceGlobalCompatConfig := result.SingletonForTests("platform_compat_config_singleton") 418 allOutputs := sourceGlobalCompatConfig.AllOutputs() 419 android.AssertIntEquals(t, message+": output len", 1, len(allOutputs)) 420 output := sourceGlobalCompatConfig.Output(allOutputs[0]) 421 android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits) 422} 423