dexpreopt_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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 dexpreopt
  15. import (
  16. "android/soong/android"
  17. "fmt"
  18. "testing"
  19. )
  20. func testSystemModuleConfig(ctx android.PathContext, name string) *ModuleConfig {
  21. return testModuleConfig(ctx, name, "system")
  22. }
  23. func testSystemProductModuleConfig(ctx android.PathContext, name string) *ModuleConfig {
  24. return testModuleConfig(ctx, name, "system/product")
  25. }
  26. func testProductModuleConfig(ctx android.PathContext, name string) *ModuleConfig {
  27. return testModuleConfig(ctx, name, "product")
  28. }
  29. func testModuleConfig(ctx android.PathContext, name, partition string) *ModuleConfig {
  30. return createTestModuleConfig(
  31. name,
  32. fmt.Sprintf("/%s/app/test/%s.apk", partition, name),
  33. android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)),
  34. android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)),
  35. android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
  36. }
  37. func testApexModuleConfig(ctx android.PathContext, name, apexName string) *ModuleConfig {
  38. return createTestModuleConfig(
  39. name,
  40. fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, name),
  41. android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)),
  42. android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)),
  43. android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
  44. }
  45. func testPlatformSystemServerModuleConfig(ctx android.PathContext, name string) *ModuleConfig {
  46. return createTestModuleConfig(
  47. name,
  48. fmt.Sprintf("/system/framework/%s.jar", name),
  49. android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)),
  50. android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)),
  51. android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
  52. }
  53. func testSystemExtSystemServerModuleConfig(ctx android.PathContext, name string) *ModuleConfig {
  54. return createTestModuleConfig(
  55. name,
  56. fmt.Sprintf("/system_ext/framework/%s.jar", name),
  57. android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)),
  58. android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)),
  59. android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
  60. }
  61. func createTestModuleConfig(name, dexLocation string, buildPath, dexPath, enforceUsesLibrariesStatusFile android.OutputPath) *ModuleConfig {
  62. return &ModuleConfig{
  63. Name: name,
  64. DexLocation: dexLocation,
  65. BuildPath: buildPath,
  66. DexPath: dexPath,
  67. UncompressedDex: false,
  68. HasApkLibraries: false,
  69. PreoptFlags: nil,
  70. ProfileClassListing: android.OptionalPath{},
  71. ProfileIsTextListing: false,
  72. EnforceUsesLibrariesStatusFile: enforceUsesLibrariesStatusFile,
  73. EnforceUsesLibraries: false,
  74. ClassLoaderContexts: nil,
  75. Archs: []android.ArchType{android.Arm},
  76. DexPreoptImagesDeps: []android.OutputPaths{android.OutputPaths{}},
  77. DexPreoptImageLocationsOnHost: []string{},
  78. PreoptBootClassPathDexFiles: nil,
  79. PreoptBootClassPathDexLocations: nil,
  80. PreoptExtractedApk: false,
  81. NoCreateAppImage: false,
  82. ForceCreateAppImage: false,
  83. PresignedPrebuilt: false,
  84. }
  85. }
  86. func TestDexPreopt(t *testing.T) {
  87. config := android.TestConfig("out", nil, "", nil)
  88. ctx := android.BuilderContextForTesting(config)
  89. globalSoong := globalSoongConfigForTests()
  90. global := GlobalConfigForTests(ctx)
  91. module := testSystemModuleConfig(ctx, "test")
  92. productPackages := android.PathForTesting("product_packages.txt")
  93. rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
  94. if err != nil {
  95. t.Fatal(err)
  96. }
  97. wantInstalls := android.RuleBuilderInstalls{
  98. {android.PathForOutput(ctx, "test/oat/arm/package.odex"), "/system/app/test/oat/arm/test.odex"},
  99. {android.PathForOutput(ctx, "test/oat/arm/package.vdex"), "/system/app/test/oat/arm/test.vdex"},
  100. }
  101. if rule.Installs().String() != wantInstalls.String() {
  102. t.Errorf("\nwant installs:\n %v\ngot:\n %v", wantInstalls, rule.Installs())
  103. }
  104. }
  105. func TestDexPreoptSystemOther(t *testing.T) {
  106. config := android.TestConfig("out", nil, "", nil)
  107. ctx := android.BuilderContextForTesting(config)
  108. globalSoong := globalSoongConfigForTests()
  109. global := GlobalConfigForTests(ctx)
  110. systemModule := testSystemModuleConfig(ctx, "Stest")
  111. systemProductModule := testSystemProductModuleConfig(ctx, "SPtest")
  112. productModule := testProductModuleConfig(ctx, "Ptest")
  113. productPackages := android.PathForTesting("product_packages.txt")
  114. global.HasSystemOther = true
  115. type moduleTest struct {
  116. module *ModuleConfig
  117. expectedPartition string
  118. }
  119. tests := []struct {
  120. patterns []string
  121. moduleTests []moduleTest
  122. }{
  123. {
  124. patterns: []string{"app/%"},
  125. moduleTests: []moduleTest{
  126. {module: systemModule, expectedPartition: "system_other/system"},
  127. {module: systemProductModule, expectedPartition: "system/product"},
  128. {module: productModule, expectedPartition: "product"},
  129. },
  130. },
  131. // product/app/% only applies to product apps inside the system partition
  132. {
  133. patterns: []string{"app/%", "product/app/%"},
  134. moduleTests: []moduleTest{
  135. {module: systemModule, expectedPartition: "system_other/system"},
  136. {module: systemProductModule, expectedPartition: "system_other/system/product"},
  137. {module: productModule, expectedPartition: "product"},
  138. },
  139. },
  140. }
  141. for _, test := range tests {
  142. global.PatternsOnSystemOther = test.patterns
  143. for _, mt := range test.moduleTests {
  144. rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module, productPackages)
  145. if err != nil {
  146. t.Fatal(err)
  147. }
  148. name := mt.module.Name
  149. wantInstalls := android.RuleBuilderInstalls{
  150. {android.PathForOutput(ctx, name+"/oat/arm/package.odex"), fmt.Sprintf("/%s/app/test/oat/arm/%s.odex", mt.expectedPartition, name)},
  151. {android.PathForOutput(ctx, name+"/oat/arm/package.vdex"), fmt.Sprintf("/%s/app/test/oat/arm/%s.vdex", mt.expectedPartition, name)},
  152. }
  153. if rule.Installs().String() != wantInstalls.String() {
  154. t.Errorf("\nwant installs:\n %v\ngot:\n %v", wantInstalls, rule.Installs())
  155. }
  156. }
  157. }
  158. }
  159. func TestDexPreoptApexSystemServerJars(t *testing.T) {
  160. config := android.TestConfig("out", nil, "", nil)
  161. ctx := android.BuilderContextForTesting(config)
  162. globalSoong := globalSoongConfigForTests()
  163. global := GlobalConfigForTests(ctx)
  164. module := testApexModuleConfig(ctx, "service-A", "com.android.apex1")
  165. productPackages := android.PathForTesting("product_packages.txt")
  166. global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
  167. []string{"com.android.apex1:service-A"})
  168. rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
  169. if err != nil {
  170. t.Fatal(err)
  171. }
  172. wantInstalls := android.RuleBuilderInstalls{
  173. {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.odex"},
  174. {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.vdex"},
  175. }
  176. android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
  177. }
  178. func TestDexPreoptStandaloneSystemServerJars(t *testing.T) {
  179. config := android.TestConfig("out", nil, "", nil)
  180. ctx := android.BuilderContextForTesting(config)
  181. globalSoong := globalSoongConfigForTests()
  182. global := GlobalConfigForTests(ctx)
  183. module := testPlatformSystemServerModuleConfig(ctx, "service-A")
  184. productPackages := android.PathForTesting("product_packages.txt")
  185. global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
  186. []string{"platform:service-A"})
  187. rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
  188. if err != nil {
  189. t.Fatal(err)
  190. }
  191. wantInstalls := android.RuleBuilderInstalls{
  192. {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/service-A.odex"},
  193. {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/service-A.vdex"},
  194. }
  195. android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
  196. }
  197. func TestDexPreoptSystemExtSystemServerJars(t *testing.T) {
  198. config := android.TestConfig("out", nil, "", nil)
  199. ctx := android.BuilderContextForTesting(config)
  200. globalSoong := globalSoongConfigForTests()
  201. global := GlobalConfigForTests(ctx)
  202. module := testSystemExtSystemServerModuleConfig(ctx, "service-A")
  203. productPackages := android.PathForTesting("product_packages.txt")
  204. global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
  205. []string{"system_ext:service-A"})
  206. rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
  207. if err != nil {
  208. t.Fatal(err)
  209. }
  210. wantInstalls := android.RuleBuilderInstalls{
  211. {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system_ext/framework/oat/arm/service-A.odex"},
  212. {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system_ext/framework/oat/arm/service-A.vdex"},
  213. }
  214. android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
  215. }
  216. func TestDexPreoptApexStandaloneSystemServerJars(t *testing.T) {
  217. config := android.TestConfig("out", nil, "", nil)
  218. ctx := android.BuilderContextForTesting(config)
  219. globalSoong := globalSoongConfigForTests()
  220. global := GlobalConfigForTests(ctx)
  221. module := testApexModuleConfig(ctx, "service-A", "com.android.apex1")
  222. productPackages := android.PathForTesting("product_packages.txt")
  223. global.ApexStandaloneSystemServerJars = android.CreateTestConfiguredJarList(
  224. []string{"com.android.apex1:service-A"})
  225. rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
  226. if err != nil {
  227. t.Fatal(err)
  228. }
  229. wantInstalls := android.RuleBuilderInstalls{
  230. {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.odex"},
  231. {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.vdex"},
  232. }
  233. android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
  234. }
  235. func TestDexPreoptProfile(t *testing.T) {
  236. config := android.TestConfig("out", nil, "", nil)
  237. ctx := android.BuilderContextForTesting(config)
  238. globalSoong := globalSoongConfigForTests()
  239. global := GlobalConfigForTests(ctx)
  240. module := testSystemModuleConfig(ctx, "test")
  241. productPackages := android.PathForTesting("product_packages.txt")
  242. module.ProfileClassListing = android.OptionalPathForPath(android.PathForTesting("profile"))
  243. rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
  244. if err != nil {
  245. t.Fatal(err)
  246. }
  247. wantInstalls := android.RuleBuilderInstalls{
  248. {android.PathForOutput(ctx, "test/profile.prof"), "/system/app/test/test.apk.prof"},
  249. {android.PathForOutput(ctx, "test/oat/arm/package.art"), "/system/app/test/oat/arm/test.art"},
  250. {android.PathForOutput(ctx, "test/oat/arm/package.odex"), "/system/app/test/oat/arm/test.odex"},
  251. {android.PathForOutput(ctx, "test/oat/arm/package.vdex"), "/system/app/test/oat/arm/test.vdex"},
  252. }
  253. if rule.Installs().String() != wantInstalls.String() {
  254. t.Errorf("\nwant installs:\n %v\ngot:\n %v", wantInstalls, rule.Installs())
  255. }
  256. }
  257. func TestDexPreoptConfigToJson(t *testing.T) {
  258. config := android.TestConfig("out", nil, "", nil)
  259. ctx := android.BuilderContextForTesting(config)
  260. module := testSystemModuleConfig(ctx, "test")
  261. data, err := moduleConfigToJSON(module)
  262. if err != nil {
  263. t.Errorf("Failed to convert module config data to JSON, %v", err)
  264. }
  265. parsed, err := ParseModuleConfig(ctx, data)
  266. if err != nil {
  267. t.Errorf("Failed to parse JSON, %v", err)
  268. }
  269. before := fmt.Sprintf("%v", module)
  270. after := fmt.Sprintf("%v", parsed)
  271. android.AssertStringEquals(t, "The result must be the same as the original after marshalling and unmarshalling it.", before, after)
  272. }