aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Juanli Shen <juanlishen@google.com>2017-09-27 12:27:20 -0700
committerGravatar Juanli Shen <juanlishen@google.com>2017-09-27 12:27:20 -0700
commitfe40815682f7da0a7d6f09be2253d6660ef8e7a5 (patch)
tree8ffb0003467f24e1817747457bf2b5dbbf273235 /test
parent708163a0b440e1489549ce6093bdf6598a6fc78c (diff)
Readd grpclb fallback
Diffstat (limited to 'test')
-rw-r--r--test/cpp/end2end/grpclb_end2end_test.cc180
1 files changed, 176 insertions, 4 deletions
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index 77ed155292..f73a9c1791 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -368,8 +368,9 @@ class GrpclbEnd2endTest : public ::testing::Test {
grpc_fake_resolver_response_generator_unref(response_generator_);
}
- void ResetStub() {
+ void ResetStub(int fallback_timeout = 0) {
ChannelArguments args;
+ args.SetGrpclbFallbackTimeout(fallback_timeout);
args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
response_generator_);
std::ostringstream uri;
@@ -470,10 +471,10 @@ class GrpclbEnd2endTest : public ::testing::Test {
grpc_exec_ctx_finish(&exec_ctx);
}
- const std::vector<int> GetBackendPorts() const {
+ const std::vector<int> GetBackendPorts(const size_t start_index = 0) const {
std::vector<int> backend_ports;
- for (const auto& bs : backend_servers_) {
- backend_ports.push_back(bs.port_);
+ for (size_t i = start_index; i < backend_servers_.size(); ++i) {
+ backend_ports.push_back(backend_servers_[i].port_);
}
return backend_ports;
}
@@ -642,6 +643,177 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
}
+TEST_F(SingleBalancerTest, Fallback) {
+ const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor();
+ const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor();
+ const size_t kNumBackendInResolution = backends_.size() / 2;
+
+ ResetStub(kFallbackTimeoutMs);
+ std::vector<AddressData> addresses;
+ addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""});
+ for (size_t i = 0; i < kNumBackendInResolution; ++i) {
+ addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""});
+ }
+ SetNextResolution(addresses);
+
+ // Send non-empty serverlist only after kServerlistDelayMs.
+ ScheduleResponseForBalancer(
+ 0, BalancerServiceImpl::BuildResponseForBackends(
+ GetBackendPorts(kNumBackendInResolution /* start_index */), {}),
+ kServerlistDelayMs);
+
+ // Wait until all the fallback backends are reachable.
+ for (size_t i = 0; i < kNumBackendInResolution; ++i) {
+ WaitForBackend(i);
+ }
+
+ // The first request.
+ gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
+ CheckRpcSendOk(kNumBackendInResolution);
+ gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
+
+ // Fallback is used: each backend returned by the resolver should have
+ // gotten one request.
+ for (size_t i = 0; i < kNumBackendInResolution; ++i) {
+ EXPECT_EQ(1U, backend_servers_[i].service_->request_count());
+ }
+ for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) {
+ EXPECT_EQ(0U, backend_servers_[i].service_->request_count());
+ }
+
+ // Wait until the serverlist reception has been processed and all backends
+ // in the serverlist are reachable.
+ for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) {
+ WaitForBackend(i);
+ }
+
+ // Send out the second request.
+ gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH ==========");
+ CheckRpcSendOk(backends_.size() - kNumBackendInResolution);
+ gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH ==========");
+
+ // Serverlist is used: each backend returned by the balancer should
+ // have gotten one request.
+ for (size_t i = 0; i < kNumBackendInResolution; ++i) {
+ EXPECT_EQ(0U, backend_servers_[i].service_->request_count());
+ }
+ for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) {
+ EXPECT_EQ(1U, backend_servers_[i].service_->request_count());
+ }
+
+ balancers_[0]->NotifyDoneWithServerlists();
+ // The balancer got a single request.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
+ // and sent a single response.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->response_count());
+}
+
+TEST_F(SingleBalancerTest, FallbackUpdate) {
+ const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor();
+ const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor();
+ const size_t kNumBackendInResolution = backends_.size() / 3;
+ const size_t kNumBackendInResolutionUpdate = backends_.size() / 3;
+
+ ResetStub(kFallbackTimeoutMs);
+ std::vector<AddressData> addresses;
+ addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""});
+ for (size_t i = 0; i < kNumBackendInResolution; ++i) {
+ addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""});
+ }
+ SetNextResolution(addresses);
+
+ // Send non-empty serverlist only after kServerlistDelayMs.
+ ScheduleResponseForBalancer(
+ 0, BalancerServiceImpl::BuildResponseForBackends(
+ GetBackendPorts(kNumBackendInResolution +
+ kNumBackendInResolutionUpdate /* start_index */),
+ {}),
+ kServerlistDelayMs);
+
+ // Wait until all the fallback backends are reachable.
+ for (size_t i = 0; i < kNumBackendInResolution; ++i) {
+ WaitForBackend(i);
+ }
+
+ // The first request.
+ gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
+ CheckRpcSendOk(kNumBackendInResolution);
+ gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
+
+ // Fallback is used: each backend returned by the resolver should have
+ // gotten one request.
+ for (size_t i = 0; i < kNumBackendInResolution; ++i) {
+ EXPECT_EQ(1U, backend_servers_[i].service_->request_count());
+ }
+ for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) {
+ EXPECT_EQ(0U, backend_servers_[i].service_->request_count());
+ }
+
+ addresses.clear();
+ addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""});
+ for (size_t i = kNumBackendInResolution;
+ i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) {
+ addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""});
+ }
+ SetNextResolution(addresses);
+
+ // Wait until the resolution update has been processed and all the new
+ // fallback backends are reachable.
+ for (size_t i = kNumBackendInResolution;
+ i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) {
+ WaitForBackend(i);
+ }
+
+ // Send out the second request.
+ gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH ==========");
+ CheckRpcSendOk(kNumBackendInResolutionUpdate);
+ gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH ==========");
+
+ // The resolution update is used: each backend in the resolution update should
+ // have gotten one request.
+ for (size_t i = 0; i < kNumBackendInResolution; ++i) {
+ EXPECT_EQ(0U, backend_servers_[i].service_->request_count());
+ }
+ for (size_t i = kNumBackendInResolution;
+ i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) {
+ EXPECT_EQ(1U, backend_servers_[i].service_->request_count());
+ }
+ for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate;
+ i < backends_.size(); ++i) {
+ EXPECT_EQ(0U, backend_servers_[i].service_->request_count());
+ }
+
+ // Wait until the serverlist reception has been processed and all backends
+ // in the serverlist are reachable.
+ for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate;
+ i < backends_.size(); ++i) {
+ WaitForBackend(i);
+ }
+
+ // Send out the third request.
+ gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH ==========");
+ CheckRpcSendOk(backends_.size() - kNumBackendInResolution -
+ kNumBackendInResolutionUpdate);
+ gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH ==========");
+
+ // Serverlist is used: each backend returned by the balancer should
+ // have gotten one request.
+ for (size_t i = 0;
+ i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) {
+ EXPECT_EQ(0U, backend_servers_[i].service_->request_count());
+ }
+ for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate;
+ i < backends_.size(); ++i) {
+ EXPECT_EQ(1U, backend_servers_[i].service_->request_count());
+ }
+
+ balancers_[0]->NotifyDoneWithServerlists();
+ // The balancer got a single request.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
+ // and sent a single response.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->response_count());
+}
+
TEST_F(SingleBalancerTest, BackendsRestart) {
const size_t kNumRpcsPerAddress = 100;
ScheduleResponseForBalancer(