blob: 942dd3190ad7c3aed20ba522ca0482bb05a76df2 [file] [log] [blame]
Colin Cross2da84922020-07-02 10:08:12 -07001// 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 blueprint
16
17import (
18 "fmt"
19 "reflect"
20 "strings"
21 "testing"
22)
23
24type providerTestModule struct {
25 SimpleName
26 properties struct {
27 Deps []string
28 }
29
30 mutatorProviderValues []string
31 generateBuildActionsProviderValues []string
32}
33
34func newProviderTestModule() (Module, []interface{}) {
35 m := &providerTestModule{}
36 return m, []interface{}{&m.properties, &m.SimpleName.Properties}
37}
38
39type providerTestMutatorInfo struct {
40 Values []string
41}
42
43type providerTestGenerateBuildActionsInfo struct {
44 Value string
45}
46
47type providerTestUnsetInfo string
48
49var providerTestMutatorInfoProvider = NewMutatorProvider(&providerTestMutatorInfo{}, "provider_mutator")
50var providerTestGenerateBuildActionsInfoProvider = NewProvider(&providerTestGenerateBuildActionsInfo{})
51var providerTestUnsetInfoProvider = NewMutatorProvider((providerTestUnsetInfo)(""), "provider_mutator")
52var providerTestUnusedMutatorProvider = NewMutatorProvider(&struct{ unused string }{}, "nonexistent_mutator")
53
54func (p *providerTestModule) GenerateBuildActions(ctx ModuleContext) {
55 unset := ctx.Provider(providerTestUnsetInfoProvider).(providerTestUnsetInfo)
56 if unset != "" {
57 panic(fmt.Sprintf("expected zero value for providerTestGenerateBuildActionsInfoProvider before it was set, got %q",
58 unset))
59 }
60
61 _ = ctx.Provider(providerTestUnusedMutatorProvider)
62
63 ctx.SetProvider(providerTestGenerateBuildActionsInfoProvider, &providerTestGenerateBuildActionsInfo{
64 Value: ctx.ModuleName(),
65 })
66
67 mp := ctx.Provider(providerTestMutatorInfoProvider).(*providerTestMutatorInfo)
68 if mp != nil {
69 p.mutatorProviderValues = mp.Values
70 }
71
72 ctx.VisitDirectDeps(func(module Module) {
73 gbap := ctx.OtherModuleProvider(module, providerTestGenerateBuildActionsInfoProvider).(*providerTestGenerateBuildActionsInfo)
74 if gbap != nil {
75 p.generateBuildActionsProviderValues = append(p.generateBuildActionsProviderValues, gbap.Value)
76 }
77 })
78}
79
80func providerTestDepsMutator(ctx BottomUpMutatorContext) {
81 if p, ok := ctx.Module().(*providerTestModule); ok {
82 ctx.AddDependency(ctx.Module(), nil, p.properties.Deps...)
83 }
84}
85
86func providerTestMutator(ctx BottomUpMutatorContext) {
87 values := []string{strings.ToLower(ctx.ModuleName())}
88
89 ctx.VisitDirectDeps(func(module Module) {
90 mp := ctx.OtherModuleProvider(module, providerTestMutatorInfoProvider).(*providerTestMutatorInfo)
91 if mp != nil {
92 values = append(values, mp.Values...)
93 }
94 })
95
96 ctx.SetProvider(providerTestMutatorInfoProvider, &providerTestMutatorInfo{
97 Values: values,
98 })
99}
100
101func providerTestAfterMutator(ctx BottomUpMutatorContext) {
102 _ = ctx.Provider(providerTestMutatorInfoProvider)
103}
104
105func TestProviders(t *testing.T) {
106 ctx := NewContext()
107 ctx.RegisterModuleType("provider_module", newProviderTestModule)
108 ctx.RegisterBottomUpMutator("provider_deps_mutator", providerTestDepsMutator)
109 ctx.RegisterBottomUpMutator("provider_mutator", providerTestMutator)
110 ctx.RegisterBottomUpMutator("provider_after_mutator", providerTestAfterMutator)
111
112 ctx.MockFileSystem(map[string][]byte{
Lukacs T. Berkieef56852021-09-02 11:34:06 +0200113 "Android.bp": []byte(`
Colin Cross2da84922020-07-02 10:08:12 -0700114 provider_module {
115 name: "A",
116 deps: ["B"],
117 }
118
119 provider_module {
120 name: "B",
121 deps: ["C", "D"],
122 }
123
124 provider_module {
125 name: "C",
126 deps: ["D"],
127 }
128
129 provider_module {
130 name: "D",
131 }
132 `),
133 })
134
Lukacs T. Berkieef56852021-09-02 11:34:06 +0200135 _, errs := ctx.ParseBlueprintsFiles("Android.bp", nil)
Colin Cross2da84922020-07-02 10:08:12 -0700136 if len(errs) == 0 {
137 _, errs = ctx.ResolveDependencies(nil)
138 }
139 if len(errs) == 0 {
140 _, errs = ctx.PrepareBuildActions(nil)
141 }
142 if len(errs) > 0 {
143 t.Errorf("unexpected errors:")
144 for _, err := range errs {
145 t.Errorf(" %s", err)
146 }
147 t.FailNow()
148 }
149
150 aModule := ctx.moduleGroupFromName("A", nil).moduleByVariantName("").logicModule.(*providerTestModule)
151 if g, w := aModule.generateBuildActionsProviderValues, []string{"B"}; !reflect.DeepEqual(g, w) {
152 t.Errorf("expected A.generateBuildActionsProviderValues %q, got %q", w, g)
153 }
154 if g, w := aModule.mutatorProviderValues, []string{"a", "b", "c", "d", "d"}; !reflect.DeepEqual(g, w) {
155 t.Errorf("expected A.mutatorProviderValues %q, got %q", w, g)
156 }
157
158 bModule := ctx.moduleGroupFromName("B", nil).moduleByVariantName("").logicModule.(*providerTestModule)
159 if g, w := bModule.generateBuildActionsProviderValues, []string{"C", "D"}; !reflect.DeepEqual(g, w) {
160 t.Errorf("expected B.generateBuildActionsProviderValues %q, got %q", w, g)
161 }
162 if g, w := bModule.mutatorProviderValues, []string{"b", "c", "d", "d"}; !reflect.DeepEqual(g, w) {
163 t.Errorf("expected B.mutatorProviderValues %q, got %q", w, g)
164 }
165}
166
167type invalidProviderUsageMutatorInfo string
168type invalidProviderUsageGenerateBuildActionsInfo string
169
170var invalidProviderUsageMutatorInfoProvider = NewMutatorProvider(invalidProviderUsageMutatorInfo(""), "mutator_under_test")
171var invalidProviderUsageGenerateBuildActionsInfoProvider = NewProvider(invalidProviderUsageGenerateBuildActionsInfo(""))
172
173type invalidProviderUsageTestModule struct {
174 parent *invalidProviderUsageTestModule
175
176 SimpleName
177 properties struct {
178 Deps []string
179
180 Early_mutator_set_of_mutator_provider bool
181 Late_mutator_set_of_mutator_provider bool
182 Late_build_actions_set_of_mutator_provider bool
183 Early_mutator_set_of_build_actions_provider bool
184
185 Early_mutator_get_of_mutator_provider bool
186 Early_module_get_of_mutator_provider bool
187 Early_mutator_get_of_build_actions_provider bool
188 Early_module_get_of_build_actions_provider bool
189
190 Duplicate_set bool
191 }
192}
193
194func invalidProviderUsageDepsMutator(ctx BottomUpMutatorContext) {
195 if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
196 ctx.AddDependency(ctx.Module(), nil, i.properties.Deps...)
197 }
198}
199
200func invalidProviderUsageParentMutator(ctx TopDownMutatorContext) {
201 if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
202 ctx.VisitDirectDeps(func(module Module) {
203 module.(*invalidProviderUsageTestModule).parent = i
204 })
205 }
206}
207
208func invalidProviderUsageBeforeMutator(ctx BottomUpMutatorContext) {
209 if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
210 if i.properties.Early_mutator_set_of_mutator_provider {
211 // A mutator attempting to set the value of a provider associated with a later mutator.
212 ctx.SetProvider(invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
213 }
214 if i.properties.Early_mutator_get_of_mutator_provider {
215 // A mutator attempting to get the value of a provider associated with a later mutator.
216 _ = ctx.Provider(invalidProviderUsageMutatorInfoProvider)
217 }
218 }
219}
220
221func invalidProviderUsageMutatorUnderTest(ctx TopDownMutatorContext) {
222 if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
223 if i.properties.Early_mutator_set_of_build_actions_provider {
224 // A mutator attempting to set the value of a non-mutator provider.
225 ctx.SetProvider(invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
226 }
227 if i.properties.Early_mutator_get_of_build_actions_provider {
228 // A mutator attempting to get the value of a non-mutator provider.
229 _ = ctx.Provider(invalidProviderUsageGenerateBuildActionsInfoProvider)
230 }
231 if i.properties.Early_module_get_of_mutator_provider {
232 // A mutator attempting to get the value of a provider associated with this mutator on
233 // a module for which this mutator hasn't run. This is a top down mutator so
234 // dependencies haven't run yet.
235 ctx.VisitDirectDeps(func(module Module) {
236 _ = ctx.OtherModuleProvider(module, invalidProviderUsageMutatorInfoProvider)
237 })
238 }
239 }
240}
241
242func invalidProviderUsageAfterMutator(ctx BottomUpMutatorContext) {
243 if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
244 if i.properties.Late_mutator_set_of_mutator_provider {
245 // A mutator trying to set the value of a provider associated with an earlier mutator.
246 ctx.SetProvider(invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
247 }
248 if i.properties.Late_mutator_set_of_mutator_provider {
249 // A mutator trying to set the value of a provider associated with an earlier mutator.
250 ctx.SetProvider(invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
251 }
252 }
253}
254
255func (i *invalidProviderUsageTestModule) GenerateBuildActions(ctx ModuleContext) {
256 if i.properties.Late_build_actions_set_of_mutator_provider {
257 // A GenerateBuildActions trying to set the value of a provider associated with a mutator.
258 ctx.SetProvider(invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
259 }
260 if i.properties.Early_module_get_of_build_actions_provider {
261 // A GenerateBuildActions trying to get the value of a provider on a module for which
262 // GenerateBuildActions hasn't run.
263 _ = ctx.OtherModuleProvider(i.parent, invalidProviderUsageGenerateBuildActionsInfoProvider)
264 }
265 if i.properties.Duplicate_set {
266 ctx.SetProvider(invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
267 ctx.SetProvider(invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
268 }
269}
270
271func TestInvalidProvidersUsage(t *testing.T) {
272 run := func(t *testing.T, module string, prop string, panicMsg string) {
273 t.Helper()
274 ctx := NewContext()
275 ctx.RegisterModuleType("invalid_provider_usage_test_module", func() (Module, []interface{}) {
276 m := &invalidProviderUsageTestModule{}
277 return m, []interface{}{&m.properties, &m.SimpleName.Properties}
278 })
279 ctx.RegisterBottomUpMutator("deps", invalidProviderUsageDepsMutator)
280 ctx.RegisterBottomUpMutator("before", invalidProviderUsageBeforeMutator)
281 ctx.RegisterTopDownMutator("mutator_under_test", invalidProviderUsageMutatorUnderTest)
282 ctx.RegisterBottomUpMutator("after", invalidProviderUsageAfterMutator)
283 ctx.RegisterTopDownMutator("parent", invalidProviderUsageParentMutator)
284
285 // Don't invalidate the parent pointer and before GenerateBuildActions.
286 ctx.skipCloneModulesAfterMutators = true
287
288 var parentBP, moduleUnderTestBP, childBP string
289
290 prop += ": true,"
291
292 switch module {
293 case "parent":
294 parentBP = prop
295 case "module_under_test":
296 moduleUnderTestBP = prop
297 case "child":
298 childBP = prop
299 }
300
301 bp := fmt.Sprintf(`
302 invalid_provider_usage_test_module {
303 name: "parent",
304 deps: ["module_under_test"],
305 %s
306 }
307
308 invalid_provider_usage_test_module {
309 name: "module_under_test",
310 deps: ["child"],
311 %s
312 }
313
314 invalid_provider_usage_test_module {
315 name: "child",
316 %s
317 }
318
319 `,
320 parentBP,
321 moduleUnderTestBP,
322 childBP)
323
324 ctx.MockFileSystem(map[string][]byte{
Lukacs T. Berkieef56852021-09-02 11:34:06 +0200325 "Android.bp": []byte(bp),
Colin Cross2da84922020-07-02 10:08:12 -0700326 })
327
Lukacs T. Berkieef56852021-09-02 11:34:06 +0200328 _, errs := ctx.ParseBlueprintsFiles("Android.bp", nil)
Colin Cross2da84922020-07-02 10:08:12 -0700329
330 if len(errs) == 0 {
331 _, errs = ctx.ResolveDependencies(nil)
332 }
333
334 if len(errs) == 0 {
335 _, errs = ctx.PrepareBuildActions(nil)
336 }
337
338 if len(errs) == 0 {
339 t.Fatal("expected an error")
340 }
341
342 if len(errs) > 1 {
343 t.Errorf("expected a single error, got %d:", len(errs))
344 for i, err := range errs {
345 t.Errorf("%d: %s", i, err)
346 }
347 t.FailNow()
348 }
349
350 if panicErr, ok := errs[0].(panicError); ok {
351 if panicErr.panic != panicMsg {
352 t.Fatalf("expected panic %q, got %q", panicMsg, panicErr.panic)
353 }
354 } else {
355 t.Fatalf("expected a panicError, got %T: %s", errs[0], errs[0].Error())
356 }
357
358 }
359
360 tests := []struct {
361 prop string
362 module string
363
364 panicMsg string
365 skip string
366 }{
367 {
368 prop: "early_mutator_set_of_mutator_provider",
369 module: "module_under_test",
370 panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test started",
371 },
372 {
373 prop: "late_mutator_set_of_mutator_provider",
374 module: "module_under_test",
375 panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo after mutator mutator_under_test finished",
376 },
377 {
378 prop: "late_build_actions_set_of_mutator_provider",
379 module: "module_under_test",
380 panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo after mutator mutator_under_test finished",
381 },
382 {
383 prop: "early_mutator_set_of_build_actions_provider",
384 module: "module_under_test",
385 panicMsg: "Can't set value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions started",
386 },
387
388 {
389 prop: "early_mutator_get_of_mutator_provider",
390 module: "module_under_test",
391 panicMsg: "Can't get value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test finished",
392 },
393 {
394 prop: "early_module_get_of_mutator_provider",
395 module: "module_under_test",
396 panicMsg: "Can't get value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test finished",
397 },
398 {
399 prop: "early_mutator_get_of_build_actions_provider",
400 module: "module_under_test",
401 panicMsg: "Can't get value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions finished",
402 },
403 {
404 prop: "early_module_get_of_build_actions_provider",
405 module: "module_under_test",
406 panicMsg: "Can't get value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions finished",
407 },
408 {
409 prop: "duplicate_set",
410 module: "module_under_test",
411 panicMsg: "Value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo is already set",
412 },
413 }
414
415 for _, tt := range tests {
416 t.Run(tt.prop, func(t *testing.T) {
417 run(t, tt.module, tt.prop, tt.panicMsg)
418 })
419 }
420}