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 "testing" 21 22 "android/soong/android" 23 "android/soong/cc" 24 "android/soong/dexpreopt" 25) 26 27func init() { 28 RegisterFakeRuntimeApexMutator() 29} 30 31func TestDexpreoptEnabled(t *testing.T) { 32 t.Parallel() 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 t.Parallel() 223 preparers := android.GroupFixturePreparers( 224 PrepareForTestWithDexpreopt, 225 PrepareForTestWithFakeApexMutator, 226 dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"), 227 ) 228 229 result := preparers.RunTestWithBp(t, test.bp) 230 ctx := result.TestContext 231 232 moduleName := "foo" 233 if test.moduleName != "" { 234 moduleName = test.moduleName 235 } 236 237 variant := "android_common" 238 if test.apexVariant { 239 variant += "_apex1000" 240 } 241 242 dexpreopt := ctx.ModuleForTests(t, moduleName, variant).MaybeRule("dexpreopt") 243 enabled := dexpreopt.Rule != nil 244 245 if enabled != test.enabled { 246 t.Fatalf("want dexpreopt %s, got %s", enabledString(test.enabled), enabledString(enabled)) 247 } 248 }) 249 250 } 251} 252 253func enabledString(enabled bool) string { 254 if enabled { 255 return "enabled" 256 } else { 257 return "disabled" 258 } 259} 260 261func TestDex2oatToolDeps(t *testing.T) { 262 t.Parallel() 263 if runtime.GOOS != "linux" { 264 // The host binary paths checked below are build OS dependent. 265 t.Skipf("Unsupported build OS %s", runtime.GOOS) 266 } 267 268 preparers := android.GroupFixturePreparers( 269 cc.PrepareForTestWithCcDefaultModules, 270 PrepareForTestWithDexpreoptWithoutFakeDex2oatd, 271 dexpreopt.PrepareForTestByEnablingDexpreopt) 272 273 testDex2oatToolDep := func(sourceEnabled, prebuiltEnabled, prebuiltPreferred bool, 274 expectedDex2oatPath string) { 275 name := fmt.Sprintf("sourceEnabled:%t,prebuiltEnabled:%t,prebuiltPreferred:%t", 276 sourceEnabled, prebuiltEnabled, prebuiltPreferred) 277 t.Run(name, func(t *testing.T) { 278 t.Parallel() 279 result := preparers.RunTestWithBp(t, fmt.Sprintf(` 280 cc_binary { 281 name: "dex2oatd", 282 enabled: %t, 283 host_supported: true, 284 } 285 cc_prebuilt_binary { 286 name: "dex2oatd", 287 enabled: %t, 288 prefer: %t, 289 host_supported: true, 290 srcs: ["x86_64/bin/dex2oatd"], 291 } 292 java_library { 293 name: "myjavalib", 294 } 295 `, sourceEnabled, prebuiltEnabled, prebuiltPreferred)) 296 pathContext := android.PathContextForTesting(result.Config) 297 dex2oatPath := dexpreopt.GetCachedGlobalSoongConfig(pathContext).Dex2oat 298 android.AssertStringEquals(t, "Testing "+name, expectedDex2oatPath, android.NormalizePathForTesting(dex2oatPath)) 299 }) 300 } 301 302 sourceDex2oatPath := "../host/linux-x86/bin/dex2oatd" 303 prebuiltDex2oatPath := ".intermediates/prebuilt_dex2oatd/linux_glibc_x86_64/dex2oatd" 304 305 testDex2oatToolDep(true, false, false, sourceDex2oatPath) 306 testDex2oatToolDep(true, true, false, sourceDex2oatPath) 307 testDex2oatToolDep(true, true, true, prebuiltDex2oatPath) 308 testDex2oatToolDep(false, true, false, prebuiltDex2oatPath) 309} 310 311func TestApexSystemServerDexpreoptInstalls(t *testing.T) { 312 preparers := android.GroupFixturePreparers( 313 PrepareForTestWithDexpreopt, 314 PrepareForTestWithFakeApexMutator, 315 dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"), 316 ) 317 318 // An APEX system server jar. 319 result := preparers.RunTestWithBp(t, ` 320 java_library { 321 name: "service-foo", 322 installable: true, 323 srcs: ["a.java"], 324 apex_available: ["com.android.apex1"], 325 sdk_version: "current", 326 }`) 327 ctx := result.TestContext 328 module := ctx.ModuleForTests(t, "service-foo", "android_common_apex1000") 329 library := module.Module().(*Library) 330 331 installs := library.dexpreopter.ApexSystemServerDexpreoptInstalls() 332 dexJars := library.dexpreopter.ApexSystemServerDexJars() 333 334 android.AssertIntEquals(t, "install count", 2, len(installs)) 335 android.AssertIntEquals(t, "dexjar count", 1, len(dexJars)) 336 337 android.AssertPathRelativeToTopEquals(t, "installs[0] OutputPathOnHost", 338 "out/soong/.intermediates/service-foo/android_common_apex1000/dexpreopt/service-foo/oat/arm64/javalib.odex", 339 installs[0].OutputPathOnHost) 340 341 android.AssertPathRelativeToTopEquals(t, "installs[0] InstallDirOnDevice", 342 "out/target/product/test_device/system/framework/oat/arm64", 343 installs[0].InstallDirOnDevice) 344 345 android.AssertStringEquals(t, "installs[0] InstallFileOnDevice", 346 "apex@com.android.apex1@javalib@service-foo.jar@classes.odex", 347 installs[0].InstallFileOnDevice) 348 349 android.AssertPathRelativeToTopEquals(t, "installs[1] OutputPathOnHost", 350 "out/soong/.intermediates/service-foo/android_common_apex1000/dexpreopt/service-foo/oat/arm64/javalib.vdex", 351 installs[1].OutputPathOnHost) 352 353 android.AssertPathRelativeToTopEquals(t, "installs[1] InstallDirOnDevice", 354 "out/target/product/test_device/system/framework/oat/arm64", 355 installs[1].InstallDirOnDevice) 356 357 android.AssertStringEquals(t, "installs[1] InstallFileOnDevice", 358 "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", 359 installs[1].InstallFileOnDevice) 360 361 // Not an APEX system server jar. 362 result = preparers.RunTestWithBp(t, ` 363 java_library { 364 name: "foo", 365 installable: true, 366 srcs: ["a.java"], 367 sdk_version: "current", 368 }`) 369 ctx = result.TestContext 370 module = ctx.ModuleForTests(t, "foo", "android_common") 371 library = module.Module().(*Library) 372 373 installs = library.dexpreopter.ApexSystemServerDexpreoptInstalls() 374 dexJars = library.dexpreopter.ApexSystemServerDexJars() 375 376 android.AssertIntEquals(t, "install count", 0, len(installs)) 377 android.AssertIntEquals(t, "dexjar count", 0, len(dexJars)) 378} 379 380func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) { 381 preparers := android.GroupFixturePreparers( 382 PrepareForTestWithJavaDefaultModules, 383 PrepareForTestWithFakeApexMutator, 384 dexpreopt.FixtureDisableDexpreopt(true), 385 ) 386 387 result := preparers.RunTestWithBp(t, ` 388 java_library { 389 name: "foo", 390 installable: true, 391 dex_preopt: { 392 profile: "art-profile", 393 }, 394 srcs: ["a.java"], 395 sdk_version: "current", 396 }`) 397 398 ctx := result.TestContext 399 dexpreopt := ctx.ModuleForTests(t, "foo", "android_common").MaybeRule("dexpreopt") 400 401 expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/foo/profile.prof"} 402 403 android.AssertArrayString(t, "outputs", expected, dexpreopt.AllOutputs()) 404} 405