20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
23 #include "absl/strings/str_cat.h"
32 using ClientStats = LrsServiceImpl::ClientStats;
38 using XdsClientTest = XdsEnd2endTest;
44 TEST_P(XdsClientTest, ResourceWrappedInResourceMessage) {
45 CreateAndStartBackends(1);
46 balancer_->ads_service()->set_wrap_resources(
true);
47 const size_t kNumRpcsPerAddress = 100;
48 EdsResourceArgs
args({
49 {
"locality0", CreateEndpointsForBackends()},
51 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
64 EXPECT_EQ(
"xds_cluster_manager_experimental",
65 channel_->GetLoadBalancingPolicyName());
68 TEST_P(XdsClientTest, ResourceTypeVersionPersistsAcrossStreamRestarts) {
69 CreateAndStartBackends(2);
70 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
71 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
75 balancer_->Shutdown();
77 balancer_->ads_service()->SetResourceMinVersion(
kLdsTypeUrl, 1);
78 balancer_->ads_service()->SetResourceMinVersion(
kRdsTypeUrl, 1);
79 balancer_->ads_service()->SetResourceMinVersion(
kCdsTypeUrl, 1);
80 balancer_->ads_service()->SetResourceMinVersion(
kEdsTypeUrl, 1);
83 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
84 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
92 TEST_P(XdsClientTest, RestartsRequestsUponReconnection) {
93 CreateAndStartBackends(2);
95 auto listener = default_listener_;
96 HttpConnectionManager http_connection_manager;
97 listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
98 &http_connection_manager);
99 auto* rds = http_connection_manager.mutable_rds();
100 rds->set_route_config_name(kDefaultRouteConfigurationName);
101 rds->mutable_config_source()->mutable_self();
102 listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
103 http_connection_manager);
104 balancer_->ads_service()->SetLdsResource(listener);
105 balancer_->ads_service()->SetRdsResource(default_route_config_);
106 const char* kNewClusterName =
"new_cluster_name";
107 const char* kNewEdsServiceName =
"new_eds_service_name";
108 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
109 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
115 balancer_->Shutdown();
120 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
121 balancer_->ads_service()->SetEdsResource(
122 BuildEdsResource(
args, kNewEdsServiceName));
124 Cluster new_cluster = default_cluster_;
125 new_cluster.set_name(kNewClusterName);
126 new_cluster.mutable_eds_cluster_config()->set_service_name(
128 balancer_->ads_service()->SetCdsResource(new_cluster);
130 RouteConfiguration new_route_config = default_route_config_;
131 new_route_config.mutable_virtual_hosts(0)
134 ->set_cluster(kNewClusterName);
135 balancer_->ads_service()->SetRdsResource(new_route_config);
141 TEST_P(XdsClientTest, MultipleBadCdsResources) {
142 constexpr
char kClusterName2[] =
"cluster_name_2";
143 constexpr
char kClusterName3[] =
"cluster_name_3";
144 CreateAndStartBackends(1);
146 auto cluster = default_cluster_;
147 cluster.set_name(kClusterName2);
148 cluster.set_type(Cluster::STATIC);
149 balancer_->ads_service()->SetCdsResource(
cluster);
151 cluster.set_name(kClusterName3);
152 balancer_->ads_service()->SetCdsResource(
cluster);
154 RouteConfiguration route_config = default_route_config_;
155 route_config.mutable_virtual_hosts(0)->clear_routes();
157 auto*
route = route_config.mutable_virtual_hosts(0)->add_routes();
158 route->mutable_match()->set_prefix(
"");
159 auto* header_matcher =
route->mutable_match()->add_headers();
160 header_matcher->set_name(
"cluster");
161 header_matcher->set_exact_match(kDefaultClusterName);
162 route->mutable_route()->set_cluster(kDefaultClusterName);
164 route = route_config.mutable_virtual_hosts(0)->add_routes();
165 route->mutable_match()->set_prefix(
"");
166 header_matcher =
route->mutable_match()->add_headers();
167 header_matcher->set_name(
"cluster");
168 header_matcher->set_exact_match(kClusterName2);
169 route->mutable_route()->set_cluster(kClusterName2);
171 route = route_config.mutable_virtual_hosts(0)->add_routes();
172 route->mutable_match()->set_prefix(
"");
173 route->mutable_route()->set_cluster(kClusterName3);
174 SetRouteConfiguration(balancer_.get(), route_config);
176 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
177 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
180 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
182 response_state->error_message,
184 ": validation error.*"
185 "DiscoveryType is not valid.*",
187 ": validation error.*"
188 "DiscoveryType is not valid")));
190 std::vector<std::pair<std::string, std::string>> metadata_default_cluster = {
191 {
"cluster", kDefaultClusterName},
195 RpcOptions().set_metadata(
std::move(metadata_default_cluster)));
197 std::vector<std::pair<std::string, std::string>> metadata_cluster_2 = {
198 {
"cluster", kClusterName2},
202 "cluster_name_2: UNAVAILABLE: invalid resource: INVALID_ARGUMENT:.*"
203 "errors parsing CDS resource.*DiscoveryType is not valid.*",
204 RpcOptions().set_metadata(
std::move(metadata_cluster_2)));
207 TEST_P(XdsClientTest, XdsStreamErrorPropagation) {
209 balancer_->ads_service()->ForceADSFailure(
213 "XdsStreamErrorPropagation test: RPC got error: code=%d message=%s",
226 using GlobalXdsClientTest = XdsEnd2endTest;
234 TEST_P(GlobalXdsClientTest, MultipleChannelsShareXdsClient) {
235 CreateAndStartBackends(1);
236 const char* kNewServerName =
"new-server.example.com";
237 Listener listener = default_listener_;
238 listener.set_name(kNewServerName);
239 SetListenerAndRouteConfiguration(balancer_.get(), listener,
240 default_route_config_);
241 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
242 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
246 channel2->GetState(
true);
250 EXPECT_EQ(1UL, balancer_->ads_service()->clients().size());
255 MultipleChannelsShareXdsClientWithResourceUpdateAfterOneChannelGoesAway) {
256 CreateAndStartBackends(2);
260 const char* kNewServerName =
"new-server.example.com";
261 Listener listener = default_listener_;
262 listener.set_name(kNewServerName);
263 SetListenerAndRouteConfiguration(balancer_.get(), listener,
264 default_route_config_);
265 balancer_->ads_service()->SetEdsResource(BuildEdsResource(EdsResourceArgs({
266 {
"locality0", CreateEndpointsForBackends(0, 1)},
271 channel2->GetState(
true);
281 balancer_->ads_service()->SetEdsResource(BuildEdsResource(EdsResourceArgs({
282 {
"locality0", CreateEndpointsForBackends(1, 2)},
291 TEST_P(GlobalXdsClientTest, MultipleBadLdsResources) {
292 CreateAndStartBackends(1);
293 constexpr
char kServerName2[] =
"server.other.com";
294 constexpr
char kServerName3[] =
"server.another.com";
295 auto listener = default_listener_;
296 listener.clear_api_listener();
297 balancer_->ads_service()->SetLdsResource(listener);
298 listener.set_name(kServerName2);
299 balancer_->ads_service()->SetLdsResource(listener);
300 listener = default_listener_;
301 listener.set_name(kServerName3);
302 SetListenerAndRouteConfiguration(balancer_.get(), listener,
303 default_route_config_);
304 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
305 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
307 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
311 ": validation error.*"
312 "Listener has neither address nor ApiListener.*")));
315 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
319 request.set_message(kRequestMessage);
325 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
329 ": validation error.*"
330 "Listener has neither address nor ApiListener.*")));
334 ": validation error.*"
335 "Listener has neither address nor ApiListener.*")));
340 auto stub3 = grpc::testing::EchoTestService::NewStub(channel3);
344 request.set_message(kRequestMessage);
348 <<
" message=" <<
status.error_message();
354 TEST_P(GlobalXdsClientTest, InvalidListenerStillExistsIfPreviouslyCached) {
355 CreateAndStartBackends(1);
357 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
358 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
361 auto listener = default_listener_;
362 listener.clear_api_listener();
363 balancer_->ads_service()->SetLdsResource(listener);
365 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
369 ": validation error.*"
370 "Listener has neither address nor ApiListener")));
378 class TimeoutTest :
public XdsEnd2endTest {
380 void SetUp()
override {
381 InitClient(BootstrapBuilder(),
"",
390 XdsTest, TimeoutTest,
392 XdsTestType().set_enable_rds_testing().set_bootstrap_source(
396 TEST_P(TimeoutTest, LdsServerIgnoresRequest) {
397 balancer_->ads_service()->IgnoreResourceType(
kLdsTypeUrl);
400 ": xDS listener resource does not exist"),
401 RpcOptions().set_timeout_ms(4000));
404 TEST_P(TimeoutTest, LdsResourceNotPresentInRequest) {
405 balancer_->ads_service()->UnsetResource(
kLdsTypeUrl, kServerName);
408 ": xDS listener resource does not exist"),
409 RpcOptions().set_timeout_ms(4000));
412 TEST_P(TimeoutTest, LdsSecondResourceNotPresentInRequest) {
415 <<
"This test cannot use bootstrap from channel args, because it "
416 "needs two channels to use the same XdsClient instance.";
417 CreateAndStartBackends(1);
418 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
419 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
420 CheckRpcSendOk(
DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
423 const char* kNewServerName =
"new-server.example.com";
425 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
429 RpcOptions rpc_options;
436 ": xDS listener resource does not exist"));
439 TEST_P(TimeoutTest, RdsServerIgnoresRequest) {
440 balancer_->ads_service()->IgnoreResourceType(
kRdsTypeUrl);
443 absl::StrCat(
"empty address list: ", kDefaultRouteConfigurationName,
444 ": xDS route configuration resource does not exist"),
445 RpcOptions().set_timeout_ms(4000));
448 TEST_P(TimeoutTest, RdsResourceNotPresentInRequest) {
449 balancer_->ads_service()->UnsetResource(
kRdsTypeUrl,
450 kDefaultRouteConfigurationName);
453 absl::StrCat(
"empty address list: ", kDefaultRouteConfigurationName,
454 ": xDS route configuration resource does not exist"),
455 RpcOptions().set_timeout_ms(4000));
458 TEST_P(TimeoutTest, RdsSecondResourceNotPresentInRequest) {
461 <<
"This test cannot use bootstrap from channel args, because it "
462 "needs two channels to use the same XdsClient instance.";
463 CreateAndStartBackends(1);
464 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
465 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
466 CheckRpcSendOk(
DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
468 const char* kNewServerName =
"new-server.example.com";
469 const char* kNewRouteConfigName =
"rds_resource_does_not_exist";
470 Listener listener = default_listener_;
471 listener.set_name(kNewServerName);
472 HttpConnectionManager http_connection_manager =
473 ClientHcmAccessor().Unpack(listener);
474 auto* rds = http_connection_manager.mutable_rds();
475 rds->set_route_config_name(kNewRouteConfigName);
476 rds->mutable_config_source()->mutable_self();
477 ClientHcmAccessor().Pack(http_connection_manager, &listener);
478 balancer_->ads_service()->SetLdsResource(listener);
483 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
487 RpcOptions rpc_options;
494 absl::StrCat(
"empty address list: ", kNewRouteConfigName,
495 ": xDS route configuration resource does not exist"));
498 TEST_P(TimeoutTest, CdsServerIgnoresRequest) {
499 balancer_->ads_service()->IgnoreResourceType(
kCdsTypeUrl);
502 absl::StrCat(
"CDS resource \"", kDefaultClusterName,
"\" does not exist"),
503 RpcOptions().set_timeout_ms(4000));
506 TEST_P(TimeoutTest, CdsResourceNotPresentInRequest) {
507 balancer_->ads_service()->UnsetResource(
kCdsTypeUrl, kDefaultClusterName);
510 absl::StrCat(
"CDS resource \"", kDefaultClusterName,
"\" does not exist"),
511 RpcOptions().set_timeout_ms(4000));
514 TEST_P(TimeoutTest, CdsSecondResourceNotPresentInRequest) {
515 CreateAndStartBackends(1);
516 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
517 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
518 CheckRpcSendOk(
DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
520 const char* kNewClusterName =
"new_cluster_name";
521 RouteConfiguration route_config = default_route_config_;
522 route_config.mutable_virtual_hosts(0)
525 ->set_cluster(kNewClusterName);
526 balancer_->ads_service()->SetRdsResource(route_config);
531 [&](
const RpcResult&
result) {
532 if (
result.status.ok())
return true;
535 "\" does not exist"),
536 result.status.error_message());
539 30000, RpcOptions().set_timeout_ms(4000));
542 TEST_P(TimeoutTest, EdsServerIgnoresRequest) {
543 balancer_->ads_service()->IgnoreResourceType(
kEdsTypeUrl);
547 "no children in weighted_target policy: ",
548 RpcOptions().set_timeout_ms(4000));
551 TEST_P(TimeoutTest, EdsResourceNotPresentInRequest) {
557 "no children in weighted_target policy: ",
558 RpcOptions().set_timeout_ms(4000));
561 TEST_P(TimeoutTest, EdsSecondResourceNotPresentInRequest) {
562 CreateAndStartBackends(1);
563 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
564 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
565 CheckRpcSendOk(
DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
567 const char* kNewClusterName =
"new_cluster_name";
568 Cluster
cluster = default_cluster_;
569 cluster.set_name(kNewClusterName);
570 cluster.mutable_eds_cluster_config()->set_service_name(
571 "eds_service_name_does_not_exist");
572 balancer_->ads_service()->SetCdsResource(
cluster);
574 RouteConfiguration route_config = default_route_config_;
575 auto*
route = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
576 *route_config.mutable_virtual_hosts(0)->add_routes() = *
route;
577 route->mutable_match()->set_path(
"/grpc.testing.EchoTestService/Echo1");
578 route->mutable_route()->set_cluster(kNewClusterName);
579 balancer_->ads_service()->SetRdsResource(route_config);
584 [](
const RpcResult&
result) {
585 if (
result.status.ok())
return true;
590 "no children in weighted_target policy: ");
594 RpcOptions().set_rpc_method(METHOD_ECHO1).set_timeout_ms(4000));
597 TEST_P(TimeoutTest, ServerDoesNotResendAfterAdsStreamRestart) {
598 CreateAndStartBackends(1);
599 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
600 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
601 CheckRpcSendOk(
DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
603 balancer_->Shutdown();
606 balancer_->ads_service()->SetResourceMinVersion(
kLdsTypeUrl, 1);
607 balancer_->ads_service()->IgnoreResourceType(
kLdsTypeUrl);
608 balancer_->ads_service()->SetResourceMinVersion(
kRdsTypeUrl, 1);
609 balancer_->ads_service()->IgnoreResourceType(
kRdsTypeUrl);
610 balancer_->ads_service()->SetResourceMinVersion(
kCdsTypeUrl, 1);
611 balancer_->ads_service()->IgnoreResourceType(
kCdsTypeUrl);
612 balancer_->ads_service()->SetResourceMinVersion(
kEdsTypeUrl, 1);
613 balancer_->ads_service()->IgnoreResourceType(
kEdsTypeUrl);
631 using BootstrapSourceTest = XdsEnd2endTest;
634 XdsTest, BootstrapSourceTest,
640 TEST_P(BootstrapSourceTest, Vanilla) {
641 CreateAndStartBackends(1);
642 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
643 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
647 CheckRpcSendOk(
DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(15000));
654 class XdsFederationTest :
public XdsEnd2endTest {
658 void SetUp()
override {
664 void TearDown()
override {
675 XdsTest, XdsFederationTest,
679 .set_enable_rds_testing()),
685 TEST_P(XdsFederationTest, FederationTargetNoAuthorityWithResourceTemplate) {
686 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
687 const char* kAuthority =
"xds.example.com";
688 const char* kNewListenerTemplate =
689 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
690 "client/%s?psm_project_id=1234";
691 const char* kNewListenerName =
692 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
693 "client/server.example.com?psm_project_id=1234";
694 const char* kNewRouteConfigName =
695 "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
696 "new_route_config_name";
697 const char* kNewEdsServiceName =
698 "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
699 "new_edsservice_name";
700 const char* kNewClusterName =
701 "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
703 BootstrapBuilder
builder = BootstrapBuilder();
704 builder.SetClientDefaultListenerResourceNameTemplate(kNewListenerTemplate);
709 "xdstp://xds.example.com/envoy.config.listener.v3.Listener"
710 "client/%s?client_listener_resource_name_template_not_in_use");
712 CreateAndStartBackends(2,
true);
714 EdsResourceArgs
args =
715 EdsResourceArgs({{
"locality0", CreateEndpointsForBackends()}});
717 BuildEdsResource(
args, kNewEdsServiceName));
719 Cluster new_cluster = default_cluster_;
720 new_cluster.set_name(kNewClusterName);
721 new_cluster.mutable_eds_cluster_config()->set_service_name(
725 RouteConfiguration new_route_config = default_route_config_;
726 new_route_config.set_name(kNewRouteConfigName);
727 new_route_config.mutable_virtual_hosts(0)
730 ->set_cluster(kNewClusterName);
732 Listener listener = default_listener_;
733 listener.set_name(kNewListenerName);
742 TEST_P(XdsFederationTest, FederationTargetAuthorityDefaultResourceTemplate) {
743 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
744 const char* kAuthority =
"xds.example.com";
745 const char* kNewServerName =
"whee%/server.example.com";
746 const char* kNewListenerName =
747 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
748 "whee%25/server.example.com";
749 const char* kNewRouteConfigName =
750 "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
751 "new_route_config_name";
752 const char* kNewEdsServiceName =
753 "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
755 const char* kNewClusterName =
756 "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
758 BootstrapBuilder
builder = BootstrapBuilder();
759 builder.AddAuthority(kAuthority,
762 CreateAndStartBackends(2,
true);
765 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
766 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
767 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
769 BuildEdsResource(
args, kNewEdsServiceName));
771 Cluster new_cluster = default_cluster_;
772 new_cluster.set_name(kNewClusterName);
773 new_cluster.mutable_eds_cluster_config()->set_service_name(
777 RouteConfiguration new_route_config = default_route_config_;
778 new_route_config.set_name(kNewRouteConfigName);
779 new_route_config.mutable_virtual_hosts(0)
782 ->set_cluster(kNewClusterName);
784 Listener listener = default_listener_;
785 listener.set_name(kNewListenerName);
793 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
800 <<
" message=" <<
status.error_message();
809 TEST_P(XdsFederationTest, FederationTargetAuthorityWithResourceTemplate) {
810 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
811 const char* kAuthority =
"xds.example.com";
812 const char* kNewServerName =
"whee%/server.example.com";
813 const char* kNewListenerTemplate =
814 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
815 "client/%s?psm_project_id=1234";
816 const char* kNewListenerName =
817 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
818 "client/whee%25/server.example.com?psm_project_id=1234";
819 const char* kNewRouteConfigName =
820 "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
821 "new_route_config_name";
822 const char* kNewEdsServiceName =
823 "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
825 const char* kNewClusterName =
826 "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
828 BootstrapBuilder
builder = BootstrapBuilder();
829 builder.AddAuthority(kAuthority,
831 kNewListenerTemplate);
833 CreateAndStartBackends(2,
true);
836 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
837 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
838 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
840 BuildEdsResource(
args, kNewEdsServiceName));
842 Cluster new_cluster = default_cluster_;
843 new_cluster.set_name(kNewClusterName);
844 new_cluster.mutable_eds_cluster_config()->set_service_name(
848 RouteConfiguration new_route_config = default_route_config_;
849 new_route_config.set_name(kNewRouteConfigName);
850 new_route_config.mutable_virtual_hosts(0)
853 ->set_cluster(kNewClusterName);
855 Listener listener = default_listener_;
856 listener.set_name(kNewListenerName);
864 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
871 <<
" message=" <<
status.error_message();
878 TEST_P(XdsFederationTest, TargetUriAuthorityUnknown) {
879 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
880 const char* kAuthority =
"xds.example.com";
881 const char* kNewServerName =
"whee%/server.example.com";
882 const char* kNewListenerTemplate =
883 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
884 "client/%s?psm_project_id=1234";
885 BootstrapBuilder
builder = BootstrapBuilder();
888 kNewListenerTemplate);
891 0, kNewServerName,
"xds.unknown.com");
892 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
900 "Invalid target URI -- authority not found for xds.unknown.com");
904 TEST_P(XdsFederationTest, RdsResourceNameAuthorityUnknown) {
905 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
906 const char* kAuthority =
"xds.example.com";
907 const char* kNewServerName =
"whee%/server.example.com";
908 const char* kNewListenerTemplate =
909 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
910 "client/%s?psm_project_id=1234";
911 const char* kNewListenerName =
912 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
913 "client/whee%25/server.example.com?psm_project_id=1234";
914 const char* kNewRouteConfigName =
915 "xdstp://xds.unknown.com/envoy.config.route.v3.RouteConfiguration/"
916 "new_route_config_name";
917 BootstrapBuilder
builder = BootstrapBuilder();
918 builder.AddAuthority(kAuthority,
920 kNewListenerTemplate);
923 RouteConfiguration new_route_config = default_route_config_;
924 new_route_config.set_name(kNewRouteConfigName);
926 Listener listener = default_listener_;
927 listener.set_name(kNewListenerName);
933 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
943 ": UNAVAILABLE: authority \"xds.unknown.com\" not present in "
944 "bootstrap config"));
948 TEST_P(XdsFederationTest, CdsResourceNameAuthorityUnknown) {
949 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
950 const char* kAuthority =
"xds.example.com";
951 const char* kNewServerName =
"whee%/server.example.com";
952 const char* kNewListenerTemplate =
953 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
954 "client/%s?psm_project_id=1234";
955 const char* kNewListenerName =
956 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
957 "client/whee%25/server.example.com?psm_project_id=1234";
958 const char* kNewRouteConfigName =
959 "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
960 "new_route_config_name";
961 const char* kNewClusterName =
962 "xdstp://xds.unknown.com/envoy.config.cluster.v3.Cluster/"
964 BootstrapBuilder
builder = BootstrapBuilder();
965 builder.AddAuthority(kAuthority,
967 kNewListenerTemplate);
970 RouteConfiguration new_route_config = default_route_config_;
971 new_route_config.set_name(kNewRouteConfigName);
972 new_route_config.mutable_virtual_hosts(0)
975 ->set_cluster(kNewClusterName);
977 Listener listener = default_listener_;
978 listener.set_name(kNewListenerName);
984 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
994 ": UNAVAILABLE: authority \"xds.unknown.com\" not present in "
995 "bootstrap config"));
999 TEST_P(XdsFederationTest, EdsResourceNameAuthorityUnknown) {
1000 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
1001 const char* kAuthority =
"xds.example.com";
1002 const char* kNewServerName =
"whee%/server.example.com";
1003 const char* kNewListenerTemplate =
1004 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1005 "client/%s?psm_project_id=1234";
1006 const char* kNewListenerName =
1007 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1008 "client/whee%25/server.example.com?psm_project_id=1234";
1009 const char* kNewRouteConfigName =
1010 "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
1011 "new_route_config_name";
1012 const char* kNewEdsServiceName =
1013 "xdstp://xds.unknown.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
1015 const char* kNewClusterName =
1016 "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
1018 BootstrapBuilder
builder = BootstrapBuilder();
1019 builder.AddAuthority(kAuthority,
1021 kNewListenerTemplate);
1024 Cluster new_cluster = default_cluster_;
1025 new_cluster.set_name(kNewClusterName);
1026 new_cluster.mutable_eds_cluster_config()->set_service_name(
1027 kNewEdsServiceName);
1030 RouteConfiguration new_route_config = default_route_config_;
1031 new_route_config.set_name(kNewRouteConfigName);
1032 new_route_config.mutable_virtual_hosts(0)
1035 ->set_cluster(kNewClusterName);
1037 Listener listener = default_listener_;
1038 listener.set_name(kNewListenerName);
1044 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
1054 "no children in weighted_target policy: ");
1060 TEST_P(XdsFederationTest, FederationServer) {
1061 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
1062 const char* kAuthority =
"xds.example.com";
1063 const char* kNewListenerTemplate =
1064 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1065 "client/%s?psm_project_id=1234";
1066 const char* kNewServerListenerTemplate =
1067 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1068 "server/%s?psm_project_id=1234";
1069 const char* kNewListenerName =
1070 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1071 "client/server.example.com?psm_project_id=1234";
1072 const char* kNewRouteConfigName =
1073 "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
1074 "new_route_config_name";
1075 const char* kNewEdsServiceName =
1076 "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
1077 "new_edsservice_name";
1078 const char* kNewClusterName =
1079 "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
1081 BootstrapBuilder
builder = BootstrapBuilder();
1082 builder.SetClientDefaultListenerResourceNameTemplate(kNewListenerTemplate);
1083 builder.SetServerListenerResourceNameTemplate(kNewServerListenerTemplate);
1088 "xdstp://xds.example.com/envoy.config.listener.v3.Listener"
1089 "client/%s?client_listener_resource_name_template_not_in_use");
1091 CreateAndStartBackends(2,
true);
1093 EdsResourceArgs
args =
1094 EdsResourceArgs({{
"locality0", CreateEndpointsForBackends()}});
1096 BuildEdsResource(
args, kNewEdsServiceName));
1098 Cluster new_cluster = default_cluster_;
1099 new_cluster.set_name(kNewClusterName);
1100 new_cluster.mutable_eds_cluster_config()->set_service_name(
1101 kNewEdsServiceName);
1104 RouteConfiguration new_route_config = default_route_config_;
1105 new_route_config.set_name(kNewRouteConfigName);
1106 new_route_config.mutable_virtual_hosts(0)
1109 ->set_cluster(kNewClusterName);
1111 Listener listener = default_listener_;
1112 listener.set_name(kNewListenerName);
1116 for (
int port : GetBackendPorts()) {
1117 Listener server_listener = default_server_listener_;
1119 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/server/",
1121 "?psm_project_id=1234"));
1122 server_listener.mutable_address()->mutable_socket_address()->set_port_value(
1133 using XdsFederationDisabledTest = XdsEnd2endTest;
1137 XdsTest, XdsFederationDisabledTest,
1141 TEST_P(XdsFederationDisabledTest, FederationDisabledWithNewStyleNames) {
1142 const char* kNewRouteConfigName =
1143 "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
1144 "new_route_config_name";
1145 const char* kNewClusterName =
1146 "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
1148 const char* kNewEdsResourceName =
1149 "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
1152 CreateAndStartBackends(1);
1153 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
1154 balancer_->ads_service()->SetEdsResource(
1155 BuildEdsResource(
args, kNewEdsResourceName));
1157 Cluster new_cluster = default_cluster_;
1158 new_cluster.set_name(kNewClusterName);
1159 new_cluster.mutable_eds_cluster_config()->set_service_name(
1160 kNewEdsResourceName);
1161 balancer_->ads_service()->SetCdsResource(new_cluster);
1163 RouteConfiguration new_route_config = default_route_config_;
1164 new_route_config.set_name(kNewRouteConfigName);
1165 new_route_config.mutable_virtual_hosts(0)
1168 ->set_cluster(kNewClusterName);
1169 SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
1179 using XdsFederationLoadReportingTest = XdsFederationTest;
1184 XdsTest, XdsFederationLoadReportingTest,
1188 .set_enable_load_reporting(),
1191 .set_enable_load_reporting()
1192 .set_enable_rds_testing()),
1199 TEST_P(XdsFederationLoadReportingTest, FederationMultipleLoadReportingTest) {
1200 ScopedExperimentalEnvVar
env_var(
"GRPC_EXPERIMENTAL_XDS_FEDERATION");
1201 const char* kAuthority =
"xds.example.com";
1202 const char* kNewServerName =
"whee%/server.example.com";
1203 const char* kNewListenerTemplate =
1204 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1205 "client/%s?psm_project_id=1234";
1206 const char* kNewListenerName =
1207 "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1208 "client/whee%25/server.example.com?psm_project_id=1234";
1209 const char* kNewRouteConfigName =
1210 "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
1211 "new_route_config_name";
1212 const char* kNewEdsServiceName =
1213 "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
1215 const char* kNewClusterName =
1216 "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
1218 const size_t kNumRpcsToDefaultBalancer = 5;
1219 const size_t kNumRpcsToAuthorityBalancer = 10;
1220 BootstrapBuilder
builder = BootstrapBuilder();
1221 builder.AddAuthority(kAuthority,
1223 kNewListenerTemplate);
1225 CreateAndStartBackends(2,
true);
1228 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
1229 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1230 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
1232 BuildEdsResource(
args, kNewEdsServiceName));
1235 Cluster new_cluster = default_cluster_;
1236 new_cluster.set_name(kNewClusterName);
1237 new_cluster.mutable_lrs_server()->mutable_self();
1238 new_cluster.mutable_eds_cluster_config()->set_service_name(
1239 kNewEdsServiceName);
1242 RouteConfiguration new_route_config = default_route_config_;
1243 new_route_config.set_name(kNewRouteConfigName);
1244 new_route_config.mutable_virtual_hosts(0)
1247 ->set_cluster(kNewClusterName);
1249 Listener listener = default_listener_;
1250 listener.set_name(kNewListenerName);
1258 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
1260 for (
size_t i = 0;
i < kNumRpcsToAuthorityBalancer; ++
i) {
1267 <<
" message=" <<
status.error_message();
1276 std::vector<ClientStats> authority_load_report =
1278 ASSERT_EQ(authority_load_report.size(), 1UL);
1279 ClientStats& authority_client_stats = authority_load_report.front();
1281 authority_client_stats.total_successful_requests());
1282 EXPECT_EQ(0U, authority_client_stats.total_requests_in_progress());
1284 authority_client_stats.total_issued_requests());
1285 EXPECT_EQ(0U, authority_client_stats.total_error_requests());
1286 EXPECT_EQ(0U, authority_client_stats.total_dropped_requests());
1290 std::vector<ClientStats> default_load_report =
1291 balancer_->lrs_service()->WaitForLoadReport();
1292 ASSERT_EQ(default_load_report.size(), 1UL);
1293 ClientStats& default_client_stats = default_load_report.front();
1295 default_client_stats.total_successful_requests());
1296 EXPECT_EQ(0U, default_client_stats.total_requests_in_progress());
1298 default_client_stats.total_issued_requests());
1299 EXPECT_EQ(0U, default_client_stats.total_error_requests());
1300 EXPECT_EQ(0U, default_client_stats.total_dropped_requests());
1301 EXPECT_EQ(1U, balancer_->lrs_service()->request_count());
1302 EXPECT_EQ(1U, balancer_->lrs_service()->response_count());
1309 class SecureNamingTest :
public XdsEnd2endTest {
1311 void SetUp()
override {
1320 TEST_P(SecureNamingTest, TargetNameIsExpected) {
1321 InitClient(BootstrapBuilder(),
"localhost:%d");
1322 CreateAndStartBackends(4);
1323 EdsResourceArgs
args({
1324 {
"locality0", CreateEndpointsForBackends()},
1326 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1331 TEST_P(SecureNamingTest, TargetNameIsUnexpected) {
1333 InitClient(BootstrapBuilder(),
1334 "incorrect_server_name");
1335 CreateAndStartBackends(4);
1336 EdsResourceArgs
args({
1337 {
"locality0", CreateEndpointsForBackends()},
1339 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1355 #if TARGET_OS_IPHONE