blob: ce12f4635c8a733bad87bcd7573f1caff686190c [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 (
18 "testing"
19
20 "android/soong/android"
Paul Duffinb432df92021-03-22 22:09:42 +000021 "android/soong/java"
22 "github.com/google/blueprint"
Paul Duffin7487a7a2021-05-19 09:36:09 +010023 "github.com/google/blueprint/proptools"
Paul Duffinb432df92021-03-22 22:09:42 +000024)
25
26// Contains tests for platform_bootclasspath logic from java/platform_bootclasspath.go that requires
27// apexes.
28
29var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
30 java.PrepareForTestWithDexpreopt,
31 PrepareForTestWithApexBuildComponents,
32)
33
34func TestPlatformBootclasspathDependencies(t *testing.T) {
35 result := android.GroupFixturePreparers(
36 prepareForTestWithPlatformBootclasspath,
37 prepareForTestWithArtApex,
38 prepareForTestWithMyapex,
39 // Configure some libraries in the art and framework boot images.
Paul Duffin60264a02021-04-12 20:02:36 +010040 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"),
41 java.FixtureConfigureUpdatableBootJars("myapex:bar"),
Paul Duffinb432df92021-03-22 22:09:42 +000042 java.PrepareForTestWithJavaSdkLibraryFiles,
43 java.FixtureWithLastReleaseApis("foo"),
44 ).RunTestWithBp(t, `
45 apex {
46 name: "com.android.art",
47 key: "com.android.art.key",
48 bootclasspath_fragments: [
49 "art-bootclasspath-fragment",
50 ],
51 updatable: false,
52 }
53
54 apex_key {
55 name: "com.android.art.key",
56 public_key: "com.android.art.avbpubkey",
57 private_key: "com.android.art.pem",
58 }
59
60 bootclasspath_fragment {
61 name: "art-bootclasspath-fragment",
62 apex_available: [
63 "com.android.art",
64 ],
65 contents: [
66 "baz",
67 "quuz",
68 ],
69 }
70
71 java_library {
72 name: "baz",
73 apex_available: [
74 "com.android.art",
75 ],
76 srcs: ["b.java"],
77 installable: true,
78 }
79
80 // Add a java_import that is not preferred and so won't have an appropriate apex variant created
81 // for it to make sure that the platform_bootclasspath doesn't try and add a dependency onto it.
82 java_import {
83 name: "baz",
84 apex_available: [
85 "com.android.art",
86 ],
87 jars: ["b.jar"],
88 }
89
90 java_library {
91 name: "quuz",
92 apex_available: [
93 "com.android.art",
94 ],
95 srcs: ["b.java"],
96 installable: true,
97 }
98
99 apex {
100 name: "myapex",
101 key: "myapex.key",
102 java_libs: [
103 "bar",
104 ],
105 updatable: false,
106 }
107
108 apex_key {
109 name: "myapex.key",
110 public_key: "testkey.avbpubkey",
111 private_key: "testkey.pem",
112 }
113
114 java_sdk_library {
115 name: "foo",
116 srcs: ["b.java"],
117 }
118
119 java_library {
120 name: "bar",
121 srcs: ["b.java"],
122 installable: true,
123 apex_available: ["myapex"],
124 permitted_packages: ["bar"],
125 }
126
127 platform_bootclasspath {
128 name: "myplatform-bootclasspath",
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100129
130 fragments: [
131 {
132 apex: "com.android.art",
133 module: "art-bootclasspath-fragment",
134 },
135 ],
Paul Duffinb432df92021-03-22 22:09:42 +0000136 }
137`,
138 )
139
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100140 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
Paul Duffin74431d52021-04-21 14:10:42 +0100141 // The configured contents of BootJars.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100142 "com.android.art:baz",
143 "com.android.art:quuz",
144 "platform:foo",
Paul Duffin74431d52021-04-21 14:10:42 +0100145
146 // The configured contents of UpdatableBootJars.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100147 "myapex:bar",
148 })
149
150 java.CheckPlatformBootclasspathFragments(t, result, "myplatform-bootclasspath", []string{
151 `com.android.art:art-bootclasspath-fragment`,
152 })
153
Paul Duffinb432df92021-03-22 22:09:42 +0000154 // Make sure that the myplatform-bootclasspath has the correct dependencies.
155 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
Paul Duffin74431d52021-04-21 14:10:42 +0100156 // The following are stubs.
157 `platform:android_stubs_current`,
158 `platform:android_system_stubs_current`,
159 `platform:android_test_stubs_current`,
160 `platform:legacy.core.platform.api.stubs`,
161
162 // Needed for generating the boot image.
Paul Duffinb432df92021-03-22 22:09:42 +0000163 `platform:dex2oatd`,
Paul Duffin74431d52021-04-21 14:10:42 +0100164
165 // The configured contents of BootJars.
Paul Duffinb432df92021-03-22 22:09:42 +0000166 `com.android.art:baz`,
167 `com.android.art:quuz`,
168 `platform:foo`,
Paul Duffin74431d52021-04-21 14:10:42 +0100169
170 // The configured contents of UpdatableBootJars.
Paul Duffinb432df92021-03-22 22:09:42 +0000171 `myapex:bar`,
Paul Duffin74431d52021-04-21 14:10:42 +0100172
173 // The fragments.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100174 `com.android.art:art-bootclasspath-fragment`,
Paul Duffinb432df92021-03-22 22:09:42 +0000175 })
176}
177
Paul Duffin7487a7a2021-05-19 09:36:09 +0100178// TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when
179// AlwaysUsePrebuiltSdk() returns true. The structure of the modules in this test matches what
180// currently exists in some places in the Android build but it is not the intended structure. It is
181// in fact an invalid structure that should cause build failures. However, fixing that structure
182// will take too long so in the meantime this tests the workarounds to avoid build breakages.
183//
184// The main issues with this structure are:
185// 1. There is no prebuilt_bootclasspath_fragment referencing the "foo" java_sdk_library_import.
186// 2. There is no prebuilt_apex/apex_set which makes the dex implementation jar available to the
187// prebuilt_bootclasspath_fragment and the "foo" java_sdk_library_import.
188//
189// Together these cause the following symptoms:
190// 1. The "foo" java_sdk_library_import does not have a dex implementation jar.
191// 2. The "foo" java_sdk_library_import does not have a myapex variant.
192//
193// TODO(b/179354495): Fix the structure in this test once the main Android build has been fixed.
194func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
195 result := android.GroupFixturePreparers(
196 prepareForTestWithPlatformBootclasspath,
197 prepareForTestWithMyapex,
198 // Configure two libraries, the first is a java_sdk_library whose prebuilt will be used because
199 // of AlwaysUsePrebuiltsSdk() but does not have an appropriate apex variant and does not provide
200 // a boot dex jar. The second is a normal library that is unaffected. The order matters because
201 // if the dependency on myapex:foo is filtered out because of either of those conditions then
202 // the dependencies resolved by the platform_bootclasspath will not match the configured list
203 // and so will fail the test.
204 java.FixtureConfigureUpdatableBootJars("myapex:foo", "myapex:bar"),
205 java.PrepareForTestWithJavaSdkLibraryFiles,
206 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
207 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
208 }),
209 java.FixtureWithPrebuiltApis(map[string][]string{
210 "current": {},
211 "30": {"foo"},
212 }),
213 ).RunTestWithBp(t, `
214 apex {
215 name: "myapex",
216 key: "myapex.key",
217 bootclasspath_fragments: [
218 "mybootclasspath-fragment",
219 ],
220 updatable: false,
221 }
222
223 apex_key {
224 name: "myapex.key",
225 public_key: "testkey.avbpubkey",
226 private_key: "testkey.pem",
227 }
228
229 java_library {
230 name: "bar",
231 srcs: ["b.java"],
232 installable: true,
233 apex_available: ["myapex"],
234 permitted_packages: ["bar"],
235 }
236
237 java_sdk_library {
238 name: "foo",
239 srcs: ["b.java"],
240 shared_library: false,
241 public: {
242 enabled: true,
243 },
244 apex_available: ["myapex"],
245 permitted_packages: ["foo"],
246 }
247
248 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
249 // because AlwaysUsePrebuiltSdks() is true.
250 java_sdk_library_import {
251 name: "foo",
252 prefer: false,
253 shared_library: false,
254 public: {
255 jars: ["sdk_library/public/foo-stubs.jar"],
256 stub_srcs: ["sdk_library/public/foo_stub_sources"],
257 current_api: "sdk_library/public/foo.txt",
258 removed_api: "sdk_library/public/foo-removed.txt",
259 sdk_version: "current",
260 },
261 apex_available: ["myapex"],
262 }
263
264 // This always depends on the source foo module, its dependencies are not affected by the
265 // AlwaysUsePrebuiltSdks().
266 bootclasspath_fragment {
267 name: "mybootclasspath-fragment",
268 apex_available: [
269 "myapex",
270 ],
271 contents: [
272 "foo", "bar",
273 ],
274 }
275
276 platform_bootclasspath {
277 name: "myplatform-bootclasspath",
278 }
279`,
280 )
281
282 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
283 // The configured contents of BootJars.
284 "platform:prebuilt_foo", // Note: This is the platform not myapex variant.
285 "myapex:bar",
286 })
287
288 // Make sure that the myplatform-bootclasspath has the correct dependencies.
289 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
290 // The following are stubs.
291 "platform:prebuilt_sdk_public_current_android",
292 "platform:prebuilt_sdk_system_current_android",
293 "platform:prebuilt_sdk_test_current_android",
294
295 // Not a prebuilt as no prebuilt existed when it was added.
296 "platform:legacy.core.platform.api.stubs",
297
298 // Needed for generating the boot image.
299 `platform:dex2oatd`,
300
301 // The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
302 // modules when available as it does not know which one will be preferred.
303 //
304 // The source module has an APEX variant but the prebuilt does not.
305 "myapex:foo",
306 "platform:prebuilt_foo",
307
308 // Only a source module exists.
309 "myapex:bar",
310 })
311}
312
Paul Duffinb432df92021-03-22 22:09:42 +0000313// CheckModuleDependencies checks the dependencies of the selected module against the expected list.
314//
315// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
316// name of the apex, or platform is it is not part of an apex and <module> is the module name.
317func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
318 t.Helper()
319 module := ctx.ModuleForTests(name, variant).Module()
320 modules := []android.Module{}
321 ctx.VisitDirectDeps(module, func(m blueprint.Module) {
322 modules = append(modules, m.(android.Module))
323 })
324
325 pairs := java.ApexNamePairsFromModules(ctx, modules)
326 android.AssertDeepEquals(t, "module dependencies", expected, pairs)
327}