20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
23 #include "absl/strings/match.h"
24 #include "absl/strings/str_cat.h"
33 using ::envoy::config::cluster::v3::CircuitBreakers;
34 using ::envoy::config::cluster::v3::RoutingPriority;
35 using ::envoy::config::endpoint::v3::HealthStatus;
36 using ::envoy::type::v3::FractionalPercent;
38 using ClientStats = LrsServiceImpl::ClientStats;
40 constexpr
char kLbDropType[] =
"lb";
41 constexpr
char kThrottleDropType[] =
"throttle";
42 constexpr
char kStatusMessageDropPrefix[] =
"EDS-configured drop: ";
48 using CdsTest = XdsEnd2endTest;
56 auto response_state = balancer_->ads_service()->cds_response_state();
63 TEST_P(CdsTest, UnsupportedClusterType) {
64 auto cluster = default_cluster_;
65 cluster.set_type(Cluster::STATIC);
66 balancer_->ads_service()->SetCdsResource(
cluster);
68 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
75 TEST_P(CdsTest, InvalidClusterStillExistsIfPreviouslyCached) {
76 CreateAndStartBackends(1);
77 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
78 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
82 auto cluster = default_cluster_;
83 cluster.set_type(Cluster::STATIC);
84 balancer_->ads_service()->SetCdsResource(
cluster);
86 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
90 ": validation error.*DiscoveryType is not valid")));
96 TEST_P(CdsTest, EdsConfigSourceDoesNotSpecifyAdsOrSelf) {
97 auto cluster = default_cluster_;
98 cluster.mutable_eds_cluster_config()->mutable_eds_config()->set_path(
100 balancer_->ads_service()->SetCdsResource(
cluster);
102 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
108 TEST_P(CdsTest, AcceptsEdsConfigSourceOfTypeAds) {
109 CreateAndStartBackends(1);
110 auto cluster = default_cluster_;
111 cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_ads();
112 balancer_->ads_service()->SetCdsResource(
cluster);
113 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
114 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
116 auto response_state = balancer_->ads_service()->cds_response_state();
123 TEST_P(CdsTest, WrongLbPolicy) {
124 auto cluster = default_cluster_;
125 cluster.set_lb_policy(Cluster::LEAST_REQUEST);
126 balancer_->ads_service()->SetCdsResource(
cluster);
128 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
135 TEST_P(CdsTest, WrongLrsServer) {
136 auto cluster = default_cluster_;
137 cluster.mutable_lrs_server()->mutable_ads();
138 balancer_->ads_service()->SetCdsResource(
cluster);
140 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
147 TEST_P(CdsTest, EndpointWeightDoesNotImpactWeightedRoundRobin) {
148 CreateAndStartBackends(2);
149 const int kLocalityWeight0 = 2;
150 const int kLocalityWeight1 = 8;
151 const int kTotalLocalityWeight = kLocalityWeight0 + kLocalityWeight1;
152 const double kLocalityWeightRate0 =
153 static_cast<double>(kLocalityWeight0) / kTotalLocalityWeight;
154 const double kLocalityWeightRate1 =
155 static_cast<double>(kLocalityWeight1) / kTotalLocalityWeight;
156 const double kErrorTolerance = 0.05;
158 ComputeIdealNumRpcs(kLocalityWeightRate0, kErrorTolerance);
160 EdsResourceArgs
args({
162 {CreateEndpoint(0, HealthStatus::UNKNOWN, 8)},
165 {CreateEndpoint(1, HealthStatus::UNKNOWN, 2)},
168 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
174 const double locality_picked_rate_0 =
175 static_cast<double>(
backends_[0]->backend_service()->request_count()) /
177 const double locality_picked_rate_1 =
178 static_cast<double>(
backends_[1]->backend_service()->request_count()) /
191 TEST_P(CdsTest, EdsServiceNameDefaultsToClusterName) {
192 CreateAndStartBackends(1);
193 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
194 balancer_->ads_service()->SetEdsResource(
195 BuildEdsResource(
args, kDefaultClusterName));
196 Cluster
cluster = default_cluster_;
197 cluster.mutable_eds_cluster_config()->clear_service_name();
198 balancer_->ads_service()->SetCdsResource(
cluster);
203 TEST_P(CdsTest, ChangeClusters) {
204 CreateAndStartBackends(2);
205 const char* kNewClusterName =
"new_cluster_name";
206 const char* kNewEdsServiceName =
"new_eds_service_name";
207 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
208 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
212 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
213 balancer_->ads_service()->SetEdsResource(
214 BuildEdsResource(
args, kNewEdsServiceName));
216 Cluster new_cluster = default_cluster_;
217 new_cluster.set_name(kNewClusterName);
218 new_cluster.mutable_eds_cluster_config()->set_service_name(
220 balancer_->ads_service()->SetCdsResource(new_cluster);
222 RouteConfiguration new_route_config = default_route_config_;
223 new_route_config.mutable_virtual_hosts(0)
226 ->set_cluster(kNewClusterName);
227 SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
233 TEST_P(CdsTest, CircuitBreaking) {
234 CreateAndStartBackends(1);
235 constexpr
size_t kMaxConcurrentRequests = 10;
237 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
238 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
240 CircuitBreakers circuit_breaks;
241 Cluster
cluster = default_cluster_;
242 auto* threshold =
cluster.mutable_circuit_breakers()->add_thresholds();
243 threshold->set_priority(RoutingPriority::DEFAULT);
244 threshold->mutable_max_requests()->set_value(kMaxConcurrentRequests);
245 balancer_->ads_service()->SetCdsResource(
cluster);
247 LongRunningRpc rpcs[kMaxConcurrentRequests];
248 for (
size_t i = 0;
i < kMaxConcurrentRequests; ++
i) {
249 rpcs[
i].StartRpc(
stub_.get());
253 kMaxConcurrentRequests) {
266 for (
size_t i = 1;
i < kMaxConcurrentRequests; ++
i) {
271 TEST_P(CdsTest, CircuitBreakingMultipleChannelsShareCallCounter) {
272 CreateAndStartBackends(1);
273 constexpr
size_t kMaxConcurrentRequests = 10;
275 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
276 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
278 CircuitBreakers circuit_breaks;
279 Cluster
cluster = default_cluster_;
280 auto* threshold =
cluster.mutable_circuit_breakers()->add_thresholds();
281 threshold->set_priority(RoutingPriority::DEFAULT);
282 threshold->mutable_max_requests()->set_value(kMaxConcurrentRequests);
283 balancer_->ads_service()->SetCdsResource(
cluster);
285 auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
288 LongRunningRpc rpcs[kMaxConcurrentRequests];
289 for (
size_t i = 0;
i < kMaxConcurrentRequests; ++
i) {
290 rpcs[
i].StartRpc(i % 2 == 0 ?
stub_.get() : stub2.get());
294 kMaxConcurrentRequests) {
307 for (
size_t i = 1;
i < kMaxConcurrentRequests; ++
i) {
312 TEST_P(CdsTest, ClusterChangeAfterAdsCallFails) {
313 CreateAndStartBackends(2);
314 const char* kNewEdsResourceName =
"new_eds_resource_name";
316 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
317 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
321 balancer_->Shutdown();
324 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
325 balancer_->ads_service()->SetEdsResource(
326 BuildEdsResource(
args, kNewEdsResourceName));
328 auto cluster = default_cluster_;
329 cluster.mutable_eds_cluster_config()->set_service_name(kNewEdsResourceName);
330 balancer_->ads_service()->SetCdsResource(
cluster);
339 class CdsDeletionTest :
public XdsEnd2endTest {
341 void SetUp()
override {}
348 TEST_P(CdsDeletionTest, ClusterDeleted) {
350 CreateAndStartBackends(1);
351 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
352 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
356 balancer_->ads_service()->UnsetResource(
kCdsTypeUrl, kDefaultClusterName);
359 if (
result.status.ok())
return true;
362 "\" does not exist"),
363 result.status.error_message());
367 auto response_state = balancer_->ads_service()->cds_response_state();
373 TEST_P(CdsDeletionTest, ClusterDeletionIgnored) {
374 InitClient(BootstrapBuilder().SetIgnoreResourceDeletion());
375 CreateAndStartBackends(2);
377 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
378 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
381 auto response_state = balancer_->ads_service()->cds_response_state();
385 balancer_->ads_service()->UnsetResource(
kCdsTypeUrl, kDefaultClusterName);
389 response_state = balancer_->ads_service()->cds_response_state();
390 if (response_state.has_value())
break;
397 const char* kNewEdsResourceName =
"new_eds_resource_name";
398 auto cluster = default_cluster_;
399 cluster.mutable_eds_cluster_config()->set_service_name(kNewEdsResourceName);
400 balancer_->ads_service()->SetCdsResource(
cluster);
401 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
402 balancer_->ads_service()->SetEdsResource(
403 BuildEdsResource(
args, kNewEdsResourceName));
412 using EdsTest = XdsEnd2endTest;
416 ::
testing::Values(XdsTestType(), XdsTestType().set_enable_load_reporting()),
421 TEST_P(EdsTest, Vanilla) {
422 CreateAndStartBackends(3);
423 const size_t kNumRpcsPerAddress = 100;
424 EdsResourceArgs
args({
425 {
"locality0", CreateEndpointsForBackends()},
427 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
440 EXPECT_EQ(
"xds_cluster_manager_experimental",
441 channel_->GetLoadBalancingPolicyName());
444 TEST_P(EdsTest, IgnoresUnhealthyEndpoints) {
445 CreateAndStartBackends(2);
446 const size_t kNumRpcsPerAddress = 100;
447 auto endpoints = CreateEndpointsForBackends();
448 endpoints.push_back(MakeNonExistantEndpoint());
449 endpoints.back().health_status = HealthStatus::DRAINING;
450 EdsResourceArgs
args({
451 {
"locality0",
std::move(endpoints), kDefaultLocalityWeight,
452 kDefaultLocalityPriority},
454 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
470 TEST_P(EdsTest, SameBackendListedMultipleTimes) {
471 CreateAndStartBackends(1);
473 auto endpoints = CreateEndpointsForBackends();
474 endpoints.push_back(endpoints.front());
475 EdsResourceArgs
args({{
"locality0", endpoints}});
476 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
480 const size_t kNumRpcsPerAddress = 10;
481 CheckRpcSendOk(
DEBUG_LOCATION, kNumRpcsPerAddress * endpoints.size());
483 EXPECT_EQ(kNumRpcsPerAddress * endpoints.size(),
484 backends_[0]->backend_service()->request_count());
488 TEST_P(EdsTest, InitiallyEmptyServerlist) {
489 CreateAndStartBackends(1);
491 EdsResourceArgs::Locality empty_locality(
"locality0", {});
493 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
498 "empty address list: ";
501 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends()}});
502 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
505 if (!
result.status.ok()) {
506 EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
507 EXPECT_EQ(result.status.error_message(), kErrorMessage);
514 TEST_P(EdsTest, AllServersUnreachableFailFast) {
517 const uint32_t kRpcTimeoutMs = 5000;
518 const size_t kNumUnreachableServers = 5;
519 std::vector<EdsResourceArgs::Endpoint> endpoints;
520 for (
size_t i = 0;
i < kNumUnreachableServers; ++
i) {
521 endpoints.emplace_back(MakeNonExistantEndpoint());
524 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
534 TEST_P(EdsTest, BackendsRestart) {
535 CreateAndStartBackends(3);
536 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
537 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
540 ShutdownAllBackends();
548 "connections to all backends failing; last error: "
549 "(UNKNOWN: Failed to connect to remote host: Connection refused|"
550 "UNAVAILABLE: Failed to connect to remote host: FD shutdown)");
554 RpcOptions().set_timeout_ms(2000).set_wait_for_ready(
true));
557 TEST_P(EdsTest, IgnoresDuplicateUpdates) {
558 CreateAndStartBackends(1);
559 const size_t kNumRpcsPerAddress = 100;
560 EdsResourceArgs
args({
561 {
"locality0", CreateEndpointsForBackends()},
563 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
570 for (
size_t i = 0;
i < kNumRpcsPerAddress; ++
i) {
572 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
584 TEST_P(EdsTest, NacksSparsePriorityList) {
585 EdsResourceArgs
args({
586 {
"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
588 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
590 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
597 TEST_P(EdsTest, NacksDuplicateLocalityInSamePriority) {
598 EdsResourceArgs
args({
599 {
"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
600 {
"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
602 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
604 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
607 "duplicate locality {region=\"xds_default_locality_region\", "
608 "zone=\"xds_default_locality_zone\", sub_zone=\"locality0\"} "
609 "found in priority 0"));
612 TEST_P(EdsTest, NacksEndpointWeightZero) {
613 EdsResourceArgs
args({{
"locality0", {MakeNonExistantEndpoint()}}});
614 auto eds_resource = BuildEdsResource(
args);
615 eds_resource.mutable_endpoints(0)
616 ->mutable_lb_endpoints(0)
617 ->mutable_load_balancing_weight()
619 balancer_->ads_service()->SetEdsResource(eds_resource);
621 ASSERT_TRUE(response_state.has_value()) <<
"timed out waiting for NACK";
629 TEST_P(EdsTest, KeepUsingLastDataIfBalancerGoesDown) {
630 CreateAndStartBackends(2);
632 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
633 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
637 balancer_->Shutdown();
644 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
645 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
653 TEST_P(EdsTest, WeightedRoundRobin) {
654 CreateAndStartBackends(2);
655 const int kLocalityWeight0 = 2;
656 const int kLocalityWeight1 = 8;
657 const int kTotalLocalityWeight = kLocalityWeight0 + kLocalityWeight1;
658 const double kLocalityWeightRate0 =
659 static_cast<double>(kLocalityWeight0) / kTotalLocalityWeight;
660 const double kLocalityWeightRate1 =
661 static_cast<double>(kLocalityWeight1) / kTotalLocalityWeight;
662 const double kErrorTolerance = 0.05;
664 ComputeIdealNumRpcs(kLocalityWeightRate0, kErrorTolerance);
666 EdsResourceArgs
args({
667 {
"locality0", CreateEndpointsForBackends(0, 1), kLocalityWeight0},
668 {
"locality1", CreateEndpointsForBackends(1, 2), kLocalityWeight1},
670 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
676 const double locality_picked_rate_0 =
677 static_cast<double>(
backends_[0]->backend_service()->request_count()) /
679 const double locality_picked_rate_1 =
680 static_cast<double>(
backends_[1]->backend_service()->request_count()) /
689 TEST_P(EdsTest, LocalityContainingNoEndpoints) {
690 CreateAndStartBackends(2);
693 EdsResourceArgs
args({
694 {
"locality0", CreateEndpointsForBackends()},
697 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
710 TEST_P(EdsTest, NoLocalities) {
711 balancer_->ads_service()->SetEdsResource(BuildEdsResource({}));
719 TEST_P(EdsTest, ManyLocalitiesStressTest) {
720 CreateAndStartBackends(2);
721 const size_t kNumLocalities = 100;
722 const uint32_t kRpcTimeoutMs = 5000;
725 EdsResourceArgs
args;
726 for (
size_t i = 0;
i < kNumLocalities; ++
i) {
728 EdsResourceArgs::Locality locality(
name, CreateEndpointsForBackends(0, 1));
731 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
734 WaitForBackendOptions().set_reset_counters(
false),
735 RpcOptions().set_timeout_ms(kRpcTimeoutMs));
738 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(1, 2)}});
739 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
746 TEST_P(EdsTest, LocalityMapUpdateChurn) {
747 CreateAndStartBackends(4);
750 const std::vector<int> kLocalityWeights0 = {2, 3, 4};
751 const double kTotalLocalityWeight0 =
752 std::accumulate(kLocalityWeights0.begin(), kLocalityWeights0.end(), 0);
753 std::vector<double> locality_weight_rate_0;
754 locality_weight_rate_0.reserve(kLocalityWeights0.size());
755 for (
int weight : kLocalityWeights0) {
756 locality_weight_rate_0.push_back(
weight / kTotalLocalityWeight0);
760 const std::vector<int> kLocalityWeights1 = {3, 2, 6};
761 const double kTotalLocalityWeight1 =
762 std::accumulate(kLocalityWeights1.begin(), kLocalityWeights1.end(), 0);
763 std::vector<double> locality_weight_rate_1 = {
765 for (
int weight : kLocalityWeights1) {
766 locality_weight_rate_1.push_back(
weight / kTotalLocalityWeight1);
768 EdsResourceArgs
args({
769 {
"locality0", CreateEndpointsForBackends(0, 1), 2},
770 {
"locality1", CreateEndpointsForBackends(1, 2), 3},
771 {
"locality2", CreateEndpointsForBackends(2, 3), 4},
773 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
782 std::vector<double> locality_picked_rates;
783 for (
size_t i = 0;
i < 3; ++
i) {
784 locality_picked_rates.push_back(
788 const double kErrorTolerance = 0.2;
789 for (
size_t i = 0;
i < 3; ++
i) {
791 locality_picked_rates[i]);
793 locality_picked_rates[i],
795 ::
testing::Ge(locality_weight_rate_0[i] * (1 - kErrorTolerance)),
796 ::
testing::Le(locality_weight_rate_0[i] * (1 + kErrorTolerance))));
798 args = EdsResourceArgs({
799 {
"locality1", CreateEndpointsForBackends(1, 2), 3},
800 {
"locality2", CreateEndpointsForBackends(2, 3), 2},
801 {
"locality3", CreateEndpointsForBackends(3, 4), 6},
803 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
817 locality_picked_rates = {0 };
818 for (
size_t i = 1;
i < 4; ++
i) {
819 locality_picked_rates.push_back(
823 for (
size_t i = 1;
i < 4; ++
i) {
825 locality_picked_rates[i]);
827 locality_picked_rates[i],
829 ::
testing::Ge(locality_weight_rate_1[i] * (1 - kErrorTolerance)),
830 ::
testing::Le(locality_weight_rate_1[i] * (1 + kErrorTolerance))));
836 TEST_P(EdsTest, ReplaceAllLocalitiesInPriority) {
837 CreateAndStartBackends(2);
839 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 1)}});
840 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
844 args = EdsResourceArgs({{
"locality1", CreateEndpointsForBackends(1, 2)}});
845 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
851 TEST_P(EdsTest, ConsistentWeightedTargetUpdates) {
852 CreateAndStartBackends(4);
854 EdsResourceArgs
args({
855 {
"locality0", CreateEndpointsForBackends(1, 2)},
856 {
"locality1", CreateEndpointsForBackends(2, 3)},
858 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
863 args = EdsResourceArgs({
864 {
"locality0", CreateEndpointsForBackends(0, 2)},
866 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
871 args = EdsResourceArgs({
872 {
"locality0", CreateEndpointsForBackends(0, 2)},
873 {
"locality1", CreateEndpointsForBackends(2, 4)},
875 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
881 CreateAndStartBackends(1);
882 const uint32_t kDropPerMillionForLb = 100000;
883 const uint32_t kDropPerMillionForThrottle = 200000;
884 const double kDropRateForLb = kDropPerMillionForLb / 1000000.0;
885 const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0;
886 const double kDropRateForLbAndThrottle =
887 kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle;
888 const double kErrorTolerance = 0.05;
890 ComputeIdealNumRpcs(kDropRateForLbAndThrottle, kErrorTolerance);
892 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
893 args.drop_categories = {{kLbDropType, kDropPerMillionForLb},
894 {kThrottleDropType, kDropPerMillionForThrottle}};
895 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
897 size_t num_drops = SendRpcsAndCountFailuresWithMessage(
899 kStatusMessageDropPrefix);
901 const double seen_drop_rate =
static_cast<double>(num_drops) /
kNumRpcs;
907 TEST_P(EdsTest, DropPerHundred) {
908 CreateAndStartBackends(1);
909 const uint32_t kDropPerHundredForLb = 10;
910 const double kDropRateForLb = kDropPerHundredForLb / 100.0;
911 const double kErrorTolerance = 0.05;
912 const size_t kNumRpcs = ComputeIdealNumRpcs(kDropRateForLb, kErrorTolerance);
914 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
915 args.drop_categories = {{kLbDropType, kDropPerHundredForLb}};
916 args.drop_denominator = FractionalPercent::HUNDRED;
917 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
919 size_t num_drops = SendRpcsAndCountFailuresWithMessage(
921 kStatusMessageDropPrefix);
923 const double seen_drop_rate =
static_cast<double>(num_drops) /
kNumRpcs;
929 TEST_P(EdsTest, DropPerTenThousand) {
930 CreateAndStartBackends(1);
931 const uint32_t kDropPerTenThousandForLb = 1000;
932 const double kDropRateForLb = kDropPerTenThousandForLb / 10000.0;
933 const double kErrorTolerance = 0.05;
934 const size_t kNumRpcs = ComputeIdealNumRpcs(kDropRateForLb, kErrorTolerance);
936 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
937 args.drop_categories = {{kLbDropType, kDropPerTenThousandForLb}};
938 args.drop_denominator = FractionalPercent::TEN_THOUSAND;
939 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
941 size_t num_drops = SendRpcsAndCountFailuresWithMessage(
943 kStatusMessageDropPrefix);
945 const double seen_drop_rate =
static_cast<double>(num_drops) /
kNumRpcs;
951 TEST_P(EdsTest, DropConfigUpdate) {
952 CreateAndStartBackends(1);
953 const uint32_t kDropPerMillionForLb = 100000;
954 const uint32_t kDropPerMillionForThrottle = 200000;
955 const double kErrorTolerance = 0.05;
956 const double kDropRateForLb = kDropPerMillionForLb / 1000000.0;
957 const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0;
958 const double kDropRateForLbAndThrottle =
959 kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle;
960 const size_t kNumRpcsLbOnly =
961 ComputeIdealNumRpcs(kDropRateForLb, kErrorTolerance);
962 const size_t kNumRpcsBoth =
963 ComputeIdealNumRpcs(kDropRateForLbAndThrottle, kErrorTolerance);
965 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
966 args.drop_categories = {{kLbDropType, kDropPerMillionForLb}};
967 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
970 size_t num_drops = SendRpcsAndCountFailuresWithMessage(
972 kStatusMessageDropPrefix);
975 double seen_drop_rate =
static_cast<double>(num_drops) / kNumRpcsLbOnly;
981 args.drop_categories = {{kLbDropType, kDropPerMillionForLb},
982 {kThrottleDropType, kDropPerMillionForThrottle}};
983 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
986 const double kDropRateThreshold =
987 (kDropRateForLb + kDropRateForLbAndThrottle) / 2;
988 size_t num_rpcs = kNumRpcsBoth;
991 [&](
const RpcResult&
result) {
994 EXPECT_EQ(result.response.message(), kRequestMessage);
996 EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
997 EXPECT_THAT(result.status.error_message(),
998 ::testing::StartsWith(kStatusMessageDropPrefix));
1001 seen_drop_rate =
static_cast<double>(num_drops) / num_rpcs;
1002 return seen_drop_rate < kDropRateThreshold;
1007 num_drops = SendRpcsAndCountFailuresWithMessage(
DEBUG_LOCATION, kNumRpcsBoth,
1009 kStatusMessageDropPrefix);
1012 seen_drop_rate =
static_cast<double>(num_drops) / kNumRpcsBoth;
1019 TEST_P(EdsTest, DropAll) {
1021 const uint32_t kDropPerMillionForLb = 100000;
1022 const uint32_t kDropPerMillionForThrottle = 1000000;
1024 EdsResourceArgs
args;
1025 args.drop_categories = {{kLbDropType, kDropPerMillionForLb},
1026 {kThrottleDropType, kDropPerMillionForThrottle}};
1027 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1029 size_t num_drops = SendRpcsAndCountFailuresWithMessage(
1031 kStatusMessageDropPrefix);
1039 class FailoverTest :
public XdsEnd2endTest {
1041 void SetUp()
override {
1048 XdsTest, FailoverTest,
1049 ::
testing::Values(XdsTestType(), XdsTestType().set_enable_load_reporting()),
1053 TEST_P(FailoverTest, ChooseHighestPriority) {
1054 CreateAndStartBackends(4);
1055 EdsResourceArgs
args({
1056 {
"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1058 {
"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1060 {
"locality2", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
1062 {
"locality3", CreateEndpointsForBackends(3, 4), kDefaultLocalityWeight,
1065 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1067 WaitForBackendOptions().set_reset_counters(
false));
1068 for (
size_t i = 0;
i < 3; ++
i) {
1074 TEST_P(FailoverTest, DoesNotUsePriorityWithNoEndpoints) {
1075 CreateAndStartBackends(3);
1076 EdsResourceArgs
args({
1077 {
"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1079 {
"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1081 {
"locality2", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
1083 {
"locality3", {}, kDefaultLocalityWeight, 0},
1085 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1087 WaitForBackendOptions().set_reset_counters(
false));
1088 for (
size_t i = 1;
i < 3; ++
i) {
1094 TEST_P(FailoverTest, DoesNotUseLocalityWithNoEndpoints) {
1095 CreateAndStartBackends(1);
1096 EdsResourceArgs
args({
1097 {
"locality0", {}, kDefaultLocalityWeight, 0},
1098 {
"locality1", CreateEndpointsForBackends(), kDefaultLocalityWeight, 0},
1100 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1107 TEST_P(FailoverTest, Failover) {
1108 CreateAndStartBackends(2);
1109 EdsResourceArgs
args({
1110 {
"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
1111 {
"locality1", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1113 {
"locality2", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1115 {
"locality3", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
1117 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1119 WaitForBackendOptions().set_reset_counters(
false));
1125 TEST_P(FailoverTest, SwitchBackToHigherPriority) {
1126 CreateAndStartBackends(4);
1128 EdsResourceArgs
args({
1129 {
"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1131 {
"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1133 {
"locality2", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
1135 {
"locality3", CreateEndpointsForBackends(3, 4), kDefaultLocalityWeight,
1138 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1140 backends_[3]->StopListeningAndSendGoaways();
1141 backends_[0]->StopListeningAndSendGoaways();
1152 TEST_P(FailoverTest, UpdateInitialUnavailable) {
1153 CreateAndStartBackends(2);
1154 EdsResourceArgs
args({
1155 {
"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
1156 {
"locality1", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
1158 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1159 constexpr
char kErrorMessageRegex[] =
1160 "connections to all backends failing; last error: "
1161 "(UNKNOWN: Failed to connect to remote host: Connection refused|"
1162 "UNAVAILABLE: Failed to connect to remote host: FD shutdown)";
1164 kErrorMessageRegex);
1165 args = EdsResourceArgs({
1166 {
"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1168 {
"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1171 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1173 if (!
result.status.ok()) {
1174 EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
1175 EXPECT_THAT(result.status.error_message(),
1176 ::testing::MatchesRegex(kErrorMessageRegex));
1183 TEST_P(FailoverTest, UpdatePriority) {
1184 CreateAndStartBackends(4);
1186 EdsResourceArgs
args({
1187 {
"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1189 {
"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1191 {
"locality2", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
1193 {
"locality3", CreateEndpointsForBackends(3, 4), kDefaultLocalityWeight,
1196 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1198 WaitForBackendOptions().set_reset_counters(
false));
1202 args = EdsResourceArgs({
1203 {
"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1205 {
"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1207 {
"locality2", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
1209 {
"locality3", CreateEndpointsForBackends(3, 4), kDefaultLocalityWeight,
1212 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1219 TEST_P(FailoverTest, MoveAllLocalitiesInCurrentPriorityToHigherPriority) {
1220 CreateAndStartBackends(3);
1221 auto non_existant_endpoint = MakeNonExistantEndpoint();
1225 EdsResourceArgs
args({
1226 {
"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
1227 {
"locality1", CreateEndpointsForBackends(0, 2), kDefaultLocalityWeight,
1230 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1235 WaitForBackendOptions().set_reset_counters(
false));
1242 args = EdsResourceArgs({
1243 {
"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
1244 {
"locality1", CreateEndpointsForBackends(0, 3), kDefaultLocalityWeight,
1247 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1251 EXPECT_TRUE(balancer_->ads_service()->eds_response_state().has_value());
1257 TEST_P(FailoverTest, PriorityChildNameChurn) {
1258 CreateAndStartBackends(4);
1259 auto non_existant_endpoint = MakeNonExistantEndpoint();
1264 EdsResourceArgs
args({
1265 {
"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
1266 {
"locality1", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
1268 {
"locality2", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1271 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1278 args = EdsResourceArgs({
1279 {
"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
1280 {
"locality2", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1282 {
"locality3", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
1285 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1292 args = EdsResourceArgs({
1293 {
"locality0", {non_existant_endpoint}, kDefaultLocalityWeight, 0},
1294 {
"locality4", CreateEndpointsForBackends(3, 4), kDefaultLocalityWeight,
1296 {
"locality3", CreateEndpointsForBackends(2, 3), kDefaultLocalityWeight,
1299 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1301 WaitForBackendOptions().set_reset_counters(
false));
1310 using ClientLoadReportingTest = XdsEnd2endTest;
1313 XdsTest, ClientLoadReportingTest,
1318 TEST_P(ClientLoadReportingTest, Vanilla) {
1319 CreateAndStartBackends(4);
1320 const size_t kNumRpcsPerAddress = 10;
1321 const size_t kNumFailuresPerAddress = 3;
1322 EdsResourceArgs
args({
1323 {
"locality0", CreateEndpointsForBackends(0, 2)},
1324 {
"locality1", CreateEndpointsForBackends(2, 4)},
1326 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1328 size_t num_warmup_rpcs =
1330 WaitForBackendOptions().set_reset_counters(
false));
1333 for (
size_t i = 0;
i < kNumFailuresPerAddress *
backends_.size(); ++
i) {
1335 RpcOptions().set_server_fail(
true));
1337 const size_t total_successful_rpcs_sent =
1338 (kNumRpcsPerAddress *
backends_.size()) + num_warmup_rpcs;
1339 const size_t total_failed_rpcs_sent =
1340 kNumFailuresPerAddress *
backends_.size();
1342 size_t total_rpcs_sent = 0;
1344 total_rpcs_sent += backend->backend_service()->request_count();
1347 total_successful_rpcs_sent + total_failed_rpcs_sent);
1349 std::vector<ClientStats> load_report =
1350 balancer_->lrs_service()->WaitForLoadReport();
1352 ClientStats& client_stats = load_report.front();
1353 EXPECT_EQ(client_stats.cluster_name(), kDefaultClusterName);
1354 EXPECT_EQ(client_stats.eds_service_name(), kDefaultEdsServiceName);
1356 client_stats.total_successful_requests());
1357 EXPECT_EQ(0U, client_stats.total_requests_in_progress());
1358 EXPECT_EQ(total_rpcs_sent, client_stats.total_issued_requests());
1359 EXPECT_EQ(total_failed_rpcs_sent, client_stats.total_error_requests());
1360 EXPECT_EQ(0U, client_stats.total_dropped_requests());
1362 client_stats.locality_stats(),
1365 size_t num_successful_rpcs = 0;
1366 size_t num_failed_rpcs = 0;
1367 for (
const auto& p : client_stats.locality_stats()) {
1368 EXPECT_EQ(
p.second.total_requests_in_progress, 0U);
1370 p.second.total_issued_requests,
1371 p.second.total_successful_requests +
p.second.total_error_requests);
1372 num_successful_rpcs +=
p.second.total_successful_requests;
1373 num_failed_rpcs +=
p.second.total_error_requests;
1375 EXPECT_EQ(num_successful_rpcs, total_successful_rpcs_sent);
1376 EXPECT_EQ(num_failed_rpcs, total_failed_rpcs_sent);
1377 EXPECT_EQ(num_successful_rpcs + num_failed_rpcs, total_rpcs_sent);
1379 EXPECT_EQ(1U, balancer_->lrs_service()->request_count());
1380 EXPECT_EQ(1U, balancer_->lrs_service()->response_count());
1384 TEST_P(ClientLoadReportingTest, SendAllClusters) {
1385 CreateAndStartBackends(2);
1386 balancer_->lrs_service()->set_send_all_clusters(
true);
1387 const size_t kNumRpcsPerAddress = 10;
1388 const size_t kNumFailuresPerAddress = 3;
1389 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
1390 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1395 for (
size_t i = 0;
i < kNumFailuresPerAddress *
backends_.size(); ++
i) {
1397 RpcOptions().set_server_fail(
true));
1401 EXPECT_EQ(kNumRpcsPerAddress + kNumFailuresPerAddress,
1405 std::vector<ClientStats> load_report =
1406 balancer_->lrs_service()->WaitForLoadReport();
1408 ClientStats& client_stats = load_report.front();
1410 client_stats.total_successful_requests());
1411 EXPECT_EQ(0U, client_stats.total_requests_in_progress());
1414 client_stats.total_issued_requests());
1416 client_stats.total_error_requests());
1417 EXPECT_EQ(0U, client_stats.total_dropped_requests());
1419 EXPECT_EQ(1U, balancer_->lrs_service()->request_count());
1420 EXPECT_EQ(1U, balancer_->lrs_service()->response_count());
1425 TEST_P(ClientLoadReportingTest, HonorsClustersRequestedByLrsServer) {
1426 CreateAndStartBackends(1);
1427 balancer_->lrs_service()->set_cluster_names({
"bogus"});
1428 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
1429 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1433 std::vector<ClientStats> load_report =
1434 balancer_->lrs_service()->WaitForLoadReport();
1437 EXPECT_EQ(1U, balancer_->lrs_service()->request_count());
1438 EXPECT_EQ(1U, balancer_->lrs_service()->response_count());
1443 TEST_P(ClientLoadReportingTest, BalancerRestart) {
1444 CreateAndStartBackends(4);
1445 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends(0, 2)}});
1446 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1449 std::vector<ClientStats> load_report =
1450 balancer_->lrs_service()->WaitForLoadReport();
1452 ClientStats client_stats =
std::move(load_report.front());
1453 EXPECT_EQ(num_rpcs, client_stats.total_successful_requests());
1454 EXPECT_EQ(0U, client_stats.total_requests_in_progress());
1455 EXPECT_EQ(0U, client_stats.total_error_requests());
1456 EXPECT_EQ(0U, client_stats.total_dropped_requests());
1458 balancer_->Shutdown();
1469 ResetBackendCounters();
1473 args = EdsResourceArgs({{
"locality0", CreateEndpointsForBackends(2, 4)}});
1474 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1482 load_report = balancer_->lrs_service()->WaitForLoadReport();
1484 client_stats =
std::move(load_report.front());
1485 EXPECT_EQ(num_rpcs, client_stats.total_successful_requests());
1486 EXPECT_EQ(0U, client_stats.total_requests_in_progress());
1487 EXPECT_EQ(0U, client_stats.total_error_requests());
1488 EXPECT_EQ(0U, client_stats.total_dropped_requests());
1492 TEST_P(ClientLoadReportingTest, ChangeClusters) {
1493 CreateAndStartBackends(4);
1494 const char* kNewClusterName =
"new_cluster_name";
1495 const char* kNewEdsServiceName =
"new_eds_service_name";
1496 balancer_->lrs_service()->set_cluster_names(
1497 {kDefaultClusterName, kNewClusterName});
1499 EdsResourceArgs
args({
1500 {
"locality0", CreateEndpointsForBackends(0, 2)},
1502 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1504 EdsResourceArgs args2({
1505 {
"locality1", CreateEndpointsForBackends(2, 4)},
1507 balancer_->ads_service()->SetEdsResource(
1508 BuildEdsResource(args2, kNewEdsServiceName));
1510 Cluster new_cluster = default_cluster_;
1511 new_cluster.set_name(kNewClusterName);
1512 new_cluster.mutable_eds_cluster_config()->set_service_name(
1513 kNewEdsServiceName);
1514 balancer_->ads_service()->SetCdsResource(new_cluster);
1518 std::vector<ClientStats> load_report =
1519 balancer_->lrs_service()->WaitForLoadReport();
1525 kDefaultEdsServiceName),
1527 &ClientStats::locality_stats,
1532 total_successful_requests,
1535 total_requests_in_progress,
1538 &ClientStats::LocalityStats::total_error_requests,
1541 &ClientStats::LocalityStats::total_issued_requests,
1545 RouteConfiguration new_route_config = default_route_config_;
1546 new_route_config.mutable_virtual_hosts(0)
1549 ->set_cluster(kNewClusterName);
1550 SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
1555 load_report = balancer_->lrs_service()->WaitForLoadReport();
1561 kDefaultClusterName),
1563 kDefaultEdsServiceName),
1565 &ClientStats::locality_stats,
1570 total_successful_requests,
1573 total_requests_in_progress,
1576 &ClientStats::LocalityStats::total_error_requests,
1579 total_issued_requests,
1585 kNewEdsServiceName),
1587 &ClientStats::locality_stats,
1592 total_successful_requests,
1595 total_requests_in_progress,
1598 &ClientStats::LocalityStats::total_error_requests,
1601 total_issued_requests,
1604 size_t total_ok = 0;
1605 for (
const ClientStats& client_stats : load_report) {
1606 total_ok += client_stats.total_successful_requests();
1610 EXPECT_EQ(1U, balancer_->lrs_service()->request_count());
1611 EXPECT_EQ(1U, balancer_->lrs_service()->response_count());
1615 TEST_P(ClientLoadReportingTest, DropStats) {
1616 CreateAndStartBackends(1);
1617 const uint32_t kDropPerMillionForLb = 100000;
1618 const uint32_t kDropPerMillionForThrottle = 200000;
1619 const double kErrorTolerance = 0.05;
1620 const double kDropRateForLb = kDropPerMillionForLb / 1000000.0;
1621 const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0;
1622 const double kDropRateForLbAndThrottle =
1623 kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle;
1625 ComputeIdealNumRpcs(kDropRateForLbAndThrottle, kErrorTolerance);
1627 EdsResourceArgs
args({{
"locality0", CreateEndpointsForBackends()}});
1628 args.drop_categories = {{kLbDropType, kDropPerMillionForLb},
1629 {kThrottleDropType, kDropPerMillionForThrottle}};
1630 balancer_->ads_service()->SetEdsResource(BuildEdsResource(
args));
1632 size_t num_drops = SendRpcsAndCountFailuresWithMessage(
1634 kStatusMessageDropPrefix);
1636 const double seen_drop_rate =
static_cast<double>(num_drops) /
kNumRpcs;
1640 ClientStats client_stats;
1642 std::vector<ClientStats> load_reports =
1643 balancer_->lrs_service()->WaitForLoadReport();
1644 for (
const auto& load_report : load_reports) {
1645 client_stats += load_report;
1647 }
while (client_stats.total_issued_requests() +
1648 client_stats.total_dropped_requests() <
1650 EXPECT_EQ(num_drops, client_stats.total_dropped_requests());
1651 EXPECT_THAT(
static_cast<double>(client_stats.dropped_requests(kLbDropType)) /
1655 static_cast<double>(client_stats.dropped_requests(kThrottleDropType)) /
1670 #if TARGET_OS_IPHONE