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)
| 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. |
| 642 | func (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{ |
nothing calls this directly
no test coverage detected