Repository: grpc/grpc-go
File: test/balancer_test.go (Go)

Code before:
	// Register listener while Ready and verify it gets a health update.
	testutils.AwaitState(ctx, t, cc, connectivity.Ready)
	for i := 0; i < 2; i++ {
		sc.RegisterHealthListener(func(scs balancer.SubConnState) {
			healthUpdateChan <- scs
		})
		select {
		case scs := <-healthUpdateChan:
			if scs.ConnectivityState != connectivity.Ready {
				t.Fatalf("Received health update = %v, want = %v", scs.ConnectivityState, connectivity.Ready)
			}
		case <-ctx.Done():
			t.Fatalf("Context timed out waiting for health update")
		}

		// No further updates are expected.
		select {
		case scs := <-healthUpdateChan:
			t.Fatalf("Received unexpected health update while channel is in state %v: %v", cc.GetState(), scs)
		case <-time.After(defaultTestShortTimeout):
		}
	}

	// Enter Idle and register a health listener and verify the health update
	// again.
	internal.EnterIdleModeForTesting.(func(*grpc.ClientConn))(cc)
	cc.Connect()
	sc = <-scChan
	testutils.AwaitState(ctx, t, cc, connectivity.Ready)
	sc.RegisterHealthListener(func(scs balancer.SubConnState) {
		healthUpdateChan <- scs
	})
	select {
	case scs := <-healthUpdateChan:
		if scs.ConnectivityState != connectivity.Ready {
			t.Fatalf("Received health update = %v, want = %v", scs.ConnectivityState, connectivity.Ready)
		}
	case <-ctx.Done():
		t.Fatalf("Context timed out waiting for health update")
	}
}


Review comment (suggestion):
When the channel enters idle mode, the LB policy is closed, but the `testBalancer.Close` is a no-op. And subsequently when `Connect` is called, `ExitIdle` on the LB policy is called, and again `testBalancer.ExitIdle` is a no-op. So, I'm wondering what is being tested here.

Code after:
		},
	}

	stub.Register(t.Name(), bf)
	svcCfg := fmt.Sprintf(`{ "loadBalancingConfig": [{%q: {}}] }`, t.Name())
	backend := stubserver.StartTestService(t, nil)
	defer backend.Stop()
	opts := []grpc.DialOption{
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithDefaultServiceConfig(svcCfg),
	}
	cc, err := grpc.NewClient(backend.Address, opts...)
	if err != nil {
		t.Fatalf("grpc.NewClient(%q) failed: %v", backend.Address, err)

	}
	defer cc.Close()

	cc.Connect()

	var sc balancer.SubConn
	select {
	case sc = <-scChan:
	case <-ctx.Done():
		t.Fatal("Context timed out waiting for SubConn creation")
	}
	healthUpdateChan := make(chan balancer.SubConnState, 1)

	// Register listener while Ready and verify it gets a health update.
	testutils.AwaitState(ctx, t, cc, connectivity.Ready)
	for i := 0; i < 2; i++ {
		sc.RegisterHealthListener(func(scs balancer.SubConnState) {
			healthUpdateChan <- scs
		})
		select {
		case scs := <-healthUpdateChan:
			if scs.ConnectivityState != connectivity.Ready {
				t.Fatalf("Received health update = %v, want = %v", scs.ConnectivityState, connectivity.Ready)
			}
		case <-ctx.Done():
			t.Fatalf("Context timed out waiting for health update")
		}

		// No further updates are expected.
		select {
		case scs := <-healthUpdateChan:
			t.Fatalf("Received unexpected health update while channel is in state %v: %v", cc.GetState(), scs)
		case <-time.After(defaultTestShortTimeout):
		}
	}