blob: f8e889983f0aa6645f66bddc5ab02003941caaa4 [file] [log] [blame]
Paul Duffine245b612021-06-10 08:59:41 +01001// 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 "reflect"
19 "testing"
20
21 "android/soong/android"
22 "android/soong/java"
Paul Duffine245b612021-06-10 08:59:41 +010023)
24
25// Contains tests for java.CreateClasspathElements logic from java/classpath_element.go that
26// requires apexes.
27
28// testClasspathElementContext is a ClasspathElementContext suitable for use in tests.
29type testClasspathElementContext struct {
Colin Cross313aa542023-12-13 13:47:44 -080030 android.OtherModuleProviderContext
Paul Duffine245b612021-06-10 08:59:41 +010031 testContext *android.TestContext
32 module android.Module
33 errs []error
34}
35
Paul Duffine245b612021-06-10 08:59:41 +010036func (t *testClasspathElementContext) ModuleErrorf(fmt string, args ...interface{}) {
37 t.errs = append(t.errs, t.testContext.ModuleErrorf(t.module, fmt, args...))
38}
39
40var _ java.ClasspathElementContext = (*testClasspathElementContext)(nil)
41
42func TestCreateClasspathElements(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -070043 t.Parallel()
Paul Duffine245b612021-06-10 08:59:41 +010044 preparer := android.GroupFixturePreparers(
45 prepareForTestWithPlatformBootclasspath,
46 prepareForTestWithArtApex,
47 prepareForTestWithMyapex,
48 // For otherapex.
49 android.FixtureMergeMockFs(android.MockFS{
50 "system/sepolicy/apex/otherapex-file_contexts": nil,
51 }),
52 java.PrepareForTestWithJavaSdkLibraryFiles,
53 java.FixtureWithLastReleaseApis("foo", "othersdklibrary"),
satayevabcd5972021-08-06 17:49:46 +010054 java.FixtureConfigureApexBootJars("myapex:bar"),
Paul Duffine245b612021-06-10 08:59:41 +010055 android.FixtureWithRootAndroidBp(`
56 apex {
57 name: "com.android.art",
58 key: "com.android.art.key",
59 bootclasspath_fragments: [
60 "art-bootclasspath-fragment",
61 ],
62 java_libs: [
63 "othersdklibrary",
64 ],
65 updatable: false,
66 }
67
68 apex_key {
69 name: "com.android.art.key",
70 public_key: "com.android.art.avbpubkey",
71 private_key: "com.android.art.pem",
72 }
73
74 bootclasspath_fragment {
75 name: "art-bootclasspath-fragment",
satayevabcd5972021-08-06 17:49:46 +010076 image_name: "art",
Paul Duffine245b612021-06-10 08:59:41 +010077 apex_available: [
78 "com.android.art",
79 ],
80 contents: [
81 "baz",
82 "quuz",
83 ],
Paul Duffin9fd56472022-03-31 15:42:30 +010084 hidden_api: {
85 split_packages: ["*"],
86 },
Paul Duffine245b612021-06-10 08:59:41 +010087 }
88
89 java_library {
90 name: "baz",
91 apex_available: [
92 "com.android.art",
93 ],
94 srcs: ["b.java"],
95 installable: true,
Jihoon Kang85bc1932024-07-01 17:04:46 +000096 sdk_version: "core_current",
Paul Duffine245b612021-06-10 08:59:41 +010097 }
98
99 java_library {
100 name: "quuz",
101 apex_available: [
102 "com.android.art",
103 ],
104 srcs: ["b.java"],
105 installable: true,
106 }
107
108 apex {
109 name: "myapex",
110 key: "myapex.key",
111 bootclasspath_fragments: [
112 "mybootclasspath-fragment",
113 ],
114 java_libs: [
115 "othersdklibrary",
116 ],
117 updatable: false,
118 }
119
120 apex_key {
121 name: "myapex.key",
122 public_key: "testkey.avbpubkey",
123 private_key: "testkey.pem",
124 }
125
126 bootclasspath_fragment {
127 name: "mybootclasspath-fragment",
128 apex_available: [
129 "myapex",
130 ],
131 contents: [
132 "bar",
133 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100134 hidden_api: {
135 split_packages: ["*"],
136 },
Paul Duffine245b612021-06-10 08:59:41 +0100137 }
138
139 java_library {
140 name: "bar",
141 srcs: ["b.java"],
142 installable: true,
143 apex_available: ["myapex"],
144 permitted_packages: ["bar"],
145 }
146
147 java_sdk_library {
148 name: "foo",
149 srcs: ["b.java"],
150 }
151
152 java_sdk_library {
153 name: "othersdklibrary",
154 srcs: ["b.java"],
155 shared_library: false,
156 apex_available: [
157 "com.android.art",
158 "myapex",
159 ],
160 }
161
Paul Duffine245b612021-06-10 08:59:41 +0100162 apex {
163 name: "otherapex",
164 key: "otherapex.key",
165 java_libs: [
166 "otherapexlibrary",
167 ],
168 updatable: false,
169 }
170
171 apex_key {
172 name: "otherapex.key",
173 public_key: "testkey.avbpubkey",
174 private_key: "testkey.pem",
175 }
176
177 java_library {
178 name: "otherapexlibrary",
179 srcs: ["b.java"],
180 installable: true,
181 apex_available: ["otherapex"],
182 permitted_packages: ["otherapexlibrary"],
183 }
184
185 platform_bootclasspath {
186 name: "myplatform-bootclasspath",
187
188 fragments: [
189 {
190 apex: "com.android.art",
191 module: "art-bootclasspath-fragment",
192 },
satayevabcd5972021-08-06 17:49:46 +0100193 {
194 apex: "myapex",
195 module: "mybootclasspath-fragment",
196 },
Paul Duffine245b612021-06-10 08:59:41 +0100197 ],
198 }
199 `),
200 )
201
202 result := preparer.RunTest(t)
203
204 artFragment := result.Module("art-bootclasspath-fragment", "android_common_apex10000")
205 artBaz := result.Module("baz", "android_common_apex10000")
206 artQuuz := result.Module("quuz", "android_common_apex10000")
207
208 myFragment := result.Module("mybootclasspath-fragment", "android_common_apex10000")
209 myBar := result.Module("bar", "android_common_apex10000")
210
Paul Duffine245b612021-06-10 08:59:41 +0100211 other := result.Module("othersdklibrary", "android_common_apex10000")
212
213 otherApexLibrary := result.Module("otherapexlibrary", "android_common_apex10000")
214
215 platformFoo := result.Module("quuz", "android_common")
216
217 bootclasspath := result.Module("myplatform-bootclasspath", "android_common")
218
219 // Use a custom assertion method instead of AssertDeepEquals as the latter formats the output
220 // using %#v which results in meaningless output as ClasspathElements are pointers.
221 assertElementsEquals := func(t *testing.T, message string, expected, actual java.ClasspathElements) {
222 if !reflect.DeepEqual(expected, actual) {
223 t.Errorf("%s: expected:\n %s\n got:\n %s", message, expected, actual)
224 }
225 }
226
227 expectFragmentElement := func(module android.Module, contents ...android.Module) java.ClasspathElement {
228 return &java.ClasspathFragmentElement{module, contents}
229 }
230 expectLibraryElement := func(module android.Module) java.ClasspathElement {
231 return &java.ClasspathLibraryElement{module}
232 }
233
234 newCtx := func() *testClasspathElementContext {
Colin Cross313aa542023-12-13 13:47:44 -0800235 return &testClasspathElementContext{
236 OtherModuleProviderContext: result.TestContext.OtherModuleProviderAdaptor(),
237 testContext: result.TestContext,
238 module: bootclasspath,
239 }
Paul Duffine245b612021-06-10 08:59:41 +0100240 }
241
242 // Verify that CreateClasspathElements works when given valid input.
243 t.Run("art:baz, art:quuz, my:bar, foo", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700244 t.Parallel()
Paul Duffine245b612021-06-10 08:59:41 +0100245 ctx := newCtx()
246 elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, artQuuz, myBar, platformFoo}, []android.Module{artFragment, myFragment})
247 expectedElements := java.ClasspathElements{
248 expectFragmentElement(artFragment, artBaz, artQuuz),
249 expectFragmentElement(myFragment, myBar),
250 expectLibraryElement(platformFoo),
251 }
252 assertElementsEquals(t, "elements", expectedElements, elements)
253 })
254
Paul Duffine245b612021-06-10 08:59:41 +0100255 // Verify that CreateClasspathElements detects when an apex has multiple fragments.
256 t.Run("multiple fragments for same apex", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700257 t.Parallel()
Paul Duffine245b612021-06-10 08:59:41 +0100258 ctx := newCtx()
259 elements := java.CreateClasspathElements(ctx, []android.Module{}, []android.Module{artFragment, artFragment})
260 android.FailIfNoMatchingErrors(t, "apex com.android.art has multiple fragments, art-bootclasspath-fragment{.*} and art-bootclasspath-fragment{.*}", ctx.errs)
261 expectedElements := java.ClasspathElements{}
262 assertElementsEquals(t, "elements", expectedElements, elements)
263 })
264
265 // Verify that CreateClasspathElements detects when a library is in multiple fragments.
266 t.Run("library from multiple fragments", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700267 t.Parallel()
Paul Duffine245b612021-06-10 08:59:41 +0100268 ctx := newCtx()
269 elements := java.CreateClasspathElements(ctx, []android.Module{other}, []android.Module{artFragment, myFragment})
270 android.FailIfNoMatchingErrors(t, "library othersdklibrary{.*} is in two separate fragments, art-bootclasspath-fragment{.*} and mybootclasspath-fragment{.*}", ctx.errs)
271 expectedElements := java.ClasspathElements{}
272 assertElementsEquals(t, "elements", expectedElements, elements)
273 })
274
275 // Verify that CreateClasspathElements detects when a fragment's contents are not contiguous and
276 // are separated by a library from another fragment.
277 t.Run("discontiguous separated by fragment", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700278 t.Parallel()
Paul Duffine245b612021-06-10 08:59:41 +0100279 ctx := newCtx()
280 elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, myBar, artQuuz, platformFoo}, []android.Module{artFragment, myFragment})
281 expectedElements := java.ClasspathElements{
282 expectFragmentElement(artFragment, artBaz, artQuuz),
283 expectFragmentElement(myFragment, myBar),
284 expectLibraryElement(platformFoo),
285 }
286 assertElementsEquals(t, "elements", expectedElements, elements)
287 android.FailIfNoMatchingErrors(t, "libraries from the same fragment must be contiguous, however baz{.*} and quuz{os:android,arch:common,apex:apex10000} from fragment art-bootclasspath-fragment{.*} are separated by libraries from fragment mybootclasspath-fragment{.*} like bar{.*}", ctx.errs)
288 })
289
290 // Verify that CreateClasspathElements detects when a fragment's contents are not contiguous and
291 // are separated by a standalone library.
292 t.Run("discontiguous separated by library", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700293 t.Parallel()
Paul Duffine245b612021-06-10 08:59:41 +0100294 ctx := newCtx()
295 elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, platformFoo, artQuuz, myBar}, []android.Module{artFragment, myFragment})
296 expectedElements := java.ClasspathElements{
297 expectFragmentElement(artFragment, artBaz, artQuuz),
298 expectLibraryElement(platformFoo),
299 expectFragmentElement(myFragment, myBar),
300 }
301 assertElementsEquals(t, "elements", expectedElements, elements)
302 android.FailIfNoMatchingErrors(t, "libraries from the same fragment must be contiguous, however baz{.*} and quuz{os:android,arch:common,apex:apex10000} from fragment art-bootclasspath-fragment{.*} are separated by library quuz{.*}", ctx.errs)
303 })
304
305 // Verify that CreateClasspathElements detects when there a library on the classpath that
306 // indicates it is from an apex the supplied fragments list does not contain a fragment for that
307 // apex.
308 t.Run("no fragment for apex", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700309 t.Parallel()
Paul Duffine245b612021-06-10 08:59:41 +0100310 ctx := newCtx()
311 elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, otherApexLibrary}, []android.Module{artFragment})
312 expectedElements := java.ClasspathElements{
313 expectFragmentElement(artFragment, artBaz),
314 }
315 assertElementsEquals(t, "elements", expectedElements, elements)
316 android.FailIfNoMatchingErrors(t, `library otherapexlibrary{.*} is from apexes \[otherapex\] which have no corresponding fragment in \[art-bootclasspath-fragment{.*}\]`, ctx.errs)
317 })
318}