hiddenapi_singleton_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. // Copyright 2020 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. "path/filepath"
  18. "testing"
  19. "android/soong/android"
  20. "github.com/google/blueprint/proptools"
  21. )
  22. // TODO(b/177892522): Move these tests into a more appropriate place.
  23. func fixtureSetPrebuiltHiddenApiDirProductVariable(prebuiltHiddenApiDir *string) android.FixturePreparer {
  24. return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
  25. variables.PrebuiltHiddenApiDir = prebuiltHiddenApiDir
  26. })
  27. }
  28. var prepareForTestWithDefaultPlatformBootclasspath = android.FixtureAddTextFile("frameworks/base/boot/Android.bp", `
  29. platform_bootclasspath {
  30. name: "platform-bootclasspath",
  31. }
  32. `)
  33. var hiddenApiFixtureFactory = android.GroupFixturePreparers(
  34. PrepareForTestWithJavaDefaultModules,
  35. PrepareForTestWithHiddenApiBuildComponents,
  36. )
  37. func TestHiddenAPISingleton(t *testing.T) {
  38. result := android.GroupFixturePreparers(
  39. hiddenApiFixtureFactory,
  40. FixtureConfigureBootJars("platform:foo"),
  41. prepareForTestWithDefaultPlatformBootclasspath,
  42. ).RunTestWithBp(t, `
  43. java_library {
  44. name: "foo",
  45. srcs: ["a.java"],
  46. compile_dex: true,
  47. }
  48. `)
  49. hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
  50. hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
  51. want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
  52. android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
  53. }
  54. func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) {
  55. expectedErrorMessage := "module prebuilt_foo{os:android,arch:common} does not provide a dex jar"
  56. android.GroupFixturePreparers(
  57. hiddenApiFixtureFactory,
  58. FixtureConfigureBootJars("platform:foo"),
  59. prepareForTestWithDefaultPlatformBootclasspath,
  60. ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorMessage)).
  61. RunTestWithBp(t, `
  62. java_library {
  63. name: "foo",
  64. srcs: ["a.java"],
  65. compile_dex: true,
  66. }
  67. java_import {
  68. name: "foo",
  69. jars: ["a.jar"],
  70. prefer: true,
  71. }
  72. `)
  73. }
  74. func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
  75. result := android.GroupFixturePreparers(
  76. hiddenApiFixtureFactory,
  77. FixtureConfigureBootJars("platform:foo"),
  78. prepareForTestWithDefaultPlatformBootclasspath,
  79. ).RunTestWithBp(t, `
  80. java_import {
  81. name: "foo",
  82. jars: ["a.jar"],
  83. compile_dex: true,
  84. }
  85. `)
  86. hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
  87. hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
  88. want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
  89. android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
  90. }
  91. func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
  92. result := android.GroupFixturePreparers(
  93. hiddenApiFixtureFactory,
  94. FixtureConfigureBootJars("platform:foo"),
  95. prepareForTestWithDefaultPlatformBootclasspath,
  96. ).RunTestWithBp(t, `
  97. java_library {
  98. name: "foo",
  99. srcs: ["a.java"],
  100. compile_dex: true,
  101. }
  102. java_import {
  103. name: "foo",
  104. jars: ["a.jar"],
  105. compile_dex: true,
  106. prefer: false,
  107. }
  108. `)
  109. hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
  110. hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
  111. fromSourceJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
  112. android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg)
  113. prebuiltJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/dex/foo.jar"
  114. android.AssertStringDoesNotContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg)
  115. }
  116. func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
  117. result := android.GroupFixturePreparers(
  118. hiddenApiFixtureFactory,
  119. FixtureConfigureBootJars("platform:foo"),
  120. prepareForTestWithDefaultPlatformBootclasspath,
  121. ).RunTestWithBp(t, `
  122. java_library {
  123. name: "foo",
  124. srcs: ["a.java"],
  125. compile_dex: true,
  126. }
  127. java_import {
  128. name: "foo",
  129. jars: ["a.jar"],
  130. compile_dex: true,
  131. prefer: true,
  132. }
  133. `)
  134. hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
  135. hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
  136. prebuiltJarArg := "--boot-dex=out/soong/.intermediates/prebuilt_foo/android_common/dex/foo.jar"
  137. android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg)
  138. fromSourceJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
  139. android.AssertStringDoesNotContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg)
  140. }
  141. func TestHiddenAPISingletonSdks(t *testing.T) {
  142. testCases := []struct {
  143. name string
  144. unbundledBuild bool
  145. publicStub string
  146. systemStub string
  147. testStub string
  148. corePlatformStub string
  149. // Additional test preparer
  150. preparer android.FixturePreparer
  151. }{
  152. {
  153. name: "testBundled",
  154. unbundledBuild: false,
  155. publicStub: "android_stubs_current",
  156. systemStub: "android_system_stubs_current",
  157. testStub: "android_test_stubs_current",
  158. corePlatformStub: "legacy.core.platform.api.stubs",
  159. preparer: android.GroupFixturePreparers(),
  160. }, {
  161. name: "testUnbundled",
  162. unbundledBuild: true,
  163. publicStub: "sdk_public_current_android",
  164. systemStub: "sdk_system_current_android",
  165. testStub: "sdk_test_current_android",
  166. corePlatformStub: "legacy.core.platform.api.stubs",
  167. preparer: PrepareForTestWithPrebuiltsOfCurrentApi,
  168. },
  169. }
  170. for _, tc := range testCases {
  171. t.Run(tc.name, func(t *testing.T) {
  172. result := android.GroupFixturePreparers(
  173. hiddenApiFixtureFactory,
  174. tc.preparer,
  175. prepareForTestWithDefaultPlatformBootclasspath,
  176. android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
  177. variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild)
  178. }),
  179. ).RunTest(t)
  180. hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common")
  181. hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags")
  182. wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild)
  183. android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantPublicStubs)
  184. wantSystemStubs := "--system-stub-classpath=" + generateSdkDexPath(tc.systemStub, tc.unbundledBuild)
  185. android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantSystemStubs)
  186. wantTestStubs := "--test-stub-classpath=" + generateSdkDexPath(tc.testStub, tc.unbundledBuild)
  187. android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantTestStubs)
  188. wantCorePlatformStubs := "--core-platform-stub-classpath=" + generateDexPath(defaultJavaDir, tc.corePlatformStub)
  189. android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantCorePlatformStubs)
  190. })
  191. }
  192. }
  193. func generateDexedPath(subDir, dex, module string) string {
  194. return fmt.Sprintf("out/soong/.intermediates/%s/android_common/%s/%s.jar", subDir, dex, module)
  195. }
  196. func generateDexPath(moduleDir string, module string) string {
  197. return generateDexedPath(filepath.Join(moduleDir, module), "dex", module)
  198. }
  199. func generateSdkDexPath(module string, unbundled bool) string {
  200. if unbundled {
  201. return generateDexedPath("prebuilts/sdk/"+module, "dex", module)
  202. }
  203. return generateDexPath(defaultJavaDir, module)
  204. }
  205. func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) {
  206. // The idea behind this test is to ensure that when the build is
  207. // confugured with a PrebuiltHiddenApiDir that the rules for the
  208. // hiddenapi singleton copy the prebuilts to the typical output
  209. // location, and then use that output location for the hiddenapi encode
  210. // dex step.
  211. // Where to find the prebuilt hiddenapi files:
  212. prebuiltHiddenApiDir := "path/to/prebuilt/hiddenapi"
  213. result := android.GroupFixturePreparers(
  214. hiddenApiFixtureFactory,
  215. FixtureConfigureBootJars("platform:foo"),
  216. fixtureSetPrebuiltHiddenApiDirProductVariable(&prebuiltHiddenApiDir),
  217. ).RunTestWithBp(t, `
  218. java_import {
  219. name: "foo",
  220. jars: ["a.jar"],
  221. compile_dex: true,
  222. }
  223. `)
  224. expectedCpInput := prebuiltHiddenApiDir + "/hiddenapi-flags.csv"
  225. expectedCpOutput := "out/soong/hiddenapi/hiddenapi-flags.csv"
  226. expectedFlagsCsv := "out/soong/hiddenapi/hiddenapi-flags.csv"
  227. foo := result.ModuleForTests("foo", "android_common")
  228. hiddenAPI := result.SingletonForTests("hiddenapi")
  229. cpRule := hiddenAPI.Rule("Cp")
  230. actualCpInput := cpRule.BuildParams.Input
  231. actualCpOutput := cpRule.BuildParams.Output
  232. encodeDexRule := foo.Rule("hiddenAPIEncodeDex")
  233. actualFlagsCsv := encodeDexRule.BuildParams.Args["flagsCsv"]
  234. android.AssertPathRelativeToTopEquals(t, "hiddenapi cp rule input", expectedCpInput, actualCpInput)
  235. android.AssertPathRelativeToTopEquals(t, "hiddenapi cp rule output", expectedCpOutput, actualCpOutput)
  236. android.AssertStringEquals(t, "hiddenapi encode dex rule flags csv", expectedFlagsCsv, actualFlagsCsv)
  237. }
  238. func TestHiddenAPIEncoding_JavaSdkLibrary(t *testing.T) {
  239. result := android.GroupFixturePreparers(
  240. hiddenApiFixtureFactory,
  241. FixtureConfigureBootJars("platform:foo"),
  242. PrepareForTestWithJavaSdkLibraryFiles,
  243. FixtureWithLastReleaseApis("foo"),
  244. // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
  245. // is disabled.
  246. android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
  247. ).RunTestWithBp(t, `
  248. java_sdk_library {
  249. name: "foo",
  250. srcs: ["a.java"],
  251. shared_library: false,
  252. compile_dex: true,
  253. public: {enabled: true},
  254. }
  255. `)
  256. checkDexEncoded := func(t *testing.T, name, unencodedDexJar, encodedDexJar string) {
  257. moduleForTests := result.ModuleForTests(name, "android_common")
  258. encodeDexRule := moduleForTests.Rule("hiddenAPIEncodeDex")
  259. actualUnencodedDexJar := encodeDexRule.Input
  260. // Make sure that the module has its dex jar encoded.
  261. android.AssertStringEquals(t, "encode embedded java_library", unencodedDexJar, actualUnencodedDexJar.String())
  262. // Make sure that the encoded dex jar is the exported one.
  263. exportedDexJar := moduleForTests.Module().(UsesLibraryDependency).DexJarBuildPath().Path()
  264. android.AssertPathRelativeToTopEquals(t, "encode embedded java_library", encodedDexJar, exportedDexJar)
  265. }
  266. // The java_library embedded with the java_sdk_library must be dex encoded.
  267. t.Run("foo", func(t *testing.T) {
  268. expectedUnencodedDexJar := "out/soong/.intermediates/foo/android_common/aligned/foo.jar"
  269. expectedEncodedDexJar := "out/soong/.intermediates/foo/android_common/hiddenapi/foo.jar"
  270. checkDexEncoded(t, "foo", expectedUnencodedDexJar, expectedEncodedDexJar)
  271. })
  272. // The dex jar of the child implementation java_library of the java_sdk_library is not currently
  273. // dex encoded.
  274. t.Run("foo.impl", func(t *testing.T) {
  275. fooImpl := result.ModuleForTests("foo.impl", "android_common")
  276. encodeDexRule := fooImpl.MaybeRule("hiddenAPIEncodeDex")
  277. if encodeDexRule.Rule != nil {
  278. t.Errorf("foo.impl is not expected to be encoded")
  279. }
  280. })
  281. }