xref: /aosp_15_r20/build/blueprint/visit_test.go (revision 1fa6dee971e1612fa5cc0aa5ca2d35a22e2c34a3)
1*1fa6dee9SAndroid Build Coastguard Worker// Copyright 2016 Google Inc. All rights reserved.
2*1fa6dee9SAndroid Build Coastguard Worker//
3*1fa6dee9SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*1fa6dee9SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*1fa6dee9SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*1fa6dee9SAndroid Build Coastguard Worker//
7*1fa6dee9SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*1fa6dee9SAndroid Build Coastguard Worker//
9*1fa6dee9SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*1fa6dee9SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*1fa6dee9SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*1fa6dee9SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*1fa6dee9SAndroid Build Coastguard Worker// limitations under the License.
14*1fa6dee9SAndroid Build Coastguard Worker
15*1fa6dee9SAndroid Build Coastguard Workerpackage blueprint
16*1fa6dee9SAndroid Build Coastguard Worker
17*1fa6dee9SAndroid Build Coastguard Workerimport (
18*1fa6dee9SAndroid Build Coastguard Worker	"fmt"
19*1fa6dee9SAndroid Build Coastguard Worker	"testing"
20*1fa6dee9SAndroid Build Coastguard Worker)
21*1fa6dee9SAndroid Build Coastguard Worker
22*1fa6dee9SAndroid Build Coastguard Workertype visitModule struct {
23*1fa6dee9SAndroid Build Coastguard Worker	SimpleName
24*1fa6dee9SAndroid Build Coastguard Worker	properties struct {
25*1fa6dee9SAndroid Build Coastguard Worker		Visit                 []string
26*1fa6dee9SAndroid Build Coastguard Worker		VisitDepsDepthFirst   string `blueprint:"mutated"`
27*1fa6dee9SAndroid Build Coastguard Worker		VisitDepsDepthFirstIf string `blueprint:"mutated"`
28*1fa6dee9SAndroid Build Coastguard Worker		VisitDirectDeps       string `blueprint:"mutated"`
29*1fa6dee9SAndroid Build Coastguard Worker		VisitDirectDepsIf     string `blueprint:"mutated"`
30*1fa6dee9SAndroid Build Coastguard Worker	}
31*1fa6dee9SAndroid Build Coastguard Worker}
32*1fa6dee9SAndroid Build Coastguard Worker
33*1fa6dee9SAndroid Build Coastguard Workerfunc newVisitModule() (Module, []interface{}) {
34*1fa6dee9SAndroid Build Coastguard Worker	m := &visitModule{}
35*1fa6dee9SAndroid Build Coastguard Worker	return m, []interface{}{&m.properties, &m.SimpleName.Properties}
36*1fa6dee9SAndroid Build Coastguard Worker}
37*1fa6dee9SAndroid Build Coastguard Worker
38*1fa6dee9SAndroid Build Coastguard Workerfunc (f *visitModule) GenerateBuildActions(ModuleContext) {
39*1fa6dee9SAndroid Build Coastguard Worker}
40*1fa6dee9SAndroid Build Coastguard Worker
41*1fa6dee9SAndroid Build Coastguard Workertype visitTag struct {
42*1fa6dee9SAndroid Build Coastguard Worker	BaseDependencyTag
43*1fa6dee9SAndroid Build Coastguard Worker}
44*1fa6dee9SAndroid Build Coastguard Worker
45*1fa6dee9SAndroid Build Coastguard Workervar visitTagDep visitTag
46*1fa6dee9SAndroid Build Coastguard Worker
47*1fa6dee9SAndroid Build Coastguard Workerfunc visitDepsMutator(ctx BottomUpMutatorContext) {
48*1fa6dee9SAndroid Build Coastguard Worker	if m, ok := ctx.Module().(*visitModule); ok {
49*1fa6dee9SAndroid Build Coastguard Worker		ctx.AddDependency(ctx.Module(), visitTagDep, m.properties.Visit...)
50*1fa6dee9SAndroid Build Coastguard Worker	}
51*1fa6dee9SAndroid Build Coastguard Worker}
52*1fa6dee9SAndroid Build Coastguard Worker
53*1fa6dee9SAndroid Build Coastguard Workerfunc visitMutator(ctx TopDownMutatorContext) {
54*1fa6dee9SAndroid Build Coastguard Worker	if m, ok := ctx.Module().(*visitModule); ok {
55*1fa6dee9SAndroid Build Coastguard Worker		ctx.VisitDepsDepthFirst(func(dep Module) {
56*1fa6dee9SAndroid Build Coastguard Worker			if ctx.OtherModuleDependencyTag(dep) != visitTagDep {
57*1fa6dee9SAndroid Build Coastguard Worker				panic(fmt.Errorf("unexpected dependency tag on %q", ctx.OtherModuleName(dep)))
58*1fa6dee9SAndroid Build Coastguard Worker			}
59*1fa6dee9SAndroid Build Coastguard Worker			m.properties.VisitDepsDepthFirst = m.properties.VisitDepsDepthFirst + ctx.OtherModuleName(dep)
60*1fa6dee9SAndroid Build Coastguard Worker		})
61*1fa6dee9SAndroid Build Coastguard Worker		ctx.VisitDepsDepthFirstIf(func(dep Module) bool {
62*1fa6dee9SAndroid Build Coastguard Worker			return ctx.OtherModuleName(dep) != "B"
63*1fa6dee9SAndroid Build Coastguard Worker		}, func(dep Module) {
64*1fa6dee9SAndroid Build Coastguard Worker			m.properties.VisitDepsDepthFirstIf = m.properties.VisitDepsDepthFirstIf + ctx.OtherModuleName(dep)
65*1fa6dee9SAndroid Build Coastguard Worker		})
66*1fa6dee9SAndroid Build Coastguard Worker		ctx.VisitDirectDeps(func(dep Module) {
67*1fa6dee9SAndroid Build Coastguard Worker			m.properties.VisitDirectDeps = m.properties.VisitDirectDeps + ctx.OtherModuleName(dep)
68*1fa6dee9SAndroid Build Coastguard Worker		})
69*1fa6dee9SAndroid Build Coastguard Worker		ctx.VisitDirectDepsIf(func(dep Module) bool {
70*1fa6dee9SAndroid Build Coastguard Worker			return ctx.OtherModuleName(dep) != "B"
71*1fa6dee9SAndroid Build Coastguard Worker		}, func(dep Module) {
72*1fa6dee9SAndroid Build Coastguard Worker			m.properties.VisitDirectDepsIf = m.properties.VisitDirectDepsIf + ctx.OtherModuleName(dep)
73*1fa6dee9SAndroid Build Coastguard Worker		})
74*1fa6dee9SAndroid Build Coastguard Worker	}
75*1fa6dee9SAndroid Build Coastguard Worker}
76*1fa6dee9SAndroid Build Coastguard Worker
77*1fa6dee9SAndroid Build Coastguard Worker// > A
78*1fa6dee9SAndroid Build Coastguard Worker// > |
79*1fa6dee9SAndroid Build Coastguard Worker// > B
80*1fa6dee9SAndroid Build Coastguard Worker// > |\
81*1fa6dee9SAndroid Build Coastguard Worker// > C \
82*1fa6dee9SAndroid Build Coastguard Worker// >  \|
83*1fa6dee9SAndroid Build Coastguard Worker// >   D
84*1fa6dee9SAndroid Build Coastguard Worker// >   |
85*1fa6dee9SAndroid Build Coastguard Worker// >   E
86*1fa6dee9SAndroid Build Coastguard Worker// >  / \
87*1fa6dee9SAndroid Build Coastguard Worker// >  \ /
88*1fa6dee9SAndroid Build Coastguard Worker// >   F
89*1fa6dee9SAndroid Build Coastguard Workerfunc setupVisitTest(t *testing.T) *Context {
90*1fa6dee9SAndroid Build Coastguard Worker	ctx := NewContext()
91*1fa6dee9SAndroid Build Coastguard Worker	ctx.RegisterModuleType("visit_module", newVisitModule)
92*1fa6dee9SAndroid Build Coastguard Worker	ctx.RegisterBottomUpMutator("visit_deps", visitDepsMutator)
93*1fa6dee9SAndroid Build Coastguard Worker	ctx.RegisterTopDownMutator("visit", visitMutator)
94*1fa6dee9SAndroid Build Coastguard Worker
95*1fa6dee9SAndroid Build Coastguard Worker	ctx.MockFileSystem(map[string][]byte{
96*1fa6dee9SAndroid Build Coastguard Worker		"Android.bp": []byte(`
97*1fa6dee9SAndroid Build Coastguard Worker			visit_module {
98*1fa6dee9SAndroid Build Coastguard Worker				name: "A",
99*1fa6dee9SAndroid Build Coastguard Worker				visit: ["B"],
100*1fa6dee9SAndroid Build Coastguard Worker			}
101*1fa6dee9SAndroid Build Coastguard Worker
102*1fa6dee9SAndroid Build Coastguard Worker			visit_module {
103*1fa6dee9SAndroid Build Coastguard Worker				name: "B",
104*1fa6dee9SAndroid Build Coastguard Worker				visit: ["C", "D"],
105*1fa6dee9SAndroid Build Coastguard Worker			}
106*1fa6dee9SAndroid Build Coastguard Worker
107*1fa6dee9SAndroid Build Coastguard Worker			visit_module {
108*1fa6dee9SAndroid Build Coastguard Worker				name: "C",
109*1fa6dee9SAndroid Build Coastguard Worker				visit: ["D"],
110*1fa6dee9SAndroid Build Coastguard Worker			}
111*1fa6dee9SAndroid Build Coastguard Worker
112*1fa6dee9SAndroid Build Coastguard Worker			visit_module {
113*1fa6dee9SAndroid Build Coastguard Worker				name: "D",
114*1fa6dee9SAndroid Build Coastguard Worker				visit: ["E"],
115*1fa6dee9SAndroid Build Coastguard Worker			}
116*1fa6dee9SAndroid Build Coastguard Worker
117*1fa6dee9SAndroid Build Coastguard Worker			visit_module {
118*1fa6dee9SAndroid Build Coastguard Worker				name: "E",
119*1fa6dee9SAndroid Build Coastguard Worker				visit: ["F", "F"],
120*1fa6dee9SAndroid Build Coastguard Worker			}
121*1fa6dee9SAndroid Build Coastguard Worker
122*1fa6dee9SAndroid Build Coastguard Worker			visit_module {
123*1fa6dee9SAndroid Build Coastguard Worker				name: "F",
124*1fa6dee9SAndroid Build Coastguard Worker			}
125*1fa6dee9SAndroid Build Coastguard Worker		`),
126*1fa6dee9SAndroid Build Coastguard Worker	})
127*1fa6dee9SAndroid Build Coastguard Worker
128*1fa6dee9SAndroid Build Coastguard Worker	_, errs := ctx.ParseBlueprintsFiles("Android.bp", nil)
129*1fa6dee9SAndroid Build Coastguard Worker	if len(errs) > 0 {
130*1fa6dee9SAndroid Build Coastguard Worker		t.Errorf("unexpected parse errors:")
131*1fa6dee9SAndroid Build Coastguard Worker		for _, err := range errs {
132*1fa6dee9SAndroid Build Coastguard Worker			t.Errorf("  %s", err)
133*1fa6dee9SAndroid Build Coastguard Worker		}
134*1fa6dee9SAndroid Build Coastguard Worker		t.FailNow()
135*1fa6dee9SAndroid Build Coastguard Worker	}
136*1fa6dee9SAndroid Build Coastguard Worker
137*1fa6dee9SAndroid Build Coastguard Worker	_, errs = ctx.ResolveDependencies(nil)
138*1fa6dee9SAndroid Build Coastguard Worker	if len(errs) > 0 {
139*1fa6dee9SAndroid Build Coastguard Worker		t.Errorf("unexpected dep errors:")
140*1fa6dee9SAndroid Build Coastguard Worker		for _, err := range errs {
141*1fa6dee9SAndroid Build Coastguard Worker			t.Errorf("  %s", err)
142*1fa6dee9SAndroid Build Coastguard Worker		}
143*1fa6dee9SAndroid Build Coastguard Worker		t.FailNow()
144*1fa6dee9SAndroid Build Coastguard Worker	}
145*1fa6dee9SAndroid Build Coastguard Worker
146*1fa6dee9SAndroid Build Coastguard Worker	return ctx
147*1fa6dee9SAndroid Build Coastguard Worker}
148*1fa6dee9SAndroid Build Coastguard Worker
149*1fa6dee9SAndroid Build Coastguard Workerfunc TestVisit(t *testing.T) {
150*1fa6dee9SAndroid Build Coastguard Worker	ctx := setupVisitTest(t)
151*1fa6dee9SAndroid Build Coastguard Worker
152*1fa6dee9SAndroid Build Coastguard Worker	topModule := ctx.moduleGroupFromName("A", nil).modules.firstModule().logicModule.(*visitModule)
153*1fa6dee9SAndroid Build Coastguard Worker	assertString(t, topModule.properties.VisitDepsDepthFirst, "FEDCB")
154*1fa6dee9SAndroid Build Coastguard Worker	assertString(t, topModule.properties.VisitDepsDepthFirstIf, "FEDC")
155*1fa6dee9SAndroid Build Coastguard Worker	assertString(t, topModule.properties.VisitDirectDeps, "B")
156*1fa6dee9SAndroid Build Coastguard Worker	assertString(t, topModule.properties.VisitDirectDepsIf, "")
157*1fa6dee9SAndroid Build Coastguard Worker
158*1fa6dee9SAndroid Build Coastguard Worker	eModule := ctx.moduleGroupFromName("E", nil).modules.firstModule().logicModule.(*visitModule)
159*1fa6dee9SAndroid Build Coastguard Worker	assertString(t, eModule.properties.VisitDepsDepthFirst, "F")
160*1fa6dee9SAndroid Build Coastguard Worker	assertString(t, eModule.properties.VisitDepsDepthFirstIf, "F")
161*1fa6dee9SAndroid Build Coastguard Worker	assertString(t, eModule.properties.VisitDirectDeps, "FF")
162*1fa6dee9SAndroid Build Coastguard Worker	assertString(t, eModule.properties.VisitDirectDepsIf, "FF")
163*1fa6dee9SAndroid Build Coastguard Worker}
164*1fa6dee9SAndroid Build Coastguard Worker
165*1fa6dee9SAndroid Build Coastguard Workerfunc assertString(t *testing.T, got, expected string) {
166*1fa6dee9SAndroid Build Coastguard Worker	if got != expected {
167*1fa6dee9SAndroid Build Coastguard Worker		t.Errorf("expected %q got %q", expected, got)
168*1fa6dee9SAndroid Build Coastguard Worker	}
169*1fa6dee9SAndroid Build Coastguard Worker}
170