Use a minimal set of mutators, module types, and singletons for tests

Calling android.NewContext() in tests results in a context that
contains all the mutators, module types, and singletons, which
causes unexpected interactions in unit tests.  Create an empty
context instead, and add in only the necessary mutators, module
types, and singletons.

Bug: 36366816
Test: soong tests
Change-Id: Ic61262c37e3436b3ad4ccaca18b737021c304be6
This commit is contained in:
Colin Cross 2017-03-16 16:50:10 -07:00
parent 4c48f724e1
commit 795c377e14
4 changed files with 74 additions and 49 deletions

View File

@ -14,7 +14,11 @@
package android
import "github.com/google/blueprint"
import (
"sync"
"github.com/google/blueprint"
)
// Mutator phases:
// Pre-arch
@ -23,36 +27,68 @@ import "github.com/google/blueprint"
// Deps
// PostDeps
func registerMutators() {
ctx := registerMutatorsContext{}
var registerMutatorsOnce sync.Once
var registeredMutators []*mutator
register := func(funcs []RegisterMutatorFunc) {
for _, f := range funcs {
f(ctx)
func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
for _, t := range mutators {
var handle blueprint.MutatorHandle
if t.bottomUpMutator != nil {
handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
} else if t.topDownMutator != nil {
handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
}
if t.parallel {
handle.Parallel()
}
}
ctx.TopDown("load_hooks", loadHookMutator).Parallel()
ctx.BottomUp("prebuilts", prebuiltMutator).Parallel()
ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
ctx.TopDown("defaults", defaultsMutator).Parallel()
register(preArch)
ctx.BottomUp("arch", archMutator).Parallel()
ctx.TopDown("arch_hooks", archHookMutator).Parallel()
register(preDeps)
ctx.BottomUp("deps", depsMutator).Parallel()
ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
register(postDeps)
}
type registerMutatorsContext struct{}
func registerMutators(ctx *blueprint.Context) {
registerMutatorsOnce.Do(func() {
ctx := &registerMutatorsContext{}
register := func(funcs []RegisterMutatorFunc) {
for _, f := range funcs {
f(ctx)
}
}
ctx.TopDown("load_hooks", loadHookMutator).Parallel()
ctx.BottomUp("prebuilts", prebuiltMutator).Parallel()
ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
ctx.TopDown("defaults", defaultsMutator).Parallel()
register(preArch)
ctx.BottomUp("arch", archMutator).Parallel()
ctx.TopDown("arch_hooks", archHookMutator).Parallel()
register(preDeps)
ctx.BottomUp("deps", depsMutator).Parallel()
ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
register(postDeps)
registeredMutators = ctx.mutators
})
registerMutatorsToContext(ctx, registeredMutators)
}
func RegisterTestMutators(ctx *blueprint.Context) {
mutators := registerMutatorsContext{}
mutators.BottomUp("deps", depsMutator).Parallel()
registerMutatorsToContext(ctx, mutators.mutators)
}
type registerMutatorsContext struct {
mutators []*mutator
}
type RegisterMutatorsContext interface {
TopDown(name string, m AndroidTopDownMutator) MutatorHandle
@ -99,7 +135,7 @@ type androidBottomUpMutatorContext struct {
androidBaseContextImpl
}
func (registerMutatorsContext) BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle {
func (x *registerMutatorsContext) BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle {
f := func(ctx blueprint.BottomUpMutatorContext) {
if a, ok := ctx.Module().(Module); ok {
actx := &androidBottomUpMutatorContext{
@ -110,11 +146,11 @@ func (registerMutatorsContext) BottomUp(name string, m AndroidBottomUpMutator) M
}
}
mutator := &mutator{name: name, bottomUpMutator: f}
mutators = append(mutators, mutator)
x.mutators = append(x.mutators, mutator)
return mutator
}
func (registerMutatorsContext) TopDown(name string, m AndroidTopDownMutator) MutatorHandle {
func (x *registerMutatorsContext) TopDown(name string, m AndroidTopDownMutator) MutatorHandle {
f := func(ctx blueprint.TopDownMutatorContext) {
if a, ok := ctx.Module().(Module); ok {
actx := &androidTopDownMutatorContext{
@ -125,7 +161,7 @@ func (registerMutatorsContext) TopDown(name string, m AndroidTopDownMutator) Mut
}
}
mutator := &mutator{name: name, topDownMutator: f}
mutators = append(mutators, mutator)
x.mutators = append(x.mutators, mutator)
return mutator
}

View File

@ -15,8 +15,6 @@
package android
import (
"sync"
"github.com/google/blueprint"
)
@ -51,8 +49,6 @@ func RegisterSingletonType(name string, factory blueprint.SingletonFactory) {
singletons = append(singletons, singleton{name, factory})
}
var registerMutatorsOnce sync.Once
func NewContext() *blueprint.Context {
ctx := blueprint.NewContext()
@ -64,19 +60,8 @@ func NewContext() *blueprint.Context {
ctx.RegisterSingletonType(t.name, t.factory)
}
registerMutatorsOnce.Do(registerMutators)
registerMutators(ctx)
for _, t := range mutators {
var handle blueprint.MutatorHandle
if t.bottomUpMutator != nil {
handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
} else if t.topDownMutator != nil {
handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
}
if t.parallel {
handle.Parallel()
}
}
ctx.RegisterSingletonType("env", EnvSingleton)
return ctx

View File

@ -22,6 +22,8 @@ import (
"testing"
"android/soong/android"
"android/soong/genrule"
"github.com/google/blueprint"
)
@ -121,13 +123,15 @@ func TestDataTests(t *testing.T) {
for _, test := range testDataTests {
t.Run(test.name, func(t *testing.T) {
ctx := android.NewContext()
ctx := blueprint.NewContext()
android.RegisterTestMutators(ctx)
ctx.MockFileSystem(map[string][]byte{
"Blueprints": []byte(`subdirs = ["dir"]`),
"dir/Blueprints": []byte(test.modules),
"dir/baz": nil,
"dir/bar/baz": nil,
})
ctx.RegisterModuleType("filegroup", genrule.FileGroupFactory)
ctx.RegisterModuleType("test", newTest)
_, errs := ctx.ParseBlueprintsFiles("Blueprints")

View File

@ -21,7 +21,7 @@ import (
)
func init() {
android.RegisterModuleType("filegroup", fileGroupFactory)
android.RegisterModuleType("filegroup", FileGroupFactory)
}
type fileGroupProperties struct {
@ -48,7 +48,7 @@ var _ android.SourceFileProducer = (*fileGroup)(nil)
// filegroup modules contain a list of files, and can be used to export files across package
// boundaries. filegroups (and genrules) can be referenced from srcs properties of other modules
// using the syntax ":module".
func fileGroupFactory() (blueprint.Module, []interface{}) {
func FileGroupFactory() (blueprint.Module, []interface{}) {
module := &fileGroup{}
return android.InitAndroidModule(module, &module.properties)