MCPcopy
hub / github.com/grpc/grpc-go / TestBalancerGracefulSwitch

Method TestBalancerGracefulSwitch

internal/balancergroup/balancergroup_test.go:642–760  ·  view source on GitHub ↗

TestBalancerGracefulSwitch tests the graceful switch functionality for a child of the balancer group. At first, the child is configured as a round robin load balancer, and thus should behave accordingly. The test then gracefully switches this child to a custom type which only creates a SubConn for t

(t *testing.T)

Source from the content-addressed store, hash-verified

640// for the second passed in address and also only picks that created SubConn.
641// The new aggregated picker should reflect this change for the child.
642func (s) TestBalancerGracefulSwitch(t *testing.T) {
643 cc := testutils.NewBalancerClientConn(t)
644 gator := weightedaggregator.New(cc, nil, testutils.NewTestWRR)
645 gator.Start()
646 bg := balancergroup.New(balancergroup.Options{
647 CC: cc,
648 BuildOpts: balancer.BuildOptions{},
649 StateAggregator: gator,
650 Logger: nil,
651 })
652 gator.Add(testBalancerIDs[0], 1)
653 bg.Add(testBalancerIDs[0], rrBuilder)
654 bg.UpdateClientConnState(testBalancerIDs[0], balancer.ClientConnState{ResolverState: resolver.State{Endpoints: testBackendEndpoints[0:2]}})
655
656 defer bg.Close()
657
658 m1 := make(map[string]balancer.SubConn)
659 scs := make(map[balancer.SubConn]bool)
660 for i := 0; i < 2; i++ {
661 addrs := <-cc.NewSubConnAddrsCh
662 sc := <-cc.NewSubConnCh
663 m1[addrs[0].Addr] = sc
664 scs[sc] = true
665 sc.UpdateState(balancer.SubConnState{ConnectivityState: connectivity.Connecting})
666 sc.UpdateState(balancer.SubConnState{ConnectivityState: connectivity.Ready})
667 }
668
669 p1 := <-cc.NewPickerCh
670 want := []balancer.SubConn{
671 m1[testBackendAddrs[0].Addr], m1[testBackendAddrs[1].Addr],
672 }
673 if err := testutils.IsRoundRobin(want, testutils.SubConnFromPicker(p1)); err != nil {
674 t.Fatal(err)
675 }
676
677 // The balancer type for testBalancersIDs[0] is currently Round Robin. Now,
678 // change it to a balancer that has separate behavior logically (creating
679 // SubConn for second address in address list and always picking that
680 // SubConn), and see if the downstream behavior reflects that change.
681 childPolicyName := t.Name()
682 stub.Register(childPolicyName, stub.BalancerFuncs{
683 Init: func(bd *stub.BalancerData) {
684 bd.ChildBalancer = balancer.Get(pickfirst.Name).Build(bd.ClientConn, bd.BuildOptions)
685 },
686 Close: func(bd *stub.BalancerData) {
687 bd.ChildBalancer.Close()
688 },
689 UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error {
690 ccs.ResolverState.Endpoints = ccs.ResolverState.Endpoints[1:]
691 return bd.ChildBalancer.UpdateClientConnState(ccs)
692 },
693 })
694 cfgJSON := json.RawMessage(fmt.Sprintf(`[{%q: {}}]`, t.Name()))
695 lbCfg, err := balancergroup.ParseConfig(cfgJSON)
696 if err != nil {
697 t.Fatalf("ParseConfig(%s) failed: %v", string(cfgJSON), err)
698 }
699 if err := bg.UpdateClientConnState(testBalancerIDs[0], balancer.ClientConnState{

Callers

nothing calls this directly

Calls 15

NewBalancerClientConnFunction · 0.92
NewFunction · 0.92
NewFunction · 0.92
IsRoundRobinFunction · 0.92
SubConnFromPickerFunction · 0.92
RegisterFunction · 0.92
GetFunction · 0.92
ParseConfigFunction · 0.92
StartMethod · 0.65
AddMethod · 0.65
UpdateClientConnStateMethod · 0.65
CloseMethod · 0.65

Tested by

no test coverage detected