blob: 1d5f890424e3ffc1bf7eb5287b95d80b38e41826 [file] [log] [blame]
Colin Crossdc35e212019-06-06 16:13:11 -07001// Copyright 2015 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 (
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000018 "fmt"
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000019 "strings"
Colin Cross2d2e68f2024-10-10 11:57:11 -070020 "sync"
21 "sync/atomic"
Colin Crossdc35e212019-06-06 16:13:11 -070022 "testing"
23
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000024 "github.com/google/blueprint"
Colin Crossdc35e212019-06-06 16:13:11 -070025)
26
27type mutatorTestModule struct {
28 ModuleBase
29 props struct {
Colin Cross9a362232019-07-01 15:32:45 -070030 Deps_missing_deps []string
31 Mutator_missing_deps []string
Colin Crossdc35e212019-06-06 16:13:11 -070032 }
33
34 missingDeps []string
35}
36
37func mutatorTestModuleFactory() Module {
38 module := &mutatorTestModule{}
39 module.AddProperties(&module.props)
40 InitAndroidModule(module)
41 return module
42}
43
44func (m *mutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
45 ctx.Build(pctx, BuildParams{
46 Rule: Touch,
47 Output: PathForModuleOut(ctx, "output"),
48 })
49
50 m.missingDeps = ctx.GetMissingDependencies()
51}
52
53func (m *mutatorTestModule) DepsMutator(ctx BottomUpMutatorContext) {
Colin Cross9a362232019-07-01 15:32:45 -070054 ctx.AddDependency(ctx.Module(), nil, m.props.Deps_missing_deps...)
Colin Crossdc35e212019-06-06 16:13:11 -070055}
56
57func addMissingDependenciesMutator(ctx TopDownMutatorContext) {
Colin Cross9a362232019-07-01 15:32:45 -070058 ctx.AddMissingDependencies(ctx.Module().(*mutatorTestModule).props.Mutator_missing_deps)
Colin Crossdc35e212019-06-06 16:13:11 -070059}
60
61func TestMutatorAddMissingDependencies(t *testing.T) {
Colin Cross98be1bb2019-12-13 20:41:13 -080062 bp := `
63 test {
64 name: "foo",
65 deps_missing_deps: ["regular_missing_dep"],
66 mutator_missing_deps: ["added_missing_dep"],
67 }
68 `
69
Paul Duffin30ac3e72021-03-20 00:36:14 +000070 result := GroupFixturePreparers(
Paul Duffine8a4ac42021-03-16 22:35:28 +000071 PrepareForTestWithAllowMissingDependencies,
72 FixtureRegisterWithContext(func(ctx RegistrationContext) {
73 ctx.RegisterModuleType("test", mutatorTestModuleFactory)
74 ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
75 ctx.TopDown("add_missing_dependencies", addMissingDependenciesMutator)
76 })
77 }),
78 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +000079 ).RunTest(t)
Colin Crossdc35e212019-06-06 16:13:11 -070080
Paul Duffine8a4ac42021-03-16 22:35:28 +000081 foo := result.ModuleForTests("foo", "").Module().(*mutatorTestModule)
Colin Crossdc35e212019-06-06 16:13:11 -070082
Paul Duffine8a4ac42021-03-16 22:35:28 +000083 AssertDeepEquals(t, "foo missing deps", []string{"added_missing_dep", "regular_missing_dep"}, foo.missingDeps)
Colin Crossdc35e212019-06-06 16:13:11 -070084}
Colin Cross9a362232019-07-01 15:32:45 -070085
Colin Crossd27205e2024-09-12 22:41:37 -070086type testTransitionMutator struct {
87 split func(ctx BaseModuleContext) []string
88 outgoingTransition func(ctx OutgoingTransitionContext, sourceVariation string) string
89 incomingTransition func(ctx IncomingTransitionContext, incomingVariation string) string
90 mutate func(ctx BottomUpMutatorContext, variation string)
91}
92
93func (t *testTransitionMutator) Split(ctx BaseModuleContext) []string {
94 if t.split != nil {
95 return t.split(ctx)
96 }
97 return []string{""}
98}
99
100func (t *testTransitionMutator) OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string {
101 if t.outgoingTransition != nil {
102 return t.outgoingTransition(ctx, sourceVariation)
103 }
104 return sourceVariation
105}
106
107func (t *testTransitionMutator) IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string {
108 if t.incomingTransition != nil {
109 return t.incomingTransition(ctx, incomingVariation)
110 }
111 return incomingVariation
112}
113
114func (t *testTransitionMutator) Mutate(ctx BottomUpMutatorContext, variation string) {
115 if t.mutate != nil {
116 t.mutate(ctx, variation)
117 }
118}
119
Colin Cross9a362232019-07-01 15:32:45 -0700120func TestModuleString(t *testing.T) {
Colin Crossae8600b2020-10-29 17:09:13 -0700121 bp := `
122 test {
123 name: "foo",
124 }
125 `
126
Colin Cross9a362232019-07-01 15:32:45 -0700127 var moduleStrings []string
128
Paul Duffin30ac3e72021-03-20 00:36:14 +0000129 GroupFixturePreparers(
Paul Duffine8a4ac42021-03-16 22:35:28 +0000130 FixtureRegisterWithContext(func(ctx RegistrationContext) {
Colin Cross9a362232019-07-01 15:32:45 -0700131
Paul Duffine8a4ac42021-03-16 22:35:28 +0000132 ctx.PreArchMutators(func(ctx RegisterMutatorsContext) {
Colin Crossd27205e2024-09-12 22:41:37 -0700133 ctx.Transition("pre_arch", &testTransitionMutator{
134 split: func(ctx BaseModuleContext) []string {
135 moduleStrings = append(moduleStrings, ctx.Module().String())
136 return []string{"a", "b"}
137 },
Paul Duffine8a4ac42021-03-16 22:35:28 +0000138 })
Paul Duffine8a4ac42021-03-16 22:35:28 +0000139 })
Colin Cross9a362232019-07-01 15:32:45 -0700140
Paul Duffine8a4ac42021-03-16 22:35:28 +0000141 ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
Colin Crossd27205e2024-09-12 22:41:37 -0700142 ctx.Transition("pre_deps", &testTransitionMutator{
143 split: func(ctx BaseModuleContext) []string {
144 moduleStrings = append(moduleStrings, ctx.Module().String())
145 return []string{"c", "d"}
146 },
Paul Duffine8a4ac42021-03-16 22:35:28 +0000147 })
148 })
Colin Cross9a362232019-07-01 15:32:45 -0700149
Paul Duffine8a4ac42021-03-16 22:35:28 +0000150 ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
Colin Crossd27205e2024-09-12 22:41:37 -0700151 ctx.Transition("post_deps", &testTransitionMutator{
152 split: func(ctx BaseModuleContext) []string {
153 moduleStrings = append(moduleStrings, ctx.Module().String())
154 return []string{"e", "f"}
155 },
156 outgoingTransition: func(ctx OutgoingTransitionContext, sourceVariation string) string {
157 return ""
158 },
Paul Duffine8a4ac42021-03-16 22:35:28 +0000159 })
160 ctx.BottomUp("rename_bottom_up", func(ctx BottomUpMutatorContext) {
161 moduleStrings = append(moduleStrings, ctx.Module().String())
Colin Crossb2388e32024-10-07 15:05:23 -0700162 ctx.Rename(ctx.Module().base().Name() + "_renamed1")
Colin Crossb8533a82024-10-05 15:25:09 -0700163 }).UsesRename()
Paul Duffine8a4ac42021-03-16 22:35:28 +0000164 ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
165 moduleStrings = append(moduleStrings, ctx.Module().String())
166 })
167 })
Colin Cross9a362232019-07-01 15:32:45 -0700168
Paul Duffine8a4ac42021-03-16 22:35:28 +0000169 ctx.RegisterModuleType("test", mutatorTestModuleFactory)
170 }),
171 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000172 ).RunTest(t)
Colin Cross9a362232019-07-01 15:32:45 -0700173
174 want := []string{
175 // Initial name.
176 "foo{}",
177
178 // After pre_arch (reversed because rename_top_down is TopDown so it visits in reverse order).
179 "foo{pre_arch:b}",
180 "foo{pre_arch:a}",
181
Colin Crossd27205e2024-09-12 22:41:37 -0700182 // After pre_deps (reversed because post_deps TransitionMutator.Split is TopDown).
Colin Crossb2388e32024-10-07 15:05:23 -0700183 "foo{pre_arch:b,pre_deps:d}",
184 "foo{pre_arch:b,pre_deps:c}",
185 "foo{pre_arch:a,pre_deps:d}",
186 "foo{pre_arch:a,pre_deps:c}",
Colin Cross9a362232019-07-01 15:32:45 -0700187
188 // After post_deps.
Colin Crossb2388e32024-10-07 15:05:23 -0700189 "foo{pre_arch:a,pre_deps:c,post_deps:e}",
190 "foo{pre_arch:a,pre_deps:c,post_deps:f}",
191 "foo{pre_arch:a,pre_deps:d,post_deps:e}",
192 "foo{pre_arch:a,pre_deps:d,post_deps:f}",
193 "foo{pre_arch:b,pre_deps:c,post_deps:e}",
194 "foo{pre_arch:b,pre_deps:c,post_deps:f}",
195 "foo{pre_arch:b,pre_deps:d,post_deps:e}",
196 "foo{pre_arch:b,pre_deps:d,post_deps:f}",
197
198 // After rename_bottom_up.
Colin Cross9a362232019-07-01 15:32:45 -0700199 "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:e}",
200 "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:f}",
201 "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:e}",
202 "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:f}",
203 "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:e}",
204 "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:f}",
205 "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:e}",
206 "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:f}",
Colin Cross9a362232019-07-01 15:32:45 -0700207 }
208
Paul Duffine8a4ac42021-03-16 22:35:28 +0000209 AssertDeepEquals(t, "module String() values", want, moduleStrings)
Colin Cross9a362232019-07-01 15:32:45 -0700210}
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000211
212func TestFinalDepsPhase(t *testing.T) {
Colin Crossae8600b2020-10-29 17:09:13 -0700213 bp := `
214 test {
215 name: "common_dep_1",
216 }
217 test {
218 name: "common_dep_2",
219 }
220 test {
221 name: "foo",
222 }
223 `
224
Colin Cross2d2e68f2024-10-10 11:57:11 -0700225 finalGot := sync.Map{}
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000226
Paul Duffin30ac3e72021-03-20 00:36:14 +0000227 GroupFixturePreparers(
Paul Duffine8a4ac42021-03-16 22:35:28 +0000228 FixtureRegisterWithContext(func(ctx RegistrationContext) {
229 dep1Tag := struct {
230 blueprint.BaseDependencyTag
231 }{}
232 dep2Tag := struct {
233 blueprint.BaseDependencyTag
234 }{}
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000235
Paul Duffine8a4ac42021-03-16 22:35:28 +0000236 ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
237 ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) {
238 if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
239 ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1")
240 }
Colin Cross8a962802024-10-09 15:29:27 -0700241 })
Colin Crossd27205e2024-09-12 22:41:37 -0700242 ctx.Transition("variant", &testTransitionMutator{
243 split: func(ctx BaseModuleContext) []string {
244 return []string{"a", "b"}
245 },
Paul Duffine8a4ac42021-03-16 22:35:28 +0000246 })
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000247 })
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000248
Paul Duffine8a4ac42021-03-16 22:35:28 +0000249 ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
250 ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) {
251 if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
252 ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2")
253 }
Colin Cross8a962802024-10-09 15:29:27 -0700254 })
Paul Duffine8a4ac42021-03-16 22:35:28 +0000255 ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
Colin Cross2d2e68f2024-10-10 11:57:11 -0700256 counter, _ := finalGot.LoadOrStore(ctx.Module().String(), &atomic.Int64{})
257 counter.(*atomic.Int64).Add(1)
Paul Duffine8a4ac42021-03-16 22:35:28 +0000258 ctx.VisitDirectDeps(func(mod Module) {
Colin Cross2d2e68f2024-10-10 11:57:11 -0700259 counter, _ := finalGot.LoadOrStore(fmt.Sprintf("%s -> %s", ctx.Module().String(), mod), &atomic.Int64{})
260 counter.(*atomic.Int64).Add(1)
Paul Duffine8a4ac42021-03-16 22:35:28 +0000261 })
Colin Cross8a962802024-10-09 15:29:27 -0700262 })
Paul Duffine8a4ac42021-03-16 22:35:28 +0000263 })
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000264
Paul Duffine8a4ac42021-03-16 22:35:28 +0000265 ctx.RegisterModuleType("test", mutatorTestModuleFactory)
266 }),
267 FixtureWithRootAndroidBp(bp),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000268 ).RunTest(t)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000269
270 finalWant := map[string]int{
271 "common_dep_1{variant:a}": 1,
272 "common_dep_1{variant:b}": 1,
273 "common_dep_2{variant:a}": 1,
274 "common_dep_2{variant:b}": 1,
275 "foo{variant:a}": 1,
276 "foo{variant:a} -> common_dep_1{variant:a}": 1,
277 "foo{variant:a} -> common_dep_2{variant:a}": 1,
278 "foo{variant:b}": 1,
279 "foo{variant:b} -> common_dep_1{variant:b}": 1,
280 "foo{variant:b} -> common_dep_2{variant:a}": 1,
281 }
282
Colin Cross2d2e68f2024-10-10 11:57:11 -0700283 finalGotMap := make(map[string]int)
284 finalGot.Range(func(k, v any) bool {
285 finalGotMap[k.(string)] = int(v.(*atomic.Int64).Load())
286 return true
287 })
288
289 AssertDeepEquals(t, "final", finalWant, finalGotMap)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000290}
291
Colin Cross1e954b62024-09-13 13:50:00 -0700292func TestTransitionMutatorInFinalDeps(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000293 GroupFixturePreparers(
Paul Duffine8a4ac42021-03-16 22:35:28 +0000294 FixtureRegisterWithContext(func(ctx RegistrationContext) {
295 ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
Colin Crossd27205e2024-09-12 22:41:37 -0700296 ctx.Transition("vars", &testTransitionMutator{
297 split: func(ctx BaseModuleContext) []string {
298 return []string{"a", "b"}
299 },
Paul Duffine8a4ac42021-03-16 22:35:28 +0000300 })
301 })
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000302
Paul Duffine8a4ac42021-03-16 22:35:28 +0000303 ctx.RegisterModuleType("test", mutatorTestModuleFactory)
304 }),
305 FixtureWithRootAndroidBp(`test {name: "foo"}`),
Colin Crossd27205e2024-09-12 22:41:37 -0700306 ).
307 ExtendWithErrorHandler(FixtureExpectsOneErrorPattern("not allowed in FinalDepsMutators")).
308 RunTest(t)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000309}