blob: c01c40a764d833885273b4cf4f7acc0e927273e3 [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"],
270 system_shared_libs: [],
271 stl: "none",
272 stubs: {
273 versions: ["1", "2", "3"],
274 },
275 }
276
277 cc_library {
278 name: "mylib3",
Jiyong Park28d395a2018-12-07 22:42:47 +0900279 srcs: ["mylib.cpp"],
280 shared_libs: ["mylib4"],
281 system_shared_libs: [],
Jiyong Park25fc6a92018-11-18 18:02:45 +0900282 stl: "none",
283 stubs: {
284 versions: ["10", "11", "12"],
285 },
286 }
Jiyong Park28d395a2018-12-07 22:42:47 +0900287
288 cc_library {
289 name: "mylib4",
290 srcs: ["mylib.cpp"],
291 system_shared_libs: [],
292 stl: "none",
293 }
Jiyong Park25fc6a92018-11-18 18:02:45 +0900294 `)
295
296 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
297 copyCmds := apexRule.Args["copy_commands"]
298
299 // Ensure that direct non-stubs dep is always included
Alex Light5098a612018-11-29 17:12:15 -0800300 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900301
302 // Ensure that indirect stubs dep is not included
Alex Light5098a612018-11-29 17:12:15 -0800303 ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900304
305 // Ensure that direct stubs dep is included
Alex Light5098a612018-11-29 17:12:15 -0800306 ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900307
308 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
309
310 // Ensure that mylib is linking with the latest version of stubs for mylib2
311 ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3_myapex/mylib2.so")
312 // ... and not linking to the non-stub (impl) variant of mylib2
313 ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_myapex/mylib2.so")
314
315 // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
316 ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_myapex/mylib3.so")
317 // .. and not linking to the stubs variant of mylib3
318 ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12_myapex/mylib3.so")
319}
320
321func TestApexWithSystemLibsStubs(t *testing.T) {
322 ctx := testApex(t, `
323 apex {
324 name: "myapex",
325 key: "myapex.key",
326 native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"],
327 }
328
329 apex_key {
330 name: "myapex.key",
331 public_key: "testkey.avbpubkey",
332 private_key: "testkey.pem",
333 }
334
335 cc_library {
336 name: "mylib",
337 srcs: ["mylib.cpp"],
338 shared_libs: ["libdl#27"],
339 stl: "none",
340 }
341
342 cc_library_shared {
343 name: "mylib_shared",
344 srcs: ["mylib.cpp"],
345 shared_libs: ["libdl#27"],
346 stl: "none",
347 }
348
349 cc_library {
350 name: "libc",
351 no_libgcc: true,
352 nocrt: true,
353 system_shared_libs: [],
354 stl: "none",
355 stubs: {
356 versions: ["27", "28", "29"],
357 },
358 }
359
360 cc_library {
361 name: "libm",
362 no_libgcc: true,
363 nocrt: true,
364 system_shared_libs: [],
365 stl: "none",
366 stubs: {
367 versions: ["27", "28", "29"],
368 },
369 }
370
371 cc_library {
372 name: "libdl",
373 no_libgcc: true,
374 nocrt: true,
375 system_shared_libs: [],
376 stl: "none",
377 stubs: {
378 versions: ["27", "28", "29"],
379 },
380 }
381 `)
382
383 apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
384 copyCmds := apexRule.Args["copy_commands"]
385
386 // Ensure that mylib, libm, libdl are included.
Alex Light5098a612018-11-29 17:12:15 -0800387 ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
388 ensureContains(t, copyCmds, "image.apex/lib64/libm.so")
389 ensureContains(t, copyCmds, "image.apex/lib64/libdl.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900390
391 // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
Alex Light5098a612018-11-29 17:12:15 -0800392 ensureNotContains(t, copyCmds, "image.apex/lib64/libc.so")
Jiyong Park25fc6a92018-11-18 18:02:45 +0900393
394 mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
395 mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
396 mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_myapex").Rule("cc").Args["cFlags"]
397
398 // For dependency to libc
399 // Ensure that mylib is linking with the latest version of stubs
400 ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_29_myapex/libc.so")
401 // ... and not linking to the non-stub (impl) variant
402 ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_myapex/libc.so")
403 // ... Cflags from stub is correctly exported to mylib
404 ensureContains(t, mylibCFlags, "__LIBC_API__=29")
405 ensureContains(t, mylibSharedCFlags, "__LIBC_API__=29")
406
407 // For dependency to libm
408 // Ensure that mylib is linking with the non-stub (impl) variant
409 ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_myapex/libm.so")
410 // ... and not linking to the stub variant
411 ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29_myapex/libm.so")
412 // ... and is not compiling with the stub
413 ensureNotContains(t, mylibCFlags, "__LIBM_API__=29")
414 ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29")
415
416 // For dependency to libdl
417 // Ensure that mylib is linking with the specified version of stubs
418 ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_27_myapex/libdl.so")
419 // ... and not linking to the other versions of stubs
420 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28_myapex/libdl.so")
421 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29_myapex/libdl.so")
422 // ... and not linking to the non-stub (impl) variant
423 ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_myapex/libdl.so")
424 // ... Cflags from stub is correctly exported to mylib
425 ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
426 ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
427}
Jiyong Park7c2ee712018-12-07 00:42:25 +0900428
429func TestFilesInSubDir(t *testing.T) {
430 ctx := testApex(t, `
431 apex {
432 name: "myapex",
433 key: "myapex.key",
434 prebuilts: ["myetc"],
435 }
436
437 apex_key {
438 name: "myapex.key",
439 public_key: "testkey.avbpubkey",
440 private_key: "testkey.pem",
441 }
442
443 prebuilt_etc {
444 name: "myetc",
445 src: "myprebuilt",
446 sub_dir: "foo/bar",
447 }
448 `)
449
450 generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("generateFsConfig")
451 dirs := strings.Split(generateFsRule.Args["exec_paths"], " ")
452
453 // Ensure that etc, etc/foo, and etc/foo/bar are all listed
454 ensureListContains(t, dirs, "etc")
455 ensureListContains(t, dirs, "etc/foo")
456 ensureListContains(t, dirs, "etc/foo/bar")
457}