blob: 7cd7c5a37974b866ddcc1900cb11dcb13302df3f [file] [log] [blame]
Colin Cross303e21f2018-08-07 16:49:25 -07001// Copyright 2018 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 tradefed
16
17import (
Julien Desprezeb7398e2019-02-28 08:45:28 -080018 "fmt"
Julien Desprezeb7398e2019-02-28 08:45:28 -080019 "strings"
20
Colin Cross303e21f2018-08-07 16:49:25 -070021 "github.com/google/blueprint"
Julien Desprezeb7398e2019-02-28 08:45:28 -080022 "github.com/google/blueprint/proptools"
Colin Cross303e21f2018-08-07 16:49:25 -070023
24 "android/soong/android"
25)
26
Dan Shi20ccd212019-08-27 10:37:24 -070027const test_xml_indent = " "
28
Jack He33338892018-09-19 02:21:28 -070029func getTestConfigTemplate(ctx android.ModuleContext, prop *string) android.OptionalPath {
30 return ctx.ExpandOptionalSource(prop, "test_config_template")
31}
32
Colin Cross303e21f2018-08-07 16:49:25 -070033func getTestConfig(ctx android.ModuleContext, prop *string) android.Path {
34 if p := ctx.ExpandOptionalSource(prop, "test_config"); p.Valid() {
35 return p.Path()
36 } else if p := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); p.Valid() {
37 return p.Path()
38 }
39 return nil
40}
41
42var autogenTestConfig = pctx.StaticRule("autogenTestConfig", blueprint.RuleParams{
Dan Shi37ee3b82019-06-06 16:23:32 -070043 Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_CONFIGS}&'${extraConfigs}'&g' $template > $out",
Colin Cross303e21f2018-08-07 16:49:25 -070044 CommandDeps: []string{"$template"},
Dan Shi37ee3b82019-06-06 16:23:32 -070045}, "name", "template", "extraConfigs")
Colin Cross303e21f2018-08-07 16:49:25 -070046
yangbill4f41bc22019-02-13 21:45:47 +080047func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string) (path android.Path, autogenPath android.WritablePath) {
Colin Cross303e21f2018-08-07 16:49:25 -070048 if p := getTestConfig(ctx, prop); p != nil {
49 return p, nil
yangbill4f41bc22019-02-13 21:45:47 +080050 } else if !android.InList("cts", testSuites) {
Colin Cross303e21f2018-08-07 16:49:25 -070051 outputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".config")
Jack He33338892018-09-19 02:21:28 -070052 return nil, outputFile
Colin Cross303e21f2018-08-07 16:49:25 -070053 } else {
54 // CTS modules can be used for test data, so test config files must be
55 // explicitly created using AndroidTest.xml
56 // TODO(b/112602712): remove the path check
57 return nil, nil
58 }
59}
60
Dan Shi37ee3b82019-06-06 16:23:32 -070061type Config interface {
62 Config() string
63}
64
65type Option struct {
66 Name string
67 Value string
68}
69
70var _ Config = Option{}
71
72func (o Option) Config() string {
73 return fmt.Sprintf(`<option name="%s" value="%s" />`, o.Name, o.Value)
74}
75
76type Preparer struct {
Dan Shi20ccd212019-08-27 10:37:24 -070077 Class string
78 Options []Option
Dan Shi37ee3b82019-06-06 16:23:32 -070079}
80
81var _ Config = Preparer{}
82
83func (p Preparer) Config() string {
Dan Shi20ccd212019-08-27 10:37:24 -070084 var optionStrings []string
85 for _, option := range p.Options {
86 optionStrings = append(optionStrings, option.Config())
87 }
88 var options string
89 if len(p.Options) == 0 {
90 options = ""
91 } else {
92 optionDelimiter := fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent)
93 options = optionDelimiter + strings.Join(optionStrings, optionDelimiter)
94 }
95 return fmt.Sprintf(`<target_preparer class="%s">%s\n%s</target_preparer>`, p.Class, options, test_xml_indent)
Dan Shi37ee3b82019-06-06 16:23:32 -070096}
97
98func autogenTemplate(ctx android.ModuleContext, output android.WritablePath, template string, configs []Config) {
99 var configStrings []string
100 for _, config := range configs {
101 configStrings = append(configStrings, config.Config())
Julien Desprezeb7398e2019-02-28 08:45:28 -0800102 }
Dan Shi20ccd212019-08-27 10:37:24 -0700103 extraConfigs := strings.Join(configStrings, fmt.Sprintf("\\n%s", test_xml_indent))
Dan Shi37ee3b82019-06-06 16:23:32 -0700104 extraConfigs = proptools.NinjaAndShellEscape(extraConfigs)
Julien Desprezeb7398e2019-02-28 08:45:28 -0800105
Colin Cross303e21f2018-08-07 16:49:25 -0700106 ctx.Build(pctx, android.BuildParams{
107 Rule: autogenTestConfig,
108 Description: "test config",
109 Output: output,
110 Args: map[string]string{
Julien Desprezeb7398e2019-02-28 08:45:28 -0800111 "name": ctx.ModuleName(),
112 "template": template,
Dan Shi37ee3b82019-06-06 16:23:32 -0700113 "extraConfigs": extraConfigs,
Colin Cross303e21f2018-08-07 16:49:25 -0700114 },
115 })
116}
117
Jack He33338892018-09-19 02:21:28 -0700118func AutoGenNativeTestConfig(ctx android.ModuleContext, testConfigProp *string,
Dan Shi37ee3b82019-06-06 16:23:32 -0700119 testConfigTemplateProp *string, testSuites []string, config []Config) android.Path {
yangbill4f41bc22019-02-13 21:45:47 +0800120 path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
Colin Cross303e21f2018-08-07 16:49:25 -0700121 if autogenPath != nil {
Jack He33338892018-09-19 02:21:28 -0700122 templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
123 if templatePath.Valid() {
Dan Shi37ee3b82019-06-06 16:23:32 -0700124 autogenTemplate(ctx, autogenPath, templatePath.String(), config)
Colin Cross303e21f2018-08-07 16:49:25 -0700125 } else {
Jack He33338892018-09-19 02:21:28 -0700126 if ctx.Device() {
Dan Shi37ee3b82019-06-06 16:23:32 -0700127 autogenTemplate(ctx, autogenPath, "${NativeTestConfigTemplate}", config)
Jack He33338892018-09-19 02:21:28 -0700128 } else {
Dan Shi37ee3b82019-06-06 16:23:32 -0700129 autogenTemplate(ctx, autogenPath, "${NativeHostTestConfigTemplate}", config)
Jack He33338892018-09-19 02:21:28 -0700130 }
Colin Cross303e21f2018-08-07 16:49:25 -0700131 }
Jack He33338892018-09-19 02:21:28 -0700132 return autogenPath
Colin Cross303e21f2018-08-07 16:49:25 -0700133 }
134 return path
135}
136
Jack He33338892018-09-19 02:21:28 -0700137func AutoGenNativeBenchmarkTestConfig(ctx android.ModuleContext, testConfigProp *string,
Dan Shi37ee3b82019-06-06 16:23:32 -0700138 testConfigTemplateProp *string, testSuites []string, configs []Config) android.Path {
yangbill4f41bc22019-02-13 21:45:47 +0800139 path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
Colin Cross303e21f2018-08-07 16:49:25 -0700140 if autogenPath != nil {
Jack He33338892018-09-19 02:21:28 -0700141 templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
142 if templatePath.Valid() {
Dan Shi37ee3b82019-06-06 16:23:32 -0700143 autogenTemplate(ctx, autogenPath, templatePath.String(), configs)
Jack He33338892018-09-19 02:21:28 -0700144 } else {
Dan Shi37ee3b82019-06-06 16:23:32 -0700145 autogenTemplate(ctx, autogenPath, "${NativeBenchmarkTestConfigTemplate}", configs)
Jack He33338892018-09-19 02:21:28 -0700146 }
147 return autogenPath
Colin Cross303e21f2018-08-07 16:49:25 -0700148 }
149 return path
150}
151
yangbill4f41bc22019-02-13 21:45:47 +0800152func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string, testSuites []string) android.Path {
153 path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
Colin Cross303e21f2018-08-07 16:49:25 -0700154 if autogenPath != nil {
Jack He33338892018-09-19 02:21:28 -0700155 templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
156 if templatePath.Valid() {
Julien Desprezeb7398e2019-02-28 08:45:28 -0800157 autogenTemplate(ctx, autogenPath, templatePath.String(), nil)
Colin Cross303e21f2018-08-07 16:49:25 -0700158 } else {
Jack He33338892018-09-19 02:21:28 -0700159 if ctx.Device() {
Julien Desprezeb7398e2019-02-28 08:45:28 -0800160 autogenTemplate(ctx, autogenPath, "${JavaTestConfigTemplate}", nil)
Jack He33338892018-09-19 02:21:28 -0700161 } else {
Julien Desprezeb7398e2019-02-28 08:45:28 -0800162 autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", nil)
Jack He33338892018-09-19 02:21:28 -0700163 }
Colin Cross303e21f2018-08-07 16:49:25 -0700164 }
Jack He33338892018-09-19 02:21:28 -0700165 return autogenPath
Colin Cross303e21f2018-08-07 16:49:25 -0700166 }
167 return path
168}
169
yelinhsieh80880a32018-11-06 11:49:55 +0800170func AutoGenPythonBinaryHostTestConfig(ctx android.ModuleContext, testConfigProp *string,
yangbill4f41bc22019-02-13 21:45:47 +0800171 testConfigTemplateProp *string, testSuites []string) android.Path {
yelinhsieh80880a32018-11-06 11:49:55 +0800172
yangbill4f41bc22019-02-13 21:45:47 +0800173 path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
yelinhsieh80880a32018-11-06 11:49:55 +0800174 if autogenPath != nil {
175 templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
176 if templatePath.Valid() {
Julien Desprezeb7398e2019-02-28 08:45:28 -0800177 autogenTemplate(ctx, autogenPath, templatePath.String(), nil)
yelinhsieh80880a32018-11-06 11:49:55 +0800178 } else {
Julien Desprezeb7398e2019-02-28 08:45:28 -0800179 autogenTemplate(ctx, autogenPath, "${PythonBinaryHostTestConfigTemplate}", nil)
yelinhsieh80880a32018-11-06 11:49:55 +0800180 }
181 return autogenPath
182 }
183 return path
184}
185
Colin Cross303e21f2018-08-07 16:49:25 -0700186var autogenInstrumentationTest = pctx.StaticRule("autogenInstrumentationTest", blueprint.RuleParams{
Jack He33338892018-09-19 02:21:28 -0700187 Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template",
Colin Cross303e21f2018-08-07 16:49:25 -0700188 CommandDeps: []string{
189 "${AutoGenTestConfigScript}",
190 "${EmptyTestConfig}",
Jack He33338892018-09-19 02:21:28 -0700191 "$template",
Colin Cross303e21f2018-08-07 16:49:25 -0700192 },
Jack He33338892018-09-19 02:21:28 -0700193}, "name", "template")
Colin Cross303e21f2018-08-07 16:49:25 -0700194
yangbill4f41bc22019-02-13 21:45:47 +0800195func AutoGenInstrumentationTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string, manifest android.Path, testSuites []string) android.Path {
196 path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
Colin Cross303e21f2018-08-07 16:49:25 -0700197 if autogenPath != nil {
Jack He33338892018-09-19 02:21:28 -0700198 template := "${InstrumentationTestConfigTemplate}"
199 moduleTemplate := getTestConfigTemplate(ctx, testConfigTemplateProp)
200 if moduleTemplate.Valid() {
201 template = moduleTemplate.String()
202 }
Colin Cross303e21f2018-08-07 16:49:25 -0700203 ctx.Build(pctx, android.BuildParams{
204 Rule: autogenInstrumentationTest,
205 Description: "test config",
206 Input: manifest,
207 Output: autogenPath,
208 Args: map[string]string{
Jack He33338892018-09-19 02:21:28 -0700209 "name": ctx.ModuleName(),
210 "template": template,
Colin Cross303e21f2018-08-07 16:49:25 -0700211 },
212 })
Jack He33338892018-09-19 02:21:28 -0700213 return autogenPath
Colin Cross303e21f2018-08-07 16:49:25 -0700214 }
215 return path
216}