1// Copyright 2016 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package cc 16 17import ( 18 "path/filepath" 19 "strconv" 20 "strings" 21 22 "github.com/google/blueprint/proptools" 23 24 "android/soong/android" 25 "android/soong/tradefed" 26) 27 28// TestLinkerProperties properties to be registered via the linker 29type TestLinkerProperties struct { 30 // if set, build against the gtest library. Defaults to true. 31 Gtest *bool 32 33 // if set, use the isolated gtest runner. Defaults to false. 34 Isolated *bool 35} 36 37// TestInstallerProperties properties to be registered via the installer 38type TestInstallerProperties struct { 39 // list of compatibility suites (for example "cts", "vts") that the module should be installed into. 40 Test_suites []string `android:"arch_variant"` 41} 42 43// Test option struct. 44type TestOptions struct { 45 // The UID that you want to run the test as on a device. 46 Run_test_as *string 47 48 // A list of free-formed strings without spaces that categorize the test. 49 Test_suite_tag []string 50 51 // a list of extra test configuration files that should be installed with the module. 52 Extra_test_configs []string `android:"path,arch_variant"` 53 54 // If the test is a hostside(no device required) unittest that shall be run during presubmit check. 55 Unit_test *bool 56 57 // Add ShippingApiLevelModuleController to auto generated test config. If the device properties 58 // for the shipping api level is less than the min_shipping_api_level, skip this module. 59 Min_shipping_api_level *int64 60 61 // Add ShippingApiLevelModuleController to auto generated test config. If any of the device 62 // shipping api level and vendor api level properties are less than the 63 // vsr_min_shipping_api_level, skip this module. 64 // As this includes the shipping api level check, it is not allowed to define 65 // min_shipping_api_level at the same time with this property. 66 Vsr_min_shipping_api_level *int64 67 68 // Add MinApiLevelModuleController with ro.vndk.version property. If ro.vndk.version has an 69 // integer value and the value is less than the min_vndk_version, skip this module. 70 Min_vndk_version *int64 71} 72 73type TestBinaryProperties struct { 74 // Create a separate binary for each source file. Useful when there is 75 // global state that can not be torn down and reset between each test suite. 76 Test_per_src *bool 77 78 // Disables the creation of a test-specific directory when used with 79 // relative_install_path. Useful if several tests need to be in the same 80 // directory, but test_per_src doesn't work. 81 No_named_install_directory *bool 82 83 // list of files or filegroup modules that provide data that should be installed alongside 84 // the test 85 Data []string `android:"path,arch_variant"` 86 87 // list of shared library modules that should be installed alongside the test 88 Data_libs []string `android:"arch_variant"` 89 90 // list of binary modules that should be installed alongside the test 91 Data_bins []string `android:"arch_variant"` 92 93 // the name of the test configuration (for example "AndroidTest.xml") that should be 94 // installed with the module. 95 Test_config *string `android:"path,arch_variant"` 96 97 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 98 // should be installed with the module. 99 Test_config_template *string `android:"path,arch_variant"` 100 101 // Test options. 102 Test_options TestOptions 103 104 // Add RootTargetPreparer to auto generated test config. This guarantees the test to run 105 // with root permission. 106 Require_root *bool 107 108 // Add RunCommandTargetPreparer to stop framework before the test and start it after the test. 109 Disable_framework *bool 110 111 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 112 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 113 // explicitly. 114 Auto_gen_config *bool 115 116 // Add parameterized mainline modules to auto generated test config. The options will be 117 // handled by TradeFed to download and install the specified modules on the device. 118 Test_mainline_modules []string 119 120 // Install the test into a folder named for the module in all test suites. 121 Per_testcase_directory *bool 122} 123 124func init() { 125 android.RegisterModuleType("cc_test", TestFactory) 126 android.RegisterModuleType("cc_test_library", TestLibraryFactory) 127 android.RegisterModuleType("cc_benchmark", BenchmarkFactory) 128 android.RegisterModuleType("cc_test_host", TestHostFactory) 129 android.RegisterModuleType("cc_benchmark_host", BenchmarkHostFactory) 130} 131 132// cc_test generates a test config file and an executable binary file to test 133// specific functionality on a device. The executable binary gets an implicit 134// static_libs dependency on libgtests unless the gtest flag is set to false. 135func TestFactory() android.Module { 136 module := NewTest(android.HostAndDeviceSupported) 137 return module.Init() 138} 139 140// cc_test_library creates an archive of files (i.e. .o files) which is later 141// referenced by another module (such as cc_test, cc_defaults or cc_test_library) 142// for archiving or linking. 143func TestLibraryFactory() android.Module { 144 module := NewTestLibrary(android.HostAndDeviceSupported) 145 return module.Init() 146} 147 148// cc_benchmark compiles an executable binary that performs benchmark testing 149// of a specific component in a device. Additional files such as test suites 150// and test configuration are installed on the side of the compiled executed 151// binary. 152func BenchmarkFactory() android.Module { 153 module := NewBenchmark(android.HostAndDeviceSupported) 154 return module.Init() 155} 156 157// cc_test_host compiles a test host binary. 158func TestHostFactory() android.Module { 159 module := NewTest(android.HostSupported) 160 return module.Init() 161} 162 163// cc_benchmark_host compiles an executable binary that performs benchmark 164// testing of a specific component in the host. Additional files such as 165// test suites and test configuration are installed on the side of the 166// compiled executed binary. 167func BenchmarkHostFactory() android.Module { 168 module := NewBenchmark(android.HostSupported) 169 return module.Init() 170} 171 172type testPerSrc interface { 173 testPerSrc() bool 174 srcs() []string 175 isAllTestsVariation() bool 176 setSrc(string, string) 177 unsetSrc() 178} 179 180func (test *testBinary) testPerSrc() bool { 181 return Bool(test.Properties.Test_per_src) 182} 183 184func (test *testBinary) srcs() []string { 185 return test.baseCompiler.Properties.Srcs 186} 187 188func (test *testBinary) dataPaths() []android.DataPath { 189 return test.data 190} 191 192func (test *testBinary) isAllTestsVariation() bool { 193 stem := test.binaryDecorator.Properties.Stem 194 return stem != nil && *stem == "" 195} 196 197func (test *testBinary) setSrc(name, src string) { 198 test.baseCompiler.Properties.Srcs = []string{src} 199 test.binaryDecorator.Properties.Stem = StringPtr(name) 200} 201 202func (test *testBinary) unsetSrc() { 203 test.baseCompiler.Properties.Srcs = nil 204 test.binaryDecorator.Properties.Stem = StringPtr("") 205} 206 207var _ testPerSrc = (*testBinary)(nil) 208 209func TestPerSrcMutator(mctx android.BottomUpMutatorContext) { 210 if m, ok := mctx.Module().(*Module); ok { 211 if test, ok := m.linker.(testPerSrc); ok { 212 numTests := len(test.srcs()) 213 if test.testPerSrc() && numTests > 0 { 214 if duplicate, found := android.CheckDuplicate(test.srcs()); found { 215 mctx.PropertyErrorf("srcs", "found a duplicate entry %q", duplicate) 216 return 217 } 218 testNames := make([]string, numTests) 219 for i, src := range test.srcs() { 220 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src)) 221 } 222 // In addition to creating one variation per test source file, 223 // create an additional "all tests" variation named "", and have it 224 // depends on all other test_per_src variations. This is useful to 225 // create subsequent dependencies of a given module on all 226 // test_per_src variations created above: by depending on 227 // variation "", that module will transitively depend on all the 228 // other test_per_src variations without the need to know their 229 // name or even their number. 230 testNames = append(testNames, "") 231 tests := mctx.CreateLocalVariations(testNames...) 232 allTests := tests[numTests] 233 allTests.(*Module).linker.(testPerSrc).unsetSrc() 234 // Prevent the "all tests" variation from being installable nor 235 // exporting to Make, as it won't create any output file. 236 allTests.(*Module).Properties.PreventInstall = true 237 allTests.(*Module).Properties.HideFromMake = true 238 for i, src := range test.srcs() { 239 tests[i].(*Module).linker.(testPerSrc).setSrc(testNames[i], src) 240 mctx.AddInterVariantDependency(testPerSrcDepTag, allTests, tests[i]) 241 } 242 mctx.AliasVariation("") 243 } 244 } 245 } 246} 247 248type testDecorator struct { 249 LinkerProperties TestLinkerProperties 250 InstallerProperties TestInstallerProperties 251 installer *baseInstaller 252 linker *baseLinker 253} 254 255func (test *testDecorator) gtest() bool { 256 return BoolDefault(test.LinkerProperties.Gtest, true) 257} 258 259func (test *testDecorator) testBinary() bool { 260 return true 261} 262 263func (test *testDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 264 if !test.gtest() { 265 return flags 266 } 267 268 flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_HAS_STD_STRING") 269 if ctx.Host() { 270 flags.Local.CFlags = append(flags.Local.CFlags, "-O0", "-g") 271 272 switch ctx.Os() { 273 case android.Windows: 274 flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_OS_WINDOWS") 275 case android.Linux: 276 flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_OS_LINUX") 277 case android.Darwin: 278 flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_OS_MAC") 279 } 280 } else { 281 flags.Local.CFlags = append(flags.Local.CFlags, "-DGTEST_OS_LINUX_ANDROID") 282 } 283 284 return flags 285} 286 287func (test *testDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps { 288 if test.gtest() { 289 if ctx.useSdk() && ctx.Device() { 290 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main_ndk_c++", "libgtest_ndk_c++") 291 } else if BoolDefault(test.LinkerProperties.Isolated, false) { 292 deps.StaticLibs = append(deps.StaticLibs, "libgtest_isolated_main") 293 // The isolated library requires liblog, but adding it 294 // as a static library means unit tests cannot override 295 // liblog functions. Instead make it a shared library 296 // dependency. 297 deps.SharedLibs = append(deps.SharedLibs, "liblog") 298 } else { 299 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest") 300 } 301 } 302 303 return deps 304} 305 306func (test *testDecorator) linkerInit(ctx BaseModuleContext, linker *baseLinker) { 307 // 1. Add ../../lib[64] to rpath so that out/host/linux-x86/nativetest/<test dir>/<test> can 308 // find out/host/linux-x86/lib[64]/library.so 309 // 2. Add ../../../lib[64] to rpath so that out/host/linux-x86/testcases/<test dir>/<CPU>/<test> can 310 // also find out/host/linux-x86/lib[64]/library.so 311 runpaths := []string{"../../lib", "../../../lib"} 312 for _, runpath := range runpaths { 313 if ctx.toolchain().Is64Bit() { 314 runpath += "64" 315 } 316 linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, runpath) 317 } 318 319 // add "" to rpath so that test binaries can find libraries in their own test directory 320 linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "") 321} 322 323func (test *testDecorator) linkerProps() []interface{} { 324 return []interface{}{&test.LinkerProperties} 325} 326 327func (test *testDecorator) installerProps() []interface{} { 328 return []interface{}{&test.InstallerProperties} 329} 330 331func NewTestInstaller() *baseInstaller { 332 return NewBaseInstaller("nativetest", "nativetest64", InstallInData) 333} 334 335type testBinary struct { 336 *testDecorator 337 *binaryDecorator 338 *baseCompiler 339 Properties TestBinaryProperties 340 data []android.DataPath 341 testConfig android.Path 342 extraTestConfigs android.Paths 343} 344 345func (test *testBinary) linkerProps() []interface{} { 346 props := append(test.testDecorator.linkerProps(), test.binaryDecorator.linkerProps()...) 347 props = append(props, &test.Properties) 348 return props 349} 350 351func (test *testBinary) linkerInit(ctx BaseModuleContext) { 352 test.testDecorator.linkerInit(ctx, test.binaryDecorator.baseLinker) 353 test.binaryDecorator.linkerInit(ctx) 354} 355 356func (test *testBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { 357 deps = test.testDecorator.linkerDeps(ctx, deps) 358 deps = test.binaryDecorator.linkerDeps(ctx, deps) 359 deps.DataLibs = append(deps.DataLibs, test.Properties.Data_libs...) 360 deps.DataBins = append(deps.DataBins, test.Properties.Data_bins...) 361 return deps 362} 363 364func (test *testBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { 365 flags = test.binaryDecorator.linkerFlags(ctx, flags) 366 flags = test.testDecorator.linkerFlags(ctx, flags) 367 return flags 368} 369 370func (test *testBinary) installerProps() []interface{} { 371 return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) 372} 373 374func (test *testBinary) install(ctx ModuleContext, file android.Path) { 375 // TODO: (b/167308193) Switch to /data/local/tests/unrestricted as the default install base. 376 testInstallBase := "/data/local/tmp" 377 if ctx.inVendor() || ctx.useVndk() { 378 testInstallBase = "/data/local/tests/vendor" 379 } 380 381 dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data) 382 383 for _, dataSrcPath := range dataSrcPaths { 384 test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath}) 385 } 386 387 ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) { 388 depName := ctx.OtherModuleName(dep) 389 linkableDep, ok := dep.(LinkableInterface) 390 if !ok { 391 ctx.ModuleErrorf("data_lib %q is not a LinkableInterface module", depName) 392 } 393 if linkableDep.OutputFile().Valid() { 394 test.data = append(test.data, 395 android.DataPath{SrcPath: linkableDep.OutputFile().Path(), 396 RelativeInstallPath: linkableDep.RelativeInstallPath()}) 397 } 398 }) 399 ctx.VisitDirectDepsWithTag(dataBinDepTag, func(dep android.Module) { 400 depName := ctx.OtherModuleName(dep) 401 linkableDep, ok := dep.(LinkableInterface) 402 if !ok { 403 ctx.ModuleErrorf("data_bin %q is not a LinkableInterface module", depName) 404 } 405 if linkableDep.OutputFile().Valid() { 406 test.data = append(test.data, 407 android.DataPath{SrcPath: linkableDep.OutputFile().Path(), 408 RelativeInstallPath: linkableDep.RelativeInstallPath()}) 409 } 410 }) 411 412 var configs []tradefed.Config 413 for _, module := range test.Properties.Test_mainline_modules { 414 configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module}) 415 } 416 if Bool(test.Properties.Require_root) { 417 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil}) 418 } else { 419 var options []tradefed.Option 420 options = append(options, tradefed.Option{Name: "force-root", Value: "false"}) 421 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options}) 422 } 423 if Bool(test.Properties.Disable_framework) { 424 var options []tradefed.Option 425 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options}) 426 } 427 if Bool(test.testDecorator.LinkerProperties.Isolated) { 428 configs = append(configs, tradefed.Option{Name: "not-shardable", Value: "true"}) 429 } 430 if test.Properties.Test_options.Run_test_as != nil { 431 configs = append(configs, tradefed.Option{Name: "run-test-as", Value: String(test.Properties.Test_options.Run_test_as)}) 432 } 433 for _, tag := range test.Properties.Test_options.Test_suite_tag { 434 configs = append(configs, tradefed.Option{Name: "test-suite-tag", Value: tag}) 435 } 436 if test.Properties.Test_options.Min_shipping_api_level != nil { 437 if test.Properties.Test_options.Vsr_min_shipping_api_level != nil { 438 ctx.PropertyErrorf("test_options.min_shipping_api_level", "must not be set at the same time as 'vsr_min_shipping_api_level'.") 439 } 440 var options []tradefed.Option 441 options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Min_shipping_api_level), 10)}) 442 configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options}) 443 } 444 if test.Properties.Test_options.Vsr_min_shipping_api_level != nil { 445 var options []tradefed.Option 446 options = append(options, tradefed.Option{Name: "vsr-min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Vsr_min_shipping_api_level), 10)}) 447 configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options}) 448 } 449 if test.Properties.Test_options.Min_vndk_version != nil { 450 var options []tradefed.Option 451 options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Min_vndk_version), 10)}) 452 options = append(options, tradefed.Option{Name: "api-level-prop", Value: "ro.vndk.version"}) 453 configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.MinApiLevelModuleController", options}) 454 } 455 456 test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config, 457 test.Properties.Test_config_template, test.testDecorator.InstallerProperties.Test_suites, configs, test.Properties.Auto_gen_config, testInstallBase) 458 459 test.extraTestConfigs = android.PathsForModuleSrc(ctx, test.Properties.Test_options.Extra_test_configs) 460 461 test.binaryDecorator.baseInstaller.dir = "nativetest" 462 test.binaryDecorator.baseInstaller.dir64 = "nativetest64" 463 464 if !Bool(test.Properties.No_named_install_directory) { 465 test.binaryDecorator.baseInstaller.relative = ctx.ModuleName() 466 } else if String(test.binaryDecorator.baseInstaller.Properties.Relative_install_path) == "" { 467 ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set") 468 } 469 470 if ctx.Host() && test.gtest() && test.Properties.Test_options.Unit_test == nil { 471 test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) 472 } 473 test.binaryDecorator.baseInstaller.install(ctx, file) 474} 475 476func NewTest(hod android.HostOrDeviceSupported) *Module { 477 module, binary := newBinary(hod, false) 478 module.multilib = android.MultilibBoth 479 binary.baseInstaller = NewTestInstaller() 480 481 test := &testBinary{ 482 testDecorator: &testDecorator{ 483 linker: binary.baseLinker, 484 installer: binary.baseInstaller, 485 }, 486 binaryDecorator: binary, 487 baseCompiler: NewBaseCompiler(), 488 } 489 module.compiler = test 490 module.linker = test 491 module.installer = test 492 return module 493} 494 495type testLibrary struct { 496 *testDecorator 497 *libraryDecorator 498} 499 500func (test *testLibrary) linkerProps() []interface{} { 501 var props []interface{} 502 props = append(props, test.testDecorator.linkerProps()...) 503 return append(props, test.libraryDecorator.linkerProps()...) 504} 505 506func (test *testLibrary) linkerInit(ctx BaseModuleContext) { 507 test.testDecorator.linkerInit(ctx, test.libraryDecorator.baseLinker) 508 test.libraryDecorator.linkerInit(ctx) 509} 510 511func (test *testLibrary) linkerDeps(ctx DepsContext, deps Deps) Deps { 512 deps = test.testDecorator.linkerDeps(ctx, deps) 513 deps = test.libraryDecorator.linkerDeps(ctx, deps) 514 return deps 515} 516 517func (test *testLibrary) linkerFlags(ctx ModuleContext, flags Flags) Flags { 518 flags = test.libraryDecorator.linkerFlags(ctx, flags) 519 flags = test.testDecorator.linkerFlags(ctx, flags) 520 return flags 521} 522 523func (test *testLibrary) installerProps() []interface{} { 524 return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) 525} 526 527func NewTestLibrary(hod android.HostOrDeviceSupported) *Module { 528 module, library := NewLibrary(android.HostAndDeviceSupported) 529 library.baseInstaller = NewTestInstaller() 530 test := &testLibrary{ 531 testDecorator: &testDecorator{ 532 linker: library.baseLinker, 533 installer: library.baseInstaller, 534 }, 535 libraryDecorator: library, 536 } 537 module.linker = test 538 module.installer = test 539 return module 540} 541 542type BenchmarkProperties struct { 543 // list of files or filegroup modules that provide data that should be installed alongside 544 // the test 545 Data []string `android:"path"` 546 547 // list of compatibility suites (for example "cts", "vts") that the module should be 548 // installed into. 549 Test_suites []string `android:"arch_variant"` 550 551 // the name of the test configuration (for example "AndroidTest.xml") that should be 552 // installed with the module. 553 Test_config *string `android:"path,arch_variant"` 554 555 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 556 // should be installed with the module. 557 Test_config_template *string `android:"path,arch_variant"` 558 559 // Add RootTargetPreparer to auto generated test config. This guarantees the test to run 560 // with root permission. 561 Require_root *bool 562 563 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 564 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 565 // explicitly. 566 Auto_gen_config *bool 567} 568 569type benchmarkDecorator struct { 570 *binaryDecorator 571 Properties BenchmarkProperties 572 data android.Paths 573 testConfig android.Path 574} 575 576func (benchmark *benchmarkDecorator) benchmarkBinary() bool { 577 return true 578} 579 580func (benchmark *benchmarkDecorator) linkerInit(ctx BaseModuleContext) { 581 runpath := "../../lib" 582 if ctx.toolchain().Is64Bit() { 583 runpath += "64" 584 } 585 benchmark.baseLinker.dynamicProperties.RunPaths = append(benchmark.baseLinker.dynamicProperties.RunPaths, runpath) 586 benchmark.binaryDecorator.linkerInit(ctx) 587} 588 589func (benchmark *benchmarkDecorator) linkerProps() []interface{} { 590 props := benchmark.binaryDecorator.linkerProps() 591 props = append(props, &benchmark.Properties) 592 return props 593} 594 595func (benchmark *benchmarkDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { 596 deps = benchmark.binaryDecorator.linkerDeps(ctx, deps) 597 deps.StaticLibs = append(deps.StaticLibs, "libgoogle-benchmark") 598 return deps 599} 600 601func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Path) { 602 benchmark.data = android.PathsForModuleSrc(ctx, benchmark.Properties.Data) 603 604 var configs []tradefed.Config 605 if Bool(benchmark.Properties.Require_root) { 606 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil}) 607 } 608 benchmark.testConfig = tradefed.AutoGenNativeBenchmarkTestConfig(ctx, benchmark.Properties.Test_config, 609 benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites, configs, benchmark.Properties.Auto_gen_config) 610 611 benchmark.binaryDecorator.baseInstaller.dir = filepath.Join("benchmarktest", ctx.ModuleName()) 612 benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName()) 613 benchmark.binaryDecorator.baseInstaller.install(ctx, file) 614} 615 616func NewBenchmark(hod android.HostOrDeviceSupported) *Module { 617 module, binary := newBinary(hod, false) 618 module.multilib = android.MultilibBoth 619 binary.baseInstaller = NewBaseInstaller("benchmarktest", "benchmarktest64", InstallInData) 620 621 benchmark := &benchmarkDecorator{ 622 binaryDecorator: binary, 623 } 624 module.linker = benchmark 625 module.installer = benchmark 626 return module 627} 628