1// Copyright 2019 The Android Open Source Project 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 rust 16 17import ( 18 "android/soong/android" 19 "android/soong/tradefed" 20) 21 22type TestProperties struct { 23 // Disables the creation of a test-specific directory when used with 24 // relative_install_path. Useful if several tests need to be in the same 25 // directory, but test_per_src doesn't work. 26 No_named_install_directory *bool 27 28 // the name of the test configuration (for example "AndroidTest.xml") that should be 29 // installed with the module. 30 Test_config *string `android:"path,arch_variant"` 31 32 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 33 // should be installed with the module. 34 Test_config_template *string `android:"path,arch_variant"` 35 36 // list of compatibility suites (for example "cts", "vts") that the module should be 37 // installed into. 38 Test_suites []string `android:"arch_variant"` 39 40 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 41 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 42 // explicitly. 43 Auto_gen_config *bool 44} 45 46// A test module is a binary module with extra --test compiler flag 47// and different default installation directory. 48// In golang, inheriance is written as a component. 49type testDecorator struct { 50 *binaryDecorator 51 Properties TestProperties 52 testConfig android.Path 53} 54 55func (test *testDecorator) nativeCoverage() bool { 56 return true 57} 58 59func NewRustTest(hod android.HostOrDeviceSupported) (*Module, *testDecorator) { 60 // Build both 32 and 64 targets for device tests. 61 // Cannot build both for host tests yet if the test depends on 62 // something like proc-macro2 that cannot be built for both. 63 multilib := android.MultilibBoth 64 if hod != android.DeviceSupported && hod != android.HostAndDeviceSupported { 65 multilib = android.MultilibFirst 66 } 67 module := newModule(hod, multilib) 68 69 test := &testDecorator{ 70 binaryDecorator: &binaryDecorator{ 71 baseCompiler: NewBaseCompiler("nativetest", "nativetest64", InstallInData), 72 }, 73 } 74 75 module.compiler = test 76 module.AddProperties(&test.Properties) 77 return module, test 78} 79 80func (test *testDecorator) compilerProps() []interface{} { 81 return append(test.binaryDecorator.compilerProps(), &test.Properties) 82} 83 84func (test *testDecorator) install(ctx ModuleContext, file android.Path) { 85 test.testConfig = tradefed.AutoGenRustTestConfig(ctx, 86 test.Properties.Test_config, 87 test.Properties.Test_config_template, 88 test.Properties.Test_suites, 89 nil, 90 test.Properties.Auto_gen_config) 91 92 // default relative install path is module name 93 if !Bool(test.Properties.No_named_install_directory) { 94 test.baseCompiler.relative = ctx.ModuleName() 95 } else if String(test.baseCompiler.Properties.Relative_install_path) == "" { 96 ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set") 97 } 98 99 test.binaryDecorator.install(ctx, file) 100} 101 102func (test *testDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { 103 flags = test.binaryDecorator.compilerFlags(ctx, flags) 104 flags.RustFlags = append(flags.RustFlags, "--test") 105 return flags 106} 107 108func (test *testDecorator) autoDep() autoDep { 109 return rlibAutoDep 110} 111 112func init() { 113 // Rust tests are binary files built with --test. 114 android.RegisterModuleType("rust_test", RustTestFactory) 115 android.RegisterModuleType("rust_test_host", RustTestHostFactory) 116} 117 118func RustTestFactory() android.Module { 119 module, _ := NewRustTest(android.HostAndDeviceSupported) 120 return module.Init() 121} 122 123func RustTestHostFactory() android.Module { 124 module, _ := NewRustTest(android.HostSupported) 125 return module.Init() 126} 127