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 return 108 } 109 110 configTemplatePath := cSuiteTest.buildCopyConfigTemplateCommand(ctx, rule, *cSuiteTest.csuiteTestProperties.Test_config_template) 111 extraConfigTemplatePaths := cSuiteTest.buildCopyExtraConfigTemplatesCommand(ctx, rule) 112 planIncludePath := cSuiteTest.buildCopyPlanIncludeCommand(ctx, rule) 113 cSuiteTest.buildWritePlanConfigRule(ctx, configTemplatePath, extraConfigTemplatePaths, planIncludePath) 114 115 rule.Build("CSuite", "generate C-Suite config files") 116 cSuiteTest.TestHost.GenerateAndroidBuildActions(ctx) 117} 118 119func CSuiteTestFactory() android.Module { 120 module := &CSuiteTest{} 121 module.AddProperties(&module.csuiteTestProperties) 122 installable := true 123 autoGenConfig := false 124 java.InitTestHost(&module.TestHost, &installable, []string{"csuite"}, &autoGenConfig) 125 126 java.InitJavaModuleMultiTargets(module, android.HostSupported) 127 128 return module 129} 130 131const ( 132 emptyPlanIncludePath = `empty` 133 configDirName = `config` 134 configTemplateFileExtension = `.template` 135 xmlFileExtension = `.xml` 136 extraTemplatePathsTemplate = ` 137 <option name="extra-templates" value="{templatePath}"/>` 138 planTemplate = `<?xml version="1.0" encoding="utf-8"?> 139<!-- Copyright (C) 2020 The Android Open Source Project 140 141 Licensed under the Apache License, Version 2.0 (the "License"); 142 you may not use this file except in compliance with the License. 143 You may obtain a copy of the License at 144 145 http://www.apache.org/licenses/LICENSE-2.0 146 147 Unless required by applicable law or agreed to in writing, software 148 distributed under the License is distributed on an "AS IS" BASIS, 149 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 150 See the License for the specific language governing permissions and 151 limitations under the License. 152--> 153<configuration> 154 <!-- Generates module files in the beginning of the test. --> 155 <test class="com.android.csuite.core.ModuleGenerator" /> 156 <!-- Cleans the generated module files after the test. --> 157 <target_preparer class="com.android.csuite.core.ModuleGenerator" /> 158 <object type="MODULE_TEMPLATE_PROVIDER" class="com.android.csuite.core.ModuleTemplate" > 159 <option name="template-root" value="{templateRoot}" /> 160 <option name="default-template" value="{templatePath}" />{extraTemplatePaths} 161 </object> 162 163 <include name="csuite-base" /> 164 <include name="{planInclude}" /> 165 <option name="plan" value="{planName}" /> 166</configuration> 167` 168) 169