diff options
Diffstat (limited to 'cc/test.go')
| -rw-r--r-- | cc/test.go | 325 |
1 files changed, 105 insertions, 220 deletions
diff --git a/cc/test.go b/cc/test.go index 3f5f71007..f5bb7610c 100644 --- a/cc/test.go +++ b/cc/test.go @@ -15,15 +15,11 @@ package cc import ( + "github.com/google/blueprint/proptools" "path/filepath" "strconv" - "strings" - - "github.com/google/blueprint/proptools" "android/soong/android" - "android/soong/bazel" - "android/soong/bazel/cquery" "android/soong/tradefed" ) @@ -77,13 +73,9 @@ type TestOptions struct { } type TestBinaryProperties struct { - // Create a separate binary for each source file. Useful when there is - // global state that can not be torn down and reset between each test suite. - Test_per_src *bool - // Disables the creation of a test-specific directory when used with // relative_install_path. Useful if several tests need to be in the same - // directory, but test_per_src doesn't work. + // directory. No_named_install_directory *bool // list of files or filegroup modules that provide data that should be installed alongside @@ -139,8 +131,7 @@ func init() { // specific functionality on a device. The executable binary gets an implicit // static_libs dependency on libgtests unless the gtest flag is set to false. func TestFactory() android.Module { - module := NewTest(android.HostAndDeviceSupported, true) - module.bazelHandler = &ccTestBazelHandler{module: module} + module := NewTest(android.HostAndDeviceSupported) return module.Init() } @@ -158,12 +149,13 @@ func TestLibraryFactory() android.Module { // binary. func BenchmarkFactory() android.Module { module := NewBenchmark(android.HostAndDeviceSupported) + module.testModule = true return module.Init() } // cc_test_host compiles a test host binary. func TestHostFactory() android.Module { - module := NewTest(android.HostSupported, true) + module := NewTest(android.HostSupported) return module.Init() } @@ -176,86 +168,14 @@ func BenchmarkHostFactory() android.Module { return module.Init() } -type testPerSrc interface { - testPerSrc() bool - srcs() []string - isAllTestsVariation() bool - setSrc(string, string) - unsetSrc() -} - -func (test *testBinary) testPerSrc() bool { - return Bool(test.Properties.Test_per_src) -} - -func (test *testBinary) srcs() []string { - return test.baseCompiler.Properties.Srcs -} - func (test *testBinary) dataPaths() []android.DataPath { return test.data } -func (test *testBinary) isAllTestsVariation() bool { - stem := test.binaryDecorator.Properties.Stem - return stem != nil && *stem == "" -} - -func (test *testBinary) setSrc(name, src string) { - test.baseCompiler.Properties.Srcs = []string{src} - test.binaryDecorator.Properties.Stem = StringPtr(name) -} - -func (test *testBinary) unsetSrc() { - test.baseCompiler.Properties.Srcs = nil - test.binaryDecorator.Properties.Stem = StringPtr("") -} - func (test *testBinary) testBinary() bool { return true } -var _ testPerSrc = (*testBinary)(nil) - -func TestPerSrcMutator(mctx android.BottomUpMutatorContext) { - if m, ok := mctx.Module().(*Module); ok { - if test, ok := m.linker.(testPerSrc); ok { - numTests := len(test.srcs()) - if test.testPerSrc() && numTests > 0 { - if duplicate, found := android.CheckDuplicate(test.srcs()); found { - mctx.PropertyErrorf("srcs", "found a duplicate entry %q", duplicate) - return - } - testNames := make([]string, numTests) - for i, src := range test.srcs() { - testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src)) - } - // In addition to creating one variation per test source file, - // create an additional "all tests" variation named "", and have it - // depends on all other test_per_src variations. This is useful to - // create subsequent dependencies of a given module on all - // test_per_src variations created above: by depending on - // variation "", that module will transitively depend on all the - // other test_per_src variations without the need to know their - // name or even their number. - testNames = append(testNames, "") - tests := mctx.CreateLocalVariations(testNames...) - allTests := tests[numTests] - allTests.(*Module).linker.(testPerSrc).unsetSrc() - // Prevent the "all tests" variation from being installable nor - // exporting to Make, as it won't create any output file. - allTests.(*Module).Properties.PreventInstall = true - allTests.(*Module).Properties.HideFromMake = true - for i, src := range test.srcs() { - tests[i].(*Module).linker.(testPerSrc).setSrc(testNames[i], src) - mctx.AddInterVariantDependency(testPerSrcDepTag, allTests, tests[i]) - } - mctx.AliasVariation("") - } - } - } -} - type testDecorator struct { LinkerProperties TestLinkerProperties InstallerProperties TestInstallerProperties @@ -267,7 +187,7 @@ func (test *testDecorator) gtest() bool { return BoolDefault(test.LinkerProperties.Gtest, true) } -func (test *testDecorator) isolated(ctx BaseModuleContext) bool { +func (test *testDecorator) isolated(ctx android.EarlyModuleContext) bool { return BoolDefault(test.LinkerProperties.Isolated, false) } @@ -323,6 +243,13 @@ func (test *testDecorator) installerProps() []interface{} { return []interface{}{&test.InstallerProperties} } +func (test *testDecorator) moduleInfoJSON(ctx android.ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { + if android.PrefixInList(moduleInfoJSON.CompatibilitySuites, "mts-") && + !android.InList("mts", moduleInfoJSON.CompatibilitySuites) { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "mts") + } +} + func NewTestInstaller() *baseInstaller { return NewBaseInstaller("nativetest", "nativetest64", InstallInData) } @@ -354,9 +281,43 @@ func (test *testBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { func (test *testBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags = test.binaryDecorator.linkerFlags(ctx, flags) flags = test.testDecorator.linkerFlags(ctx, flags) + + // Add a default rpath to allow tests to dlopen libraries specified in data_libs. + // Host modules already get an rpath specified in linker.go. + if !ctx.Host() { + flags.Global.LdFlags = append(flags.Global.LdFlags, `-Wl,-rpath,\$$ORIGIN`) + } return flags } +func (test *testBinary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { + if ctx.Host() && Bool(test.Properties.Test_options.Unit_test) { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests") + } + moduleInfoJSON.TestOptionsTags = append(moduleInfoJSON.TestOptionsTags, test.Properties.Test_options.Tags...) + moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, test.Properties.Test_mainline_modules...) + if test.testConfig != nil { + if _, ok := test.testConfig.(android.WritablePath); ok { + moduleInfoJSON.AutoTestConfig = []string{"true"} + } + moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, test.testConfig.String()) + } + moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, test.extraTestConfigs.Strings()...) + + moduleInfoJSON.DataDependencies = append(moduleInfoJSON.DataDependencies, test.Properties.Data_bins...) + + if len(test.InstallerProperties.Test_suites) > 0 { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, test.InstallerProperties.Test_suites...) + } else { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") + } + + test.binaryDecorator.moduleInfoJSON(ctx, moduleInfoJSON) + test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON) + moduleInfoJSON.Class = []string{"NATIVE_TESTS"} + +} + func (test *testBinary) installerProps() []interface{} { return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) } @@ -393,9 +354,8 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { } }) - useVendor := ctx.inVendor() || ctx.useVndk() - testInstallBase := getTestInstallBase(useVendor) - configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx)) + testInstallBase := getTestInstallBase(ctx.InVendorOrProduct()) + configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx), ctx.Device()) test.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ TestConfigProp: test.Properties.Test_config, @@ -423,6 +383,8 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { if ctx.Host() && test.gtest() && test.Properties.Test_options.Unit_test == nil { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } + + test.binaryDecorator.baseInstaller.installTestData(ctx, test.data) test.binaryDecorator.baseInstaller.install(ctx, file) } @@ -435,22 +397,24 @@ func getTestInstallBase(useVendor bool) string { return testInstallBase } -func getTradefedConfigOptions(ctx android.EarlyModuleContext, properties *TestBinaryProperties, isolated bool) []tradefed.Config { +func getTradefedConfigOptions(ctx android.EarlyModuleContext, properties *TestBinaryProperties, isolated bool, device bool) []tradefed.Config { var configs []tradefed.Config for _, module := range properties.Test_mainline_modules { configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module}) } - if Bool(properties.Require_root) { - configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil}) - } else { - var options []tradefed.Option - options = append(options, tradefed.Option{Name: "force-root", Value: "false"}) - configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options}) - } - if Bool(properties.Disable_framework) { - var options []tradefed.Option - configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options}) + if device { + if Bool(properties.Require_root) { + configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil}) + } else { + var options []tradefed.Option + options = append(options, tradefed.Option{Name: "force-root", Value: "false"}) + configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options}) + } + if Bool(properties.Disable_framework) { + var options []tradefed.Option + configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options}) + } } if isolated { configs = append(configs, tradefed.Option{Name: "not-shardable", Value: "true"}) @@ -483,10 +447,10 @@ func getTradefedConfigOptions(ctx android.EarlyModuleContext, properties *TestBi return configs } -func NewTest(hod android.HostOrDeviceSupported, bazelable bool) *Module { - module, binary := newBinary(hod, bazelable) - module.bazelable = bazelable +func NewTest(hod android.HostOrDeviceSupported) *Module { + module, binary := newBinary(hod) module.multilib = android.MultilibBoth + module.testModule = true binary.baseInstaller = NewTestInstaller() test := &testBinary{ @@ -530,6 +494,15 @@ func (test *testLibrary) linkerFlags(ctx ModuleContext, flags Flags) Flags { return flags } +func (test *testLibrary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { + if len(test.InstallerProperties.Test_suites) > 0 { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, test.InstallerProperties.Test_suites...) + } + + test.libraryDecorator.moduleInfoJSON(ctx, moduleInfoJSON) + test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON) +} + func (test *testLibrary) installerProps() []interface{} { return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) } @@ -546,7 +519,6 @@ func NewTestLibrary(hod android.HostOrDeviceSupported) *Module { } module.linker = test module.installer = test - module.bazelable = true return module } @@ -580,7 +552,7 @@ type BenchmarkProperties struct { type benchmarkDecorator struct { *binaryDecorator Properties BenchmarkProperties - data android.Paths + data []android.DataPath testConfig android.Path } @@ -601,7 +573,9 @@ func (benchmark *benchmarkDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps } func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Path) { - benchmark.data = android.PathsForModuleSrc(ctx, benchmark.Properties.Data) + for _, d := range android.PathsForModuleSrc(ctx, benchmark.Properties.Data) { + benchmark.data = append(benchmark.data, android.DataPath{SrcPath: d}) + } var configs []tradefed.Config if Bool(benchmark.Properties.Require_root) { @@ -619,131 +593,42 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Pat benchmark.binaryDecorator.baseInstaller.dir = filepath.Join("benchmarktest", ctx.ModuleName()) benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName()) + benchmark.binaryDecorator.baseInstaller.installTestData(ctx, benchmark.data) benchmark.binaryDecorator.baseInstaller.install(ctx, file) } -func NewBenchmark(hod android.HostOrDeviceSupported) *Module { - module, binary := newBinary(hod, false) - module.multilib = android.MultilibBoth - binary.baseInstaller = NewBaseInstaller("benchmarktest", "benchmarktest64", InstallInData) +func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { + benchmark.binaryDecorator.moduleInfoJSON(ctx, moduleInfoJSON) - benchmark := &benchmarkDecorator{ - binaryDecorator: binary, - } - module.linker = benchmark - module.installer = benchmark - return module -} - -type ccTestBazelHandler struct { - module *Module -} - -var _ BazelHandler = (*ccTestBazelHandler)(nil) - -func (handler *ccTestBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) { - bazelCtx := ctx.Config().BazelContext - bazelCtx.QueueBazelRequest(label, cquery.GetCcUnstrippedInfo, android.GetConfigKey(ctx)) -} - -func (handler *ccTestBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) { - bazelCtx := ctx.Config().BazelContext - info, err := bazelCtx.GetCcUnstrippedInfo(label, android.GetConfigKey(ctx)) - if err != nil { - ctx.ModuleErrorf(err.Error()) - return + moduleInfoJSON.Class = []string{"NATIVE_TESTS"} + if len(benchmark.Properties.Test_suites) > 0 { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, benchmark.Properties.Test_suites...) + } else { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - var outputFilePath android.Path = android.PathForBazelOut(ctx, info.OutputFile) - if len(info.TidyFiles) > 0 { - handler.module.tidyFiles = android.PathsForBazelOut(ctx, info.TidyFiles) - outputFilePath = android.AttachValidationActions(ctx, outputFilePath, handler.module.tidyFiles) + if android.PrefixInList(moduleInfoJSON.CompatibilitySuites, "mts-") && + !android.InList("mts", moduleInfoJSON.CompatibilitySuites) { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "mts") } - handler.module.outputFile = android.OptionalPathForPath(outputFilePath) - handler.module.linker.(*testBinary).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput) - handler.module.setAndroidMkVariablesFromCquery(info.CcAndroidMkInfo) -} - -// binaryAttributes contains Bazel attributes corresponding to a cc test -type testBinaryAttributes struct { - binaryAttributes - - Gtest bool - Isolated bool - - tidyAttributes - tradefed.TestConfigAttributes -} - -// testBinaryBp2build is the bp2build converter for cc_test modules. A cc_test's -// dependency graph and compilation/linking steps are functionally similar to a -// cc_binary, but has additional dependencies on test deps like gtest, and -// produces additional runfiles like XML plans for Tradefed orchestration -// -// TODO(b/244432609): handle `isolated` property. -// TODO(b/244432134): handle custom runpaths for tests that assume runfile layouts not -// default to bazel. (see linkerInit function) -func testBinaryBp2build(ctx android.TopDownMutatorContext, m *Module) { - var testBinaryAttrs testBinaryAttributes - testBinaryAttrs.binaryAttributes = binaryBp2buildAttrs(ctx, m) - - var data bazel.LabelListAttribute - var tags bazel.StringListAttribute - - testBinaryProps := m.GetArchVariantProperties(ctx, &TestBinaryProperties{}) - for axis, configToProps := range testBinaryProps { - for config, props := range configToProps { - if p, ok := props.(*TestBinaryProperties); ok { - // Combine data, data_bins and data_libs into a single 'data' attribute. - var combinedData bazel.LabelList - combinedData.Append(android.BazelLabelForModuleSrc(ctx, p.Data)) - combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_bins)) - combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_libs)) - data.SetSelectValue(axis, config, combinedData) - tags.SetSelectValue(axis, config, p.Test_options.Tags) - } + if benchmark.testConfig != nil { + if _, ok := benchmark.testConfig.(android.WritablePath); ok { + moduleInfoJSON.AutoTestConfig = []string{"true"} } + moduleInfoJSON.TestConfig = []string{benchmark.testConfig.String()} } +} - m.convertTidyAttributes(ctx, &testBinaryAttrs.tidyAttributes) - - for _, propIntf := range m.GetProperties() { - if testLinkerProps, ok := propIntf.(*TestLinkerProperties); ok { - testBinaryAttrs.Gtest = proptools.BoolDefault(testLinkerProps.Gtest, true) - testBinaryAttrs.Isolated = proptools.BoolDefault(testLinkerProps.Isolated, true) - break - } - } +func NewBenchmark(hod android.HostOrDeviceSupported) *Module { + module, binary := newBinary(hod) + module.multilib = android.MultilibBoth + binary.baseInstaller = NewBaseInstaller("benchmarktest", "benchmarktest64", InstallInData) - for _, testProps := range m.GetProperties() { - if p, ok := testProps.(*TestBinaryProperties); ok { - useVendor := false // TODO Bug: 262914724 - testInstallBase := getTestInstallBase(useVendor) - testConfigAttributes := tradefed.GetTestConfigAttributes( - ctx, - p.Test_config, - p.Test_options.Extra_test_configs, - p.Auto_gen_config, - p.Test_options.Test_suite_tag, - p.Test_config_template, - getTradefedConfigOptions(ctx, p, testBinaryAttrs.Isolated), - &testInstallBase, - ) - testBinaryAttrs.TestConfigAttributes = testConfigAttributes - } + benchmark := &benchmarkDecorator{ + binaryDecorator: binary, } - - // TODO (b/262914724): convert to tradefed_cc_test and tradefed_cc_test_host - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "cc_test", - Bzl_load_location: "//build/bazel/rules/cc:cc_test.bzl", - }, - android.CommonAttributes{ - Name: m.Name(), - Data: data, - Tags: tags, - }, - &testBinaryAttrs) + module.linker = benchmark + module.installer = benchmark + return module } |