blob: 8c5b5bbce9efcd3f2bb27d392ce780a421430dd7 [file] [log] [blame]
Colin Cross8e0c5112015-01-23 14:15:10 -08001// Copyright 2014 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
Jamie Gennis1bc967e2014-05-27 16:34:41 -070015package blueprint
16
17import (
18 "bytes"
19 "testing"
20)
21
Yuchen Wuf9958462015-10-09 17:31:27 -070022type Walker interface {
23 Walk() bool
24}
25
Jamie Gennis1bc967e2014-05-27 16:34:41 -070026type fooModule struct {
27 properties struct {
28 Foo string
29 }
30}
31
Jamie Gennis68540da2014-10-06 09:10:40 -070032func newFooModule() (Module, []interface{}) {
Jamie Gennis1bc967e2014-05-27 16:34:41 -070033 m := &fooModule{}
Jamie Gennis68540da2014-10-06 09:10:40 -070034 return m, []interface{}{&m.properties}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070035}
36
37func (f *fooModule) GenerateBuildActions(ModuleContext) {
38}
39
40func (f *fooModule) Foo() string {
41 return f.properties.Foo
42}
43
Yuchen Wuf9958462015-10-09 17:31:27 -070044func (f *fooModule) Walk() bool {
45 return true
46}
47
Jamie Gennis1bc967e2014-05-27 16:34:41 -070048type barModule struct {
49 properties struct {
50 Bar bool
51 }
52}
53
Jamie Gennis68540da2014-10-06 09:10:40 -070054func newBarModule() (Module, []interface{}) {
Jamie Gennis1bc967e2014-05-27 16:34:41 -070055 m := &barModule{}
Jamie Gennis68540da2014-10-06 09:10:40 -070056 return m, []interface{}{&m.properties}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070057}
58
59func (b *barModule) GenerateBuildActions(ModuleContext) {
60}
61
62func (b *barModule) Bar() bool {
63 return b.properties.Bar
64}
65
Yuchen Wuf9958462015-10-09 17:31:27 -070066func (b *barModule) Walk() bool {
67 return false
68}
69
Jamie Gennis1bc967e2014-05-27 16:34:41 -070070func TestContextParse(t *testing.T) {
71 ctx := NewContext()
Jamie Gennis68540da2014-10-06 09:10:40 -070072 ctx.RegisterModuleType("foo_module", newFooModule)
73 ctx.RegisterModuleType("bar_module", newBarModule)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070074
75 r := bytes.NewBufferString(`
76 foo_module {
77 name: "MyFooModule",
78 deps: ["MyBarModule"],
79 }
80
81 bar_module {
82 name: "MyBarModule",
83 }
84 `)
85
Colin Cross1fef5362015-04-20 16:50:54 -070086 _, _, _, errs := ctx.parse(".", "Blueprint", r, nil)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070087 if len(errs) > 0 {
88 t.Errorf("unexpected parse errors:")
89 for _, err := range errs {
90 t.Errorf(" %s", err)
91 }
92 t.FailNow()
93 }
94
Colin Cross763b6f12015-10-29 15:32:56 -070095 errs = ctx.ResolveDependencies(nil)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070096 if len(errs) > 0 {
97 t.Errorf("unexpected dep errors:")
98 for _, err := range errs {
99 t.Errorf(" %s", err)
100 }
101 t.FailNow()
102 }
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700103}
Yuchen Wuf9958462015-10-09 17:31:27 -0700104
105// |---B===D - represents a non-walkable edge
106// A = represents a walkable edge
107// |===C---E===G
108// | | A should not be visited because it's the root node.
109// |===F===| B, D and E should not be walked.
110func TestWalkDeps(t *testing.T) {
111 ctx := NewContext()
Colin Crossd7b0f602016-06-02 15:30:20 -0700112 ctx.MockFileSystem(map[string][]byte{
113 "Blueprints": []byte(`
114 foo_module {
115 name: "A",
116 deps: ["B", "C"],
117 }
118
119 bar_module {
120 name: "B",
121 deps: ["D"],
122 }
123
124 foo_module {
125 name: "C",
126 deps: ["E", "F"],
127 }
128
129 foo_module {
130 name: "D",
131 }
132
133 bar_module {
134 name: "E",
135 deps: ["G"],
136 }
137
138 foo_module {
139 name: "F",
140 deps: ["G"],
141 }
142
143 foo_module {
144 name: "G",
145 }
146 `),
147 })
148
Yuchen Wuf9958462015-10-09 17:31:27 -0700149 ctx.RegisterModuleType("foo_module", newFooModule)
150 ctx.RegisterModuleType("bar_module", newBarModule)
Colin Crossd7b0f602016-06-02 15:30:20 -0700151 _, errs := ctx.ParseBlueprintsFiles("Blueprints")
152 if len(errs) > 0 {
153 t.Errorf("unexpected parse errors:")
154 for _, err := range errs {
155 t.Errorf(" %s", err)
156 }
157 t.FailNow()
158 }
159
160 errs = ctx.ResolveDependencies(nil)
161 if len(errs) > 0 {
162 t.Errorf("unexpected dep errors:")
163 for _, err := range errs {
164 t.Errorf(" %s", err)
165 }
166 t.FailNow()
167 }
Yuchen Wuf9958462015-10-09 17:31:27 -0700168
169 var output string
170 topModule := ctx.moduleGroups["A"].modules[0]
171 ctx.walkDeps(topModule,
172 func(module, parent Module) bool {
173 if module.(Walker).Walk() {
174 output += ctx.ModuleName(module)
175 return true
176 }
177 return false
178 })
179 if output != "CFG" {
180 t.Fatalf("unexpected walkDeps behaviour: %s\nshould be: CFG", output)
181 }
182}