blob: 44abe2aa0077183db514a71c686bf79b016aee31 [file] [log] [blame]
Colin Cross0fce0ba2021-01-08 16:40:12 -08001// Copyright 2021 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 cc
16
17import (
18 "android/soong/android"
19 "fmt"
20 "path/filepath"
21 "strings"
22 "testing"
23)
24
25func TestVendorSnapshotCapture(t *testing.T) {
26 bp := `
27 cc_library {
28 name: "libvndk",
29 vendor_available: true,
30 product_available: true,
31 vndk: {
32 enabled: true,
33 },
34 nocrt: true,
35 }
36
37 cc_library {
38 name: "libvendor",
39 vendor: true,
40 nocrt: true,
41 }
42
43 cc_library {
44 name: "libvendor_available",
45 vendor_available: true,
46 nocrt: true,
47 }
48
49 cc_library_headers {
50 name: "libvendor_headers",
51 vendor_available: true,
52 nocrt: true,
53 }
54
55 cc_binary {
56 name: "vendor_bin",
57 vendor: true,
58 nocrt: true,
59 }
60
61 cc_binary {
62 name: "vendor_available_bin",
63 vendor_available: true,
64 nocrt: true,
65 }
66
67 toolchain_library {
68 name: "libb",
69 vendor_available: true,
70 src: "libb.a",
71 }
72
73 cc_object {
74 name: "obj",
75 vendor_available: true,
76 }
77
78 cc_library {
79 name: "libllndk",
80 llndk_stubs: "libllndk.llndk",
81 }
82
83 llndk_library {
84 name: "libllndk.llndk",
85 symbol_file: "",
86 }
87`
88 config := TestConfig(buildDir, android.Android, nil, bp, nil)
89 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
90 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
91 ctx := testCcWithConfig(t, config)
92
93 // Check Vendor snapshot output.
94
95 snapshotDir := "vendor-snapshot"
96 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
97 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
98
99 var jsonFiles []string
100
101 for _, arch := range [][]string{
102 []string{"arm64", "armv8-a"},
103 []string{"arm", "armv7-a-neon"},
104 } {
105 archType := arch[0]
106 archVariant := arch[1]
107 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
108
109 // For shared libraries, only non-VNDK vendor_available modules are captured
110 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
111 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
112 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
113 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
114 jsonFiles = append(jsonFiles,
115 filepath.Join(sharedDir, "libvendor.so.json"),
116 filepath.Join(sharedDir, "libvendor_available.so.json"))
117
118 // LLNDK modules are not captured
119 checkSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant)
120
121 // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
122 // Also cfi variants are captured, except for prebuilts like toolchain_library
123 staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant)
124 staticCfiVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static_cfi", archType, archVariant)
125 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
126 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
127 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
128 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant)
129 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
130 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant)
131 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
132 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
133 jsonFiles = append(jsonFiles,
134 filepath.Join(staticDir, "libb.a.json"),
135 filepath.Join(staticDir, "libvndk.a.json"),
136 filepath.Join(staticDir, "libvndk.cfi.a.json"),
137 filepath.Join(staticDir, "libvendor.a.json"),
138 filepath.Join(staticDir, "libvendor.cfi.a.json"),
139 filepath.Join(staticDir, "libvendor_available.a.json"),
140 filepath.Join(staticDir, "libvendor_available.cfi.a.json"))
141
142 // For binary executables, all vendor:true and vendor_available modules are captured.
143 if archType == "arm64" {
144 binaryVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
145 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
146 checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
147 checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
148 jsonFiles = append(jsonFiles,
149 filepath.Join(binaryDir, "vendor_bin.json"),
150 filepath.Join(binaryDir, "vendor_available_bin.json"))
151 }
152
153 // For header libraries, all vendor:true and vendor_available modules are captured.
154 headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
155 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json"))
156
157 // For object modules, all vendor:true and vendor_available modules are captured.
158 objectVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
159 objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
160 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
161 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
162 }
163
164 for _, jsonFile := range jsonFiles {
165 // verify all json files exist
166 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
167 t.Errorf("%q expected but not found", jsonFile)
168 }
169 }
170
171 // fake snapshot should have all outputs in the normal snapshot.
172 fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
173 for _, output := range snapshotSingleton.AllOutputs() {
174 fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
175 if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
176 t.Errorf("%q expected but not found", fakeOutput)
177 }
178 }
179}
180
181func TestVendorSnapshotDirected(t *testing.T) {
182 bp := `
183 cc_library_shared {
184 name: "libvendor",
185 vendor: true,
186 nocrt: true,
187 }
188
189 cc_library_shared {
190 name: "libvendor_available",
191 vendor_available: true,
192 nocrt: true,
193 }
194
195 genrule {
196 name: "libfoo_gen",
197 cmd: "",
198 out: ["libfoo.so"],
199 }
200
201 cc_prebuilt_library_shared {
202 name: "libfoo",
203 vendor: true,
204 prefer: true,
205 srcs: [":libfoo_gen"],
206 }
207
208 cc_library_shared {
209 name: "libfoo",
210 vendor: true,
211 nocrt: true,
212 }
213`
214 config := TestConfig(buildDir, android.Android, nil, bp, nil)
215 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
216 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
217 config.TestProductVariables.DirectedVendorSnapshot = true
218 config.TestProductVariables.VendorSnapshotModules = make(map[string]bool)
219 config.TestProductVariables.VendorSnapshotModules["libvendor"] = true
220 config.TestProductVariables.VendorSnapshotModules["libfoo"] = true
221 ctx := testCcWithConfig(t, config)
222
223 // Check Vendor snapshot output.
224
225 snapshotDir := "vendor-snapshot"
226 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
227 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
228
229 var includeJsonFiles []string
230 var excludeJsonFiles []string
231
232 for _, arch := range [][]string{
233 []string{"arm64", "armv8-a"},
234 []string{"arm", "armv7-a-neon"},
235 } {
236 archType := arch[0]
237 archVariant := arch[1]
238 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
239
240 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
241 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
242
243 // Included modules
244 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
245 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
246 // Check that snapshot captures "prefer: true" prebuilt
247 checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
248 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
249
250 // Excluded modules
251 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
252 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json"))
253 }
254
255 // Verify that each json file for an included module has a rule.
256 for _, jsonFile := range includeJsonFiles {
257 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
258 t.Errorf("include json file %q not found", jsonFile)
259 }
260 }
261
262 // Verify that each json file for an excluded module has no rule.
263 for _, jsonFile := range excludeJsonFiles {
264 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
265 t.Errorf("exclude json file %q found", jsonFile)
266 }
267 }
268}
269
270func TestVendorSnapshotUse(t *testing.T) {
271 frameworkBp := `
272 cc_library {
273 name: "libvndk",
274 vendor_available: true,
275 product_available: true,
276 vndk: {
277 enabled: true,
278 },
279 nocrt: true,
280 compile_multilib: "64",
281 }
282
283 cc_library {
284 name: "libvendor",
285 vendor: true,
286 nocrt: true,
287 no_libcrt: true,
288 stl: "none",
289 system_shared_libs: [],
290 compile_multilib: "64",
291 }
292
293 cc_binary {
294 name: "bin",
295 vendor: true,
296 nocrt: true,
297 no_libcrt: true,
298 stl: "none",
299 system_shared_libs: [],
300 compile_multilib: "64",
301 }
302`
303
304 vndkBp := `
305 vndk_prebuilt_shared {
306 name: "libvndk",
307 version: "BOARD",
308 target_arch: "arm64",
309 vendor_available: true,
310 product_available: true,
311 vndk: {
312 enabled: true,
313 },
314 arch: {
315 arm64: {
316 srcs: ["libvndk.so"],
317 export_include_dirs: ["include/libvndk"],
318 },
319 },
320 }
321`
322
323 vendorProprietaryBp := `
324 cc_library {
325 name: "libvendor_without_snapshot",
326 vendor: true,
327 nocrt: true,
328 no_libcrt: true,
329 stl: "none",
330 system_shared_libs: [],
331 compile_multilib: "64",
332 }
333
334 cc_library_shared {
335 name: "libclient",
336 vendor: true,
337 nocrt: true,
338 no_libcrt: true,
339 stl: "none",
340 system_shared_libs: [],
341 shared_libs: ["libvndk"],
342 static_libs: ["libvendor", "libvendor_without_snapshot"],
343 compile_multilib: "64",
344 srcs: ["client.cpp"],
345 }
346
347 cc_binary {
348 name: "bin_without_snapshot",
349 vendor: true,
350 nocrt: true,
351 no_libcrt: true,
352 stl: "none",
353 system_shared_libs: [],
354 static_libs: ["libvndk"],
355 compile_multilib: "64",
356 srcs: ["bin.cpp"],
357 }
358
359 vendor_snapshot_static {
360 name: "libvndk",
361 version: "BOARD",
362 target_arch: "arm64",
363 vendor: true,
364 arch: {
365 arm64: {
366 src: "libvndk.a",
367 export_include_dirs: ["include/libvndk"],
368 },
369 },
370 }
371
372 vendor_snapshot_shared {
373 name: "libvendor",
374 version: "BOARD",
375 target_arch: "arm64",
376 vendor: true,
377 arch: {
378 arm64: {
379 src: "libvendor.so",
380 export_include_dirs: ["include/libvendor"],
381 },
382 },
383 }
384
385 vendor_snapshot_static {
386 name: "libvendor",
387 version: "BOARD",
388 target_arch: "arm64",
389 vendor: true,
390 arch: {
391 arm64: {
392 src: "libvendor.a",
393 export_include_dirs: ["include/libvendor"],
394 },
395 },
396 }
397
398 vendor_snapshot_binary {
399 name: "bin",
400 version: "BOARD",
401 target_arch: "arm64",
402 vendor: true,
403 arch: {
404 arm64: {
405 src: "bin",
406 },
407 },
408 }
409`
410 depsBp := GatherRequiredDepsForTest(android.Android)
411
412 mockFS := map[string][]byte{
413 "deps/Android.bp": []byte(depsBp),
414 "framework/Android.bp": []byte(frameworkBp),
415 "vendor/Android.bp": []byte(vendorProprietaryBp),
416 "vendor/bin": nil,
417 "vendor/bin.cpp": nil,
418 "vendor/client.cpp": nil,
419 "vendor/include/libvndk/a.h": nil,
420 "vendor/include/libvendor/b.h": nil,
421 "vendor/libvndk.a": nil,
422 "vendor/libvendor.a": nil,
423 "vendor/libvendor.so": nil,
424 "vndk/Android.bp": []byte(vndkBp),
425 "vndk/include/libvndk/a.h": nil,
426 "vndk/libvndk.so": nil,
427 }
428
429 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
430 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
431 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
432 ctx := CreateTestContext(config)
433 ctx.Register()
434
435 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"})
436 android.FailIfErrored(t, errs)
437 _, errs = ctx.PrepareBuildActions(config)
438 android.FailIfErrored(t, errs)
439
440 sharedVariant := "android_vendor.BOARD_arm64_armv8-a_shared"
441 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
442 binaryVariant := "android_vendor.BOARD_arm64_armv8-a"
443
444 // libclient uses libvndk.vndk.BOARD.arm64, libvendor.vendor_static.BOARD.arm64, libvendor_without_snapshot
445 libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"]
446 for _, includeFlags := range []string{
447 "-Ivndk/include/libvndk", // libvndk
448 "-Ivendor/include/libvendor", // libvendor
449 } {
450 if !strings.Contains(libclientCcFlags, includeFlags) {
451 t.Errorf("flags for libclient must contain %#v, but was %#v.",
452 includeFlags, libclientCcFlags)
453 }
454 }
455
456 libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"]
457 for _, input := range [][]string{
458 []string{sharedVariant, "libvndk.vndk.BOARD.arm64"},
459 []string{staticVariant, "libvendor.vendor_static.BOARD.arm64"},
460 []string{staticVariant, "libvendor_without_snapshot"},
461 } {
462 outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
463 if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
464 t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
465 }
466 }
467
468 // bin_without_snapshot uses libvndk.vendor_static.BOARD.arm64
469 binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"]
470 if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") {
471 t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.",
472 "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags)
473 }
474
475 binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"]
476 libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.BOARD.arm64"})
477 if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
478 t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
479 libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
480 }
481
482 // libvendor.so is installed by libvendor.vendor_shared.BOARD.arm64
483 ctx.ModuleForTests("libvendor.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor.so")
484
485 // libvendor_without_snapshot.so is installed by libvendor_without_snapshot
486 ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so")
487
488 // bin is installed by bin.vendor_binary.BOARD.arm64
489 ctx.ModuleForTests("bin.vendor_binary.BOARD.arm64", binaryVariant).Output("bin")
490
491 // bin_without_snapshot is installed by bin_without_snapshot
492 ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
493
494 // libvendor and bin don't have vendor.BOARD variant
495 libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
496 if inList(sharedVariant, libvendorVariants) {
497 t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
498 }
499
500 binVariants := ctx.ModuleVariantsForTests("bin")
501 if inList(binaryVariant, binVariants) {
502 t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
503 }
504}
505
506func TestVendorSnapshotSanitizer(t *testing.T) {
507 bp := `
508 vendor_snapshot_static {
509 name: "libsnapshot",
510 vendor: true,
511 target_arch: "arm64",
512 version: "BOARD",
513 arch: {
514 arm64: {
515 src: "libsnapshot.a",
516 cfi: {
517 src: "libsnapshot.cfi.a",
518 }
519 },
520 },
521 }
522`
523 config := TestConfig(buildDir, android.Android, nil, bp, nil)
524 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
525 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
526 ctx := testCcWithConfig(t, config)
527
528 // Check non-cfi and cfi variant.
529 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
530 staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi"
531
532 staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module)
533 assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a")
534
535 staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module)
536 assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
537}
538
539func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
540 t.Helper()
541 m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
542 if m.ExcludeFromVendorSnapshot() != expected {
543 t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
544 }
545}
546
547func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
548 t.Helper()
549 m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module)
550 if m.ExcludeFromRecoverySnapshot() != expected {
551 t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected)
552 }
553}
554
555func TestVendorSnapshotExclude(t *testing.T) {
556
557 // This test verifies that the exclude_from_vendor_snapshot property
558 // makes its way from the Android.bp source file into the module data
559 // structure. It also verifies that modules are correctly included or
560 // excluded in the vendor snapshot based on their path (framework or
561 // vendor) and the exclude_from_vendor_snapshot property.
562
563 frameworkBp := `
564 cc_library_shared {
565 name: "libinclude",
566 srcs: ["src/include.cpp"],
567 vendor_available: true,
568 }
569 cc_library_shared {
570 name: "libexclude",
571 srcs: ["src/exclude.cpp"],
572 vendor: true,
573 exclude_from_vendor_snapshot: true,
574 }
575 cc_library_shared {
576 name: "libavailable_exclude",
577 srcs: ["src/exclude.cpp"],
578 vendor_available: true,
579 exclude_from_vendor_snapshot: true,
580 }
581 `
582
583 vendorProprietaryBp := `
584 cc_library_shared {
585 name: "libvendor",
586 srcs: ["vendor.cpp"],
587 vendor: true,
588 }
589 `
590
591 depsBp := GatherRequiredDepsForTest(android.Android)
592
593 mockFS := map[string][]byte{
594 "deps/Android.bp": []byte(depsBp),
595 "framework/Android.bp": []byte(frameworkBp),
596 "framework/include.cpp": nil,
597 "framework/exclude.cpp": nil,
598 "device/Android.bp": []byte(vendorProprietaryBp),
599 "device/vendor.cpp": nil,
600 }
601
602 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
603 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
604 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
605 ctx := CreateTestContext(config)
606 ctx.Register()
607
608 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
609 android.FailIfErrored(t, errs)
610 _, errs = ctx.PrepareBuildActions(config)
611 android.FailIfErrored(t, errs)
612
613 // Test an include and exclude framework module.
614 assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false)
615 assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true)
616 assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true)
617
618 // A vendor module is excluded, but by its path, not the
619 // exclude_from_vendor_snapshot property.
620 assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false)
621
622 // Verify the content of the vendor snapshot.
623
624 snapshotDir := "vendor-snapshot"
625 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
626 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
627
628 var includeJsonFiles []string
629 var excludeJsonFiles []string
630
631 for _, arch := range [][]string{
632 []string{"arm64", "armv8-a"},
633 []string{"arm", "armv7-a-neon"},
634 } {
635 archType := arch[0]
636 archVariant := arch[1]
637 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
638
639 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
640 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
641
642 // Included modules
643 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
644 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
645
646 // Excluded modules
647 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
648 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
649 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
650 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
651 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
652 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
653 }
654
655 // Verify that each json file for an included module has a rule.
656 for _, jsonFile := range includeJsonFiles {
657 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
658 t.Errorf("include json file %q not found", jsonFile)
659 }
660 }
661
662 // Verify that each json file for an excluded module has no rule.
663 for _, jsonFile := range excludeJsonFiles {
664 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
665 t.Errorf("exclude json file %q found", jsonFile)
666 }
667 }
668}
669
670func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) {
671
672 // This test verifies that using the exclude_from_vendor_snapshot
673 // property on a module in a vendor proprietary path generates an
674 // error. These modules are already excluded, so we prohibit using the
675 // property in this way, which could add to confusion.
676
677 vendorProprietaryBp := `
678 cc_library_shared {
679 name: "libvendor",
680 srcs: ["vendor.cpp"],
681 vendor: true,
682 exclude_from_vendor_snapshot: true,
683 }
684 `
685
686 depsBp := GatherRequiredDepsForTest(android.Android)
687
688 mockFS := map[string][]byte{
689 "deps/Android.bp": []byte(depsBp),
690 "device/Android.bp": []byte(vendorProprietaryBp),
691 "device/vendor.cpp": nil,
692 }
693
694 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
695 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
696 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
697 ctx := CreateTestContext(config)
698 ctx.Register()
699
700 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"})
701 android.FailIfErrored(t, errs)
702
703 _, errs = ctx.PrepareBuildActions(config)
704 android.CheckErrorsAgainstExpectations(t, errs, []string{
705 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
706 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
707 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
708 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
709 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
710 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
711 })
712}
713
714func TestRecoverySnapshotCapture(t *testing.T) {
715 bp := `
716 cc_library {
717 name: "libvndk",
718 vendor_available: true,
719 recovery_available: true,
720 product_available: true,
721 vndk: {
722 enabled: true,
723 },
724 nocrt: true,
725 }
726
727 cc_library {
728 name: "librecovery",
729 recovery: true,
730 nocrt: true,
731 }
732
733 cc_library {
734 name: "librecovery_available",
735 recovery_available: true,
736 nocrt: true,
737 }
738
739 cc_library_headers {
740 name: "librecovery_headers",
741 recovery_available: true,
742 nocrt: true,
743 }
744
745 cc_binary {
746 name: "recovery_bin",
747 recovery: true,
748 nocrt: true,
749 }
750
751 cc_binary {
752 name: "recovery_available_bin",
753 recovery_available: true,
754 nocrt: true,
755 }
756
757 toolchain_library {
758 name: "libb",
759 recovery_available: true,
760 src: "libb.a",
761 }
762
763 cc_object {
764 name: "obj",
765 recovery_available: true,
766 }
767`
768 config := TestConfig(buildDir, android.Android, nil, bp, nil)
769 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
770 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
771 ctx := testCcWithConfig(t, config)
772
773 // Check Recovery snapshot output.
774
775 snapshotDir := "recovery-snapshot"
776 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
777 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
778
779 var jsonFiles []string
780
781 for _, arch := range [][]string{
782 []string{"arm64", "armv8-a"},
783 } {
784 archType := arch[0]
785 archVariant := arch[1]
786 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
787
788 // For shared libraries, only recovery_available modules are captured.
789 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
790 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
791 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant)
792 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
793 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
794 jsonFiles = append(jsonFiles,
795 filepath.Join(sharedDir, "libvndk.so.json"),
796 filepath.Join(sharedDir, "librecovery.so.json"),
797 filepath.Join(sharedDir, "librecovery_available.so.json"))
798
799 // For static libraries, all recovery:true and recovery_available modules are captured.
800 staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant)
801 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
802 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
803 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
804 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
805 jsonFiles = append(jsonFiles,
806 filepath.Join(staticDir, "libb.a.json"),
807 filepath.Join(staticDir, "librecovery.a.json"),
808 filepath.Join(staticDir, "librecovery_available.a.json"))
809
810 // For binary executables, all recovery:true and recovery_available modules are captured.
811 if archType == "arm64" {
812 binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
813 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
814 checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
815 checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
816 jsonFiles = append(jsonFiles,
817 filepath.Join(binaryDir, "recovery_bin.json"),
818 filepath.Join(binaryDir, "recovery_available_bin.json"))
819 }
820
821 // For header libraries, all vendor:true and vendor_available modules are captured.
822 headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
823 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json"))
824
825 // For object modules, all vendor:true and vendor_available modules are captured.
826 objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
827 objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
828 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
829 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
830 }
831
832 for _, jsonFile := range jsonFiles {
833 // verify all json files exist
834 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
835 t.Errorf("%q expected but not found", jsonFile)
836 }
837 }
838}
839
840func TestRecoverySnapshotExclude(t *testing.T) {
841 // This test verifies that the exclude_from_recovery_snapshot property
842 // makes its way from the Android.bp source file into the module data
843 // structure. It also verifies that modules are correctly included or
844 // excluded in the recovery snapshot based on their path (framework or
845 // vendor) and the exclude_from_recovery_snapshot property.
846
847 frameworkBp := `
848 cc_library_shared {
849 name: "libinclude",
850 srcs: ["src/include.cpp"],
851 recovery_available: true,
852 }
853 cc_library_shared {
854 name: "libexclude",
855 srcs: ["src/exclude.cpp"],
856 recovery: true,
857 exclude_from_recovery_snapshot: true,
858 }
859 cc_library_shared {
860 name: "libavailable_exclude",
861 srcs: ["src/exclude.cpp"],
862 recovery_available: true,
863 exclude_from_recovery_snapshot: true,
864 }
865 `
866
867 vendorProprietaryBp := `
868 cc_library_shared {
869 name: "librecovery",
870 srcs: ["recovery.cpp"],
871 recovery: true,
872 }
873 `
874
875 depsBp := GatherRequiredDepsForTest(android.Android)
876
877 mockFS := map[string][]byte{
878 "deps/Android.bp": []byte(depsBp),
879 "framework/Android.bp": []byte(frameworkBp),
880 "framework/include.cpp": nil,
881 "framework/exclude.cpp": nil,
882 "device/Android.bp": []byte(vendorProprietaryBp),
883 "device/recovery.cpp": nil,
884 }
885
886 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
887 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
888 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
889 ctx := CreateTestContext(config)
890 ctx.Register()
891
892 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
893 android.FailIfErrored(t, errs)
894 _, errs = ctx.PrepareBuildActions(config)
895 android.FailIfErrored(t, errs)
896
897 // Test an include and exclude framework module.
898 assertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false)
899 assertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true)
900 assertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true)
901
902 // A recovery module is excluded, but by its path, not the
903 // exclude_from_recovery_snapshot property.
904 assertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false)
905
906 // Verify the content of the recovery snapshot.
907
908 snapshotDir := "recovery-snapshot"
909 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
910 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
911
912 var includeJsonFiles []string
913 var excludeJsonFiles []string
914
915 for _, arch := range [][]string{
916 []string{"arm64", "armv8-a"},
917 } {
918 archType := arch[0]
919 archVariant := arch[1]
920 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
921
922 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
923 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
924
925 // Included modules
926 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
927 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
928
929 // Excluded modules
930 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
931 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
932 checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
933 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
934 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
935 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
936 }
937
938 // Verify that each json file for an included module has a rule.
939 for _, jsonFile := range includeJsonFiles {
940 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
941 t.Errorf("include json file %q not found", jsonFile)
942 }
943 }
944
945 // Verify that each json file for an excluded module has no rule.
946 for _, jsonFile := range excludeJsonFiles {
947 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
948 t.Errorf("exclude json file %q found", jsonFile)
949 }
950 }
951}