blob: 191b535a35ad98c7462cc106d997fe4e664b04d2 [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"
Colin Crossdc35e212019-06-06 16:13:11 -070019 "reflect"
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000020 "strings"
Colin Crossdc35e212019-06-06 16:13:11 -070021 "testing"
22
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000023 "github.com/google/blueprint"
Colin Crossdc35e212019-06-06 16:13:11 -070024 "github.com/google/blueprint/proptools"
25)
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
70 config := TestConfig(buildDir, nil, bp, nil)
Colin Crossdc35e212019-06-06 16:13:11 -070071 config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
72
73 ctx := NewTestContext()
74 ctx.SetAllowMissingDependencies(true)
75
Colin Cross4b49b762019-11-22 15:25:03 -080076 ctx.RegisterModuleType("test", mutatorTestModuleFactory)
Colin Crossdc35e212019-06-06 16:13:11 -070077 ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
78 ctx.TopDown("add_missing_dependencies", addMissingDependenciesMutator)
79 })
80
Colin Cross98be1bb2019-12-13 20:41:13 -080081 ctx.Register(config)
Colin Crossdc35e212019-06-06 16:13:11 -070082 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
83 FailIfErrored(t, errs)
84 _, errs = ctx.PrepareBuildActions(config)
85 FailIfErrored(t, errs)
86
87 foo := ctx.ModuleForTests("foo", "").Module().(*mutatorTestModule)
88
89 if g, w := foo.missingDeps, []string{"added_missing_dep", "regular_missing_dep"}; !reflect.DeepEqual(g, w) {
90 t.Errorf("want foo missing deps %q, got %q", w, g)
91 }
92}
Colin Cross9a362232019-07-01 15:32:45 -070093
94func TestModuleString(t *testing.T) {
95 ctx := NewTestContext()
96
97 var moduleStrings []string
98
99 ctx.PreArchMutators(func(ctx RegisterMutatorsContext) {
100 ctx.BottomUp("pre_arch", func(ctx BottomUpMutatorContext) {
101 moduleStrings = append(moduleStrings, ctx.Module().String())
102 ctx.CreateVariations("a", "b")
103 })
104 ctx.TopDown("rename_top_down", func(ctx TopDownMutatorContext) {
105 moduleStrings = append(moduleStrings, ctx.Module().String())
106 ctx.Rename(ctx.Module().base().Name() + "_renamed1")
107 })
108 })
109
110 ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
111 ctx.BottomUp("pre_deps", func(ctx BottomUpMutatorContext) {
112 moduleStrings = append(moduleStrings, ctx.Module().String())
113 ctx.CreateVariations("c", "d")
114 })
115 })
116
117 ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
118 ctx.BottomUp("post_deps", func(ctx BottomUpMutatorContext) {
119 moduleStrings = append(moduleStrings, ctx.Module().String())
120 ctx.CreateLocalVariations("e", "f")
121 })
122 ctx.BottomUp("rename_bottom_up", func(ctx BottomUpMutatorContext) {
123 moduleStrings = append(moduleStrings, ctx.Module().String())
124 ctx.Rename(ctx.Module().base().Name() + "_renamed2")
125 })
126 ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
127 moduleStrings = append(moduleStrings, ctx.Module().String())
128 })
129 })
130
Colin Cross4b49b762019-11-22 15:25:03 -0800131 ctx.RegisterModuleType("test", mutatorTestModuleFactory)
Colin Cross9a362232019-07-01 15:32:45 -0700132
133 bp := `
134 test {
135 name: "foo",
136 }
137 `
138
Colin Cross98be1bb2019-12-13 20:41:13 -0800139 config := TestConfig(buildDir, nil, bp, nil)
Colin Cross9a362232019-07-01 15:32:45 -0700140
Colin Cross98be1bb2019-12-13 20:41:13 -0800141 ctx.Register(config)
Colin Cross9a362232019-07-01 15:32:45 -0700142
143 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
144 FailIfErrored(t, errs)
145 _, errs = ctx.PrepareBuildActions(config)
146 FailIfErrored(t, errs)
147
148 want := []string{
149 // Initial name.
150 "foo{}",
151
152 // After pre_arch (reversed because rename_top_down is TopDown so it visits in reverse order).
153 "foo{pre_arch:b}",
154 "foo{pre_arch:a}",
155
156 // After rename_top_down.
157 "foo_renamed1{pre_arch:a}",
158 "foo_renamed1{pre_arch:b}",
159
160 // After pre_deps.
161 "foo_renamed1{pre_arch:a,pre_deps:c}",
162 "foo_renamed1{pre_arch:a,pre_deps:d}",
163 "foo_renamed1{pre_arch:b,pre_deps:c}",
164 "foo_renamed1{pre_arch:b,pre_deps:d}",
165
166 // After post_deps.
167 "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:e}",
168 "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:f}",
169 "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:e}",
170 "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:f}",
171 "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:e}",
172 "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:f}",
173 "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:e}",
174 "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:f}",
175
176 // After rename_bottom_up.
177 "foo_renamed2{pre_arch:a,pre_deps:c,post_deps:e}",
178 "foo_renamed2{pre_arch:a,pre_deps:c,post_deps:f}",
179 "foo_renamed2{pre_arch:a,pre_deps:d,post_deps:e}",
180 "foo_renamed2{pre_arch:a,pre_deps:d,post_deps:f}",
181 "foo_renamed2{pre_arch:b,pre_deps:c,post_deps:e}",
182 "foo_renamed2{pre_arch:b,pre_deps:c,post_deps:f}",
183 "foo_renamed2{pre_arch:b,pre_deps:d,post_deps:e}",
184 "foo_renamed2{pre_arch:b,pre_deps:d,post_deps:f}",
185 }
186
187 if !reflect.DeepEqual(moduleStrings, want) {
188 t.Errorf("want module String() values:\n%q\ngot:\n%q", want, moduleStrings)
189 }
190}
Martin Stjernholm710ec3a2020-01-16 15:12:04 +0000191
192func TestFinalDepsPhase(t *testing.T) {
193 ctx := NewTestContext()
194
195 finalGot := map[string]int{}
196
197 dep1Tag := struct {
198 blueprint.BaseDependencyTag
199 }{}
200 dep2Tag := struct {
201 blueprint.BaseDependencyTag
202 }{}
203
204 ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
205 ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) {
206 if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
207 ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1")
208 }
209 })
210 ctx.BottomUp("variant", func(ctx BottomUpMutatorContext) {
211 ctx.CreateLocalVariations("a", "b")
212 })
213 })
214
215 ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
216 ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) {
217 if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
218 ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2")
219 }
220 })
221 ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
222 finalGot[ctx.Module().String()] += 1
223 ctx.VisitDirectDeps(func(mod Module) {
224 finalGot[fmt.Sprintf("%s -> %s", ctx.Module().String(), mod)] += 1
225 })
226 })
227 })
228
229 ctx.RegisterModuleType("test", mutatorTestModuleFactory)
230
231 bp := `
232 test {
233 name: "common_dep_1",
234 }
235 test {
236 name: "common_dep_2",
237 }
238 test {
239 name: "foo",
240 }
241 `
242
243 config := TestConfig(buildDir, nil, bp, nil)
244 ctx.Register(config)
245
246 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
247 FailIfErrored(t, errs)
248 _, errs = ctx.PrepareBuildActions(config)
249 FailIfErrored(t, errs)
250
251 finalWant := map[string]int{
252 "common_dep_1{variant:a}": 1,
253 "common_dep_1{variant:b}": 1,
254 "common_dep_2{variant:a}": 1,
255 "common_dep_2{variant:b}": 1,
256 "foo{variant:a}": 1,
257 "foo{variant:a} -> common_dep_1{variant:a}": 1,
258 "foo{variant:a} -> common_dep_2{variant:a}": 1,
259 "foo{variant:b}": 1,
260 "foo{variant:b} -> common_dep_1{variant:b}": 1,
261 "foo{variant:b} -> common_dep_2{variant:a}": 1,
262 }
263
264 if !reflect.DeepEqual(finalWant, finalGot) {
265 t.Errorf("want:\n%q\ngot:\n%q", finalWant, finalGot)
266 }
267}
268
269func TestNoCreateVariationsInFinalDeps(t *testing.T) {
270 ctx := NewTestContext()
271
272 checkErr := func() {
273 if err := recover(); err == nil || !strings.Contains(fmt.Sprintf("%s", err), "not allowed in FinalDepsMutators") {
274 panic("Expected FinalDepsMutators consistency check to fail")
275 }
276 }
277
278 ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
279 ctx.BottomUp("vars", func(ctx BottomUpMutatorContext) {
280 defer checkErr()
281 ctx.CreateVariations("a", "b")
282 })
283 ctx.BottomUp("local_vars", func(ctx BottomUpMutatorContext) {
284 defer checkErr()
285 ctx.CreateLocalVariations("a", "b")
286 })
287 })
288
289 ctx.RegisterModuleType("test", mutatorTestModuleFactory)
290 config := TestConfig(buildDir, nil, `test {name: "foo"}`, nil)
291 ctx.Register(config)
292
293 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
294 FailIfErrored(t, errs)
295 _, errs = ctx.PrepareBuildActions(config)
296 FailIfErrored(t, errs)
297}