xref: /aosp_15_r20/build/soong/android/test_suites.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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
22func init() {
23	RegisterParallelSingletonType("testsuites", testSuiteFilesFactory)
24}
25
26func testSuiteFilesFactory() Singleton {
27	return &testSuiteFiles{}
28}
29
30type testSuiteFiles struct {
31	robolectric []Path
32	ravenwood   []Path
33}
34
35type TestSuiteModule interface {
36	Module
37	TestSuites() []string
38}
39
40func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) {
41	files := make(map[string]map[string]InstallPaths)
42
43	ctx.VisitAllModules(func(m Module) {
44		if tsm, ok := m.(TestSuiteModule); ok {
45			for _, testSuite := range tsm.TestSuites() {
46				if files[testSuite] == nil {
47					files[testSuite] = make(map[string]InstallPaths)
48				}
49				name := ctx.ModuleName(m)
50				files[testSuite][name] = append(files[testSuite][name],
51					OtherModuleProviderOrDefault(ctx, tsm, InstallFilesProvider).InstallFiles...)
52			}
53		}
54	})
55
56	t.robolectric = robolectricTestSuite(ctx, files["robolectric-tests"])
57	ctx.Phony("robolectric-tests", t.robolectric...)
58
59	t.ravenwood = ravenwoodTestSuite(ctx, files["ravenwood-tests"])
60	ctx.Phony("ravenwood-tests", t.ravenwood...)
61}
62
63func (t *testSuiteFiles) MakeVars(ctx MakeVarsContext) {
64	ctx.DistForGoal("robolectric-tests", t.robolectric...)
65	ctx.DistForGoal("ravenwood-tests", t.ravenwood...)
66}
67
68func robolectricTestSuite(ctx SingletonContext, files map[string]InstallPaths) []Path {
69	var installedPaths InstallPaths
70	for _, module := range SortedKeys(files) {
71		installedPaths = append(installedPaths, files[module]...)
72	}
73
74	outputFile := pathForPackaging(ctx, "robolectric-tests.zip")
75	rule := NewRuleBuilder(pctx, ctx)
76	rule.Command().BuiltTool("soong_zip").
77		FlagWithOutput("-o ", outputFile).
78		FlagWithArg("-P ", "host/testcases").
79		FlagWithArg("-C ", pathForTestCases(ctx).String()).
80		FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()).
81		Flag("-sha256") // necessary to save cas_uploader's time
82
83	testList := buildTestList(ctx, "robolectric-tests_list", installedPaths)
84	testListZipOutputFile := pathForPackaging(ctx, "robolectric-tests_list.zip")
85
86	rule.Command().BuiltTool("soong_zip").
87		FlagWithOutput("-o ", testListZipOutputFile).
88		FlagWithArg("-C ", pathForPackaging(ctx).String()).
89		FlagWithInput("-f ", testList).
90		Flag("-sha256")
91
92	rule.Build("robolectric_tests_zip", "robolectric-tests.zip")
93
94	return []Path{outputFile, testListZipOutputFile}
95}
96
97func ravenwoodTestSuite(ctx SingletonContext, files map[string]InstallPaths) []Path {
98	var installedPaths InstallPaths
99	for _, module := range SortedKeys(files) {
100		installedPaths = append(installedPaths, files[module]...)
101	}
102
103	outputFile := pathForPackaging(ctx, "ravenwood-tests.zip")
104	rule := NewRuleBuilder(pctx, ctx)
105	rule.Command().BuiltTool("soong_zip").
106		FlagWithOutput("-o ", outputFile).
107		FlagWithArg("-P ", "host/testcases").
108		FlagWithArg("-C ", pathForTestCases(ctx).String()).
109		FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()).
110		Flag("-sha256") // necessary to save cas_uploader's time
111
112	testList := buildTestList(ctx, "ravenwood-tests_list", installedPaths)
113	testListZipOutputFile := pathForPackaging(ctx, "ravenwood-tests_list.zip")
114
115	rule.Command().BuiltTool("soong_zip").
116		FlagWithOutput("-o ", testListZipOutputFile).
117		FlagWithArg("-C ", pathForPackaging(ctx).String()).
118		FlagWithInput("-f ", testList).
119		Flag("-sha256")
120
121	rule.Build("ravenwood_tests_zip", "ravenwood-tests.zip")
122
123	return []Path{outputFile, testListZipOutputFile}
124}
125
126func buildTestList(ctx SingletonContext, listFile string, installedPaths InstallPaths) Path {
127	buf := &strings.Builder{}
128	for _, p := range installedPaths {
129		if p.Ext() != ".config" {
130			continue
131		}
132		pc, err := toTestListPath(p.String(), pathForTestCases(ctx).String(), "host/testcases")
133		if err != nil {
134			ctx.Errorf("Failed to convert path: %s, %v", p.String(), err)
135			continue
136		}
137		buf.WriteString(pc)
138		buf.WriteString("\n")
139	}
140	outputFile := pathForPackaging(ctx, listFile)
141	WriteFileRuleVerbatim(ctx, outputFile, buf.String())
142	return outputFile
143}
144
145func toTestListPath(path, relativeRoot, prefix string) (string, error) {
146	dest, err := filepath.Rel(relativeRoot, path)
147	if err != nil {
148		return "", err
149	}
150	return filepath.Join(prefix, dest), nil
151}
152
153func pathForPackaging(ctx PathContext, pathComponents ...string) OutputPath {
154	pathComponents = append([]string{"packaging"}, pathComponents...)
155	return PathForOutput(ctx, pathComponents...)
156}
157
158func pathForTestCases(ctx PathContext) InstallPath {
159	return pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases")
160}
161