bootclasspath_fragment_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. // Copyright (C) 2021 The Android Open Source Project
  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. "strings"
  17. "testing"
  18. "android/soong/android"
  19. "android/soong/dexpreopt"
  20. )
  21. // Contains some simple tests for bootclasspath_fragment logic, additional tests can be found in
  22. // apex/bootclasspath_fragment_test.go as the ART boot image requires modules from the ART apex.
  23. var prepareForTestWithBootclasspathFragment = android.GroupFixturePreparers(
  24. PrepareForTestWithJavaDefaultModules,
  25. dexpreopt.PrepareForTestByEnablingDexpreopt,
  26. )
  27. func TestBootclasspathFragment_UnknownImageName(t *testing.T) {
  28. prepareForTestWithBootclasspathFragment.
  29. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
  30. `\Qimage_name: unknown image name "unknown", expected "art"\E`)).
  31. RunTestWithBp(t, `
  32. bootclasspath_fragment {
  33. name: "unknown-bootclasspath-fragment",
  34. image_name: "unknown",
  35. contents: ["foo"],
  36. }
  37. `)
  38. }
  39. func TestPrebuiltBootclasspathFragment_UnknownImageName(t *testing.T) {
  40. prepareForTestWithBootclasspathFragment.
  41. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
  42. `\Qimage_name: unknown image name "unknown", expected "art"\E`)).
  43. RunTestWithBp(t, `
  44. prebuilt_bootclasspath_fragment {
  45. name: "unknown-bootclasspath-fragment",
  46. image_name: "unknown",
  47. contents: ["foo"],
  48. }
  49. `)
  50. }
  51. func TestBootclasspathFragmentInconsistentArtConfiguration_Platform(t *testing.T) {
  52. android.GroupFixturePreparers(
  53. prepareForTestWithBootclasspathFragment,
  54. dexpreopt.FixtureSetArtBootJars("platform:foo", "apex:bar"),
  55. ).
  56. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
  57. `\QArtApexJars is invalid as it requests a platform variant of "foo"\E`)).
  58. RunTestWithBp(t, `
  59. bootclasspath_fragment {
  60. name: "bootclasspath-fragment",
  61. image_name: "art",
  62. contents: ["foo", "bar"],
  63. apex_available: [
  64. "apex",
  65. ],
  66. }
  67. `)
  68. }
  69. func TestBootclasspathFragmentInconsistentArtConfiguration_ApexMixture(t *testing.T) {
  70. android.GroupFixturePreparers(
  71. prepareForTestWithBootclasspathFragment,
  72. dexpreopt.FixtureSetArtBootJars("apex1:foo", "apex2:bar"),
  73. ).
  74. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
  75. `\QArtApexJars configuration is inconsistent, expected all jars to be in the same apex but it specifies apex "apex1" and "apex2"\E`)).
  76. RunTestWithBp(t, `
  77. bootclasspath_fragment {
  78. name: "bootclasspath-fragment",
  79. image_name: "art",
  80. contents: ["foo", "bar"],
  81. apex_available: [
  82. "apex1",
  83. "apex2",
  84. ],
  85. }
  86. `)
  87. }
  88. func TestBootclasspathFragment_Coverage(t *testing.T) {
  89. prepareWithBp := android.FixtureWithRootAndroidBp(`
  90. bootclasspath_fragment {
  91. name: "myfragment",
  92. contents: [
  93. "mybootlib",
  94. ],
  95. api: {
  96. stub_libs: [
  97. "mysdklibrary",
  98. ],
  99. },
  100. coverage: {
  101. contents: [
  102. "coveragelib",
  103. ],
  104. api: {
  105. stub_libs: [
  106. "mycoveragestubs",
  107. ],
  108. },
  109. },
  110. hidden_api: {
  111. split_packages: ["*"],
  112. },
  113. }
  114. java_library {
  115. name: "mybootlib",
  116. srcs: ["Test.java"],
  117. system_modules: "none",
  118. sdk_version: "none",
  119. compile_dex: true,
  120. }
  121. java_library {
  122. name: "coveragelib",
  123. srcs: ["Test.java"],
  124. system_modules: "none",
  125. sdk_version: "none",
  126. compile_dex: true,
  127. }
  128. java_sdk_library {
  129. name: "mysdklibrary",
  130. srcs: ["Test.java"],
  131. compile_dex: true,
  132. public: {enabled: true},
  133. system: {enabled: true},
  134. }
  135. java_sdk_library {
  136. name: "mycoveragestubs",
  137. srcs: ["Test.java"],
  138. compile_dex: true,
  139. public: {enabled: true},
  140. }
  141. `)
  142. checkContents := func(t *testing.T, result *android.TestResult, expected ...string) {
  143. module := result.Module("myfragment", "android_common").(*BootclasspathFragmentModule)
  144. android.AssertArrayString(t, "contents property", expected, module.properties.Contents)
  145. }
  146. preparer := android.GroupFixturePreparers(
  147. prepareForTestWithBootclasspathFragment,
  148. PrepareForTestWithJavaSdkLibraryFiles,
  149. FixtureWithLastReleaseApis("mysdklibrary", "mycoveragestubs"),
  150. FixtureConfigureApexBootJars("someapex:mybootlib"),
  151. prepareWithBp,
  152. )
  153. t.Run("without coverage", func(t *testing.T) {
  154. result := preparer.RunTest(t)
  155. checkContents(t, result, "mybootlib")
  156. })
  157. t.Run("with coverage", func(t *testing.T) {
  158. result := android.GroupFixturePreparers(
  159. prepareForTestWithFrameworkJacocoInstrumentation,
  160. preparer,
  161. ).RunTest(t)
  162. checkContents(t, result, "mybootlib", "coveragelib")
  163. })
  164. }
  165. func TestBootclasspathFragment_StubLibs(t *testing.T) {
  166. result := android.GroupFixturePreparers(
  167. prepareForTestWithBootclasspathFragment,
  168. PrepareForTestWithJavaSdkLibraryFiles,
  169. FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary", "mycoreplatform"),
  170. FixtureConfigureApexBootJars("someapex:mysdklibrary"),
  171. ).RunTestWithBp(t, `
  172. bootclasspath_fragment {
  173. name: "myfragment",
  174. contents: ["mysdklibrary"],
  175. api: {
  176. stub_libs: [
  177. "mystublib",
  178. "myothersdklibrary",
  179. ],
  180. },
  181. core_platform_api: {
  182. stub_libs: ["mycoreplatform.stubs"],
  183. },
  184. hidden_api: {
  185. split_packages: ["*"],
  186. },
  187. }
  188. java_library {
  189. name: "mystublib",
  190. srcs: ["Test.java"],
  191. system_modules: "none",
  192. sdk_version: "none",
  193. compile_dex: true,
  194. }
  195. java_sdk_library {
  196. name: "mysdklibrary",
  197. srcs: ["a.java"],
  198. shared_library: false,
  199. public: {enabled: true},
  200. system: {enabled: true},
  201. }
  202. java_sdk_library {
  203. name: "myothersdklibrary",
  204. srcs: ["a.java"],
  205. shared_library: false,
  206. public: {enabled: true},
  207. }
  208. java_sdk_library {
  209. name: "mycoreplatform",
  210. srcs: ["a.java"],
  211. shared_library: false,
  212. public: {enabled: true},
  213. }
  214. `)
  215. fragment := result.Module("myfragment", "android_common")
  216. info := result.ModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo)
  217. stubsJar := "out/soong/.intermediates/mystublib/android_common/dex/mystublib.jar"
  218. // Stubs jars for mysdklibrary
  219. publicStubsJar := "out/soong/.intermediates/mysdklibrary.stubs/android_common/dex/mysdklibrary.stubs.jar"
  220. systemStubsJar := "out/soong/.intermediates/mysdklibrary.stubs.system/android_common/dex/mysdklibrary.stubs.system.jar"
  221. // Stubs jars for myothersdklibrary
  222. otherPublicStubsJar := "out/soong/.intermediates/myothersdklibrary.stubs/android_common/dex/myothersdklibrary.stubs.jar"
  223. // Check that SdkPublic uses public stubs for all sdk libraries.
  224. android.AssertPathsRelativeToTopEquals(t, "public dex stubs jar", []string{otherPublicStubsJar, publicStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(PublicHiddenAPIScope))
  225. // Check that SdkSystem uses system stubs for mysdklibrary and public stubs for myothersdklibrary
  226. // as it does not provide system stubs.
  227. android.AssertPathsRelativeToTopEquals(t, "system dex stubs jar", []string{otherPublicStubsJar, systemStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(SystemHiddenAPIScope))
  228. // Check that SdkTest also uses system stubs for mysdklibrary as it does not provide test stubs
  229. // and public stubs for myothersdklibrary as it does not provide test stubs either.
  230. android.AssertPathsRelativeToTopEquals(t, "test dex stubs jar", []string{otherPublicStubsJar, systemStubsJar, stubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(TestHiddenAPIScope))
  231. // Check that SdkCorePlatform uses public stubs from the mycoreplatform library.
  232. corePlatformStubsJar := "out/soong/.intermediates/mycoreplatform.stubs/android_common/dex/mycoreplatform.stubs.jar"
  233. android.AssertPathsRelativeToTopEquals(t, "core platform dex stubs jar", []string{corePlatformStubsJar}, info.TransitiveStubDexJarsByScope.StubDexJarsForScope(CorePlatformHiddenAPIScope))
  234. // Check the widest stubs.. The list contains the widest stub dex jar provided by each module.
  235. expectedWidestPaths := []string{
  236. // mycoreplatform's widest API is core platform.
  237. corePlatformStubsJar,
  238. // myothersdklibrary's widest API is public.
  239. otherPublicStubsJar,
  240. // sdklibrary's widest API is system.
  241. systemStubsJar,
  242. // mystublib's only provides one API and so it must be the widest.
  243. stubsJar,
  244. }
  245. android.AssertPathsRelativeToTopEquals(t, "widest dex stubs jar", expectedWidestPaths, info.TransitiveStubDexJarsByScope.StubDexJarsForWidestAPIScope())
  246. }
  247. func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) {
  248. result := android.GroupFixturePreparers(
  249. prepareForTestWithBootclasspathFragment,
  250. PrepareForTestWithJavaSdkLibraryFiles,
  251. FixtureWithLastReleaseApis("mysdklibrary", "mynewlibrary"),
  252. FixtureConfigureApexBootJars("myapex:mybootlib", "myapex:mynewlibrary"),
  253. android.MockFS{
  254. "my-blocked.txt": nil,
  255. "my-max-target-o-low-priority.txt": nil,
  256. "my-max-target-p.txt": nil,
  257. "my-max-target-q.txt": nil,
  258. "my-max-target-r-low-priority.txt": nil,
  259. "my-removed.txt": nil,
  260. "my-unsupported-packages.txt": nil,
  261. "my-unsupported.txt": nil,
  262. "my-new-max-target-q.txt": nil,
  263. }.AddToFixture(),
  264. android.FixtureWithRootAndroidBp(`
  265. bootclasspath_fragment {
  266. name: "mybootclasspathfragment",
  267. apex_available: ["myapex"],
  268. contents: ["mybootlib", "mynewlibrary"],
  269. hidden_api: {
  270. unsupported: [
  271. "my-unsupported.txt",
  272. ],
  273. removed: [
  274. "my-removed.txt",
  275. ],
  276. max_target_r_low_priority: [
  277. "my-max-target-r-low-priority.txt",
  278. ],
  279. max_target_q: [
  280. "my-max-target-q.txt",
  281. ],
  282. max_target_p: [
  283. "my-max-target-p.txt",
  284. ],
  285. max_target_o_low_priority: [
  286. "my-max-target-o-low-priority.txt",
  287. ],
  288. blocked: [
  289. "my-blocked.txt",
  290. ],
  291. unsupported_packages: [
  292. "my-unsupported-packages.txt",
  293. ],
  294. split_packages: ["sdklibrary"],
  295. package_prefixes: ["sdklibrary.all.mine"],
  296. single_packages: ["sdklibrary.mine"],
  297. },
  298. }
  299. java_library {
  300. name: "mybootlib",
  301. apex_available: ["myapex"],
  302. srcs: ["Test.java"],
  303. system_modules: "none",
  304. sdk_version: "none",
  305. min_sdk_version: "1",
  306. compile_dex: true,
  307. permitted_packages: ["mybootlib"],
  308. }
  309. java_sdk_library {
  310. name: "mynewlibrary",
  311. apex_available: ["myapex"],
  312. srcs: ["Test.java"],
  313. min_sdk_version: "10",
  314. compile_dex: true,
  315. public: {enabled: true},
  316. permitted_packages: ["mysdklibrary"],
  317. hidden_api: {
  318. max_target_q: [
  319. "my-new-max-target-q.txt",
  320. ],
  321. split_packages: ["sdklibrary", "newlibrary"],
  322. package_prefixes: ["newlibrary.all.mine"],
  323. single_packages: ["newlibrary.mine"],
  324. },
  325. }
  326. `),
  327. ).RunTest(t)
  328. // Make sure that the library exports hidden API properties for use by the bootclasspath_fragment.
  329. library := result.Module("mynewlibrary", "android_common")
  330. info := result.ModuleProvider(library, hiddenAPIPropertyInfoProvider).(HiddenAPIPropertyInfo)
  331. android.AssertArrayString(t, "split packages", []string{"sdklibrary", "newlibrary"}, info.SplitPackages)
  332. android.AssertArrayString(t, "package prefixes", []string{"newlibrary.all.mine"}, info.PackagePrefixes)
  333. android.AssertArrayString(t, "single packages", []string{"newlibrary.mine"}, info.SinglePackages)
  334. for _, c := range HiddenAPIFlagFileCategories {
  335. expectedMaxTargetQPaths := []string(nil)
  336. if c.PropertyName == "max_target_q" {
  337. expectedMaxTargetQPaths = []string{"my-new-max-target-q.txt"}
  338. }
  339. android.AssertPathsRelativeToTopEquals(t, c.PropertyName, expectedMaxTargetQPaths, info.FlagFilesByCategory[c])
  340. }
  341. // Make sure that the signature-patterns.csv is passed all the appropriate package properties
  342. // from the bootclasspath_fragment and its contents.
  343. fragment := result.ModuleForTests("mybootclasspathfragment", "android_common")
  344. rule := fragment.Output("modular-hiddenapi/signature-patterns.csv")
  345. expectedCommand := strings.Join([]string{
  346. "--split-package newlibrary",
  347. "--split-package sdklibrary",
  348. "--package-prefix newlibrary.all.mine",
  349. "--package-prefix sdklibrary.all.mine",
  350. "--single-package newlibrary.mine",
  351. "--single-package sdklibrary",
  352. }, " ")
  353. android.AssertStringDoesContain(t, "signature patterns command", rule.RuleParams.Command, expectedCommand)
  354. }
  355. func TestBootclasspathFragment_Test(t *testing.T) {
  356. result := android.GroupFixturePreparers(
  357. prepareForTestWithBootclasspathFragment,
  358. PrepareForTestWithJavaSdkLibraryFiles,
  359. FixtureWithLastReleaseApis("mysdklibrary"),
  360. ).RunTestWithBp(t, `
  361. bootclasspath_fragment {
  362. name: "myfragment",
  363. contents: ["mysdklibrary"],
  364. hidden_api: {
  365. split_packages: [],
  366. },
  367. }
  368. bootclasspath_fragment_test {
  369. name: "a_test_fragment",
  370. contents: ["mysdklibrary"],
  371. hidden_api: {
  372. split_packages: [],
  373. },
  374. }
  375. java_sdk_library {
  376. name: "mysdklibrary",
  377. srcs: ["a.java"],
  378. shared_library: false,
  379. public: {enabled: true},
  380. system: {enabled: true},
  381. }
  382. `)
  383. fragment := result.Module("myfragment", "android_common").(*BootclasspathFragmentModule)
  384. android.AssertBoolEquals(t, "not a test fragment", false, fragment.isTestFragment())
  385. fragment = result.Module("a_test_fragment", "android_common").(*BootclasspathFragmentModule)
  386. android.AssertBoolEquals(t, "is a test fragment by type", true, fragment.isTestFragment())
  387. }