From 0fce0bab128bc42a9490e71ba2389714cbbf8076 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 8 Jan 2021 16:40:12 -0800 Subject: [PATCH 1/2] Move vendor snapshot tests into vendor_snapshot_test.go Move the vendor snapshot tests into vendor_snapshot_test.go to reduce the size of cc_test.go Bug: 177098205 Test: go test ./build/soong/cc/... Change-Id: Ib1120f986fc0111a9487fce00539a4c5ae7e2e87 --- cc/Android.bp | 1 + cc/cc_test.go | 928 ------------------------------------ cc/vendor_snapshot_test.go | 951 +++++++++++++++++++++++++++++++++++++ 3 files changed, 952 insertions(+), 928 deletions(-) create mode 100644 cc/vendor_snapshot_test.go diff --git a/cc/Android.bp b/cc/Android.bp index 33f3db22a..6ec7e0ee7 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -87,6 +87,7 @@ bootstrap_go_package { "prebuilt_test.go", "proto_test.go", "test_data_test.go", + "vendor_snapshot_test.go", ], pluginFor: ["soong_build"], } diff --git a/cc/cc_test.go b/cc/cc_test.go index d0d875996..7288cc476 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -1110,934 +1110,6 @@ func TestDoubleLoadbleDep(t *testing.T) { `) } -func TestVendorSnapshotCapture(t *testing.T) { - bp := ` - cc_library { - name: "libvndk", - vendor_available: true, - product_available: true, - vndk: { - enabled: true, - }, - nocrt: true, - } - - cc_library { - name: "libvendor", - vendor: true, - nocrt: true, - } - - cc_library { - name: "libvendor_available", - vendor_available: true, - nocrt: true, - } - - cc_library_headers { - name: "libvendor_headers", - vendor_available: true, - nocrt: true, - } - - cc_binary { - name: "vendor_bin", - vendor: true, - nocrt: true, - } - - cc_binary { - name: "vendor_available_bin", - vendor_available: true, - nocrt: true, - } - - toolchain_library { - name: "libb", - vendor_available: true, - src: "libb.a", - } - - cc_object { - name: "obj", - vendor_available: true, - } - - cc_library { - name: "libllndk", - llndk_stubs: "libllndk.llndk", - } - - llndk_library { - name: "libllndk.llndk", - symbol_file: "", - } -` - config := TestConfig(buildDir, android.Android, nil, bp, nil) - config.TestProductVariables.DeviceVndkVersion = StringPtr("current") - config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - ctx := testCcWithConfig(t, config) - - // Check Vendor snapshot output. - - snapshotDir := "vendor-snapshot" - snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") - snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") - - var jsonFiles []string - - for _, arch := range [][]string{ - []string{"arm64", "armv8-a"}, - []string{"arm", "armv7-a-neon"}, - } { - archType := arch[0] - archVariant := arch[1] - archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) - - // For shared libraries, only non-VNDK vendor_available modules are captured - sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant) - sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") - checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) - checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant) - jsonFiles = append(jsonFiles, - filepath.Join(sharedDir, "libvendor.so.json"), - filepath.Join(sharedDir, "libvendor_available.so.json")) - - // LLNDK modules are not captured - checkSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant) - - // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured. - // Also cfi variants are captured, except for prebuilts like toolchain_library - staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant) - staticCfiVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static_cfi", archType, archVariant) - staticDir := filepath.Join(snapshotVariantPath, archDir, "static") - checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant) - checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant) - checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant) - checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant) - checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant) - checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant) - checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant) - jsonFiles = append(jsonFiles, - filepath.Join(staticDir, "libb.a.json"), - filepath.Join(staticDir, "libvndk.a.json"), - filepath.Join(staticDir, "libvndk.cfi.a.json"), - filepath.Join(staticDir, "libvendor.a.json"), - filepath.Join(staticDir, "libvendor.cfi.a.json"), - filepath.Join(staticDir, "libvendor_available.a.json"), - filepath.Join(staticDir, "libvendor_available.cfi.a.json")) - - // For binary executables, all vendor:true and vendor_available modules are captured. - if archType == "arm64" { - binaryVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant) - binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") - checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant) - checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant) - jsonFiles = append(jsonFiles, - filepath.Join(binaryDir, "vendor_bin.json"), - filepath.Join(binaryDir, "vendor_available_bin.json")) - } - - // For header libraries, all vendor:true and vendor_available modules are captured. - headerDir := filepath.Join(snapshotVariantPath, archDir, "header") - jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json")) - - // For object modules, all vendor:true and vendor_available modules are captured. - objectVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant) - objectDir := filepath.Join(snapshotVariantPath, archDir, "object") - checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant) - jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json")) - } - - for _, jsonFile := range jsonFiles { - // verify all json files exist - if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { - t.Errorf("%q expected but not found", jsonFile) - } - } - - // fake snapshot should have all outputs in the normal snapshot. - fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot") - for _, output := range snapshotSingleton.AllOutputs() { - fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1) - if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil { - t.Errorf("%q expected but not found", fakeOutput) - } - } -} - -func TestVendorSnapshotDirected(t *testing.T) { - bp := ` - cc_library_shared { - name: "libvendor", - vendor: true, - nocrt: true, - } - - cc_library_shared { - name: "libvendor_available", - vendor_available: true, - nocrt: true, - } - - genrule { - name: "libfoo_gen", - cmd: "", - out: ["libfoo.so"], - } - - cc_prebuilt_library_shared { - name: "libfoo", - vendor: true, - prefer: true, - srcs: [":libfoo_gen"], - } - - cc_library_shared { - name: "libfoo", - vendor: true, - nocrt: true, - } -` - config := TestConfig(buildDir, android.Android, nil, bp, nil) - config.TestProductVariables.DeviceVndkVersion = StringPtr("current") - config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - config.TestProductVariables.DirectedVendorSnapshot = true - config.TestProductVariables.VendorSnapshotModules = make(map[string]bool) - config.TestProductVariables.VendorSnapshotModules["libvendor"] = true - config.TestProductVariables.VendorSnapshotModules["libfoo"] = true - ctx := testCcWithConfig(t, config) - - // Check Vendor snapshot output. - - snapshotDir := "vendor-snapshot" - snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") - snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") - - var includeJsonFiles []string - var excludeJsonFiles []string - - for _, arch := range [][]string{ - []string{"arm64", "armv8-a"}, - []string{"arm", "armv7-a-neon"}, - } { - archType := arch[0] - archVariant := arch[1] - archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) - - sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant) - sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") - - // Included modules - checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) - includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json")) - // Check that snapshot captures "prefer: true" prebuilt - checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant) - includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json")) - - // Excluded modules - checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant) - excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json")) - } - - // Verify that each json file for an included module has a rule. - for _, jsonFile := range includeJsonFiles { - if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { - t.Errorf("include json file %q not found", jsonFile) - } - } - - // Verify that each json file for an excluded module has no rule. - for _, jsonFile := range excludeJsonFiles { - if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { - t.Errorf("exclude json file %q found", jsonFile) - } - } -} - -func TestVendorSnapshotUse(t *testing.T) { - frameworkBp := ` - cc_library { - name: "libvndk", - vendor_available: true, - product_available: true, - vndk: { - enabled: true, - }, - nocrt: true, - compile_multilib: "64", - } - - cc_library { - name: "libvendor", - vendor: true, - nocrt: true, - no_libcrt: true, - stl: "none", - system_shared_libs: [], - compile_multilib: "64", - } - - cc_binary { - name: "bin", - vendor: true, - nocrt: true, - no_libcrt: true, - stl: "none", - system_shared_libs: [], - compile_multilib: "64", - } -` - - vndkBp := ` - vndk_prebuilt_shared { - name: "libvndk", - version: "BOARD", - target_arch: "arm64", - vendor_available: true, - product_available: true, - vndk: { - enabled: true, - }, - arch: { - arm64: { - srcs: ["libvndk.so"], - export_include_dirs: ["include/libvndk"], - }, - }, - } -` - - vendorProprietaryBp := ` - cc_library { - name: "libvendor_without_snapshot", - vendor: true, - nocrt: true, - no_libcrt: true, - stl: "none", - system_shared_libs: [], - compile_multilib: "64", - } - - cc_library_shared { - name: "libclient", - vendor: true, - nocrt: true, - no_libcrt: true, - stl: "none", - system_shared_libs: [], - shared_libs: ["libvndk"], - static_libs: ["libvendor", "libvendor_without_snapshot"], - compile_multilib: "64", - srcs: ["client.cpp"], - } - - cc_binary { - name: "bin_without_snapshot", - vendor: true, - nocrt: true, - no_libcrt: true, - stl: "none", - system_shared_libs: [], - static_libs: ["libvndk"], - compile_multilib: "64", - srcs: ["bin.cpp"], - } - - vendor_snapshot_static { - name: "libvndk", - version: "BOARD", - target_arch: "arm64", - vendor: true, - arch: { - arm64: { - src: "libvndk.a", - export_include_dirs: ["include/libvndk"], - }, - }, - } - - vendor_snapshot_shared { - name: "libvendor", - version: "BOARD", - target_arch: "arm64", - vendor: true, - arch: { - arm64: { - src: "libvendor.so", - export_include_dirs: ["include/libvendor"], - }, - }, - } - - vendor_snapshot_static { - name: "libvendor", - version: "BOARD", - target_arch: "arm64", - vendor: true, - arch: { - arm64: { - src: "libvendor.a", - export_include_dirs: ["include/libvendor"], - }, - }, - } - - vendor_snapshot_binary { - name: "bin", - version: "BOARD", - target_arch: "arm64", - vendor: true, - arch: { - arm64: { - src: "bin", - }, - }, - } -` - depsBp := GatherRequiredDepsForTest(android.Android) - - mockFS := map[string][]byte{ - "deps/Android.bp": []byte(depsBp), - "framework/Android.bp": []byte(frameworkBp), - "vendor/Android.bp": []byte(vendorProprietaryBp), - "vendor/bin": nil, - "vendor/bin.cpp": nil, - "vendor/client.cpp": nil, - "vendor/include/libvndk/a.h": nil, - "vendor/include/libvendor/b.h": nil, - "vendor/libvndk.a": nil, - "vendor/libvendor.a": nil, - "vendor/libvendor.so": nil, - "vndk/Android.bp": []byte(vndkBp), - "vndk/include/libvndk/a.h": nil, - "vndk/libvndk.so": nil, - } - - config := TestConfig(buildDir, android.Android, nil, "", mockFS) - config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD") - config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - ctx := CreateTestContext(config) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"}) - android.FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - android.FailIfErrored(t, errs) - - sharedVariant := "android_vendor.BOARD_arm64_armv8-a_shared" - staticVariant := "android_vendor.BOARD_arm64_armv8-a_static" - binaryVariant := "android_vendor.BOARD_arm64_armv8-a" - - // libclient uses libvndk.vndk.BOARD.arm64, libvendor.vendor_static.BOARD.arm64, libvendor_without_snapshot - libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"] - for _, includeFlags := range []string{ - "-Ivndk/include/libvndk", // libvndk - "-Ivendor/include/libvendor", // libvendor - } { - if !strings.Contains(libclientCcFlags, includeFlags) { - t.Errorf("flags for libclient must contain %#v, but was %#v.", - includeFlags, libclientCcFlags) - } - } - - libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"] - for _, input := range [][]string{ - []string{sharedVariant, "libvndk.vndk.BOARD.arm64"}, - []string{staticVariant, "libvendor.vendor_static.BOARD.arm64"}, - []string{staticVariant, "libvendor_without_snapshot"}, - } { - outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */) - if !strings.Contains(libclientLdFlags, outputPaths[0].String()) { - t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags) - } - } - - // bin_without_snapshot uses libvndk.vendor_static.BOARD.arm64 - binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"] - if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") { - t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.", - "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags) - } - - binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"] - libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.BOARD.arm64"}) - if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) { - t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v", - libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags) - } - - // libvendor.so is installed by libvendor.vendor_shared.BOARD.arm64 - ctx.ModuleForTests("libvendor.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor.so") - - // libvendor_without_snapshot.so is installed by libvendor_without_snapshot - ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so") - - // bin is installed by bin.vendor_binary.BOARD.arm64 - ctx.ModuleForTests("bin.vendor_binary.BOARD.arm64", binaryVariant).Output("bin") - - // bin_without_snapshot is installed by bin_without_snapshot - ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot") - - // libvendor and bin don't have vendor.BOARD variant - libvendorVariants := ctx.ModuleVariantsForTests("libvendor") - if inList(sharedVariant, libvendorVariants) { - t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant) - } - - binVariants := ctx.ModuleVariantsForTests("bin") - if inList(binaryVariant, binVariants) { - t.Errorf("bin must not have variant %#v, but it does", sharedVariant) - } -} - -func TestVendorSnapshotSanitizer(t *testing.T) { - bp := ` - vendor_snapshot_static { - name: "libsnapshot", - vendor: true, - target_arch: "arm64", - version: "BOARD", - arch: { - arm64: { - src: "libsnapshot.a", - cfi: { - src: "libsnapshot.cfi.a", - } - }, - }, - } -` - config := TestConfig(buildDir, android.Android, nil, bp, nil) - config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD") - config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - ctx := testCcWithConfig(t, config) - - // Check non-cfi and cfi variant. - staticVariant := "android_vendor.BOARD_arm64_armv8-a_static" - staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi" - - staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module) - assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a") - - staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module) - assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a") -} - -func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) { - t.Helper() - m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module) - if m.ExcludeFromVendorSnapshot() != expected { - t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected) - } -} - -func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) { - t.Helper() - m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module) - if m.ExcludeFromRecoverySnapshot() != expected { - t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected) - } -} - -func TestVendorSnapshotExclude(t *testing.T) { - - // This test verifies that the exclude_from_vendor_snapshot property - // makes its way from the Android.bp source file into the module data - // structure. It also verifies that modules are correctly included or - // excluded in the vendor snapshot based on their path (framework or - // vendor) and the exclude_from_vendor_snapshot property. - - frameworkBp := ` - cc_library_shared { - name: "libinclude", - srcs: ["src/include.cpp"], - vendor_available: true, - } - cc_library_shared { - name: "libexclude", - srcs: ["src/exclude.cpp"], - vendor: true, - exclude_from_vendor_snapshot: true, - } - cc_library_shared { - name: "libavailable_exclude", - srcs: ["src/exclude.cpp"], - vendor_available: true, - exclude_from_vendor_snapshot: true, - } - ` - - vendorProprietaryBp := ` - cc_library_shared { - name: "libvendor", - srcs: ["vendor.cpp"], - vendor: true, - } - ` - - depsBp := GatherRequiredDepsForTest(android.Android) - - mockFS := map[string][]byte{ - "deps/Android.bp": []byte(depsBp), - "framework/Android.bp": []byte(frameworkBp), - "framework/include.cpp": nil, - "framework/exclude.cpp": nil, - "device/Android.bp": []byte(vendorProprietaryBp), - "device/vendor.cpp": nil, - } - - config := TestConfig(buildDir, android.Android, nil, "", mockFS) - config.TestProductVariables.DeviceVndkVersion = StringPtr("current") - config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - ctx := CreateTestContext(config) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"}) - android.FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - android.FailIfErrored(t, errs) - - // Test an include and exclude framework module. - assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false) - assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true) - assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true) - - // A vendor module is excluded, but by its path, not the - // exclude_from_vendor_snapshot property. - assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false) - - // Verify the content of the vendor snapshot. - - snapshotDir := "vendor-snapshot" - snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") - snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") - - var includeJsonFiles []string - var excludeJsonFiles []string - - for _, arch := range [][]string{ - []string{"arm64", "armv8-a"}, - []string{"arm", "armv7-a-neon"}, - } { - archType := arch[0] - archVariant := arch[1] - archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) - - sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant) - sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") - - // Included modules - checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant) - includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json")) - - // Excluded modules - checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant) - excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json")) - checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) - excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json")) - checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant) - excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json")) - } - - // Verify that each json file for an included module has a rule. - for _, jsonFile := range includeJsonFiles { - if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { - t.Errorf("include json file %q not found", jsonFile) - } - } - - // Verify that each json file for an excluded module has no rule. - for _, jsonFile := range excludeJsonFiles { - if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { - t.Errorf("exclude json file %q found", jsonFile) - } - } -} - -func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) { - - // This test verifies that using the exclude_from_vendor_snapshot - // property on a module in a vendor proprietary path generates an - // error. These modules are already excluded, so we prohibit using the - // property in this way, which could add to confusion. - - vendorProprietaryBp := ` - cc_library_shared { - name: "libvendor", - srcs: ["vendor.cpp"], - vendor: true, - exclude_from_vendor_snapshot: true, - } - ` - - depsBp := GatherRequiredDepsForTest(android.Android) - - mockFS := map[string][]byte{ - "deps/Android.bp": []byte(depsBp), - "device/Android.bp": []byte(vendorProprietaryBp), - "device/vendor.cpp": nil, - } - - config := TestConfig(buildDir, android.Android, nil, "", mockFS) - config.TestProductVariables.DeviceVndkVersion = StringPtr("current") - config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - ctx := CreateTestContext(config) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"}) - android.FailIfErrored(t, errs) - - _, errs = ctx.PrepareBuildActions(config) - android.CheckErrorsAgainstExpectations(t, errs, []string{ - `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, - `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, - `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, - `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, - `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, - `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, - }) -} - -func TestRecoverySnapshotCapture(t *testing.T) { - bp := ` - cc_library { - name: "libvndk", - vendor_available: true, - recovery_available: true, - product_available: true, - vndk: { - enabled: true, - }, - nocrt: true, - } - - cc_library { - name: "librecovery", - recovery: true, - nocrt: true, - } - - cc_library { - name: "librecovery_available", - recovery_available: true, - nocrt: true, - } - - cc_library_headers { - name: "librecovery_headers", - recovery_available: true, - nocrt: true, - } - - cc_binary { - name: "recovery_bin", - recovery: true, - nocrt: true, - } - - cc_binary { - name: "recovery_available_bin", - recovery_available: true, - nocrt: true, - } - - toolchain_library { - name: "libb", - recovery_available: true, - src: "libb.a", - } - - cc_object { - name: "obj", - recovery_available: true, - } -` - config := TestConfig(buildDir, android.Android, nil, bp, nil) - config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current") - config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - ctx := testCcWithConfig(t, config) - - // Check Recovery snapshot output. - - snapshotDir := "recovery-snapshot" - snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") - snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") - - var jsonFiles []string - - for _, arch := range [][]string{ - []string{"arm64", "armv8-a"}, - } { - archType := arch[0] - archVariant := arch[1] - archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) - - // For shared libraries, only recovery_available modules are captured. - sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) - sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") - checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant) - checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) - checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant) - jsonFiles = append(jsonFiles, - filepath.Join(sharedDir, "libvndk.so.json"), - filepath.Join(sharedDir, "librecovery.so.json"), - filepath.Join(sharedDir, "librecovery_available.so.json")) - - // For static libraries, all recovery:true and recovery_available modules are captured. - staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant) - staticDir := filepath.Join(snapshotVariantPath, archDir, "static") - checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant) - checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant) - checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant) - jsonFiles = append(jsonFiles, - filepath.Join(staticDir, "libb.a.json"), - filepath.Join(staticDir, "librecovery.a.json"), - filepath.Join(staticDir, "librecovery_available.a.json")) - - // For binary executables, all recovery:true and recovery_available modules are captured. - if archType == "arm64" { - binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant) - binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") - checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant) - checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant) - jsonFiles = append(jsonFiles, - filepath.Join(binaryDir, "recovery_bin.json"), - filepath.Join(binaryDir, "recovery_available_bin.json")) - } - - // For header libraries, all vendor:true and vendor_available modules are captured. - headerDir := filepath.Join(snapshotVariantPath, archDir, "header") - jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json")) - - // For object modules, all vendor:true and vendor_available modules are captured. - objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant) - objectDir := filepath.Join(snapshotVariantPath, archDir, "object") - checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant) - jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json")) - } - - for _, jsonFile := range jsonFiles { - // verify all json files exist - if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { - t.Errorf("%q expected but not found", jsonFile) - } - } -} - -func TestRecoverySnapshotExclude(t *testing.T) { - // This test verifies that the exclude_from_recovery_snapshot property - // makes its way from the Android.bp source file into the module data - // structure. It also verifies that modules are correctly included or - // excluded in the recovery snapshot based on their path (framework or - // vendor) and the exclude_from_recovery_snapshot property. - - frameworkBp := ` - cc_library_shared { - name: "libinclude", - srcs: ["src/include.cpp"], - recovery_available: true, - } - cc_library_shared { - name: "libexclude", - srcs: ["src/exclude.cpp"], - recovery: true, - exclude_from_recovery_snapshot: true, - } - cc_library_shared { - name: "libavailable_exclude", - srcs: ["src/exclude.cpp"], - recovery_available: true, - exclude_from_recovery_snapshot: true, - } - ` - - vendorProprietaryBp := ` - cc_library_shared { - name: "librecovery", - srcs: ["recovery.cpp"], - recovery: true, - } - ` - - depsBp := GatherRequiredDepsForTest(android.Android) - - mockFS := map[string][]byte{ - "deps/Android.bp": []byte(depsBp), - "framework/Android.bp": []byte(frameworkBp), - "framework/include.cpp": nil, - "framework/exclude.cpp": nil, - "device/Android.bp": []byte(vendorProprietaryBp), - "device/recovery.cpp": nil, - } - - config := TestConfig(buildDir, android.Android, nil, "", mockFS) - config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current") - config.TestProductVariables.Platform_vndk_version = StringPtr("VER") - ctx := CreateTestContext(config) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"}) - android.FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - android.FailIfErrored(t, errs) - - // Test an include and exclude framework module. - assertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false) - assertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true) - assertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true) - - // A recovery module is excluded, but by its path, not the - // exclude_from_recovery_snapshot property. - assertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false) - - // Verify the content of the recovery snapshot. - - snapshotDir := "recovery-snapshot" - snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") - snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") - - var includeJsonFiles []string - var excludeJsonFiles []string - - for _, arch := range [][]string{ - []string{"arm64", "armv8-a"}, - } { - archType := arch[0] - archVariant := arch[1] - archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) - - sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) - sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") - - // Included modules - checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant) - includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json")) - - // Excluded modules - checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant) - excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json")) - checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) - excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json")) - checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant) - excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json")) - } - - // Verify that each json file for an included module has a rule. - for _, jsonFile := range includeJsonFiles { - if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { - t.Errorf("include json file %q not found", jsonFile) - } - } - - // Verify that each json file for an excluded module has no rule. - for _, jsonFile := range excludeJsonFiles { - if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { - t.Errorf("exclude json file %q found", jsonFile) - } - } -} - func TestDoubleLoadableDepError(t *testing.T) { // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib. testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", ` diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go new file mode 100644 index 000000000..44abe2aa0 --- /dev/null +++ b/cc/vendor_snapshot_test.go @@ -0,0 +1,951 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cc + +import ( + "android/soong/android" + "fmt" + "path/filepath" + "strings" + "testing" +) + +func TestVendorSnapshotCapture(t *testing.T) { + bp := ` + cc_library { + name: "libvndk", + vendor_available: true, + product_available: true, + vndk: { + enabled: true, + }, + nocrt: true, + } + + cc_library { + name: "libvendor", + vendor: true, + nocrt: true, + } + + cc_library { + name: "libvendor_available", + vendor_available: true, + nocrt: true, + } + + cc_library_headers { + name: "libvendor_headers", + vendor_available: true, + nocrt: true, + } + + cc_binary { + name: "vendor_bin", + vendor: true, + nocrt: true, + } + + cc_binary { + name: "vendor_available_bin", + vendor_available: true, + nocrt: true, + } + + toolchain_library { + name: "libb", + vendor_available: true, + src: "libb.a", + } + + cc_object { + name: "obj", + vendor_available: true, + } + + cc_library { + name: "libllndk", + llndk_stubs: "libllndk.llndk", + } + + llndk_library { + name: "libllndk.llndk", + symbol_file: "", + } +` + config := TestConfig(buildDir, android.Android, nil, bp, nil) + config.TestProductVariables.DeviceVndkVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := testCcWithConfig(t, config) + + // Check Vendor snapshot output. + + snapshotDir := "vendor-snapshot" + snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") + snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") + + var jsonFiles []string + + for _, arch := range [][]string{ + []string{"arm64", "armv8-a"}, + []string{"arm", "armv7-a-neon"}, + } { + archType := arch[0] + archVariant := arch[1] + archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) + + // For shared libraries, only non-VNDK vendor_available modules are captured + sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant) + sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") + checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant) + jsonFiles = append(jsonFiles, + filepath.Join(sharedDir, "libvendor.so.json"), + filepath.Join(sharedDir, "libvendor_available.so.json")) + + // LLNDK modules are not captured + checkSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant) + + // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured. + // Also cfi variants are captured, except for prebuilts like toolchain_library + staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant) + staticCfiVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static_cfi", archType, archVariant) + staticDir := filepath.Join(snapshotVariantPath, archDir, "static") + checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant) + jsonFiles = append(jsonFiles, + filepath.Join(staticDir, "libb.a.json"), + filepath.Join(staticDir, "libvndk.a.json"), + filepath.Join(staticDir, "libvndk.cfi.a.json"), + filepath.Join(staticDir, "libvendor.a.json"), + filepath.Join(staticDir, "libvendor.cfi.a.json"), + filepath.Join(staticDir, "libvendor_available.a.json"), + filepath.Join(staticDir, "libvendor_available.cfi.a.json")) + + // For binary executables, all vendor:true and vendor_available modules are captured. + if archType == "arm64" { + binaryVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant) + binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") + checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant) + checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant) + jsonFiles = append(jsonFiles, + filepath.Join(binaryDir, "vendor_bin.json"), + filepath.Join(binaryDir, "vendor_available_bin.json")) + } + + // For header libraries, all vendor:true and vendor_available modules are captured. + headerDir := filepath.Join(snapshotVariantPath, archDir, "header") + jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json")) + + // For object modules, all vendor:true and vendor_available modules are captured. + objectVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant) + objectDir := filepath.Join(snapshotVariantPath, archDir, "object") + checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant) + jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json")) + } + + for _, jsonFile := range jsonFiles { + // verify all json files exist + if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { + t.Errorf("%q expected but not found", jsonFile) + } + } + + // fake snapshot should have all outputs in the normal snapshot. + fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot") + for _, output := range snapshotSingleton.AllOutputs() { + fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1) + if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil { + t.Errorf("%q expected but not found", fakeOutput) + } + } +} + +func TestVendorSnapshotDirected(t *testing.T) { + bp := ` + cc_library_shared { + name: "libvendor", + vendor: true, + nocrt: true, + } + + cc_library_shared { + name: "libvendor_available", + vendor_available: true, + nocrt: true, + } + + genrule { + name: "libfoo_gen", + cmd: "", + out: ["libfoo.so"], + } + + cc_prebuilt_library_shared { + name: "libfoo", + vendor: true, + prefer: true, + srcs: [":libfoo_gen"], + } + + cc_library_shared { + name: "libfoo", + vendor: true, + nocrt: true, + } +` + config := TestConfig(buildDir, android.Android, nil, bp, nil) + config.TestProductVariables.DeviceVndkVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + config.TestProductVariables.DirectedVendorSnapshot = true + config.TestProductVariables.VendorSnapshotModules = make(map[string]bool) + config.TestProductVariables.VendorSnapshotModules["libvendor"] = true + config.TestProductVariables.VendorSnapshotModules["libfoo"] = true + ctx := testCcWithConfig(t, config) + + // Check Vendor snapshot output. + + snapshotDir := "vendor-snapshot" + snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") + snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") + + var includeJsonFiles []string + var excludeJsonFiles []string + + for _, arch := range [][]string{ + []string{"arm64", "armv8-a"}, + []string{"arm", "armv7-a-neon"}, + } { + archType := arch[0] + archVariant := arch[1] + archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) + + sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant) + sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") + + // Included modules + checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) + includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json")) + // Check that snapshot captures "prefer: true" prebuilt + checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant) + includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json")) + + // Excluded modules + checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant) + excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json")) + } + + // Verify that each json file for an included module has a rule. + for _, jsonFile := range includeJsonFiles { + if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { + t.Errorf("include json file %q not found", jsonFile) + } + } + + // Verify that each json file for an excluded module has no rule. + for _, jsonFile := range excludeJsonFiles { + if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { + t.Errorf("exclude json file %q found", jsonFile) + } + } +} + +func TestVendorSnapshotUse(t *testing.T) { + frameworkBp := ` + cc_library { + name: "libvndk", + vendor_available: true, + product_available: true, + vndk: { + enabled: true, + }, + nocrt: true, + compile_multilib: "64", + } + + cc_library { + name: "libvendor", + vendor: true, + nocrt: true, + no_libcrt: true, + stl: "none", + system_shared_libs: [], + compile_multilib: "64", + } + + cc_binary { + name: "bin", + vendor: true, + nocrt: true, + no_libcrt: true, + stl: "none", + system_shared_libs: [], + compile_multilib: "64", + } +` + + vndkBp := ` + vndk_prebuilt_shared { + name: "libvndk", + version: "BOARD", + target_arch: "arm64", + vendor_available: true, + product_available: true, + vndk: { + enabled: true, + }, + arch: { + arm64: { + srcs: ["libvndk.so"], + export_include_dirs: ["include/libvndk"], + }, + }, + } +` + + vendorProprietaryBp := ` + cc_library { + name: "libvendor_without_snapshot", + vendor: true, + nocrt: true, + no_libcrt: true, + stl: "none", + system_shared_libs: [], + compile_multilib: "64", + } + + cc_library_shared { + name: "libclient", + vendor: true, + nocrt: true, + no_libcrt: true, + stl: "none", + system_shared_libs: [], + shared_libs: ["libvndk"], + static_libs: ["libvendor", "libvendor_without_snapshot"], + compile_multilib: "64", + srcs: ["client.cpp"], + } + + cc_binary { + name: "bin_without_snapshot", + vendor: true, + nocrt: true, + no_libcrt: true, + stl: "none", + system_shared_libs: [], + static_libs: ["libvndk"], + compile_multilib: "64", + srcs: ["bin.cpp"], + } + + vendor_snapshot_static { + name: "libvndk", + version: "BOARD", + target_arch: "arm64", + vendor: true, + arch: { + arm64: { + src: "libvndk.a", + export_include_dirs: ["include/libvndk"], + }, + }, + } + + vendor_snapshot_shared { + name: "libvendor", + version: "BOARD", + target_arch: "arm64", + vendor: true, + arch: { + arm64: { + src: "libvendor.so", + export_include_dirs: ["include/libvendor"], + }, + }, + } + + vendor_snapshot_static { + name: "libvendor", + version: "BOARD", + target_arch: "arm64", + vendor: true, + arch: { + arm64: { + src: "libvendor.a", + export_include_dirs: ["include/libvendor"], + }, + }, + } + + vendor_snapshot_binary { + name: "bin", + version: "BOARD", + target_arch: "arm64", + vendor: true, + arch: { + arm64: { + src: "bin", + }, + }, + } +` + depsBp := GatherRequiredDepsForTest(android.Android) + + mockFS := map[string][]byte{ + "deps/Android.bp": []byte(depsBp), + "framework/Android.bp": []byte(frameworkBp), + "vendor/Android.bp": []byte(vendorProprietaryBp), + "vendor/bin": nil, + "vendor/bin.cpp": nil, + "vendor/client.cpp": nil, + "vendor/include/libvndk/a.h": nil, + "vendor/include/libvendor/b.h": nil, + "vendor/libvndk.a": nil, + "vendor/libvendor.a": nil, + "vendor/libvendor.so": nil, + "vndk/Android.bp": []byte(vndkBp), + "vndk/include/libvndk/a.h": nil, + "vndk/libvndk.so": nil, + } + + config := TestConfig(buildDir, android.Android, nil, "", mockFS) + config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := CreateTestContext(config) + ctx.Register() + + _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"}) + android.FailIfErrored(t, errs) + _, errs = ctx.PrepareBuildActions(config) + android.FailIfErrored(t, errs) + + sharedVariant := "android_vendor.BOARD_arm64_armv8-a_shared" + staticVariant := "android_vendor.BOARD_arm64_armv8-a_static" + binaryVariant := "android_vendor.BOARD_arm64_armv8-a" + + // libclient uses libvndk.vndk.BOARD.arm64, libvendor.vendor_static.BOARD.arm64, libvendor_without_snapshot + libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"] + for _, includeFlags := range []string{ + "-Ivndk/include/libvndk", // libvndk + "-Ivendor/include/libvendor", // libvendor + } { + if !strings.Contains(libclientCcFlags, includeFlags) { + t.Errorf("flags for libclient must contain %#v, but was %#v.", + includeFlags, libclientCcFlags) + } + } + + libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"] + for _, input := range [][]string{ + []string{sharedVariant, "libvndk.vndk.BOARD.arm64"}, + []string{staticVariant, "libvendor.vendor_static.BOARD.arm64"}, + []string{staticVariant, "libvendor_without_snapshot"}, + } { + outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */) + if !strings.Contains(libclientLdFlags, outputPaths[0].String()) { + t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags) + } + } + + // bin_without_snapshot uses libvndk.vendor_static.BOARD.arm64 + binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"] + if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") { + t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.", + "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags) + } + + binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"] + libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.BOARD.arm64"}) + if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) { + t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v", + libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags) + } + + // libvendor.so is installed by libvendor.vendor_shared.BOARD.arm64 + ctx.ModuleForTests("libvendor.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor.so") + + // libvendor_without_snapshot.so is installed by libvendor_without_snapshot + ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so") + + // bin is installed by bin.vendor_binary.BOARD.arm64 + ctx.ModuleForTests("bin.vendor_binary.BOARD.arm64", binaryVariant).Output("bin") + + // bin_without_snapshot is installed by bin_without_snapshot + ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot") + + // libvendor and bin don't have vendor.BOARD variant + libvendorVariants := ctx.ModuleVariantsForTests("libvendor") + if inList(sharedVariant, libvendorVariants) { + t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant) + } + + binVariants := ctx.ModuleVariantsForTests("bin") + if inList(binaryVariant, binVariants) { + t.Errorf("bin must not have variant %#v, but it does", sharedVariant) + } +} + +func TestVendorSnapshotSanitizer(t *testing.T) { + bp := ` + vendor_snapshot_static { + name: "libsnapshot", + vendor: true, + target_arch: "arm64", + version: "BOARD", + arch: { + arm64: { + src: "libsnapshot.a", + cfi: { + src: "libsnapshot.cfi.a", + } + }, + }, + } +` + config := TestConfig(buildDir, android.Android, nil, bp, nil) + config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := testCcWithConfig(t, config) + + // Check non-cfi and cfi variant. + staticVariant := "android_vendor.BOARD_arm64_armv8-a_static" + staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi" + + staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module) + assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a") + + staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module) + assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a") +} + +func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) { + t.Helper() + m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module) + if m.ExcludeFromVendorSnapshot() != expected { + t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected) + } +} + +func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) { + t.Helper() + m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module) + if m.ExcludeFromRecoverySnapshot() != expected { + t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected) + } +} + +func TestVendorSnapshotExclude(t *testing.T) { + + // This test verifies that the exclude_from_vendor_snapshot property + // makes its way from the Android.bp source file into the module data + // structure. It also verifies that modules are correctly included or + // excluded in the vendor snapshot based on their path (framework or + // vendor) and the exclude_from_vendor_snapshot property. + + frameworkBp := ` + cc_library_shared { + name: "libinclude", + srcs: ["src/include.cpp"], + vendor_available: true, + } + cc_library_shared { + name: "libexclude", + srcs: ["src/exclude.cpp"], + vendor: true, + exclude_from_vendor_snapshot: true, + } + cc_library_shared { + name: "libavailable_exclude", + srcs: ["src/exclude.cpp"], + vendor_available: true, + exclude_from_vendor_snapshot: true, + } + ` + + vendorProprietaryBp := ` + cc_library_shared { + name: "libvendor", + srcs: ["vendor.cpp"], + vendor: true, + } + ` + + depsBp := GatherRequiredDepsForTest(android.Android) + + mockFS := map[string][]byte{ + "deps/Android.bp": []byte(depsBp), + "framework/Android.bp": []byte(frameworkBp), + "framework/include.cpp": nil, + "framework/exclude.cpp": nil, + "device/Android.bp": []byte(vendorProprietaryBp), + "device/vendor.cpp": nil, + } + + config := TestConfig(buildDir, android.Android, nil, "", mockFS) + config.TestProductVariables.DeviceVndkVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := CreateTestContext(config) + ctx.Register() + + _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"}) + android.FailIfErrored(t, errs) + _, errs = ctx.PrepareBuildActions(config) + android.FailIfErrored(t, errs) + + // Test an include and exclude framework module. + assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false) + assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true) + assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true) + + // A vendor module is excluded, but by its path, not the + // exclude_from_vendor_snapshot property. + assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false) + + // Verify the content of the vendor snapshot. + + snapshotDir := "vendor-snapshot" + snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") + snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") + + var includeJsonFiles []string + var excludeJsonFiles []string + + for _, arch := range [][]string{ + []string{"arm64", "armv8-a"}, + []string{"arm", "armv7-a-neon"}, + } { + archType := arch[0] + archVariant := arch[1] + archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) + + sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant) + sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") + + // Included modules + checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant) + includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json")) + + // Excluded modules + checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant) + excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json")) + checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) + excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json")) + checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant) + excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json")) + } + + // Verify that each json file for an included module has a rule. + for _, jsonFile := range includeJsonFiles { + if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { + t.Errorf("include json file %q not found", jsonFile) + } + } + + // Verify that each json file for an excluded module has no rule. + for _, jsonFile := range excludeJsonFiles { + if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { + t.Errorf("exclude json file %q found", jsonFile) + } + } +} + +func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) { + + // This test verifies that using the exclude_from_vendor_snapshot + // property on a module in a vendor proprietary path generates an + // error. These modules are already excluded, so we prohibit using the + // property in this way, which could add to confusion. + + vendorProprietaryBp := ` + cc_library_shared { + name: "libvendor", + srcs: ["vendor.cpp"], + vendor: true, + exclude_from_vendor_snapshot: true, + } + ` + + depsBp := GatherRequiredDepsForTest(android.Android) + + mockFS := map[string][]byte{ + "deps/Android.bp": []byte(depsBp), + "device/Android.bp": []byte(vendorProprietaryBp), + "device/vendor.cpp": nil, + } + + config := TestConfig(buildDir, android.Android, nil, "", mockFS) + config.TestProductVariables.DeviceVndkVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := CreateTestContext(config) + ctx.Register() + + _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"}) + android.FailIfErrored(t, errs) + + _, errs = ctx.PrepareBuildActions(config) + android.CheckErrorsAgainstExpectations(t, errs, []string{ + `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, + `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, + `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, + `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, + `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, + `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, + }) +} + +func TestRecoverySnapshotCapture(t *testing.T) { + bp := ` + cc_library { + name: "libvndk", + vendor_available: true, + recovery_available: true, + product_available: true, + vndk: { + enabled: true, + }, + nocrt: true, + } + + cc_library { + name: "librecovery", + recovery: true, + nocrt: true, + } + + cc_library { + name: "librecovery_available", + recovery_available: true, + nocrt: true, + } + + cc_library_headers { + name: "librecovery_headers", + recovery_available: true, + nocrt: true, + } + + cc_binary { + name: "recovery_bin", + recovery: true, + nocrt: true, + } + + cc_binary { + name: "recovery_available_bin", + recovery_available: true, + nocrt: true, + } + + toolchain_library { + name: "libb", + recovery_available: true, + src: "libb.a", + } + + cc_object { + name: "obj", + recovery_available: true, + } +` + config := TestConfig(buildDir, android.Android, nil, bp, nil) + config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := testCcWithConfig(t, config) + + // Check Recovery snapshot output. + + snapshotDir := "recovery-snapshot" + snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") + snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") + + var jsonFiles []string + + for _, arch := range [][]string{ + []string{"arm64", "armv8-a"}, + } { + archType := arch[0] + archVariant := arch[1] + archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) + + // For shared libraries, only recovery_available modules are captured. + sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) + sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") + checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant) + checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) + checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant) + jsonFiles = append(jsonFiles, + filepath.Join(sharedDir, "libvndk.so.json"), + filepath.Join(sharedDir, "librecovery.so.json"), + filepath.Join(sharedDir, "librecovery_available.so.json")) + + // For static libraries, all recovery:true and recovery_available modules are captured. + staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant) + staticDir := filepath.Join(snapshotVariantPath, archDir, "static") + checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant) + jsonFiles = append(jsonFiles, + filepath.Join(staticDir, "libb.a.json"), + filepath.Join(staticDir, "librecovery.a.json"), + filepath.Join(staticDir, "librecovery_available.a.json")) + + // For binary executables, all recovery:true and recovery_available modules are captured. + if archType == "arm64" { + binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant) + binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") + checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant) + checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant) + jsonFiles = append(jsonFiles, + filepath.Join(binaryDir, "recovery_bin.json"), + filepath.Join(binaryDir, "recovery_available_bin.json")) + } + + // For header libraries, all vendor:true and vendor_available modules are captured. + headerDir := filepath.Join(snapshotVariantPath, archDir, "header") + jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json")) + + // For object modules, all vendor:true and vendor_available modules are captured. + objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant) + objectDir := filepath.Join(snapshotVariantPath, archDir, "object") + checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant) + jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json")) + } + + for _, jsonFile := range jsonFiles { + // verify all json files exist + if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { + t.Errorf("%q expected but not found", jsonFile) + } + } +} + +func TestRecoverySnapshotExclude(t *testing.T) { + // This test verifies that the exclude_from_recovery_snapshot property + // makes its way from the Android.bp source file into the module data + // structure. It also verifies that modules are correctly included or + // excluded in the recovery snapshot based on their path (framework or + // vendor) and the exclude_from_recovery_snapshot property. + + frameworkBp := ` + cc_library_shared { + name: "libinclude", + srcs: ["src/include.cpp"], + recovery_available: true, + } + cc_library_shared { + name: "libexclude", + srcs: ["src/exclude.cpp"], + recovery: true, + exclude_from_recovery_snapshot: true, + } + cc_library_shared { + name: "libavailable_exclude", + srcs: ["src/exclude.cpp"], + recovery_available: true, + exclude_from_recovery_snapshot: true, + } + ` + + vendorProprietaryBp := ` + cc_library_shared { + name: "librecovery", + srcs: ["recovery.cpp"], + recovery: true, + } + ` + + depsBp := GatherRequiredDepsForTest(android.Android) + + mockFS := map[string][]byte{ + "deps/Android.bp": []byte(depsBp), + "framework/Android.bp": []byte(frameworkBp), + "framework/include.cpp": nil, + "framework/exclude.cpp": nil, + "device/Android.bp": []byte(vendorProprietaryBp), + "device/recovery.cpp": nil, + } + + config := TestConfig(buildDir, android.Android, nil, "", mockFS) + config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := CreateTestContext(config) + ctx.Register() + + _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"}) + android.FailIfErrored(t, errs) + _, errs = ctx.PrepareBuildActions(config) + android.FailIfErrored(t, errs) + + // Test an include and exclude framework module. + assertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false) + assertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true) + assertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true) + + // A recovery module is excluded, but by its path, not the + // exclude_from_recovery_snapshot property. + assertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false) + + // Verify the content of the recovery snapshot. + + snapshotDir := "recovery-snapshot" + snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") + snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") + + var includeJsonFiles []string + var excludeJsonFiles []string + + for _, arch := range [][]string{ + []string{"arm64", "armv8-a"}, + } { + archType := arch[0] + archVariant := arch[1] + archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) + + sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) + sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") + + // Included modules + checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant) + includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json")) + + // Excluded modules + checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant) + excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json")) + checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) + excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json")) + checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant) + excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json")) + } + + // Verify that each json file for an included module has a rule. + for _, jsonFile := range includeJsonFiles { + if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { + t.Errorf("include json file %q not found", jsonFile) + } + } + + // Verify that each json file for an excluded module has no rule. + for _, jsonFile := range excludeJsonFiles { + if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { + t.Errorf("exclude json file %q found", jsonFile) + } + } +} From 2e577f36574e36879b0a1f2587f9e3da6cc94b72 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 22 Jan 2021 13:06:25 -0800 Subject: [PATCH 2/2] Add vendor_available coverage to TestVendorSnapshotUse Test that the correct suffix is added to the Make references to a vendor_available library in a vendor snapshot. Bug: 177098205 Test: vendor_snapshot_test.go Change-Id: I0c9b81d63798e221db856fa0e4742a467c356fcb --- cc/vendor_snapshot_test.go | 59 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go index 44abe2aa0..cce28b0f8 100644 --- a/cc/vendor_snapshot_test.go +++ b/cc/vendor_snapshot_test.go @@ -18,6 +18,7 @@ import ( "android/soong/android" "fmt" "path/filepath" + "reflect" "strings" "testing" ) @@ -290,6 +291,16 @@ func TestVendorSnapshotUse(t *testing.T) { compile_multilib: "64", } + cc_library { + name: "libvendor_available", + vendor_available: true, + nocrt: true, + no_libcrt: true, + stl: "none", + system_shared_libs: [], + compile_multilib: "64", + } + cc_binary { name: "bin", vendor: true, @@ -338,7 +349,7 @@ func TestVendorSnapshotUse(t *testing.T) { no_libcrt: true, stl: "none", system_shared_libs: [], - shared_libs: ["libvndk"], + shared_libs: ["libvndk", "libvendor_available"], static_libs: ["libvendor", "libvendor_without_snapshot"], compile_multilib: "64", srcs: ["client.cpp"], @@ -395,6 +406,32 @@ func TestVendorSnapshotUse(t *testing.T) { }, } + vendor_snapshot_shared { + name: "libvendor_available", + version: "BOARD", + target_arch: "arm64", + vendor: true, + arch: { + arm64: { + src: "libvendor_available.so", + export_include_dirs: ["include/libvendor"], + }, + }, + } + + vendor_snapshot_static { + name: "libvendor_available", + version: "BOARD", + target_arch: "arm64", + vendor: true, + arch: { + arm64: { + src: "libvendor_available.a", + export_include_dirs: ["include/libvendor"], + }, + }, + } + vendor_snapshot_binary { name: "bin", version: "BOARD", @@ -465,6 +502,16 @@ func TestVendorSnapshotUse(t *testing.T) { } } + libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs + if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor"}; !reflect.DeepEqual(g, w) { + t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g) + } + + libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs + if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot"}; !reflect.DeepEqual(g, w) { + t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g) + } + // bin_without_snapshot uses libvndk.vendor_static.BOARD.arm64 binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"] if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") { @@ -482,6 +529,9 @@ func TestVendorSnapshotUse(t *testing.T) { // libvendor.so is installed by libvendor.vendor_shared.BOARD.arm64 ctx.ModuleForTests("libvendor.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor.so") + // libvendor_available.so is installed by libvendor_available.vendor_shared.BOARD.arm64 + ctx.ModuleForTests("libvendor_available.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor_available.so") + // libvendor_without_snapshot.so is installed by libvendor_without_snapshot ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so") @@ -491,12 +541,17 @@ func TestVendorSnapshotUse(t *testing.T) { // bin_without_snapshot is installed by bin_without_snapshot ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot") - // libvendor and bin don't have vendor.BOARD variant + // libvendor, libvendor_available and bin don't have vendor.BOARD variant libvendorVariants := ctx.ModuleVariantsForTests("libvendor") if inList(sharedVariant, libvendorVariants) { t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant) } + libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available") + if inList(sharedVariant, libvendorAvailableVariants) { + t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant) + } + binVariants := ctx.ModuleVariantsForTests("bin") if inList(binaryVariant, binVariants) { t.Errorf("bin must not have variant %#v, but it does", sharedVariant)