diff options
author | 2021-11-04 14:09:38 -0400 | |
---|---|---|
committer | 2021-11-15 17:18:42 -0500 | |
commit | 4e5f07d27ba2e8ae460457a5a977478b9b2c96eb (patch) | |
tree | bc60672c4224d020a36995bf8d641ac84602af2c | |
parent | 8d10fc39afdda6a9c3f27f3ed0999db9c8c2199a (diff) |
rust: Add data_libs and data_bins to rust_test
Allows defining data binaries and libraries that should be installed
alongside a rust_test module, similar to cc_test.
This refactors cc_test as well so it can define rust_ffi_shared and
rust_binary modules as data.
Bug: 171710847
Test: New Soong tests pass.
Test: Example module installs data appropriately.
Change-Id: I0b56098fb475ec54f9b7a761220d260fe68cbee1
-rw-r--r-- | cc/cc_test.go | 17 | ||||
-rw-r--r-- | cc/test.go | 25 | ||||
-rw-r--r-- | rust/rust.go | 12 | ||||
-rw-r--r-- | rust/test.go | 36 | ||||
-rw-r--r-- | rust/test_test.go | 126 |
5 files changed, 198 insertions, 18 deletions
diff --git a/cc/cc_test.go b/cc/cc_test.go index 4c9f5799b..d36eb4d2c 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -730,9 +730,16 @@ func TestDataLibsRelativeInstallPath(t *testing.T) { gtest: false, } + cc_binary { + name: "test_bin", + relative_install_path: "foo/bar/baz", + compile_multilib: "both", + } + cc_test { name: "main_test", data_libs: ["test_lib"], + data_bins: ["test_bin"], gtest: false, } ` @@ -750,10 +757,10 @@ func TestDataLibsRelativeInstallPath(t *testing.T) { t.Fatalf("Expected cc_test to produce output files, error: %s", err) } if len(outputFiles) != 1 { - t.Errorf("expected exactly one output file. output files: [%s]", outputFiles) + t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles) } - if len(testBinary.dataPaths()) != 1 { - t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths()) + if len(testBinary.dataPaths()) != 2 { + t.Fatalf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths()) } outputPath := outputFiles[0].String() @@ -766,6 +773,10 @@ func TestDataLibsRelativeInstallPath(t *testing.T) { t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+ " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0]) } + if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") { + t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+ + " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1]) + } } func TestVndkWhenVndkVersionIsNotSet(t *testing.T) { diff --git a/cc/test.go b/cc/test.go index c589165f0..f37fdae38 100644 --- a/cc/test.go +++ b/cc/test.go @@ -378,31 +378,26 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) { depName := ctx.OtherModuleName(dep) - ccDep, ok := dep.(LinkableInterface) - - if !ok { - ctx.ModuleErrorf("data_lib %q is not a linkable cc module", depName) - } - ccModule, ok := dep.(*Module) + linkableDep, ok := dep.(LinkableInterface) if !ok { - ctx.ModuleErrorf("data_lib %q is not a cc module", depName) + ctx.ModuleErrorf("data_lib %q is not a LinkableInterface module", depName) } - if ccDep.OutputFile().Valid() { + if linkableDep.OutputFile().Valid() { test.data = append(test.data, - android.DataPath{SrcPath: ccDep.OutputFile().Path(), - RelativeInstallPath: ccModule.installer.relativeInstallPath()}) + android.DataPath{SrcPath: linkableDep.OutputFile().Path(), + RelativeInstallPath: linkableDep.RelativeInstallPath()}) } }) ctx.VisitDirectDepsWithTag(dataBinDepTag, func(dep android.Module) { depName := ctx.OtherModuleName(dep) - ccModule, ok := dep.(*Module) + linkableDep, ok := dep.(LinkableInterface) if !ok { - ctx.ModuleErrorf("data_bin %q is not a cc module", depName) + ctx.ModuleErrorf("data_bin %q is not a LinkableInterface module", depName) } - if ccModule.OutputFile().Valid() { + if linkableDep.OutputFile().Valid() { test.data = append(test.data, - android.DataPath{SrcPath: ccModule.OutputFile().Path(), - RelativeInstallPath: ccModule.installer.relativeInstallPath()}) + android.DataPath{SrcPath: linkableDep.OutputFile().Path(), + RelativeInstallPath: linkableDep.RelativeInstallPath()}) } }) diff --git a/rust/rust.go b/rust/rust.go index 7c8e80b5a..a97fc91cd 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -390,6 +390,10 @@ type Deps struct { WholeStaticLibs []string HeaderLibs []string + // Used for data dependencies adjacent to tests + DataLibs []string + DataBins []string + CrtBegin, CrtEnd string } @@ -975,6 +979,8 @@ var ( procMacroDepTag = dependencyTag{name: "procMacro", procMacro: true} testPerSrcDepTag = dependencyTag{name: "rust_unit_tests"} sourceDepTag = dependencyTag{name: "source"} + dataLibDepTag = dependencyTag{name: "data lib"} + dataBinDepTag = dependencyTag{name: "data bin"} ) func IsDylibDepTag(depTag blueprint.DependencyTag) bool { @@ -1400,6 +1406,12 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { } } + actx.AddVariationDependencies([]blueprint.Variation{ + {Mutator: "link", Variation: "shared"}, + }, dataLibDepTag, deps.DataLibs...) + + actx.AddVariationDependencies(nil, dataBinDepTag, deps.DataBins...) + // proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy. actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...) } diff --git a/rust/test.go b/rust/test.go index 56da509b5..021ead0f6 100644 --- a/rust/test.go +++ b/rust/test.go @@ -18,6 +18,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/cc" "android/soong/tradefed" ) @@ -49,6 +50,12 @@ type TestProperties struct { // the test Data []string `android:"path,arch_variant"` + // list of shared library modules that should be installed alongside the test + Data_libs []string `android:"arch_variant"` + + // list of binary modules that should be installed alongside the test + Data_bins []string `android:"arch_variant"` + // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true // explicitly. @@ -137,6 +144,32 @@ func (test *testDecorator) install(ctx ModuleContext) { dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data) + ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) { + depName := ctx.OtherModuleName(dep) + linkableDep, ok := dep.(cc.LinkableInterface) + if !ok { + ctx.ModuleErrorf("data_lib %q is not a linkable module", depName) + } + if linkableDep.OutputFile().Valid() { + test.data = append(test.data, + android.DataPath{SrcPath: linkableDep.OutputFile().Path(), + RelativeInstallPath: linkableDep.RelativeInstallPath()}) + } + }) + + ctx.VisitDirectDepsWithTag(dataBinDepTag, func(dep android.Module) { + depName := ctx.OtherModuleName(dep) + linkableDep, ok := dep.(cc.LinkableInterface) + if !ok { + ctx.ModuleErrorf("data_bin %q is not a linkable module", depName) + } + if linkableDep.OutputFile().Valid() { + test.data = append(test.data, + android.DataPath{SrcPath: linkableDep.OutputFile().Path(), + RelativeInstallPath: linkableDep.RelativeInstallPath()}) + } + }) + for _, dataSrcPath := range dataSrcPaths { test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath}) } @@ -194,5 +227,8 @@ func (test *testDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { deps.Rustlibs = append(deps.Rustlibs, "libtest") + deps.DataLibs = append(deps.DataLibs, test.Properties.Data_libs...) + deps.DataBins = append(deps.DataBins, test.Properties.Data_bins...) + return deps } diff --git a/rust/test_test.go b/rust/test_test.go index 892761a07..112417673 100644 --- a/rust/test_test.go +++ b/rust/test_test.go @@ -74,3 +74,129 @@ func TestRustTestLinkage(t *testing.T) { t.Errorf("Device rust_test module 'my_test' does not link libstd as an rlib") } } + +func TestDataLibs(t *testing.T) { + bp := ` + cc_library { + name: "test_lib", + srcs: ["test_lib.cpp"], + } + + rust_binary { + name: "rusty", + srcs: ["foo.rs"], + compile_multilib: "both", + } + + rust_ffi { + name: "librust_test_lib", + crate_name: "rust_test_lib", + srcs: ["test_lib.rs"], + relative_install_path: "foo/bar/baz", + compile_multilib: "64", + } + + rust_test { + name: "main_test", + srcs: ["foo.rs"], + data_libs: ["test_lib"], + data_bins: ["rusty"], + } + ` + + ctx := testRust(t, bp) + + module := ctx.ModuleForTests("main_test", "android_arm64_armv8-a").Module() + testBinary := module.(*Module).compiler.(*testDecorator) + outputFiles, err := module.(android.OutputFileProducer).OutputFiles("") + if err != nil { + t.Fatalf("Expected rust_test to produce output files, error: %s", err) + } + if len(outputFiles) != 1 { + t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles) + } + if len(testBinary.dataPaths()) != 2 { + t.Fatalf("expected exactly two test data files. test data files: [%s]", testBinary.dataPaths()) + } + + outputPath := outputFiles[0].String() + dataLibraryPath := testBinary.dataPaths()[0].SrcPath.String() + dataBinaryPath := testBinary.dataPaths()[1].SrcPath.String() + + if !strings.HasSuffix(outputPath, "/main_test") { + t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath) + } + if !strings.HasSuffix(dataLibraryPath, "/test_lib.so") { + t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", dataLibraryPath) + } + if !strings.HasSuffix(dataBinaryPath, "/rusty") { + t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", dataBinaryPath) + } +} + +func TestDataLibsRelativeInstallPath(t *testing.T) { + bp := ` + cc_library { + name: "test_lib", + srcs: ["test_lib.cpp"], + relative_install_path: "foo/bar/baz", + compile_multilib: "64", + } + + rust_ffi { + name: "librust_test_lib", + crate_name: "rust_test_lib", + srcs: ["test_lib.rs"], + relative_install_path: "foo/bar/baz", + compile_multilib: "64", + } + + rust_binary { + name: "rusty", + srcs: ["foo.rs"], + relative_install_path: "foo/bar/baz", + compile_multilib: "64", + } + + rust_test { + name: "main_test", + srcs: ["foo.rs"], + data_libs: ["test_lib", "librust_test_lib"], + data_bins: ["rusty"], + compile_multilib: "64", + } + ` + + ctx := testRust(t, bp) + module := ctx.ModuleForTests("main_test", "android_arm64_armv8-a").Module() + testBinary := module.(*Module).compiler.(*testDecorator) + outputFiles, err := module.(android.OutputFileProducer).OutputFiles("") + if err != nil { + t.Fatalf("Expected rust_test to produce output files, error: %s", err) + } + if len(outputFiles) != 1 { + t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles) + } + if len(testBinary.dataPaths()) != 3 { + t.Fatalf("expected exactly two test data files. test data files: [%s]", testBinary.dataPaths()) + } + + outputPath := outputFiles[0].String() + + if !strings.HasSuffix(outputPath, "/main_test") { + t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath) + } + entries := android.AndroidMkEntriesForTest(t, ctx, module)[0] + if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") { + t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+ + " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0]) + } + if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":librust_test_lib.so:foo/bar/baz") { + t.Errorf("expected LOCAL_TEST_DATA to end with `:librust_test_lib.so:foo/bar/baz`,"+ + " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1]) + } + if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][2], ":rusty:foo/bar/baz") { + t.Errorf("expected LOCAL_TEST_DATA to end with `:rusty:foo/bar/baz`,"+ + " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][2]) + } +} |