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

Method TestBalancerSwitch_Graceful

test/balancer_switching_test.go:455–530  ·  view source on GitHub ↗

TestBalancerSwitch_Graceful tests the graceful switching of LB policies. It starts off by configuring "round_robin" on the channel and ensures that RPCs are successful. Then, it switches to a stub balancer which does not report a picker until instructed by the test do to so. At this point, the test

(t *testing.T)

Source from the content-addressed store, hash-verified

453// asks the new balancer to report a healthy picker and the test verifies that
454// the RPCs get routed using the picker reported by the new balancer.
455func (s) TestBalancerSwitch_Graceful(t *testing.T) {
456 backends, cleanup := startBackendsForBalancerSwitch(t)
457 defer cleanup()
458 addrs := stubBackendsToResolverAddrs(backends)
459
460 r := manual.NewBuilderWithScheme("whatever")
461 cc, err := grpc.NewClient(r.Scheme()+":///test.server", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithResolvers(r))
462 if err != nil {
463 t.Fatalf("grpc.NewClient() failed: %v", err)
464 }
465 defer cc.Close()
466 cc.Connect()
467 // Push a resolver update with the service config specifying "round_robin".
468 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
469 defer cancel()
470 r.UpdateState(resolver.State{
471 Addresses: addrs[1:],
472 ServiceConfig: parseServiceConfig(t, r, rrServiceConfig),
473 })
474 client := testgrpc.NewTestServiceClient(cc)
475 if err := rrutil.CheckRoundRobinRPCs(ctx, client, addrs[1:]); err != nil {
476 t.Fatal(err)
477 }
478
479 // Register a stub balancer which uses a "pick_first" balancer underneath and
480 // signals on a channel when it receives ClientConn updates. But it does not
481 // forward the ccUpdate to the underlying "pick_first" balancer until the test
482 // asks it to do so. This allows us to test the graceful switch functionality.
483 // Until the test asks the stub balancer to forward the ccUpdate, RPCs should
484 // get routed to the old balancer. And once the test gives the go ahead, RPCs
485 // should get routed to the new balancer.
486 ccUpdateCh := make(chan struct{})
487 waitToProceed := make(chan struct{})
488 stub.Register(t.Name(), stub.BalancerFuncs{
489 Init: func(bd *stub.BalancerData) {
490 pf := balancer.Get(pickfirst.Name)
491 bd.ChildBalancer = pf.Build(bd.ClientConn, bd.BuildOptions)
492 },
493 Close: func(bd *stub.BalancerData) {
494 bd.ChildBalancer.Close()
495 },
496 UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error {
497 close(ccUpdateCh)
498 go func() {
499 <-waitToProceed
500 bd.ChildBalancer.UpdateClientConnState(ccs)
501 }()
502 return nil
503 },
504 })
505
506 // Push a resolver update with the service config specifying our stub
507 // balancer. We should see a trace event for this balancer switch. But RPCs
508 // should still be routed to the old balancer since our stub balancer does not
509 // report a ready picker until we ask it to do so.
510 r.UpdateState(resolver.State{
511 Addresses: addrs[:1],
512 ServiceConfig: r.CC().ParseServiceConfig(fmt.Sprintf(`{"loadBalancingConfig": [{"%v": {}}]}`, t.Name())),

Callers

nothing calls this directly

Calls 15

NewBuilderWithSchemeFunction · 0.92
NewClientFunction · 0.92
WithTransportCredentialsFunction · 0.92
NewCredentialsFunction · 0.92
WithResolversFunction · 0.92
RegisterFunction · 0.92
GetFunction · 0.92
CCMethod · 0.80
parseServiceConfigFunction · 0.70
SchemeMethod · 0.65

Tested by

no test coverage detected