blob: d1794ee5ceea2ba174fb363af7f934b551e7e2df [file] [log] [blame]
Jiyong Park25fc6a92018-11-18 18:02:45 +09001// Copyright 2018 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 apex
16
17import (
18 "android/soong/android"
19 "android/soong/cc"
20 "io/ioutil"
21 "os"
22 "strings"
23 "testing"
24)
25
26func testApex(t *testing.T, bp string) *android.TestContext {
27 config, buildDir := setup(t)
28 defer teardown(buildDir)
29
30 ctx := android.NewTestArchContext()
31 ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apexBundleFactory))
32 ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apexKeyFactory))
33
34 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
35 ctx.TopDown("apex_deps", apexDepsMutator)
36 ctx.BottomUp("apex", apexMutator)
37 })
38
39 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
40 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory))
41 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
42 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
43 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
44 ctx.BottomUp("link", cc.LinkageMutator).Parallel()
45 ctx.BottomUp("version", cc.VersionMutator).Parallel()
46 ctx.BottomUp("begin", cc.BeginMutator).Parallel()
47 })
48
49 ctx.Register()
50
51 bp = bp + `
52 toolchain_library {
53 name: "libcompiler_rt-extras",
54 src: "",
55 }
56
57 toolchain_library {
58 name: "libatomic",
59 src: "",
60 }
61
62 toolchain_library {
63 name: "libgcc",
64 src: "",
65 }
66
67 toolchain_library {
68 name: "libclang_rt.builtins-aarch64-android",
69 src: "",
70 }
71
72 toolchain_library {
73 name: "libclang_rt.builtins-arm-android",
74 src: "",
75 }
76
77 cc_object {
78 name: "crtbegin_so",
79 stl: "none",
80 }
81
82 cc_object {
83 name: "crtend_so",
84 stl: "none",
85 }
86
87 `
88
89 ctx.MockFileSystem(map[string][]byte{
90 "Android.bp": []byte(bp),
91 "testkey.avbpubkey": nil,
92 "testkey.pem": nil,
93 "build/target/product/security": nil,
94 "apex_manifest.json": nil,
95 "system/sepolicy/apex/myapex-file_contexts": nil,
96 "mylib.cpp": nil,
97 })
98 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
99 android.FailIfErrored(t, errs)
100 _, errs = ctx.PrepareBuildActions(config)
101 android.FailIfErrored(t, errs)
102
103 return ctx
104}
105
106func setup(t *testing.T) (config android.Config, buildDir string) {
107 buildDir, err := ioutil.TempDir("", "soong_apex_test")
108 if err != nil {
109 t.Fatal(err)
110 }
111
112 config = android.TestArchConfig(buildDir, nil)
113
114 return
115}
116
117func teardown(buildDir string) {
118 os.RemoveAll(buildDir)
119}
120
121// ensure that 'result' contains 'expected'
122func ensureContains(t *testing.T, result string, expected string) {
123 if !strings.Contains(result, expected) {
124 t.Errorf("%q is not found in %q", expected, result)
125 }
126}
127
128// ensures that 'result' does not contain 'notExpected'
129func ensureNotContains(t *testing.T, result string, notExpected string) {
130 if strings.Contains(result, notExpected) {
131 t.Errorf("%q is found in %q", notExpected, result)
132 }
133}
134
135func ensureListContains(t *testing.T, result []string, expected string) {
136 if !android.InList(expected, result) {
137 t.Errorf("%q is not found in %v", expected, result)
138 }
139}
140
141func ensureListNotContains(t *testing.T, result []string, notExpected string) {
142 if android.InList(notExpected, result) {
143 t.Errorf("%q is found in %v", notExpected, result)
144 }
145}
146
147// Minimal test
148func TestBasicApex(t *testing.T) {
149 ctx := testApex(t, `
150 apex {
151 name: "myapex",
152 key: "myapex.key",
153 native_shared_libs: ["mylib"],
154 }
155
156 apex_key {
157 name: "myapex.key",
158 public_key: "testkey.avbpubkey",
159 private_key: "testkey.pem",
160 }
161
162 cc_library {
163 name: "mylib",
164 srcs: ["mylib.cpp"],
165 shared_libs: ["mylib2"],
166 system_shared_libs: [],
167 stl: "none",
168 }
169
170 cc_library {
171 name: "mylib2",
172 srcs: ["mylib.cpp"],
173 system_shared_libs: [],
174 stl: "none",
175 }
176 `)
177
178 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
179 copyCmds := apexRule.Args["copy_commands"]
180
181 // Ensure that main rule creates an output
182 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
183
184 // Ensure that apex variant is created for the direct dep
185 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
186
187 // Ensure that apex variant is created for the indirect dep
188 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
189
190 // Ensure that both direct and indirect deps are copied into apex
Alex Light5098a612018-11-29 17:12:15 -0800191 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
192 ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
193}
194
195func TestBasicZipApex(t *testing.T) {
196 ctx := testApex(t, `
197 apex {
198 name: "myapex",
199 key: "myapex.key",
200 payload_type: "zip",
201 native_shared_libs: ["mylib"],
202 }
203
204 apex_key {
205 name: "myapex.key",
206 public_key: "testkey.avbpubkey",
207 private_key: "testkey.pem",
208 }
209
210 cc_library {
211 name: "mylib",
212 srcs: ["mylib.cpp"],
213 shared_libs: ["mylib2"],
214 system_shared_libs: [],
215 stl: "none",
216 }
217
218 cc_library {
219 name: "mylib2",
220 srcs: ["mylib.cpp"],
221 system_shared_libs: [],
222 stl: "none",
223 }
224 `)
225
226 zipApexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("zipApexRule")
227 copyCmds := zipApexRule.Args["copy_commands"]
228
229 // Ensure that main rule creates an output
230 ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned")
231
232 // Ensure that APEX variant is created for the direct dep
233 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
234
235 // Ensure that APEX variant is created for the indirect dep
236 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
237
238 // Ensure that both direct and indirect deps are copied into apex
239 ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so")
240 ensureContains(t, copyCmds, "image.zipapex/lib64/mylib2.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900241}
242
243func TestApexWithStubs(t *testing.T) {
244 ctx := testApex(t, `
245 apex {
246 name: "myapex",
247 key: "myapex.key",
248 native_shared_libs: ["mylib", "mylib3"],
249 }
250
251 apex_key {
252 name: "myapex.key",
253 public_key: "testkey.avbpubkey",
254 private_key: "testkey.pem",
255 }
256
257 cc_library {
258 name: "mylib",
259 srcs: ["mylib.cpp"],
260 shared_libs: ["mylib2", "mylib3"],
261 system_shared_libs: [],
262 stl: "none",
263 }
264
265 cc_library {
266 name: "mylib2",
267 srcs: ["mylib.cpp"],
268 system_shared_libs: [],
269 stl: "none",
270 stubs: {
271 versions: ["1", "2", "3"],
272 },
273 }
274
275 cc_library {
276 name: "mylib3",
277 srcs: ["mylib.cpp"],
278 system_shared_libs: [],
279 stl: "none",
280 stubs: {
281 versions: ["10", "11", "12"],
282 },
283 }
284 `)
285
286 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
287 copyCmds := apexRule.Args["copy_commands"]
288
289 // Ensure that direct non-stubs dep is always included
Alex Light5098a612018-11-29 17:12:15 -0800290 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900291
292 // Ensure that indirect stubs dep is not included
Alex Light5098a612018-11-29 17:12:15 -0800293 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900294
295 // Ensure that direct stubs dep is included
Alex Light5098a612018-11-29 17:12:15 -0800296 ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900297
298 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
299
300 // Ensure that mylib is linking with the latest version of stubs for mylib2
301 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3_myapex/mylib2.so")
302 // ... and not linking to the non-stub (impl) variant of mylib2
303 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_myapex/mylib2.so")
304
305 // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
306 ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_myapex/mylib3.so")
307 // .. and not linking to the stubs variant of mylib3
308 ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12_myapex/mylib3.so")
309}
310
311func TestApexWithSystemLibsStubs(t *testing.T) {
312 ctx := testApex(t, `
313 apex {
314 name: "myapex",
315 key: "myapex.key",
316 native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"],
317 }
318
319 apex_key {
320 name: "myapex.key",
321 public_key: "testkey.avbpubkey",
322 private_key: "testkey.pem",
323 }
324
325 cc_library {
326 name: "mylib",
327 srcs: ["mylib.cpp"],
328 shared_libs: ["libdl#27"],
329 stl: "none",
330 }
331
332 cc_library_shared {
333 name: "mylib_shared",
334 srcs: ["mylib.cpp"],
335 shared_libs: ["libdl#27"],
336 stl: "none",
337 }
338
339 cc_library {
340 name: "libc",
341 no_libgcc: true,
342 nocrt: true,
343 system_shared_libs: [],
344 stl: "none",
345 stubs: {
346 versions: ["27", "28", "29"],
347 },
348 }
349
350 cc_library {
351 name: "libm",
352 no_libgcc: true,
353 nocrt: true,
354 system_shared_libs: [],
355 stl: "none",
356 stubs: {
357 versions: ["27", "28", "29"],
358 },
359 }
360
361 cc_library {
362 name: "libdl",
363 no_libgcc: true,
364 nocrt: true,
365 system_shared_libs: [],
366 stl: "none",
367 stubs: {
368 versions: ["27", "28", "29"],
369 },
370 }
371 `)
372
373 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
374 copyCmds := apexRule.Args["copy_commands"]
375
376 // Ensure that mylib, libm, libdl are included.
Alex Light5098a612018-11-29 17:12:15 -0800377 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
378 ensureContains(t, copyCmds, "image.apex/lib64/libm.so")
379 ensureContains(t, copyCmds, "image.apex/lib64/libdl.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900380
381 // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
Alex Light5098a612018-11-29 17:12:15 -0800382 ensureNotContains(t, copyCmds, "image.apex/lib64/libc.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900383
384 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
385 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
386 mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_myapex").Rule("cc").Args["cFlags"]
387
388 // For dependency to libc
389 // Ensure that mylib is linking with the latest version of stubs
390 ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_29_myapex/libc.so")
391 // ... and not linking to the non-stub (impl) variant
392 ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_myapex/libc.so")
393 // ... Cflags from stub is correctly exported to mylib
394 ensureContains(t, mylibCFlags, "__LIBC_API__=29")
395 ensureContains(t, mylibSharedCFlags, "__LIBC_API__=29")
396
397 // For dependency to libm
398 // Ensure that mylib is linking with the non-stub (impl) variant
399 ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_myapex/libm.so")
400 // ... and not linking to the stub variant
401 ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29_myapex/libm.so")
402 // ... and is not compiling with the stub
403 ensureNotContains(t, mylibCFlags, "__LIBM_API__=29")
404 ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29")
405
406 // For dependency to libdl
407 // Ensure that mylib is linking with the specified version of stubs
408 ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_27_myapex/libdl.so")
409 // ... and not linking to the other versions of stubs
410 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28_myapex/libdl.so")
411 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29_myapex/libdl.so")
412 // ... and not linking to the non-stub (impl) variant
413 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_myapex/libdl.so")
414 // ... Cflags from stub is correctly exported to mylib
415 ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
416 ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
417}