• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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 (
18	"fmt"
19	"sort"
20	"strings"
21
22	"github.com/google/blueprint"
23	"github.com/google/blueprint/proptools"
24
25	"android/soong/android"
26)
27
28func getTestConfigTemplate(ctx android.ModuleContext, prop *string) android.OptionalPath {
29	return ctx.ExpandOptionalSource(prop, "test_config_template")
30}
31
32func getTestConfig(ctx android.ModuleContext, prop *string) android.Path {
33	if p := ctx.ExpandOptionalSource(prop, "test_config"); p.Valid() {
34		return p.Path()
35	} else if p := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); p.Valid() {
36		return p.Path()
37	}
38	return nil
39}
40
41var autogenTestConfig = pctx.StaticRule("autogenTestConfig", blueprint.RuleParams{
42	Command:     "sed 's&{MODULE}&${name}&g;s&{EXTRA_OPTIONS}&'${extraOptions}'&g' $template > $out",
43	CommandDeps: []string{"$template"},
44}, "name", "template", "extraOptions")
45
46func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string) (path android.Path, autogenPath android.WritablePath) {
47	if p := getTestConfig(ctx, prop); p != nil {
48		return p, nil
49	} else if !android.InList("cts", testSuites) {
50		outputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".config")
51		return nil, outputFile
52	} else {
53		// CTS modules can be used for test data, so test config files must be
54		// explicitly created using AndroidTest.xml
55		// TODO(b/112602712): remove the path check
56		return nil, nil
57	}
58}
59
60func autogenTemplate(ctx android.ModuleContext, output android.WritablePath, template string, optionsMap map[string]string) {
61	// If no test option found, delete {EXTRA_OPTIONS} line.
62	var options []string
63	for optionName, value := range optionsMap {
64		if value != "" {
65			options = append(options, fmt.Sprintf(`<option name="%s" value="%s" />`, optionName, value))
66		}
67	}
68	sort.Strings(options)
69	extraOptions := strings.Join(options, "\n        ")
70	extraOptions = proptools.NinjaAndShellEscape(extraOptions)
71
72	ctx.Build(pctx, android.BuildParams{
73		Rule:        autogenTestConfig,
74		Description: "test config",
75		Output:      output,
76		Args: map[string]string{
77			"name":         ctx.ModuleName(),
78			"template":     template,
79			"extraOptions": extraOptions,
80		},
81	})
82}
83
84func AutoGenNativeTestConfig(ctx android.ModuleContext, testConfigProp *string,
85	testConfigTemplateProp *string, testSuites []string,
86	optionsMap map[string]string) android.Path {
87	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
88	if autogenPath != nil {
89		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
90		if templatePath.Valid() {
91			autogenTemplate(ctx, autogenPath, templatePath.String(), optionsMap)
92		} else {
93			if ctx.Device() {
94				autogenTemplate(ctx, autogenPath, "${NativeTestConfigTemplate}",
95					optionsMap)
96			} else {
97				autogenTemplate(ctx, autogenPath, "${NativeHostTestConfigTemplate}",
98					optionsMap)
99			}
100		}
101		return autogenPath
102	}
103	return path
104}
105
106func AutoGenNativeBenchmarkTestConfig(ctx android.ModuleContext, testConfigProp *string,
107	testConfigTemplateProp *string, testSuites []string) android.Path {
108	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
109	if autogenPath != nil {
110		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
111		if templatePath.Valid() {
112			autogenTemplate(ctx, autogenPath, templatePath.String(), nil)
113		} else {
114			autogenTemplate(ctx, autogenPath, "${NativeBenchmarkTestConfigTemplate}", nil)
115		}
116		return autogenPath
117	}
118	return path
119}
120
121func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string, testSuites []string) android.Path {
122	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
123	if autogenPath != nil {
124		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
125		if templatePath.Valid() {
126			autogenTemplate(ctx, autogenPath, templatePath.String(), nil)
127		} else {
128			if ctx.Device() {
129				autogenTemplate(ctx, autogenPath, "${JavaTestConfigTemplate}", nil)
130			} else {
131				autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", nil)
132			}
133		}
134		return autogenPath
135	}
136	return path
137}
138
139func AutoGenPythonBinaryHostTestConfig(ctx android.ModuleContext, testConfigProp *string,
140	testConfigTemplateProp *string, testSuites []string) android.Path {
141
142	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
143	if autogenPath != nil {
144		templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
145		if templatePath.Valid() {
146			autogenTemplate(ctx, autogenPath, templatePath.String(), nil)
147		} else {
148			autogenTemplate(ctx, autogenPath, "${PythonBinaryHostTestConfigTemplate}", nil)
149		}
150		return autogenPath
151	}
152	return path
153}
154
155var autogenInstrumentationTest = pctx.StaticRule("autogenInstrumentationTest", blueprint.RuleParams{
156	Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template",
157	CommandDeps: []string{
158		"${AutoGenTestConfigScript}",
159		"${EmptyTestConfig}",
160		"$template",
161	},
162}, "name", "template")
163
164func AutoGenInstrumentationTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string, manifest android.Path, testSuites []string) android.Path {
165	path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites)
166	if autogenPath != nil {
167		template := "${InstrumentationTestConfigTemplate}"
168		moduleTemplate := getTestConfigTemplate(ctx, testConfigTemplateProp)
169		if moduleTemplate.Valid() {
170			template = moduleTemplate.String()
171		}
172		ctx.Build(pctx, android.BuildParams{
173			Rule:        autogenInstrumentationTest,
174			Description: "test config",
175			Input:       manifest,
176			Output:      autogenPath,
177			Args: map[string]string{
178				"name":     ctx.ModuleName(),
179				"template": template,
180			},
181		})
182		return autogenPath
183	}
184	return path
185}
186