Quelle provider_test.go
Sprache: unbekannt
|
|
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
// Copyright 2020 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 (
"bytes"
"fmt"
"reflect"
"strings"
"testing"
"github.com/google/blueprint/gobtools"
)
type providerTestModule struct {
ModuleBase
SimpleName
properties struct {
Deps []string
}
mutatorProviderValues []string
generateBuildActionsProviderValues []string
}
func newProviderTestModule() (Module, []interface{}) {
m := &providerTestModule{}
return m, []interface{}{&m.properties, &m.SimpleName.Properties}
}
var providerTestSingletonProvider = NewSingletonProvider[bool]()
type providerTestParallelSingleton struct {
visitAllSingletons bool
}
func (s *providerTestParallelSingleton) GenerateBuildActions(ctx SingletonContext) {
if s.visitAllSingletons {
ctx.VisitAllSingletons(func(s SingletonProxy) {})
}
ctx.SetSingletonProvider(providerTestSingletonProvider, true)
}
func (s *providerTestParallelSingleton) IncrementalSupported() bool {
return true
}
type providerTestSequentialSingleton struct {
getModuleProvider bool
setModuleProvider bool
}
func (s *providerTestSequentialSingleton) GenerateBuildActions(ctx SingletonContext) {
if s.getModuleProvider {
ctx.VisitAllSingletons(func(s SingletonProxy) {
ctx.OtherSingletonProvider(s, providerTestMutatorInfoProvider)
})
}
if s.setModuleProvider {
ctx.SetSingletonProvider(providerTestMutatorInfoProvider, nil)
}
ctx.VisitAllSingletons(func(s SingletonProxy) {
ctx.OtherSingletonProvider(s, providerTestSingletonProvider)
})
}
func (s *providerTestSequentialSingleton) IncrementalSupported() bool {
return true
}
type providerTestMutatorInfo struct {
Values []string
}
type providerTestGenerateBuildActionsInfo struct {
Value string
}
func (providerTestGenerateBuildActionsInfo) Encode(ctx gobtools.EncContext, buf *bytes.Buffer) error {
return nil
}
func (providerTestGenerateBuildActionsInfo) GetTypeId() int16 {
return -1
}
type providerTestUnsetInfo string
var providerTestMutatorInfoProvider = NewMutatorProvider[*providerTestMutatorInfo]("provider_mutator")
var providerTestGenerateBuildActionsInfoProvider = NewProvider[*providerTestGenerateBuildActionsInfo]()
var providerTestUnsetInfoProvider = NewMutatorProvider[providerTestUnsetInfo]("provider_mutator")
var providerTestUnusedMutatorProvider = NewMutatorProvider[*struct{ unused string }]("nonexistent_mutator")
func (p *providerTestModule) GenerateBuildActions(ctx ModuleContext) {
unset, ok := ModuleProvider(ctx, providerTestUnsetInfoProvider)
if ok {
panic(fmt.Errorf("expected false return value for providerTestGenerateBuildActionsInfoProvider before it was set"))
}
if unset != "" {
panic(fmt.Errorf("expected zero value for providerTestGenerateBuildActionsInfoProvider before it was set, got %q",
unset))
}
// Verify reading providerTestUnusedMutatorProvider doesn't panic
_, _ = ModuleProvider(ctx, providerTestUnusedMutatorProvider)
SetProvider(ctx, providerTestGenerateBuildActionsInfoProvider, &providerTestGenerateBuildActionsInfo{
Value: ctx.ModuleName(),
})
mp, ok := ModuleProvider(ctx, providerTestMutatorInfoProvider)
if ok {
p.mutatorProviderValues = mp.Values
}
ctx.VisitDirectDeps(func(module Module) {
gbap, _ := OtherModuleProvider(ctx, module, providerTestGenerateBuildActionsInfoProvider)
if gbap != nil {
p.generateBuildActionsProviderValues = append(p.generateBuildActionsProviderValues, gbap.Value)
}
})
}
func providerTestDepsMutator(ctx BottomUpMutatorContext) {
if p, ok := ctx.Module().(*providerTestModule); ok {
ctx.AddDependency(ctx.Module(), nil, p.properties.Deps...)
}
}
func providerTestMutator(ctx BottomUpMutatorContext) {
values := []string{strings.ToLower(ctx.ModuleName())}
ctx.VisitDirectDeps(func(module Module) {
mp, _ := OtherModuleProvider(ctx, module, providerTestMutatorInfoProvider)
if mp != nil {
values = append(values, mp.Values...)
}
})
SetProvider(ctx, providerTestMutatorInfoProvider, &providerTestMutatorInfo{
Values: values,
})
}
func providerTestAfterMutator(ctx BottomUpMutatorContext) {
// Verify reading providerTestUnusedMutatorProvider doesn't panic
_, _ = ModuleProvider(ctx, providerTestMutatorInfoProvider)
}
func TestProviders(t *testing.T) {
ctx := NewContext()
ctx.RegisterModuleType("provider_module", newProviderTestModule)
ctx.RegisterBottomUpMutator("provider_deps_mutator", providerTestDepsMutator)
ctx.RegisterBottomUpMutator("provider_mutator", providerTestMutator)
ctx.RegisterBottomUpMutator("provider_after_mutator", providerTestAfterMutator)
ctx.MockFileSystem(map[string][]byte{
"Android.bp": []byte(`
provider_module {
name: "A",
deps: ["B"],
}
provider_module {
name: "B",
deps: ["C", "D"],
}
provider_module {
name: "C",
deps: ["D"],
}
provider_module {
name: "D",
}
`),
})
_, errs := ctx.ParseBlueprintsFiles("Android.bp", nil)
if len(errs) == 0 {
_, errs = ctx.ResolveDependencies(nil)
}
if len(errs) == 0 {
_, errs = ctx.PrepareBuildActions(nil)
}
if len(errs) > 0 {
t.Errorf("unexpected errors:")
for _, err := range errs {
t.Errorf(" %s", err)
}
t.FailNow()
}
aModule := ctx.moduleGroupFromName("A", nil).moduleByVariantName("").logicModule.(*providerTestModule)
if g, w := aModule.generateBuildActionsProviderValues, []string{"B"}; !reflect.DeepEqual(g, w) {
t.Errorf("expected A.generateBuildActionsProviderValues %q, got %q", w, g)
}
if g, w := aModule.mutatorProviderValues, []string{"a", "b", "c", "d", "d"}; !reflect.DeepEqual(g, w) {
t.Errorf("expected A.mutatorProviderValues %q, got %q", w, g)
}
bModule := ctx.moduleGroupFromName("B", nil).moduleByVariantName("").logicModule.(*providerTestModule)
if g, w := bModule.generateBuildActionsProviderValues, []string{"C", "D"}; !reflect.DeepEqual(g, w) {
t.Errorf("expected B.generateBuildActionsProviderValues %q, got %q", w, g)
}
if g, w := bModule.mutatorProviderValues, []string{"b", "c", "d", "d"}; !reflect.DeepEqual(g, w) {
t.Errorf("expected B.mutatorProviderValues %q, got %q", w, g)
}
}
type invalidProviderUsageMutatorInfo string
type invalidProviderUsageGenerateBuildActionsInfo string
func (invalidProviderUsageGenerateBuildActionsInfo) Encode(ctx gobtools.EncContext, buf *bytes.Buffer) error {
return nil
}
func (invalidProviderUsageGenerateBuildActionsInfo) GetTypeId() int16 {
return -1
}
var invalidProviderUsageMutatorInfoProvider = NewMutatorProvider[invalidProviderUsageMutatorInfo]("mutator_under_test")
var invalidProviderUsageGenerateBuildActionsInfoProvider = NewProvider[invalidProviderUsageGenerateBuildActionsInfo]()
type invalidProviderUsageTestModule struct {
ModuleBase
SimpleName
properties struct {
Deps []string
Early_mutator_set_of_mutator_provider bool
Late_mutator_set_of_mutator_provider bool
Late_build_actions_set_of_mutator_provider bool
Early_mutator_set_of_build_actions_provider bool
Early_mutator_get_of_mutator_provider bool
Early_mutator_get_of_build_actions_provider bool
Duplicate_set bool
}
}
func invalidProviderUsageDepsMutator(ctx BottomUpMutatorContext) {
if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
ctx.AddDependency(ctx.Module(), nil, i.properties.Deps...)
}
}
func invalidProviderUsageBeforeMutator(ctx BottomUpMutatorContext) {
if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
if i.properties.Early_mutator_set_of_mutator_provider {
// A mutator attempting to set the value of a provider associated with a later mutator.
SetProvider(ctx, invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
}
if i.properties.Early_mutator_get_of_mutator_provider {
// A mutator attempting to get the value of a provider associated with a later mutator.
_, _ = ModuleProvider(ctx, invalidProviderUsageMutatorInfoProvider)
}
}
}
func invalidProviderUsageMutatorUnderTest(ctx BottomUpMutatorContext) {
if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
if i.properties.Early_mutator_set_of_build_actions_provider {
// A mutator attempting to set the value of a non-mutator provider.
SetProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
}
if i.properties.Early_mutator_get_of_build_actions_provider {
// A mutator attempting to get the value of a non-mutator provider.
_, _ = ModuleProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider)
}
}
}
func invalidProviderUsageAfterMutator(ctx BottomUpMutatorContext) {
if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok {
if i.properties.Late_mutator_set_of_mutator_provider {
// A mutator trying to set the value of a provider associated with an earlier mutator.
SetProvider(ctx, invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
}
if i.properties.Late_mutator_set_of_mutator_provider {
// A mutator trying to set the value of a provider associated with an earlier mutator.
SetProvider(ctx, invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
}
}
}
func (i *invalidProviderUsageTestModule) GenerateBuildActions(ctx ModuleContext) {
if i.properties.Late_build_actions_set_of_mutator_provider {
// A GenerateBuildActions trying to set the value of a provider associated with a mutator.
SetProvider(ctx, invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo(""))
}
if i.properties.Duplicate_set {
SetProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
SetProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo(""))
}
}
func TestInvalidProvidersUsage(t *testing.T) {
run := func(t *testing.T, module string, prop string, panicMsg string) {
t.Helper()
ctx := NewContext()
ctx.RegisterModuleType("invalid_provider_usage_test_module", func() (Module, []interface{}) {
m := &invalidProviderUsageTestModule{}
return m, []interface{}{&m.properties, &m.SimpleName.Properties}
})
ctx.RegisterBottomUpMutator("deps", invalidProviderUsageDepsMutator)
ctx.RegisterBottomUpMutator("before", invalidProviderUsageBeforeMutator)
ctx.RegisterBottomUpMutator("mutator_under_test", invalidProviderUsageMutatorUnderTest)
ctx.RegisterBottomUpMutator("after", invalidProviderUsageAfterMutator)
// Don't invalidate the parent pointer and before GenerateBuildActions.
ctx.SkipCloneModulesAfterMutators = true
var parentBP, moduleUnderTestBP, childBP string
prop += ": true,"
switch module {
case "parent":
parentBP = prop
case "module_under_test":
moduleUnderTestBP = prop
case "child":
childBP = prop
}
bp := fmt.Sprintf(`
invalid_provider_usage_test_module {
name: "parent",
deps: ["module_under_test"],
%s
}
invalid_provider_usage_test_module {
name: "module_under_test",
deps: ["child"],
%s
}
invalid_provider_usage_test_module {
name: "child",
%s
}
`,
parentBP,
moduleUnderTestBP,
childBP)
ctx.MockFileSystem(map[string][]byte{
"Android.bp": []byte(bp),
})
_, errs := ctx.ParseBlueprintsFiles("Android.bp", nil)
if len(errs) == 0 {
_, errs = ctx.ResolveDependencies(nil)
}
if len(errs) == 0 {
_, errs = ctx.PrepareBuildActions(nil)
}
if len(errs) == 0 {
t.Fatal("expected an error")
}
if len(errs) > 1 {
t.Errorf("expected a single error, got %d:", len(errs))
for i, err := range errs {
t.Errorf("%d: %s", i, err)
}
t.FailNow()
}
if panicErr, ok := errs[0].(panicError); ok {
if panicErr.panic != panicMsg {
t.Fatalf("expected panic %q, got %q", panicMsg, panicErr.panic)
}
} else {
t.Fatalf("expected a panicError, got %T: %s", errs[0], errs[0].Error())
}
}
tests := []struct {
prop string
module string
panicMsg string
skip string
}{
{
prop: "early_mutator_set_of_mutator_provider",
module: "module_under_test",
panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test started",
},
{
prop: "late_mutator_set_of_mutator_provider",
module: "module_under_test",
panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo after mutator mutator_under_test finished",
},
{
prop: "late_build_actions_set_of_mutator_provider",
module: "module_under_test",
panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo after mutator mutator_under_test finished",
},
{
prop: "early_mutator_set_of_build_actions_provider",
module: "module_under_test",
panicMsg: "Can't set value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions started",
},
{
prop: "early_mutator_get_of_mutator_provider",
module: "module_under_test",
panicMsg: "Can't get value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test finished",
},
{
prop: "early_mutator_get_of_build_actions_provider",
module: "module_under_test",
panicMsg: "Can't get value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions finished",
},
{
prop: "duplicate_set",
module: "module_under_test",
panicMsg: "Value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo is already set",
},
}
for _, tt := range tests {
t.Run(tt.prop, func(t *testing.T) {
run(t, tt.module, tt.prop, tt.panicMsg)
})
}
}
func TestInvalidSingletonProvidersUsage(t *testing.T) {
type singletonType struct {
name string
factory SingletonFactory
parallel bool
}
run := func(t *testing.T, singletons []singletonType, panicMsg string) {
t.Helper()
ctx := NewContext()
for _, s := range singletons {
ctx.RegisterSingletonType(s.name, s.factory, s.parallel)
}
ctx.MockFileSystem(map[string][]byte{
"Android.bp": {},
})
_, errs := ctx.ParseBlueprintsFiles("Android.bp", nil)
if len(errs) == 0 {
_, errs = ctx.ResolveDependencies(nil)
}
if len(errs) == 0 {
_, errs = ctx.PrepareBuildActions(nil)
}
if len(panicMsg) == 0 {
if len(errs) != 0 {
t.Fatal("got an error: ", errs)
}
return
}
if len(errs) == 0 {
t.Fatal("expected an error")
}
if len(errs) > 1 {
t.Errorf("expected a single error, got %d:", len(errs))
for i, err := range errs {
t.Errorf("%d: %s", i, err)
}
t.FailNow()
}
if panicErr, ok := errs[0].(panicError); ok {
if panicErr.panic != panicMsg {
t.Fatalf("expected panic %q, got %q", panicMsg, panicErr.panic)
}
} else {
t.Fatalf("expected a panicError, got %T: %s", errs[0], errs[0].Error())
}
}
tests := []struct {
testName string
singletons []singletonType
panicMsg string
}{
{
testName: "get_non_singleton_provider",
singletons: []singletonType{
{
name: "parallel_singleton",
factory: func() Singleton {
return &providerTestParallelSingleton{}
},
parallel: true,
},
{
name: "sequential_singleton",
factory: func() Singleton {
return &providerTestSequentialSingleton{
getModuleProvider: true,
}
},
parallel: false,
},
},
panicMsg: "Can't get value of non-singleton provider *blueprint.providerTestMutatorInfo usign singleton specific get method",
},
{
testName: "set_non_singleton_provider",
singletons: []singletonType{
{
name: "sequential_singleton",
factory: func() Singleton {
return &providerTestSequentialSingleton{
setModuleProvider: true,
}
},
parallel: false,
},
},
panicMsg: "Can't set value of non-singleton provider *blueprint.providerTestMutatorInfo inside singleton sequential_singleton",
},
{
testName: "set_get_singleton_provider",
singletons: []singletonType{
{
name: "parallel_singleton",
factory: func() Singleton {
return &providerTestParallelSingleton{}
},
parallel: true,
},
{
name: "sequential_singleton",
factory: func() Singleton {
return &providerTestSequentialSingleton{}
},
parallel: false,
},
},
panicMsg: "",
},
{
testName: "visit_all_singletons_in_parallel_singleton",
singletons: []singletonType{
{
name: "parallel_singleton",
factory: func() Singleton {
return &providerTestParallelSingleton{visitAllSingletons: true}
},
parallel: true,
},
},
panicMsg: "VisitAllSingletons not allowed in parallel singletons parallel_singleton",
},
}
for _, tt := range tests {
t.Run(tt.testName, func(t *testing.T) {
run(t, tt.singletons, tt.panicMsg)
})
}
}
[Dauer der Verarbeitung: 0.20 Sekunden, vorverarbeitet 2026-06-28]
|
2026-07-09
|