blob: 873e72c05ce3f79c7abc2468154afc9b8e8128c7 [file] [log] [blame]
Colin Cross365bc6b2016-08-08 11:21:09 -07001// Copyright 2016 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
Colin Crossbafd5f52016-08-06 22:52:01 -070017import (
18 "fmt"
19 "testing"
20)
Colin Cross365bc6b2016-08-08 11:21:09 -070021
22type visitModule struct {
Colin Cross0b7e83e2016-05-17 14:58:05 -070023 SimpleName
Colin Cross365bc6b2016-08-08 11:21:09 -070024 properties struct {
25 Visit []string
26 VisitDepsDepthFirst string `blueprint:"mutated"`
27 VisitDepsDepthFirstIf string `blueprint:"mutated"`
28 VisitDirectDeps string `blueprint:"mutated"`
29 VisitDirectDepsIf string `blueprint:"mutated"`
30 }
31}
32
33func newVisitModule() (Module, []interface{}) {
34 m := &visitModule{}
Colin Cross0b7e83e2016-05-17 14:58:05 -070035 return m, []interface{}{&m.properties, &m.SimpleName.Properties}
Colin Cross365bc6b2016-08-08 11:21:09 -070036}
37
38func (f *visitModule) GenerateBuildActions(ModuleContext) {
39}
40
41type visitTag struct {
42 BaseDependencyTag
43}
44
45var visitTagDep visitTag
46
47func visitDepsMutator(ctx BottomUpMutatorContext) {
48 if m, ok := ctx.Module().(*visitModule); ok {
49 ctx.AddDependency(ctx.Module(), visitTagDep, m.properties.Visit...)
50 }
51}
52
53func visitMutator(ctx TopDownMutatorContext) {
54 if m, ok := ctx.Module().(*visitModule); ok {
55 ctx.VisitDepsDepthFirst(func(dep Module) {
Colin Crossbafd5f52016-08-06 22:52:01 -070056 if ctx.OtherModuleDependencyTag(dep) != visitTagDep {
57 panic(fmt.Errorf("unexpected dependency tag on %q", ctx.OtherModuleName(dep)))
58 }
Colin Cross365bc6b2016-08-08 11:21:09 -070059 m.properties.VisitDepsDepthFirst = m.properties.VisitDepsDepthFirst + ctx.OtherModuleName(dep)
60 })
61 ctx.VisitDepsDepthFirstIf(func(dep Module) bool {
62 return ctx.OtherModuleName(dep) != "B"
63 }, func(dep Module) {
64 m.properties.VisitDepsDepthFirstIf = m.properties.VisitDepsDepthFirstIf + ctx.OtherModuleName(dep)
65 })
66 ctx.VisitDirectDeps(func(dep Module) {
67 m.properties.VisitDirectDeps = m.properties.VisitDirectDeps + ctx.OtherModuleName(dep)
68 })
69 ctx.VisitDirectDepsIf(func(dep Module) bool {
70 return ctx.OtherModuleName(dep) != "B"
71 }, func(dep Module) {
72 m.properties.VisitDirectDepsIf = m.properties.VisitDirectDepsIf + ctx.OtherModuleName(dep)
73 })
74 }
75}
76
77// A
78// |
79// B
80// |\
81// C \
82// \|
83// D
84// |
85// E
Colin Cross9607a9f2018-06-20 11:16:37 -070086// / \
87// \ /
88// F
Colin Cross365bc6b2016-08-08 11:21:09 -070089func setupVisitTest(t *testing.T) *Context {
90 ctx := NewContext()
91 ctx.RegisterModuleType("visit_module", newVisitModule)
92 ctx.RegisterBottomUpMutator("visit_deps", visitDepsMutator)
93 ctx.RegisterTopDownMutator("visit", visitMutator)
94
95 ctx.MockFileSystem(map[string][]byte{
96 "Blueprints": []byte(`
97 visit_module {
98 name: "A",
99 visit: ["B"],
100 }
101
102 visit_module {
103 name: "B",
104 visit: ["C", "D"],
105 }
106
107 visit_module {
108 name: "C",
109 visit: ["D"],
110 }
111
112 visit_module {
113 name: "D",
114 visit: ["E"],
115 }
116
117 visit_module {
118 name: "E",
Colin Cross9607a9f2018-06-20 11:16:37 -0700119 visit: ["F", "F"],
120 }
121
122 visit_module {
123 name: "F",
Colin Cross365bc6b2016-08-08 11:21:09 -0700124 }
125 `),
126 })
127
128 _, errs := ctx.ParseBlueprintsFiles("Blueprints")
129 if len(errs) > 0 {
130 t.Errorf("unexpected parse errors:")
131 for _, err := range errs {
132 t.Errorf(" %s", err)
133 }
134 t.FailNow()
135 }
136
Colin Cross874a3462017-07-31 17:26:06 -0700137 _, errs = ctx.ResolveDependencies(nil)
Colin Cross365bc6b2016-08-08 11:21:09 -0700138 if len(errs) > 0 {
139 t.Errorf("unexpected dep errors:")
140 for _, err := range errs {
141 t.Errorf(" %s", err)
142 }
143 t.FailNow()
144 }
145
146 return ctx
147}
148
149func TestVisit(t *testing.T) {
150 ctx := setupVisitTest(t)
151
Jeff Gastond70bf752017-11-10 15:12:08 -0800152 topModule := ctx.modulesFromName("A", nil)[0].logicModule.(*visitModule)
Colin Cross9607a9f2018-06-20 11:16:37 -0700153 assertString(t, topModule.properties.VisitDepsDepthFirst, "FEDCB")
154 assertString(t, topModule.properties.VisitDepsDepthFirstIf, "FEDC")
Colin Cross365bc6b2016-08-08 11:21:09 -0700155 assertString(t, topModule.properties.VisitDirectDeps, "B")
156 assertString(t, topModule.properties.VisitDirectDepsIf, "")
Colin Cross9607a9f2018-06-20 11:16:37 -0700157
158 eModule := ctx.modulesFromName("E", nil)[0].logicModule.(*visitModule)
159 assertString(t, eModule.properties.VisitDepsDepthFirst, "F")
160 assertString(t, eModule.properties.VisitDepsDepthFirstIf, "F")
161 assertString(t, eModule.properties.VisitDirectDeps, "FF")
162 assertString(t, eModule.properties.VisitDirectDepsIf, "FF")
Colin Cross365bc6b2016-08-08 11:21:09 -0700163}
164
165func assertString(t *testing.T, got, expected string) {
166 if got != expected {
167 t.Errorf("expected %q got %q", expected, got)
168 }
169}