diff options
author | Juanli Shen <juanlishen@google.com> | 2018-08-16 17:54:27 -0700 |
---|---|---|
committer | Juanli Shen <juanlishen@google.com> | 2018-08-16 17:54:27 -0700 |
commit | d19fd1c689b1d60cf329331da7fab5d1ca6063cc (patch) | |
tree | db70e1d361caa71f127ba30557210b3bb80ad40e /test | |
parent | 61dabce400f3b139205e8f983e167d9ed6e7e6d4 (diff) |
PF: Check connectivity state before watching
Diffstat (limited to 'test')
-rw-r--r-- | test/cpp/end2end/client_lb_end2end_test.cc | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 26c241b74a..68219c16dc 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -291,6 +291,17 @@ class ClientLbEnd2endTest : public ::testing::Test { ResetCounters(); } + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + bool SeenAllServers() { for (const auto& server : servers_) { if (server->service_.request_count() == 0) return false; @@ -590,6 +601,50 @@ TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { + std::vector<int> ports = {grpc_pick_unused_port_or_die()}; + StartServers(1, ports); + auto channel_1 = BuildChannel("pick_first"); + auto stub_1 = BuildStub(channel_1); + SetNextResolution(ports); + gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 1 *******"); + WaitForServer(stub_1, 0, DEBUG_LOCATION); + gpr_log(GPR_INFO, "****** CHANNEL 1 CONNECTED *******"); + servers_[0]->Shutdown(); + // Channel 1 will receive a re-resolution containing the same server. It will + // create a new subchannel and hold a ref to it. + servers_.clear(); + StartServers(1, ports); + gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); + auto channel_2 = BuildChannel("pick_first"); + auto stub_2 = BuildStub(channel_2); + // TODO(juanlishen): This resolution result will only be visible to channel 2 + // since the response generator is only associated with channel 2 now. We + // should change the response generator to be able to deliver updates to + // multiple channels at once. + SetNextResolution(ports); + gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******"); + WaitForServer(stub_2, 0, DEBUG_LOCATION, true); + gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******"); + servers_[0]->Shutdown(); + // Wait until the disconnection has triggered the connectivity notification. + // Otherwise, the subchannel may be picked for next call but will fail soon. + EXPECT_TRUE(WaitForChannelNotReady(channel_2.get())); + // Channel 2 will also receive a re-resolution containing the same server. + // Both channels will ref the same subchannel that failed. + servers_.clear(); + StartServers(1, ports); + gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******"); + gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******"); + // The first call after the server restart will succeed. + CheckRpcSendOk(stub_2, DEBUG_LOCATION); + gpr_log(GPR_INFO, "****** CHANNEL 2 FINISHED A CALL *******"); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_1->GetLoadBalancingPolicyName()); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_2->GetLoadBalancingPolicyName()); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; |