blob: 7209c027592dd1aaff93729315b27312d25bc2b5 [file] [log] [blame]
Paul Duffinb432df92021-03-22 22:09:42 +00001// 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
15package apex
16
17import (
Paul Duffinffa83752021-06-09 14:32:53 +010018 "fmt"
19 "strings"
Paul Duffinb432df92021-03-22 22:09:42 +000020 "testing"
21
22 "android/soong/android"
Paul Duffinb432df92021-03-22 22:09:42 +000023 "android/soong/java"
24 "github.com/google/blueprint"
Paul Duffin7487a7a2021-05-19 09:36:09 +010025 "github.com/google/blueprint/proptools"
Paul Duffinb432df92021-03-22 22:09:42 +000026)
27
28// Contains tests for platform_bootclasspath logic from java/platform_bootclasspath.go that requires
29// apexes.
30
31var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
32 java.PrepareForTestWithDexpreopt,
33 PrepareForTestWithApexBuildComponents,
34)
35
Paul Duffinffa83752021-06-09 14:32:53 +010036func TestPlatformBootclasspath_Fragments(t *testing.T) {
37 result := android.GroupFixturePreparers(
38 prepareForTestWithPlatformBootclasspath,
Paul Duffindc3f9562021-06-09 15:31:05 +010039 prepareForTestWithMyapex,
Paul Duffinffa83752021-06-09 14:32:53 +010040 java.PrepareForTestWithJavaSdkLibraryFiles,
41 java.FixtureWithLastReleaseApis("foo"),
Paul Duffindc3f9562021-06-09 15:31:05 +010042 java.FixtureConfigureBootJars("myapex:bar"),
Paul Duffinffa83752021-06-09 14:32:53 +010043 android.FixtureWithRootAndroidBp(`
44 platform_bootclasspath {
45 name: "platform-bootclasspath",
46 fragments: [
Paul Duffindc3f9562021-06-09 15:31:05 +010047 {
48 apex: "myapex",
49 module:"bar-fragment",
50 },
Paul Duffinffa83752021-06-09 14:32:53 +010051 ],
52 hidden_api: {
53 unsupported: [
54 "unsupported.txt",
55 ],
56 removed: [
57 "removed.txt",
58 ],
59 max_target_r_low_priority: [
60 "max-target-r-low-priority.txt",
61 ],
62 max_target_q: [
63 "max-target-q.txt",
64 ],
65 max_target_p: [
66 "max-target-p.txt",
67 ],
68 max_target_o_low_priority: [
69 "max-target-o-low-priority.txt",
70 ],
71 blocked: [
72 "blocked.txt",
73 ],
74 unsupported_packages: [
75 "unsupported-packages.txt",
76 ],
77 },
78 }
79
Paul Duffindc3f9562021-06-09 15:31:05 +010080 apex {
81 name: "myapex",
82 key: "myapex.key",
83 bootclasspath_fragments: [
84 "bar-fragment",
85 ],
86 updatable: false,
87 }
88
89 apex_key {
90 name: "myapex.key",
91 public_key: "testkey.avbpubkey",
92 private_key: "testkey.pem",
93 }
94
Paul Duffinffa83752021-06-09 14:32:53 +010095 bootclasspath_fragment {
96 name: "bar-fragment",
97 contents: ["bar"],
Paul Duffindc3f9562021-06-09 15:31:05 +010098 apex_available: ["myapex"],
Paul Duffinffa83752021-06-09 14:32:53 +010099 api: {
100 stub_libs: ["foo"],
101 },
102 hidden_api: {
103 unsupported: [
104 "bar-unsupported.txt",
105 ],
106 removed: [
107 "bar-removed.txt",
108 ],
109 max_target_r_low_priority: [
110 "bar-max-target-r-low-priority.txt",
111 ],
112 max_target_q: [
113 "bar-max-target-q.txt",
114 ],
115 max_target_p: [
116 "bar-max-target-p.txt",
117 ],
118 max_target_o_low_priority: [
119 "bar-max-target-o-low-priority.txt",
120 ],
121 blocked: [
122 "bar-blocked.txt",
123 ],
124 unsupported_packages: [
125 "bar-unsupported-packages.txt",
126 ],
127 },
128 }
129
130 java_library {
131 name: "bar",
Paul Duffindc3f9562021-06-09 15:31:05 +0100132 apex_available: ["myapex"],
Paul Duffinffa83752021-06-09 14:32:53 +0100133 srcs: ["a.java"],
134 system_modules: "none",
135 sdk_version: "none",
136 compile_dex: true,
Paul Duffindc3f9562021-06-09 15:31:05 +0100137 permitted_packages: ["bar"],
Paul Duffinffa83752021-06-09 14:32:53 +0100138 }
139
140 java_sdk_library {
141 name: "foo",
142 srcs: ["a.java"],
143 public: {
144 enabled: true,
145 },
146 compile_dex: true,
147 }
148 `),
149 ).RunTest(t)
150
151 pbcp := result.Module("platform-bootclasspath", "android_common")
152 info := result.ModuleProvider(pbcp, java.MonolithicHiddenAPIInfoProvider).(java.MonolithicHiddenAPIInfo)
153
154 for _, category := range java.HiddenAPIFlagFileCategories {
155 name := category.PropertyName
156 message := fmt.Sprintf("category %s", name)
157 filename := strings.ReplaceAll(name, "_", "-")
158 expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)}
159 android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category])
160 }
161
Paul Duffindc3f9562021-06-09 15:31:05 +0100162 android.AssertPathsRelativeToTopEquals(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/stub-flags.csv"}, info.StubFlagsPaths)
163 android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
164 android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
165 android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/index.csv"}, info.IndexPaths)
166 android.AssertPathsRelativeToTopEquals(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/all-flags.csv"}, info.AllFlagsPaths)
Paul Duffinffa83752021-06-09 14:32:53 +0100167}
168
Paul Duffinb432df92021-03-22 22:09:42 +0000169func TestPlatformBootclasspathDependencies(t *testing.T) {
170 result := android.GroupFixturePreparers(
171 prepareForTestWithPlatformBootclasspath,
172 prepareForTestWithArtApex,
173 prepareForTestWithMyapex,
174 // Configure some libraries in the art and framework boot images.
Paul Duffin60264a02021-04-12 20:02:36 +0100175 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"),
176 java.FixtureConfigureUpdatableBootJars("myapex:bar"),
Paul Duffinb432df92021-03-22 22:09:42 +0000177 java.PrepareForTestWithJavaSdkLibraryFiles,
178 java.FixtureWithLastReleaseApis("foo"),
179 ).RunTestWithBp(t, `
180 apex {
181 name: "com.android.art",
182 key: "com.android.art.key",
183 bootclasspath_fragments: [
184 "art-bootclasspath-fragment",
185 ],
186 updatable: false,
187 }
188
189 apex_key {
190 name: "com.android.art.key",
191 public_key: "com.android.art.avbpubkey",
192 private_key: "com.android.art.pem",
193 }
194
195 bootclasspath_fragment {
196 name: "art-bootclasspath-fragment",
197 apex_available: [
198 "com.android.art",
199 ],
200 contents: [
201 "baz",
202 "quuz",
203 ],
204 }
205
206 java_library {
207 name: "baz",
208 apex_available: [
209 "com.android.art",
210 ],
211 srcs: ["b.java"],
212 installable: true,
213 }
214
215 // Add a java_import that is not preferred and so won't have an appropriate apex variant created
216 // for it to make sure that the platform_bootclasspath doesn't try and add a dependency onto it.
217 java_import {
218 name: "baz",
219 apex_available: [
220 "com.android.art",
221 ],
222 jars: ["b.jar"],
223 }
224
225 java_library {
226 name: "quuz",
227 apex_available: [
228 "com.android.art",
229 ],
230 srcs: ["b.java"],
231 installable: true,
232 }
233
234 apex {
235 name: "myapex",
236 key: "myapex.key",
Paul Duffin89f570a2021-06-16 01:42:33 +0100237 bootclasspath_fragments: [
238 "my-bootclasspath-fragment",
Paul Duffinb432df92021-03-22 22:09:42 +0000239 ],
240 updatable: false,
241 }
242
Paul Duffin89f570a2021-06-16 01:42:33 +0100243 bootclasspath_fragment {
244 name: "my-bootclasspath-fragment",
245 contents: ["bar"],
246 apex_available: ["myapex"],
247 }
248
Paul Duffinb432df92021-03-22 22:09:42 +0000249 apex_key {
250 name: "myapex.key",
251 public_key: "testkey.avbpubkey",
252 private_key: "testkey.pem",
253 }
254
255 java_sdk_library {
256 name: "foo",
257 srcs: ["b.java"],
258 }
259
260 java_library {
261 name: "bar",
262 srcs: ["b.java"],
263 installable: true,
264 apex_available: ["myapex"],
265 permitted_packages: ["bar"],
266 }
267
268 platform_bootclasspath {
269 name: "myplatform-bootclasspath",
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100270
271 fragments: [
272 {
273 apex: "com.android.art",
274 module: "art-bootclasspath-fragment",
275 },
Paul Duffin89f570a2021-06-16 01:42:33 +0100276 {
277 apex: "myapex",
278 module: "my-bootclasspath-fragment",
279 },
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100280 ],
Paul Duffinb432df92021-03-22 22:09:42 +0000281 }
282`,
283 )
284
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100285 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
Paul Duffin74431d52021-04-21 14:10:42 +0100286 // The configured contents of BootJars.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100287 "com.android.art:baz",
288 "com.android.art:quuz",
289 "platform:foo",
Paul Duffin74431d52021-04-21 14:10:42 +0100290
291 // The configured contents of UpdatableBootJars.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100292 "myapex:bar",
293 })
294
295 java.CheckPlatformBootclasspathFragments(t, result, "myplatform-bootclasspath", []string{
Paul Duffin89f570a2021-06-16 01:42:33 +0100296 "com.android.art:art-bootclasspath-fragment",
297 "myapex:my-bootclasspath-fragment",
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100298 })
299
Paul Duffinb432df92021-03-22 22:09:42 +0000300 // Make sure that the myplatform-bootclasspath has the correct dependencies.
301 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
Paul Duffin74431d52021-04-21 14:10:42 +0100302 // The following are stubs.
303 `platform:android_stubs_current`,
304 `platform:android_system_stubs_current`,
305 `platform:android_test_stubs_current`,
306 `platform:legacy.core.platform.api.stubs`,
307
308 // Needed for generating the boot image.
Paul Duffinb432df92021-03-22 22:09:42 +0000309 `platform:dex2oatd`,
Paul Duffin74431d52021-04-21 14:10:42 +0100310
311 // The configured contents of BootJars.
Paul Duffinb432df92021-03-22 22:09:42 +0000312 `com.android.art:baz`,
313 `com.android.art:quuz`,
314 `platform:foo`,
Paul Duffin74431d52021-04-21 14:10:42 +0100315
316 // The configured contents of UpdatableBootJars.
Paul Duffinb432df92021-03-22 22:09:42 +0000317 `myapex:bar`,
Paul Duffin74431d52021-04-21 14:10:42 +0100318
319 // The fragments.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100320 `com.android.art:art-bootclasspath-fragment`,
Paul Duffin89f570a2021-06-16 01:42:33 +0100321 `myapex:my-bootclasspath-fragment`,
Paul Duffinb432df92021-03-22 22:09:42 +0000322 })
323}
324
Paul Duffin7487a7a2021-05-19 09:36:09 +0100325// TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when
326// AlwaysUsePrebuiltSdk() returns true. The structure of the modules in this test matches what
327// currently exists in some places in the Android build but it is not the intended structure. It is
328// in fact an invalid structure that should cause build failures. However, fixing that structure
329// will take too long so in the meantime this tests the workarounds to avoid build breakages.
330//
331// The main issues with this structure are:
332// 1. There is no prebuilt_bootclasspath_fragment referencing the "foo" java_sdk_library_import.
333// 2. There is no prebuilt_apex/apex_set which makes the dex implementation jar available to the
334// prebuilt_bootclasspath_fragment and the "foo" java_sdk_library_import.
335//
336// Together these cause the following symptoms:
337// 1. The "foo" java_sdk_library_import does not have a dex implementation jar.
338// 2. The "foo" java_sdk_library_import does not have a myapex variant.
339//
340// TODO(b/179354495): Fix the structure in this test once the main Android build has been fixed.
341func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
342 result := android.GroupFixturePreparers(
343 prepareForTestWithPlatformBootclasspath,
344 prepareForTestWithMyapex,
345 // Configure two libraries, the first is a java_sdk_library whose prebuilt will be used because
346 // of AlwaysUsePrebuiltsSdk() but does not have an appropriate apex variant and does not provide
347 // a boot dex jar. The second is a normal library that is unaffected. The order matters because
348 // if the dependency on myapex:foo is filtered out because of either of those conditions then
349 // the dependencies resolved by the platform_bootclasspath will not match the configured list
350 // and so will fail the test.
351 java.FixtureConfigureUpdatableBootJars("myapex:foo", "myapex:bar"),
352 java.PrepareForTestWithJavaSdkLibraryFiles,
353 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
354 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
355 }),
356 java.FixtureWithPrebuiltApis(map[string][]string{
357 "current": {},
358 "30": {"foo"},
359 }),
360 ).RunTestWithBp(t, `
361 apex {
362 name: "myapex",
363 key: "myapex.key",
364 bootclasspath_fragments: [
365 "mybootclasspath-fragment",
366 ],
367 updatable: false,
368 }
369
370 apex_key {
371 name: "myapex.key",
372 public_key: "testkey.avbpubkey",
373 private_key: "testkey.pem",
374 }
375
376 java_library {
377 name: "bar",
378 srcs: ["b.java"],
379 installable: true,
380 apex_available: ["myapex"],
381 permitted_packages: ["bar"],
382 }
383
384 java_sdk_library {
385 name: "foo",
386 srcs: ["b.java"],
387 shared_library: false,
388 public: {
389 enabled: true,
390 },
391 apex_available: ["myapex"],
392 permitted_packages: ["foo"],
393 }
394
395 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
396 // because AlwaysUsePrebuiltSdks() is true.
397 java_sdk_library_import {
398 name: "foo",
399 prefer: false,
400 shared_library: false,
Paul Duffin630b11e2021-07-15 13:35:26 +0100401 permitted_packages: ["foo"],
Paul Duffin7487a7a2021-05-19 09:36:09 +0100402 public: {
403 jars: ["sdk_library/public/foo-stubs.jar"],
404 stub_srcs: ["sdk_library/public/foo_stub_sources"],
405 current_api: "sdk_library/public/foo.txt",
406 removed_api: "sdk_library/public/foo-removed.txt",
407 sdk_version: "current",
408 },
409 apex_available: ["myapex"],
410 }
411
412 // This always depends on the source foo module, its dependencies are not affected by the
413 // AlwaysUsePrebuiltSdks().
414 bootclasspath_fragment {
415 name: "mybootclasspath-fragment",
416 apex_available: [
417 "myapex",
418 ],
419 contents: [
420 "foo", "bar",
421 ],
422 }
423
424 platform_bootclasspath {
425 name: "myplatform-bootclasspath",
Paul Duffin89f570a2021-06-16 01:42:33 +0100426 fragments: [
427 {
428 apex: "myapex",
429 module:"mybootclasspath-fragment",
430 },
431 ],
Paul Duffin7487a7a2021-05-19 09:36:09 +0100432 }
433`,
434 )
435
436 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
437 // The configured contents of BootJars.
438 "platform:prebuilt_foo", // Note: This is the platform not myapex variant.
439 "myapex:bar",
440 })
441
442 // Make sure that the myplatform-bootclasspath has the correct dependencies.
443 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
444 // The following are stubs.
445 "platform:prebuilt_sdk_public_current_android",
446 "platform:prebuilt_sdk_system_current_android",
447 "platform:prebuilt_sdk_test_current_android",
448
449 // Not a prebuilt as no prebuilt existed when it was added.
450 "platform:legacy.core.platform.api.stubs",
451
452 // Needed for generating the boot image.
Paul Duffin89f570a2021-06-16 01:42:33 +0100453 "platform:dex2oatd",
Paul Duffin7487a7a2021-05-19 09:36:09 +0100454
455 // The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
456 // modules when available as it does not know which one will be preferred.
457 //
458 // The source module has an APEX variant but the prebuilt does not.
459 "myapex:foo",
460 "platform:prebuilt_foo",
461
462 // Only a source module exists.
463 "myapex:bar",
Paul Duffin89f570a2021-06-16 01:42:33 +0100464
465 // The fragments.
466 "myapex:mybootclasspath-fragment",
Paul Duffin7487a7a2021-05-19 09:36:09 +0100467 })
468}
469
Paul Duffinb432df92021-03-22 22:09:42 +0000470// CheckModuleDependencies checks the dependencies of the selected module against the expected list.
471//
472// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
473// name of the apex, or platform is it is not part of an apex and <module> is the module name.
474func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
475 t.Helper()
476 module := ctx.ModuleForTests(name, variant).Module()
477 modules := []android.Module{}
478 ctx.VisitDirectDeps(module, func(m blueprint.Module) {
479 modules = append(modules, m.(android.Module))
480 })
481
482 pairs := java.ApexNamePairsFromModules(ctx, modules)
483 android.AssertDeepEquals(t, "module dependencies", expected, pairs)
484}
satayevb3090502021-06-15 17:49:10 +0100485
486// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in
487// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config
488// by setting generate_classpaths_proto property to false.
489func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) {
490 result := android.GroupFixturePreparers(
491 prepareForTestWithPlatformBootclasspath,
492 prepareForTestWithMyapex,
493 java.FixtureConfigureUpdatableBootJars("myapex:foo"),
494 android.FixtureWithRootAndroidBp(`
495 platform_bootclasspath {
496 name: "platform-bootclasspath",
497 fragments: [
498 {
499 apex: "myapex",
500 module:"foo-fragment",
501 },
502 ],
503 }
504
505 apex {
506 name: "myapex",
507 key: "myapex.key",
508 bootclasspath_fragments: ["foo-fragment"],
509 updatable: false,
510 }
511
512 apex_key {
513 name: "myapex.key",
514 public_key: "testkey.avbpubkey",
515 private_key: "testkey.pem",
516 }
517
518 bootclasspath_fragment {
519 name: "foo-fragment",
520 generate_classpaths_proto: false,
521 contents: ["foo"],
522 apex_available: ["myapex"],
523 }
524
525 java_library {
526 name: "foo",
527 srcs: ["a.java"],
528 system_modules: "none",
529 sdk_version: "none",
530 compile_dex: true,
531 apex_available: ["myapex"],
532 permitted_packages: ["foo"],
533 }
534 `),
535 ).RunTest(t)
536
537 java.CheckClasspathFragmentProtoContentInfoProvider(t, result,
538 true, // proto should be generated
539 "myapex:foo", // apex doesn't generate its own config, so must be in platform_bootclasspath
540 "bootclasspath.pb",
541 "out/soong/target/product/test_device/system/etc/classpaths",
542 )
543}