1// Copyright 2018 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 "runtime" 20 "strings" 21 "testing" 22 23 "android/soong/android" 24 "android/soong/cc" 25 "android/soong/dexpreopt" 26) 27 28func init() { 29 RegisterFakeRuntimeApexMutator() 30} 31 32func TestDexpreoptEnabled(t *testing.T) { 33 tests := []struct { 34 name string 35 bp string 36 moduleName string 37 apexVariant bool 38 enabled bool 39 }{ 40 { 41 name: "app", 42 bp: ` 43 android_app { 44 name: "foo", 45 srcs: ["a.java"], 46 sdk_version: "current", 47 }`, 48 enabled: true, 49 }, 50 { 51 name: "installable java library", 52 bp: ` 53 java_library { 54 name: "foo", 55 installable: true, 56 srcs: ["a.java"], 57 }`, 58 enabled: true, 59 }, 60 { 61 name: "java binary", 62 bp: ` 63 java_binary { 64 name: "foo", 65 srcs: ["a.java"], 66 main_class: "foo.bar.jb", 67 }`, 68 enabled: true, 69 }, 70 { 71 name: "app without sources", 72 bp: ` 73 android_app { 74 name: "foo", 75 sdk_version: "current", 76 }`, 77 enabled: false, 78 }, 79 { 80 name: "app with libraries", 81 bp: ` 82 android_app { 83 name: "foo", 84 static_libs: ["lib"], 85 sdk_version: "current", 86 } 87 88 java_library { 89 name: "lib", 90 srcs: ["a.java"], 91 sdk_version: "current", 92 }`, 93 enabled: true, 94 }, 95 { 96 name: "installable java library without sources", 97 bp: ` 98 java_library { 99 name: "foo", 100 installable: true, 101 }`, 102 enabled: false, 103 }, 104 { 105 name: "static java library", 106 bp: ` 107 java_library { 108 name: "foo", 109 srcs: ["a.java"], 110 }`, 111 enabled: false, 112 }, 113 { 114 name: "java test", 115 bp: ` 116 java_test { 117 name: "foo", 118 srcs: ["a.java"], 119 }`, 120 enabled: false, 121 }, 122 { 123 name: "android test", 124 bp: ` 125 android_test { 126 name: "foo", 127 srcs: ["a.java"], 128 }`, 129 enabled: false, 130 }, 131 { 132 name: "android test helper app", 133 bp: ` 134 android_test_helper_app { 135 name: "foo", 136 srcs: ["a.java"], 137 }`, 138 enabled: false, 139 }, 140 { 141 name: "compile_dex", 142 bp: ` 143 java_library { 144 name: "foo", 145 srcs: ["a.java"], 146 compile_dex: true, 147 }`, 148 enabled: false, 149 }, 150 { 151 name: "dex_import", 152 bp: ` 153 dex_import { 154 name: "foo", 155 jars: ["a.jar"], 156 }`, 157 enabled: true, 158 }, 159 { 160 name: "apex variant", 161 bp: ` 162 java_library { 163 name: "foo", 164 installable: true, 165 srcs: ["a.java"], 166 apex_available: ["com.android.apex1"], 167 }`, 168 apexVariant: true, 169 enabled: false, 170 }, 171 { 172 name: "apex variant of apex system server jar", 173 bp: ` 174 java_library { 175 name: "service-foo", 176 installable: true, 177 srcs: ["a.java"], 178 apex_available: ["com.android.apex1"], 179 }`, 180 moduleName: "service-foo", 181 apexVariant: true, 182 enabled: true, 183 }, 184 { 185 name: "apex variant of prebuilt apex system server jar", 186 bp: ` 187 java_library { 188 name: "prebuilt_service-foo", 189 installable: true, 190 srcs: ["a.java"], 191 apex_available: ["com.android.apex1"], 192 }`, 193 moduleName: "prebuilt_service-foo", 194 apexVariant: true, 195 enabled: true, 196 }, 197 { 198 name: "platform variant of apex system server jar", 199 bp: ` 200 java_library { 201 name: "service-foo", 202 installable: true, 203 srcs: ["a.java"], 204 apex_available: ["com.android.apex1"], 205 }`, 206 moduleName: "service-foo", 207 apexVariant: false, 208 enabled: false, 209 }, 210 } 211 212 for _, test := range tests { 213 t.Run(test.name, func(t *testing.T) { 214 preparers := android.GroupFixturePreparers( 215 PrepareForTestWithDexpreopt, 216 PrepareForTestWithFakeApexMutator, 217 dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"), 218 ) 219 220 result := preparers.RunTestWithBp(t, test.bp) 221 ctx := result.TestContext 222 223 moduleName := "foo" 224 if test.moduleName != "" { 225 moduleName = test.moduleName 226 } 227 228 variant := "android_common" 229 if test.apexVariant { 230 variant += "_apex1000" 231 } 232 233 dexpreopt := ctx.ModuleForTests(moduleName, variant).MaybeRule("dexpreopt") 234 enabled := dexpreopt.Rule != nil 235 236 if enabled != test.enabled { 237 t.Fatalf("want dexpreopt %s, got %s", enabledString(test.enabled), enabledString(enabled)) 238 } 239 }) 240 241 } 242} 243 244func enabledString(enabled bool) string { 245 if enabled { 246 return "enabled" 247 } else { 248 return "disabled" 249 } 250} 251 252func TestDex2oatToolDeps(t *testing.T) { 253 if runtime.GOOS != "linux" { 254 // The host binary paths checked below are build OS dependent. 255 t.Skipf("Unsupported build OS %s", runtime.GOOS) 256 } 257 258 preparers := android.GroupFixturePreparers( 259 cc.PrepareForTestWithCcDefaultModules, 260 PrepareForTestWithDexpreoptWithoutFakeDex2oatd, 261 dexpreopt.PrepareForTestByEnablingDexpreopt) 262 263 testDex2oatToolDep := func(sourceEnabled, prebuiltEnabled, prebuiltPreferred bool, 264 expectedDex2oatPath string) { 265 name := fmt.Sprintf("sourceEnabled:%t,prebuiltEnabled:%t,prebuiltPreferred:%t", 266 sourceEnabled, prebuiltEnabled, prebuiltPreferred) 267 t.Run(name, func(t *testing.T) { 268 result := preparers.RunTestWithBp(t, fmt.Sprintf(` 269 cc_binary { 270 name: "dex2oatd", 271 enabled: %t, 272 host_supported: true, 273 } 274 cc_prebuilt_binary { 275 name: "dex2oatd", 276 enabled: %t, 277 prefer: %t, 278 host_supported: true, 279 srcs: ["x86_64/bin/dex2oatd"], 280 } 281 java_library { 282 name: "myjavalib", 283 } 284 `, sourceEnabled, prebuiltEnabled, prebuiltPreferred)) 285 pathContext := android.PathContextForTesting(result.Config) 286 dex2oatPath := dexpreopt.GetCachedGlobalSoongConfig(pathContext).Dex2oat 287 android.AssertStringEquals(t, "Testing "+name, expectedDex2oatPath, android.NormalizePathForTesting(dex2oatPath)) 288 }) 289 } 290 291 sourceDex2oatPath := "host/linux-x86/bin/dex2oatd" 292 prebuiltDex2oatPath := ".intermediates/prebuilt_dex2oatd/linux_glibc_x86_64/dex2oatd" 293 294 testDex2oatToolDep(true, false, false, sourceDex2oatPath) 295 testDex2oatToolDep(true, true, false, sourceDex2oatPath) 296 testDex2oatToolDep(true, true, true, prebuiltDex2oatPath) 297 testDex2oatToolDep(false, true, false, prebuiltDex2oatPath) 298} 299 300func TestDexpreoptBuiltInstalledForApex(t *testing.T) { 301 preparers := android.GroupFixturePreparers( 302 PrepareForTestWithDexpreopt, 303 PrepareForTestWithFakeApexMutator, 304 dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"), 305 ) 306 307 // An APEX system server jar. 308 result := preparers.RunTestWithBp(t, ` 309 java_library { 310 name: "service-foo", 311 installable: true, 312 srcs: ["a.java"], 313 apex_available: ["com.android.apex1"], 314 }`) 315 ctx := result.TestContext 316 module := ctx.ModuleForTests("service-foo", "android_common_apex1000") 317 library := module.Module().(*Library) 318 319 installs := library.dexpreopter.DexpreoptBuiltInstalledForApex() 320 321 android.AssertIntEquals(t, "install count", 2, len(installs)) 322 323 android.AssertStringEquals(t, "installs[0] FullModuleName", 324 "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex", 325 installs[0].FullModuleName()) 326 327 android.AssertStringEquals(t, "installs[0] SubModuleName", 328 "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex", 329 installs[0].SubModuleName()) 330 331 android.AssertStringEquals(t, "installs[1] FullModuleName", 332 "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", 333 installs[1].FullModuleName()) 334 335 android.AssertStringEquals(t, "installs[1] SubModuleName", 336 "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", 337 installs[1].SubModuleName()) 338 339 // Not an APEX system server jar. 340 result = preparers.RunTestWithBp(t, ` 341 java_library { 342 name: "foo", 343 installable: true, 344 srcs: ["a.java"], 345 }`) 346 ctx = result.TestContext 347 module = ctx.ModuleForTests("foo", "android_common") 348 library = module.Module().(*Library) 349 350 installs = library.dexpreopter.DexpreoptBuiltInstalledForApex() 351 352 android.AssertIntEquals(t, "install count", 0, len(installs)) 353} 354 355func filterDexpreoptEntriesList(entriesList []android.AndroidMkEntries) []android.AndroidMkEntries { 356 var results []android.AndroidMkEntries 357 for _, entries := range entriesList { 358 if strings.Contains(entries.EntryMap["LOCAL_MODULE"][0], "-dexpreopt-") { 359 results = append(results, entries) 360 } 361 } 362 return results 363} 364 365func verifyEntries(t *testing.T, message string, expectedModule string, 366 expectedPrebuiltModuleFile string, expectedModulePath string, expectedInstalledModuleStem string, 367 entries android.AndroidMkEntries) { 368 android.AssertStringEquals(t, message+" LOCAL_MODULE", expectedModule, 369 entries.EntryMap["LOCAL_MODULE"][0]) 370 371 android.AssertStringEquals(t, message+" LOCAL_MODULE_CLASS", "ETC", 372 entries.EntryMap["LOCAL_MODULE_CLASS"][0]) 373 374 android.AssertStringDoesContain(t, message+" LOCAL_PREBUILT_MODULE_FILE", 375 entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"][0], expectedPrebuiltModuleFile) 376 377 android.AssertStringDoesContain(t, message+" LOCAL_MODULE_PATH", 378 entries.EntryMap["LOCAL_MODULE_PATH"][0], expectedModulePath) 379 380 android.AssertStringEquals(t, message+" LOCAL_INSTALLED_MODULE_STEM", 381 expectedInstalledModuleStem, entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"][0]) 382 383 android.AssertStringEquals(t, message+" LOCAL_NOT_AVAILABLE_FOR_PLATFORM", 384 "false", entries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"][0]) 385} 386 387func TestAndroidMkEntriesForApex(t *testing.T) { 388 preparers := android.GroupFixturePreparers( 389 PrepareForTestWithDexpreopt, 390 PrepareForTestWithFakeApexMutator, 391 dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"), 392 ) 393 394 // An APEX system server jar. 395 result := preparers.RunTestWithBp(t, ` 396 java_library { 397 name: "service-foo", 398 installable: true, 399 srcs: ["a.java"], 400 apex_available: ["com.android.apex1"], 401 }`) 402 ctx := result.TestContext 403 module := ctx.ModuleForTests("service-foo", "android_common_apex1000") 404 405 entriesList := android.AndroidMkEntriesForTest(t, ctx, module.Module()) 406 entriesList = filterDexpreoptEntriesList(entriesList) 407 408 android.AssertIntEquals(t, "entries count", 2, len(entriesList)) 409 410 verifyEntries(t, 411 "entriesList[0]", 412 "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex", 413 "/dexpreopt/oat/arm64/javalib.odex", 414 "/system/framework/oat/arm64", 415 "apex@com.android.apex1@javalib@service-foo.jar@classes.odex", 416 entriesList[0]) 417 418 verifyEntries(t, 419 "entriesList[1]", 420 "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", 421 "/dexpreopt/oat/arm64/javalib.vdex", 422 "/system/framework/oat/arm64", 423 "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", 424 entriesList[1]) 425 426 // Not an APEX system server jar. 427 result = preparers.RunTestWithBp(t, ` 428 java_library { 429 name: "foo", 430 installable: true, 431 srcs: ["a.java"], 432 }`) 433 ctx = result.TestContext 434 module = ctx.ModuleForTests("foo", "android_common") 435 436 entriesList = android.AndroidMkEntriesForTest(t, ctx, module.Module()) 437 entriesList = filterDexpreoptEntriesList(entriesList) 438 439 android.AssertIntEquals(t, "entries count", 0, len(entriesList)) 440} 441 442func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) { 443 preparers := android.GroupFixturePreparers( 444 PrepareForTestWithJavaDefaultModules, 445 PrepareForTestWithFakeApexMutator, 446 dexpreopt.FixtureDisableDexpreopt(true), 447 ) 448 449 result := preparers.RunTestWithBp(t, ` 450 java_library { 451 name: "foo", 452 installable: true, 453 dex_preopt: { 454 profile: "art-profile", 455 }, 456 srcs: ["a.java"], 457 }`) 458 459 ctx := result.TestContext 460 dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt") 461 462 expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/profile.prof"} 463 464 android.AssertArrayString(t, "outputs", expected, dexpreopt.AllOutputs()) 465} 466