1*1fa6dee9SAndroid Build Coastguard Worker// Copyright 2024 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 "regexp" 20*1fa6dee9SAndroid Build Coastguard Worker "slices" 21*1fa6dee9SAndroid Build Coastguard Worker "strings" 22*1fa6dee9SAndroid Build Coastguard Worker "testing" 23*1fa6dee9SAndroid Build Coastguard Worker) 24*1fa6dee9SAndroid Build Coastguard Worker 25*1fa6dee9SAndroid Build Coastguard Workerfunc testTransitionCommon(bp string, neverFar bool, ctxHook func(*Context)) (*Context, []error) { 26*1fa6dee9SAndroid Build Coastguard Worker ctx := newContext() 27*1fa6dee9SAndroid Build Coastguard Worker ctx.MockFileSystem(map[string][]byte{ 28*1fa6dee9SAndroid Build Coastguard Worker "Android.bp": []byte(bp), 29*1fa6dee9SAndroid Build Coastguard Worker }) 30*1fa6dee9SAndroid Build Coastguard Worker 31*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterBottomUpMutator("deps", depsMutator) 32*1fa6dee9SAndroid Build Coastguard Worker handle := ctx.RegisterTransitionMutator("transition", transitionTestMutator{}) 33*1fa6dee9SAndroid Build Coastguard Worker if neverFar { 34*1fa6dee9SAndroid Build Coastguard Worker handle.NeverFar() 35*1fa6dee9SAndroid Build Coastguard Worker } 36*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterBottomUpMutator("post_transition_deps", postTransitionDepsMutator).UsesReverseDependencies() 37*1fa6dee9SAndroid Build Coastguard Worker 38*1fa6dee9SAndroid Build Coastguard Worker ctx.RegisterModuleType("transition_module", newTransitionModule) 39*1fa6dee9SAndroid Build Coastguard Worker 40*1fa6dee9SAndroid Build Coastguard Worker if ctxHook != nil { 41*1fa6dee9SAndroid Build Coastguard Worker ctxHook(ctx) 42*1fa6dee9SAndroid Build Coastguard Worker } 43*1fa6dee9SAndroid Build Coastguard Worker 44*1fa6dee9SAndroid Build Coastguard Worker _, errs := ctx.ParseBlueprintsFiles("Android.bp", nil) 45*1fa6dee9SAndroid Build Coastguard Worker if len(errs) > 0 { 46*1fa6dee9SAndroid Build Coastguard Worker return nil, errs 47*1fa6dee9SAndroid Build Coastguard Worker } 48*1fa6dee9SAndroid Build Coastguard Worker 49*1fa6dee9SAndroid Build Coastguard Worker _, errs = ctx.ResolveDependencies(nil) 50*1fa6dee9SAndroid Build Coastguard Worker if len(errs) > 0 { 51*1fa6dee9SAndroid Build Coastguard Worker return nil, errs 52*1fa6dee9SAndroid Build Coastguard Worker } 53*1fa6dee9SAndroid Build Coastguard Worker 54*1fa6dee9SAndroid Build Coastguard Worker return ctx, nil 55*1fa6dee9SAndroid Build Coastguard Worker} 56*1fa6dee9SAndroid Build Coastguard Worker 57*1fa6dee9SAndroid Build Coastguard Workerfunc testTransition(bp string) (*Context, []error) { 58*1fa6dee9SAndroid Build Coastguard Worker return testTransitionCommon(bp, false, nil) 59*1fa6dee9SAndroid Build Coastguard Worker} 60*1fa6dee9SAndroid Build Coastguard Worker 61*1fa6dee9SAndroid Build Coastguard Workerfunc testTransitionNeverFar(bp string) (*Context, []error) { 62*1fa6dee9SAndroid Build Coastguard Worker return testTransitionCommon(bp, true, nil) 63*1fa6dee9SAndroid Build Coastguard Worker} 64*1fa6dee9SAndroid Build Coastguard Worker 65*1fa6dee9SAndroid Build Coastguard Workerfunc testTransitionAllowMissingDeps(bp string) (*Context, []error) { 66*1fa6dee9SAndroid Build Coastguard Worker return testTransitionCommon(bp, false, func(ctx *Context) { 67*1fa6dee9SAndroid Build Coastguard Worker ctx.SetAllowMissingDependencies(true) 68*1fa6dee9SAndroid Build Coastguard Worker }) 69*1fa6dee9SAndroid Build Coastguard Worker} 70*1fa6dee9SAndroid Build Coastguard Worker 71*1fa6dee9SAndroid Build Coastguard Workerfunc assertNoErrors(t *testing.T, errs []error) { 72*1fa6dee9SAndroid Build Coastguard Worker t.Helper() 73*1fa6dee9SAndroid Build Coastguard Worker if len(errs) > 0 { 74*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("unexpected errors:") 75*1fa6dee9SAndroid Build Coastguard Worker for _, err := range errs { 76*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" %s", err) 77*1fa6dee9SAndroid Build Coastguard Worker } 78*1fa6dee9SAndroid Build Coastguard Worker t.FailNow() 79*1fa6dee9SAndroid Build Coastguard Worker } 80*1fa6dee9SAndroid Build Coastguard Worker} 81*1fa6dee9SAndroid Build Coastguard Worker 82*1fa6dee9SAndroid Build Coastguard Workerfunc assertOneErrorMatches(t *testing.T, errs []error, re string) { 83*1fa6dee9SAndroid Build Coastguard Worker t.Helper() 84*1fa6dee9SAndroid Build Coastguard Worker if len(errs) == 0 { 85*1fa6dee9SAndroid Build Coastguard Worker t.Fatalf("expected 1 error, but found 0") 86*1fa6dee9SAndroid Build Coastguard Worker } 87*1fa6dee9SAndroid Build Coastguard Worker if len(errs) > 1 { 88*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected exactly 1 error, but found:") 89*1fa6dee9SAndroid Build Coastguard Worker for _, err := range errs { 90*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" %s", err) 91*1fa6dee9SAndroid Build Coastguard Worker } 92*1fa6dee9SAndroid Build Coastguard Worker t.FailNow() 93*1fa6dee9SAndroid Build Coastguard Worker } 94*1fa6dee9SAndroid Build Coastguard Worker if match, err := regexp.MatchString(re, errs[0].Error()); err != nil { 95*1fa6dee9SAndroid Build Coastguard Worker t.Fatal(err.Error()) 96*1fa6dee9SAndroid Build Coastguard Worker } else if !match { 97*1fa6dee9SAndroid Build Coastguard Worker t.Fatalf("expected error matching %q, but got: %q", re, errs[0].Error()) 98*1fa6dee9SAndroid Build Coastguard Worker } 99*1fa6dee9SAndroid Build Coastguard Worker} 100*1fa6dee9SAndroid Build Coastguard Worker 101*1fa6dee9SAndroid Build Coastguard Workerconst testTransitionBp = ` 102*1fa6dee9SAndroid Build Coastguard Worker transition_module { 103*1fa6dee9SAndroid Build Coastguard Worker name: "A", 104*1fa6dee9SAndroid Build Coastguard Worker deps: ["B", "C"], 105*1fa6dee9SAndroid Build Coastguard Worker split: ["b", "a"], 106*1fa6dee9SAndroid Build Coastguard Worker } 107*1fa6dee9SAndroid Build Coastguard Worker 108*1fa6dee9SAndroid Build Coastguard Worker transition_module { 109*1fa6dee9SAndroid Build Coastguard Worker name: "B", 110*1fa6dee9SAndroid Build Coastguard Worker deps: ["C"], 111*1fa6dee9SAndroid Build Coastguard Worker outgoing: "c", 112*1fa6dee9SAndroid Build Coastguard Worker %s 113*1fa6dee9SAndroid Build Coastguard Worker } 114*1fa6dee9SAndroid Build Coastguard Worker 115*1fa6dee9SAndroid Build Coastguard Worker transition_module { 116*1fa6dee9SAndroid Build Coastguard Worker name: "C", 117*1fa6dee9SAndroid Build Coastguard Worker deps: ["D"], 118*1fa6dee9SAndroid Build Coastguard Worker } 119*1fa6dee9SAndroid Build Coastguard Worker 120*1fa6dee9SAndroid Build Coastguard Worker transition_module { 121*1fa6dee9SAndroid Build Coastguard Worker name: "D", 122*1fa6dee9SAndroid Build Coastguard Worker incoming: "d", 123*1fa6dee9SAndroid Build Coastguard Worker deps: ["E"], 124*1fa6dee9SAndroid Build Coastguard Worker } 125*1fa6dee9SAndroid Build Coastguard Worker 126*1fa6dee9SAndroid Build Coastguard Worker transition_module { 127*1fa6dee9SAndroid Build Coastguard Worker name: "E", 128*1fa6dee9SAndroid Build Coastguard Worker } 129*1fa6dee9SAndroid Build Coastguard Worker 130*1fa6dee9SAndroid Build Coastguard Worker transition_module { 131*1fa6dee9SAndroid Build Coastguard Worker name: "F", 132*1fa6dee9SAndroid Build Coastguard Worker incoming: "", 133*1fa6dee9SAndroid Build Coastguard Worker } 134*1fa6dee9SAndroid Build Coastguard Worker 135*1fa6dee9SAndroid Build Coastguard Worker transition_module { 136*1fa6dee9SAndroid Build Coastguard Worker name: "G", 137*1fa6dee9SAndroid Build Coastguard Worker outgoing: "h", 138*1fa6dee9SAndroid Build Coastguard Worker %s 139*1fa6dee9SAndroid Build Coastguard Worker } 140*1fa6dee9SAndroid Build Coastguard Worker 141*1fa6dee9SAndroid Build Coastguard Worker transition_module { 142*1fa6dee9SAndroid Build Coastguard Worker name: "H", 143*1fa6dee9SAndroid Build Coastguard Worker split: ["h"], 144*1fa6dee9SAndroid Build Coastguard Worker } 145*1fa6dee9SAndroid Build Coastguard Worker ` 146*1fa6dee9SAndroid Build Coastguard Worker 147*1fa6dee9SAndroid Build Coastguard Workerfunc getTransitionModule(ctx *Context, name, variant string) *transitionModule { 148*1fa6dee9SAndroid Build Coastguard Worker group := ctx.moduleGroupFromName(name, nil) 149*1fa6dee9SAndroid Build Coastguard Worker module := group.moduleByVariantName(variant) 150*1fa6dee9SAndroid Build Coastguard Worker return module.logicModule.(*transitionModule) 151*1fa6dee9SAndroid Build Coastguard Worker} 152*1fa6dee9SAndroid Build Coastguard Worker 153*1fa6dee9SAndroid Build Coastguard Workerfunc checkTransitionVariants(t *testing.T, ctx *Context, name string, expectedVariants []string) { 154*1fa6dee9SAndroid Build Coastguard Worker t.Helper() 155*1fa6dee9SAndroid Build Coastguard Worker group := ctx.moduleGroupFromName(name, nil) 156*1fa6dee9SAndroid Build Coastguard Worker var gotVariants []string 157*1fa6dee9SAndroid Build Coastguard Worker for _, module := range group.modules { 158*1fa6dee9SAndroid Build Coastguard Worker gotVariants = append(gotVariants, module.variant.variations.get("transition")) 159*1fa6dee9SAndroid Build Coastguard Worker } 160*1fa6dee9SAndroid Build Coastguard Worker if !slices.Equal(expectedVariants, gotVariants) { 161*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected variants of %q to be %q, got %q", name, expectedVariants, gotVariants) 162*1fa6dee9SAndroid Build Coastguard Worker } 163*1fa6dee9SAndroid Build Coastguard Worker} 164*1fa6dee9SAndroid Build Coastguard Worker 165*1fa6dee9SAndroid Build Coastguard Workerfunc checkTransitionDeps(t *testing.T, ctx *Context, m Module, expected ...string) { 166*1fa6dee9SAndroid Build Coastguard Worker t.Helper() 167*1fa6dee9SAndroid Build Coastguard Worker var got []string 168*1fa6dee9SAndroid Build Coastguard Worker ctx.VisitDirectDeps(m, func(m Module) { 169*1fa6dee9SAndroid Build Coastguard Worker got = append(got, ctx.ModuleName(m)+"("+ctx.ModuleSubDir(m)+")") 170*1fa6dee9SAndroid Build Coastguard Worker }) 171*1fa6dee9SAndroid Build Coastguard Worker if !slices.Equal(got, expected) { 172*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("unexpected %q dependencies, got %q expected %q", 173*1fa6dee9SAndroid Build Coastguard Worker ctx.ModuleName(m), got, expected) 174*1fa6dee9SAndroid Build Coastguard Worker } 175*1fa6dee9SAndroid Build Coastguard Worker} 176*1fa6dee9SAndroid Build Coastguard Worker 177*1fa6dee9SAndroid Build Coastguard Workerfunc checkTransitionMutate(t *testing.T, m *transitionModule, variant string) { 178*1fa6dee9SAndroid Build Coastguard Worker t.Helper() 179*1fa6dee9SAndroid Build Coastguard Worker if m.properties.Mutated != variant { 180*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("unexpected mutated property in %q, expected %q got %q", m.Name(), variant, m.properties.Mutated) 181*1fa6dee9SAndroid Build Coastguard Worker } 182*1fa6dee9SAndroid Build Coastguard Worker} 183*1fa6dee9SAndroid Build Coastguard Worker 184*1fa6dee9SAndroid Build Coastguard Workerfunc TestTransition(t *testing.T) { 185*1fa6dee9SAndroid Build Coastguard Worker ctx, errs := testTransition(fmt.Sprintf(testTransitionBp, "", "")) 186*1fa6dee9SAndroid Build Coastguard Worker assertNoErrors(t, errs) 187*1fa6dee9SAndroid Build Coastguard Worker 188*1fa6dee9SAndroid Build Coastguard Worker // Module A uses Split to create a and b variants 189*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "A", []string{"b", "a"}) 190*1fa6dee9SAndroid Build Coastguard Worker // Module B inherits a and b variants from A 191*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "B", []string{"", "a", "b"}) 192*1fa6dee9SAndroid Build Coastguard Worker // Module C inherits a and b variants from A, but gets an outgoing c variant from B 193*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "C", []string{"", "a", "b", "c"}) 194*1fa6dee9SAndroid Build Coastguard Worker // Module D always has incoming variant d 195*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "D", []string{"", "d"}) 196*1fa6dee9SAndroid Build Coastguard Worker // Module E inherits d from D 197*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "E", []string{"", "d"}) 198*1fa6dee9SAndroid Build Coastguard Worker // Module F is untouched 199*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "F", []string{""}) 200*1fa6dee9SAndroid Build Coastguard Worker 201*1fa6dee9SAndroid Build Coastguard Worker A_a := getTransitionModule(ctx, "A", "a") 202*1fa6dee9SAndroid Build Coastguard Worker A_b := getTransitionModule(ctx, "A", "b") 203*1fa6dee9SAndroid Build Coastguard Worker B_a := getTransitionModule(ctx, "B", "a") 204*1fa6dee9SAndroid Build Coastguard Worker B_b := getTransitionModule(ctx, "B", "b") 205*1fa6dee9SAndroid Build Coastguard Worker C_a := getTransitionModule(ctx, "C", "a") 206*1fa6dee9SAndroid Build Coastguard Worker C_b := getTransitionModule(ctx, "C", "b") 207*1fa6dee9SAndroid Build Coastguard Worker C_c := getTransitionModule(ctx, "C", "c") 208*1fa6dee9SAndroid Build Coastguard Worker D_d := getTransitionModule(ctx, "D", "d") 209*1fa6dee9SAndroid Build Coastguard Worker E_d := getTransitionModule(ctx, "E", "d") 210*1fa6dee9SAndroid Build Coastguard Worker F := getTransitionModule(ctx, "F", "") 211*1fa6dee9SAndroid Build Coastguard Worker G := getTransitionModule(ctx, "G", "") 212*1fa6dee9SAndroid Build Coastguard Worker H_h := getTransitionModule(ctx, "H", "h") 213*1fa6dee9SAndroid Build Coastguard Worker 214*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, A_a, "B(a)", "C(a)") 215*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, A_b, "B(b)", "C(b)") 216*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, B_a, "C(c)") 217*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, B_b, "C(c)") 218*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, C_a, "D(d)") 219*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, C_b, "D(d)") 220*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, C_c, "D(d)") 221*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, D_d, "E(d)") 222*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, E_d) 223*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, F) 224*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, G) 225*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, H_h) 226*1fa6dee9SAndroid Build Coastguard Worker 227*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, A_a, "a") 228*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, A_b, "b") 229*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, B_a, "a") 230*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, B_b, "b") 231*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, C_a, "a") 232*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, C_b, "b") 233*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, C_c, "c") 234*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, D_d, "d") 235*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, E_d, "d") 236*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, F, "") 237*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, G, "") 238*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, H_h, "h") 239*1fa6dee9SAndroid Build Coastguard Worker} 240*1fa6dee9SAndroid Build Coastguard Worker 241*1fa6dee9SAndroid Build Coastguard Workerfunc TestPostTransitionDeps(t *testing.T) { 242*1fa6dee9SAndroid Build Coastguard Worker ctx, errs := testTransition(fmt.Sprintf(testTransitionBp, 243*1fa6dee9SAndroid Build Coastguard Worker `post_transition_deps: ["C", "D:late", "E:d", "F"],`, 244*1fa6dee9SAndroid Build Coastguard Worker `post_transition_deps: ["H"],`)) 245*1fa6dee9SAndroid Build Coastguard Worker assertNoErrors(t, errs) 246*1fa6dee9SAndroid Build Coastguard Worker 247*1fa6dee9SAndroid Build Coastguard Worker // Module A uses Split to create a and b variants 248*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "A", []string{"b", "a"}) 249*1fa6dee9SAndroid Build Coastguard Worker // Module B inherits a and b variants from A 250*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "B", []string{"", "a", "b"}) 251*1fa6dee9SAndroid Build Coastguard Worker // Module C inherits a and b variants from A, but gets an outgoing c variant from B 252*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "C", []string{"", "a", "b", "c"}) 253*1fa6dee9SAndroid Build Coastguard Worker // Module D always has incoming variant d 254*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "D", []string{"", "d"}) 255*1fa6dee9SAndroid Build Coastguard Worker // Module E inherits d from D 256*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "E", []string{"", "d"}) 257*1fa6dee9SAndroid Build Coastguard Worker // Module F is untouched 258*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "F", []string{""}) 259*1fa6dee9SAndroid Build Coastguard Worker 260*1fa6dee9SAndroid Build Coastguard Worker A_a := getTransitionModule(ctx, "A", "a") 261*1fa6dee9SAndroid Build Coastguard Worker A_b := getTransitionModule(ctx, "A", "b") 262*1fa6dee9SAndroid Build Coastguard Worker B_a := getTransitionModule(ctx, "B", "a") 263*1fa6dee9SAndroid Build Coastguard Worker B_b := getTransitionModule(ctx, "B", "b") 264*1fa6dee9SAndroid Build Coastguard Worker C_a := getTransitionModule(ctx, "C", "a") 265*1fa6dee9SAndroid Build Coastguard Worker C_b := getTransitionModule(ctx, "C", "b") 266*1fa6dee9SAndroid Build Coastguard Worker C_c := getTransitionModule(ctx, "C", "c") 267*1fa6dee9SAndroid Build Coastguard Worker D_d := getTransitionModule(ctx, "D", "d") 268*1fa6dee9SAndroid Build Coastguard Worker E_d := getTransitionModule(ctx, "E", "d") 269*1fa6dee9SAndroid Build Coastguard Worker F := getTransitionModule(ctx, "F", "") 270*1fa6dee9SAndroid Build Coastguard Worker G := getTransitionModule(ctx, "G", "") 271*1fa6dee9SAndroid Build Coastguard Worker H_h := getTransitionModule(ctx, "H", "h") 272*1fa6dee9SAndroid Build Coastguard Worker 273*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, A_a, "B(a)", "C(a)") 274*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, A_b, "B(b)", "C(b)") 275*1fa6dee9SAndroid Build Coastguard Worker // Verify post-mutator dependencies added to B. The first C(c) is a pre-mutator dependency. 276*1fa6dee9SAndroid Build Coastguard Worker // C(c) was added by C and rewritten by OutgoingTransition on B 277*1fa6dee9SAndroid Build Coastguard Worker // D(d) was added by D:late and rewritten by IncomingTransition on D 278*1fa6dee9SAndroid Build Coastguard Worker // E(d) was added by E:d 279*1fa6dee9SAndroid Build Coastguard Worker // F() was added by F and rewritten OutgoingTransition on B and then IncomingTransition on F 280*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, B_a, "C(c)", "C(c)", "D(d)", "E(d)", "F()") 281*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, B_b, "C(c)", "C(c)", "D(d)", "E(d)", "F()") 282*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, C_a, "D(d)") 283*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, C_b, "D(d)") 284*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, C_c, "D(d)") 285*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, D_d, "E(d)") 286*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, E_d) 287*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, F) 288*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, G, "H(h)") 289*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, H_h) 290*1fa6dee9SAndroid Build Coastguard Worker 291*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, A_a, "a") 292*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, A_b, "b") 293*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, B_a, "a") 294*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, B_b, "b") 295*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, C_a, "a") 296*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, C_b, "b") 297*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, C_c, "c") 298*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, D_d, "d") 299*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, E_d, "d") 300*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, F, "") 301*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, G, "") 302*1fa6dee9SAndroid Build Coastguard Worker checkTransitionMutate(t, H_h, "h") 303*1fa6dee9SAndroid Build Coastguard Worker} 304*1fa6dee9SAndroid Build Coastguard Worker 305*1fa6dee9SAndroid Build Coastguard Workerfunc TestPostTransitionReverseDeps(t *testing.T) { 306*1fa6dee9SAndroid Build Coastguard Worker ctx, errs := testTransition(` 307*1fa6dee9SAndroid Build Coastguard Worker transition_module { 308*1fa6dee9SAndroid Build Coastguard Worker name: "A", 309*1fa6dee9SAndroid Build Coastguard Worker split: ["a1", "a2"], 310*1fa6dee9SAndroid Build Coastguard Worker } 311*1fa6dee9SAndroid Build Coastguard Worker 312*1fa6dee9SAndroid Build Coastguard Worker transition_module { 313*1fa6dee9SAndroid Build Coastguard Worker name: "B", 314*1fa6dee9SAndroid Build Coastguard Worker split: ["a1", "a2"], 315*1fa6dee9SAndroid Build Coastguard Worker post_transition_reverse_deps: ["A"], 316*1fa6dee9SAndroid Build Coastguard Worker } 317*1fa6dee9SAndroid Build Coastguard Worker `) 318*1fa6dee9SAndroid Build Coastguard Worker assertNoErrors(t, errs) 319*1fa6dee9SAndroid Build Coastguard Worker 320*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "A", []string{"a1", "a2"}) 321*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "B", []string{"a1", "a2"}) 322*1fa6dee9SAndroid Build Coastguard Worker 323*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "A", "a1"), "B(a1)") 324*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "A", "a2"), "B(a2)") 325*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "B", "a1")) 326*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "B", "a2")) 327*1fa6dee9SAndroid Build Coastguard Worker} 328*1fa6dee9SAndroid Build Coastguard Worker 329*1fa6dee9SAndroid Build Coastguard Workerfunc TestPostTransitionReverseVariationDeps(t *testing.T) { 330*1fa6dee9SAndroid Build Coastguard Worker ctx, errs := testTransition(` 331*1fa6dee9SAndroid Build Coastguard Worker transition_module { 332*1fa6dee9SAndroid Build Coastguard Worker name: "A", 333*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 334*1fa6dee9SAndroid Build Coastguard Worker } 335*1fa6dee9SAndroid Build Coastguard Worker 336*1fa6dee9SAndroid Build Coastguard Worker transition_module { 337*1fa6dee9SAndroid Build Coastguard Worker name: "B", 338*1fa6dee9SAndroid Build Coastguard Worker split: ["b"], 339*1fa6dee9SAndroid Build Coastguard Worker post_transition_reverse_variation_deps: ["A(a)"], 340*1fa6dee9SAndroid Build Coastguard Worker } 341*1fa6dee9SAndroid Build Coastguard Worker `) 342*1fa6dee9SAndroid Build Coastguard Worker assertNoErrors(t, errs) 343*1fa6dee9SAndroid Build Coastguard Worker 344*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "A", []string{"a"}) 345*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "B", []string{"b"}) 346*1fa6dee9SAndroid Build Coastguard Worker 347*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "A", "a"), "B(b)") 348*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "B", "b")) 349*1fa6dee9SAndroid Build Coastguard Worker} 350*1fa6dee9SAndroid Build Coastguard Worker 351*1fa6dee9SAndroid Build Coastguard Workerfunc TestFarVariationDep(t *testing.T) { 352*1fa6dee9SAndroid Build Coastguard Worker ctx, errs := testTransition(` 353*1fa6dee9SAndroid Build Coastguard Worker transition_module { 354*1fa6dee9SAndroid Build Coastguard Worker name: "A", 355*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 356*1fa6dee9SAndroid Build Coastguard Worker deps: ["B"], 357*1fa6dee9SAndroid Build Coastguard Worker } 358*1fa6dee9SAndroid Build Coastguard Worker transition_module { 359*1fa6dee9SAndroid Build Coastguard Worker name: "B", 360*1fa6dee9SAndroid Build Coastguard Worker split: ["", "a"], 361*1fa6dee9SAndroid Build Coastguard Worker } 362*1fa6dee9SAndroid Build Coastguard Worker transition_module { 363*1fa6dee9SAndroid Build Coastguard Worker name: "C", 364*1fa6dee9SAndroid Build Coastguard Worker split: ["c"], 365*1fa6dee9SAndroid Build Coastguard Worker post_transition_far_deps: ["D"], 366*1fa6dee9SAndroid Build Coastguard Worker } 367*1fa6dee9SAndroid Build Coastguard Worker transition_module { 368*1fa6dee9SAndroid Build Coastguard Worker name: "D", 369*1fa6dee9SAndroid Build Coastguard Worker split: ["", "c"], 370*1fa6dee9SAndroid Build Coastguard Worker } 371*1fa6dee9SAndroid Build Coastguard Worker `) 372*1fa6dee9SAndroid Build Coastguard Worker assertNoErrors(t, errs) 373*1fa6dee9SAndroid Build Coastguard Worker 374*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "A", []string{"a"}) 375*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "B", []string{"", "a"}) 376*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "C", []string{"c"}) 377*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "D", []string{"", "c"}) 378*1fa6dee9SAndroid Build Coastguard Worker 379*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "A", "a"), "B(a)") 380*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "C", "c"), "D()") 381*1fa6dee9SAndroid Build Coastguard Worker} 382*1fa6dee9SAndroid Build Coastguard Worker 383*1fa6dee9SAndroid Build Coastguard Workerfunc TestNeverFarFarVariationDep(t *testing.T) { 384*1fa6dee9SAndroid Build Coastguard Worker ctx, errs := testTransitionNeverFar(` 385*1fa6dee9SAndroid Build Coastguard Worker transition_module { 386*1fa6dee9SAndroid Build Coastguard Worker name: "A", 387*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 388*1fa6dee9SAndroid Build Coastguard Worker deps: ["B"], 389*1fa6dee9SAndroid Build Coastguard Worker } 390*1fa6dee9SAndroid Build Coastguard Worker transition_module { 391*1fa6dee9SAndroid Build Coastguard Worker name: "B", 392*1fa6dee9SAndroid Build Coastguard Worker split: ["", "a"], 393*1fa6dee9SAndroid Build Coastguard Worker } 394*1fa6dee9SAndroid Build Coastguard Worker transition_module { 395*1fa6dee9SAndroid Build Coastguard Worker name: "C", 396*1fa6dee9SAndroid Build Coastguard Worker split: ["c"], 397*1fa6dee9SAndroid Build Coastguard Worker post_transition_far_deps: ["D"], 398*1fa6dee9SAndroid Build Coastguard Worker } 399*1fa6dee9SAndroid Build Coastguard Worker transition_module { 400*1fa6dee9SAndroid Build Coastguard Worker name: "D", 401*1fa6dee9SAndroid Build Coastguard Worker split: ["", "c"], 402*1fa6dee9SAndroid Build Coastguard Worker } 403*1fa6dee9SAndroid Build Coastguard Worker `) 404*1fa6dee9SAndroid Build Coastguard Worker assertNoErrors(t, errs) 405*1fa6dee9SAndroid Build Coastguard Worker 406*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "A", []string{"a"}) 407*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "B", []string{"", "a"}) 408*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "C", []string{"c"}) 409*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "D", []string{"", "c"}) 410*1fa6dee9SAndroid Build Coastguard Worker 411*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "A", "a"), "B(a)") 412*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "C", "c"), "D(c)") 413*1fa6dee9SAndroid Build Coastguard Worker} 414*1fa6dee9SAndroid Build Coastguard Worker 415*1fa6dee9SAndroid Build Coastguard Workerfunc TestPostTransitionReverseDepsErrorOnMissingDep(t *testing.T) { 416*1fa6dee9SAndroid Build Coastguard Worker _, errs := testTransition(` 417*1fa6dee9SAndroid Build Coastguard Worker transition_module { 418*1fa6dee9SAndroid Build Coastguard Worker name: "A", 419*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 420*1fa6dee9SAndroid Build Coastguard Worker } 421*1fa6dee9SAndroid Build Coastguard Worker 422*1fa6dee9SAndroid Build Coastguard Worker transition_module { 423*1fa6dee9SAndroid Build Coastguard Worker name: "B", 424*1fa6dee9SAndroid Build Coastguard Worker split: ["b"], 425*1fa6dee9SAndroid Build Coastguard Worker post_transition_reverse_deps: ["A"], 426*1fa6dee9SAndroid Build Coastguard Worker } 427*1fa6dee9SAndroid Build Coastguard Worker `) 428*1fa6dee9SAndroid Build Coastguard Worker assertOneErrorMatches(t, errs, `reverse dependency "A" of "B" missing variant:\s*transition:b\s*available variants:\s*transition:a`) 429*1fa6dee9SAndroid Build Coastguard Worker} 430*1fa6dee9SAndroid Build Coastguard Worker 431*1fa6dee9SAndroid Build Coastguard Workerfunc TestErrorInIncomingTransition(t *testing.T) { 432*1fa6dee9SAndroid Build Coastguard Worker _, errs := testTransition(` 433*1fa6dee9SAndroid Build Coastguard Worker transition_module { 434*1fa6dee9SAndroid Build Coastguard Worker name: "A", 435*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 436*1fa6dee9SAndroid Build Coastguard Worker deps: ["B"], 437*1fa6dee9SAndroid Build Coastguard Worker } 438*1fa6dee9SAndroid Build Coastguard Worker transition_module { 439*1fa6dee9SAndroid Build Coastguard Worker name: "B", 440*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 441*1fa6dee9SAndroid Build Coastguard Worker incoming_transition_error: "my incoming transition error", 442*1fa6dee9SAndroid Build Coastguard Worker } 443*1fa6dee9SAndroid Build Coastguard Worker `) 444*1fa6dee9SAndroid Build Coastguard Worker assertOneErrorMatches(t, errs, "my incoming transition error") 445*1fa6dee9SAndroid Build Coastguard Worker} 446*1fa6dee9SAndroid Build Coastguard Worker 447*1fa6dee9SAndroid Build Coastguard Workerfunc TestErrorInOutgoingTransition(t *testing.T) { 448*1fa6dee9SAndroid Build Coastguard Worker _, errs := testTransition(` 449*1fa6dee9SAndroid Build Coastguard Worker transition_module { 450*1fa6dee9SAndroid Build Coastguard Worker name: "A", 451*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 452*1fa6dee9SAndroid Build Coastguard Worker deps: ["B"], 453*1fa6dee9SAndroid Build Coastguard Worker outgoing_transition_error: "my outgoing transition error", 454*1fa6dee9SAndroid Build Coastguard Worker } 455*1fa6dee9SAndroid Build Coastguard Worker transition_module { 456*1fa6dee9SAndroid Build Coastguard Worker name: "B", 457*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 458*1fa6dee9SAndroid Build Coastguard Worker } 459*1fa6dee9SAndroid Build Coastguard Worker `) 460*1fa6dee9SAndroid Build Coastguard Worker assertOneErrorMatches(t, errs, "my outgoing transition error") 461*1fa6dee9SAndroid Build Coastguard Worker} 462*1fa6dee9SAndroid Build Coastguard Worker 463*1fa6dee9SAndroid Build Coastguard Workerfunc TestPostTransitionReverseDepsAllowMissingDeps(t *testing.T) { 464*1fa6dee9SAndroid Build Coastguard Worker _, errs := testTransitionAllowMissingDeps(` 465*1fa6dee9SAndroid Build Coastguard Worker transition_module { 466*1fa6dee9SAndroid Build Coastguard Worker name: "A", 467*1fa6dee9SAndroid Build Coastguard Worker split: ["a"], 468*1fa6dee9SAndroid Build Coastguard Worker } 469*1fa6dee9SAndroid Build Coastguard Worker 470*1fa6dee9SAndroid Build Coastguard Worker transition_module { 471*1fa6dee9SAndroid Build Coastguard Worker name: "B", 472*1fa6dee9SAndroid Build Coastguard Worker split: ["b"], 473*1fa6dee9SAndroid Build Coastguard Worker post_transition_reverse_deps: ["A"], 474*1fa6dee9SAndroid Build Coastguard Worker } 475*1fa6dee9SAndroid Build Coastguard Worker `) 476*1fa6dee9SAndroid Build Coastguard Worker assertNoErrors(t, errs) 477*1fa6dee9SAndroid Build Coastguard Worker} 478*1fa6dee9SAndroid Build Coastguard Worker 479*1fa6dee9SAndroid Build Coastguard Workerfunc TestPostTransitionDepsMissingVariant(t *testing.T) { 480*1fa6dee9SAndroid Build Coastguard Worker // TODO: eventually this will create the missing variant on demand 481*1fa6dee9SAndroid Build Coastguard Worker _, errs := testTransition(fmt.Sprintf(testTransitionBp, 482*1fa6dee9SAndroid Build Coastguard Worker `post_transition_deps: ["E:missing"],`, "")) 483*1fa6dee9SAndroid Build Coastguard Worker expectedError := `Android.bp:8:4: dependency "E" of "B" missing variant: 484*1fa6dee9SAndroid Build Coastguard Worker transition:missing 485*1fa6dee9SAndroid Build Coastguard Workeravailable variants: 486*1fa6dee9SAndroid Build Coastguard Worker <empty variant> 487*1fa6dee9SAndroid Build Coastguard Worker transition:d` 488*1fa6dee9SAndroid Build Coastguard Worker if len(errs) != 1 || errs[0].Error() != expectedError { 489*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected error %q, got %q", expectedError, errs) 490*1fa6dee9SAndroid Build Coastguard Worker } 491*1fa6dee9SAndroid Build Coastguard Worker} 492*1fa6dee9SAndroid Build Coastguard Worker 493*1fa6dee9SAndroid Build Coastguard Workerfunc TestIsAddingDependency(t *testing.T) { 494*1fa6dee9SAndroid Build Coastguard Worker ctx, errs := testTransition(` 495*1fa6dee9SAndroid Build Coastguard Worker transition_module { 496*1fa6dee9SAndroid Build Coastguard Worker name: "A", 497*1fa6dee9SAndroid Build Coastguard Worker split: ["a1"], 498*1fa6dee9SAndroid Build Coastguard Worker deps: ["C"], 499*1fa6dee9SAndroid Build Coastguard Worker } 500*1fa6dee9SAndroid Build Coastguard Worker 501*1fa6dee9SAndroid Build Coastguard Worker transition_module { 502*1fa6dee9SAndroid Build Coastguard Worker name: "B", 503*1fa6dee9SAndroid Build Coastguard Worker split: ["b1"], 504*1fa6dee9SAndroid Build Coastguard Worker post_transition_deps: ["C"], 505*1fa6dee9SAndroid Build Coastguard Worker } 506*1fa6dee9SAndroid Build Coastguard Worker 507*1fa6dee9SAndroid Build Coastguard Worker transition_module { 508*1fa6dee9SAndroid Build Coastguard Worker name: "C", 509*1fa6dee9SAndroid Build Coastguard Worker split: ["c1", "c2"], 510*1fa6dee9SAndroid Build Coastguard Worker incoming: "c1", 511*1fa6dee9SAndroid Build Coastguard Worker post_transition_incoming: "c2", 512*1fa6dee9SAndroid Build Coastguard Worker } 513*1fa6dee9SAndroid Build Coastguard Worker `) 514*1fa6dee9SAndroid Build Coastguard Worker assertNoErrors(t, errs) 515*1fa6dee9SAndroid Build Coastguard Worker 516*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "A", []string{"a1"}) 517*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "B", []string{"b1"}) 518*1fa6dee9SAndroid Build Coastguard Worker checkTransitionVariants(t, ctx, "C", []string{"c1", "c2"}) 519*1fa6dee9SAndroid Build Coastguard Worker 520*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "A", "a1"), "C(c1)") 521*1fa6dee9SAndroid Build Coastguard Worker checkTransitionDeps(t, ctx, getTransitionModule(ctx, "B", "b1"), "C(c2)") 522*1fa6dee9SAndroid Build Coastguard Worker} 523*1fa6dee9SAndroid Build Coastguard Worker 524*1fa6dee9SAndroid Build Coastguard Workertype transitionTestMutator struct{} 525*1fa6dee9SAndroid Build Coastguard Worker 526*1fa6dee9SAndroid Build Coastguard Workerfunc (transitionTestMutator) Split(ctx BaseModuleContext) []string { 527*1fa6dee9SAndroid Build Coastguard Worker if split := ctx.Module().(*transitionModule).properties.Split; len(split) > 0 { 528*1fa6dee9SAndroid Build Coastguard Worker return split 529*1fa6dee9SAndroid Build Coastguard Worker } 530*1fa6dee9SAndroid Build Coastguard Worker return []string{""} 531*1fa6dee9SAndroid Build Coastguard Worker} 532*1fa6dee9SAndroid Build Coastguard Worker 533*1fa6dee9SAndroid Build Coastguard Workerfunc (transitionTestMutator) OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string { 534*1fa6dee9SAndroid Build Coastguard Worker if err := ctx.Module().(*transitionModule).properties.Outgoing_transition_error; err != nil { 535*1fa6dee9SAndroid Build Coastguard Worker ctx.ModuleErrorf("Error: %s", *err) 536*1fa6dee9SAndroid Build Coastguard Worker } 537*1fa6dee9SAndroid Build Coastguard Worker if outgoing := ctx.Module().(*transitionModule).properties.Outgoing; outgoing != nil { 538*1fa6dee9SAndroid Build Coastguard Worker return *outgoing 539*1fa6dee9SAndroid Build Coastguard Worker } 540*1fa6dee9SAndroid Build Coastguard Worker return sourceVariation 541*1fa6dee9SAndroid Build Coastguard Worker} 542*1fa6dee9SAndroid Build Coastguard Worker 543*1fa6dee9SAndroid Build Coastguard Workerfunc (transitionTestMutator) IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string { 544*1fa6dee9SAndroid Build Coastguard Worker if err := ctx.Module().(*transitionModule).properties.Incoming_transition_error; err != nil { 545*1fa6dee9SAndroid Build Coastguard Worker ctx.ModuleErrorf("Error: %s", *err) 546*1fa6dee9SAndroid Build Coastguard Worker } 547*1fa6dee9SAndroid Build Coastguard Worker if ctx.IsAddingDependency() { 548*1fa6dee9SAndroid Build Coastguard Worker if incoming := ctx.Module().(*transitionModule).properties.Post_transition_incoming; incoming != nil { 549*1fa6dee9SAndroid Build Coastguard Worker return *incoming 550*1fa6dee9SAndroid Build Coastguard Worker } 551*1fa6dee9SAndroid Build Coastguard Worker } 552*1fa6dee9SAndroid Build Coastguard Worker if incoming := ctx.Module().(*transitionModule).properties.Incoming; incoming != nil { 553*1fa6dee9SAndroid Build Coastguard Worker return *incoming 554*1fa6dee9SAndroid Build Coastguard Worker } 555*1fa6dee9SAndroid Build Coastguard Worker return incomingVariation 556*1fa6dee9SAndroid Build Coastguard Worker} 557*1fa6dee9SAndroid Build Coastguard Worker 558*1fa6dee9SAndroid Build Coastguard Workerfunc (transitionTestMutator) Mutate(ctx BottomUpMutatorContext, variation string) { 559*1fa6dee9SAndroid Build Coastguard Worker ctx.Module().(*transitionModule).properties.Mutated = variation 560*1fa6dee9SAndroid Build Coastguard Worker} 561*1fa6dee9SAndroid Build Coastguard Worker 562*1fa6dee9SAndroid Build Coastguard Workertype transitionModule struct { 563*1fa6dee9SAndroid Build Coastguard Worker SimpleName 564*1fa6dee9SAndroid Build Coastguard Worker properties struct { 565*1fa6dee9SAndroid Build Coastguard Worker Deps []string 566*1fa6dee9SAndroid Build Coastguard Worker Post_transition_deps []string 567*1fa6dee9SAndroid Build Coastguard Worker Post_transition_far_deps []string 568*1fa6dee9SAndroid Build Coastguard Worker Post_transition_reverse_deps []string 569*1fa6dee9SAndroid Build Coastguard Worker Post_transition_reverse_variation_deps []string 570*1fa6dee9SAndroid Build Coastguard Worker Split []string 571*1fa6dee9SAndroid Build Coastguard Worker Outgoing *string 572*1fa6dee9SAndroid Build Coastguard Worker Incoming *string 573*1fa6dee9SAndroid Build Coastguard Worker Post_transition_incoming *string 574*1fa6dee9SAndroid Build Coastguard Worker Outgoing_transition_error *string 575*1fa6dee9SAndroid Build Coastguard Worker Incoming_transition_error *string 576*1fa6dee9SAndroid Build Coastguard Worker 577*1fa6dee9SAndroid Build Coastguard Worker Mutated string `blueprint:"mutated"` 578*1fa6dee9SAndroid Build Coastguard Worker } 579*1fa6dee9SAndroid Build Coastguard Worker} 580*1fa6dee9SAndroid Build Coastguard Worker 581*1fa6dee9SAndroid Build Coastguard Workerfunc newTransitionModule() (Module, []interface{}) { 582*1fa6dee9SAndroid Build Coastguard Worker m := &transitionModule{} 583*1fa6dee9SAndroid Build Coastguard Worker return m, []interface{}{&m.properties, &m.SimpleName.Properties} 584*1fa6dee9SAndroid Build Coastguard Worker} 585*1fa6dee9SAndroid Build Coastguard Worker 586*1fa6dee9SAndroid Build Coastguard Workerfunc (f *transitionModule) GenerateBuildActions(ModuleContext) { 587*1fa6dee9SAndroid Build Coastguard Worker} 588*1fa6dee9SAndroid Build Coastguard Worker 589*1fa6dee9SAndroid Build Coastguard Workerfunc (f *transitionModule) Deps() []string { 590*1fa6dee9SAndroid Build Coastguard Worker return f.properties.Deps 591*1fa6dee9SAndroid Build Coastguard Worker} 592*1fa6dee9SAndroid Build Coastguard Worker 593*1fa6dee9SAndroid Build Coastguard Workerfunc (f *transitionModule) IgnoreDeps() []string { 594*1fa6dee9SAndroid Build Coastguard Worker return nil 595*1fa6dee9SAndroid Build Coastguard Worker} 596*1fa6dee9SAndroid Build Coastguard Worker 597*1fa6dee9SAndroid Build Coastguard Workervar nameAndVariantRegexp = regexp.MustCompile(`([a-zA-Z0-9_]+)\(([a-zA-Z0-9_]+)\)`) 598*1fa6dee9SAndroid Build Coastguard Worker 599*1fa6dee9SAndroid Build Coastguard Workerfunc postTransitionDepsMutator(mctx BottomUpMutatorContext) { 600*1fa6dee9SAndroid Build Coastguard Worker if m, ok := mctx.Module().(*transitionModule); ok { 601*1fa6dee9SAndroid Build Coastguard Worker for _, dep := range m.properties.Post_transition_deps { 602*1fa6dee9SAndroid Build Coastguard Worker module, variation, _ := strings.Cut(dep, ":") 603*1fa6dee9SAndroid Build Coastguard Worker var variations []Variation 604*1fa6dee9SAndroid Build Coastguard Worker if variation != "" { 605*1fa6dee9SAndroid Build Coastguard Worker variations = append(variations, Variation{"transition", variation}) 606*1fa6dee9SAndroid Build Coastguard Worker } 607*1fa6dee9SAndroid Build Coastguard Worker mctx.AddVariationDependencies(variations, walkerDepsTag{follow: true}, module) 608*1fa6dee9SAndroid Build Coastguard Worker } 609*1fa6dee9SAndroid Build Coastguard Worker for _, dep := range m.properties.Post_transition_far_deps { 610*1fa6dee9SAndroid Build Coastguard Worker mctx.AddFarVariationDependencies(nil, walkerDepsTag{follow: true}, dep) 611*1fa6dee9SAndroid Build Coastguard Worker } 612*1fa6dee9SAndroid Build Coastguard Worker for _, dep := range m.properties.Post_transition_reverse_deps { 613*1fa6dee9SAndroid Build Coastguard Worker mctx.AddReverseDependency(m, walkerDepsTag{follow: true}, dep) 614*1fa6dee9SAndroid Build Coastguard Worker } 615*1fa6dee9SAndroid Build Coastguard Worker for _, dep := range m.properties.Post_transition_reverse_variation_deps { 616*1fa6dee9SAndroid Build Coastguard Worker match := nameAndVariantRegexp.FindStringSubmatch(dep) 617*1fa6dee9SAndroid Build Coastguard Worker if len(match) == 0 || match[0] != dep { 618*1fa6dee9SAndroid Build Coastguard Worker panic(fmt.Sprintf("Invalid Post_transition_reverse_variation_deps: %q. Expected module_name(variant)", dep)) 619*1fa6dee9SAndroid Build Coastguard Worker } 620*1fa6dee9SAndroid Build Coastguard Worker mctx.AddReverseVariationDependency([]Variation{ 621*1fa6dee9SAndroid Build Coastguard Worker {Mutator: "transition", Variation: match[2]}, 622*1fa6dee9SAndroid Build Coastguard Worker }, walkerDepsTag{follow: true}, match[1]) 623*1fa6dee9SAndroid Build Coastguard Worker } 624*1fa6dee9SAndroid Build Coastguard Worker } 625*1fa6dee9SAndroid Build Coastguard Worker} 626