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