|
|
|
@ -259,6 +259,36 @@ class BackendServiceImpl : public BackendService { |
|
|
|
|
return status; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Status Echo1(ServerContext* context, const EchoRequest* request, |
|
|
|
|
EchoResponse* response) override { |
|
|
|
|
// Backend should receive the call credentials metadata.
|
|
|
|
|
auto call_credentials_entry = |
|
|
|
|
context->client_metadata().find(g_kCallCredsMdKey); |
|
|
|
|
EXPECT_NE(call_credentials_entry, context->client_metadata().end()); |
|
|
|
|
if (call_credentials_entry != context->client_metadata().end()) { |
|
|
|
|
EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); |
|
|
|
|
} |
|
|
|
|
echo1_request_count_++; |
|
|
|
|
const auto status = TestServiceImpl::Echo1(context, request, response); |
|
|
|
|
AddClient(context->peer()); |
|
|
|
|
return status; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Status Echo2(ServerContext* context, const EchoRequest* request, |
|
|
|
|
EchoResponse* response) override { |
|
|
|
|
// Backend should receive the call credentials metadata.
|
|
|
|
|
auto call_credentials_entry = |
|
|
|
|
context->client_metadata().find(g_kCallCredsMdKey); |
|
|
|
|
EXPECT_NE(call_credentials_entry, context->client_metadata().end()); |
|
|
|
|
if (call_credentials_entry != context->client_metadata().end()) { |
|
|
|
|
EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); |
|
|
|
|
} |
|
|
|
|
echo2_request_count_++; |
|
|
|
|
const auto status = TestServiceImpl::Echo2(context, request, response); |
|
|
|
|
AddClient(context->peer()); |
|
|
|
|
return status; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Start() {} |
|
|
|
|
void Shutdown() {} |
|
|
|
|
|
|
|
|
@ -267,6 +297,10 @@ class BackendServiceImpl : public BackendService { |
|
|
|
|
return clients_; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
size_t Echo1RequestCount() { return echo1_request_count_; } |
|
|
|
|
|
|
|
|
|
size_t Echo2RequestCount() { return echo2_request_count_; } |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
void AddClient(const grpc::string& client) { |
|
|
|
|
grpc_core::MutexLock lock(&clients_mu_); |
|
|
|
@ -276,6 +310,8 @@ class BackendServiceImpl : public BackendService { |
|
|
|
|
grpc_core::Mutex mu_; |
|
|
|
|
grpc_core::Mutex clients_mu_; |
|
|
|
|
std::set<grpc::string> clients_; |
|
|
|
|
size_t echo1_request_count_ = 0; |
|
|
|
|
size_t echo2_request_count_ = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class ClientStats { |
|
|
|
@ -1356,6 +1392,34 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { |
|
|
|
|
return status; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Status SendEcho1Rpc(EchoResponse* response = nullptr, int timeout_ms = 1000, |
|
|
|
|
bool wait_for_ready = false) { |
|
|
|
|
const bool local_response = (response == nullptr); |
|
|
|
|
if (local_response) response = new EchoResponse; |
|
|
|
|
EchoRequest request; |
|
|
|
|
request.set_message(kRequestMessage_); |
|
|
|
|
ClientContext context; |
|
|
|
|
context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); |
|
|
|
|
if (wait_for_ready) context.set_wait_for_ready(true); |
|
|
|
|
Status status = stub_->Echo1(&context, request, response); |
|
|
|
|
if (local_response) delete response; |
|
|
|
|
return status; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Status SendEcho2Rpc(EchoResponse* response = nullptr, int timeout_ms = 1000, |
|
|
|
|
bool wait_for_ready = false) { |
|
|
|
|
const bool local_response = (response == nullptr); |
|
|
|
|
if (local_response) response = new EchoResponse; |
|
|
|
|
EchoRequest request; |
|
|
|
|
request.set_message(kRequestMessage_); |
|
|
|
|
ClientContext context; |
|
|
|
|
context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); |
|
|
|
|
if (wait_for_ready) context.set_wait_for_ready(true); |
|
|
|
|
Status status = stub_->Echo2(&context, request, response); |
|
|
|
|
if (local_response) delete response; |
|
|
|
|
return status; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000, |
|
|
|
|
bool wait_for_ready = false) { |
|
|
|
|
for (size_t i = 0; i < times; ++i) { |
|
|
|
@ -1372,6 +1436,28 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { |
|
|
|
|
EXPECT_FALSE(status.ok()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CheckEcho1RpcSendOk(const size_t times = 1, const int timeout_ms = 1000, |
|
|
|
|
bool wait_for_ready = false) { |
|
|
|
|
for (size_t i = 0; i < times; ++i) { |
|
|
|
|
EchoResponse response; |
|
|
|
|
const Status status = SendEcho1Rpc(&response, timeout_ms, wait_for_ready); |
|
|
|
|
EXPECT_TRUE(status.ok()) << "code=" << status.error_code() |
|
|
|
|
<< " message=" << status.error_message(); |
|
|
|
|
EXPECT_EQ(response.message(), kRequestMessage_); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CheckEcho2RpcSendOk(const size_t times = 1, const int timeout_ms = 1000, |
|
|
|
|
bool wait_for_ready = false) { |
|
|
|
|
for (size_t i = 0; i < times; ++i) { |
|
|
|
|
EchoResponse response; |
|
|
|
|
const Status status = SendEcho2Rpc(&response, timeout_ms, wait_for_ready); |
|
|
|
|
EXPECT_TRUE(status.ok()) << "code=" << status.error_code() |
|
|
|
|
<< " message=" << status.error_message(); |
|
|
|
|
EXPECT_EQ(response.message(), kRequestMessage_); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
// This method could benefit test subclasses; to make it accessible
|
|
|
|
|
// via bind with a qualified name, it needs to be public.
|
|
|
|
@ -2129,26 +2215,26 @@ TEST_P(LdsTest, Timeout) { |
|
|
|
|
CheckRpcSendFailure(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Tests that LDS client should choose the default route (with no matching
|
|
|
|
|
// specified) after unable to find a match with previous routes.
|
|
|
|
|
TEST_P(LdsTest, XdsRoutingPathMatching) { |
|
|
|
|
const char* kNewCluster1Name = "new_cluster_1"; |
|
|
|
|
const char* kNewCluster2Name = "new_cluster_2"; |
|
|
|
|
const size_t kNumRpcs = 10; |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Populate new EDS resources.
|
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts(0, 2)}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); |
|
|
|
|
// We need to wait for all backends to come online.
|
|
|
|
|
WaitForAllBackends(0, 2); |
|
|
|
|
// Populate new EDS resources.
|
|
|
|
|
AdsServiceImpl::EdsResourceArgs args1({ |
|
|
|
|
{"locality0", GetBackendPorts(2, 3)}, |
|
|
|
|
}); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args2({ |
|
|
|
|
{"locality0", GetBackendPorts(3, 4)}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
AdsServiceImpl::BuildEdsResource(args1, kNewCluster1Name), |
|
|
|
|
kNewCluster1Name); |
|
|
|
@ -2163,28 +2249,34 @@ TEST_P(LdsTest, XdsRoutingPathMatching) { |
|
|
|
|
new_cluster2.set_name(kNewCluster2Name); |
|
|
|
|
balancers_[0]->ads_service()->SetCdsResource(new_cluster2, kNewCluster2Name); |
|
|
|
|
// Change RDS resource to set up prefix matching to direct traffic to the
|
|
|
|
|
// first new cluster.
|
|
|
|
|
// second new cluster.
|
|
|
|
|
RouteConfiguration new_route_config = |
|
|
|
|
balancers_[0]->ads_service()->default_route_config(); |
|
|
|
|
auto* mismatched_route = |
|
|
|
|
auto* mismatched_route1 = |
|
|
|
|
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); |
|
|
|
|
mismatched_route->mutable_match()->set_path( |
|
|
|
|
"/grpc.testing.EchoTestService/Echo"); |
|
|
|
|
mismatched_route->mutable_route()->set_cluster(kNewCluster1Name); |
|
|
|
|
auto* matched_route = new_route_config.mutable_virtual_hosts(0)->add_routes(); |
|
|
|
|
matched_route->mutable_match()->set_path( |
|
|
|
|
"/grpc.testing.EchoTestService/NewMethod"); |
|
|
|
|
matched_route->mutable_route()->set_cluster(kNewCluster2Name); |
|
|
|
|
mismatched_route1->mutable_match()->set_path( |
|
|
|
|
"/grpc.testing.EchoTestService/Echo1"); |
|
|
|
|
mismatched_route1->mutable_route()->set_cluster(kNewCluster1Name); |
|
|
|
|
auto* mismatched_route2 = |
|
|
|
|
new_route_config.mutable_virtual_hosts(0)->add_routes(); |
|
|
|
|
mismatched_route2->mutable_match()->set_path( |
|
|
|
|
"/grpc.testing.EchoTestService/Echo2"); |
|
|
|
|
mismatched_route2->mutable_route()->set_cluster(kNewCluster2Name); |
|
|
|
|
auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes(); |
|
|
|
|
default_route->mutable_match()->set_prefix(""); |
|
|
|
|
default_route->mutable_match()->set_path(""); |
|
|
|
|
default_route->mutable_route()->set_cluster(kDefaultResourceName); |
|
|
|
|
Listener listener = |
|
|
|
|
balancers_[0]->ads_service()->BuildListener(new_route_config); |
|
|
|
|
balancers_[0]->ads_service()->SetLdsResource(listener, kDefaultResourceName); |
|
|
|
|
// Wait for the new backend to come up.
|
|
|
|
|
WaitForAllBackends(2, 3); |
|
|
|
|
CheckRpcSendOk(kNumRpcs); |
|
|
|
|
CheckEcho1RpcSendOk(kNumRpcs, 1000, true); |
|
|
|
|
CheckEcho2RpcSendOk(kNumRpcs, 1000, true); |
|
|
|
|
// Make sure RPCs all go to the correct backend.
|
|
|
|
|
for (size_t i = 0; i < 4; ++i) { |
|
|
|
|
if (i == 2) { |
|
|
|
|
EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->request_count()); |
|
|
|
|
EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->Echo1RequestCount()); |
|
|
|
|
} else if (i == 3) { |
|
|
|
|
EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->Echo2RequestCount()); |
|
|
|
|
} else { |
|
|
|
|
EXPECT_EQ(0, backends_[i]->backend_service()->request_count()); |
|
|
|
|
} |
|
|
|
@ -2197,13 +2289,6 @@ TEST_P(LdsTest, XdsRoutingPrefixMatching) { |
|
|
|
|
const size_t kNumRpcs = 10; |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts(0, 2)}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); |
|
|
|
|
// We need to wait for all backends to come online.
|
|
|
|
|
WaitForAllBackends(0, 2); |
|
|
|
|
// Populate new EDS resources.
|
|
|
|
|
AdsServiceImpl::EdsResourceArgs args1({ |
|
|
|
|
{"locality0", GetBackendPorts(2, 3)}, |
|
|
|
@ -2239,15 +2324,13 @@ TEST_P(LdsTest, XdsRoutingPrefixMatching) { |
|
|
|
|
Listener listener = |
|
|
|
|
balancers_[0]->ads_service()->BuildListener(new_route_config); |
|
|
|
|
balancers_[0]->ads_service()->SetLdsResource(listener, kDefaultResourceName); |
|
|
|
|
// Wait for the new backend to come up.
|
|
|
|
|
WaitForAllBackends(3, 4); |
|
|
|
|
CheckRpcSendOk(kNumRpcs); |
|
|
|
|
CheckEcho1RpcSendOk(kNumRpcs, 1000, true); |
|
|
|
|
// Make sure RPCs all go to the correct backend.
|
|
|
|
|
for (size_t i = 0; i < 4; ++i) { |
|
|
|
|
if (i == 3) { |
|
|
|
|
EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->request_count()); |
|
|
|
|
EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->Echo1RequestCount()); |
|
|
|
|
} else { |
|
|
|
|
EXPECT_EQ(0, backends_[i]->backend_service()->request_count()); |
|
|
|
|
EXPECT_EQ(0, backends_[i]->backend_service()->Echo1RequestCount()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -2260,20 +2343,18 @@ TEST_P(LdsTest, XdsRoutingDefaultRoute) { |
|
|
|
|
const size_t kNumRpcs = 10; |
|
|
|
|
SetNextResolution({}); |
|
|
|
|
SetNextResolutionForLbChannelAllBalancers(); |
|
|
|
|
// Populate new EDS resources.
|
|
|
|
|
AdsServiceImpl::EdsResourceArgs args({ |
|
|
|
|
{"locality0", GetBackendPorts(0, 2)}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); |
|
|
|
|
// We need to wait for all backends to come online.
|
|
|
|
|
WaitForAllBackends(0, 2); |
|
|
|
|
// Populate new EDS resources.
|
|
|
|
|
AdsServiceImpl::EdsResourceArgs args1({ |
|
|
|
|
{"locality0", GetBackendPorts(2, 3)}, |
|
|
|
|
}); |
|
|
|
|
AdsServiceImpl::EdsResourceArgs args2({ |
|
|
|
|
{"locality0", GetBackendPorts(3, 4)}, |
|
|
|
|
}); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); |
|
|
|
|
balancers_[0]->ads_service()->SetEdsResource( |
|
|
|
|
AdsServiceImpl::BuildEdsResource(args1, kNewCluster1Name), |
|
|
|
|
kNewCluster1Name); |
|
|
|
@ -2287,8 +2368,8 @@ TEST_P(LdsTest, XdsRoutingDefaultRoute) { |
|
|
|
|
Cluster new_cluster2 = balancers_[0]->ads_service()->default_cluster(); |
|
|
|
|
new_cluster2.set_name(kNewCluster2Name); |
|
|
|
|
balancers_[0]->ads_service()->SetCdsResource(new_cluster2, kNewCluster2Name); |
|
|
|
|
// Change RDS resource to set up prefix matching to direct traffic to the
|
|
|
|
|
// second new cluster.
|
|
|
|
|
// Change RDS resource to set up prefix matching and path matching that do
|
|
|
|
|
// match the traffic, so traffic goes to the default cluster.
|
|
|
|
|
RouteConfiguration new_route_config = |
|
|
|
|
balancers_[0]->ads_service()->default_route_config(); |
|
|
|
|
auto* mismatched_route1 = |
|
|
|
@ -2299,7 +2380,7 @@ TEST_P(LdsTest, XdsRoutingDefaultRoute) { |
|
|
|
|
auto* mismatched_route2 = |
|
|
|
|
new_route_config.mutable_virtual_hosts(0)->add_routes(); |
|
|
|
|
mismatched_route2->mutable_match()->set_path( |
|
|
|
|
"/grpc.testing.EchoTestService/EchoMismatch"); |
|
|
|
|
"/grpc.testing.EchoTestService/Echo1"); |
|
|
|
|
mismatched_route2->mutable_route()->set_cluster(kNewCluster2Name); |
|
|
|
|
auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes(); |
|
|
|
|
default_route->mutable_match()->set_prefix(""); |
|
|
|
@ -2308,7 +2389,6 @@ TEST_P(LdsTest, XdsRoutingDefaultRoute) { |
|
|
|
|
Listener listener = |
|
|
|
|
balancers_[0]->ads_service()->BuildListener(new_route_config); |
|
|
|
|
balancers_[0]->ads_service()->SetLdsResource(listener, kDefaultResourceName); |
|
|
|
|
// Wait for the new backend to come up.
|
|
|
|
|
WaitForAllBackends(0, 2); |
|
|
|
|
CheckRpcSendOk(kNumRpcs); |
|
|
|
|
// Make sure RPCs all go to the correct backend.
|
|
|
|
|