Test mocks the updates sent to the health listener and verifies that the balancer correctly reports the health state once the SubConn's connectivity state becomes READY.
(t *testing.T)
| 2500 | // balancer correctly reports the health state once the SubConn's connectivity |
| 2501 | // state becomes READY. |
| 2502 | func (s) TestPickFirstLeaf_HealthUpdates(t *testing.T) { |
| 2503 | // Wrap the clientconn to intercept NewSubConn. |
| 2504 | // Capture the health list by wrapping the SC. |
| 2505 | // Wrap the picker to unwrap the SC. |
| 2506 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 2507 | defer cancel() |
| 2508 | healthListenerCh := make(chan func(balancer.SubConnState)) |
| 2509 | scConnectivityStateCh := make(chan balancer.SubConnState, 5) |
| 2510 | |
| 2511 | bf := stub.BalancerFuncs{ |
| 2512 | Init: func(bd *stub.BalancerData) { |
| 2513 | ccw := &healthListenerCapturingCCWrapper{ |
| 2514 | ClientConn: bd.ClientConn, |
| 2515 | healthListenerCh: healthListenerCh, |
| 2516 | subConnStateCh: scConnectivityStateCh, |
| 2517 | } |
| 2518 | bd.ChildBalancer = balancer.Get(pfbalancer.Name).Build(ccw, bd.BuildOptions) |
| 2519 | }, |
| 2520 | Close: func(bd *stub.BalancerData) { |
| 2521 | bd.ChildBalancer.Close() |
| 2522 | }, |
| 2523 | UpdateClientConnState: func(bd *stub.BalancerData, ccs balancer.ClientConnState) error { |
| 2524 | ccs.ResolverState = pfbalancer.EnableHealthListener(ccs.ResolverState) |
| 2525 | return bd.ChildBalancer.UpdateClientConnState(ccs) |
| 2526 | }, |
| 2527 | } |
| 2528 | |
| 2529 | stub.Register(t.Name(), bf) |
| 2530 | svcCfg := fmt.Sprintf(`{ "loadBalancingConfig": [{%q: {}}] }`, t.Name()) |
| 2531 | backend := stubserver.StartTestService(t, nil) |
| 2532 | defer backend.Stop() |
| 2533 | opts := []grpc.DialOption{ |
| 2534 | grpc.WithTransportCredentials(insecure.NewCredentials()), |
| 2535 | grpc.WithDefaultServiceConfig(svcCfg), |
| 2536 | } |
| 2537 | cc, err := grpc.NewClient(backend.Address, opts...) |
| 2538 | if err != nil { |
| 2539 | t.Fatalf("grpc.NewClient(%q) failed: %v", backend.Address, err) |
| 2540 | |
| 2541 | } |
| 2542 | defer cc.Close() |
| 2543 | cc.Connect() |
| 2544 | |
| 2545 | var healthListener func(balancer.SubConnState) |
| 2546 | select { |
| 2547 | case healthListener = <-healthListenerCh: |
| 2548 | case <-ctx.Done(): |
| 2549 | t.Fatal("Context timed out waiting for health listener to be registered.") |
| 2550 | } |
| 2551 | |
| 2552 | // Wait for the raw connectivity state to become READY. The LB policy should |
| 2553 | // wait for the health updates before transitioning the channel to READY. |
| 2554 | for { |
| 2555 | var scs balancer.SubConnState |
| 2556 | select { |
| 2557 | case scs = <-scConnectivityStateCh: |
| 2558 | case <-ctx.Done(): |
| 2559 | t.Fatal("Context timed out waiting for the SubConn connectivity state to become READY.") |
nothing calls this directly
no test coverage detected