blob: 04f844cbc32a4d92c9239ffee9466a47f7d5ea86 [file] [log] [blame]
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -07001// 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 "path/filepath"
19 "strings"
20
21 "android/soong/android"
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070022 "android/soong/tradefed"
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -070023)
24
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070025type TestProperties struct {
26 // the name of the test configuration (for example "AndroidTest.xml") that should be
27 // installed with the module.
28 Test_config *string `android:"arch_variant"`
29
30 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that
31 // should be installed with the module.
32 Test_config_template *string `android:"arch_variant"`
33
34 // list of compatibility suites (for example "cts", "vts") that the module should be
35 // installed into.
36 Test_suites []string `android:"arch_variant"`
37
38 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
39 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
40 // explicitly.
41 Auto_gen_config *bool
42}
43
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -070044// A test module is a binary module with extra --test compiler flag
45// and different default installation directory.
46// In golang, inheriance is written as a component.
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070047type testDecorator struct {
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -070048 *binaryDecorator
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070049 Properties TestProperties
50 testConfig android.Path
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -070051}
52
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070053func NewRustTest(hod android.HostOrDeviceSupported) (*Module, *testDecorator) {
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -070054 module := newModule(hod, android.MultilibFirst)
55
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070056 test := &testDecorator{
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -070057 binaryDecorator: &binaryDecorator{
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080058 baseCompiler: NewBaseCompiler("nativetest", "nativetest64", InstallInData),
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -070059 },
60 }
61
62 module.compiler = test
63
64 return module, test
65}
66
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070067func (test *testDecorator) compilerProps() []interface{} {
68 return append(test.binaryDecorator.compilerProps(), &test.Properties)
69}
70
Chih-Hung Hsiehede57ae2019-11-22 20:22:35 -080071func (test *testDecorator) getMutatedModuleSubName(moduleName string) string {
72 stem := String(test.baseCompiler.Properties.Stem)
73 if stem != "" && !strings.HasSuffix(moduleName, "_"+stem) {
74 // Avoid repeated suffix in the module name.
75 return "_" + stem
76 }
77 return ""
78}
79
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070080func (test *testDecorator) install(ctx ModuleContext, file android.Path) {
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080081 name := ctx.ModuleName()
82 path := test.baseCompiler.relativeInstallPath()
83 // on device, use mutated module name
84 name = name + test.getMutatedModuleSubName(name)
85 if !ctx.Device() { // on host, use mutated module name + arch type + stem name
86 stem := String(test.baseCompiler.Properties.Stem)
87 if stem == "" {
88 stem = name
Chih-Hung Hsiehede57ae2019-11-22 20:22:35 -080089 }
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080090 name = filepath.Join(name, ctx.Arch().ArchType.String(), stem)
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070091 }
Chih-Hung Hsiehede57ae2019-11-22 20:22:35 -080092 test.testConfig = tradefed.AutoGenRustTestConfig(ctx, name,
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -070093 test.Properties.Test_config,
94 test.Properties.Test_config_template,
95 test.Properties.Test_suites,
96 test.Properties.Auto_gen_config)
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080097 // default relative install path is module name
98 if path == "" {
99 test.baseCompiler.relative = ctx.ModuleName()
100 }
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -0700101 test.binaryDecorator.install(ctx, file)
102}
103
104func (test *testDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -0700105 flags = test.binaryDecorator.compilerFlags(ctx, flags)
106 flags.RustFlags = append(flags.RustFlags, "--test")
107 return flags
108}
109
110func init() {
111 // Rust tests are binary files built with --test.
112 android.RegisterModuleType("rust_test", RustTestFactory)
113 android.RegisterModuleType("rust_test_host", RustTestHostFactory)
114}
115
116func RustTestFactory() android.Module {
117 module, _ := NewRustTest(android.HostAndDeviceSupported)
118 return module.Init()
119}
120
121func RustTestHostFactory() android.Module {
122 module, _ := NewRustTest(android.HostSupported)
123 return module.Init()
124}
125
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -0700126func (test *testDecorator) testPerSrc() bool {
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -0700127 return true
128}
129
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -0700130func (test *testDecorator) srcs() []string {
131 return test.binaryDecorator.Properties.Srcs
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -0700132}
133
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -0700134func (test *testDecorator) setSrc(name, src string) {
135 test.binaryDecorator.Properties.Srcs = []string{src}
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -0700136 test.baseCompiler.Properties.Stem = StringPtr(name)
137}
138
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -0700139func (test *testDecorator) unsetSrc() {
140 test.binaryDecorator.Properties.Srcs = nil
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -0700141 test.baseCompiler.Properties.Stem = StringPtr("")
142}
143
144type testPerSrc interface {
145 testPerSrc() bool
146 srcs() []string
147 setSrc(string, string)
148 unsetSrc()
149}
150
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -0700151var _ testPerSrc = (*testDecorator)(nil)
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -0700152
153func TestPerSrcMutator(mctx android.BottomUpMutatorContext) {
154 if m, ok := mctx.Module().(*Module); ok {
155 if test, ok := m.compiler.(testPerSrc); ok {
156 numTests := len(test.srcs())
157 if test.testPerSrc() && numTests > 0 {
158 if duplicate, found := android.CheckDuplicate(test.srcs()); found {
159 mctx.PropertyErrorf("srcs", "found a duplicate entry %q", duplicate)
160 return
161 }
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -0700162 // Rust compiler always compiles one source file at a time and
163 // uses the crate name as output file name.
164 // Cargo uses the test source file name as default crate name,
165 // but that can be redefined.
166 // So when there are multiple source files, the source file names will
167 // be the output file names, but when there is only one test file,
168 // use the crate name.
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -0700169 testNames := make([]string, numTests)
170 for i, src := range test.srcs() {
171 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
172 }
Chih-Hung Hsieh41805be2019-10-31 20:56:47 -0700173 crateName := m.compiler.crateName()
174 if numTests == 1 && crateName != "" {
175 testNames[0] = crateName
176 }
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -0700177 // TODO(chh): Add an "all tests" variation like cc/test.go?
178 tests := mctx.CreateLocalVariations(testNames...)
179 for i, src := range test.srcs() {
180 tests[i].(*Module).compiler.(testPerSrc).setSrc(testNames[i], src)
181 }
182 }
183 }
184 }
185}