• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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