1// Copyright 2020 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 csuite
16
17import (
18	"android/soong/android"
19	"android/soong/java"
20	"strings"
21)
22
23var (
24	pctx = android.NewPackageContext("android/soong/csuite")
25)
26
27func init() {
28	android.RegisterModuleType("csuite_test", CSuiteTestFactory)
29}
30
31type csuiteTestProperties struct {
32	// Local path to a module template xml file.
33	// The content of the template will be used to generate test modules at runtime.
34	Test_config_template *string `android:"path"`
35
36	// Local path to a test plan config xml to be included in the generated plan.
37	Test_plan_include *string `android:"path"`
38}
39
40type CSuiteTest struct {
41	// Java TestHost.
42	java.TestHost
43
44	// C-Suite test properties struct.
45	csuiteTestProperties csuiteTestProperties
46}
47
48func (cSuiteTest *CSuiteTest) buildCopyConfigTemplateCommand(ctx android.ModuleContext, rule *android.RuleBuilder) string {
49	if cSuiteTest.csuiteTestProperties.Test_config_template == nil {
50		ctx.ModuleErrorf(`'test_config_template' is missing.`)
51	}
52	inputPath := android.PathForModuleSrc(ctx, *cSuiteTest.csuiteTestProperties.Test_config_template)
53	genPath := android.PathForModuleGen(ctx, planConfigDirName, ctx.ModuleName()+configTemplateFileExtension)
54	rule.Command().Textf("cp").Input(inputPath).Output(genPath)
55	cSuiteTest.AddExtraResource(genPath)
56	return genPath.Rel()
57}
58
59func (cSuiteTest *CSuiteTest) buildCopyPlanIncludeCommand(ctx android.ModuleContext, rule *android.RuleBuilder) string {
60	if cSuiteTest.csuiteTestProperties.Test_plan_include == nil {
61		return emptyPlanIncludePath
62	}
63	inputPath := android.PathForModuleSrc(ctx, *cSuiteTest.csuiteTestProperties.Test_plan_include)
64	genPath := android.PathForModuleGen(ctx, planConfigDirName, "includes", ctx.ModuleName()+".xml")
65	rule.Command().Textf("cp").Input(inputPath).Output(genPath)
66	cSuiteTest.AddExtraResource(genPath)
67	return strings.Replace(genPath.Rel(), "config/", "", -1)
68}
69
70func (cSuiteTest *CSuiteTest) buildWritePlanConfigRule(ctx android.ModuleContext, configTemplatePath string, planIncludePath string) {
71	planName := ctx.ModuleName()
72	content := strings.Replace(planTemplate, "{planName}", planName, -1)
73	content = strings.Replace(content, "{templatePath}", configTemplatePath, -1)
74	content = strings.Replace(content, "{planInclude}", planIncludePath, -1)
75	genPath := android.PathForModuleGen(ctx, planConfigDirName, planName+planFileExtension)
76	android.WriteFileRule(ctx, genPath, content)
77	cSuiteTest.AddExtraResource(genPath)
78}
79
80func (cSuiteTest *CSuiteTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
81	rule := android.NewRuleBuilder(pctx, ctx)
82
83	configTemplatePath := cSuiteTest.buildCopyConfigTemplateCommand(ctx, rule)
84	planIncludePath := cSuiteTest.buildCopyPlanIncludeCommand(ctx, rule)
85	cSuiteTest.buildWritePlanConfigRule(ctx, configTemplatePath, planIncludePath)
86
87	rule.Build("CSuite", "generate C-Suite config files")
88	cSuiteTest.TestHost.GenerateAndroidBuildActions(ctx)
89}
90
91func CSuiteTestFactory() android.Module {
92	module := &CSuiteTest{}
93	module.AddProperties(&module.csuiteTestProperties)
94	installable := true
95	autoGenConfig := false
96	java.InitTestHost(&module.TestHost, &installable, []string{"csuite"}, &autoGenConfig)
97
98	java.InitJavaModuleMultiTargets(module, android.HostSupported)
99
100	return module
101}
102
103const (
104	emptyPlanIncludePath        = `empty`
105	planConfigDirName           = `config`
106	configTemplateFileExtension = `.xml.template`
107	planFileExtension           = `.xml`
108	planTemplate                = `<?xml version="1.0" encoding="utf-8"?>
109<!-- Copyright (C) 2020 The Android Open Source Project
110
111     Licensed under the Apache License, Version 2.0 (the "License");
112     you may not use this file except in compliance with the License.
113     You may obtain a copy of the License at
114
115          http://www.apache.org/licenses/LICENSE-2.0
116
117     Unless required by applicable law or agreed to in writing, software
118     distributed under the License is distributed on an "AS IS" BASIS,
119     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120     See the License for the specific language governing permissions and
121     limitations under the License.
122-->
123<configuration>
124     <test class="com.android.csuite.config.ModuleGenerator">
125          <option name="template" value="{templatePath}" />
126     </test>
127     <include name="csuite-base" />
128     <include name="{planInclude}" />
129     <option name="plan" value="{planName}" />
130</configuration>
131`
132)
133