diff options
Diffstat (limited to 'rust/rust_test.go')
-rw-r--r-- | rust/rust_test.go | 425 |
1 files changed, 412 insertions, 13 deletions
diff --git a/rust/rust_test.go b/rust/rust_test.go index 835114c13..576209d04 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -15,14 +15,17 @@ package rust import ( + "fmt" "os" "runtime" "strings" "testing" "github.com/google/blueprint/proptools" + "google.golang.org/protobuf/encoding/prototext" "android/soong/android" + "android/soong/cmd/sbox/sbox_proto" "android/soong/genrule" ) @@ -64,11 +67,14 @@ var rustMockedFiles = android.MockFS{ // testRust returns a TestContext in which a basic environment has been setup. // This environment contains a few mocked files. See rustMockedFiles for the list of these files. -func testRust(t *testing.T, bp string) *android.TestContext { +func testRust(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext { skipTestIfOsNotSupported(t) result := android.GroupFixturePreparers( prepareForRustTest, rustMockedFiles.AddToFixture(), + android.GroupFixturePreparers( + preparers..., + ), ). RunTestWithBp(t, bp) return result.TestContext @@ -202,11 +208,11 @@ func skipTestIfOsNotSupported(t *testing.T) { // Test that we can extract the link path from a lib path. func TestLinkPathFromFilePath(t *testing.T) { barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so") - libName := linkPathFromFilePath(barPath) - expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/" + libName := barPath.Dir() + expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared" - if libName != expectedResult { - t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName) + if libName.String() != expectedResult { + t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName.String()) } } @@ -256,7 +262,7 @@ func TestDepsTracking(t *testing.T) { `) module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module) rustc := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") - rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustLink") + rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc") // Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up. if !android.InList("librlib.rlib-std", module.Properties.AndroidMkRlibs) { @@ -275,16 +281,16 @@ func TestDepsTracking(t *testing.T) { t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)") } - if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic=wholestatic") { - t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"]) + if !strings.Contains(rustc.RuleParams.Command, "-lstatic=wholestatic") { + t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.RuleParams.Command) } - if !strings.Contains(rustLink.Args["linkFlags"], "cc_stubs_dep.so") { - t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.Args["linkFlags"]) + if !strings.Contains(rustLink.RuleParams.Command, "cc_stubs_dep.so") { + t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.RuleParams.Command) } - if !android.SuffixInList(rustLink.OrderOnly.Strings(), "cc_stubs_dep.so") { - t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustLink.OrderOnly.Strings()) + if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so") { + t.Errorf("shared cc dep not being passed as implicit to rustc %#v", rustLink.OrderOnly.Strings()) } if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so.toc") { @@ -427,7 +433,7 @@ func TestProcMacroDeviceDeps(t *testing.T) { `) rustc := ctx.ModuleForTests("libpm", "linux_glibc_x86_64").Rule("rustc") - if !strings.Contains(rustc.Args["libFlags"], "libbar/linux_glibc_x86_64") { + if !strings.Contains(rustc.RuleParams.Command, "libbar/linux_glibc_x86_64") { t.Errorf("Proc_macro is not using host variant of dependent modules.") } } @@ -480,3 +486,396 @@ func assertString(t *testing.T, got, expected string) { t.Errorf("expected %q got %q", expected, got) } } + +var ( + sboxCompilationFiles = []string{ + "out/soong/.intermediates/defaults/rust/libaddr2line/android_arm64_armv8-a_rlib/libaddr2line.rlib", + "out/soong/.intermediates/defaults/rust/libadler/android_arm64_armv8-a_rlib/libadler.rlib", + "out/soong/.intermediates/defaults/rust/liballoc/android_arm64_armv8-a_rlib/liballoc.rlib", + "out/soong/.intermediates/defaults/rust/libcfg_if/android_arm64_armv8-a_rlib/libcfg_if.rlib", + "out/soong/.intermediates/defaults/rust/libcompiler_builtins/android_arm64_armv8-a_rlib/libcompiler_builtins.rlib", + "out/soong/.intermediates/defaults/rust/libcore/android_arm64_armv8-a_rlib/libcore.rlib", + "out/soong/.intermediates/defaults/rust/libgimli/android_arm64_armv8-a_rlib/libgimli.rlib", + "out/soong/.intermediates/defaults/rust/libhashbrown/android_arm64_armv8-a_rlib/libhashbrown.rlib", + "out/soong/.intermediates/defaults/rust/liblibc/android_arm64_armv8-a_rlib/liblibc.rlib", + "out/soong/.intermediates/defaults/rust/libmemchr/android_arm64_armv8-a_rlib/libmemchr.rlib", + "out/soong/.intermediates/defaults/rust/libminiz_oxide/android_arm64_armv8-a_rlib/libminiz_oxide.rlib", + "out/soong/.intermediates/defaults/rust/libobject/android_arm64_armv8-a_rlib/libobject.rlib", + "out/soong/.intermediates/defaults/rust/libpanic_unwind/android_arm64_armv8-a_rlib/libpanic_unwind.rlib", + "out/soong/.intermediates/defaults/rust/librustc_demangle/android_arm64_armv8-a_rlib/librustc_demangle.rlib", + "out/soong/.intermediates/defaults/rust/librustc_std_workspace_alloc/android_arm64_armv8-a_rlib/librustc_std_workspace_alloc.rlib", + "out/soong/.intermediates/defaults/rust/librustc_std_workspace_core/android_arm64_armv8-a_rlib/librustc_std_workspace_core.rlib", + "out/soong/.intermediates/defaults/rust/libstd_detect/android_arm64_armv8-a_rlib/libstd_detect.rlib", + "build/soong/scripts/mkcratersp.py", + "defaults/rust/linux-x86/1.69.0/bin/rustc", + "defaults/rust/linux-x86/1.69.0/lib/libstd.so", + "defaults/rust/linux-x86/1.69.0/lib64/libc++.so.1", + } + sboxCompilationFilesWithCc = []string{ + "defaults/cc/common", + "out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so", + "out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so.toc", + "out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so", + "out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so.toc", + "out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so", + "out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so.toc", + "out/soong/.intermediates/defaults/rust/liblog/android_arm64_armv8-a_shared/liblog.so", + "out/soong/.intermediates/defaults/rust/liblog/android_arm64_armv8-a_shared/liblog.so.toc", + } +) + +func TestSandboxCompilation(t *testing.T) { + ctx := testRust(t, ` + filegroup { + name: "libsrcs1", + srcs: ["src_filegroup1.rs"], + } + filegroup { + name: "libsrcs2", + srcs: ["src_filegroup2.rs"], + } + rust_library { + name: "libfizz_buzz", + crate_name:"fizz_buzz", + crate_root: "foo.rs", + srcs: [ + "src_lib*.rs", + ":libsrcs1", + ":libsrcs2", + ], + compile_data: [ + "compile_data1.txt", + "compile_data2.txt", + ], + dylib: { + srcs: ["dylib_only.rs"], + }, + rlib: { + srcs: ["rlib_only.rs"], + }, + } + rust_binary { + name: "fizz_buzz", + crate_name:"fizz_buzz", + crate_root: "foo.rs", + srcs: [ + "src_lib*.rs", + ":libsrcs1", + ":libsrcs2", + ], + } + rust_ffi { + name: "librust_ffi", + crate_name: "rust_ffi", + crate_root: "foo.rs", + static: { + srcs: ["static_only.rs"], + }, + shared: { + srcs: ["shared_only.rs"], + }, + srcs: ["src1.rs"], + } + cc_library_static { + name: "cc_dep_static", + } + cc_library_shared { + name: "cc_dep_shared", + } + rust_library { + name: "libfizz_buzz_cc_deps", + crate_name:"fizz_buzz", + crate_root: "foo.rs", + srcs: ["src*.rs"], + shared_libs: ["cc_dep_shared"], + static_libs: ["cc_dep_static"], + } + rust_library { + name: "libfizz_buzz_intermediate_cc_deps", + crate_name:"fizz_buzz", + crate_root: "foo.rs", + srcs: ["src*.rs"], + rustlibs: ["libfizz_buzz_cc_deps"], + } + rust_library { + name: "libfizz_buzz_transitive_cc_deps", + crate_name:"fizz_buzz", + crate_root: "foo.rs", + srcs: ["src*.rs"], + rustlibs: ["libfizz_buzz_intermediate_cc_deps"], + } + `, + android.FixtureMergeMockFs(android.MockFS{ + "src_lib1.rs": nil, + "src_lib2.rs": nil, + "src_lib3.rs": nil, + "src_lib4.rs": nil, + "src_filegroup1.rs": nil, + "src_filegroup2.rs": nil, + "static_only.rs": nil, + "shared_only.rs": nil, + }), + ) + + testcases := []struct { + name string + moduleName string + variant string + rustcExpectedFilesToCopy []string + expectedFlags []string + }{ + { + name: "rust_library (dylib)", + moduleName: "libfizz_buzz", + variant: "android_arm64_armv8-a_dylib", + rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{ + "foo.rs", + "src_lib1.rs", + "src_lib2.rs", + "src_lib3.rs", + "src_lib4.rs", + "src_filegroup1.rs", + "src_filegroup2.rs", + "compile_data1.txt", + "compile_data2.txt", + "dylib_only.rs", + "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/out/src_filegroup1.rs", + "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/out/src_filegroup2.rs", + + "out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so", + "out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so.toc", + "out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so", + "out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so.toc", + "out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so", + "out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so.toc", + "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so", + "out/soong/.intermediates/defaults/cc/common/crtbegin_so/android_arm64_armv8-a/crtbegin_so.o", + "out/soong/.intermediates/defaults/cc/common/crtend_so/android_arm64_armv8-a/crtend_so.o", + "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so.clippy", + }), + expectedFlags: []string{ + "-C linker=build/soong/scripts/mkcratersp.py", + "--emit link", + "-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.dylib.so.rsp", + "--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.dylib.so.d.raw", + "foo.rs", // this is the entry point + }, + }, + { + name: "rust_library (rlib dylib-std)", + moduleName: "libfizz_buzz", + variant: "android_arm64_armv8-a_rlib_dylib-std", + rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{ + "foo.rs", + "src_lib1.rs", + "src_lib2.rs", + "src_lib3.rs", + "src_lib4.rs", + "src_filegroup1.rs", + "src_filegroup2.rs", + "rlib_only.rs", + "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/out/src_filegroup1.rs", + "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/out/src_filegroup2.rs", + "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so", + }), + expectedFlags: []string{ + "--emit link", + "-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib", + "--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib.d.raw", + "foo.rs", // this is the entry point + }, + }, + { + name: "rust_library (rlib rlib-std)", + moduleName: "libfizz_buzz", + variant: "android_arm64_armv8-a_rlib_rlib-std", + rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{ + "foo.rs", + "src_lib1.rs", + "src_lib2.rs", + "src_lib3.rs", + "src_lib4.rs", + "src_filegroup1.rs", + "src_filegroup2.rs", + "rlib_only.rs", + "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/out/src_filegroup1.rs", + "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/out/src_filegroup2.rs", + "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/libfizz_buzz.rlib.clippy", + "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_rlib/libstd.rlib", + }), + expectedFlags: []string{ + "--emit link", + "-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib", + "--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib.d.raw", + "foo.rs", // this is the entry point + }, + }, + { + name: "rust_binary", + moduleName: "fizz_buzz", + variant: "android_arm64_armv8-a", + rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{ + "foo.rs", + "src_lib1.rs", + "src_lib2.rs", + "src_lib3.rs", + "src_lib4.rs", + "src_filegroup1.rs", + "src_filegroup2.rs", + "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/out/src_filegroup1.rs", + "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/out/src_filegroup2.rs", + + "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so", + "out/soong/.intermediates/defaults/cc/common/crtbegin_dynamic/android_arm64_armv8-a/crtbegin_dynamic.o", + "out/soong/.intermediates/defaults/cc/common/crtend_android/android_arm64_armv8-a/crtend_android.o", + "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz.clippy", + }), + expectedFlags: []string{ + "--emit link", + "-o __SBOX_SANDBOX_DIR__/out/fizz_buzz", + "--emit dep-info=__SBOX_SANDBOX_DIR__/out/fizz_buzz.d.raw", + "foo.rs", // this is the entry point + }, + }, + { + name: "rust_ffi static lib variant", + moduleName: "librust_ffi", + variant: "android_arm64_armv8-a_static", + rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{ + "foo.rs", + "src1.rs", + "static_only.rs", + "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/librust_ffi.a.clippy", + "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_rlib/libstd.rlib", + }), + expectedFlags: []string{ + "--emit link", + "-o __SBOX_SANDBOX_DIR__/out/librust_ffi.a", + "--emit dep-info=__SBOX_SANDBOX_DIR__/out/librust_ffi.a.d.raw", + "foo.rs", // this is the entry point + }, + }, + { + name: "rust_ffi shared lib variant", + moduleName: "librust_ffi", + variant: "android_arm64_armv8-a_shared", + rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{ + "foo.rs", + "src1.rs", + "shared_only.rs", + + "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so", + "out/soong/.intermediates/defaults/cc/common/crtbegin_so/android_arm64_armv8-a/crtbegin_so.o", + "out/soong/.intermediates/defaults/cc/common/crtend_so/android_arm64_armv8-a/crtend_so.o", + "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so.clippy", + }), + expectedFlags: []string{ + "--emit link", + "-o __SBOX_SANDBOX_DIR__/out/librust_ffi.so", + "--emit dep-info=__SBOX_SANDBOX_DIR__/out/librust_ffi.so.d.raw", + "foo.rs", // this is the entry point + }, + }, + { + name: "rust_library with cc deps (dylib)", + moduleName: "libfizz_buzz_cc_deps", + variant: "android_arm64_armv8-a_dylib", + rustcExpectedFilesToCopy: []string{ + "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc", + }, + }, + { + name: "rust_library with cc deps (rlib rlib-std)", + moduleName: "libfizz_buzz_cc_deps", + variant: "android_arm64_armv8-a_rlib_rlib-std", + rustcExpectedFilesToCopy: []string{ + "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc", + }, + }, + { + name: "rust_library with cc deps (rlib dylib-std)", + moduleName: "libfizz_buzz_cc_deps", + variant: "android_arm64_armv8-a_rlib_dylib-std", + rustcExpectedFilesToCopy: []string{ + "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc", + }, + }, + { + name: "rust_library with transitive cc deps (dylib)", + moduleName: "libfizz_buzz_transitive_cc_deps", + variant: "android_arm64_armv8-a_dylib", + rustcExpectedFilesToCopy: []string{ + "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc", + }, + }, + { + name: "rust_library with transitive cc deps (rlib rlib-std)", + moduleName: "libfizz_buzz_transitive_cc_deps", + variant: "android_arm64_armv8-a_rlib_rlib-std", + rustcExpectedFilesToCopy: []string{ + "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc", + }, + }, + { + name: "rust_library with transitive cc deps (rlib dylib-std)", + moduleName: "libfizz_buzz_transitive_cc_deps", + variant: "android_arm64_armv8-a_rlib_dylib-std", + rustcExpectedFilesToCopy: []string{ + "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so", + "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc", + }, + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + writeFile := ctx.ModuleForTests(tc.moduleName, tc.variant).Rule("unescapedWriteFile") + contents := writeFile.BuildParams.Args["content"] + manifestProto := sbox_proto.Manifest{} + err := prototext.Unmarshal([]byte(contents), &manifestProto) + if err != nil { + t.Errorf("expected no errors unmarshaling manifest proto; got %v", err) + } + + if len(manifestProto.Commands) != 1 { + t.Errorf("expected 1 command; got %v", len(manifestProto.Commands)) + } + + // check that sandbox contains correct files + rustc := manifestProto.Commands[0] + actualFilesToCopy := []string{} + for _, copy := range rustc.CopyBefore { + actualFilesToCopy = append(actualFilesToCopy, copy.GetFrom()) + } + _, expectedFilesNotCopied, _ := android.ListSetDifference(tc.rustcExpectedFilesToCopy, actualFilesToCopy) + if len(expectedFilesNotCopied) > 0 { + t.Errorf("did not copy expected files to sbox: %v;\n files copied: %v", expectedFilesNotCopied, actualFilesToCopy) + } + + rustcCmd := proptools.String(rustc.Command) + for _, flag := range tc.expectedFlags { + android.AssertStringDoesContain( + t, + fmt.Sprintf( + "missing flag in rustc invocation; expected to find substring %q; got %q", + flag, + rustcCmd, + ), + rustcCmd, + flag, + ) + } + }) + } +} |