// Copyright 2020 Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package csuite import ( "android/soong/android" "android/soong/java" "strings" ) var ( pctx = android.NewPackageContext("android/soong/csuite") ) func init() { android.RegisterModuleType("csuite_test", CSuiteTestFactory) } type csuiteTestProperties struct { // Local path to a default module template xml file. // The content of the template will be used to generate test modules at runtime. Test_config_template *string `android:"path"` // Local paths to extra module template xml files. Extra_test_config_templates []string `android:"path"` // Local path to a test plan config xml to be included in the generated plan. Test_plan_include *string `android:"path"` } type CSuiteTest struct { // Java TestHost. java.TestHost // C-Suite test properties struct. csuiteTestProperties csuiteTestProperties } func (cSuiteTest *CSuiteTest) buildCopyConfigTemplateCommand(ctx android.ModuleContext, rule *android.RuleBuilder, templatePath string) string { if !strings.HasSuffix(templatePath, xmlFileExtension) { ctx.ModuleErrorf(`Config template path should ends with ` + xmlFileExtension) } inputPath := android.PathForModuleSrc(ctx, templatePath) genPath := android.PathForModuleGen(ctx, configDirName, ctx.ModuleName(), inputPath.Rel()+configTemplateFileExtension) rule.Command().Textf("cp").Input(inputPath).Output(genPath) cSuiteTest.AddExtraResource(genPath) return genPath.Rel() } func (cSuiteTest *CSuiteTest) buildCopyExtraConfigTemplatesCommand(ctx android.ModuleContext, rule *android.RuleBuilder) []string { output := make([]string, len(cSuiteTest.csuiteTestProperties.Extra_test_config_templates)) for idx, templatePath := range cSuiteTest.csuiteTestProperties.Extra_test_config_templates { output[idx] = cSuiteTest.buildCopyConfigTemplateCommand(ctx, rule, templatePath) } return output } func (cSuiteTest *CSuiteTest) buildCopyPlanIncludeCommand(ctx android.ModuleContext, rule *android.RuleBuilder) string { if cSuiteTest.csuiteTestProperties.Test_plan_include == nil { return emptyPlanIncludePath } inputPath := android.PathForModuleSrc(ctx, *cSuiteTest.csuiteTestProperties.Test_plan_include) genPath := android.PathForModuleGen(ctx, configDirName, "includes", ctx.ModuleName()+".xml") rule.Command().Textf("cp").Input(inputPath).Output(genPath) cSuiteTest.AddExtraResource(genPath) return strings.Replace(genPath.Rel(), "config/", "", -1) } func (cSuiteTest *CSuiteTest) buildWritePlanConfigRule(ctx android.ModuleContext, configTemplatePath string, extraConfigTemplatePaths []string, planIncludePath string) { planName := ctx.ModuleName() content := strings.Replace(planTemplate, "{planName}", planName, -1) content = strings.Replace(content, "{templatePath}", configTemplatePath, -1) content = strings.Replace(content, "{templateRoot}", android.PathForModuleGen(ctx, configDirName, ctx.ModuleName()).Rel(), -1) content = strings.Replace(content, "{planInclude}", planIncludePath, -1) extraTemplateConfigLines := "" for _, extraPath := range extraConfigTemplatePaths { extraTemplateConfigLines += strings.Replace(extraTemplatePathsTemplate, "{templatePath}", extraPath, -1) } content = strings.Replace(content, "{extraTemplatePaths}", extraTemplateConfigLines, -1) genPath := android.PathForModuleGen(ctx, configDirName, planName+xmlFileExtension) android.WriteFileRule(ctx, genPath, content) cSuiteTest.AddExtraResource(genPath) } func (cSuiteTest *CSuiteTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule := android.NewRuleBuilder(pctx, ctx) if cSuiteTest.csuiteTestProperties.Test_config_template == nil { ctx.ModuleErrorf(`'test_config_template' is missing.`) return } configTemplatePath := cSuiteTest.buildCopyConfigTemplateCommand(ctx, rule, *cSuiteTest.csuiteTestProperties.Test_config_template) extraConfigTemplatePaths := cSuiteTest.buildCopyExtraConfigTemplatesCommand(ctx, rule) planIncludePath := cSuiteTest.buildCopyPlanIncludeCommand(ctx, rule) cSuiteTest.buildWritePlanConfigRule(ctx, configTemplatePath, extraConfigTemplatePaths, planIncludePath) rule.Build("CSuite", "generate C-Suite config files") cSuiteTest.TestHost.GenerateAndroidBuildActions(ctx) } func CSuiteTestFactory() android.Module { module := &CSuiteTest{} module.AddProperties(&module.csuiteTestProperties) installable := true autoGenConfig := false java.InitTestHost(&module.TestHost, &installable, []string{"csuite"}, &autoGenConfig) java.InitJavaModuleMultiTargets(module, android.HostSupported) return module } const ( emptyPlanIncludePath = `empty` configDirName = `config` configTemplateFileExtension = `.template` xmlFileExtension = `.xml` extraTemplatePathsTemplate = `