1 // Copyright 2017 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <chrono>
16 #include <string>
17 #include <thread>
18 #include <vector>
19
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 #include "src/core/client_channel/backup_poller.h"
24 #include "src/core/lib/config/config_vars.h"
25 #include "src/proto/grpc/testing/xds/v3/fault.grpc.pb.h"
26 #include "src/proto/grpc/testing/xds/v3/router.grpc.pb.h"
27 #include "test/cpp/end2end/xds/xds_end2end_test_lib.h"
28
29 namespace grpc {
30 namespace testing {
31 namespace {
32
33 using std::chrono::system_clock;
34
35 using LdsTest = XdsEnd2endTest;
36
37 INSTANTIATE_TEST_SUITE_P(XdsTest, LdsTest, ::testing::Values(XdsTestType()),
38 &XdsTestType::Name);
39
40 // Testing just one example of an invalid resource here.
41 // Unit tests for XdsListenerResourceType have exhaustive tests for all
42 // of the invalid cases.
TEST_P(LdsTest,NacksInvalidListener)43 TEST_P(LdsTest, NacksInvalidListener) {
44 auto listener = default_listener_;
45 listener.clear_api_listener();
46 balancer_->ads_service()->SetLdsResource(listener);
47 const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
48 ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
49 EXPECT_THAT(
50 response_state->error_message,
51 ::testing::HasSubstr("Listener has neither address nor ApiListener"));
52 }
53
54 // Tests that we go into TRANSIENT_FAILURE if the Listener is not an API
55 // listener.
TEST_P(LdsTest,NotAnApiListener)56 TEST_P(LdsTest, NotAnApiListener) {
57 Listener listener = default_server_listener_;
58 listener.set_name(kServerName);
59 auto hcm = ServerHcmAccessor().Unpack(listener);
60 auto* rds = hcm.mutable_rds();
61 rds->set_route_config_name(kDefaultRouteConfigurationName);
62 rds->mutable_config_source()->mutable_self();
63 ServerHcmAccessor().Pack(hcm, &listener);
64 balancer_->ads_service()->SetLdsResource(listener);
65 // RPCs should fail.
66 CheckRpcSendFailure(
67 DEBUG_LOCATION, StatusCode::UNAVAILABLE,
68 absl::StrCat(kServerName, ": UNAVAILABLE: not an API listener"));
69 // We should have ACKed the LDS resource.
70 const auto deadline =
71 absl::Now() + (absl::Seconds(30) * grpc_test_slowdown_factor());
72 while (true) {
73 ASSERT_LT(absl::Now(), deadline) << "timed out waiting for LDS ACK";
74 auto response_state = balancer_->ads_service()->lds_response_state();
75 if (response_state.has_value()) {
76 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
77 break;
78 }
79 absl::SleepFor(absl::Seconds(1) * grpc_test_slowdown_factor());
80 }
81 }
82
83 class LdsDeletionTest : public XdsEnd2endTest {
84 protected:
SetUp()85 void SetUp() override {} // Individual tests call InitClient().
86 };
87
88 INSTANTIATE_TEST_SUITE_P(XdsTest, LdsDeletionTest,
89 ::testing::Values(XdsTestType()), &XdsTestType::Name);
90
91 // Tests that we go into TRANSIENT_FAILURE if the Listener is deleted.
TEST_P(LdsDeletionTest,ListenerDeleted)92 TEST_P(LdsDeletionTest, ListenerDeleted) {
93 InitClient();
94 CreateAndStartBackends(1);
95 EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
96 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
97 // We need to wait for all backends to come online.
98 WaitForAllBackends(DEBUG_LOCATION);
99 // Unset LDS resource.
100 balancer_->ads_service()->UnsetResource(kLdsTypeUrl, kServerName);
101 // Wait for RPCs to start failing.
102 SendRpcsUntil(DEBUG_LOCATION, [](const RpcResult& result) {
103 if (result.status.ok()) return true; // Keep going.
104 EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
105 EXPECT_EQ(result.status.error_message(),
106 absl::StrCat("empty address list: ", kServerName,
107 ": xDS listener resource does not exist"));
108 return false;
109 });
110 // Make sure we ACK'ed the update.
111 auto response_state = balancer_->ads_service()->lds_response_state();
112 ASSERT_TRUE(response_state.has_value());
113 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
114 }
115
116 // Tests that we ignore Listener deletions if configured to do so.
TEST_P(LdsDeletionTest,ListenerDeletionIgnored)117 TEST_P(LdsDeletionTest, ListenerDeletionIgnored) {
118 InitClient(MakeBootstrapBuilder().SetIgnoreResourceDeletion());
119 CreateAndStartBackends(2);
120 // Bring up client pointing to backend 0 and wait for it to connect.
121 EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
122 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
123 WaitForAllBackends(DEBUG_LOCATION, 0, 1);
124 // Make sure we ACKed the LDS update.
125 auto response_state = balancer_->ads_service()->lds_response_state();
126 ASSERT_TRUE(response_state.has_value());
127 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
128 // Unset LDS resource and wait for client to ACK the update.
129 balancer_->ads_service()->UnsetResource(kLdsTypeUrl, kServerName);
130 const auto deadline =
131 absl::Now() + (absl::Seconds(30) * grpc_test_slowdown_factor());
132 while (true) {
133 ASSERT_LT(absl::Now(), deadline) << "timed out waiting for LDS ACK";
134 response_state = balancer_->ads_service()->lds_response_state();
135 if (response_state.has_value()) break;
136 absl::SleepFor(absl::Seconds(1) * grpc_test_slowdown_factor());
137 }
138 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
139 // Make sure we can still send RPCs.
140 CheckRpcSendOk(DEBUG_LOCATION);
141 // Now recreate the LDS resource pointing to a different CDS and EDS
142 // resource, pointing to backend 1, and make sure the client uses it.
143 const char* kNewClusterName = "new_cluster_name";
144 const char* kNewEdsResourceName = "new_eds_resource_name";
145 auto cluster = default_cluster_;
146 cluster.set_name(kNewClusterName);
147 cluster.mutable_eds_cluster_config()->set_service_name(kNewEdsResourceName);
148 balancer_->ads_service()->SetCdsResource(cluster);
149 args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
150 balancer_->ads_service()->SetEdsResource(
151 BuildEdsResource(args, kNewEdsResourceName));
152 RouteConfiguration new_route_config = default_route_config_;
153 new_route_config.mutable_virtual_hosts(0)
154 ->mutable_routes(0)
155 ->mutable_route()
156 ->set_cluster(kNewClusterName);
157 SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
158 new_route_config);
159 // Wait for client to start using backend 1.
160 WaitForAllBackends(DEBUG_LOCATION, 1, 2);
161 }
162
163 using LdsRdsInteractionTest = XdsEnd2endTest;
164
165 INSTANTIATE_TEST_SUITE_P(
166 XdsTest, LdsRdsInteractionTest,
167 ::testing::Values(XdsTestType().set_enable_rds_testing()),
168 &XdsTestType::Name);
169
TEST_P(LdsRdsInteractionTest,SwitchFromRdsToInlineRouteConfig)170 TEST_P(LdsRdsInteractionTest, SwitchFromRdsToInlineRouteConfig) {
171 CreateAndStartBackends(2);
172 // Bring up client pointing to backend 0 and wait for it to connect.
173 EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
174 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
175 WaitForBackend(DEBUG_LOCATION, 0);
176 // RDS should have been ACKed.
177 auto response_state = balancer_->ads_service()->rds_response_state();
178 ASSERT_TRUE(response_state.has_value());
179 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
180 // Now recreate the LDS resource with an inline route config pointing to a
181 // different CDS and EDS resource, pointing to backend 1, and make sure
182 // the client uses it.
183 const char* kNewClusterName = "new_cluster_name";
184 const char* kNewEdsResourceName = "new_eds_resource_name";
185 auto cluster = default_cluster_;
186 cluster.set_name(kNewClusterName);
187 cluster.mutable_eds_cluster_config()->set_service_name(kNewEdsResourceName);
188 balancer_->ads_service()->SetCdsResource(cluster);
189 args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
190 balancer_->ads_service()->SetEdsResource(
191 BuildEdsResource(args, kNewEdsResourceName));
192 RouteConfiguration new_route_config = default_route_config_;
193 new_route_config.mutable_virtual_hosts(0)
194 ->mutable_routes(0)
195 ->mutable_route()
196 ->set_cluster(kNewClusterName);
197 Listener listener = default_listener_;
198 HttpConnectionManager http_connection_manager =
199 ClientHcmAccessor().Unpack(listener);
200 *http_connection_manager.mutable_route_config() = new_route_config;
201 ClientHcmAccessor().Pack(http_connection_manager, &listener);
202 balancer_->ads_service()->SetLdsResource(listener);
203 // Wait for client to start using backend 1.
204 WaitForBackend(DEBUG_LOCATION, 1);
205 // Send an update to the original RDS resource, which the client
206 // should no longer be subscribed to. We need this RouteConfig to be
207 // different than the original one so that the update does not get
208 // squelched by XdsClient, so we add a second domain to the vhost that
209 // will not actually be used.
210 new_route_config = default_route_config_;
211 new_route_config.mutable_virtual_hosts(0)->add_domains("foo.example.com");
212 balancer_->ads_service()->SetRdsResource(new_route_config);
213 // Wait for RDS ACK to know that the client saw the change.
214 // TODO(roth): The client does not actually ACK here, it just sends an
215 // unsubscription request, but our fake xDS server is incorrectly treating
216 // that as an ACK. When we have time, fix the behavior of the fake
217 // xDS server, and then change this test to ensure that there is no RDS
218 // ACK within the 30-second timeout period.
219 const auto deadline =
220 absl::Now() + (absl::Seconds(30) * grpc_test_slowdown_factor());
221 while (true) {
222 ASSERT_LT(absl::Now(), deadline) << "timed out waiting for RDS ACK";
223 response_state = balancer_->ads_service()->rds_response_state();
224 if (response_state.has_value()) break;
225 absl::SleepFor(absl::Seconds(1) * grpc_test_slowdown_factor());
226 }
227 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
228 // Make sure RPCs are still going to backend 1. This shows that the
229 // client did not replace its route config with the one from the RDS
230 // resource that it should no longer be using.
231 ResetBackendCounters();
232 CheckRpcSendOk(DEBUG_LOCATION);
233 EXPECT_EQ(0, backends_[0]->backend_service()->request_count());
234 EXPECT_EQ(1, backends_[1]->backend_service()->request_count());
235 }
236
TEST_P(LdsRdsInteractionTest,SwitchFromInlineRouteConfigToRds)237 TEST_P(LdsRdsInteractionTest, SwitchFromInlineRouteConfigToRds) {
238 CreateAndStartBackends(2);
239 // Create an LDS resource with an inline RouteConfig pointing to a
240 // different CDS and EDS resource, sending traffic to backend 0.
241 const char* kNewClusterName = "new_cluster_name";
242 const char* kNewEdsResourceName = "new_eds_resource_name";
243 auto cluster = default_cluster_;
244 cluster.set_name(kNewClusterName);
245 cluster.mutable_eds_cluster_config()->set_service_name(kNewEdsResourceName);
246 balancer_->ads_service()->SetCdsResource(cluster);
247 EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
248 balancer_->ads_service()->SetEdsResource(
249 BuildEdsResource(args, kNewEdsResourceName));
250 RouteConfiguration route_config = default_route_config_;
251 route_config.mutable_virtual_hosts(0)
252 ->mutable_routes(0)
253 ->mutable_route()
254 ->set_cluster(kNewClusterName);
255 Listener listener = default_listener_;
256 HttpConnectionManager http_connection_manager =
257 ClientHcmAccessor().Unpack(listener);
258 *http_connection_manager.mutable_route_config() = route_config;
259 ClientHcmAccessor().Pack(http_connection_manager, &listener);
260 balancer_->ads_service()->SetLdsResource(listener);
261 // Start the client and make sure traffic goes to backend 0.
262 WaitForBackend(DEBUG_LOCATION, 0);
263 // RDS should not have been ACKed, because the RouteConfig was inlined.
264 ASSERT_FALSE(balancer_->ads_service()->rds_response_state().has_value());
265 // Change the LDS resource to point to an RDS resource. The LDS resource
266 // configures the fault injection filter with a config that fails all RPCs.
267 // However, the RDS resource has a typed_per_filter_config override that
268 // disables the fault injection filter. The RDS resource points to a
269 // new cluster that sends traffic to backend 1.
270 args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
271 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
272 route_config = default_route_config_;
273 auto* config_map = route_config.mutable_virtual_hosts(0)
274 ->mutable_routes(0)
275 ->mutable_typed_per_filter_config();
276 (*config_map)["envoy.fault"].PackFrom(
277 envoy::extensions::filters::http::fault::v3::HTTPFault());
278 envoy::extensions::filters::http::fault::v3::HTTPFault http_fault;
279 auto* abort_percentage = http_fault.mutable_abort()->mutable_percentage();
280 abort_percentage->set_numerator(100);
281 abort_percentage->set_denominator(abort_percentage->HUNDRED);
282 http_fault.mutable_abort()->set_grpc_status(
283 static_cast<uint32_t>(StatusCode::ABORTED));
284 listener = default_listener_;
285 http_connection_manager = ClientHcmAccessor().Unpack(listener);
286 *http_connection_manager.add_http_filters() =
287 http_connection_manager.http_filters(0);
288 auto* filter = http_connection_manager.mutable_http_filters(0);
289 filter->set_name("envoy.fault");
290 filter->mutable_typed_config()->PackFrom(http_fault);
291 ClientHcmAccessor().Pack(http_connection_manager, &listener);
292 SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
293 route_config);
294 // Wait for traffic to switch to backend 1. There should be no RPC
295 // failures here; if there are, that indicates that the client started
296 // using the new LDS resource before it saw the new RDS resource.
297 WaitForBackend(DEBUG_LOCATION, 1);
298 }
299
TEST_P(LdsRdsInteractionTest,HcmConfigUpdatedWithoutRdsChange)300 TEST_P(LdsRdsInteractionTest, HcmConfigUpdatedWithoutRdsChange) {
301 CreateAndStartBackends(1);
302 // Bring up client pointing to backend 0 and wait for it to connect.
303 EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
304 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
305 WaitForBackend(DEBUG_LOCATION, 0);
306 // LDS should have been ACKed.
307 auto response_state = balancer_->ads_service()->lds_response_state();
308 ASSERT_TRUE(response_state.has_value());
309 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
310 // Now update the LDS resource to add the fault injection filter with
311 // a config that fails all RPCs.
312 envoy::extensions::filters::http::fault::v3::HTTPFault http_fault;
313 auto* abort_percentage = http_fault.mutable_abort()->mutable_percentage();
314 abort_percentage->set_numerator(100);
315 abort_percentage->set_denominator(abort_percentage->HUNDRED);
316 http_fault.mutable_abort()->set_grpc_status(
317 static_cast<uint32_t>(StatusCode::ABORTED));
318 Listener listener = default_listener_;
319 HttpConnectionManager http_connection_manager =
320 ClientHcmAccessor().Unpack(listener);
321 *http_connection_manager.add_http_filters() =
322 http_connection_manager.http_filters(0);
323 auto* filter = http_connection_manager.mutable_http_filters(0);
324 filter->set_name("envoy.fault");
325 filter->mutable_typed_config()->PackFrom(http_fault);
326 ClientHcmAccessor().Pack(http_connection_manager, &listener);
327 SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
328 default_route_config_);
329 // Wait for the LDS update to be ACKed.
330 const auto deadline =
331 absl::Now() + (absl::Seconds(30) * grpc_test_slowdown_factor());
332 while (true) {
333 ASSERT_LT(absl::Now(), deadline) << "timed out waiting for LDS ACK";
334 response_state = balancer_->ads_service()->lds_response_state();
335 if (response_state.has_value()) break;
336 absl::SleepFor(absl::Seconds(1) * grpc_test_slowdown_factor());
337 }
338 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
339 // Now RPCs should fail with ABORTED status.
340 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::ABORTED, "Fault injected");
341 }
342
TEST_P(LdsRdsInteractionTest,LdsUpdateChangesHcmConfigAndRdsResourceName)343 TEST_P(LdsRdsInteractionTest, LdsUpdateChangesHcmConfigAndRdsResourceName) {
344 CreateAndStartBackends(2);
345 // Bring up client pointing to backend 0 and wait for it to connect.
346 EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
347 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
348 WaitForBackend(DEBUG_LOCATION, 0);
349 // Change the LDS resource to point to an RDS resource. The LDS resource
350 // configures the fault injection filter with a config that fails all RPCs.
351 // However, the RDS resource has a typed_per_filter_config override that
352 // disables the fault injection filter. The RDS resource points to a
353 // new cluster that sends traffic to backend 1.
354 const char* kNewClusterName = "new_cluster_name";
355 const char* kNewEdsResourceName = "new_eds_resource_name";
356 auto cluster = default_cluster_;
357 cluster.set_name(kNewClusterName);
358 cluster.mutable_eds_cluster_config()->set_service_name(kNewEdsResourceName);
359 balancer_->ads_service()->SetCdsResource(cluster);
360 args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
361 balancer_->ads_service()->SetEdsResource(
362 BuildEdsResource(args, kNewEdsResourceName));
363 RouteConfiguration route_config = default_route_config_;
364 route_config.set_name("new_route_config");
365 route_config.mutable_virtual_hosts(0)
366 ->mutable_routes(0)
367 ->mutable_route()
368 ->set_cluster(kNewClusterName);
369 auto* config_map = route_config.mutable_virtual_hosts(0)
370 ->mutable_routes(0)
371 ->mutable_typed_per_filter_config();
372 (*config_map)["envoy.fault"].PackFrom(
373 envoy::extensions::filters::http::fault::v3::HTTPFault());
374 envoy::extensions::filters::http::fault::v3::HTTPFault http_fault;
375 auto* abort_percentage = http_fault.mutable_abort()->mutable_percentage();
376 abort_percentage->set_numerator(100);
377 abort_percentage->set_denominator(abort_percentage->HUNDRED);
378 http_fault.mutable_abort()->set_grpc_status(
379 static_cast<uint32_t>(StatusCode::ABORTED));
380 Listener listener = default_listener_;
381 HttpConnectionManager http_connection_manager =
382 ClientHcmAccessor().Unpack(listener);
383 *http_connection_manager.add_http_filters() =
384 http_connection_manager.http_filters(0);
385 auto* filter = http_connection_manager.mutable_http_filters(0);
386 filter->set_name("envoy.fault");
387 filter->mutable_typed_config()->PackFrom(http_fault);
388 ClientHcmAccessor().Pack(http_connection_manager, &listener);
389 SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
390 route_config);
391 // Wait for traffic to switch to backend 1. There should be no RPC
392 // failures here; if there are, that indicates that the client started
393 // using the new LDS resource before it saw the new RDS resource.
394 WaitForBackend(DEBUG_LOCATION, 1);
395 }
396
397 using LdsRdsTest = XdsEnd2endTest;
398
399 // Test with and without RDS.
400 INSTANTIATE_TEST_SUITE_P(
401 XdsTest, LdsRdsTest,
402 ::testing::Values(XdsTestType(), XdsTestType().set_enable_rds_testing()),
403 &XdsTestType::Name);
404
405 MATCHER_P2(AdjustedClockInRange, t1, t2,
406 absl::StrFormat("time between %s and %s", t1.ToString().c_str(),
407 t2.ToString().c_str())) {
408 gpr_cycle_counter cycle_now = gpr_get_cycle_counter();
409 grpc_core::Timestamp cycle_time =
410 grpc_core::Timestamp::FromCycleCounterRoundDown(cycle_now);
411 grpc_core::Timestamp time_spec =
412 grpc_core::Timestamp::FromTimespecRoundDown(gpr_now(GPR_CLOCK_MONOTONIC));
413 grpc_core::Timestamp now = arg + (time_spec - cycle_time);
414 bool ok = true;
415 ok &= ::testing::ExplainMatchResult(::testing::Ge(t1), now, result_listener);
416 ok &= ::testing::ExplainMatchResult(::testing::Lt(t2), now, result_listener);
417 return ok;
418 }
419
420 // Tests that LDS client ACKs but fails if matching domain can't be found in
421 // the LDS response.
TEST_P(LdsRdsTest,NoMatchedDomain)422 TEST_P(LdsRdsTest, NoMatchedDomain) {
423 RouteConfiguration route_config = default_route_config_;
424 route_config.mutable_virtual_hosts(0)->clear_domains();
425 route_config.mutable_virtual_hosts(0)->add_domains("unmatched_domain");
426 SetRouteConfiguration(balancer_.get(), route_config);
427 CheckRpcSendFailure(
428 DEBUG_LOCATION, StatusCode::UNAVAILABLE,
429 absl::StrCat(
430 (GetParam().enable_rds_testing() ? kDefaultRouteConfigurationName
431 : kServerName),
432 ": UNAVAILABLE: could not find VirtualHost for ", kServerName,
433 " in RouteConfiguration"));
434 // Do a bit of polling, to allow the ACK to get to the ADS server.
435 channel_->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100));
436 auto response_state = RouteConfigurationResponseState(balancer_.get());
437 ASSERT_TRUE(response_state.has_value());
438 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
439 }
440
441 // Tests that LDS client should choose the virtual host with matching domain
442 // if multiple virtual hosts exist in the LDS response.
TEST_P(LdsRdsTest,ChooseMatchedDomain)443 TEST_P(LdsRdsTest, ChooseMatchedDomain) {
444 RouteConfiguration route_config = default_route_config_;
445 *(route_config.add_virtual_hosts()) = route_config.virtual_hosts(0);
446 route_config.mutable_virtual_hosts(0)->clear_domains();
447 route_config.mutable_virtual_hosts(0)->add_domains("unmatched_domain");
448 SetRouteConfiguration(balancer_.get(), route_config);
449 (void)SendRpc();
450 auto response_state = RouteConfigurationResponseState(balancer_.get());
451 ASSERT_TRUE(response_state.has_value());
452 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
453 }
454
455 // Tests that LDS client should choose the last route in the virtual host if
456 // multiple routes exist in the LDS response.
TEST_P(LdsRdsTest,ChooseLastRoute)457 TEST_P(LdsRdsTest, ChooseLastRoute) {
458 RouteConfiguration route_config = default_route_config_;
459 *(route_config.mutable_virtual_hosts(0)->add_routes()) =
460 route_config.virtual_hosts(0).routes(0);
461 route_config.mutable_virtual_hosts(0)
462 ->mutable_routes(0)
463 ->mutable_route()
464 ->mutable_cluster_header();
465 SetRouteConfiguration(balancer_.get(), route_config);
466 (void)SendRpc();
467 auto response_state = RouteConfigurationResponseState(balancer_.get());
468 ASSERT_TRUE(response_state.has_value());
469 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
470 }
471
TEST_P(LdsRdsTest,NoMatchingRoute)472 TEST_P(LdsRdsTest, NoMatchingRoute) {
473 EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
474 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
475 RouteConfiguration route_config = default_route_config_;
476 route_config.mutable_virtual_hosts(0)
477 ->mutable_routes(0)
478 ->mutable_match()
479 ->set_prefix("/unknown/method");
480 SetRouteConfiguration(balancer_.get(), route_config);
481 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
482 "No matching route found in xDS route config");
483 // Do a bit of polling, to allow the ACK to get to the ADS server.
484 channel_->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100));
485 auto response_state = RouteConfigurationResponseState(balancer_.get());
486 ASSERT_TRUE(response_state.has_value());
487 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
488 }
489
TEST_P(LdsRdsTest,EmptyRouteList)490 TEST_P(LdsRdsTest, EmptyRouteList) {
491 RouteConfiguration route_config = default_route_config_;
492 route_config.mutable_virtual_hosts(0)->clear_routes();
493 SetRouteConfiguration(balancer_.get(), route_config);
494 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
495 "No matching route found in xDS route config");
496 // Do a bit of polling, to allow the ACK to get to the ADS server.
497 channel_->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100));
498 auto response_state = RouteConfigurationResponseState(balancer_.get());
499 ASSERT_TRUE(response_state.has_value());
500 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
501 }
502
503 // Testing just one example of an invalid resource here.
504 // Unit tests for XdsRouteConfigResourceType have exhaustive tests for all
505 // of the invalid cases.
TEST_P(LdsRdsTest,NacksInvalidRouteConfig)506 TEST_P(LdsRdsTest, NacksInvalidRouteConfig) {
507 RouteConfiguration route_config = default_route_config_;
508 route_config.mutable_virtual_hosts(0)->mutable_routes(0)->clear_match();
509 SetRouteConfiguration(balancer_.get(), route_config);
510 const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
511 ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
512 EXPECT_EQ(
513 response_state->error_message,
514 absl::StrCat(
515 "xDS response validation errors: [resource index 0: ",
516 GetParam().enable_rds_testing()
517 ? "route_config_name: INVALID_ARGUMENT: "
518 "errors validating RouteConfiguration resource: ["
519 "field:"
520 : "server.example.com: INVALID_ARGUMENT: "
521 "errors validating ApiListener: ["
522 "field:api_listener.api_listener.value["
523 "envoy.extensions.filters.network.http_connection_manager.v3"
524 ".HttpConnectionManager].route_config.",
525 "virtual_hosts[0].routes[0].match "
526 "error:field not present]]"));
527 }
528
529 // Tests that LDS client should fail RPCs with UNAVAILABLE status code if the
530 // matching route has an action other than RouteAction.
TEST_P(LdsRdsTest,MatchingRouteHasNoRouteAction)531 TEST_P(LdsRdsTest, MatchingRouteHasNoRouteAction) {
532 EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
533 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
534 RouteConfiguration route_config = default_route_config_;
535 // Set a route with an inappropriate route action
536 auto* vhost = route_config.mutable_virtual_hosts(0);
537 vhost->mutable_routes(0)->mutable_redirect();
538 // Add another route to make sure that the resolver code actually tries to
539 // match to a route instead of using a shorthand logic to error out.
540 auto* route = vhost->add_routes();
541 route->mutable_match()->set_prefix("");
542 route->mutable_route()->set_cluster(kDefaultClusterName);
543 SetRouteConfiguration(balancer_.get(), route_config);
544 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
545 "Matching route has inappropriate action");
546 }
547
548 // Tests that LDS client should choose the default route (with no matching
549 // specified) after unable to find a match with previous routes.
TEST_P(LdsRdsTest,XdsRoutingPathMatching)550 TEST_P(LdsRdsTest, XdsRoutingPathMatching) {
551 CreateAndStartBackends(4);
552 const char* kNewCluster1Name = "new_cluster_1";
553 const char* kNewEdsService1Name = "new_eds_service_name_1";
554 const char* kNewCluster2Name = "new_cluster_2";
555 const char* kNewEdsService2Name = "new_eds_service_name_2";
556 const size_t kNumEcho1Rpcs = 10;
557 const size_t kNumEcho2Rpcs = 20;
558 const size_t kNumEchoRpcs = 30;
559 // Populate new EDS resources.
560 EdsResourceArgs args({
561 {"locality0", CreateEndpointsForBackends(0, 2)},
562 });
563 EdsResourceArgs args1({
564 {"locality0", CreateEndpointsForBackends(2, 3)},
565 });
566 EdsResourceArgs args2({
567 {"locality0", CreateEndpointsForBackends(3, 4)},
568 });
569 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
570 balancer_->ads_service()->SetEdsResource(
571 BuildEdsResource(args1, kNewEdsService1Name));
572 balancer_->ads_service()->SetEdsResource(
573 BuildEdsResource(args2, kNewEdsService2Name));
574 // Populate new CDS resources.
575 Cluster new_cluster1 = default_cluster_;
576 new_cluster1.set_name(kNewCluster1Name);
577 new_cluster1.mutable_eds_cluster_config()->set_service_name(
578 kNewEdsService1Name);
579 balancer_->ads_service()->SetCdsResource(new_cluster1);
580 Cluster new_cluster2 = default_cluster_;
581 new_cluster2.set_name(kNewCluster2Name);
582 new_cluster2.mutable_eds_cluster_config()->set_service_name(
583 kNewEdsService2Name);
584 balancer_->ads_service()->SetCdsResource(new_cluster2);
585 // Populating Route Configurations for LDS.
586 RouteConfiguration new_route_config = default_route_config_;
587 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
588 route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service/Echo1");
589 route1->mutable_route()->set_cluster(kNewCluster1Name);
590 auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
591 route2->mutable_match()->set_path("/grpc.testing.EchoTest2Service/Echo2");
592 route2->mutable_route()->set_cluster(kNewCluster2Name);
593 auto* route3 = new_route_config.mutable_virtual_hosts(0)->add_routes();
594 route3->mutable_match()->set_path("/grpc.testing.EchoTest3Service/Echo3");
595 route3->mutable_route()->set_cluster(kDefaultClusterName);
596 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
597 default_route->mutable_match()->set_prefix("");
598 default_route->mutable_route()->set_cluster(kDefaultClusterName);
599 SetRouteConfiguration(balancer_.get(), new_route_config);
600 WaitForAllBackends(DEBUG_LOCATION, 0, 2, /*check_status=*/nullptr,
601 WaitForBackendOptions(),
602 RpcOptions().set_timeout_ms(5000));
603 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
604 RpcOptions().set_wait_for_ready(true));
605 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
606 RpcOptions()
607 .set_rpc_service(SERVICE_ECHO1)
608 .set_rpc_method(METHOD_ECHO1)
609 .set_wait_for_ready(true));
610 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho2Rpcs,
611 RpcOptions()
612 .set_rpc_service(SERVICE_ECHO2)
613 .set_rpc_method(METHOD_ECHO2)
614 .set_wait_for_ready(true));
615 // Make sure RPCs all go to the correct backend.
616 for (size_t i = 0; i < 2; ++i) {
617 EXPECT_EQ(kNumEchoRpcs / 2,
618 backends_[i]->backend_service()->request_count());
619 EXPECT_EQ(0, backends_[i]->backend_service1()->request_count());
620 EXPECT_EQ(0, backends_[i]->backend_service2()->request_count());
621 }
622 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
623 EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
624 EXPECT_EQ(0, backends_[2]->backend_service2()->request_count());
625 EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
626 EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
627 EXPECT_EQ(kNumEcho2Rpcs, backends_[3]->backend_service2()->request_count());
628 }
629
TEST_P(LdsRdsTest,XdsRoutingPathMatchingCaseInsensitive)630 TEST_P(LdsRdsTest, XdsRoutingPathMatchingCaseInsensitive) {
631 CreateAndStartBackends(4);
632 const char* kNewCluster1Name = "new_cluster_1";
633 const char* kNewEdsService1Name = "new_eds_service_name_1";
634 const char* kNewCluster2Name = "new_cluster_2";
635 const char* kNewEdsService2Name = "new_eds_service_name_2";
636 const size_t kNumEcho1Rpcs = 10;
637 const size_t kNumEchoRpcs = 30;
638 // Populate new EDS resources.
639 EdsResourceArgs args({
640 {"locality0", CreateEndpointsForBackends(0, 1)},
641 });
642 EdsResourceArgs args1({
643 {"locality0", CreateEndpointsForBackends(1, 2)},
644 });
645 EdsResourceArgs args2({
646 {"locality0", CreateEndpointsForBackends(2, 3)},
647 });
648 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
649 balancer_->ads_service()->SetEdsResource(
650 BuildEdsResource(args1, kNewEdsService1Name));
651 balancer_->ads_service()->SetEdsResource(
652 BuildEdsResource(args2, kNewEdsService2Name));
653 // Populate new CDS resources.
654 Cluster new_cluster1 = default_cluster_;
655 new_cluster1.set_name(kNewCluster1Name);
656 new_cluster1.mutable_eds_cluster_config()->set_service_name(
657 kNewEdsService1Name);
658 balancer_->ads_service()->SetCdsResource(new_cluster1);
659 Cluster new_cluster2 = default_cluster_;
660 new_cluster2.set_name(kNewCluster2Name);
661 new_cluster2.mutable_eds_cluster_config()->set_service_name(
662 kNewEdsService2Name);
663 balancer_->ads_service()->SetCdsResource(new_cluster2);
664 // Populating Route Configurations for LDS.
665 RouteConfiguration new_route_config = default_route_config_;
666 // First route will not match, since it's case-sensitive.
667 // Second route will match with same path.
668 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
669 route1->mutable_match()->set_path("/GrPc.TeStInG.EcHoTeSt1SErViCe/EcHo1");
670 route1->mutable_route()->set_cluster(kNewCluster1Name);
671 auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
672 route2->mutable_match()->set_path("/GrPc.TeStInG.EcHoTeSt1SErViCe/EcHo1");
673 route2->mutable_match()->mutable_case_sensitive()->set_value(false);
674 route2->mutable_route()->set_cluster(kNewCluster2Name);
675 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
676 default_route->mutable_match()->set_prefix("");
677 default_route->mutable_route()->set_cluster(kDefaultClusterName);
678 SetRouteConfiguration(balancer_.get(), new_route_config);
679 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
680 RpcOptions().set_wait_for_ready(true));
681 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
682 RpcOptions()
683 .set_rpc_service(SERVICE_ECHO1)
684 .set_rpc_method(METHOD_ECHO1)
685 .set_wait_for_ready(true));
686 // Make sure RPCs all go to the correct backend.
687 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
688 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
689 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
690 EXPECT_EQ(0, backends_[1]->backend_service1()->request_count());
691 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
692 EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
693 }
694
TEST_P(LdsRdsTest,XdsRoutingPrefixMatching)695 TEST_P(LdsRdsTest, XdsRoutingPrefixMatching) {
696 CreateAndStartBackends(4);
697 const char* kNewCluster1Name = "new_cluster_1";
698 const char* kNewEdsService1Name = "new_eds_service_name_1";
699 const char* kNewCluster2Name = "new_cluster_2";
700 const char* kNewEdsService2Name = "new_eds_service_name_2";
701 const size_t kNumEcho1Rpcs = 10;
702 const size_t kNumEcho2Rpcs = 20;
703 const size_t kNumEchoRpcs = 30;
704 // Populate new EDS resources.
705 EdsResourceArgs args({
706 {"locality0", CreateEndpointsForBackends(0, 2)},
707 });
708 EdsResourceArgs args1({
709 {"locality0", CreateEndpointsForBackends(2, 3)},
710 });
711 EdsResourceArgs args2({
712 {"locality0", CreateEndpointsForBackends(3, 4)},
713 });
714 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
715 balancer_->ads_service()->SetEdsResource(
716 BuildEdsResource(args1, kNewEdsService1Name));
717 balancer_->ads_service()->SetEdsResource(
718 BuildEdsResource(args2, kNewEdsService2Name));
719 // Populate new CDS resources.
720 Cluster new_cluster1 = default_cluster_;
721 new_cluster1.set_name(kNewCluster1Name);
722 new_cluster1.mutable_eds_cluster_config()->set_service_name(
723 kNewEdsService1Name);
724 balancer_->ads_service()->SetCdsResource(new_cluster1);
725 Cluster new_cluster2 = default_cluster_;
726 new_cluster2.set_name(kNewCluster2Name);
727 new_cluster2.mutable_eds_cluster_config()->set_service_name(
728 kNewEdsService2Name);
729 balancer_->ads_service()->SetCdsResource(new_cluster2);
730 // Populating Route Configurations for LDS.
731 RouteConfiguration new_route_config = default_route_config_;
732 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
733 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
734 route1->mutable_route()->set_cluster(kNewCluster1Name);
735 auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
736 route2->mutable_match()->set_prefix("/grpc.testing.EchoTest2Service/");
737 route2->mutable_route()->set_cluster(kNewCluster2Name);
738 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
739 default_route->mutable_match()->set_prefix("");
740 default_route->mutable_route()->set_cluster(kDefaultClusterName);
741 SetRouteConfiguration(balancer_.get(), new_route_config);
742 WaitForAllBackends(DEBUG_LOCATION, 0, 2);
743 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
744 RpcOptions().set_wait_for_ready(true));
745 CheckRpcSendOk(
746 DEBUG_LOCATION, kNumEcho1Rpcs,
747 RpcOptions().set_rpc_service(SERVICE_ECHO1).set_wait_for_ready(true));
748 CheckRpcSendOk(
749 DEBUG_LOCATION, kNumEcho2Rpcs,
750 RpcOptions().set_rpc_service(SERVICE_ECHO2).set_wait_for_ready(true));
751 // Make sure RPCs all go to the correct backend.
752 for (size_t i = 0; i < 2; ++i) {
753 EXPECT_EQ(kNumEchoRpcs / 2,
754 backends_[i]->backend_service()->request_count());
755 EXPECT_EQ(0, backends_[i]->backend_service1()->request_count());
756 EXPECT_EQ(0, backends_[i]->backend_service2()->request_count());
757 }
758 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
759 EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
760 EXPECT_EQ(0, backends_[2]->backend_service2()->request_count());
761 EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
762 EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
763 EXPECT_EQ(kNumEcho2Rpcs, backends_[3]->backend_service2()->request_count());
764 }
765
TEST_P(LdsRdsTest,XdsRoutingPrefixMatchingCaseInsensitive)766 TEST_P(LdsRdsTest, XdsRoutingPrefixMatchingCaseInsensitive) {
767 CreateAndStartBackends(3);
768 const char* kNewCluster1Name = "new_cluster_1";
769 const char* kNewEdsService1Name = "new_eds_service_name_1";
770 const char* kNewCluster2Name = "new_cluster_2";
771 const char* kNewEdsService2Name = "new_eds_service_name_2";
772 const size_t kNumEcho1Rpcs = 10;
773 const size_t kNumEchoRpcs = 30;
774 // Populate new EDS resources.
775 EdsResourceArgs args({
776 {"locality0", CreateEndpointsForBackends(0, 1)},
777 });
778 EdsResourceArgs args1({
779 {"locality0", CreateEndpointsForBackends(1, 2)},
780 });
781 EdsResourceArgs args2({
782 {"locality0", CreateEndpointsForBackends(2, 3)},
783 });
784 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
785 balancer_->ads_service()->SetEdsResource(
786 BuildEdsResource(args1, kNewEdsService1Name));
787 balancer_->ads_service()->SetEdsResource(
788 BuildEdsResource(args2, kNewEdsService2Name));
789 // Populate new CDS resources.
790 Cluster new_cluster1 = default_cluster_;
791 new_cluster1.set_name(kNewCluster1Name);
792 new_cluster1.mutable_eds_cluster_config()->set_service_name(
793 kNewEdsService1Name);
794 balancer_->ads_service()->SetCdsResource(new_cluster1);
795 Cluster new_cluster2 = default_cluster_;
796 new_cluster2.set_name(kNewCluster2Name);
797 new_cluster2.mutable_eds_cluster_config()->set_service_name(
798 kNewEdsService2Name);
799 balancer_->ads_service()->SetCdsResource(new_cluster2);
800 // Populating Route Configurations for LDS.
801 RouteConfiguration new_route_config = default_route_config_;
802 // First route will not match, since it's case-sensitive.
803 // Second route will match with same path.
804 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
805 route1->mutable_match()->set_prefix("/GrPc.TeStInG.EcHoTeSt1SErViCe");
806 route1->mutable_route()->set_cluster(kNewCluster1Name);
807 auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
808 route2->mutable_match()->set_prefix("/GrPc.TeStInG.EcHoTeSt1SErViCe");
809 route2->mutable_match()->mutable_case_sensitive()->set_value(false);
810 route2->mutable_route()->set_cluster(kNewCluster2Name);
811 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
812 default_route->mutable_match()->set_prefix("");
813 default_route->mutable_route()->set_cluster(kDefaultClusterName);
814 SetRouteConfiguration(balancer_.get(), new_route_config);
815 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
816 RpcOptions().set_wait_for_ready(true));
817 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
818 RpcOptions()
819 .set_rpc_service(SERVICE_ECHO1)
820 .set_rpc_method(METHOD_ECHO1)
821 .set_wait_for_ready(true));
822 // Make sure RPCs all go to the correct backend.
823 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
824 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
825 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
826 EXPECT_EQ(0, backends_[1]->backend_service1()->request_count());
827 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
828 EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
829 }
830
TEST_P(LdsRdsTest,XdsRoutingPathRegexMatching)831 TEST_P(LdsRdsTest, XdsRoutingPathRegexMatching) {
832 CreateAndStartBackends(4);
833 const char* kNewCluster1Name = "new_cluster_1";
834 const char* kNewEdsService1Name = "new_eds_service_name_1";
835 const char* kNewCluster2Name = "new_cluster_2";
836 const char* kNewEdsService2Name = "new_eds_service_name_2";
837 const size_t kNumEcho1Rpcs = 10;
838 const size_t kNumEcho2Rpcs = 20;
839 const size_t kNumEchoRpcs = 30;
840 // Populate new EDS resources.
841 EdsResourceArgs args({
842 {"locality0", CreateEndpointsForBackends(0, 2)},
843 });
844 EdsResourceArgs args1({
845 {"locality0", CreateEndpointsForBackends(2, 3)},
846 });
847 EdsResourceArgs args2({
848 {"locality0", CreateEndpointsForBackends(3, 4)},
849 });
850 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
851 balancer_->ads_service()->SetEdsResource(
852 BuildEdsResource(args1, kNewEdsService1Name));
853 balancer_->ads_service()->SetEdsResource(
854 BuildEdsResource(args2, kNewEdsService2Name));
855 // Populate new CDS resources.
856 Cluster new_cluster1 = default_cluster_;
857 new_cluster1.set_name(kNewCluster1Name);
858 new_cluster1.mutable_eds_cluster_config()->set_service_name(
859 kNewEdsService1Name);
860 balancer_->ads_service()->SetCdsResource(new_cluster1);
861 Cluster new_cluster2 = default_cluster_;
862 new_cluster2.set_name(kNewCluster2Name);
863 new_cluster2.mutable_eds_cluster_config()->set_service_name(
864 kNewEdsService2Name);
865 balancer_->ads_service()->SetCdsResource(new_cluster2);
866 // Populating Route Configurations for LDS.
867 RouteConfiguration new_route_config = default_route_config_;
868 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
869 // Will match "/grpc.testing.EchoTest1Service/"
870 route1->mutable_match()->mutable_safe_regex()->set_regex(".*1.*");
871 route1->mutable_route()->set_cluster(kNewCluster1Name);
872 auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
873 // Will match "/grpc.testing.EchoTest2Service/"
874 route2->mutable_match()->mutable_safe_regex()->set_regex(".*2.*");
875 route2->mutable_route()->set_cluster(kNewCluster2Name);
876 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
877 default_route->mutable_match()->set_prefix("");
878 default_route->mutable_route()->set_cluster(kDefaultClusterName);
879 SetRouteConfiguration(balancer_.get(), new_route_config);
880 WaitForAllBackends(DEBUG_LOCATION, 0, 2);
881 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
882 RpcOptions().set_wait_for_ready(true));
883 CheckRpcSendOk(
884 DEBUG_LOCATION, kNumEcho1Rpcs,
885 RpcOptions().set_rpc_service(SERVICE_ECHO1).set_wait_for_ready(true));
886 CheckRpcSendOk(
887 DEBUG_LOCATION, kNumEcho2Rpcs,
888 RpcOptions().set_rpc_service(SERVICE_ECHO2).set_wait_for_ready(true));
889 // Make sure RPCs all go to the correct backend.
890 for (size_t i = 0; i < 2; ++i) {
891 EXPECT_EQ(kNumEchoRpcs / 2,
892 backends_[i]->backend_service()->request_count());
893 EXPECT_EQ(0, backends_[i]->backend_service1()->request_count());
894 EXPECT_EQ(0, backends_[i]->backend_service2()->request_count());
895 }
896 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
897 EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
898 EXPECT_EQ(0, backends_[2]->backend_service2()->request_count());
899 EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
900 EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
901 EXPECT_EQ(kNumEcho2Rpcs, backends_[3]->backend_service2()->request_count());
902 }
903
TEST_P(LdsRdsTest,XdsRoutingWeightedCluster)904 TEST_P(LdsRdsTest, XdsRoutingWeightedCluster) {
905 CreateAndStartBackends(3);
906 const char* kNewCluster1Name = "new_cluster_1";
907 const char* kNewEdsService1Name = "new_eds_service_name_1";
908 const char* kNewCluster2Name = "new_cluster_2";
909 const char* kNewEdsService2Name = "new_eds_service_name_2";
910 const char* kNotUsedClusterName = "not_used_cluster";
911 const size_t kNumEchoRpcs = 10; // RPCs that will go to a fixed backend.
912 const size_t kWeight75 = 75;
913 const size_t kWeight25 = 25;
914 const double kErrorTolerance = 0.05;
915 const double kWeight75Percent = static_cast<double>(kWeight75) / 100;
916 const double kWeight25Percent = static_cast<double>(kWeight25) / 100;
917 const size_t kNumEcho1Rpcs =
918 ComputeIdealNumRpcs(kWeight75Percent, kErrorTolerance);
919 // Populate new EDS resources.
920 EdsResourceArgs args({
921 {"locality0", CreateEndpointsForBackends(0, 1)},
922 });
923 EdsResourceArgs args1({
924 {"locality0", CreateEndpointsForBackends(1, 2)},
925 });
926 EdsResourceArgs args2({
927 {"locality0", CreateEndpointsForBackends(2, 3)},
928 });
929 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
930 balancer_->ads_service()->SetEdsResource(
931 BuildEdsResource(args1, kNewEdsService1Name));
932 balancer_->ads_service()->SetEdsResource(
933 BuildEdsResource(args2, kNewEdsService2Name));
934 // Populate new CDS resources.
935 Cluster new_cluster1 = default_cluster_;
936 new_cluster1.set_name(kNewCluster1Name);
937 new_cluster1.mutable_eds_cluster_config()->set_service_name(
938 kNewEdsService1Name);
939 balancer_->ads_service()->SetCdsResource(new_cluster1);
940 Cluster new_cluster2 = default_cluster_;
941 new_cluster2.set_name(kNewCluster2Name);
942 new_cluster2.mutable_eds_cluster_config()->set_service_name(
943 kNewEdsService2Name);
944 balancer_->ads_service()->SetCdsResource(new_cluster2);
945 // Populating Route Configurations for LDS.
946 RouteConfiguration new_route_config = default_route_config_;
947 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
948 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
949 auto* weighted_cluster1 =
950 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
951 weighted_cluster1->set_name(kNewCluster1Name);
952 weighted_cluster1->mutable_weight()->set_value(kWeight75);
953 auto* weighted_cluster2 =
954 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
955 weighted_cluster2->set_name(kNewCluster2Name);
956 weighted_cluster2->mutable_weight()->set_value(kWeight25);
957 // Cluster with weight 0 will not be used.
958 auto* weighted_cluster3 =
959 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
960 weighted_cluster3->set_name(kNotUsedClusterName);
961 weighted_cluster3->mutable_weight()->set_value(0);
962 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
963 default_route->mutable_match()->set_prefix("");
964 default_route->mutable_route()->set_cluster(kDefaultClusterName);
965 SetRouteConfiguration(balancer_.get(), new_route_config);
966 WaitForAllBackends(DEBUG_LOCATION, 0, 1);
967 WaitForAllBackends(DEBUG_LOCATION, 1, 3, /*check_status=*/nullptr,
968 WaitForBackendOptions(),
969 RpcOptions().set_rpc_service(SERVICE_ECHO1));
970 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
971 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
972 RpcOptions().set_rpc_service(SERVICE_ECHO1));
973 // Make sure RPCs all go to the correct backend.
974 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
975 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
976 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
977 const int weight_75_request_count =
978 backends_[1]->backend_service1()->request_count();
979 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
980 const int weight_25_request_count =
981 backends_[2]->backend_service1()->request_count();
982 gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
983 weight_75_request_count, weight_25_request_count);
984 EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEcho1Rpcs,
985 ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
986 EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEcho1Rpcs,
987 ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
988 }
989
TEST_P(LdsRdsTest,XdsRoutingWeightedClusterNoIntegerOverflow)990 TEST_P(LdsRdsTest, XdsRoutingWeightedClusterNoIntegerOverflow) {
991 CreateAndStartBackends(3);
992 const char* kNewCluster1Name = "new_cluster_1";
993 const char* kNewEdsService1Name = "new_eds_service_name_1";
994 const char* kNewCluster2Name = "new_cluster_2";
995 const char* kNewEdsService2Name = "new_eds_service_name_2";
996 const size_t kNumEchoRpcs = 10; // RPCs that will go to a fixed backend.
997 const uint32_t kWeight1 = std::numeric_limits<uint32_t>::max() / 3;
998 const uint32_t kWeight2 = std::numeric_limits<uint32_t>::max() - kWeight1;
999 const double kErrorTolerance = 0.05;
1000 const double kWeight1Percent =
1001 static_cast<double>(kWeight1) / std::numeric_limits<uint32_t>::max();
1002 const double kWeight2Percent =
1003 static_cast<double>(kWeight2) / std::numeric_limits<uint32_t>::max();
1004 const size_t kNumEcho1Rpcs =
1005 ComputeIdealNumRpcs(kWeight2Percent, kErrorTolerance);
1006 // Populate new EDS resources.
1007 EdsResourceArgs args({
1008 {"locality0", CreateEndpointsForBackends(0, 1)},
1009 });
1010 EdsResourceArgs args1({
1011 {"locality0", CreateEndpointsForBackends(1, 2)},
1012 });
1013 EdsResourceArgs args2({
1014 {"locality0", CreateEndpointsForBackends(2, 3)},
1015 });
1016 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1017 balancer_->ads_service()->SetEdsResource(
1018 BuildEdsResource(args1, kNewEdsService1Name));
1019 balancer_->ads_service()->SetEdsResource(
1020 BuildEdsResource(args2, kNewEdsService2Name));
1021 // Populate new CDS resources.
1022 Cluster new_cluster1 = default_cluster_;
1023 new_cluster1.set_name(kNewCluster1Name);
1024 new_cluster1.mutable_eds_cluster_config()->set_service_name(
1025 kNewEdsService1Name);
1026 balancer_->ads_service()->SetCdsResource(new_cluster1);
1027 Cluster new_cluster2 = default_cluster_;
1028 new_cluster2.set_name(kNewCluster2Name);
1029 new_cluster2.mutable_eds_cluster_config()->set_service_name(
1030 kNewEdsService2Name);
1031 balancer_->ads_service()->SetCdsResource(new_cluster2);
1032 // Populating Route Configurations for LDS.
1033 RouteConfiguration new_route_config = default_route_config_;
1034 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1035 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
1036 auto* weighted_cluster1 =
1037 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1038 weighted_cluster1->set_name(kNewCluster1Name);
1039 weighted_cluster1->mutable_weight()->set_value(kWeight1);
1040 auto* weighted_cluster2 =
1041 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1042 weighted_cluster2->set_name(kNewCluster2Name);
1043 weighted_cluster2->mutable_weight()->set_value(kWeight2);
1044 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1045 default_route->mutable_match()->set_prefix("");
1046 default_route->mutable_route()->set_cluster(kDefaultClusterName);
1047 SetRouteConfiguration(balancer_.get(), new_route_config);
1048 WaitForAllBackends(DEBUG_LOCATION, 0, 1);
1049 WaitForAllBackends(DEBUG_LOCATION, 1, 3, /*check_status=*/nullptr,
1050 WaitForBackendOptions(),
1051 RpcOptions().set_rpc_service(SERVICE_ECHO1));
1052 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1053 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
1054 RpcOptions().set_rpc_service(SERVICE_ECHO1));
1055 // Make sure RPCs all go to the correct backend.
1056 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1057 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1058 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1059 const int weight1_request_count =
1060 backends_[1]->backend_service1()->request_count();
1061 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1062 const int weight2_request_count =
1063 backends_[2]->backend_service1()->request_count();
1064 gpr_log(GPR_INFO, "target1 received %d rpcs and target2 received %d rpcs",
1065 weight1_request_count, weight2_request_count);
1066 EXPECT_THAT(static_cast<double>(weight1_request_count) / kNumEcho1Rpcs,
1067 ::testing::DoubleNear(kWeight1Percent, kErrorTolerance));
1068 EXPECT_THAT(static_cast<double>(weight2_request_count) / kNumEcho1Rpcs,
1069 ::testing::DoubleNear(kWeight2Percent, kErrorTolerance));
1070 }
1071
TEST_P(LdsRdsTest,RouteActionWeightedTargetDefaultRoute)1072 TEST_P(LdsRdsTest, RouteActionWeightedTargetDefaultRoute) {
1073 CreateAndStartBackends(3);
1074 const char* kNewCluster1Name = "new_cluster_1";
1075 const char* kNewEdsService1Name = "new_eds_service_name_1";
1076 const char* kNewCluster2Name = "new_cluster_2";
1077 const char* kNewEdsService2Name = "new_eds_service_name_2";
1078 const size_t kWeight75 = 75;
1079 const size_t kWeight25 = 25;
1080 const double kErrorTolerance = 0.05;
1081 const double kWeight75Percent = static_cast<double>(kWeight75) / 100;
1082 const double kWeight25Percent = static_cast<double>(kWeight25) / 100;
1083 const size_t kNumEchoRpcs =
1084 ComputeIdealNumRpcs(kWeight75Percent, kErrorTolerance);
1085 // Populate new EDS resources.
1086 EdsResourceArgs args({
1087 {"locality0", CreateEndpointsForBackends(0, 1)},
1088 });
1089 EdsResourceArgs args1({
1090 {"locality0", CreateEndpointsForBackends(1, 2)},
1091 });
1092 EdsResourceArgs args2({
1093 {"locality0", CreateEndpointsForBackends(2, 3)},
1094 });
1095 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1096 balancer_->ads_service()->SetEdsResource(
1097 BuildEdsResource(args1, kNewEdsService1Name));
1098 balancer_->ads_service()->SetEdsResource(
1099 BuildEdsResource(args2, kNewEdsService2Name));
1100 // Populate new CDS resources.
1101 Cluster new_cluster1 = default_cluster_;
1102 new_cluster1.set_name(kNewCluster1Name);
1103 new_cluster1.mutable_eds_cluster_config()->set_service_name(
1104 kNewEdsService1Name);
1105 balancer_->ads_service()->SetCdsResource(new_cluster1);
1106 Cluster new_cluster2 = default_cluster_;
1107 new_cluster2.set_name(kNewCluster2Name);
1108 new_cluster2.mutable_eds_cluster_config()->set_service_name(
1109 kNewEdsService2Name);
1110 balancer_->ads_service()->SetCdsResource(new_cluster2);
1111 // Populating Route Configurations for LDS.
1112 RouteConfiguration new_route_config = default_route_config_;
1113 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1114 route1->mutable_match()->set_prefix("");
1115 auto* weighted_cluster1 =
1116 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1117 weighted_cluster1->set_name(kNewCluster1Name);
1118 weighted_cluster1->mutable_weight()->set_value(kWeight75);
1119 auto* weighted_cluster2 =
1120 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1121 weighted_cluster2->set_name(kNewCluster2Name);
1122 weighted_cluster2->mutable_weight()->set_value(kWeight25);
1123 SetRouteConfiguration(balancer_.get(), new_route_config);
1124 WaitForAllBackends(DEBUG_LOCATION, 1, 3);
1125 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1126 // Make sure RPCs all go to the correct backend.
1127 EXPECT_EQ(0, backends_[0]->backend_service()->request_count());
1128 const int weight_75_request_count =
1129 backends_[1]->backend_service()->request_count();
1130 const int weight_25_request_count =
1131 backends_[2]->backend_service()->request_count();
1132 gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1133 weight_75_request_count, weight_25_request_count);
1134 EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEchoRpcs,
1135 ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1136 EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEchoRpcs,
1137 ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1138 }
1139
TEST_P(LdsRdsTest,XdsRoutingWeightedClusterUpdateWeights)1140 TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateWeights) {
1141 CreateAndStartBackends(4);
1142 const char* kNewCluster1Name = "new_cluster_1";
1143 const char* kNewEdsService1Name = "new_eds_service_name_1";
1144 const char* kNewCluster2Name = "new_cluster_2";
1145 const char* kNewEdsService2Name = "new_eds_service_name_2";
1146 const char* kNewCluster3Name = "new_cluster_3";
1147 const char* kNewEdsService3Name = "new_eds_service_name_3";
1148 const size_t kNumEchoRpcs = 10;
1149 const size_t kWeight75 = 75;
1150 const size_t kWeight25 = 25;
1151 const size_t kWeight50 = 50;
1152 const double kErrorTolerance = 0.05;
1153 const double kWeight75Percent = static_cast<double>(kWeight75) / 100;
1154 const double kWeight25Percent = static_cast<double>(kWeight25) / 100;
1155 const double kWeight50Percent = static_cast<double>(kWeight50) / 100;
1156 const size_t kNumEcho1Rpcs7525 =
1157 ComputeIdealNumRpcs(kWeight75Percent, kErrorTolerance);
1158 const size_t kNumEcho1Rpcs5050 =
1159 ComputeIdealNumRpcs(kWeight50Percent, kErrorTolerance);
1160 // Populate new EDS resources.
1161 EdsResourceArgs args({
1162 {"locality0", CreateEndpointsForBackends(0, 1)},
1163 });
1164 EdsResourceArgs args1({
1165 {"locality0", CreateEndpointsForBackends(1, 2)},
1166 });
1167 EdsResourceArgs args2({
1168 {"locality0", CreateEndpointsForBackends(2, 3)},
1169 });
1170 EdsResourceArgs args3({
1171 {"locality0", CreateEndpointsForBackends(3, 4)},
1172 });
1173 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1174 balancer_->ads_service()->SetEdsResource(
1175 BuildEdsResource(args1, kNewEdsService1Name));
1176 balancer_->ads_service()->SetEdsResource(
1177 BuildEdsResource(args2, kNewEdsService2Name));
1178 balancer_->ads_service()->SetEdsResource(
1179 BuildEdsResource(args3, kNewEdsService3Name));
1180 // Populate new CDS resources.
1181 Cluster new_cluster1 = default_cluster_;
1182 new_cluster1.set_name(kNewCluster1Name);
1183 new_cluster1.mutable_eds_cluster_config()->set_service_name(
1184 kNewEdsService1Name);
1185 balancer_->ads_service()->SetCdsResource(new_cluster1);
1186 Cluster new_cluster2 = default_cluster_;
1187 new_cluster2.set_name(kNewCluster2Name);
1188 new_cluster2.mutable_eds_cluster_config()->set_service_name(
1189 kNewEdsService2Name);
1190 balancer_->ads_service()->SetCdsResource(new_cluster2);
1191 Cluster new_cluster3 = default_cluster_;
1192 new_cluster3.set_name(kNewCluster3Name);
1193 new_cluster3.mutable_eds_cluster_config()->set_service_name(
1194 kNewEdsService3Name);
1195 balancer_->ads_service()->SetCdsResource(new_cluster3);
1196 // Populating Route Configurations.
1197 RouteConfiguration new_route_config = default_route_config_;
1198 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1199 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
1200 auto* weighted_cluster1 =
1201 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1202 weighted_cluster1->set_name(kNewCluster1Name);
1203 weighted_cluster1->mutable_weight()->set_value(kWeight75);
1204 auto* weighted_cluster2 =
1205 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1206 weighted_cluster2->set_name(kNewCluster2Name);
1207 weighted_cluster2->mutable_weight()->set_value(kWeight25);
1208 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1209 default_route->mutable_match()->set_prefix("");
1210 default_route->mutable_route()->set_cluster(kDefaultClusterName);
1211 SetRouteConfiguration(balancer_.get(), new_route_config);
1212 WaitForAllBackends(DEBUG_LOCATION, 0, 1, /*check_status=*/nullptr,
1213 WaitForBackendOptions(),
1214 RpcOptions().set_timeout_ms(5000));
1215 WaitForAllBackends(
1216 DEBUG_LOCATION, 1, 3, /*check_status=*/nullptr, WaitForBackendOptions(),
1217 RpcOptions().set_rpc_service(SERVICE_ECHO1).set_timeout_ms(5000));
1218 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
1219 RpcOptions().set_timeout_ms(5000));
1220 CheckRpcSendOk(
1221 DEBUG_LOCATION, kNumEcho1Rpcs7525,
1222 RpcOptions().set_rpc_service(SERVICE_ECHO1).set_timeout_ms(5000));
1223 // Make sure RPCs all go to the correct backend.
1224 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1225 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1226 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1227 const int weight_75_request_count =
1228 backends_[1]->backend_service1()->request_count();
1229 EXPECT_EQ(0, backends_[1]->backend_service2()->request_count());
1230 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1231 const int weight_25_request_count =
1232 backends_[2]->backend_service1()->request_count();
1233 EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1234 EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1235 gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1236 weight_75_request_count, weight_25_request_count);
1237 EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEcho1Rpcs7525,
1238 ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1239 EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEcho1Rpcs7525,
1240 ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1241 // Change Route Configurations: same clusters different weights.
1242 weighted_cluster1->mutable_weight()->set_value(kWeight50);
1243 weighted_cluster2->mutable_weight()->set_value(kWeight50);
1244 // Change default route to a new cluster to help to identify when new
1245 // polices are seen by the client.
1246 default_route->mutable_route()->set_cluster(kNewCluster3Name);
1247 SetRouteConfiguration(balancer_.get(), new_route_config);
1248 ResetBackendCounters();
1249 WaitForAllBackends(DEBUG_LOCATION, 3, 4, /*check_status=*/nullptr,
1250 WaitForBackendOptions(),
1251 RpcOptions().set_timeout_ms(5000));
1252 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
1253 RpcOptions().set_timeout_ms(5000));
1254 CheckRpcSendOk(
1255 DEBUG_LOCATION, kNumEcho1Rpcs5050,
1256 RpcOptions().set_rpc_service(SERVICE_ECHO1).set_timeout_ms(5000));
1257 // Make sure RPCs all go to the correct backend.
1258 EXPECT_EQ(0, backends_[0]->backend_service()->request_count());
1259 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1260 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1261 const int weight_50_request_count_1 =
1262 backends_[1]->backend_service1()->request_count();
1263 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1264 const int weight_50_request_count_2 =
1265 backends_[2]->backend_service1()->request_count();
1266 EXPECT_EQ(kNumEchoRpcs, backends_[3]->backend_service()->request_count());
1267 EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1268 EXPECT_THAT(
1269 static_cast<double>(weight_50_request_count_1) / kNumEcho1Rpcs5050,
1270 ::testing::DoubleNear(kWeight50Percent, kErrorTolerance));
1271 EXPECT_THAT(
1272 static_cast<double>(weight_50_request_count_2) / kNumEcho1Rpcs5050,
1273 ::testing::DoubleNear(kWeight50Percent, kErrorTolerance));
1274 }
1275
TEST_P(LdsRdsTest,XdsRoutingWeightedClusterUpdateClusters)1276 TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateClusters) {
1277 CreateAndStartBackends(4);
1278 const char* kNewCluster1Name = "new_cluster_1";
1279 const char* kNewEdsService1Name = "new_eds_service_name_1";
1280 const char* kNewCluster2Name = "new_cluster_2";
1281 const char* kNewEdsService2Name = "new_eds_service_name_2";
1282 const char* kNewCluster3Name = "new_cluster_3";
1283 const char* kNewEdsService3Name = "new_eds_service_name_3";
1284 const size_t kNumEchoRpcs = 10;
1285 const size_t kWeight75 = 75;
1286 const size_t kWeight25 = 25;
1287 const size_t kWeight50 = 50;
1288 const double kErrorTolerance = 0.05;
1289 const double kWeight75Percent = static_cast<double>(kWeight75) / 100;
1290 const double kWeight25Percent = static_cast<double>(kWeight25) / 100;
1291 const double kWeight50Percent = static_cast<double>(kWeight50) / 100;
1292 const size_t kNumEcho1Rpcs7525 =
1293 ComputeIdealNumRpcs(kWeight75Percent, kErrorTolerance);
1294 const size_t kNumEcho1Rpcs5050 =
1295 ComputeIdealNumRpcs(kWeight50Percent, kErrorTolerance);
1296 // Populate new EDS resources.
1297 EdsResourceArgs args({
1298 {"locality0", CreateEndpointsForBackends(0, 1)},
1299 });
1300 EdsResourceArgs args1({
1301 {"locality0", CreateEndpointsForBackends(1, 2)},
1302 });
1303 EdsResourceArgs args2({
1304 {"locality0", CreateEndpointsForBackends(2, 3)},
1305 });
1306 EdsResourceArgs args3({
1307 {"locality0", CreateEndpointsForBackends(3, 4)},
1308 });
1309 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1310 balancer_->ads_service()->SetEdsResource(
1311 BuildEdsResource(args1, kNewEdsService1Name));
1312 balancer_->ads_service()->SetEdsResource(
1313 BuildEdsResource(args2, kNewEdsService2Name));
1314 balancer_->ads_service()->SetEdsResource(
1315 BuildEdsResource(args3, kNewEdsService3Name));
1316 // Populate new CDS resources.
1317 Cluster new_cluster1 = default_cluster_;
1318 new_cluster1.set_name(kNewCluster1Name);
1319 new_cluster1.mutable_eds_cluster_config()->set_service_name(
1320 kNewEdsService1Name);
1321 balancer_->ads_service()->SetCdsResource(new_cluster1);
1322 Cluster new_cluster2 = default_cluster_;
1323 new_cluster2.set_name(kNewCluster2Name);
1324 new_cluster2.mutable_eds_cluster_config()->set_service_name(
1325 kNewEdsService2Name);
1326 balancer_->ads_service()->SetCdsResource(new_cluster2);
1327 Cluster new_cluster3 = default_cluster_;
1328 new_cluster3.set_name(kNewCluster3Name);
1329 new_cluster3.mutable_eds_cluster_config()->set_service_name(
1330 kNewEdsService3Name);
1331 balancer_->ads_service()->SetCdsResource(new_cluster3);
1332 // Populating Route Configurations.
1333 RouteConfiguration new_route_config = default_route_config_;
1334 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1335 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
1336 auto* weighted_cluster1 =
1337 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1338 weighted_cluster1->set_name(kNewCluster1Name);
1339 weighted_cluster1->mutable_weight()->set_value(kWeight75);
1340 auto* weighted_cluster2 =
1341 route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1342 weighted_cluster2->set_name(kDefaultClusterName);
1343 weighted_cluster2->mutable_weight()->set_value(kWeight25);
1344 auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1345 default_route->mutable_match()->set_prefix("");
1346 default_route->mutable_route()->set_cluster(kDefaultClusterName);
1347 SetRouteConfiguration(balancer_.get(), new_route_config);
1348 WaitForBackend(DEBUG_LOCATION, 0);
1349 WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
1350 WaitForBackendOptions(),
1351 RpcOptions().set_rpc_service(SERVICE_ECHO1));
1352 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1353 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs7525,
1354 RpcOptions().set_rpc_service(SERVICE_ECHO1));
1355 // Make sure RPCs all go to the correct backend.
1356 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1357 int weight_25_request_count =
1358 backends_[0]->backend_service1()->request_count();
1359 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1360 int weight_75_request_count =
1361 backends_[1]->backend_service1()->request_count();
1362 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1363 EXPECT_EQ(0, backends_[2]->backend_service1()->request_count());
1364 EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1365 EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1366 gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1367 weight_75_request_count, weight_25_request_count);
1368 EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEcho1Rpcs7525,
1369 ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1370 EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEcho1Rpcs7525,
1371 ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1372 // Change Route Configurations: new set of clusters with different weights.
1373 weighted_cluster1->mutable_weight()->set_value(kWeight50);
1374 weighted_cluster2->set_name(kNewCluster2Name);
1375 weighted_cluster2->mutable_weight()->set_value(kWeight50);
1376 SetRouteConfiguration(balancer_.get(), new_route_config);
1377 ResetBackendCounters();
1378 WaitForBackend(DEBUG_LOCATION, 2, /*check_status=*/nullptr,
1379 WaitForBackendOptions(),
1380 RpcOptions().set_rpc_service(SERVICE_ECHO1));
1381 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1382 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs5050,
1383 RpcOptions().set_rpc_service(SERVICE_ECHO1));
1384 // Make sure RPCs all go to the correct backend.
1385 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1386 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1387 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1388 const int weight_50_request_count_1 =
1389 backends_[1]->backend_service1()->request_count();
1390 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1391 const int weight_50_request_count_2 =
1392 backends_[2]->backend_service1()->request_count();
1393 EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1394 EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1395 EXPECT_THAT(
1396 static_cast<double>(weight_50_request_count_1) / kNumEcho1Rpcs5050,
1397 ::testing::DoubleNear(kWeight50Percent, kErrorTolerance));
1398 EXPECT_THAT(
1399 static_cast<double>(weight_50_request_count_2) / kNumEcho1Rpcs5050,
1400 ::testing::DoubleNear(kWeight50Percent, kErrorTolerance));
1401 // Change Route Configurations.
1402 weighted_cluster1->mutable_weight()->set_value(kWeight75);
1403 weighted_cluster2->set_name(kNewCluster3Name);
1404 weighted_cluster2->mutable_weight()->set_value(kWeight25);
1405 SetRouteConfiguration(balancer_.get(), new_route_config);
1406 ResetBackendCounters();
1407 WaitForBackend(DEBUG_LOCATION, 3, /*check_status=*/nullptr,
1408 WaitForBackendOptions(),
1409 RpcOptions().set_rpc_service(SERVICE_ECHO1));
1410 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1411 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs7525,
1412 RpcOptions().set_rpc_service(SERVICE_ECHO1));
1413 // Make sure RPCs all go to the correct backend.
1414 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1415 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1416 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1417 weight_75_request_count = backends_[1]->backend_service1()->request_count();
1418 EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1419 EXPECT_EQ(0, backends_[2]->backend_service1()->request_count());
1420 EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1421 weight_25_request_count = backends_[3]->backend_service1()->request_count();
1422 gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1423 weight_75_request_count, weight_25_request_count);
1424 EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEcho1Rpcs7525,
1425 ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1426 EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEcho1Rpcs7525,
1427 ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1428 }
1429
TEST_P(LdsRdsTest,XdsRoutingClusterUpdateClusters)1430 TEST_P(LdsRdsTest, XdsRoutingClusterUpdateClusters) {
1431 CreateAndStartBackends(2);
1432 const char* kNewClusterName = "new_cluster";
1433 const char* kNewEdsServiceName = "new_eds_service_name";
1434 const size_t kNumEchoRpcs = 5;
1435 // Populate new EDS resources.
1436 EdsResourceArgs args({
1437 {"locality0", CreateEndpointsForBackends(0, 1)},
1438 });
1439 EdsResourceArgs args1({
1440 {"locality0", CreateEndpointsForBackends(1, 2)},
1441 });
1442 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1443 balancer_->ads_service()->SetEdsResource(
1444 BuildEdsResource(args1, kNewEdsServiceName));
1445 // Populate new CDS resources.
1446 Cluster new_cluster = default_cluster_;
1447 new_cluster.set_name(kNewClusterName);
1448 new_cluster.mutable_eds_cluster_config()->set_service_name(
1449 kNewEdsServiceName);
1450 balancer_->ads_service()->SetCdsResource(new_cluster);
1451 // Send Route Configuration.
1452 RouteConfiguration new_route_config = default_route_config_;
1453 SetRouteConfiguration(balancer_.get(), new_route_config);
1454 WaitForAllBackends(DEBUG_LOCATION, 0, 1);
1455 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1456 // Make sure RPCs all go to the correct backend.
1457 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1458 // Change Route Configurations: new default cluster.
1459 auto* default_route =
1460 new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1461 default_route->mutable_route()->set_cluster(kNewClusterName);
1462 SetRouteConfiguration(balancer_.get(), new_route_config);
1463 WaitForAllBackends(DEBUG_LOCATION, 1, 2);
1464 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1465 // Make sure RPCs all go to the correct backend.
1466 EXPECT_EQ(kNumEchoRpcs, backends_[1]->backend_service()->request_count());
1467 }
1468
TEST_P(LdsRdsTest,XdsRoutingClusterUpdateClustersWithPickingDelays)1469 TEST_P(LdsRdsTest, XdsRoutingClusterUpdateClustersWithPickingDelays) {
1470 // Start with only backend 1 up, but the default cluster pointing to
1471 // backend 0, which is down.
1472 CreateBackends(2);
1473 StartBackend(1);
1474 EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
1475 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1476 // Start an RPC with wait_for_ready=true and no deadline. This will
1477 // stay pending until backend 0 is reachable.
1478 LongRunningRpc rpc;
1479 rpc.StartRpc(stub_.get(),
1480 RpcOptions().set_wait_for_ready(true).set_timeout_ms(0));
1481 // Send a non-wait_for_ready RPC, which should fail. This tells us
1482 // that the client has received the update and attempted to connect.
1483 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
1484 MakeConnectionFailureRegex(
1485 "connections to all backends failing; last error: "));
1486 // Now create a new cluster, pointing to backend 1.
1487 const char* kNewClusterName = "new_cluster";
1488 const char* kNewEdsServiceName = "new_eds_service_name";
1489 EdsResourceArgs args1({{"locality0", CreateEndpointsForBackends(1, 2)}});
1490 balancer_->ads_service()->SetEdsResource(
1491 BuildEdsResource(args1, kNewEdsServiceName));
1492 // Populate new CDS resources.
1493 Cluster new_cluster = default_cluster_;
1494 new_cluster.set_name(kNewClusterName);
1495 new_cluster.mutable_eds_cluster_config()->set_service_name(
1496 kNewEdsServiceName);
1497 balancer_->ads_service()->SetCdsResource(new_cluster);
1498 // Send a update RouteConfiguration to use backend 1.
1499 RouteConfiguration new_route_config = default_route_config_;
1500 auto* default_route =
1501 new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1502 default_route->mutable_route()->set_cluster(kNewClusterName);
1503 SetRouteConfiguration(balancer_.get(), new_route_config);
1504 // Wait for RPCs to go to the new backend: 1, this ensures that the client
1505 // has processed the update.
1506 WaitForBackend(
1507 DEBUG_LOCATION, 1,
1508 [&](const RpcResult& result) {
1509 if (!result.status.ok()) {
1510 EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
1511 EXPECT_THAT(
1512 result.status.error_message(),
1513 ::testing::MatchesRegex(MakeConnectionFailureRegex(
1514 "connections to all backends failing; last error: ")));
1515 }
1516 },
1517 WaitForBackendOptions().set_reset_counters(false));
1518 // Bring up the backend 0. Yhis will allow the delayed RPC to finally
1519 // complete.
1520 StartBackend(0);
1521 Status status = rpc.GetStatus();
1522 EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
1523 << " message=" << status.error_message();
1524 // Make sure RPCs went to the correct backends.
1525 EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
1526 EXPECT_EQ(1, backends_[1]->backend_service()->request_count());
1527 }
1528
TEST_P(LdsRdsTest,XdsRoutingApplyXdsTimeout)1529 TEST_P(LdsRdsTest, XdsRoutingApplyXdsTimeout) {
1530 const auto kTimeoutGrpcHeaderMax = grpc_core::Duration::Milliseconds(1500);
1531 const auto kTimeoutMaxStreamDuration =
1532 grpc_core::Duration::Milliseconds(2500);
1533 const auto kTimeoutHttpMaxStreamDuration =
1534 grpc_core::Duration::Milliseconds(3500);
1535 const auto kTimeoutApplication = grpc_core::Duration::Milliseconds(4500);
1536 const char* kNewCluster1Name = "new_cluster_1";
1537 const char* kNewEdsService1Name = "new_eds_service_name_1";
1538 const char* kNewCluster2Name = "new_cluster_2";
1539 const char* kNewEdsService2Name = "new_eds_service_name_2";
1540 const char* kNewCluster3Name = "new_cluster_3";
1541 const char* kNewEdsService3Name = "new_eds_service_name_3";
1542 // Populate new EDS resources.
1543 EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
1544 EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}});
1545 EdsResourceArgs args2({{"locality0", {MakeNonExistantEndpoint()}}});
1546 EdsResourceArgs args3({{"locality0", {MakeNonExistantEndpoint()}}});
1547 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1548 balancer_->ads_service()->SetEdsResource(
1549 BuildEdsResource(args1, kNewEdsService1Name));
1550 balancer_->ads_service()->SetEdsResource(
1551 BuildEdsResource(args2, kNewEdsService2Name));
1552 balancer_->ads_service()->SetEdsResource(
1553 BuildEdsResource(args3, kNewEdsService3Name));
1554 // Populate new CDS resources.
1555 Cluster new_cluster1 = default_cluster_;
1556 new_cluster1.set_name(kNewCluster1Name);
1557 new_cluster1.mutable_eds_cluster_config()->set_service_name(
1558 kNewEdsService1Name);
1559 balancer_->ads_service()->SetCdsResource(new_cluster1);
1560 Cluster new_cluster2 = default_cluster_;
1561 new_cluster2.set_name(kNewCluster2Name);
1562 new_cluster2.mutable_eds_cluster_config()->set_service_name(
1563 kNewEdsService2Name);
1564 balancer_->ads_service()->SetCdsResource(new_cluster2);
1565 Cluster new_cluster3 = default_cluster_;
1566 new_cluster3.set_name(kNewCluster3Name);
1567 new_cluster3.mutable_eds_cluster_config()->set_service_name(
1568 kNewEdsService3Name);
1569 balancer_->ads_service()->SetCdsResource(new_cluster3);
1570 // Construct listener.
1571 auto listener = default_listener_;
1572 HttpConnectionManager http_connection_manager;
1573 listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
1574 &http_connection_manager);
1575 // Set up HTTP max_stream_duration of 3.5 seconds
1576 SetProtoDuration(
1577 kTimeoutHttpMaxStreamDuration,
1578 http_connection_manager.mutable_common_http_protocol_options()
1579 ->mutable_max_stream_duration());
1580 listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
1581 http_connection_manager);
1582 // Construct route config.
1583 RouteConfiguration new_route_config = default_route_config_;
1584 // route 1: Set max_stream_duration of 2.5 seconds, Set
1585 // grpc_timeout_header_max of 1.5
1586 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1587 route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service/Echo1");
1588 route1->mutable_route()->set_cluster(kNewCluster1Name);
1589 auto* max_stream_duration =
1590 route1->mutable_route()->mutable_max_stream_duration();
1591 SetProtoDuration(kTimeoutMaxStreamDuration,
1592 max_stream_duration->mutable_max_stream_duration());
1593 SetProtoDuration(kTimeoutGrpcHeaderMax,
1594 max_stream_duration->mutable_grpc_timeout_header_max());
1595 // route 2: Set max_stream_duration of 2.5 seconds
1596 auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1597 route2->mutable_match()->set_path("/grpc.testing.EchoTest2Service/Echo2");
1598 route2->mutable_route()->set_cluster(kNewCluster2Name);
1599 max_stream_duration = route2->mutable_route()->mutable_max_stream_duration();
1600 SetProtoDuration(kTimeoutMaxStreamDuration,
1601 max_stream_duration->mutable_max_stream_duration());
1602 // route 3: No timeout values in route configuration
1603 auto* route3 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1604 route3->mutable_match()->set_path("/grpc.testing.EchoTestService/Echo");
1605 route3->mutable_route()->set_cluster(kNewCluster3Name);
1606 // Set listener and route config.
1607 SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
1608 new_route_config);
1609 // Test grpc_timeout_header_max of 1.5 seconds applied
1610 grpc_core::Timestamp t0 = NowFromCycleCounter();
1611 grpc_core::Timestamp t1 =
1612 t0 + (kTimeoutGrpcHeaderMax * grpc_test_slowdown_factor());
1613 grpc_core::Timestamp t2 =
1614 t0 + (kTimeoutMaxStreamDuration * grpc_test_slowdown_factor());
1615 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED,
1616 "Deadline Exceeded",
1617 RpcOptions()
1618 .set_rpc_service(SERVICE_ECHO1)
1619 .set_rpc_method(METHOD_ECHO1)
1620 .set_wait_for_ready(true)
1621 .set_timeout(kTimeoutApplication));
1622 EXPECT_THAT(NowFromCycleCounter(), AdjustedClockInRange(t1, t2));
1623 // Test max_stream_duration of 2.5 seconds applied
1624 t0 = NowFromCycleCounter();
1625 t1 = t0 + (kTimeoutMaxStreamDuration * grpc_test_slowdown_factor());
1626 t2 = t0 + (kTimeoutHttpMaxStreamDuration * grpc_test_slowdown_factor());
1627 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED,
1628 "Deadline Exceeded",
1629 RpcOptions()
1630 .set_rpc_service(SERVICE_ECHO2)
1631 .set_rpc_method(METHOD_ECHO2)
1632 .set_wait_for_ready(true)
1633 .set_timeout(kTimeoutApplication));
1634 EXPECT_THAT(NowFromCycleCounter(), AdjustedClockInRange(t1, t2));
1635 // Test http_stream_duration of 3.5 seconds applied
1636 t0 = NowFromCycleCounter();
1637 t1 = t0 + (kTimeoutHttpMaxStreamDuration * grpc_test_slowdown_factor());
1638 t2 = t0 + (kTimeoutApplication * grpc_test_slowdown_factor());
1639 CheckRpcSendFailure(
1640 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
1641 RpcOptions().set_wait_for_ready(true).set_timeout(kTimeoutApplication));
1642 EXPECT_THAT(NowFromCycleCounter(), AdjustedClockInRange(t1, t2));
1643 }
1644
TEST_P(LdsRdsTest,XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit)1645 TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit) {
1646 const auto kTimeoutMaxStreamDuration =
1647 grpc_core::Duration::Milliseconds(2500);
1648 const auto kTimeoutHttpMaxStreamDuration =
1649 grpc_core::Duration::Milliseconds(3500);
1650 const auto kTimeoutApplication = grpc_core::Duration::Milliseconds(4500);
1651 const char* kNewCluster1Name = "new_cluster_1";
1652 const char* kNewEdsService1Name = "new_eds_service_name_1";
1653 const char* kNewCluster2Name = "new_cluster_2";
1654 const char* kNewEdsService2Name = "new_eds_service_name_2";
1655 // Populate new EDS resources.
1656 EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
1657 EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}});
1658 EdsResourceArgs args2({{"locality0", {MakeNonExistantEndpoint()}}});
1659 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1660 balancer_->ads_service()->SetEdsResource(
1661 BuildEdsResource(args1, kNewEdsService1Name));
1662 balancer_->ads_service()->SetEdsResource(
1663 BuildEdsResource(args2, kNewEdsService2Name));
1664 // Populate new CDS resources.
1665 Cluster new_cluster1 = default_cluster_;
1666 new_cluster1.set_name(kNewCluster1Name);
1667 new_cluster1.mutable_eds_cluster_config()->set_service_name(
1668 kNewEdsService1Name);
1669 balancer_->ads_service()->SetCdsResource(new_cluster1);
1670 Cluster new_cluster2 = default_cluster_;
1671 new_cluster2.set_name(kNewCluster2Name);
1672 new_cluster2.mutable_eds_cluster_config()->set_service_name(
1673 kNewEdsService2Name);
1674 balancer_->ads_service()->SetCdsResource(new_cluster2);
1675 // Construct listener.
1676 auto listener = default_listener_;
1677 HttpConnectionManager http_connection_manager;
1678 listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
1679 &http_connection_manager);
1680 // Set up HTTP max_stream_duration of 3.5 seconds
1681 SetProtoDuration(
1682 kTimeoutHttpMaxStreamDuration,
1683 http_connection_manager.mutable_common_http_protocol_options()
1684 ->mutable_max_stream_duration());
1685 listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
1686 http_connection_manager);
1687 // Construct route config.
1688 RouteConfiguration new_route_config = default_route_config_;
1689 // route 1: Set max_stream_duration of 2.5 seconds, Set
1690 // grpc_timeout_header_max of 0
1691 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1692 route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service/Echo1");
1693 route1->mutable_route()->set_cluster(kNewCluster1Name);
1694 auto* max_stream_duration =
1695 route1->mutable_route()->mutable_max_stream_duration();
1696 SetProtoDuration(kTimeoutMaxStreamDuration,
1697 max_stream_duration->mutable_max_stream_duration());
1698 SetProtoDuration(grpc_core::Duration::Zero(),
1699 max_stream_duration->mutable_grpc_timeout_header_max());
1700 // route 2: Set max_stream_duration to 0
1701 auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1702 route2->mutable_match()->set_path("/grpc.testing.EchoTest2Service/Echo2");
1703 route2->mutable_route()->set_cluster(kNewCluster2Name);
1704 max_stream_duration = route2->mutable_route()->mutable_max_stream_duration();
1705 SetProtoDuration(grpc_core::Duration::Zero(),
1706 max_stream_duration->mutable_max_stream_duration());
1707 // Set listener and route config.
1708 SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
1709 new_route_config);
1710 // Test application timeout is applied for route 1
1711 auto t0 = system_clock::now();
1712 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED,
1713 "Deadline Exceeded",
1714 RpcOptions()
1715 .set_rpc_service(SERVICE_ECHO1)
1716 .set_rpc_method(METHOD_ECHO1)
1717 .set_wait_for_ready(true)
1718 .set_timeout(kTimeoutApplication));
1719 auto elapsed_nano_seconds =
1720 std::chrono::duration_cast<std::chrono::nanoseconds>(system_clock::now() -
1721 t0);
1722 EXPECT_GT(
1723 elapsed_nano_seconds.count(),
1724 (kTimeoutApplication * grpc_test_slowdown_factor()).millis() * 1000);
1725 // Test application timeout is applied for route 2
1726 t0 = system_clock::now();
1727 CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED,
1728 "Deadline Exceeded",
1729 RpcOptions()
1730 .set_rpc_service(SERVICE_ECHO2)
1731 .set_rpc_method(METHOD_ECHO2)
1732 .set_wait_for_ready(true)
1733 .set_timeout(kTimeoutApplication));
1734 elapsed_nano_seconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
1735 system_clock::now() - t0);
1736 EXPECT_GT(
1737 elapsed_nano_seconds.count(),
1738 (kTimeoutApplication * grpc_test_slowdown_factor()).millis() * 1000);
1739 }
1740
TEST_P(LdsRdsTest,XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit)1741 TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit) {
1742 const auto kTimeoutApplication = grpc_core::Duration::Milliseconds(4500);
1743 // Populate new EDS resources.
1744 EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
1745 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1746 auto listener = default_listener_;
1747 HttpConnectionManager http_connection_manager;
1748 listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
1749 &http_connection_manager);
1750 // Set up HTTP max_stream_duration to be explicit 0
1751 auto* duration =
1752 http_connection_manager.mutable_common_http_protocol_options()
1753 ->mutable_max_stream_duration();
1754 duration->set_seconds(0);
1755 duration->set_nanos(0);
1756 listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
1757 http_connection_manager);
1758 // Set listener and route config.
1759 SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
1760 default_route_config_);
1761 // Test application timeout is applied for route 1
1762 auto t0 = system_clock::now();
1763 CheckRpcSendFailure(
1764 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
1765 RpcOptions().set_wait_for_ready(true).set_timeout(kTimeoutApplication));
1766 auto elapsed_nano_seconds =
1767 std::chrono::duration_cast<std::chrono::nanoseconds>(system_clock::now() -
1768 t0);
1769 EXPECT_GT(
1770 elapsed_nano_seconds.count(),
1771 (kTimeoutApplication * grpc_test_slowdown_factor()).millis() * 1000);
1772 }
1773
1774 // Test to ensure application-specified deadline won't be affected when
1775 // the xDS config does not specify a timeout.
TEST_P(LdsRdsTest,XdsRoutingWithOnlyApplicationTimeout)1776 TEST_P(LdsRdsTest, XdsRoutingWithOnlyApplicationTimeout) {
1777 const auto kTimeoutApplication = grpc_core::Duration::Milliseconds(4500);
1778 // Populate new EDS resources.
1779 EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
1780 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1781 auto t0 = system_clock::now();
1782 CheckRpcSendFailure(
1783 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
1784 RpcOptions().set_wait_for_ready(true).set_timeout(kTimeoutApplication));
1785 auto elapsed_nano_seconds =
1786 std::chrono::duration_cast<std::chrono::nanoseconds>(system_clock::now() -
1787 t0);
1788 EXPECT_GT(
1789 elapsed_nano_seconds.count(),
1790 (kTimeoutApplication * grpc_test_slowdown_factor()).millis() * 1000);
1791 }
1792
TEST_P(LdsRdsTest,XdsRetryPolicyNumRetries)1793 TEST_P(LdsRdsTest, XdsRetryPolicyNumRetries) {
1794 CreateAndStartBackends(1);
1795 const size_t kNumRetries = 3;
1796 // Populate new EDS resources.
1797 EdsResourceArgs args({
1798 {"locality0", CreateEndpointsForBackends(0, 1)},
1799 });
1800 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1801 // Construct route config to set retry policy.
1802 RouteConfiguration new_route_config = default_route_config_;
1803 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1804 auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
1805 retry_policy->set_retry_on(
1806 "5xx,cancelled,deadline-exceeded,internal,resource-exhausted,"
1807 "unavailable");
1808 retry_policy->mutable_num_retries()->set_value(kNumRetries);
1809 SetRouteConfiguration(balancer_.get(), new_route_config);
1810 // Ensure we retried the correct number of times on all supported status.
1811 CheckRpcSendFailure(
1812 DEBUG_LOCATION, StatusCode::CANCELLED, "",
1813 RpcOptions().set_server_expected_error(StatusCode::CANCELLED));
1814 EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
1815 ResetBackendCounters();
1816 CheckRpcSendFailure(
1817 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "",
1818 RpcOptions().set_server_expected_error(StatusCode::DEADLINE_EXCEEDED));
1819 EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
1820 ResetBackendCounters();
1821 CheckRpcSendFailure(
1822 DEBUG_LOCATION, StatusCode::INTERNAL, "",
1823 RpcOptions().set_server_expected_error(StatusCode::INTERNAL));
1824 EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
1825 ResetBackendCounters();
1826 CheckRpcSendFailure(
1827 DEBUG_LOCATION, StatusCode::RESOURCE_EXHAUSTED, "",
1828 RpcOptions().set_server_expected_error(StatusCode::RESOURCE_EXHAUSTED));
1829 EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
1830 ResetBackendCounters();
1831 CheckRpcSendFailure(
1832 DEBUG_LOCATION, StatusCode::UNAVAILABLE, "",
1833 RpcOptions().set_server_expected_error(StatusCode::UNAVAILABLE));
1834 EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
1835 ResetBackendCounters();
1836 // Ensure we don't retry on an unsupported status.
1837 CheckRpcSendFailure(
1838 DEBUG_LOCATION, StatusCode::UNAUTHENTICATED, "",
1839 RpcOptions().set_server_expected_error(StatusCode::UNAUTHENTICATED));
1840 EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
1841 }
1842
TEST_P(LdsRdsTest,XdsRetryPolicyAtVirtualHostLevel)1843 TEST_P(LdsRdsTest, XdsRetryPolicyAtVirtualHostLevel) {
1844 CreateAndStartBackends(1);
1845 const size_t kNumRetries = 3;
1846 // Populate new EDS resources.
1847 EdsResourceArgs args({
1848 {"locality0", CreateEndpointsForBackends(0, 1)},
1849 });
1850 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1851 // Construct route config to set retry policy.
1852 RouteConfiguration new_route_config = default_route_config_;
1853 auto* retry_policy =
1854 new_route_config.mutable_virtual_hosts(0)->mutable_retry_policy();
1855 retry_policy->set_retry_on(
1856 "cancelled,deadline-exceeded,internal,resource-exhausted,unavailable");
1857 retry_policy->mutable_num_retries()->set_value(kNumRetries);
1858 SetRouteConfiguration(balancer_.get(), new_route_config);
1859 // Ensure we retried the correct number of times on a supported status.
1860 CheckRpcSendFailure(
1861 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "",
1862 RpcOptions().set_server_expected_error(StatusCode::DEADLINE_EXCEEDED));
1863 EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
1864 }
1865
TEST_P(LdsRdsTest,XdsRetryPolicyLongBackOff)1866 TEST_P(LdsRdsTest, XdsRetryPolicyLongBackOff) {
1867 CreateAndStartBackends(1);
1868 // Set num retries to 3, but due to longer back off, we expect only 1 retry
1869 // will take place.
1870 const size_t kNumRetries = 3;
1871 // Populate new EDS resources.
1872 EdsResourceArgs args({
1873 {"locality0", CreateEndpointsForBackends(0, 1)},
1874 });
1875 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1876 // Construct route config to set retry policy.
1877 RouteConfiguration new_route_config = default_route_config_;
1878 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1879 auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
1880 retry_policy->set_retry_on(
1881 "5xx,cancelled,deadline-exceeded,internal,resource-exhausted,"
1882 "unavailable");
1883 retry_policy->mutable_num_retries()->set_value(kNumRetries);
1884 // Set backoff to 1 second, 1/2 of rpc timeout of 2 second.
1885 SetProtoDuration(
1886 grpc_core::Duration::Seconds(1),
1887 retry_policy->mutable_retry_back_off()->mutable_base_interval());
1888 SetRouteConfiguration(balancer_.get(), new_route_config);
1889 // No need to set max interval and just let it be the default of 10x of base.
1890 // We expect 1 retry before the RPC times out with DEADLINE_EXCEEDED.
1891 CheckRpcSendFailure(
1892 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
1893 RpcOptions().set_timeout_ms(2500).set_server_expected_error(
1894 StatusCode::CANCELLED));
1895 EXPECT_EQ(1 + 1, backends_[0]->backend_service()->request_count());
1896 }
1897
TEST_P(LdsRdsTest,XdsRetryPolicyMaxBackOff)1898 TEST_P(LdsRdsTest, XdsRetryPolicyMaxBackOff) {
1899 CreateAndStartBackends(1);
1900 // Set num retries to 3, but due to longer back off, we expect only 2 retry
1901 // will take place, while the 2nd one will obey the max backoff.
1902 const size_t kNumRetries = 3;
1903 // Populate new EDS resources.
1904 EdsResourceArgs args({
1905 {"locality0", CreateEndpointsForBackends(0, 1)},
1906 });
1907 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1908 // Construct route config to set retry policy.
1909 RouteConfiguration new_route_config = default_route_config_;
1910 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1911 auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
1912 retry_policy->set_retry_on(
1913 "5xx,cancelled,deadline-exceeded,internal,resource-exhausted,"
1914 "unavailable");
1915 retry_policy->mutable_num_retries()->set_value(kNumRetries);
1916 // Set backoff to 1 second.
1917 SetProtoDuration(
1918 grpc_core::Duration::Seconds(1),
1919 retry_policy->mutable_retry_back_off()->mutable_base_interval());
1920 // Set max interval to be the same as base, so 2 retries will take 2 seconds
1921 // and both retries will take place before the 2.5 seconds rpc timeout.
1922 // Tested to ensure if max is not set, this test will be the same as
1923 // XdsRetryPolicyLongBackOff and we will only see 1 retry in that case.
1924 SetProtoDuration(
1925 grpc_core::Duration::Seconds(1),
1926 retry_policy->mutable_retry_back_off()->mutable_max_interval());
1927 SetRouteConfiguration(balancer_.get(), new_route_config);
1928 // Send an initial RPC to make sure we get connected (we don't want
1929 // the channel startup time to affect the retry timing).
1930 CheckRpcSendOk(DEBUG_LOCATION);
1931 ResetBackendCounters();
1932 // We expect 2 retry before the RPC times out with DEADLINE_EXCEEDED.
1933 CheckRpcSendFailure(
1934 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
1935 RpcOptions().set_timeout_ms(2500).set_server_expected_error(
1936 StatusCode::CANCELLED));
1937 EXPECT_EQ(2 + 1, backends_[0]->backend_service()->request_count());
1938 }
1939
TEST_P(LdsRdsTest,XdsRetryPolicyUnsupportedStatusCode)1940 TEST_P(LdsRdsTest, XdsRetryPolicyUnsupportedStatusCode) {
1941 CreateAndStartBackends(1);
1942 const size_t kNumRetries = 3;
1943 // Populate new EDS resources.
1944 EdsResourceArgs args({
1945 {"locality0", CreateEndpointsForBackends(0, 1)},
1946 });
1947 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1948 // Construct route config to set retry policy.
1949 RouteConfiguration new_route_config = default_route_config_;
1950 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1951 auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
1952 retry_policy->set_retry_on("5xx");
1953 retry_policy->mutable_num_retries()->set_value(kNumRetries);
1954 SetRouteConfiguration(balancer_.get(), new_route_config);
1955 // We expect no retry.
1956 CheckRpcSendFailure(
1957 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "",
1958 RpcOptions().set_server_expected_error(StatusCode::DEADLINE_EXCEEDED));
1959 EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
1960 }
1961
TEST_P(LdsRdsTest,XdsRetryPolicyUnsupportedStatusCodeWithVirtualHostLevelRetry)1962 TEST_P(LdsRdsTest,
1963 XdsRetryPolicyUnsupportedStatusCodeWithVirtualHostLevelRetry) {
1964 CreateAndStartBackends(1);
1965 const size_t kNumRetries = 3;
1966 // Populate new EDS resources.
1967 EdsResourceArgs args({
1968 {"locality0", CreateEndpointsForBackends(0, 1)},
1969 });
1970 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1971 // Construct route config to set retry policy with no supported retry_on
1972 // statuses.
1973 RouteConfiguration new_route_config = default_route_config_;
1974 auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1975 auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
1976 retry_policy->set_retry_on("5xx");
1977 retry_policy->mutable_num_retries()->set_value(kNumRetries);
1978 // Construct a virtual host level retry policy with supported statuses.
1979 auto* virtual_host_retry_policy =
1980 new_route_config.mutable_virtual_hosts(0)->mutable_retry_policy();
1981 virtual_host_retry_policy->set_retry_on(
1982 "cancelled,deadline-exceeded,internal,resource-exhausted,unavailable");
1983 virtual_host_retry_policy->mutable_num_retries()->set_value(kNumRetries);
1984 SetRouteConfiguration(balancer_.get(), new_route_config);
1985 // We expect no retry.
1986 CheckRpcSendFailure(
1987 DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "",
1988 RpcOptions().set_server_expected_error(StatusCode::DEADLINE_EXCEEDED));
1989 EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
1990 }
1991
TEST_P(LdsRdsTest,XdsRoutingHeadersMatching)1992 TEST_P(LdsRdsTest, XdsRoutingHeadersMatching) {
1993 CreateAndStartBackends(2);
1994 const char* kNewClusterName = "new_cluster";
1995 const char* kNewEdsServiceName = "new_eds_service_name";
1996 const size_t kNumEcho1Rpcs = 100;
1997 const size_t kNumEchoRpcs = 5;
1998 // Populate new EDS resources.
1999 EdsResourceArgs args({
2000 {"locality0", CreateEndpointsForBackends(0, 1)},
2001 });
2002 EdsResourceArgs args1({
2003 {"locality0", CreateEndpointsForBackends(1, 2)},
2004 });
2005 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2006 balancer_->ads_service()->SetEdsResource(
2007 BuildEdsResource(args1, kNewEdsServiceName));
2008 // Populate new CDS resources.
2009 Cluster new_cluster = default_cluster_;
2010 new_cluster.set_name(kNewClusterName);
2011 new_cluster.mutable_eds_cluster_config()->set_service_name(
2012 kNewEdsServiceName);
2013 balancer_->ads_service()->SetCdsResource(new_cluster);
2014 // Populating Route Configurations for LDS.
2015 RouteConfiguration route_config = default_route_config_;
2016 auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2017 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2018 auto* header_matcher1 = route1->mutable_match()->add_headers();
2019 header_matcher1->set_name("header1");
2020 header_matcher1->set_exact_match("POST,PUT,GET");
2021 auto* header_matcher2 = route1->mutable_match()->add_headers();
2022 header_matcher2->set_name("header2");
2023 header_matcher2->mutable_safe_regex_match()->set_regex("[a-z]*");
2024 auto* header_matcher3 = route1->mutable_match()->add_headers();
2025 header_matcher3->set_name("header3");
2026 header_matcher3->mutable_range_match()->set_start(1);
2027 header_matcher3->mutable_range_match()->set_end(1000);
2028 auto* header_matcher4 = route1->mutable_match()->add_headers();
2029 header_matcher4->set_name("header4");
2030 header_matcher4->set_present_match(false);
2031 auto* header_matcher5 = route1->mutable_match()->add_headers();
2032 header_matcher5->set_name("header5");
2033 header_matcher5->set_present_match(true);
2034 auto* header_matcher6 = route1->mutable_match()->add_headers();
2035 header_matcher6->set_name("header6");
2036 header_matcher6->set_prefix_match("/grpc");
2037 auto* header_matcher7 = route1->mutable_match()->add_headers();
2038 header_matcher7->set_name("header7");
2039 header_matcher7->set_suffix_match(".cc");
2040 header_matcher7->set_invert_match(true);
2041 route1->mutable_route()->set_cluster(kNewClusterName);
2042 auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2043 default_route->mutable_match()->set_prefix("");
2044 default_route->mutable_route()->set_cluster(kDefaultClusterName);
2045 SetRouteConfiguration(balancer_.get(), route_config);
2046 std::vector<std::pair<std::string, std::string>> metadata = {
2047 {"header1", "POST"},
2048 {"header2", "blah"},
2049 {"header3", "1"},
2050 {"header5", "anything"},
2051 {"header6", "/grpc.testing.EchoTest1Service/"},
2052 {"header1", "PUT"},
2053 {"header7", "grpc.java"},
2054 {"header1", "GET"},
2055 };
2056 const auto header_match_rpc_options = RpcOptions()
2057 .set_rpc_service(SERVICE_ECHO1)
2058 .set_rpc_method(METHOD_ECHO1)
2059 .set_metadata(std::move(metadata));
2060 // Make sure all backends are up.
2061 WaitForBackend(DEBUG_LOCATION, 0);
2062 WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
2063 WaitForBackendOptions(), header_match_rpc_options);
2064 // Send RPCs.
2065 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
2066 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs, header_match_rpc_options);
2067 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
2068 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
2069 EXPECT_EQ(0, backends_[0]->backend_service2()->request_count());
2070 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2071 EXPECT_EQ(kNumEcho1Rpcs, backends_[1]->backend_service1()->request_count());
2072 EXPECT_EQ(0, backends_[1]->backend_service2()->request_count());
2073 auto response_state = RouteConfigurationResponseState(balancer_.get());
2074 ASSERT_TRUE(response_state.has_value());
2075 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2076 }
2077
TEST_P(LdsRdsTest,XdsRoutingHeadersMatchingSpecialHeaderContentType)2078 TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialHeaderContentType) {
2079 CreateAndStartBackends(2);
2080 const char* kNewClusterName = "new_cluster";
2081 const char* kNewEdsServiceName = "new_eds_service_name";
2082 const size_t kNumEchoRpcs = 100;
2083 // Populate new EDS resources.
2084 EdsResourceArgs args({
2085 {"locality0", CreateEndpointsForBackends(0, 1)},
2086 });
2087 EdsResourceArgs args1({
2088 {"locality0", CreateEndpointsForBackends(1, 2)},
2089 });
2090 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2091 balancer_->ads_service()->SetEdsResource(
2092 BuildEdsResource(args1, kNewEdsServiceName));
2093 // Populate new CDS resources.
2094 Cluster new_cluster = default_cluster_;
2095 new_cluster.set_name(kNewClusterName);
2096 new_cluster.mutable_eds_cluster_config()->set_service_name(
2097 kNewEdsServiceName);
2098 balancer_->ads_service()->SetCdsResource(new_cluster);
2099 // Populating Route Configurations for LDS.
2100 RouteConfiguration route_config = default_route_config_;
2101 auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2102 route1->mutable_match()->set_prefix("");
2103 auto* header_matcher1 = route1->mutable_match()->add_headers();
2104 header_matcher1->set_name("content-type");
2105 header_matcher1->set_exact_match("notapplication/grpc");
2106 route1->mutable_route()->set_cluster(kNewClusterName);
2107 auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2108 default_route->mutable_match()->set_prefix("");
2109 auto* header_matcher2 = default_route->mutable_match()->add_headers();
2110 header_matcher2->set_name("content-type");
2111 header_matcher2->set_exact_match("application/grpc");
2112 default_route->mutable_route()->set_cluster(kDefaultClusterName);
2113 SetRouteConfiguration(balancer_.get(), route_config);
2114 // Make sure the backend is up.
2115 WaitForAllBackends(DEBUG_LOCATION, 0, 1);
2116 // Send RPCs.
2117 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
2118 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
2119 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2120 auto response_state = RouteConfigurationResponseState(balancer_.get());
2121 ASSERT_TRUE(response_state.has_value());
2122 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2123 }
2124
TEST_P(LdsRdsTest,XdsRoutingHeadersMatchingSpecialCasesToIgnore)2125 TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialCasesToIgnore) {
2126 CreateAndStartBackends(2);
2127 const char* kNewCluster1Name = "new_cluster_1";
2128 const char* kNewEdsService1Name = "new_eds_service_name_1";
2129 const size_t kNumEchoRpcs = 100;
2130 // Populate new EDS resources.
2131 EdsResourceArgs args({
2132 {"locality0", CreateEndpointsForBackends(0, 1)},
2133 });
2134 EdsResourceArgs args1({
2135 {"locality0", CreateEndpointsForBackends(1, 2)},
2136 });
2137 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2138 balancer_->ads_service()->SetEdsResource(
2139 BuildEdsResource(args1, kNewEdsService1Name));
2140 // Populate new CDS resources.
2141 Cluster new_cluster1 = default_cluster_;
2142 new_cluster1.set_name(kNewCluster1Name);
2143 new_cluster1.mutable_eds_cluster_config()->set_service_name(
2144 kNewEdsService1Name);
2145 balancer_->ads_service()->SetCdsResource(new_cluster1);
2146 // Populating Route Configurations for LDS.
2147 RouteConfiguration route_config = default_route_config_;
2148 auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2149 route1->mutable_match()->set_prefix("");
2150 auto* header_matcher1 = route1->mutable_match()->add_headers();
2151 header_matcher1->set_name("grpc-foo-bin");
2152 header_matcher1->set_present_match(true);
2153 route1->mutable_route()->set_cluster(kNewCluster1Name);
2154 auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2155 default_route->mutable_match()->set_prefix("");
2156 default_route->mutable_route()->set_cluster(kDefaultClusterName);
2157 SetRouteConfiguration(balancer_.get(), route_config);
2158 // Send headers which will mismatch each route
2159 std::vector<std::pair<std::string, std::string>> metadata = {
2160 {"grpc-foo-bin", "grpc-foo-bin"},
2161 };
2162 WaitForAllBackends(DEBUG_LOCATION, 0, 1);
2163 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
2164 RpcOptions().set_metadata(metadata));
2165 // Verify that only the default backend got RPCs since all previous routes
2166 // were mismatched.
2167 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
2168 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2169 auto response_state = RouteConfigurationResponseState(balancer_.get());
2170 ASSERT_TRUE(response_state.has_value());
2171 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2172 }
2173
TEST_P(LdsRdsTest,XdsRoutingRuntimeFractionMatching)2174 TEST_P(LdsRdsTest, XdsRoutingRuntimeFractionMatching) {
2175 CreateAndStartBackends(2);
2176 const char* kNewClusterName = "new_cluster";
2177 const char* kNewEdsServiceName = "new_eds_service_name";
2178 const double kErrorTolerance = 0.05;
2179 const size_t kRouteMatchNumerator = 25;
2180 const double kRouteMatchPercent =
2181 static_cast<double>(kRouteMatchNumerator) / 100;
2182 const size_t kNumRpcs =
2183 ComputeIdealNumRpcs(kRouteMatchPercent, kErrorTolerance);
2184 // Populate new EDS resources.
2185 EdsResourceArgs args({
2186 {"locality0", CreateEndpointsForBackends(0, 1)},
2187 });
2188 EdsResourceArgs args1({
2189 {"locality0", CreateEndpointsForBackends(1, 2)},
2190 });
2191 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2192 balancer_->ads_service()->SetEdsResource(
2193 BuildEdsResource(args1, kNewEdsServiceName));
2194 // Populate new CDS resources.
2195 Cluster new_cluster = default_cluster_;
2196 new_cluster.set_name(kNewClusterName);
2197 new_cluster.mutable_eds_cluster_config()->set_service_name(
2198 kNewEdsServiceName);
2199 balancer_->ads_service()->SetCdsResource(new_cluster);
2200 // Populating Route Configurations for LDS.
2201 RouteConfiguration route_config = default_route_config_;
2202 auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2203 route1->mutable_match()
2204 ->mutable_runtime_fraction()
2205 ->mutable_default_value()
2206 ->set_numerator(kRouteMatchNumerator);
2207 route1->mutable_route()->set_cluster(kNewClusterName);
2208 auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2209 default_route->mutable_match()->set_prefix("");
2210 default_route->mutable_route()->set_cluster(kDefaultClusterName);
2211 SetRouteConfiguration(balancer_.get(), route_config);
2212 WaitForAllBackends(DEBUG_LOCATION, 0, 2);
2213 CheckRpcSendOk(DEBUG_LOCATION, kNumRpcs);
2214 const int default_backend_count =
2215 backends_[0]->backend_service()->request_count();
2216 const int matched_backend_count =
2217 backends_[1]->backend_service()->request_count();
2218 EXPECT_THAT(static_cast<double>(default_backend_count) / kNumRpcs,
2219 ::testing::DoubleNear(1 - kRouteMatchPercent, kErrorTolerance));
2220 EXPECT_THAT(static_cast<double>(matched_backend_count) / kNumRpcs,
2221 ::testing::DoubleNear(kRouteMatchPercent, kErrorTolerance));
2222 auto response_state = RouteConfigurationResponseState(balancer_.get());
2223 ASSERT_TRUE(response_state.has_value());
2224 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2225 }
2226
TEST_P(LdsRdsTest,XdsRoutingHeadersMatchingUnmatchCases)2227 TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingUnmatchCases) {
2228 CreateAndStartBackends(4);
2229 const char* kNewCluster1Name = "new_cluster_1";
2230 const char* kNewEdsService1Name = "new_eds_service_name_1";
2231 const char* kNewCluster2Name = "new_cluster_2";
2232 const char* kNewEdsService2Name = "new_eds_service_name_2";
2233 const char* kNewCluster3Name = "new_cluster_3";
2234 const char* kNewEdsService3Name = "new_eds_service_name_3";
2235 const size_t kNumEcho1Rpcs = 100;
2236 const size_t kNumEchoRpcs = 5;
2237 // Populate new EDS resources.
2238 EdsResourceArgs args({
2239 {"locality0", CreateEndpointsForBackends(0, 1)},
2240 });
2241 EdsResourceArgs args1({
2242 {"locality0", CreateEndpointsForBackends(1, 2)},
2243 });
2244 EdsResourceArgs args2({
2245 {"locality0", CreateEndpointsForBackends(2, 3)},
2246 });
2247 EdsResourceArgs args3({
2248 {"locality0", CreateEndpointsForBackends(3, 4)},
2249 });
2250 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2251 balancer_->ads_service()->SetEdsResource(
2252 BuildEdsResource(args1, kNewEdsService1Name));
2253 balancer_->ads_service()->SetEdsResource(
2254 BuildEdsResource(args2, kNewEdsService2Name));
2255 balancer_->ads_service()->SetEdsResource(
2256 BuildEdsResource(args3, kNewEdsService3Name));
2257 // Populate new CDS resources.
2258 Cluster new_cluster1 = default_cluster_;
2259 new_cluster1.set_name(kNewCluster1Name);
2260 new_cluster1.mutable_eds_cluster_config()->set_service_name(
2261 kNewEdsService1Name);
2262 balancer_->ads_service()->SetCdsResource(new_cluster1);
2263 Cluster new_cluster2 = default_cluster_;
2264 new_cluster2.set_name(kNewCluster2Name);
2265 new_cluster2.mutable_eds_cluster_config()->set_service_name(
2266 kNewEdsService2Name);
2267 balancer_->ads_service()->SetCdsResource(new_cluster2);
2268 Cluster new_cluster3 = default_cluster_;
2269 new_cluster3.set_name(kNewCluster3Name);
2270 new_cluster3.mutable_eds_cluster_config()->set_service_name(
2271 kNewEdsService3Name);
2272 balancer_->ads_service()->SetCdsResource(new_cluster3);
2273 // Populating Route Configurations for LDS.
2274 RouteConfiguration route_config = default_route_config_;
2275 auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2276 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2277 auto* header_matcher1 = route1->mutable_match()->add_headers();
2278 header_matcher1->set_name("header1");
2279 header_matcher1->set_exact_match("POST");
2280 route1->mutable_route()->set_cluster(kNewCluster1Name);
2281 auto route2 = route_config.mutable_virtual_hosts(0)->add_routes();
2282 route2->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2283 auto* header_matcher2 = route2->mutable_match()->add_headers();
2284 header_matcher2->set_name("header2");
2285 header_matcher2->mutable_range_match()->set_start(1);
2286 header_matcher2->mutable_range_match()->set_end(1000);
2287 route2->mutable_route()->set_cluster(kNewCluster2Name);
2288 auto route3 = route_config.mutable_virtual_hosts(0)->add_routes();
2289 route3->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2290 auto* header_matcher3 = route3->mutable_match()->add_headers();
2291 header_matcher3->set_name("header3");
2292 header_matcher3->mutable_safe_regex_match()->set_regex("[a-z]*");
2293 route3->mutable_route()->set_cluster(kNewCluster3Name);
2294 auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2295 default_route->mutable_match()->set_prefix("");
2296 default_route->mutable_route()->set_cluster(kDefaultClusterName);
2297 SetRouteConfiguration(balancer_.get(), route_config);
2298 // Send headers which will mismatch each route
2299 std::vector<std::pair<std::string, std::string>> metadata = {
2300 {"header1", "POST"},
2301 {"header2", "1000"},
2302 {"header3", "123"},
2303 {"header1", "GET"},
2304 };
2305 WaitForAllBackends(DEBUG_LOCATION, 0, 1);
2306 CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
2307 RpcOptions().set_metadata(metadata));
2308 CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
2309 RpcOptions()
2310 .set_rpc_service(SERVICE_ECHO1)
2311 .set_rpc_method(METHOD_ECHO1)
2312 .set_metadata(metadata));
2313 // Verify that only the default backend got RPCs since all previous routes
2314 // were mismatched.
2315 for (size_t i = 1; i < 4; ++i) {
2316 EXPECT_EQ(0, backends_[i]->backend_service()->request_count());
2317 EXPECT_EQ(0, backends_[i]->backend_service1()->request_count());
2318 EXPECT_EQ(0, backends_[i]->backend_service2()->request_count());
2319 }
2320 EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
2321 EXPECT_EQ(kNumEcho1Rpcs, backends_[0]->backend_service1()->request_count());
2322 EXPECT_EQ(0, backends_[0]->backend_service2()->request_count());
2323 auto response_state = RouteConfigurationResponseState(balancer_.get());
2324 ASSERT_TRUE(response_state.has_value());
2325 EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2326 }
2327
TEST_P(LdsRdsTest,XdsRoutingChangeRoutesWithoutChangingClusters)2328 TEST_P(LdsRdsTest, XdsRoutingChangeRoutesWithoutChangingClusters) {
2329 CreateAndStartBackends(2);
2330 const char* kNewClusterName = "new_cluster";
2331 const char* kNewEdsServiceName = "new_eds_service_name";
2332 // Populate new EDS resources.
2333 EdsResourceArgs args({
2334 {"locality0", CreateEndpointsForBackends(0, 1)},
2335 });
2336 EdsResourceArgs args1({
2337 {"locality0", CreateEndpointsForBackends(1, 2)},
2338 });
2339 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2340 balancer_->ads_service()->SetEdsResource(
2341 BuildEdsResource(args1, kNewEdsServiceName));
2342 // Populate new CDS resources.
2343 Cluster new_cluster = default_cluster_;
2344 new_cluster.set_name(kNewClusterName);
2345 new_cluster.mutable_eds_cluster_config()->set_service_name(
2346 kNewEdsServiceName);
2347 balancer_->ads_service()->SetCdsResource(new_cluster);
2348 // Populating Route Configurations for LDS.
2349 RouteConfiguration route_config = default_route_config_;
2350 auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2351 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2352 route1->mutable_route()->set_cluster(kNewClusterName);
2353 auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2354 default_route->mutable_match()->set_prefix("");
2355 default_route->mutable_route()->set_cluster(kDefaultClusterName);
2356 SetRouteConfiguration(balancer_.get(), route_config);
2357 // Make sure all backends are up and that requests for each RPC
2358 // service go to the right backends.
2359 WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
2360 WaitForBackendOptions().set_reset_counters(false));
2361 WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
2362 WaitForBackendOptions().set_reset_counters(false),
2363 RpcOptions().set_rpc_service(SERVICE_ECHO1));
2364 WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
2365 WaitForBackendOptions().set_reset_counters(false),
2366 RpcOptions().set_rpc_service(SERVICE_ECHO2));
2367 // Requests for services Echo and Echo2 should have gone to backend 0.
2368 EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
2369 EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
2370 EXPECT_EQ(1, backends_[0]->backend_service2()->request_count());
2371 // Requests for service Echo1 should have gone to backend 1.
2372 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2373 EXPECT_EQ(1, backends_[1]->backend_service1()->request_count());
2374 EXPECT_EQ(0, backends_[1]->backend_service2()->request_count());
2375 // Now send an update that changes the first route to match a
2376 // different RPC service, and wait for the client to make the change.
2377 route1->mutable_match()->set_prefix("/grpc.testing.EchoTest2Service/");
2378 SetRouteConfiguration(balancer_.get(), route_config);
2379 WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
2380 WaitForBackendOptions(),
2381 RpcOptions().set_rpc_service(SERVICE_ECHO2));
2382 // Now repeat the earlier test, making sure all traffic goes to the
2383 // right place.
2384 WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
2385 WaitForBackendOptions().set_reset_counters(false));
2386 WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
2387 WaitForBackendOptions().set_reset_counters(false),
2388 RpcOptions().set_rpc_service(SERVICE_ECHO1));
2389 WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
2390 WaitForBackendOptions().set_reset_counters(false),
2391 RpcOptions().set_rpc_service(SERVICE_ECHO2));
2392 // Requests for services Echo and Echo1 should have gone to backend 0.
2393 EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
2394 EXPECT_EQ(1, backends_[0]->backend_service1()->request_count());
2395 EXPECT_EQ(0, backends_[0]->backend_service2()->request_count());
2396 // Requests for service Echo2 should have gone to backend 1.
2397 EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2398 EXPECT_EQ(0, backends_[1]->backend_service1()->request_count());
2399 EXPECT_EQ(1, backends_[1]->backend_service2()->request_count());
2400 }
2401
2402 } // namespace
2403 } // namespace testing
2404 } // namespace grpc
2405
main(int argc,char ** argv)2406 int main(int argc, char** argv) {
2407 grpc::testing::TestEnvironment env(&argc, argv);
2408 ::testing::InitGoogleTest(&argc, argv);
2409 // Make the backup poller poll very frequently in order to pick up
2410 // updates from all the subchannels's FDs.
2411 grpc_core::ConfigVars::Overrides overrides;
2412 overrides.client_channel_backup_poll_interval_ms = 1;
2413 grpc_core::ConfigVars::SetOverrides(overrides);
2414 #if TARGET_OS_IPHONE
2415 // Workaround Apple CFStream bug
2416 grpc_core::SetEnv("grpc_cfstream", "0");
2417 #endif
2418 grpc_init();
2419 const auto result = RUN_ALL_TESTS();
2420 grpc_shutdown();
2421 return result;
2422 }
2423