blob: 39b4652bd523eaeb130cffe5fabf27e4403685d6 [file] [log] [blame]
Ulya Trafimovich69612672020-10-20 17:41:54 +01001// 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
15package dexpreopt
16
17// This file contains unit tests for class loader context structure.
18// For class loader context tests involving .bp files, see TestUsesLibraries in java package.
19
20import (
Ulya Trafimovich7bc1cf52021-01-05 15:41:55 +000021 "fmt"
Ulya Trafimovich69612672020-10-20 17:41:54 +010022 "reflect"
Jiakai Zhanga4496782023-05-17 16:57:30 +010023 "sort"
Ulya Trafimovich69612672020-10-20 17:41:54 +010024 "strings"
25 "testing"
26
27 "android/soong/android"
28)
29
30func TestCLC(t *testing.T) {
31 // Construct class loader context with the following structure:
32 // .
33 // ├── 29
34 // │   ├── android.hidl.manager
35 // │   └── android.hidl.base
36 // │
37 // └── any
Jiakai Zhanga4496782023-05-17 16:57:30 +010038 // ├── a' (a single quotation mark (') is there to test escaping)
Ulya Trafimovich69612672020-10-20 17:41:54 +010039 // ├── b
40 // ├── c
41 // ├── d
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +000042 // │   ├── a2
43 // │   ├── b2
44 // │   └── c2
45 // │   ├── a1
46 // │   └── b1
Ulya Trafimovich69612672020-10-20 17:41:54 +010047 // ├── f
48 // ├── a3
49 // └── b3
50 //
51 ctx := testContext()
52
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +010053 optional := false
54
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +000055 m := make(ClassLoaderContextMap)
Ulya Trafimovich69612672020-10-20 17:41:54 +010056
Jiakai Zhanga4496782023-05-17 16:57:30 +010057 m.AddContext(ctx, AnySdkVersion, "a'", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +010058 m.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
59 m.AddContext(ctx, AnySdkVersion, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
Ulya Trafimovich69612672020-10-20 17:41:54 +010060
61 // Add some libraries with nested subcontexts.
62
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +000063 m1 := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +010064 m1.AddContext(ctx, AnySdkVersion, "a1", optional, buildPath(ctx, "a1"), installPath(ctx, "a1"), nil)
65 m1.AddContext(ctx, AnySdkVersion, "b1", optional, buildPath(ctx, "b1"), installPath(ctx, "b1"), nil)
Ulya Trafimovich69612672020-10-20 17:41:54 +010066
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +000067 m2 := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +010068 m2.AddContext(ctx, AnySdkVersion, "a2", optional, buildPath(ctx, "a2"), installPath(ctx, "a2"), nil)
69 m2.AddContext(ctx, AnySdkVersion, "b2", optional, buildPath(ctx, "b2"), installPath(ctx, "b2"), nil)
70 m2.AddContext(ctx, AnySdkVersion, "c2", optional, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1)
Ulya Trafimovich69612672020-10-20 17:41:54 +010071
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +000072 m3 := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +010073 m3.AddContext(ctx, AnySdkVersion, "a3", optional, buildPath(ctx, "a3"), installPath(ctx, "a3"), nil)
74 m3.AddContext(ctx, AnySdkVersion, "b3", optional, buildPath(ctx, "b3"), installPath(ctx, "b3"), nil)
Ulya Trafimovich69612672020-10-20 17:41:54 +010075
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +010076 m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), m2)
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +000077 // When the same library is both in conditional and unconditional context, it should be removed
78 // from conditional context.
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +010079 m.AddContext(ctx, 42, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
80 m.AddContext(ctx, AnySdkVersion, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
Ulya Trafimovich18554242020-11-03 15:55:11 +000081
82 // Merge map with implicit root library that is among toplevel contexts => does nothing.
83 m.AddContextMap(m1, "c")
84 // Merge map with implicit root library that is not among toplevel contexts => all subcontexts
85 // of the other map are added as toplevel contexts.
86 m.AddContextMap(m3, "m_g")
Ulya Trafimovich69612672020-10-20 17:41:54 +010087
88 // Compatibility libraries with unknown install paths get default paths.
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +010089 m.AddContext(ctx, 29, AndroidHidlManager, optional, buildPath(ctx, AndroidHidlManager), nil, nil)
90 m.AddContext(ctx, 29, AndroidHidlBase, optional, buildPath(ctx, AndroidHidlBase), nil, nil)
Ulya Trafimovich69612672020-10-20 17:41:54 +010091
92 // Add "android.test.mock" to conditional CLC, observe that is gets removed because it is only
93 // needed as a compatibility library if "android.test.runner" is in CLC as well.
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +010094 m.AddContext(ctx, 30, AndroidTestMock, optional, buildPath(ctx, AndroidTestMock), nil, nil)
Ulya Trafimovich69612672020-10-20 17:41:54 +010095
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +000096 valid, validationError := validateClassLoaderContext(m)
Ulya Trafimovich69612672020-10-20 17:41:54 +010097
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +000098 fixClassLoaderContext(m)
Ulya Trafimovich69612672020-10-20 17:41:54 +010099
Ulya Trafimovich69612672020-10-20 17:41:54 +0100100 var havePaths android.Paths
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +0100101 var haveUsesLibsReq, haveUsesLibsOpt []string
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +0000102 if valid && validationError == nil {
Jiakai Zhanga4496782023-05-17 16:57:30 +0100103 havePaths = ComputeClassLoaderContextDependencies(m)
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +0100104 haveUsesLibsReq, haveUsesLibsOpt = m.UsesLibs()
Ulya Trafimovich69612672020-10-20 17:41:54 +0100105 }
106
107 // Test that validation is successful (all paths are known).
108 t.Run("validate", func(t *testing.T) {
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +0000109 if !(valid && validationError == nil) {
Ulya Trafimovich69612672020-10-20 17:41:54 +0100110 t.Errorf("invalid class loader context")
111 }
112 })
113
Ulya Trafimovich69612672020-10-20 17:41:54 +0100114 // Test that all expected build paths are gathered.
115 t.Run("paths", func(t *testing.T) {
116 wantPaths := []string{
Colin Cross7b6a55f2021-11-09 12:34:39 -0800117 "out/soong/android.hidl.manager-V1.0-java.jar", "out/soong/android.hidl.base-V1.0-java.jar",
118 "out/soong/a.jar", "out/soong/b.jar", "out/soong/c.jar", "out/soong/d.jar",
119 "out/soong/a2.jar", "out/soong/b2.jar", "out/soong/c2.jar",
120 "out/soong/a1.jar", "out/soong/b1.jar",
121 "out/soong/f.jar", "out/soong/a3.jar", "out/soong/b3.jar",
Ulya Trafimovich69612672020-10-20 17:41:54 +0100122 }
Jiakai Zhanga4496782023-05-17 16:57:30 +0100123 actual := havePaths.Strings()
124 // The order does not matter.
125 sort.Strings(wantPaths)
126 sort.Strings(actual)
127 android.AssertArrayString(t, "", wantPaths, actual)
128 })
129
130 // Test the JSON passed to construct_context.py.
131 t.Run("json", func(t *testing.T) {
132 // The tree structure within each SDK version should be kept exactly the same when serialized
133 // to JSON. The order matters because the Python script keeps the order within each SDK version
134 // as is.
135 // The JSON is passed to the Python script as a commandline flag, so quotation ('') and escaping
136 // must be performed.
137 android.AssertStringEquals(t, "", strings.TrimSpace(`
138'{"29":[{"Name":"android.hidl.manager-V1.0-java","Optional":false,"Host":"out/soong/android.hidl.manager-V1.0-java.jar","Device":"/system/framework/android.hidl.manager-V1.0-java.jar","Subcontexts":[]},{"Name":"android.hidl.base-V1.0-java","Optional":false,"Host":"out/soong/android.hidl.base-V1.0-java.jar","Device":"/system/framework/android.hidl.base-V1.0-java.jar","Subcontexts":[]}],"30":[],"42":[],"any":[{"Name":"a'\''","Optional":false,"Host":"out/soong/a.jar","Device":"/system/a.jar","Subcontexts":[]},{"Name":"b","Optional":false,"Host":"out/soong/b.jar","Device":"/system/b.jar","Subcontexts":[]},{"Name":"c","Optional":false,"Host":"out/soong/c.jar","Device":"/system/c.jar","Subcontexts":[]},{"Name":"d","Optional":false,"Host":"out/soong/d.jar","Device":"/system/d.jar","Subcontexts":[{"Name":"a2","Optional":false,"Host":"out/soong/a2.jar","Device":"/system/a2.jar","Subcontexts":[]},{"Name":"b2","Optional":false,"Host":"out/soong/b2.jar","Device":"/system/b2.jar","Subcontexts":[]},{"Name":"c2","Optional":false,"Host":"out/soong/c2.jar","Device":"/system/c2.jar","Subcontexts":[{"Name":"a1","Optional":false,"Host":"out/soong/a1.jar","Device":"/system/a1.jar","Subcontexts":[]},{"Name":"b1","Optional":false,"Host":"out/soong/b1.jar","Device":"/system/b1.jar","Subcontexts":[]}]}]},{"Name":"f","Optional":false,"Host":"out/soong/f.jar","Device":"/system/f.jar","Subcontexts":[]},{"Name":"a3","Optional":false,"Host":"out/soong/a3.jar","Device":"/system/a3.jar","Subcontexts":[]},{"Name":"b3","Optional":false,"Host":"out/soong/b3.jar","Device":"/system/b3.jar","Subcontexts":[]}]}'
139`), m.DumpForFlag())
Ulya Trafimovich69612672020-10-20 17:41:54 +0100140 })
141
142 // Test for libraries that are added by the manifest_fixer.
143 t.Run("uses libs", func(t *testing.T) {
Jiakai Zhanga4496782023-05-17 16:57:30 +0100144 wantUsesLibsReq := []string{"a'", "b", "c", "d", "f", "a3", "b3"}
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +0100145 wantUsesLibsOpt := []string{}
146 if !reflect.DeepEqual(wantUsesLibsReq, haveUsesLibsReq) {
147 t.Errorf("\nwant required uses libs: %s\nhave required uses libs: %s", wantUsesLibsReq, haveUsesLibsReq)
148 }
149 if !reflect.DeepEqual(wantUsesLibsOpt, haveUsesLibsOpt) {
150 t.Errorf("\nwant optional uses libs: %s\nhave optional uses libs: %s", wantUsesLibsOpt, haveUsesLibsOpt)
Ulya Trafimovich69612672020-10-20 17:41:54 +0100151 }
152 })
153}
154
Jeongik Cha19ade892021-04-22 20:55:21 +0900155func TestCLCJson(t *testing.T) {
156 ctx := testContext()
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +0100157 optional := false
Jeongik Cha19ade892021-04-22 20:55:21 +0900158 m := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100159 m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
160 m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
161 m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
162 m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil)
Jeongik Cha19ade892021-04-22 20:55:21 +0900163 jsonCLC := toJsonClassLoaderContext(m)
164 restored := fromJsonClassLoaderContext(ctx, jsonCLC)
165 android.AssertIntEquals(t, "The size of the maps should be the same.", len(m), len(restored))
166 for k := range m {
167 a, _ := m[k]
168 b, ok := restored[k]
169 android.AssertBoolEquals(t, "The both maps should have the same keys.", ok, true)
170 android.AssertIntEquals(t, "The size of the elements should be the same.", len(a), len(b))
171 for i, elemA := range a {
172 before := fmt.Sprintf("%v", *elemA)
173 after := fmt.Sprintf("%v", *b[i])
174 android.AssertStringEquals(t, "The content should be the same.", before, after)
175 }
176 }
177}
178
Ulya Trafimovich7bc1cf52021-01-05 15:41:55 +0000179// Test that unknown library paths cause a validation error.
180func testCLCUnknownPath(t *testing.T, whichPath string) {
Ulya Trafimovich69612672020-10-20 17:41:54 +0100181 ctx := testContext()
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +0100182 optional := false
Ulya Trafimovich69612672020-10-20 17:41:54 +0100183
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +0000184 m := make(ClassLoaderContextMap)
Ulya Trafimovich7bc1cf52021-01-05 15:41:55 +0000185 if whichPath == "build" {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100186 m.AddContext(ctx, AnySdkVersion, "a", optional, nil, nil, nil)
Ulya Trafimovich7bc1cf52021-01-05 15:41:55 +0000187 } else {
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100188 m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), nil, nil)
Ulya Trafimovich7bc1cf52021-01-05 15:41:55 +0000189 }
Ulya Trafimovich69612672020-10-20 17:41:54 +0100190
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +0000191 // The library should be added to <uses-library> tags by the manifest_fixer.
Ulya Trafimovich7bc1cf52021-01-05 15:41:55 +0000192 t.Run("uses libs", func(t *testing.T) {
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +0100193 haveUsesLibsReq, haveUsesLibsOpt := m.UsesLibs()
194 wantUsesLibsReq := []string{"a"}
195 wantUsesLibsOpt := []string{}
196 if !reflect.DeepEqual(wantUsesLibsReq, haveUsesLibsReq) {
197 t.Errorf("\nwant required uses libs: %s\nhave required uses libs: %s", wantUsesLibsReq, haveUsesLibsReq)
198 }
199 if !reflect.DeepEqual(wantUsesLibsOpt, haveUsesLibsOpt) {
200 t.Errorf("\nwant optional uses libs: %s\nhave optional uses libs: %s", wantUsesLibsOpt, haveUsesLibsOpt)
Ulya Trafimovich8cbc5d22020-11-03 15:15:46 +0000201 }
202 })
Ulya Trafimovich69612672020-10-20 17:41:54 +0100203
Ulya Trafimovich7bc1cf52021-01-05 15:41:55 +0000204 // But CLC cannot be constructed: there is a validation error.
205 _, err := validateClassLoaderContext(m)
206 checkError(t, err, fmt.Sprintf("invalid %s path for <uses-library> \"a\"", whichPath))
207}
208
209// Test that unknown build path is an error.
210func TestCLCUnknownBuildPath(t *testing.T) {
211 testCLCUnknownPath(t, "build")
212}
213
214// Test that unknown install path is an error.
215func TestCLCUnknownInstallPath(t *testing.T) {
216 testCLCUnknownPath(t, "install")
Ulya Trafimovich69612672020-10-20 17:41:54 +0100217}
218
Ulya Trafimovich5e13a732020-11-03 15:33:03 +0000219// An attempt to add conditional nested subcontext should fail.
220func TestCLCNestedConditional(t *testing.T) {
221 ctx := testContext()
Ulya Trafimovichfc0f6e32021-08-12 16:16:11 +0100222 optional := false
Ulya Trafimovich5e13a732020-11-03 15:33:03 +0000223 m1 := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100224 m1.AddContext(ctx, 42, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
Ulya Trafimovich5e13a732020-11-03 15:33:03 +0000225 m := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100226 err := m.addContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), m1)
Ulya Trafimovich5e13a732020-11-03 15:33:03 +0000227 checkError(t, err, "nested class loader context shouldn't have conditional part")
228}
229
Paul Duffin06530572022-02-03 17:54:15 +0000230func TestCLCMExcludeLibs(t *testing.T) {
231 ctx := testContext()
232 const optional = false
Paul Duffin06530572022-02-03 17:54:15 +0000233
234 excludeLibs := func(t *testing.T, m ClassLoaderContextMap, excluded_libs ...string) ClassLoaderContextMap {
235 // Dump the CLCM before creating a new copy that excludes a specific set of libraries.
236 before := m.Dump()
237
238 // Create a new CLCM that excludes some libraries.
239 c := m.ExcludeLibs(excluded_libs)
240
241 // Make sure that the original CLCM was not changed.
242 after := m.Dump()
243 android.AssertStringEquals(t, "input CLCM modified", before, after)
244
245 return c
246 }
247
248 t.Run("exclude nothing", func(t *testing.T) {
249 m := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100250 m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
Paul Duffin06530572022-02-03 17:54:15 +0000251
252 a := excludeLibs(t, m)
253
254 android.AssertStringEquals(t, "output CLCM ", `{
255 "28": [
256 {
257 "Name": "a",
258 "Optional": false,
Paul Duffin06530572022-02-03 17:54:15 +0000259 "Host": "out/soong/a.jar",
260 "Device": "/system/a.jar",
261 "Subcontexts": []
262 }
263 ]
264}`, a.Dump())
265 })
266
267 t.Run("one item from list", func(t *testing.T) {
268 m := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100269 m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
270 m.AddContext(ctx, 28, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
Paul Duffin06530572022-02-03 17:54:15 +0000271
272 a := excludeLibs(t, m, "a")
273
274 expected := `{
275 "28": [
276 {
277 "Name": "b",
278 "Optional": false,
Paul Duffin06530572022-02-03 17:54:15 +0000279 "Host": "out/soong/b.jar",
280 "Device": "/system/b.jar",
281 "Subcontexts": []
282 }
283 ]
284}`
285 android.AssertStringEquals(t, "output CLCM ", expected, a.Dump())
286 })
287
288 t.Run("all items from a list", func(t *testing.T) {
289 m := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100290 m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
291 m.AddContext(ctx, 28, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
Paul Duffin06530572022-02-03 17:54:15 +0000292
293 a := excludeLibs(t, m, "a", "b")
294
295 android.AssertStringEquals(t, "output CLCM ", `{}`, a.Dump())
296 })
297
298 t.Run("items from a subcontext", func(t *testing.T) {
299 s := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100300 s.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
301 s.AddContext(ctx, AnySdkVersion, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
Paul Duffin06530572022-02-03 17:54:15 +0000302
303 m := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100304 m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), s)
Paul Duffin06530572022-02-03 17:54:15 +0000305
306 a := excludeLibs(t, m, "b")
307
308 android.AssertStringEquals(t, "output CLCM ", `{
309 "28": [
310 {
311 "Name": "a",
312 "Optional": false,
Paul Duffin06530572022-02-03 17:54:15 +0000313 "Host": "out/soong/a.jar",
314 "Device": "/system/a.jar",
315 "Subcontexts": [
316 {
317 "Name": "c",
318 "Optional": false,
Paul Duffin06530572022-02-03 17:54:15 +0000319 "Host": "out/soong/c.jar",
320 "Device": "/system/c.jar",
321 "Subcontexts": []
322 }
323 ]
324 }
325 ]
326}`, a.Dump())
327 })
328}
329
Ulya Trafimovich91f015e2022-04-27 17:51:49 +0100330// Test that CLC is correctly serialized to JSON.
331func TestCLCtoJSON(t *testing.T) {
332 ctx := testContext()
333 optional := false
Ulya Trafimovich91f015e2022-04-27 17:51:49 +0100334 m := make(ClassLoaderContextMap)
Ulya Trafimovichf5d91bb2022-05-04 12:00:02 +0100335 m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
336 m.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
Ulya Trafimovich91f015e2022-04-27 17:51:49 +0100337 android.AssertStringEquals(t, "output CLCM ", `{
338 "28": [
339 {
340 "Name": "a",
341 "Optional": false,
Ulya Trafimovich91f015e2022-04-27 17:51:49 +0100342 "Host": "out/soong/a.jar",
343 "Device": "/system/a.jar",
344 "Subcontexts": []
345 }
346 ],
347 "any": [
348 {
349 "Name": "b",
350 "Optional": false,
Ulya Trafimovich91f015e2022-04-27 17:51:49 +0100351 "Host": "out/soong/b.jar",
352 "Device": "/system/b.jar",
353 "Subcontexts": []
354 }
355 ]
356}`, m.Dump())
357}
358
Ulya Trafimovich69612672020-10-20 17:41:54 +0100359func checkError(t *testing.T, have error, want string) {
360 if have == nil {
361 t.Errorf("\nwant error: '%s'\nhave: none", want)
362 } else if msg := have.Error(); !strings.HasPrefix(msg, want) {
363 t.Errorf("\nwant error: '%s'\nhave error: '%s'\n", want, msg)
364 }
365}
366
367func testContext() android.ModuleInstallPathContext {
368 config := android.TestConfig("out", nil, "", nil)
369 return android.ModuleInstallPathContextForTesting(config)
370}
371
372func buildPath(ctx android.PathContext, lib string) android.Path {
373 return android.PathForOutput(ctx, lib+".jar")
374}
375
376func installPath(ctx android.ModuleInstallPathContext, lib string) android.InstallPath {
377 return android.PathForModuleInstall(ctx, lib+".jar")
378}