blob: 96ed92fc51e6a0c40129ce791f13f1efebbf246b [file] [log] [blame]
Ronald Braunstein73b08ff2023-12-19 10:24:47 -08001// Copyright 2024 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.
14package android
15
16import (
17 "android/soong/android/team_proto"
18 "log"
19 "testing"
20
21 "google.golang.org/protobuf/proto"
22)
23
24func TestAllTeams(t *testing.T) {
25 t.Parallel()
26 ctx := GroupFixturePreparers(
Ronald Braunsteinc5603092024-03-27 06:46:47 -070027 prepareForTestWithTeamAndFakes,
Ronald Braunsteinc864b242024-04-16 07:33:52 -070028 // This adds two variants, one armv7-a-neon, one armv8-a
29 PrepareForTestWithArchMutator,
Ronald Braunstein73b08ff2023-12-19 10:24:47 -080030 FixtureRegisterWithContext(func(ctx RegistrationContext) {
Ronald Braunstein73b08ff2023-12-19 10:24:47 -080031 ctx.RegisterParallelSingletonType("all_teams", AllTeamsFactory)
32 }),
33 ).RunTestWithBp(t, `
34 fake {
35 name: "main_test",
36 team: "someteam",
37 }
38 team {
39 name: "someteam",
40 trendy_team_id: "cool_team",
41 }
42
43 team {
44 name: "team2",
45 trendy_team_id: "22222",
46 }
47
48 fake {
49 name: "tool",
50 team: "team2",
51 }
52
53 fake {
54 name: "noteam",
Ronald Braunsteinc5603092024-03-27 06:46:47 -070055 test_only: true,
56 }
Ronald Braunsteinc864b242024-04-16 07:33:52 -070057 // write the test-only provider value once
Ronald Braunsteinc5603092024-03-27 06:46:47 -070058 fake {
Ronald Braunsteinc864b242024-04-16 07:33:52 -070059 name: "test-and-team-and-top1",
Ronald Braunsteinc5603092024-03-27 06:46:47 -070060 test_only: true,
61 team: "team2",
Ronald Braunsteinc864b242024-04-16 07:33:52 -070062 arch: {arm: { skip: false},
63 arm64: { skip: true}},
64 }
65 // write the test-only provider once, but on the other arch
66 fake {
67 name: "test-and-team-and-top2",
68 test_only: true,
69 team: "team2",
70 arch: {arm: { skip: true},
71 arm64: { skip: false}},
72 }
73 // write the test-only provider value twice
74 fake {
75 name: "test-and-team-and-top3",
76 test_only: true,
77 team: "team2",
78 }
79 // Don't write the test-only provider value
80 fake {
81 name: "test-and-team-and-top4",
82 test_only: true,
83 team: "team2",
84 arch: {arm: { skip: true},
85 arm64: { skip: true}},
Ronald Braunstein73b08ff2023-12-19 10:24:47 -080086 }
87 `)
88
89 var teams *team_proto.AllTeams
90 teams = getTeamProtoOutput(t, ctx)
91
92 // map of module name -> trendy team name.
Ronald Braunsteinc864b242024-04-16 07:33:52 -070093 actualTeams := make(map[string]string)
Ronald Braunsteinc5603092024-03-27 06:46:47 -070094 actualTests := []string{}
95 actualTopLevelTests := []string{}
96
Ronald Braunstein73b08ff2023-12-19 10:24:47 -080097 for _, teamProto := range teams.Teams {
Ronald Braunsteinc864b242024-04-16 07:33:52 -070098 if teamProto.TrendyTeamId != nil {
99 actualTeams[teamProto.GetTargetName()] = *teamProto.TrendyTeamId
100 } else {
101 actualTeams[teamProto.GetTargetName()] = ""
102 }
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700103 if teamProto.GetTestOnly() {
104 actualTests = append(actualTests, teamProto.GetTargetName())
105 }
106 if teamProto.GetTopLevelTarget() {
107 actualTopLevelTests = append(actualTopLevelTests, teamProto.GetTargetName())
108 }
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800109 }
Ronald Braunsteinc864b242024-04-16 07:33:52 -0700110 expectedTeams := map[string]string{
111 "main_test": "cool_team",
112 "tool": "22222",
113 "test-and-team-and-top1": "22222",
114 "test-and-team-and-top2": "22222",
115 "test-and-team-and-top3": "22222",
116 "test-and-team-and-top4": "22222",
117 "noteam": "",
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800118 }
119
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700120 expectedTests := []string{
121 "noteam",
Ronald Braunsteinc864b242024-04-16 07:33:52 -0700122 "test-and-team-and-top1",
123 "test-and-team-and-top2",
124 "test-and-team-and-top3",
125 // There should be no test-and-team-top4 as we skip writing all variants
126 // test-only for all variants
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700127 }
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800128 AssertDeepEquals(t, "compare maps", expectedTeams, actualTeams)
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700129 AssertDeepEquals(t, "test matchup", expectedTests, actualTests)
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800130}
131
132func getTeamProtoOutput(t *testing.T, ctx *TestResult) *team_proto.AllTeams {
133 teams := new(team_proto.AllTeams)
134 config := ctx.SingletonForTests("all_teams")
135 allOutputs := config.AllOutputs()
136
137 protoPath := allOutputs[0]
138
139 out := config.MaybeOutput(protoPath)
140 outProto := []byte(ContentFromFileRuleForTests(t, ctx.TestContext, out))
141 if err := proto.Unmarshal(outProto, teams); err != nil {
142 log.Fatalln("Failed to parse teams proto:", err)
143 }
144 return teams
145}
146
147// Android.bp
148//
149// team: team_top
150//
151// # dir1 has no modules with teams,
152// # but has a dir with no Android.bp
153// dir1/Android.bp
154//
155// module_dir1
156//
157// # dirs without and Android.bp should be fine.
158// dir1/dir2/dir3/Android.bp
159//
160// package {}
161// module_dir123
162//
163// teams_dir/Android.bp
164//
165// module_with_team1: team1
166// team1: 111
167//
168// # team comes from upper package default
169// teams_dir/deeper/Android.bp
170//
171// module2_with_team1: team1
172//
173// package_defaults/Android.bp
174// package_defaults/pd2/Android.bp
175//
176// package{ default_team: team_top}
177// module_pd2 ## should get team_top
178//
179// package_defaults/pd2/pd3/Android.bp
180//
181// module_pd3 ## should get team_top
182func TestPackageLookup(t *testing.T) {
183 t.Parallel()
184 rootBp := `
185 team {
186 name: "team_top",
187 trendy_team_id: "trendy://team_top",
188 } `
189
190 dir1Bp := `
191 fake {
192 name: "module_dir1",
193 } `
194 dir3Bp := `
195 package {}
196 fake {
197 name: "module_dir123",
198 } `
199 teamsDirBp := `
200 fake {
201 name: "module_with_team1",
202 team: "team1"
203
204 }
205 team {
206 name: "team1",
207 trendy_team_id: "111",
208 } `
209 teamsDirDeeper := `
210 fake {
211 name: "module2_with_team1",
212 team: "team1"
213 } `
214 // create an empty one.
215 packageDefaultsBp := ""
216 packageDefaultspd2 := `
217 package { default_team: "team_top"}
218 fake {
219 name: "modulepd2",
220 } `
221
222 packageDefaultspd3 := `
223 fake {
224 name: "modulepd3",
225 }
226 fake {
227 name: "modulepd3b",
228 team: "team1"
229 } `
230
231 ctx := GroupFixturePreparers(
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700232 prepareForTestWithTeamAndFakes,
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800233 PrepareForTestWithPackageModule,
234 FixtureRegisterWithContext(func(ctx RegistrationContext) {
Ronald Braunstein73b08ff2023-12-19 10:24:47 -0800235 ctx.RegisterParallelSingletonType("all_teams", AllTeamsFactory)
236 }),
237 FixtureAddTextFile("Android.bp", rootBp),
238 FixtureAddTextFile("dir1/Android.bp", dir1Bp),
239 FixtureAddTextFile("dir1/dir2/dir3/Android.bp", dir3Bp),
240 FixtureAddTextFile("teams_dir/Android.bp", teamsDirBp),
241 FixtureAddTextFile("teams_dir/deeper/Android.bp", teamsDirDeeper),
242 FixtureAddTextFile("package_defaults/Android.bp", packageDefaultsBp),
243 FixtureAddTextFile("package_defaults/pd2/Android.bp", packageDefaultspd2),
244 FixtureAddTextFile("package_defaults/pd2/pd3/Android.bp", packageDefaultspd3),
245 ).RunTest(t)
246
247 var teams *team_proto.AllTeams
248 teams = getTeamProtoOutput(t, ctx)
249
250 // map of module name -> trendy team name.
251 actualTeams := make(map[string]*string)
252 for _, teamProto := range teams.Teams {
253 actualTeams[teamProto.GetTargetName()] = teamProto.TrendyTeamId
254 }
255 expectedTeams := map[string]*string{
256 "module_with_team1": proto.String("111"),
257 "module2_with_team1": proto.String("111"),
258 "modulepd2": proto.String("trendy://team_top"),
259 "modulepd3": proto.String("trendy://team_top"),
260 "modulepd3b": proto.String("111"),
261 "module_dir1": nil,
262 "module_dir123": nil,
263 }
264 AssertDeepEquals(t, "compare maps", expectedTeams, actualTeams)
265}
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700266
267type fakeForTests struct {
268 ModuleBase
269
270 sourceProperties SourceProperties
Ronald Braunsteinc864b242024-04-16 07:33:52 -0700271 props struct {
272 // If true, don't write test-only value in provider
273 Skip bool `android:"arch_variant"`
274 }
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700275}
276
277func fakeFactory() Module {
278 module := &fakeForTests{}
Ronald Braunsteinc864b242024-04-16 07:33:52 -0700279 module.AddProperties(&module.sourceProperties, &module.props)
280 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibBoth)
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700281
282 return module
283}
284
285var prepareForTestWithTeamAndFakes = GroupFixturePreparers(
286 FixtureRegisterWithContext(RegisterTeamBuildComponents),
287 FixtureRegisterWithContext(func(ctx RegistrationContext) {
288 ctx.RegisterModuleType("fake", fakeFactory)
289 }),
290)
291
292func (f *fakeForTests) GenerateAndroidBuildActions(ctx ModuleContext) {
293 if Bool(f.sourceProperties.Test_only) {
294 SetProvider(ctx, TestOnlyProviderKey, TestModuleInformation{
Ronald Braunsteinc864b242024-04-16 07:33:52 -0700295 TestOnly: Bool(f.sourceProperties.Test_only) && !f.props.Skip,
Ronald Braunsteinc5603092024-03-27 06:46:47 -0700296 TopLevelTarget: false,
297 })
298 }
299}