summaryrefslogtreecommitdiff
path: root/cc/test.go
diff options
context:
space:
mode:
Diffstat (limited to 'cc/test.go')
-rw-r--r--cc/test.go325
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
}