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 android 16 17import ( 18 "path/filepath" 19 "strings" 20 21 "github.com/google/blueprint" 22) 23 24func init() { 25 RegisterParallelSingletonType("testsuites", testSuiteFilesFactory) 26} 27 28func testSuiteFilesFactory() Singleton { 29 return &testSuiteFiles{} 30} 31 32type testSuiteFiles struct{} 33 34type TestSuiteModule interface { 35 Module 36 TestSuites() []string 37} 38 39type TestSuiteInfo struct { 40 TestSuites []string 41} 42 43var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() 44 45type SupportFilesInfo struct { 46 SupportFiles InstallPaths 47} 48 49var SupportFilesInfoProvider = blueprint.NewProvider[SupportFilesInfo]() 50 51func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { 52 files := make(map[string]map[string]InstallPaths) 53 54 ctx.VisitAllModuleProxies(func(m ModuleProxy) { 55 if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { 56 for _, testSuite := range tsm.TestSuites { 57 if files[testSuite] == nil { 58 files[testSuite] = make(map[string]InstallPaths) 59 } 60 name := ctx.ModuleName(m) 61 files[testSuite][name] = append(files[testSuite][name], 62 OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) 63 } 64 } 65 }) 66 67 robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"]) 68 ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip) 69 ctx.DistForGoal("robolectric-tests", robolectricZip, robolectrictListZip) 70 71 ravenwoodZip, ravenwoodListZip := buildTestSuite(ctx, "ravenwood-tests", files["ravenwood-tests"]) 72 ctx.Phony("ravenwood-tests", ravenwoodZip, ravenwoodListZip) 73 ctx.DistForGoal("ravenwood-tests", ravenwoodZip, ravenwoodListZip) 74} 75 76func buildTestSuite(ctx SingletonContext, suiteName string, files map[string]InstallPaths) (Path, Path) { 77 var installedPaths InstallPaths 78 for _, module := range SortedKeys(files) { 79 installedPaths = append(installedPaths, files[module]...) 80 } 81 82 outputFile := pathForPackaging(ctx, suiteName+".zip") 83 rule := NewRuleBuilder(pctx, ctx) 84 rule.Command().BuiltTool("soong_zip"). 85 FlagWithOutput("-o ", outputFile). 86 FlagWithArg("-P ", "host/testcases"). 87 FlagWithArg("-C ", pathForTestCases(ctx).String()). 88 FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()). 89 Flag("-sha256") // necessary to save cas_uploader's time 90 91 testList := buildTestList(ctx, suiteName+"_list", installedPaths) 92 testListZipOutputFile := pathForPackaging(ctx, suiteName+"_list.zip") 93 94 rule.Command().BuiltTool("soong_zip"). 95 FlagWithOutput("-o ", testListZipOutputFile). 96 FlagWithArg("-C ", pathForPackaging(ctx).String()). 97 FlagWithInput("-f ", testList). 98 Flag("-sha256") 99 100 rule.Build(strings.ReplaceAll(suiteName, "-", "_")+"_zip", suiteName+".zip") 101 102 return outputFile, testListZipOutputFile 103} 104 105func buildTestList(ctx SingletonContext, listFile string, installedPaths InstallPaths) Path { 106 buf := &strings.Builder{} 107 for _, p := range installedPaths { 108 if p.Ext() != ".config" { 109 continue 110 } 111 pc, err := toTestListPath(p.String(), pathForTestCases(ctx).String(), "host/testcases") 112 if err != nil { 113 ctx.Errorf("Failed to convert path: %s, %v", p.String(), err) 114 continue 115 } 116 buf.WriteString(pc) 117 buf.WriteString("\n") 118 } 119 outputFile := pathForPackaging(ctx, listFile) 120 WriteFileRuleVerbatim(ctx, outputFile, buf.String()) 121 return outputFile 122} 123 124func toTestListPath(path, relativeRoot, prefix string) (string, error) { 125 dest, err := filepath.Rel(relativeRoot, path) 126 if err != nil { 127 return "", err 128 } 129 return filepath.Join(prefix, dest), nil 130} 131 132func pathForPackaging(ctx PathContext, pathComponents ...string) OutputPath { 133 pathComponents = append([]string{"packaging"}, pathComponents...) 134 return PathForOutput(ctx, pathComponents...) 135} 136 137func pathForTestCases(ctx PathContext) InstallPath { 138 return pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases") 139} 140