2016-08-08 20:21:09 +02:00
|
|
|
// Copyright 2016 Google Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package blueprint
|
|
|
|
|
2016-08-07 07:52:01 +02:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
)
|
2016-08-08 20:21:09 +02:00
|
|
|
|
|
|
|
type visitModule struct {
|
2016-05-17 23:58:05 +02:00
|
|
|
SimpleName
|
2016-08-08 20:21:09 +02:00
|
|
|
properties struct {
|
|
|
|
Visit []string
|
|
|
|
VisitDepsDepthFirst string `blueprint:"mutated"`
|
|
|
|
VisitDepsDepthFirstIf string `blueprint:"mutated"`
|
|
|
|
VisitDirectDeps string `blueprint:"mutated"`
|
|
|
|
VisitDirectDepsIf string `blueprint:"mutated"`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func newVisitModule() (Module, []interface{}) {
|
|
|
|
m := &visitModule{}
|
2016-05-17 23:58:05 +02:00
|
|
|
return m, []interface{}{&m.properties, &m.SimpleName.Properties}
|
2016-08-08 20:21:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *visitModule) GenerateBuildActions(ModuleContext) {
|
|
|
|
}
|
|
|
|
|
|
|
|
type visitTag struct {
|
|
|
|
BaseDependencyTag
|
|
|
|
}
|
|
|
|
|
|
|
|
var visitTagDep visitTag
|
|
|
|
|
|
|
|
func visitDepsMutator(ctx BottomUpMutatorContext) {
|
|
|
|
if m, ok := ctx.Module().(*visitModule); ok {
|
|
|
|
ctx.AddDependency(ctx.Module(), visitTagDep, m.properties.Visit...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func visitMutator(ctx TopDownMutatorContext) {
|
|
|
|
if m, ok := ctx.Module().(*visitModule); ok {
|
|
|
|
ctx.VisitDepsDepthFirst(func(dep Module) {
|
2016-08-07 07:52:01 +02:00
|
|
|
if ctx.OtherModuleDependencyTag(dep) != visitTagDep {
|
|
|
|
panic(fmt.Errorf("unexpected dependency tag on %q", ctx.OtherModuleName(dep)))
|
|
|
|
}
|
2016-08-08 20:21:09 +02:00
|
|
|
m.properties.VisitDepsDepthFirst = m.properties.VisitDepsDepthFirst + ctx.OtherModuleName(dep)
|
|
|
|
})
|
|
|
|
ctx.VisitDepsDepthFirstIf(func(dep Module) bool {
|
|
|
|
return ctx.OtherModuleName(dep) != "B"
|
|
|
|
}, func(dep Module) {
|
|
|
|
m.properties.VisitDepsDepthFirstIf = m.properties.VisitDepsDepthFirstIf + ctx.OtherModuleName(dep)
|
|
|
|
})
|
|
|
|
ctx.VisitDirectDeps(func(dep Module) {
|
|
|
|
m.properties.VisitDirectDeps = m.properties.VisitDirectDeps + ctx.OtherModuleName(dep)
|
|
|
|
})
|
|
|
|
ctx.VisitDirectDepsIf(func(dep Module) bool {
|
|
|
|
return ctx.OtherModuleName(dep) != "B"
|
|
|
|
}, func(dep Module) {
|
|
|
|
m.properties.VisitDirectDepsIf = m.properties.VisitDirectDepsIf + ctx.OtherModuleName(dep)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// A
|
|
|
|
// |
|
|
|
|
// B
|
|
|
|
// |\
|
|
|
|
// C \
|
|
|
|
// \|
|
|
|
|
// D
|
|
|
|
// |
|
|
|
|
// E
|
|
|
|
func setupVisitTest(t *testing.T) *Context {
|
|
|
|
ctx := NewContext()
|
|
|
|
ctx.RegisterModuleType("visit_module", newVisitModule)
|
|
|
|
ctx.RegisterBottomUpMutator("visit_deps", visitDepsMutator)
|
|
|
|
ctx.RegisterTopDownMutator("visit", visitMutator)
|
|
|
|
|
|
|
|
ctx.MockFileSystem(map[string][]byte{
|
|
|
|
"Blueprints": []byte(`
|
|
|
|
visit_module {
|
|
|
|
name: "A",
|
|
|
|
visit: ["B"],
|
|
|
|
}
|
|
|
|
|
|
|
|
visit_module {
|
|
|
|
name: "B",
|
|
|
|
visit: ["C", "D"],
|
|
|
|
}
|
|
|
|
|
|
|
|
visit_module {
|
|
|
|
name: "C",
|
|
|
|
visit: ["D"],
|
|
|
|
}
|
|
|
|
|
|
|
|
visit_module {
|
|
|
|
name: "D",
|
|
|
|
visit: ["E"],
|
|
|
|
}
|
|
|
|
|
|
|
|
visit_module {
|
|
|
|
name: "E",
|
|
|
|
}
|
|
|
|
`),
|
|
|
|
})
|
|
|
|
|
|
|
|
_, errs := ctx.ParseBlueprintsFiles("Blueprints")
|
|
|
|
if len(errs) > 0 {
|
|
|
|
t.Errorf("unexpected parse errors:")
|
|
|
|
for _, err := range errs {
|
|
|
|
t.Errorf(" %s", err)
|
|
|
|
}
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
|
2017-08-01 02:26:06 +02:00
|
|
|
_, errs = ctx.ResolveDependencies(nil)
|
2016-08-08 20:21:09 +02:00
|
|
|
if len(errs) > 0 {
|
|
|
|
t.Errorf("unexpected dep errors:")
|
|
|
|
for _, err := range errs {
|
|
|
|
t.Errorf(" %s", err)
|
|
|
|
}
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestVisit(t *testing.T) {
|
|
|
|
ctx := setupVisitTest(t)
|
|
|
|
|
2017-11-11 00:12:08 +01:00
|
|
|
topModule := ctx.modulesFromName("A", nil)[0].logicModule.(*visitModule)
|
2016-08-08 20:21:09 +02:00
|
|
|
assertString(t, topModule.properties.VisitDepsDepthFirst, "EDCB")
|
|
|
|
assertString(t, topModule.properties.VisitDepsDepthFirstIf, "EDC")
|
|
|
|
assertString(t, topModule.properties.VisitDirectDeps, "B")
|
|
|
|
assertString(t, topModule.properties.VisitDirectDepsIf, "")
|
|
|
|
}
|
|
|
|
|
|
|
|
func assertString(t *testing.T, got, expected string) {
|
|
|
|
if got != expected {
|
|
|
|
t.Errorf("expected %q got %q", expected, got)
|
|
|
|
}
|
|
|
|
}
|