• 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	"strings"
20	"sync"
21	"sync/atomic"
22	"testing"
23
24	"github.com/google/blueprint"
25)
26
27type mutatorTestModule struct {
28	ModuleBase
29	props struct {
30		Deps_missing_deps    []string
31		Mutator_missing_deps []string
32	}
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) {
54	ctx.AddDependency(ctx.Module(), nil, m.props.Deps_missing_deps...)
55}
56
57func addMissingDependenciesMutator(ctx BottomUpMutatorContext) {
58	ctx.AddMissingDependencies(ctx.Module().(*mutatorTestModule).props.Mutator_missing_deps)
59}
60
61func TestMutatorAddMissingDependencies(t *testing.T) {
62	bp := `
63		test {
64			name: "foo",
65			deps_missing_deps: ["regular_missing_dep"],
66			mutator_missing_deps: ["added_missing_dep"],
67		}
68	`
69
70	result := GroupFixturePreparers(
71		PrepareForTestWithAllowMissingDependencies,
72		FixtureRegisterWithContext(func(ctx RegistrationContext) {
73			ctx.RegisterModuleType("test", mutatorTestModuleFactory)
74			ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
75				ctx.BottomUp("add_missing_dependencies", addMissingDependenciesMutator)
76			})
77		}),
78		FixtureWithRootAndroidBp(bp),
79	).RunTest(t)
80
81	foo := result.ModuleForTests(t, "foo", "").Module().(*mutatorTestModule)
82
83	AssertDeepEquals(t, "foo missing deps", []string{"added_missing_dep", "regular_missing_dep"}, foo.missingDeps)
84}
85
86func TestFinalDepsPhase(t *testing.T) {
87	bp := `
88		test {
89			name: "common_dep_1",
90		}
91		test {
92			name: "common_dep_2",
93		}
94		test {
95			name: "foo",
96		}
97	`
98
99	finalGot := sync.Map{}
100
101	GroupFixturePreparers(
102		FixtureRegisterWithContext(func(ctx RegistrationContext) {
103			dep1Tag := struct {
104				blueprint.BaseDependencyTag
105			}{}
106			dep2Tag := struct {
107				blueprint.BaseDependencyTag
108			}{}
109
110			ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
111				ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) {
112					if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
113						ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1")
114					}
115				})
116				ctx.Transition("variant", &testTransitionMutator{
117					split: func(ctx BaseModuleContext) []string {
118						return []string{"a", "b"}
119					},
120				})
121			})
122
123			ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
124				ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) {
125					if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
126						ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2")
127					}
128				})
129				ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
130					counter, _ := finalGot.LoadOrStore(ctx.Module().String(), &atomic.Int64{})
131					counter.(*atomic.Int64).Add(1)
132					ctx.VisitDirectDeps(func(mod Module) {
133						counter, _ := finalGot.LoadOrStore(fmt.Sprintf("%s -> %s", ctx.Module().String(), mod), &atomic.Int64{})
134						counter.(*atomic.Int64).Add(1)
135					})
136				})
137			})
138
139			ctx.RegisterModuleType("test", mutatorTestModuleFactory)
140		}),
141		FixtureWithRootAndroidBp(bp),
142	).RunTest(t)
143
144	finalWant := map[string]int{
145		"common_dep_1{variant:a}":                   1,
146		"common_dep_1{variant:b}":                   1,
147		"common_dep_2{variant:a}":                   1,
148		"common_dep_2{variant:b}":                   1,
149		"foo{variant:a}":                            1,
150		"foo{variant:a} -> common_dep_1{variant:a}": 1,
151		"foo{variant:a} -> common_dep_2{variant:a}": 1,
152		"foo{variant:b}":                            1,
153		"foo{variant:b} -> common_dep_1{variant:b}": 1,
154		"foo{variant:b} -> common_dep_2{variant:a}": 1,
155	}
156
157	finalGotMap := make(map[string]int)
158	finalGot.Range(func(k, v any) bool {
159		finalGotMap[k.(string)] = int(v.(*atomic.Int64).Load())
160		return true
161	})
162
163	AssertDeepEquals(t, "final", finalWant, finalGotMap)
164}
165