1*1fa6dee9SAndroid Build Coastguard Worker// Copyright 2020 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 "reflect" 20*1fa6dee9SAndroid Build Coastguard Worker "strings" 21*1fa6dee9SAndroid Build Coastguard Worker "testing" 22*1fa6dee9SAndroid Build Coastguard Worker) 23*1fa6dee9SAndroid Build Coastguard Worker 24*1fa6dee9SAndroid Build Coastguard Workertype providerTestModule struct { 25*1fa6dee9SAndroid Build Coastguard Worker SimpleName 26*1fa6dee9SAndroid Build Coastguard Worker properties struct { 27*1fa6dee9SAndroid Build Coastguard Worker Deps []string 28*1fa6dee9SAndroid Build Coastguard Worker } 29*1fa6dee9SAndroid Build Coastguard Worker 30*1fa6dee9SAndroid Build Coastguard Worker mutatorProviderValues []string 31*1fa6dee9SAndroid Build Coastguard Worker generateBuildActionsProviderValues []string 32*1fa6dee9SAndroid Build Coastguard Worker} 33*1fa6dee9SAndroid Build Coastguard Worker 34*1fa6dee9SAndroid Build Coastguard Workerfunc newProviderTestModule() (Module, []interface{}) { 35*1fa6dee9SAndroid Build Coastguard Worker m := &providerTestModule{} 36*1fa6dee9SAndroid Build Coastguard Worker return m, []interface{}{&m.properties, &m.SimpleName.Properties} 37*1fa6dee9SAndroid Build Coastguard Worker} 38*1fa6dee9SAndroid Build Coastguard Worker 39*1fa6dee9SAndroid Build Coastguard Workertype providerTestMutatorInfo struct { 40*1fa6dee9SAndroid Build Coastguard Worker Values []string 41*1fa6dee9SAndroid Build Coastguard Worker} 42*1fa6dee9SAndroid Build Coastguard Worker 43*1fa6dee9SAndroid Build Coastguard Workertype providerTestGenerateBuildActionsInfo struct { 44*1fa6dee9SAndroid Build Coastguard Worker Value string 45*1fa6dee9SAndroid Build Coastguard Worker} 46*1fa6dee9SAndroid Build Coastguard Worker 47*1fa6dee9SAndroid Build Coastguard Workertype providerTestUnsetInfo string 48*1fa6dee9SAndroid Build Coastguard Worker 49*1fa6dee9SAndroid Build Coastguard Workervar providerTestMutatorInfoProvider = NewMutatorProvider[*providerTestMutatorInfo]("provider_mutator") 50*1fa6dee9SAndroid Build Coastguard Workervar providerTestGenerateBuildActionsInfoProvider = NewProvider[*providerTestGenerateBuildActionsInfo]() 51*1fa6dee9SAndroid Build Coastguard Workervar providerTestUnsetInfoProvider = NewMutatorProvider[providerTestUnsetInfo]("provider_mutator") 52*1fa6dee9SAndroid Build Coastguard Workervar providerTestUnusedMutatorProvider = NewMutatorProvider[*struct{ unused string }]("nonexistent_mutator") 53*1fa6dee9SAndroid Build Coastguard Worker 54*1fa6dee9SAndroid Build Coastguard Workerfunc (p *providerTestModule) GenerateBuildActions(ctx ModuleContext) { 55*1fa6dee9SAndroid Build Coastguard Worker unset, ok := ModuleProvider(ctx, providerTestUnsetInfoProvider) 56*1fa6dee9SAndroid Build Coastguard Worker if ok { 57*1fa6dee9SAndroid Build Coastguard Worker panic(fmt.Errorf("expected false return value for providerTestGenerateBuildActionsInfoProvider before it was set")) 58*1fa6dee9SAndroid Build Coastguard Worker } 59*1fa6dee9SAndroid Build Coastguard Worker if unset != "" { 60*1fa6dee9SAndroid Build Coastguard Worker panic(fmt.Errorf("expected zero value for providerTestGenerateBuildActionsInfoProvider before it was set, got %q", 61*1fa6dee9SAndroid Build Coastguard Worker unset)) 62*1fa6dee9SAndroid Build Coastguard Worker } 63*1fa6dee9SAndroid Build Coastguard Worker 64*1fa6dee9SAndroid Build Coastguard Worker // Verify reading providerTestUnusedMutatorProvider doesn't panic 65*1fa6dee9SAndroid Build Coastguard Worker _, _ = ModuleProvider(ctx, providerTestUnusedMutatorProvider) 66*1fa6dee9SAndroid Build Coastguard Worker 67*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, providerTestGenerateBuildActionsInfoProvider, &providerTestGenerateBuildActionsInfo{ 68*1fa6dee9SAndroid Build Coastguard Worker Value: ctx.ModuleName(), 69*1fa6dee9SAndroid Build Coastguard Worker }) 70*1fa6dee9SAndroid Build Coastguard Worker 71*1fa6dee9SAndroid Build Coastguard Worker mp, ok := ModuleProvider(ctx, providerTestMutatorInfoProvider) 72*1fa6dee9SAndroid Build Coastguard Worker if ok { 73*1fa6dee9SAndroid Build Coastguard Worker p.mutatorProviderValues = mp.Values 74*1fa6dee9SAndroid Build Coastguard Worker } 75*1fa6dee9SAndroid Build Coastguard Worker 76*1fa6dee9SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(module Module) { 77*1fa6dee9SAndroid Build Coastguard Worker gbap, _ := OtherModuleProvider(ctx, module, providerTestGenerateBuildActionsInfoProvider) 78*1fa6dee9SAndroid Build Coastguard Worker if gbap != nil { 79*1fa6dee9SAndroid Build Coastguard Worker p.generateBuildActionsProviderValues = append(p.generateBuildActionsProviderValues, gbap.Value) 80*1fa6dee9SAndroid Build Coastguard Worker } 81*1fa6dee9SAndroid Build Coastguard Worker }) 82*1fa6dee9SAndroid Build Coastguard Worker} 83*1fa6dee9SAndroid Build Coastguard Worker 84*1fa6dee9SAndroid Build Coastguard Workerfunc providerTestDepsMutator(ctx BottomUpMutatorContext) { 85*1fa6dee9SAndroid Build Coastguard Worker if p, ok := ctx.Module().(*providerTestModule); ok { 86*1fa6dee9SAndroid Build Coastguard Worker ctx.AddDependency(ctx.Module(), nil, p.properties.Deps...) 87*1fa6dee9SAndroid Build Coastguard Worker } 88*1fa6dee9SAndroid Build Coastguard Worker} 89*1fa6dee9SAndroid Build Coastguard Worker 90*1fa6dee9SAndroid Build Coastguard Workerfunc providerTestMutator(ctx BottomUpMutatorContext) { 91*1fa6dee9SAndroid Build Coastguard Worker values := []string{strings.ToLower(ctx.ModuleName())} 92*1fa6dee9SAndroid Build Coastguard Worker 93*1fa6dee9SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(module Module) { 94*1fa6dee9SAndroid Build Coastguard Worker mp, _ := OtherModuleProvider(ctx, module, providerTestMutatorInfoProvider) 95*1fa6dee9SAndroid Build Coastguard Worker if mp != nil { 96*1fa6dee9SAndroid Build Coastguard Worker values = append(values, mp.Values...) 97*1fa6dee9SAndroid Build Coastguard Worker } 98*1fa6dee9SAndroid Build Coastguard Worker }) 99*1fa6dee9SAndroid Build Coastguard Worker 100*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, providerTestMutatorInfoProvider, &providerTestMutatorInfo{ 101*1fa6dee9SAndroid Build Coastguard Worker Values: values, 102*1fa6dee9SAndroid Build Coastguard Worker }) 103*1fa6dee9SAndroid Build Coastguard Worker} 104*1fa6dee9SAndroid Build Coastguard Worker 105*1fa6dee9SAndroid Build Coastguard Workerfunc providerTestAfterMutator(ctx BottomUpMutatorContext) { 106*1fa6dee9SAndroid Build Coastguard Worker // Verify reading providerTestUnusedMutatorProvider doesn't panic 107*1fa6dee9SAndroid Build Coastguard Worker _, _ = ModuleProvider(ctx, providerTestMutatorInfoProvider) 108*1fa6dee9SAndroid Build Coastguard Worker} 109*1fa6dee9SAndroid Build Coastguard Worker 110*1fa6dee9SAndroid Build Coastguard Workerfunc TestProviders(t *testing.T) { 111*1fa6dee9SAndroid Build Coastguard Worker ctx := NewContext() 112*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterModuleType("provider_module", newProviderTestModule) 113*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterBottomUpMutator("provider_deps_mutator", providerTestDepsMutator) 114*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterBottomUpMutator("provider_mutator", providerTestMutator) 115*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterBottomUpMutator("provider_after_mutator", providerTestAfterMutator) 116*1fa6dee9SAndroid Build Coastguard Worker 117*1fa6dee9SAndroid Build Coastguard Worker ctx.MockFileSystem(map[string][]byte{ 118*1fa6dee9SAndroid Build Coastguard Worker "Android.bp": []byte(` 119*1fa6dee9SAndroid Build Coastguard Worker provider_module { 120*1fa6dee9SAndroid Build Coastguard Worker name: "A", 121*1fa6dee9SAndroid Build Coastguard Worker deps: ["B"], 122*1fa6dee9SAndroid Build Coastguard Worker } 123*1fa6dee9SAndroid Build Coastguard Worker 124*1fa6dee9SAndroid Build Coastguard Worker provider_module { 125*1fa6dee9SAndroid Build Coastguard Worker name: "B", 126*1fa6dee9SAndroid Build Coastguard Worker deps: ["C", "D"], 127*1fa6dee9SAndroid Build Coastguard Worker } 128*1fa6dee9SAndroid Build Coastguard Worker 129*1fa6dee9SAndroid Build Coastguard Worker provider_module { 130*1fa6dee9SAndroid Build Coastguard Worker name: "C", 131*1fa6dee9SAndroid Build Coastguard Worker deps: ["D"], 132*1fa6dee9SAndroid Build Coastguard Worker } 133*1fa6dee9SAndroid Build Coastguard Worker 134*1fa6dee9SAndroid Build Coastguard Worker provider_module { 135*1fa6dee9SAndroid Build Coastguard Worker name: "D", 136*1fa6dee9SAndroid Build Coastguard Worker } 137*1fa6dee9SAndroid Build Coastguard Worker `), 138*1fa6dee9SAndroid Build Coastguard Worker }) 139*1fa6dee9SAndroid Build Coastguard Worker 140*1fa6dee9SAndroid Build Coastguard Worker _, errs := ctx.ParseBlueprintsFiles("Android.bp", nil) 141*1fa6dee9SAndroid Build Coastguard Worker if len(errs) == 0 { 142*1fa6dee9SAndroid Build Coastguard Worker _, errs = ctx.ResolveDependencies(nil) 143*1fa6dee9SAndroid Build Coastguard Worker } 144*1fa6dee9SAndroid Build Coastguard Worker if len(errs) == 0 { 145*1fa6dee9SAndroid Build Coastguard Worker _, errs = ctx.PrepareBuildActions(nil) 146*1fa6dee9SAndroid Build Coastguard Worker } 147*1fa6dee9SAndroid Build Coastguard Worker if len(errs) > 0 { 148*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("unexpected errors:") 149*1fa6dee9SAndroid Build Coastguard Worker for _, err := range errs { 150*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" %s", err) 151*1fa6dee9SAndroid Build Coastguard Worker } 152*1fa6dee9SAndroid Build Coastguard Worker t.FailNow() 153*1fa6dee9SAndroid Build Coastguard Worker } 154*1fa6dee9SAndroid Build Coastguard Worker 155*1fa6dee9SAndroid Build Coastguard Worker aModule := ctx.moduleGroupFromName("A", nil).moduleByVariantName("").logicModule.(*providerTestModule) 156*1fa6dee9SAndroid Build Coastguard Worker if g, w := aModule.generateBuildActionsProviderValues, []string{"B"}; !reflect.DeepEqual(g, w) { 157*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected A.generateBuildActionsProviderValues %q, got %q", w, g) 158*1fa6dee9SAndroid Build Coastguard Worker } 159*1fa6dee9SAndroid Build Coastguard Worker if g, w := aModule.mutatorProviderValues, []string{"a", "b", "c", "d", "d"}; !reflect.DeepEqual(g, w) { 160*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected A.mutatorProviderValues %q, got %q", w, g) 161*1fa6dee9SAndroid Build Coastguard Worker } 162*1fa6dee9SAndroid Build Coastguard Worker 163*1fa6dee9SAndroid Build Coastguard Worker bModule := ctx.moduleGroupFromName("B", nil).moduleByVariantName("").logicModule.(*providerTestModule) 164*1fa6dee9SAndroid Build Coastguard Worker if g, w := bModule.generateBuildActionsProviderValues, []string{"C", "D"}; !reflect.DeepEqual(g, w) { 165*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected B.generateBuildActionsProviderValues %q, got %q", w, g) 166*1fa6dee9SAndroid Build Coastguard Worker } 167*1fa6dee9SAndroid Build Coastguard Worker if g, w := bModule.mutatorProviderValues, []string{"b", "c", "d", "d"}; !reflect.DeepEqual(g, w) { 168*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected B.mutatorProviderValues %q, got %q", w, g) 169*1fa6dee9SAndroid Build Coastguard Worker } 170*1fa6dee9SAndroid Build Coastguard Worker} 171*1fa6dee9SAndroid Build Coastguard Worker 172*1fa6dee9SAndroid Build Coastguard Workertype invalidProviderUsageMutatorInfo string 173*1fa6dee9SAndroid Build Coastguard Workertype invalidProviderUsageGenerateBuildActionsInfo string 174*1fa6dee9SAndroid Build Coastguard Worker 175*1fa6dee9SAndroid Build Coastguard Workervar invalidProviderUsageMutatorInfoProvider = NewMutatorProvider[invalidProviderUsageMutatorInfo]("mutator_under_test") 176*1fa6dee9SAndroid Build Coastguard Workervar invalidProviderUsageGenerateBuildActionsInfoProvider = NewProvider[invalidProviderUsageGenerateBuildActionsInfo]() 177*1fa6dee9SAndroid Build Coastguard Worker 178*1fa6dee9SAndroid Build Coastguard Workertype invalidProviderUsageTestModule struct { 179*1fa6dee9SAndroid Build Coastguard Worker parent *invalidProviderUsageTestModule 180*1fa6dee9SAndroid Build Coastguard Worker 181*1fa6dee9SAndroid Build Coastguard Worker SimpleName 182*1fa6dee9SAndroid Build Coastguard Worker properties struct { 183*1fa6dee9SAndroid Build Coastguard Worker Deps []string 184*1fa6dee9SAndroid Build Coastguard Worker 185*1fa6dee9SAndroid Build Coastguard Worker Early_mutator_set_of_mutator_provider bool 186*1fa6dee9SAndroid Build Coastguard Worker Late_mutator_set_of_mutator_provider bool 187*1fa6dee9SAndroid Build Coastguard Worker Late_build_actions_set_of_mutator_provider bool 188*1fa6dee9SAndroid Build Coastguard Worker Early_mutator_set_of_build_actions_provider bool 189*1fa6dee9SAndroid Build Coastguard Worker 190*1fa6dee9SAndroid Build Coastguard Worker Early_mutator_get_of_mutator_provider bool 191*1fa6dee9SAndroid Build Coastguard Worker Early_module_get_of_mutator_provider bool 192*1fa6dee9SAndroid Build Coastguard Worker Early_mutator_get_of_build_actions_provider bool 193*1fa6dee9SAndroid Build Coastguard Worker Early_module_get_of_build_actions_provider bool 194*1fa6dee9SAndroid Build Coastguard Worker 195*1fa6dee9SAndroid Build Coastguard Worker Duplicate_set bool 196*1fa6dee9SAndroid Build Coastguard Worker } 197*1fa6dee9SAndroid Build Coastguard Worker} 198*1fa6dee9SAndroid Build Coastguard Worker 199*1fa6dee9SAndroid Build Coastguard Workerfunc invalidProviderUsageDepsMutator(ctx BottomUpMutatorContext) { 200*1fa6dee9SAndroid Build Coastguard Worker if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok { 201*1fa6dee9SAndroid Build Coastguard Worker ctx.AddDependency(ctx.Module(), nil, i.properties.Deps...) 202*1fa6dee9SAndroid Build Coastguard Worker } 203*1fa6dee9SAndroid Build Coastguard Worker} 204*1fa6dee9SAndroid Build Coastguard Worker 205*1fa6dee9SAndroid Build Coastguard Workerfunc invalidProviderUsageParentMutator(ctx TopDownMutatorContext) { 206*1fa6dee9SAndroid Build Coastguard Worker if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok { 207*1fa6dee9SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(module Module) { 208*1fa6dee9SAndroid Build Coastguard Worker module.(*invalidProviderUsageTestModule).parent = i 209*1fa6dee9SAndroid Build Coastguard Worker }) 210*1fa6dee9SAndroid Build Coastguard Worker } 211*1fa6dee9SAndroid Build Coastguard Worker} 212*1fa6dee9SAndroid Build Coastguard Worker 213*1fa6dee9SAndroid Build Coastguard Workerfunc invalidProviderUsageBeforeMutator(ctx BottomUpMutatorContext) { 214*1fa6dee9SAndroid Build Coastguard Worker if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok { 215*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Early_mutator_set_of_mutator_provider { 216*1fa6dee9SAndroid Build Coastguard Worker // A mutator attempting to set the value of a provider associated with a later mutator. 217*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo("")) 218*1fa6dee9SAndroid Build Coastguard Worker } 219*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Early_mutator_get_of_mutator_provider { 220*1fa6dee9SAndroid Build Coastguard Worker // A mutator attempting to get the value of a provider associated with a later mutator. 221*1fa6dee9SAndroid Build Coastguard Worker _, _ = ModuleProvider(ctx, invalidProviderUsageMutatorInfoProvider) 222*1fa6dee9SAndroid Build Coastguard Worker } 223*1fa6dee9SAndroid Build Coastguard Worker } 224*1fa6dee9SAndroid Build Coastguard Worker} 225*1fa6dee9SAndroid Build Coastguard Worker 226*1fa6dee9SAndroid Build Coastguard Workerfunc invalidProviderUsageMutatorUnderTest(ctx TopDownMutatorContext) { 227*1fa6dee9SAndroid Build Coastguard Worker if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok { 228*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Early_mutator_set_of_build_actions_provider { 229*1fa6dee9SAndroid Build Coastguard Worker // A mutator attempting to set the value of a non-mutator provider. 230*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo("")) 231*1fa6dee9SAndroid Build Coastguard Worker } 232*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Early_mutator_get_of_build_actions_provider { 233*1fa6dee9SAndroid Build Coastguard Worker // A mutator attempting to get the value of a non-mutator provider. 234*1fa6dee9SAndroid Build Coastguard Worker _, _ = ModuleProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider) 235*1fa6dee9SAndroid Build Coastguard Worker } 236*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Early_module_get_of_mutator_provider { 237*1fa6dee9SAndroid Build Coastguard Worker // A mutator attempting to get the value of a provider associated with this mutator on 238*1fa6dee9SAndroid Build Coastguard Worker // a module for which this mutator hasn't run. This is a top down mutator so 239*1fa6dee9SAndroid Build Coastguard Worker // dependencies haven't run yet. 240*1fa6dee9SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(module Module) { 241*1fa6dee9SAndroid Build Coastguard Worker _, _ = OtherModuleProvider(ctx, module, invalidProviderUsageMutatorInfoProvider) 242*1fa6dee9SAndroid Build Coastguard Worker }) 243*1fa6dee9SAndroid Build Coastguard Worker } 244*1fa6dee9SAndroid Build Coastguard Worker } 245*1fa6dee9SAndroid Build Coastguard Worker} 246*1fa6dee9SAndroid Build Coastguard Worker 247*1fa6dee9SAndroid Build Coastguard Workerfunc invalidProviderUsageAfterMutator(ctx BottomUpMutatorContext) { 248*1fa6dee9SAndroid Build Coastguard Worker if i, ok := ctx.Module().(*invalidProviderUsageTestModule); ok { 249*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Late_mutator_set_of_mutator_provider { 250*1fa6dee9SAndroid Build Coastguard Worker // A mutator trying to set the value of a provider associated with an earlier mutator. 251*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo("")) 252*1fa6dee9SAndroid Build Coastguard Worker } 253*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Late_mutator_set_of_mutator_provider { 254*1fa6dee9SAndroid Build Coastguard Worker // A mutator trying to set the value of a provider associated with an earlier mutator. 255*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo("")) 256*1fa6dee9SAndroid Build Coastguard Worker } 257*1fa6dee9SAndroid Build Coastguard Worker } 258*1fa6dee9SAndroid Build Coastguard Worker} 259*1fa6dee9SAndroid Build Coastguard Worker 260*1fa6dee9SAndroid Build Coastguard Workerfunc (i *invalidProviderUsageTestModule) GenerateBuildActions(ctx ModuleContext) { 261*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Late_build_actions_set_of_mutator_provider { 262*1fa6dee9SAndroid Build Coastguard Worker // A GenerateBuildActions trying to set the value of a provider associated with a mutator. 263*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, invalidProviderUsageMutatorInfoProvider, invalidProviderUsageMutatorInfo("")) 264*1fa6dee9SAndroid Build Coastguard Worker } 265*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Early_module_get_of_build_actions_provider { 266*1fa6dee9SAndroid Build Coastguard Worker // A GenerateBuildActions trying to get the value of a provider on a module for which 267*1fa6dee9SAndroid Build Coastguard Worker // GenerateBuildActions hasn't run. 268*1fa6dee9SAndroid Build Coastguard Worker _, _ = OtherModuleProvider(ctx, i.parent, invalidProviderUsageGenerateBuildActionsInfoProvider) 269*1fa6dee9SAndroid Build Coastguard Worker } 270*1fa6dee9SAndroid Build Coastguard Worker if i.properties.Duplicate_set { 271*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo("")) 272*1fa6dee9SAndroid Build Coastguard Worker SetProvider(ctx, invalidProviderUsageGenerateBuildActionsInfoProvider, invalidProviderUsageGenerateBuildActionsInfo("")) 273*1fa6dee9SAndroid Build Coastguard Worker } 274*1fa6dee9SAndroid Build Coastguard Worker} 275*1fa6dee9SAndroid Build Coastguard Worker 276*1fa6dee9SAndroid Build Coastguard Workerfunc TestInvalidProvidersUsage(t *testing.T) { 277*1fa6dee9SAndroid Build Coastguard Worker run := func(t *testing.T, module string, prop string, panicMsg string) { 278*1fa6dee9SAndroid Build Coastguard Worker t.Helper() 279*1fa6dee9SAndroid Build Coastguard Worker ctx := NewContext() 280*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterModuleType("invalid_provider_usage_test_module", func() (Module, []interface{}) { 281*1fa6dee9SAndroid Build Coastguard Worker m := &invalidProviderUsageTestModule{} 282*1fa6dee9SAndroid Build Coastguard Worker return m, []interface{}{&m.properties, &m.SimpleName.Properties} 283*1fa6dee9SAndroid Build Coastguard Worker }) 284*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterBottomUpMutator("deps", invalidProviderUsageDepsMutator) 285*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterBottomUpMutator("before", invalidProviderUsageBeforeMutator) 286*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterTopDownMutator("mutator_under_test", invalidProviderUsageMutatorUnderTest) 287*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterBottomUpMutator("after", invalidProviderUsageAfterMutator) 288*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterTopDownMutator("parent", invalidProviderUsageParentMutator) 289*1fa6dee9SAndroid Build Coastguard Worker 290*1fa6dee9SAndroid Build Coastguard Worker // Don't invalidate the parent pointer and before GenerateBuildActions. 291*1fa6dee9SAndroid Build Coastguard Worker ctx.SkipCloneModulesAfterMutators = true 292*1fa6dee9SAndroid Build Coastguard Worker 293*1fa6dee9SAndroid Build Coastguard Worker var parentBP, moduleUnderTestBP, childBP string 294*1fa6dee9SAndroid Build Coastguard Worker 295*1fa6dee9SAndroid Build Coastguard Worker prop += ": true," 296*1fa6dee9SAndroid Build Coastguard Worker 297*1fa6dee9SAndroid Build Coastguard Worker switch module { 298*1fa6dee9SAndroid Build Coastguard Worker case "parent": 299*1fa6dee9SAndroid Build Coastguard Worker parentBP = prop 300*1fa6dee9SAndroid Build Coastguard Worker case "module_under_test": 301*1fa6dee9SAndroid Build Coastguard Worker moduleUnderTestBP = prop 302*1fa6dee9SAndroid Build Coastguard Worker case "child": 303*1fa6dee9SAndroid Build Coastguard Worker childBP = prop 304*1fa6dee9SAndroid Build Coastguard Worker } 305*1fa6dee9SAndroid Build Coastguard Worker 306*1fa6dee9SAndroid Build Coastguard Worker bp := fmt.Sprintf(` 307*1fa6dee9SAndroid Build Coastguard Worker invalid_provider_usage_test_module { 308*1fa6dee9SAndroid Build Coastguard Worker name: "parent", 309*1fa6dee9SAndroid Build Coastguard Worker deps: ["module_under_test"], 310*1fa6dee9SAndroid Build Coastguard Worker %s 311*1fa6dee9SAndroid Build Coastguard Worker } 312*1fa6dee9SAndroid Build Coastguard Worker 313*1fa6dee9SAndroid Build Coastguard Worker invalid_provider_usage_test_module { 314*1fa6dee9SAndroid Build Coastguard Worker name: "module_under_test", 315*1fa6dee9SAndroid Build Coastguard Worker deps: ["child"], 316*1fa6dee9SAndroid Build Coastguard Worker %s 317*1fa6dee9SAndroid Build Coastguard Worker } 318*1fa6dee9SAndroid Build Coastguard Worker 319*1fa6dee9SAndroid Build Coastguard Worker invalid_provider_usage_test_module { 320*1fa6dee9SAndroid Build Coastguard Worker name: "child", 321*1fa6dee9SAndroid Build Coastguard Worker %s 322*1fa6dee9SAndroid Build Coastguard Worker } 323*1fa6dee9SAndroid Build Coastguard Worker 324*1fa6dee9SAndroid Build Coastguard Worker `, 325*1fa6dee9SAndroid Build Coastguard Worker parentBP, 326*1fa6dee9SAndroid Build Coastguard Worker moduleUnderTestBP, 327*1fa6dee9SAndroid Build Coastguard Worker childBP) 328*1fa6dee9SAndroid Build Coastguard Worker 329*1fa6dee9SAndroid Build Coastguard Worker ctx.MockFileSystem(map[string][]byte{ 330*1fa6dee9SAndroid Build Coastguard Worker "Android.bp": []byte(bp), 331*1fa6dee9SAndroid Build Coastguard Worker }) 332*1fa6dee9SAndroid Build Coastguard Worker 333*1fa6dee9SAndroid Build Coastguard Worker _, errs := ctx.ParseBlueprintsFiles("Android.bp", nil) 334*1fa6dee9SAndroid Build Coastguard Worker 335*1fa6dee9SAndroid Build Coastguard Worker if len(errs) == 0 { 336*1fa6dee9SAndroid Build Coastguard Worker _, errs = ctx.ResolveDependencies(nil) 337*1fa6dee9SAndroid Build Coastguard Worker } 338*1fa6dee9SAndroid Build Coastguard Worker 339*1fa6dee9SAndroid Build Coastguard Worker if len(errs) == 0 { 340*1fa6dee9SAndroid Build Coastguard Worker _, errs = ctx.PrepareBuildActions(nil) 341*1fa6dee9SAndroid Build Coastguard Worker } 342*1fa6dee9SAndroid Build Coastguard Worker 343*1fa6dee9SAndroid Build Coastguard Worker if len(errs) == 0 { 344*1fa6dee9SAndroid Build Coastguard Worker t.Fatal("expected an error") 345*1fa6dee9SAndroid Build Coastguard Worker } 346*1fa6dee9SAndroid Build Coastguard Worker 347*1fa6dee9SAndroid Build Coastguard Worker if len(errs) > 1 { 348*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected a single error, got %d:", len(errs)) 349*1fa6dee9SAndroid Build Coastguard Worker for i, err := range errs { 350*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("%d: %s", i, err) 351*1fa6dee9SAndroid Build Coastguard Worker } 352*1fa6dee9SAndroid Build Coastguard Worker t.FailNow() 353*1fa6dee9SAndroid Build Coastguard Worker } 354*1fa6dee9SAndroid Build Coastguard Worker 355*1fa6dee9SAndroid Build Coastguard Worker if panicErr, ok := errs[0].(panicError); ok { 356*1fa6dee9SAndroid Build Coastguard Worker if panicErr.panic != panicMsg { 357*1fa6dee9SAndroid Build Coastguard Worker t.Fatalf("expected panic %q, got %q", panicMsg, panicErr.panic) 358*1fa6dee9SAndroid Build Coastguard Worker } 359*1fa6dee9SAndroid Build Coastguard Worker } else { 360*1fa6dee9SAndroid Build Coastguard Worker t.Fatalf("expected a panicError, got %T: %s", errs[0], errs[0].Error()) 361*1fa6dee9SAndroid Build Coastguard Worker } 362*1fa6dee9SAndroid Build Coastguard Worker 363*1fa6dee9SAndroid Build Coastguard Worker } 364*1fa6dee9SAndroid Build Coastguard Worker 365*1fa6dee9SAndroid Build Coastguard Worker tests := []struct { 366*1fa6dee9SAndroid Build Coastguard Worker prop string 367*1fa6dee9SAndroid Build Coastguard Worker module string 368*1fa6dee9SAndroid Build Coastguard Worker 369*1fa6dee9SAndroid Build Coastguard Worker panicMsg string 370*1fa6dee9SAndroid Build Coastguard Worker skip string 371*1fa6dee9SAndroid Build Coastguard Worker }{ 372*1fa6dee9SAndroid Build Coastguard Worker { 373*1fa6dee9SAndroid Build Coastguard Worker prop: "early_mutator_set_of_mutator_provider", 374*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 375*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test started", 376*1fa6dee9SAndroid Build Coastguard Worker }, 377*1fa6dee9SAndroid Build Coastguard Worker { 378*1fa6dee9SAndroid Build Coastguard Worker prop: "late_mutator_set_of_mutator_provider", 379*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 380*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo after mutator mutator_under_test finished", 381*1fa6dee9SAndroid Build Coastguard Worker }, 382*1fa6dee9SAndroid Build Coastguard Worker { 383*1fa6dee9SAndroid Build Coastguard Worker prop: "late_build_actions_set_of_mutator_provider", 384*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 385*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Can't set value of provider blueprint.invalidProviderUsageMutatorInfo after mutator mutator_under_test finished", 386*1fa6dee9SAndroid Build Coastguard Worker }, 387*1fa6dee9SAndroid Build Coastguard Worker { 388*1fa6dee9SAndroid Build Coastguard Worker prop: "early_mutator_set_of_build_actions_provider", 389*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 390*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Can't set value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions started", 391*1fa6dee9SAndroid Build Coastguard Worker }, 392*1fa6dee9SAndroid Build Coastguard Worker 393*1fa6dee9SAndroid Build Coastguard Worker { 394*1fa6dee9SAndroid Build Coastguard Worker prop: "early_mutator_get_of_mutator_provider", 395*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 396*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Can't get value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test finished", 397*1fa6dee9SAndroid Build Coastguard Worker }, 398*1fa6dee9SAndroid Build Coastguard Worker { 399*1fa6dee9SAndroid Build Coastguard Worker prop: "early_module_get_of_mutator_provider", 400*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 401*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Can't get value of provider blueprint.invalidProviderUsageMutatorInfo before mutator mutator_under_test finished", 402*1fa6dee9SAndroid Build Coastguard Worker }, 403*1fa6dee9SAndroid Build Coastguard Worker { 404*1fa6dee9SAndroid Build Coastguard Worker prop: "early_mutator_get_of_build_actions_provider", 405*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 406*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Can't get value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions finished", 407*1fa6dee9SAndroid Build Coastguard Worker }, 408*1fa6dee9SAndroid Build Coastguard Worker { 409*1fa6dee9SAndroid Build Coastguard Worker prop: "early_module_get_of_build_actions_provider", 410*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 411*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Can't get value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo before GenerateBuildActions finished", 412*1fa6dee9SAndroid Build Coastguard Worker }, 413*1fa6dee9SAndroid Build Coastguard Worker { 414*1fa6dee9SAndroid Build Coastguard Worker prop: "duplicate_set", 415*1fa6dee9SAndroid Build Coastguard Worker module: "module_under_test", 416*1fa6dee9SAndroid Build Coastguard Worker panicMsg: "Value of provider blueprint.invalidProviderUsageGenerateBuildActionsInfo is already set", 417*1fa6dee9SAndroid Build Coastguard Worker }, 418*1fa6dee9SAndroid Build Coastguard Worker } 419*1fa6dee9SAndroid Build Coastguard Worker 420*1fa6dee9SAndroid Build Coastguard Worker for _, tt := range tests { 421*1fa6dee9SAndroid Build Coastguard Worker t.Run(tt.prop, func(t *testing.T) { 422*1fa6dee9SAndroid Build Coastguard Worker run(t, tt.module, tt.prop, tt.panicMsg) 423*1fa6dee9SAndroid Build Coastguard Worker }) 424*1fa6dee9SAndroid Build Coastguard Worker } 425*1fa6dee9SAndroid Build Coastguard Worker} 426