• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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 (
18	"fmt"
19	"reflect"
20	"strings"
21	"testing"
22
23	"github.com/google/blueprint"
24)
25
26type mutatorTestModule struct {
27	ModuleBase
28	props struct {
29		Deps_missing_deps    []string
30		Mutator_missing_deps []string
31	}
32
33	missingDeps []string
34}
35
36func mutatorTestModuleFactory() Module {
37	module := &mutatorTestModule{}
38	module.AddProperties(&module.props)
39	InitAndroidModule(module)
40	return module
41}
42
43func (m *mutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
44	ctx.Build(pctx, BuildParams{
45		Rule:   Touch,
46		Output: PathForModuleOut(ctx, "output"),
47	})
48
49	m.missingDeps = ctx.GetMissingDependencies()
50}
51
52func (m *mutatorTestModule) DepsMutator(ctx BottomUpMutatorContext) {
53	ctx.AddDependency(ctx.Module(), nil, m.props.Deps_missing_deps...)
54}
55
56func addMissingDependenciesMutator(ctx TopDownMutatorContext) {
57	ctx.AddMissingDependencies(ctx.Module().(*mutatorTestModule).props.Mutator_missing_deps)
58}
59
60func TestMutatorAddMissingDependencies(t *testing.T) {
61	bp := `
62		test {
63			name: "foo",
64			deps_missing_deps: ["regular_missing_dep"],
65			mutator_missing_deps: ["added_missing_dep"],
66		}
67	`
68
69	result := GroupFixturePreparers(
70		PrepareForTestWithAllowMissingDependencies,
71		FixtureRegisterWithContext(func(ctx RegistrationContext) {
72			ctx.RegisterModuleType("test", mutatorTestModuleFactory)
73			ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
74				ctx.TopDown("add_missing_dependencies", addMissingDependenciesMutator)
75			})
76		}),
77		FixtureWithRootAndroidBp(bp),
78	).RunTest(t)
79
80	foo := result.ModuleForTests("foo", "").Module().(*mutatorTestModule)
81
82	AssertDeepEquals(t, "foo missing deps", []string{"added_missing_dep", "regular_missing_dep"}, foo.missingDeps)
83}
84
85func TestModuleString(t *testing.T) {
86	bp := `
87		test {
88			name: "foo",
89		}
90	`
91
92	var moduleStrings []string
93
94	GroupFixturePreparers(
95		FixtureRegisterWithContext(func(ctx RegistrationContext) {
96
97			ctx.PreArchMutators(func(ctx RegisterMutatorsContext) {
98				ctx.BottomUp("pre_arch", func(ctx BottomUpMutatorContext) {
99					moduleStrings = append(moduleStrings, ctx.Module().String())
100					ctx.CreateVariations("a", "b")
101				})
102				ctx.TopDown("rename_top_down", func(ctx TopDownMutatorContext) {
103					moduleStrings = append(moduleStrings, ctx.Module().String())
104					ctx.Rename(ctx.Module().base().Name() + "_renamed1")
105				})
106			})
107
108			ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
109				ctx.BottomUp("pre_deps", func(ctx BottomUpMutatorContext) {
110					moduleStrings = append(moduleStrings, ctx.Module().String())
111					ctx.CreateVariations("c", "d")
112				})
113			})
114
115			ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
116				ctx.BottomUp("post_deps", func(ctx BottomUpMutatorContext) {
117					moduleStrings = append(moduleStrings, ctx.Module().String())
118					ctx.CreateLocalVariations("e", "f")
119				})
120				ctx.BottomUp("rename_bottom_up", func(ctx BottomUpMutatorContext) {
121					moduleStrings = append(moduleStrings, ctx.Module().String())
122					ctx.Rename(ctx.Module().base().Name() + "_renamed2")
123				})
124				ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
125					moduleStrings = append(moduleStrings, ctx.Module().String())
126				})
127			})
128
129			ctx.RegisterModuleType("test", mutatorTestModuleFactory)
130		}),
131		FixtureWithRootAndroidBp(bp),
132	).RunTest(t)
133
134	want := []string{
135		// Initial name.
136		"foo{}",
137
138		// After pre_arch (reversed because rename_top_down is TopDown so it visits in reverse order).
139		"foo{pre_arch:b}",
140		"foo{pre_arch:a}",
141
142		// After rename_top_down.
143		"foo_renamed1{pre_arch:a}",
144		"foo_renamed1{pre_arch:b}",
145
146		// After pre_deps.
147		"foo_renamed1{pre_arch:a,pre_deps:c}",
148		"foo_renamed1{pre_arch:a,pre_deps:d}",
149		"foo_renamed1{pre_arch:b,pre_deps:c}",
150		"foo_renamed1{pre_arch:b,pre_deps:d}",
151
152		// After post_deps.
153		"foo_renamed1{pre_arch:a,pre_deps:c,post_deps:e}",
154		"foo_renamed1{pre_arch:a,pre_deps:c,post_deps:f}",
155		"foo_renamed1{pre_arch:a,pre_deps:d,post_deps:e}",
156		"foo_renamed1{pre_arch:a,pre_deps:d,post_deps:f}",
157		"foo_renamed1{pre_arch:b,pre_deps:c,post_deps:e}",
158		"foo_renamed1{pre_arch:b,pre_deps:c,post_deps:f}",
159		"foo_renamed1{pre_arch:b,pre_deps:d,post_deps:e}",
160		"foo_renamed1{pre_arch:b,pre_deps:d,post_deps:f}",
161
162		// After rename_bottom_up.
163		"foo_renamed2{pre_arch:a,pre_deps:c,post_deps:e}",
164		"foo_renamed2{pre_arch:a,pre_deps:c,post_deps:f}",
165		"foo_renamed2{pre_arch:a,pre_deps:d,post_deps:e}",
166		"foo_renamed2{pre_arch:a,pre_deps:d,post_deps:f}",
167		"foo_renamed2{pre_arch:b,pre_deps:c,post_deps:e}",
168		"foo_renamed2{pre_arch:b,pre_deps:c,post_deps:f}",
169		"foo_renamed2{pre_arch:b,pre_deps:d,post_deps:e}",
170		"foo_renamed2{pre_arch:b,pre_deps:d,post_deps:f}",
171	}
172
173	AssertDeepEquals(t, "module String() values", want, moduleStrings)
174}
175
176func TestFinalDepsPhase(t *testing.T) {
177	bp := `
178		test {
179			name: "common_dep_1",
180		}
181		test {
182			name: "common_dep_2",
183		}
184		test {
185			name: "foo",
186		}
187	`
188
189	finalGot := map[string]int{}
190
191	GroupFixturePreparers(
192		FixtureRegisterWithContext(func(ctx RegistrationContext) {
193			dep1Tag := struct {
194				blueprint.BaseDependencyTag
195			}{}
196			dep2Tag := struct {
197				blueprint.BaseDependencyTag
198			}{}
199
200			ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
201				ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) {
202					if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
203						ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1")
204					}
205				})
206				ctx.BottomUp("variant", func(ctx BottomUpMutatorContext) {
207					ctx.CreateLocalVariations("a", "b")
208				})
209			})
210
211			ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
212				ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) {
213					if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
214						ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2")
215					}
216				})
217				ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
218					finalGot[ctx.Module().String()] += 1
219					ctx.VisitDirectDeps(func(mod Module) {
220						finalGot[fmt.Sprintf("%s -> %s", ctx.Module().String(), mod)] += 1
221					})
222				})
223			})
224
225			ctx.RegisterModuleType("test", mutatorTestModuleFactory)
226		}),
227		FixtureWithRootAndroidBp(bp),
228	).RunTest(t)
229
230	finalWant := map[string]int{
231		"common_dep_1{variant:a}":                   1,
232		"common_dep_1{variant:b}":                   1,
233		"common_dep_2{variant:a}":                   1,
234		"common_dep_2{variant:b}":                   1,
235		"foo{variant:a}":                            1,
236		"foo{variant:a} -> common_dep_1{variant:a}": 1,
237		"foo{variant:a} -> common_dep_2{variant:a}": 1,
238		"foo{variant:b}":                            1,
239		"foo{variant:b} -> common_dep_1{variant:b}": 1,
240		"foo{variant:b} -> common_dep_2{variant:a}": 1,
241	}
242
243	AssertDeepEquals(t, "final", finalWant, finalGot)
244}
245
246func TestNoCreateVariationsInFinalDeps(t *testing.T) {
247	checkErr := func() {
248		if err := recover(); err == nil || !strings.Contains(fmt.Sprintf("%s", err), "not allowed in FinalDepsMutators") {
249			panic("Expected FinalDepsMutators consistency check to fail")
250		}
251	}
252
253	GroupFixturePreparers(
254		FixtureRegisterWithContext(func(ctx RegistrationContext) {
255			ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
256				ctx.BottomUp("vars", func(ctx BottomUpMutatorContext) {
257					defer checkErr()
258					ctx.CreateVariations("a", "b")
259				})
260				ctx.BottomUp("local_vars", func(ctx BottomUpMutatorContext) {
261					defer checkErr()
262					ctx.CreateLocalVariations("a", "b")
263				})
264			})
265
266			ctx.RegisterModuleType("test", mutatorTestModuleFactory)
267		}),
268		FixtureWithRootAndroidBp(`test {name: "foo"}`),
269	).RunTest(t)
270}
271
272func TestConvertApexAvailableToTags(t *testing.T) {
273	input := []string{
274		"com.android.adbd",
275		"//apex_available:platform",
276	}
277	actual := ConvertApexAvailableToTags(input)
278	expected := []string{
279		"apex_available=com.android.adbd",
280		"apex_available=//apex_available:platform",
281	}
282	if !reflect.DeepEqual(actual, expected) {
283		t.Errorf("Expected: %v, actual: %v", expected, actual)
284	}
285
286	if ConvertApexAvailableToTags(nil) != nil {
287		t.Errorf("Expected providing nil to return nil")
288	}
289}
290