blob: acc895fe968caaf0de6c3100b9a60c404020f4f8 [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()
Alex Lightee250722018-12-06 14:00:02 -080031 ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(ApexBundleFactory))
Jiyong Park25fc6a92018-11-18 18:02:45 +090032 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))
Jiyong Park7c2ee712018-12-07 00:42:25 +090043 ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory))
Jiyong Park25fc6a92018-11-18 18:02:45 +090044 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
45 ctx.BottomUp("link", cc.LinkageMutator).Parallel()
46 ctx.BottomUp("version", cc.VersionMutator).Parallel()
47 ctx.BottomUp("begin", cc.BeginMutator).Parallel()
48 })
49
50 ctx.Register()
51
52 bp = bp + `
53 toolchain_library {
54 name: "libcompiler_rt-extras",
55 src: "",
56 }
57
58 toolchain_library {
59 name: "libatomic",
60 src: "",
61 }
62
63 toolchain_library {
64 name: "libgcc",
65 src: "",
66 }
67
68 toolchain_library {
69 name: "libclang_rt.builtins-aarch64-android",
70 src: "",
71 }
72
73 toolchain_library {
74 name: "libclang_rt.builtins-arm-android",
75 src: "",
76 }
77
78 cc_object {
79 name: "crtbegin_so",
80 stl: "none",
81 }
82
83 cc_object {
84 name: "crtend_so",
85 stl: "none",
86 }
87
88 `
89
90 ctx.MockFileSystem(map[string][]byte{
91 "Android.bp": []byte(bp),
92 "testkey.avbpubkey": nil,
93 "testkey.pem": nil,
94 "build/target/product/security": nil,
95 "apex_manifest.json": nil,
96 "system/sepolicy/apex/myapex-file_contexts": nil,
97 "mylib.cpp": nil,
Jiyong Park7c2ee712018-12-07 00:42:25 +090098 "myprebuilt": nil,
Jiyong Park25fc6a92018-11-18 18:02:45 +090099 })
100 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
101 android.FailIfErrored(t, errs)
102 _, errs = ctx.PrepareBuildActions(config)
103 android.FailIfErrored(t, errs)
104
105 return ctx
106}
107
108func setup(t *testing.T) (config android.Config, buildDir string) {
109 buildDir, err := ioutil.TempDir("", "soong_apex_test")
110 if err != nil {
111 t.Fatal(err)
112 }
113
114 config = android.TestArchConfig(buildDir, nil)
115
116 return
117}
118
119func teardown(buildDir string) {
120 os.RemoveAll(buildDir)
121}
122
123// ensure that 'result' contains 'expected'
124func ensureContains(t *testing.T, result string, expected string) {
125 if !strings.Contains(result, expected) {
126 t.Errorf("%q is not found in %q", expected, result)
127 }
128}
129
130// ensures that 'result' does not contain 'notExpected'
131func ensureNotContains(t *testing.T, result string, notExpected string) {
132 if strings.Contains(result, notExpected) {
133 t.Errorf("%q is found in %q", notExpected, result)
134 }
135}
136
137func ensureListContains(t *testing.T, result []string, expected string) {
138 if !android.InList(expected, result) {
139 t.Errorf("%q is not found in %v", expected, result)
140 }
141}
142
143func ensureListNotContains(t *testing.T, result []string, notExpected string) {
144 if android.InList(notExpected, result) {
145 t.Errorf("%q is found in %v", notExpected, result)
146 }
147}
148
149// Minimal test
150func TestBasicApex(t *testing.T) {
151 ctx := testApex(t, `
152 apex {
153 name: "myapex",
154 key: "myapex.key",
155 native_shared_libs: ["mylib"],
156 }
157
158 apex_key {
159 name: "myapex.key",
160 public_key: "testkey.avbpubkey",
161 private_key: "testkey.pem",
162 }
163
164 cc_library {
165 name: "mylib",
166 srcs: ["mylib.cpp"],
167 shared_libs: ["mylib2"],
168 system_shared_libs: [],
169 stl: "none",
170 }
171
172 cc_library {
173 name: "mylib2",
174 srcs: ["mylib.cpp"],
175 system_shared_libs: [],
176 stl: "none",
177 }
178 `)
179
180 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
181 copyCmds := apexRule.Args["copy_commands"]
182
183 // Ensure that main rule creates an output
184 ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
185
186 // Ensure that apex variant is created for the direct dep
187 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
188
189 // Ensure that apex variant is created for the indirect dep
190 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
191
192 // Ensure that both direct and indirect deps are copied into apex
Alex Light5098a612018-11-29 17:12:15 -0800193 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
194 ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
195}
196
197func TestBasicZipApex(t *testing.T) {
198 ctx := testApex(t, `
199 apex {
200 name: "myapex",
201 key: "myapex.key",
202 payload_type: "zip",
203 native_shared_libs: ["mylib"],
204 }
205
206 apex_key {
207 name: "myapex.key",
208 public_key: "testkey.avbpubkey",
209 private_key: "testkey.pem",
210 }
211
212 cc_library {
213 name: "mylib",
214 srcs: ["mylib.cpp"],
215 shared_libs: ["mylib2"],
216 system_shared_libs: [],
217 stl: "none",
218 }
219
220 cc_library {
221 name: "mylib2",
222 srcs: ["mylib.cpp"],
223 system_shared_libs: [],
224 stl: "none",
225 }
226 `)
227
228 zipApexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("zipApexRule")
229 copyCmds := zipApexRule.Args["copy_commands"]
230
231 // Ensure that main rule creates an output
232 ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned")
233
234 // Ensure that APEX variant is created for the direct dep
235 ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
236
237 // Ensure that APEX variant is created for the indirect dep
238 ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
239
240 // Ensure that both direct and indirect deps are copied into apex
241 ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so")
242 ensureContains(t, copyCmds, "image.zipapex/lib64/mylib2.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900243}
244
245func TestApexWithStubs(t *testing.T) {
246 ctx := testApex(t, `
247 apex {
248 name: "myapex",
249 key: "myapex.key",
250 native_shared_libs: ["mylib", "mylib3"],
251 }
252
253 apex_key {
254 name: "myapex.key",
255 public_key: "testkey.avbpubkey",
256 private_key: "testkey.pem",
257 }
258
259 cc_library {
260 name: "mylib",
261 srcs: ["mylib.cpp"],
262 shared_libs: ["mylib2", "mylib3"],
263 system_shared_libs: [],
264 stl: "none",
265 }
266
267 cc_library {
268 name: "mylib2",
269 srcs: ["mylib.cpp"],
Jiyong Park64379952018-12-13 18:37:29 +0900270 cflags: ["-include mylib.h"],
Jiyong Park25fc6a92018-11-18 18:02:45 +0900271 system_shared_libs: [],
272 stl: "none",
273 stubs: {
274 versions: ["1", "2", "3"],
275 },
276 }
277
278 cc_library {
279 name: "mylib3",
Jiyong Park28d395a2018-12-07 22:42:47 +0900280 srcs: ["mylib.cpp"],
281 shared_libs: ["mylib4"],
282 system_shared_libs: [],
Jiyong Park25fc6a92018-11-18 18:02:45 +0900283 stl: "none",
284 stubs: {
285 versions: ["10", "11", "12"],
286 },
287 }
Jiyong Park28d395a2018-12-07 22:42:47 +0900288
289 cc_library {
290 name: "mylib4",
291 srcs: ["mylib.cpp"],
292 system_shared_libs: [],
293 stl: "none",
294 }
Jiyong Park25fc6a92018-11-18 18:02:45 +0900295 `)
296
297 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
298 copyCmds := apexRule.Args["copy_commands"]
299
300 // Ensure that direct non-stubs dep is always included
Alex Light5098a612018-11-29 17:12:15 -0800301 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900302
303 // Ensure that indirect stubs dep is not included
Alex Light5098a612018-11-29 17:12:15 -0800304 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900305
306 // Ensure that direct stubs dep is included
Alex Light5098a612018-11-29 17:12:15 -0800307 ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900308
309 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
310
311 // Ensure that mylib is linking with the latest version of stubs for mylib2
312 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3_myapex/mylib2.so")
313 // ... and not linking to the non-stub (impl) variant of mylib2
314 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_myapex/mylib2.so")
315
316 // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
317 ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_myapex/mylib3.so")
318 // .. and not linking to the stubs variant of mylib3
319 ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12_myapex/mylib3.so")
Jiyong Park64379952018-12-13 18:37:29 +0900320
321 // Ensure that stubs libs are built without -include flags
322 mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
323 ensureNotContains(t, mylib2Cflags, "-include ")
Jiyong Park3fd0baf2018-12-07 16:25:39 +0900324
325 // Ensure that genstub is invoked with --apex
326 ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_3_myapex").Rule("genStubSrc").Args["flags"])
Jiyong Park25fc6a92018-11-18 18:02:45 +0900327}
328
Jiyong Park0ddfcd12018-12-11 01:35:25 +0900329func TestApexWithExplicitStubsDependency(t *testing.T) {
330 ctx := testApex(t, `
331 apex {
332 name: "myapex",
333 key: "myapex.key",
334 native_shared_libs: ["mylib"],
335 }
336
337 apex_key {
338 name: "myapex.key",
339 public_key: "testkey.avbpubkey",
340 private_key: "testkey.pem",
341 }
342
343 cc_library {
344 name: "mylib",
345 srcs: ["mylib.cpp"],
346 shared_libs: ["libfoo#10"],
347 system_shared_libs: [],
348 stl: "none",
349 }
350
351 cc_library {
352 name: "libfoo",
353 srcs: ["mylib.cpp"],
354 shared_libs: ["libbar"],
355 system_shared_libs: [],
356 stl: "none",
357 stubs: {
358 versions: ["10", "20", "30"],
359 },
360 }
361
362 cc_library {
363 name: "libbar",
364 srcs: ["mylib.cpp"],
365 system_shared_libs: [],
366 stl: "none",
367 }
368
369 `)
370
371 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
372 copyCmds := apexRule.Args["copy_commands"]
373
374 // Ensure that direct non-stubs dep is always included
375 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
376
377 // Ensure that indirect stubs dep is not included
378 ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
379
380 // Ensure that dependency of stubs is not included
381 ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
382
383 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
384
385 // Ensure that mylib is linking with version 10 of libfoo
386 ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10_myapex/libfoo.so")
387 // ... and not linking to the non-stub (impl) variant of libfoo
388 ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_myapex/libfoo.so")
389
390 libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_10_myapex").Rule("ld").Args["libFlags"]
391
392 // Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
393 ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
394}
395
Jiyong Park25fc6a92018-11-18 18:02:45 +0900396func TestApexWithSystemLibsStubs(t *testing.T) {
397 ctx := testApex(t, `
398 apex {
399 name: "myapex",
400 key: "myapex.key",
401 native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"],
402 }
403
404 apex_key {
405 name: "myapex.key",
406 public_key: "testkey.avbpubkey",
407 private_key: "testkey.pem",
408 }
409
410 cc_library {
411 name: "mylib",
412 srcs: ["mylib.cpp"],
413 shared_libs: ["libdl#27"],
414 stl: "none",
415 }
416
417 cc_library_shared {
418 name: "mylib_shared",
419 srcs: ["mylib.cpp"],
420 shared_libs: ["libdl#27"],
421 stl: "none",
422 }
423
424 cc_library {
425 name: "libc",
426 no_libgcc: true,
427 nocrt: true,
428 system_shared_libs: [],
429 stl: "none",
430 stubs: {
431 versions: ["27", "28", "29"],
432 },
433 }
434
435 cc_library {
436 name: "libm",
437 no_libgcc: true,
438 nocrt: true,
439 system_shared_libs: [],
440 stl: "none",
441 stubs: {
442 versions: ["27", "28", "29"],
443 },
444 }
445
446 cc_library {
447 name: "libdl",
448 no_libgcc: true,
449 nocrt: true,
450 system_shared_libs: [],
451 stl: "none",
452 stubs: {
453 versions: ["27", "28", "29"],
454 },
455 }
456 `)
457
458 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
459 copyCmds := apexRule.Args["copy_commands"]
460
461 // Ensure that mylib, libm, libdl are included.
Alex Light5098a612018-11-29 17:12:15 -0800462 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
463 ensureContains(t, copyCmds, "image.apex/lib64/libm.so")
464 ensureContains(t, copyCmds, "image.apex/lib64/libdl.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900465
466 // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
Alex Light5098a612018-11-29 17:12:15 -0800467 ensureNotContains(t, copyCmds, "image.apex/lib64/libc.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900468
469 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
470 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
471 mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_myapex").Rule("cc").Args["cFlags"]
472
473 // For dependency to libc
474 // Ensure that mylib is linking with the latest version of stubs
475 ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_29_myapex/libc.so")
476 // ... and not linking to the non-stub (impl) variant
477 ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_myapex/libc.so")
478 // ... Cflags from stub is correctly exported to mylib
479 ensureContains(t, mylibCFlags, "__LIBC_API__=29")
480 ensureContains(t, mylibSharedCFlags, "__LIBC_API__=29")
481
482 // For dependency to libm
483 // Ensure that mylib is linking with the non-stub (impl) variant
484 ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_myapex/libm.so")
485 // ... and not linking to the stub variant
486 ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29_myapex/libm.so")
487 // ... and is not compiling with the stub
488 ensureNotContains(t, mylibCFlags, "__LIBM_API__=29")
489 ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29")
490
491 // For dependency to libdl
492 // Ensure that mylib is linking with the specified version of stubs
493 ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_27_myapex/libdl.so")
494 // ... and not linking to the other versions of stubs
495 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28_myapex/libdl.so")
496 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29_myapex/libdl.so")
497 // ... and not linking to the non-stub (impl) variant
498 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_myapex/libdl.so")
499 // ... Cflags from stub is correctly exported to mylib
500 ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
501 ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
502}
Jiyong Park7c2ee712018-12-07 00:42:25 +0900503
504func TestFilesInSubDir(t *testing.T) {
505 ctx := testApex(t, `
506 apex {
507 name: "myapex",
508 key: "myapex.key",
509 prebuilts: ["myetc"],
510 }
511
512 apex_key {
513 name: "myapex.key",
514 public_key: "testkey.avbpubkey",
515 private_key: "testkey.pem",
516 }
517
518 prebuilt_etc {
519 name: "myetc",
520 src: "myprebuilt",
521 sub_dir: "foo/bar",
522 }
523 `)
524
525 generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("generateFsConfig")
526 dirs := strings.Split(generateFsRule.Args["exec_paths"], " ")
527
528 // Ensure that etc, etc/foo, and etc/foo/bar are all listed
529 ensureListContains(t, dirs, "etc")
530 ensureListContains(t, dirs, "etc/foo")
531 ensureListContains(t, dirs, "etc/foo/bar")
532}