dexpreopt_test.go 12 KB

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