platform_build_blueprint/module_ctx_test.go
Colin Cross f7beb89df5 Add support for module variant aliases
Adding a dependency on a module with variants can be problematic
if the code adding the dependency is not aware of every mutator
that has created variants.  Add an AliasVariations to
BottomUpMutatorContext, which allows a mutator to alias the
original variant of a module to one of the new variants of the
module, which will allow future dependencies to be added using
the original list of variations.  The aliases are transient,
and only exist until the next mutator that calls CreateVariations
when visiting the module without also calling AliasVariations.

Test: TestAlises
Change-Id: Ieaa04b5a6bdcb5a1ff5114b1e03460de795d4479
2019-11-14 12:58:52 -08:00

197 lines
5.9 KiB
Go

// Copyright 2019 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
import (
"reflect"
"strings"
"testing"
)
type moduleCtxTestModule struct {
SimpleName
}
func newModuleCtxTestModule() (Module, []interface{}) {
m := &moduleCtxTestModule{}
return m, []interface{}{&m.SimpleName.Properties}
}
func (f *moduleCtxTestModule) GenerateBuildActions(ModuleContext) {
}
func noCreateAliasMutator(name string) func(ctx BottomUpMutatorContext) {
return func(ctx BottomUpMutatorContext) {
if ctx.ModuleName() == name {
ctx.CreateVariations("a", "b")
}
}
}
func createAliasMutator(name string) func(ctx BottomUpMutatorContext) {
return func(ctx BottomUpMutatorContext) {
if ctx.ModuleName() == name {
ctx.CreateVariations("a", "b")
ctx.AliasVariation("b")
}
}
}
func addVariantDepsMutator(variants []Variation, tag DependencyTag, from, to string) func(ctx BottomUpMutatorContext) {
return func(ctx BottomUpMutatorContext) {
if ctx.ModuleName() == from {
ctx.AddVariationDependencies(variants, tag, to)
}
}
}
func TestAliases(t *testing.T) {
runWithFailures := func(ctx *Context, expectedErr string) {
t.Helper()
bp := `
test {
name: "foo",
}
test {
name: "bar",
}
`
mockFS := map[string][]byte{
"Blueprints": []byte(bp),
}
ctx.MockFileSystem(mockFS)
_, errs := ctx.ParseFileList(".", []string{"Blueprints"})
if len(errs) > 0 {
t.Errorf("unexpected parse errors:")
for _, err := range errs {
t.Errorf(" %s", err)
}
}
_, errs = ctx.ResolveDependencies(nil)
if len(errs) > 0 {
if expectedErr == "" {
t.Errorf("unexpected dep errors:")
for _, err := range errs {
t.Errorf(" %s", err)
}
} else {
for _, err := range errs {
if strings.Contains(err.Error(), expectedErr) {
continue
} else {
t.Errorf("unexpected dep error: %s", err)
}
}
}
} else if expectedErr != "" {
t.Errorf("missing dep error: %s", expectedErr)
}
}
run := func(ctx *Context) {
t.Helper()
runWithFailures(ctx, "")
}
t.Run("simple", func(t *testing.T) {
// Creates a module "bar" with variants "a" and "b" and alias "" -> "b".
// Tests a dependency from "foo" to "bar" variant "b" through alias "".
ctx := NewContext()
ctx.RegisterModuleType("test", newModuleCtxTestModule)
ctx.RegisterBottomUpMutator("1", createAliasMutator("bar"))
ctx.RegisterBottomUpMutator("2", addVariantDepsMutator(nil, nil, "foo", "bar"))
run(ctx)
foo := ctx.moduleGroupFromName("foo", nil).modules[0]
barB := ctx.moduleGroupFromName("bar", nil).modules[1]
if g, w := barB.variantName, "b"; g != w {
t.Fatalf("expected bar.modules[1] variant to be %q, got %q", w, g)
}
if g, w := foo.forwardDeps, []*moduleInfo{barB}; !reflect.DeepEqual(g, w) {
t.Fatalf("expected foo deps to be %q, got %q", w, g)
}
})
t.Run("chained", func(t *testing.T) {
// Creates a module "bar" with variants "a_a", "a_b", "b_a" and "b_b" and aliases "" -> "b_b",
// "a" -> "a_b", and "b" -> "b_b".
// Tests a dependency from "foo" to "bar" variant "b_b" through alias "".
ctx := NewContext()
ctx.RegisterModuleType("test", newModuleCtxTestModule)
ctx.RegisterBottomUpMutator("1", createAliasMutator("bar"))
ctx.RegisterBottomUpMutator("2", createAliasMutator("bar"))
ctx.RegisterBottomUpMutator("3", addVariantDepsMutator(nil, nil, "foo", "bar"))
run(ctx)
foo := ctx.moduleGroupFromName("foo", nil).modules[0]
barBB := ctx.moduleGroupFromName("bar", nil).modules[3]
if g, w := barBB.variantName, "b_b"; g != w {
t.Fatalf("expected bar.modules[3] variant to be %q, got %q", w, g)
}
if g, w := foo.forwardDeps, []*moduleInfo{barBB}; !reflect.DeepEqual(g, w) {
t.Fatalf("expected foo deps to be %q, got %q", w, g)
}
})
t.Run("chained2", func(t *testing.T) {
// Creates a module "bar" with variants "a_a", "a_b", "b_a" and "b_b" and aliases "" -> "b_b",
// "a" -> "a_b", and "b" -> "b_b".
// Tests a dependency from "foo" to "bar" variant "a_b" through alias "a".
ctx := NewContext()
ctx.RegisterModuleType("test", newModuleCtxTestModule)
ctx.RegisterBottomUpMutator("1", createAliasMutator("bar"))
ctx.RegisterBottomUpMutator("2", createAliasMutator("bar"))
ctx.RegisterBottomUpMutator("3", addVariantDepsMutator([]Variation{{"1", "a"}}, nil, "foo", "bar"))
run(ctx)
foo := ctx.moduleGroupFromName("foo", nil).modules[0]
barAB := ctx.moduleGroupFromName("bar", nil).modules[1]
if g, w := barAB.variantName, "a_b"; g != w {
t.Fatalf("expected bar.modules[1] variant to be %q, got %q", w, g)
}
if g, w := foo.forwardDeps, []*moduleInfo{barAB}; !reflect.DeepEqual(g, w) {
t.Fatalf("expected foo deps to be %q, got %q", w, g)
}
})
t.Run("removed dangling alias", func(t *testing.T) {
// Creates a module "bar" with variants "a" and "b" and aliases "" -> "b", then splits the variants into
// "a_a", "a_b", "b_a" and "b_b" without creating new aliases.
// Tests a dependency from "foo" to removed "bar" alias "" fails.
ctx := NewContext()
ctx.RegisterModuleType("test", newModuleCtxTestModule)
ctx.RegisterBottomUpMutator("1", createAliasMutator("bar"))
ctx.RegisterBottomUpMutator("2", noCreateAliasMutator("bar"))
ctx.RegisterBottomUpMutator("3", addVariantDepsMutator(nil, nil, "foo", "bar"))
runWithFailures(ctx, `dependency "bar" of "foo" missing variant:`+"\n \n"+
"available variants:"+
"\n 1:a, 2:a\n 1:a, 2:b\n 1:b, 2:a\n 1:b, 2:b")
})
}