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