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 default 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 paths to extra module template xml files. 37 Extra_test_config_templates []string `android:"path"` 38 39 // Local path to a test plan config xml to be included in the generated plan. 40 Test_plan_include *string `android:"path"` 41} 42 43type CSuiteTest struct { 44 // Java TestHost. 45 java.TestHost 46 47 // C-Suite test properties struct. 48 csuiteTestProperties csuiteTestProperties 49} 50 51func (cSuiteTest *CSuiteTest) buildCopyConfigTemplateCommand(ctx android.ModuleContext, rule *android.RuleBuilder, templatePath string) string { 52 if !strings.HasSuffix(templatePath, xmlFileExtension) { 53 ctx.ModuleErrorf(`Config template path should ends with ` + xmlFileExtension) 54 } 55 56 inputPath := android.PathForModuleSrc(ctx, templatePath) 57 genPath := android.PathForModuleGen(ctx, configDirName, ctx.ModuleName(), inputPath.Rel()+configTemplateFileExtension) 58 rule.Command().Textf("cp").Input(inputPath).Output(genPath) 59 cSuiteTest.AddExtraResource(genPath) 60 return genPath.Rel() 61} 62 63func (cSuiteTest *CSuiteTest) buildCopyExtraConfigTemplatesCommand(ctx android.ModuleContext, rule *android.RuleBuilder) []string { 64 output := make([]string, len(cSuiteTest.csuiteTestProperties.Extra_test_config_templates)) 65 66 for idx, templatePath := range cSuiteTest.csuiteTestProperties.Extra_test_config_templates { 67 output[idx] = cSuiteTest.buildCopyConfigTemplateCommand(ctx, rule, templatePath) 68 } 69 70 return output 71} 72 73func (cSuiteTest *CSuiteTest) buildCopyPlanIncludeCommand(ctx android.ModuleContext, rule *android.RuleBuilder) string { 74 if cSuiteTest.csuiteTestProperties.Test_plan_include == nil { 75 return emptyPlanIncludePath 76 } 77 inputPath := android.PathForModuleSrc(ctx, *cSuiteTest.csuiteTestProperties.Test_plan_include) 78 genPath := android.PathForModuleGen(ctx, configDirName, "includes", ctx.ModuleName()+".xml") 79 rule.Command().Textf("cp").Input(inputPath).Output(genPath) 80 cSuiteTest.AddExtraResource(genPath) 81 return strings.Replace(genPath.Rel(), "config/", "", -1) 82} 83 84func (cSuiteTest *CSuiteTest) buildWritePlanConfigRule(ctx android.ModuleContext, configTemplatePath string, extraConfigTemplatePaths []string, planIncludePath string) { 85 planName := ctx.ModuleName() 86 content := strings.Replace(planTemplate, "{planName}", planName, -1) 87 content = strings.Replace(content, "{templatePath}", configTemplatePath, -1) 88 content = strings.Replace(content, "{templateRoot}", android.PathForModuleGen(ctx, configDirName, ctx.ModuleName()).Rel(), -1) 89 content = strings.Replace(content, "{planInclude}", planIncludePath, -1) 90 91 extraTemplateConfigLines := "" 92 for _, extraPath := range extraConfigTemplatePaths { 93 extraTemplateConfigLines += strings.Replace(extraTemplatePathsTemplate, "{templatePath}", extraPath, -1) 94 } 95 content = strings.Replace(content, "{extraTemplatePaths}", extraTemplateConfigLines, -1) 96 97 genPath := android.PathForModuleGen(ctx, configDirName, planName+xmlFileExtension) 98 android.WriteFileRule(ctx, genPath, content) 99 cSuiteTest.AddExtraResource(genPath) 100} 101 102func (cSuiteTest *CSuiteTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 103 rule := android.NewRuleBuilder(pctx, ctx) 104 105 if cSuiteTest.csuiteTestProperties.Test_config_template == nil { 106 ctx.ModuleErrorf(`'test_config_template' is missing.`) 107 } 108 109 configTemplatePath := cSuiteTest.buildCopyConfigTemplateCommand(ctx, rule, *cSuiteTest.csuiteTestProperties.Test_config_template) 110 extraConfigTemplatePaths := cSuiteTest.buildCopyExtraConfigTemplatesCommand(ctx, rule) 111 planIncludePath := cSuiteTest.buildCopyPlanIncludeCommand(ctx, rule) 112 cSuiteTest.buildWritePlanConfigRule(ctx, configTemplatePath, extraConfigTemplatePaths, planIncludePath) 113 114 rule.Build("CSuite", "generate C-Suite config files") 115 cSuiteTest.TestHost.GenerateAndroidBuildActions(ctx) 116} 117 118func CSuiteTestFactory() android.Module { 119 module := &CSuiteTest{} 120 module.AddProperties(&module.csuiteTestProperties) 121 installable := true 122 autoGenConfig := false 123 java.InitTestHost(&module.TestHost, &installable, []string{"csuite"}, &autoGenConfig) 124 125 java.InitJavaModuleMultiTargets(module, android.HostSupported) 126 127 return module 128} 129 130const ( 131 emptyPlanIncludePath = `empty` 132 configDirName = `config` 133 configTemplateFileExtension = `.template` 134 xmlFileExtension = `.xml` 135 extraTemplatePathsTemplate = ` 136 <option name="extra-templates" value="{templatePath}"/>` 137 planTemplate = `<?xml version="1.0" encoding="utf-8"?> 138<!-- Copyright (C) 2020 The Android Open Source Project 139 140 Licensed under the Apache License, Version 2.0 (the "License"); 141 you may not use this file except in compliance with the License. 142 You may obtain a copy of the License at 143 144 http://www.apache.org/licenses/LICENSE-2.0 145 146 Unless required by applicable law or agreed to in writing, software 147 distributed under the License is distributed on an "AS IS" BASIS, 148 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149 See the License for the specific language governing permissions and 150 limitations under the License. 151--> 152<configuration> 153 <!-- Generates module files in the beginning of the test. --> 154 <test class="com.android.csuite.core.ModuleGenerator" /> 155 <!-- Cleans the generated module files after the test. --> 156 <target_preparer class="com.android.csuite.core.ModuleGenerator" /> 157 <object type="MODULE_TEMPLATE_PROVIDER" class="com.android.csuite.core.ModuleTemplate" > 158 <option name="template-root" value="{templateRoot}" /> 159 <option name="default-template" value="{templatePath}" />{extraTemplatePaths} 160 </object> 161 162 <include name="csuite-base" /> 163 <include name="{planInclude}" /> 164 <option name="plan" value="{planName}" /> 165</configuration> 166` 167) 168