xds_routing_end2end_test.cc
Go to the documentation of this file.
1 // Copyright 2017 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <chrono>
16 #include <string>
17 #include <thread>
18 #include <vector>
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
24 #include "src/proto/grpc/testing/xds/v3/fault.grpc.pb.h"
25 #include "src/proto/grpc/testing/xds/v3/router.grpc.pb.h"
28 
29 namespace grpc {
30 namespace testing {
31 namespace {
32 
33 using ::envoy::extensions::filters::http::fault::v3::HTTPFault;
34 using std::chrono::system_clock;
35 
36 using LdsTest = XdsEnd2endTest;
37 
38 INSTANTIATE_TEST_SUITE_P(XdsTest, LdsTest, ::testing::Values(XdsTestType()),
40 
41 // Tests that LDS client should send a NACK if there is no API listener in the
42 // Listener in the LDS response.
43 TEST_P(LdsTest, NoApiListener) {
44  auto listener = default_listener_;
45  listener.clear_api_listener();
46  balancer_->ads_service()->SetLdsResource(listener);
47  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
48  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
50  response_state->error_message,
51  ::testing::HasSubstr("Listener has neither address nor ApiListener"));
52 }
53 
54 // Tests that LDS client should send a NACK if the route_specifier in the
55 // http_connection_manager is neither inlined route_config nor RDS.
56 TEST_P(LdsTest, WrongRouteSpecifier) {
57  auto listener = default_listener_;
58  HttpConnectionManager http_connection_manager;
59  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
60  &http_connection_manager);
61  http_connection_manager.mutable_scoped_routes();
62  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
63  http_connection_manager);
64  balancer_->ads_service()->SetLdsResource(listener);
65  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
66  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
68  response_state->error_message,
70  "HttpConnectionManager neither has inlined route_config nor RDS."));
71 }
72 
73 // Tests that LDS client should send a NACK if the rds message in the
74 // http_connection_manager is missing the config_source field.
75 TEST_P(LdsTest, RdsMissingConfigSource) {
76  auto listener = default_listener_;
77  HttpConnectionManager http_connection_manager;
78  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
79  &http_connection_manager);
80  http_connection_manager.mutable_rds()->set_route_config_name(
81  kDefaultRouteConfigurationName);
82  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
83  http_connection_manager);
84  balancer_->ads_service()->SetLdsResource(listener);
85  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
86  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
87  EXPECT_THAT(response_state->error_message,
89  "HttpConnectionManager missing config_source for RDS."));
90 }
91 
92 // Tests that LDS client should send a NACK if the rds message in the
93 // http_connection_manager has a config_source field that does not specify
94 // ADS or SELF.
95 TEST_P(LdsTest, RdsConfigSourceDoesNotSpecifyAdsOrSelf) {
96  auto listener = default_listener_;
97  HttpConnectionManager http_connection_manager;
98  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
99  &http_connection_manager);
100  auto* rds = http_connection_manager.mutable_rds();
101  rds->set_route_config_name(kDefaultRouteConfigurationName);
102  rds->mutable_config_source()->set_path("/foo/bar");
103  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
104  http_connection_manager);
105  balancer_->ads_service()->SetLdsResource(listener);
106  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
107  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
108  EXPECT_THAT(response_state->error_message,
109  ::testing::HasSubstr("HttpConnectionManager ConfigSource for "
110  "RDS does not specify ADS or SELF."));
111 }
112 
113 // Tests that LDS client accepts the rds message in the
114 // http_connection_manager with a config_source field that specifies ADS.
115 TEST_P(LdsTest, AcceptsRdsConfigSourceOfTypeAds) {
116  CreateAndStartBackends(1);
117  auto listener = default_listener_;
118  HttpConnectionManager http_connection_manager;
119  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
120  &http_connection_manager);
121  auto* rds = http_connection_manager.mutable_rds();
122  rds->set_route_config_name(kDefaultRouteConfigurationName);
123  rds->mutable_config_source()->mutable_ads();
124  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
125  http_connection_manager);
126  SetListenerAndRouteConfiguration(balancer_.get(), listener,
127  default_route_config_);
128  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
129  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
130  WaitForAllBackends(DEBUG_LOCATION);
131  auto response_state = balancer_->ads_service()->lds_response_state();
132  ASSERT_TRUE(response_state.has_value());
133  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
134 }
135 
136 // Tests that we NACK non-terminal filters at the end of the list.
137 TEST_P(LdsTest, NacksNonTerminalHttpFilterAtEndOfList) {
138  auto listener = default_listener_;
139  HttpConnectionManager http_connection_manager;
140  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
141  &http_connection_manager);
142  auto* filter = http_connection_manager.mutable_http_filters(0);
143  filter->set_name("unknown");
144  filter->mutable_typed_config()->set_type_url(
145  "custom/grpc.testing.client_only_http_filter");
146  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
147  http_connection_manager);
148  SetListenerAndRouteConfiguration(balancer_.get(), listener,
149  default_route_config_);
150  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
151  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
152  EXPECT_THAT(response_state->error_message,
154  "non-terminal filter for config type grpc.testing"
155  ".client_only_http_filter is the last filter in the chain"));
156 }
157 
158 // Test that we NACK terminal filters that are not at the end of the list.
159 TEST_P(LdsTest, NacksTerminalFilterBeforeEndOfList) {
160  auto listener = default_listener_;
161  HttpConnectionManager http_connection_manager;
162  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
163  &http_connection_manager);
164  // The default_listener_ has a terminal router filter by default. Add an
165  // additional filter.
166  auto* filter = http_connection_manager.add_http_filters();
167  filter->set_name("grpc.testing.terminal_http_filter");
168  filter->mutable_typed_config()->set_type_url(
169  "custom/grpc.testing.terminal_http_filter");
170  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
171  http_connection_manager);
172  SetListenerAndRouteConfiguration(balancer_.get(), listener,
173  default_route_config_);
174  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
175  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
176  EXPECT_THAT(
177  response_state->error_message,
179  "terminal filter for config type envoy.extensions.filters.http"
180  ".router.v3.Router must be the last filter in the chain"));
181 }
182 
183 // Test that we NACK empty filter names.
184 TEST_P(LdsTest, RejectsEmptyHttpFilterName) {
185  auto listener = default_listener_;
186  HttpConnectionManager http_connection_manager;
187  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
188  &http_connection_manager);
189  *http_connection_manager.add_http_filters() =
190  http_connection_manager.http_filters(0);
191  auto* filter = http_connection_manager.mutable_http_filters(0);
192  filter->Clear();
193  filter->mutable_typed_config()->PackFrom(Listener());
194  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
195  http_connection_manager);
196  SetListenerAndRouteConfiguration(balancer_.get(), listener,
197  default_route_config_);
198  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
199  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
200  EXPECT_THAT(response_state->error_message,
201  ::testing::HasSubstr("empty filter name at index 0"));
202 }
203 
204 // Test that we NACK duplicate HTTP filter names.
205 TEST_P(LdsTest, RejectsDuplicateHttpFilterName) {
206  auto listener = default_listener_;
207  HttpConnectionManager http_connection_manager;
208  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
209  &http_connection_manager);
210  *http_connection_manager.add_http_filters() =
211  http_connection_manager.http_filters(0);
212  http_connection_manager.mutable_http_filters(0)
213  ->mutable_typed_config()
214  ->PackFrom(HTTPFault());
215  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
216  http_connection_manager);
217  SetListenerAndRouteConfiguration(balancer_.get(), listener,
218  default_route_config_);
219  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
220  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
221  EXPECT_THAT(response_state->error_message,
222  ::testing::HasSubstr("duplicate HTTP filter name: router"));
223 }
224 
225 // Test that we NACK unknown filter types.
226 TEST_P(LdsTest, RejectsUnknownHttpFilterType) {
227  auto listener = default_listener_;
228  HttpConnectionManager http_connection_manager;
229  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
230  &http_connection_manager);
231  *http_connection_manager.add_http_filters() =
232  http_connection_manager.http_filters(0);
233  auto* filter = http_connection_manager.mutable_http_filters(0);
234  filter->set_name("unknown");
235  filter->mutable_typed_config()->PackFrom(Listener());
236  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
237  http_connection_manager);
238  SetListenerAndRouteConfiguration(balancer_.get(), listener,
239  default_route_config_);
240  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
241  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
242  EXPECT_THAT(response_state->error_message,
243  ::testing::HasSubstr("no filter registered for config type "
244  "envoy.config.listener.v3.Listener"));
245 }
246 
247 // Test that we ignore optional unknown filter types.
248 TEST_P(LdsTest, IgnoresOptionalUnknownHttpFilterType) {
249  CreateAndStartBackends(1);
250  auto listener = default_listener_;
251  HttpConnectionManager http_connection_manager;
252  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
253  &http_connection_manager);
254  *http_connection_manager.add_http_filters() =
255  http_connection_manager.http_filters(0);
256  auto* filter = http_connection_manager.mutable_http_filters(0);
257  filter->set_name("unknown");
258  filter->mutable_typed_config()->PackFrom(Listener());
259  filter->set_is_optional(true);
260  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
261  http_connection_manager);
262  SetListenerAndRouteConfiguration(balancer_.get(), listener,
263  default_route_config_);
264  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
265  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
266  WaitForAllBackends(DEBUG_LOCATION);
267  auto response_state = balancer_->ads_service()->lds_response_state();
268  ASSERT_TRUE(response_state.has_value());
269  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
270 }
271 
272 // Test that we NACK filters without configs.
273 TEST_P(LdsTest, RejectsHttpFilterWithoutConfig) {
274  auto listener = default_listener_;
275  HttpConnectionManager http_connection_manager;
276  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
277  &http_connection_manager);
278  *http_connection_manager.add_http_filters() =
279  http_connection_manager.http_filters(0);
280  auto* filter = http_connection_manager.mutable_http_filters(0);
281  filter->Clear();
282  filter->set_name("unknown");
283  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
284  http_connection_manager);
285  SetListenerAndRouteConfiguration(balancer_.get(), listener,
286  default_route_config_);
287  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
288  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
289  EXPECT_THAT(response_state->error_message,
291  "no filter config specified for filter name unknown"));
292 }
293 
294 // Test that we ignore optional filters without configs.
295 TEST_P(LdsTest, IgnoresOptionalHttpFilterWithoutConfig) {
296  CreateAndStartBackends(1);
297  auto listener = default_listener_;
298  HttpConnectionManager http_connection_manager;
299  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
300  &http_connection_manager);
301  *http_connection_manager.add_http_filters() =
302  http_connection_manager.http_filters(0);
303  auto* filter = http_connection_manager.mutable_http_filters(0);
304  filter->Clear();
305  filter->set_name("unknown");
306  filter->set_is_optional(true);
307  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
308  http_connection_manager);
309  SetListenerAndRouteConfiguration(balancer_.get(), listener,
310  default_route_config_);
311  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
312  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
313  WaitForAllBackends(DEBUG_LOCATION);
314  auto response_state = balancer_->ads_service()->lds_response_state();
315  ASSERT_TRUE(response_state.has_value());
316  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
317 }
318 
319 // Test that we NACK unparseable filter configs.
320 TEST_P(LdsTest, RejectsUnparseableHttpFilterType) {
321  auto listener = default_listener_;
322  HttpConnectionManager http_connection_manager;
323  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
324  &http_connection_manager);
325  *http_connection_manager.add_http_filters() =
326  http_connection_manager.http_filters(0);
327  auto* filter = http_connection_manager.mutable_http_filters(0);
328  filter->set_name("unknown");
329  filter->mutable_typed_config()->PackFrom(listener);
330  filter->mutable_typed_config()->set_type_url(
331  "type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault");
332  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
333  http_connection_manager);
334  SetListenerAndRouteConfiguration(balancer_.get(), listener,
335  default_route_config_);
336  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
337  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
338  EXPECT_THAT(
339  response_state->error_message,
341  "filter config for type "
342  "envoy.extensions.filters.http.fault.v3.HTTPFault failed to parse"));
343 }
344 
345 // Test that we NACK HTTP filters unsupported on client-side.
346 TEST_P(LdsTest, RejectsHttpFiltersNotSupportedOnClients) {
347  auto listener = default_listener_;
348  HttpConnectionManager http_connection_manager;
349  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
350  &http_connection_manager);
351  *http_connection_manager.add_http_filters() =
352  http_connection_manager.http_filters(0);
353  auto* filter = http_connection_manager.mutable_http_filters(0);
354  filter->set_name("grpc.testing.server_only_http_filter");
355  filter->mutable_typed_config()->set_type_url(
356  "custom/grpc.testing.server_only_http_filter");
357  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
358  http_connection_manager);
359  SetListenerAndRouteConfiguration(balancer_.get(), listener,
360  default_route_config_);
361  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
362  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
363  EXPECT_THAT(
364  response_state->error_message,
365  ::testing::HasSubstr("Filter grpc.testing.server_only_http_filter is not "
366  "supported on clients"));
367 }
368 
369 // Test that we ignore optional HTTP filters unsupported on client-side.
370 TEST_P(LdsTest, IgnoresOptionalHttpFiltersNotSupportedOnClients) {
371  CreateAndStartBackends(1);
372  auto listener = default_listener_;
373  HttpConnectionManager http_connection_manager;
374  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
375  &http_connection_manager);
376  *http_connection_manager.add_http_filters() =
377  http_connection_manager.http_filters(0);
378  auto* filter = http_connection_manager.mutable_http_filters(0);
379  filter->set_name("grpc.testing.server_only_http_filter");
380  filter->mutable_typed_config()->set_type_url(
381  "custom/grpc.testing.server_only_http_filter");
382  filter->set_is_optional(true);
383  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
384  http_connection_manager);
385  SetListenerAndRouteConfiguration(balancer_.get(), listener,
386  default_route_config_);
387  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
388  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
389  WaitForAllBackends(DEBUG_LOCATION);
390  auto response_state = balancer_->ads_service()->lds_response_state();
391  ASSERT_TRUE(response_state.has_value());
392  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
393 }
394 
395 // Test that we NACK non-zero xff_num_trusted_hops
396 TEST_P(LdsTest, RejectsNonZeroXffNumTrusterHops) {
397  auto listener = default_listener_;
398  HttpConnectionManager http_connection_manager;
399  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
400  &http_connection_manager);
401  http_connection_manager.set_xff_num_trusted_hops(1);
402  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
403  http_connection_manager);
404  SetListenerAndRouteConfiguration(balancer_.get(), listener,
405  default_route_config_);
406  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
407  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
408  EXPECT_THAT(response_state->error_message,
409  ::testing::HasSubstr("'xff_num_trusted_hops' must be zero"));
410 }
411 
412 // Test that we NACK non-empty original_ip_detection_extensions
413 TEST_P(LdsTest, RejectsNonEmptyOriginalIpDetectionExtensions) {
414  auto listener = default_listener_;
415  HttpConnectionManager http_connection_manager;
416  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
417  &http_connection_manager);
418  http_connection_manager.add_original_ip_detection_extensions();
419  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
420  http_connection_manager);
421  SetListenerAndRouteConfiguration(balancer_.get(), listener,
422  default_route_config_);
423  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
424  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
425  EXPECT_THAT(
426  response_state->error_message,
427  ::testing::HasSubstr("'original_ip_detection_extensions' must be empty"));
428 }
429 
430 using LdsV2Test = XdsEnd2endTest;
431 
432 INSTANTIATE_TEST_SUITE_P(XdsTest, LdsV2Test,
433  ::testing::Values(XdsTestType().set_use_v2()),
435 
436 // Tests that we ignore the HTTP filter list in v2.
437 // TODO(roth): The test framework is not set up to allow us to test
438 // the server sending v2 resources when the client requests v3, so this
439 // just tests a pure v2 setup. When we have time, fix this.
440 TEST_P(LdsV2Test, IgnoresHttpFilters) {
441  CreateAndStartBackends(1);
442  auto listener = default_listener_;
443  HttpConnectionManager http_connection_manager;
444  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
445  &http_connection_manager);
446  auto* filter = http_connection_manager.add_http_filters();
447  filter->set_name("unknown");
448  filter->mutable_typed_config()->PackFrom(Listener());
449  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
450  http_connection_manager);
451  SetListenerAndRouteConfiguration(balancer_.get(), listener,
452  default_route_config_);
453  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
454  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
455  CheckRpcSendOk(DEBUG_LOCATION);
456 }
457 
458 class LdsDeletionTest : public XdsEnd2endTest {
459  protected:
460  void SetUp() override {} // Individual tests call InitClient().
461 };
462 
463 INSTANTIATE_TEST_SUITE_P(XdsTest, LdsDeletionTest,
464  ::testing::Values(XdsTestType()), &XdsTestType::Name);
465 
466 // Tests that we go into TRANSIENT_FAILURE if the Listener is deleted.
467 TEST_P(LdsDeletionTest, ListenerDeleted) {
468  InitClient();
469  CreateAndStartBackends(1);
470  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
471  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
472  // We need to wait for all backends to come online.
473  WaitForAllBackends(DEBUG_LOCATION);
474  // Unset LDS resource.
475  balancer_->ads_service()->UnsetResource(kLdsTypeUrl, kServerName);
476  // Wait for RPCs to start failing.
477  SendRpcsUntil(DEBUG_LOCATION, [](const RpcResult& result) {
478  if (result.status.ok()) return true; // Keep going.
479  EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
480  EXPECT_EQ(result.status.error_message(),
481  absl::StrCat("empty address list: ", kServerName,
482  ": xDS listener resource does not exist"));
483  return false;
484  });
485  // Make sure we ACK'ed the update.
486  auto response_state = balancer_->ads_service()->lds_response_state();
487  ASSERT_TRUE(response_state.has_value());
488  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
489 }
490 
491 // Tests that we ignore Listener deletions if configured to do so.
492 TEST_P(LdsDeletionTest, ListenerDeletionIgnored) {
493  InitClient(BootstrapBuilder().SetIgnoreResourceDeletion());
494  CreateAndStartBackends(2);
495  // Bring up client pointing to backend 0 and wait for it to connect.
496  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
497  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
498  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
499  // Make sure we ACKed the LDS update.
500  auto response_state = balancer_->ads_service()->lds_response_state();
501  ASSERT_TRUE(response_state.has_value());
502  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
503  // Unset LDS resource and wait for client to ACK the update.
504  balancer_->ads_service()->UnsetResource(kLdsTypeUrl, kServerName);
505  const auto deadline = absl::Now() + absl::Seconds(30);
506  while (true) {
507  ASSERT_LT(absl::Now(), deadline) << "timed out waiting for LDS ACK";
508  response_state = balancer_->ads_service()->lds_response_state();
509  if (response_state.has_value()) break;
510  }
511  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
512  // Make sure we can still send RPCs.
513  CheckRpcSendOk(DEBUG_LOCATION);
514  // Now recreate the LDS resource pointing to a different CDS and EDS
515  // resource, pointing to backend 1, and make sure the client uses it.
516  const char* kNewClusterName = "new_cluster_name";
517  const char* kNewEdsResourceName = "new_eds_resource_name";
518  auto cluster = default_cluster_;
519  cluster.set_name(kNewClusterName);
520  cluster.mutable_eds_cluster_config()->set_service_name(kNewEdsResourceName);
521  balancer_->ads_service()->SetCdsResource(cluster);
522  args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
523  balancer_->ads_service()->SetEdsResource(
524  BuildEdsResource(args, kNewEdsResourceName));
525  RouteConfiguration new_route_config = default_route_config_;
526  new_route_config.mutable_virtual_hosts(0)
527  ->mutable_routes(0)
528  ->mutable_route()
529  ->set_cluster(kNewClusterName);
530  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
531  new_route_config);
532  // Wait for client to start using backend 1.
533  WaitForAllBackends(DEBUG_LOCATION, 1, 2);
534 }
535 
536 using LdsRdsTest = XdsEnd2endTest;
537 
538 // Test with and without RDS.
539 // Also test with v2 and RDS to ensure that we handle those cases.
541  XdsTest, LdsRdsTest,
542  ::testing::Values(XdsTestType(), XdsTestType().set_enable_rds_testing(),
543  XdsTestType().set_enable_rds_testing().set_use_v2()),
545 
546 MATCHER_P2(AdjustedClockInRange, t1, t2, "equals time") {
547  gpr_cycle_counter cycle_now = gpr_get_cycle_counter();
548  grpc_core::Timestamp cycle_time =
550  grpc_core::Timestamp time_spec =
552  grpc_core::Timestamp now = arg + (time_spec - cycle_time);
553  bool ok = true;
554  ok &= ::testing::ExplainMatchResult(::testing::Ge(t1), now, result_listener);
555  ok &= ::testing::ExplainMatchResult(::testing::Lt(t2), now, result_listener);
556  return ok;
557 }
558 
559 // Tests that XdsClient sends an ACK for the RouteConfiguration, whether or
560 // not it was inlined into the LDS response.
561 TEST_P(LdsRdsTest, Vanilla) {
562  (void)SendRpc();
563  auto response_state = RouteConfigurationResponseState(balancer_.get());
564  ASSERT_TRUE(response_state.has_value());
565  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
566  // Make sure we actually used the RPC service for the right version of xDS.
567  EXPECT_EQ(balancer_->ads_service()->seen_v2_client(), GetParam().use_v2());
568  EXPECT_NE(balancer_->ads_service()->seen_v3_client(), GetParam().use_v2());
569 }
570 
571 TEST_P(LdsRdsTest, DefaultRouteSpecifiesSlashPrefix) {
572  CreateAndStartBackends(1);
573  RouteConfiguration route_config = default_route_config_;
574  route_config.mutable_virtual_hosts(0)
575  ->mutable_routes(0)
576  ->mutable_match()
577  ->set_prefix("/");
578  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
579  route_config);
580  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
581  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
582  // We need to wait for all backends to come online.
583  WaitForAllBackends(DEBUG_LOCATION);
584 }
585 
586 // Tests that LDS client ACKs but fails if matching domain can't be found in
587 // the LDS response.
588 TEST_P(LdsRdsTest, NoMatchedDomain) {
589  RouteConfiguration route_config = default_route_config_;
590  route_config.mutable_virtual_hosts(0)->clear_domains();
591  route_config.mutable_virtual_hosts(0)->add_domains("unmatched_domain");
592  SetRouteConfiguration(balancer_.get(), route_config);
593  CheckRpcSendFailure(
595  absl::StrCat(
596  (GetParam().enable_rds_testing() ? kDefaultRouteConfigurationName
597  : kServerName),
598  ": UNAVAILABLE: could not find VirtualHost for ", kServerName,
599  " in RouteConfiguration"));
600  // Do a bit of polling, to allow the ACK to get to the ADS server.
601  channel_->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100));
602  auto response_state = RouteConfigurationResponseState(balancer_.get());
603  ASSERT_TRUE(response_state.has_value());
604  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
605 }
606 
607 // Tests that LDS client should choose the virtual host with matching domain
608 // if multiple virtual hosts exist in the LDS response.
609 TEST_P(LdsRdsTest, ChooseMatchedDomain) {
610  RouteConfiguration route_config = default_route_config_;
611  *(route_config.add_virtual_hosts()) = route_config.virtual_hosts(0);
612  route_config.mutable_virtual_hosts(0)->clear_domains();
613  route_config.mutable_virtual_hosts(0)->add_domains("unmatched_domain");
614  SetRouteConfiguration(balancer_.get(), route_config);
615  (void)SendRpc();
616  auto response_state = RouteConfigurationResponseState(balancer_.get());
617  ASSERT_TRUE(response_state.has_value());
618  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
619 }
620 
621 // Tests that LDS client should choose the last route in the virtual host if
622 // multiple routes exist in the LDS response.
623 TEST_P(LdsRdsTest, ChooseLastRoute) {
624  RouteConfiguration route_config = default_route_config_;
625  *(route_config.mutable_virtual_hosts(0)->add_routes()) =
626  route_config.virtual_hosts(0).routes(0);
627  route_config.mutable_virtual_hosts(0)
628  ->mutable_routes(0)
629  ->mutable_route()
630  ->mutable_cluster_header();
631  SetRouteConfiguration(balancer_.get(), route_config);
632  (void)SendRpc();
633  auto response_state = RouteConfigurationResponseState(balancer_.get());
634  ASSERT_TRUE(response_state.has_value());
635  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
636 }
637 
638 // Tests that LDS client should ignore route which has query_parameters.
639 TEST_P(LdsRdsTest, RouteMatchHasQueryParameters) {
640  RouteConfiguration route_config = default_route_config_;
641  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
642  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
643  route1->mutable_match()->add_query_parameters();
644  SetRouteConfiguration(balancer_.get(), route_config);
645  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
646  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
647  EXPECT_THAT(response_state->error_message,
648  ::testing::HasSubstr("No valid routes specified."));
649 }
650 
651 // Tests that LDS client should send a ACK if route match has a prefix
652 // that is either empty or a single slash
653 TEST_P(LdsRdsTest, RouteMatchHasValidPrefixEmptyOrSingleSlash) {
654  RouteConfiguration route_config = default_route_config_;
655  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
656  route1->mutable_match()->set_prefix("");
657  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
658  default_route->mutable_match()->set_prefix("/");
659  default_route->mutable_route()->set_cluster(kDefaultClusterName);
660  SetRouteConfiguration(balancer_.get(), route_config);
661  (void)SendRpc();
662  const auto response_state = RouteConfigurationResponseState(balancer_.get());
663  ASSERT_TRUE(response_state.has_value());
664  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
665 }
666 
667 // Tests that LDS client should ignore route which has a path
668 // prefix string does not start with "/".
669 TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixNoLeadingSlash) {
670  RouteConfiguration route_config = default_route_config_;
671  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
672  route1->mutable_match()->set_prefix("grpc.testing.EchoTest1Service/");
673  SetRouteConfiguration(balancer_.get(), route_config);
674  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
675  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
676  EXPECT_THAT(response_state->error_message,
677  ::testing::HasSubstr("No valid routes specified."));
678 }
679 
680 // Tests that LDS client should ignore route which has a prefix
681 // string with more than 2 slashes.
682 TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixExtraContent) {
683  RouteConfiguration route_config = default_route_config_;
684  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
685  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/Echo1/");
686  SetRouteConfiguration(balancer_.get(), route_config);
687  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
688  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
689  EXPECT_THAT(response_state->error_message,
690  ::testing::HasSubstr("No valid routes specified."));
691 }
692 
693 // Tests that LDS client should ignore route which has a prefix
694 // string "//".
695 TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixDoubleSlash) {
696  RouteConfiguration route_config = default_route_config_;
697  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
698  route1->mutable_match()->set_prefix("//");
699  SetRouteConfiguration(balancer_.get(), route_config);
700  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
701  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
702  EXPECT_THAT(response_state->error_message,
703  ::testing::HasSubstr("No valid routes specified."));
704 }
705 
706 // Tests that LDS client should ignore route which has path
707 // but it's empty.
708 TEST_P(LdsRdsTest, RouteMatchHasInvalidPathEmptyPath) {
709  RouteConfiguration route_config = default_route_config_;
710  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
711  route1->mutable_match()->set_path("");
712  SetRouteConfiguration(balancer_.get(), route_config);
713  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
714  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
715  EXPECT_THAT(response_state->error_message,
716  ::testing::HasSubstr("No valid routes specified."));
717 }
718 
719 // Tests that LDS client should ignore route which has path
720 // string does not start with "/".
721 TEST_P(LdsRdsTest, RouteMatchHasInvalidPathNoLeadingSlash) {
722  RouteConfiguration route_config = default_route_config_;
723  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
724  route1->mutable_match()->set_path("grpc.testing.EchoTest1Service/Echo1");
725  SetRouteConfiguration(balancer_.get(), route_config);
726  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
727  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
728  EXPECT_THAT(response_state->error_message,
729  ::testing::HasSubstr("No valid routes specified."));
730 }
731 
732 // Tests that LDS client should ignore route which has path
733 // string that has too many slashes; for example, ends with "/".
734 TEST_P(LdsRdsTest, RouteMatchHasInvalidPathTooManySlashes) {
735  RouteConfiguration route_config = default_route_config_;
736  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
737  route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service/Echo1/");
738  SetRouteConfiguration(balancer_.get(), route_config);
739  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
740  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
741  EXPECT_THAT(response_state->error_message,
742  ::testing::HasSubstr("No valid routes specified."));
743 }
744 
745 // Tests that LDS client should ignore route which has path
746 // string that has only 1 slash: missing "/" between service and method.
747 TEST_P(LdsRdsTest, RouteMatchHasInvalidPathOnlyOneSlash) {
748  RouteConfiguration route_config = default_route_config_;
749  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
750  route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service.Echo1");
751  SetRouteConfiguration(balancer_.get(), route_config);
752  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
753  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
754  EXPECT_THAT(response_state->error_message,
755  ::testing::HasSubstr("No valid routes specified."));
756 }
757 
758 // Tests that LDS client should ignore route which has path
759 // string that is missing service.
760 TEST_P(LdsRdsTest, RouteMatchHasInvalidPathMissingService) {
761  RouteConfiguration route_config = default_route_config_;
762  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
763  route1->mutable_match()->set_path("//Echo1");
764  SetRouteConfiguration(balancer_.get(), route_config);
765  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
766  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
767  EXPECT_THAT(response_state->error_message,
768  ::testing::HasSubstr("No valid routes specified."));
769 }
770 
771 // Tests that LDS client should ignore route which has path
772 // string that is missing method.
773 TEST_P(LdsRdsTest, RouteMatchHasInvalidPathMissingMethod) {
774  RouteConfiguration route_config = default_route_config_;
775  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
776  route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service/");
777  SetRouteConfiguration(balancer_.get(), route_config);
778  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
779  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
780  EXPECT_THAT(response_state->error_message,
781  ::testing::HasSubstr("No valid routes specified."));
782 }
783 
784 // Test that LDS client should reject route which has invalid path regex.
785 TEST_P(LdsRdsTest, RouteMatchHasInvalidPathRegex) {
786  const char* kNewCluster1Name = "new_cluster_1";
787  RouteConfiguration route_config = default_route_config_;
788  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
789  route1->mutable_match()->mutable_safe_regex()->set_regex("a[z-a]");
790  route1->mutable_route()->set_cluster(kNewCluster1Name);
791  SetRouteConfiguration(balancer_.get(), route_config);
792  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
793  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
794  EXPECT_THAT(response_state->error_message,
796  "path matcher: Invalid regex string specified in matcher."));
797 }
798 
799 // Tests that LDS client should fail RPCs with UNAVAILABLE status code if the
800 // matching route has an action other than RouteAction.
801 TEST_P(LdsRdsTest, MatchingRouteHasNoRouteAction) {
802  RouteConfiguration route_config = default_route_config_;
803  // Set a route with an inappropriate route action
804  auto* vhost = route_config.mutable_virtual_hosts(0);
805  vhost->mutable_routes(0)->mutable_redirect();
806  // Add another route to make sure that the resolver code actually tries to
807  // match to a route instead of using a shorthand logic to error out.
808  auto* route = vhost->add_routes();
809  route->mutable_match()->set_prefix("");
810  route->mutable_route()->set_cluster(kDefaultClusterName);
811  SetRouteConfiguration(balancer_.get(), route_config);
812  CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
813  "Matching route has inappropriate action");
814 }
815 
816 TEST_P(LdsRdsTest, RouteActionClusterHasEmptyClusterName) {
817  RouteConfiguration route_config = default_route_config_;
818  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
819  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
820  route1->mutable_route()->set_cluster("");
821  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
822  default_route->mutable_match()->set_prefix("");
823  default_route->mutable_route()->set_cluster(kDefaultClusterName);
824  SetRouteConfiguration(balancer_.get(), route_config);
825  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
826  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
827  EXPECT_THAT(
828  response_state->error_message,
829  ::testing::HasSubstr("RouteAction cluster contains empty cluster name."));
830 }
831 
832 TEST_P(LdsRdsTest, RouteActionWeightedTargetHasIncorrectTotalWeightSet) {
833  const size_t kWeight75 = 75;
834  const char* kNewCluster1Name = "new_cluster_1";
835  RouteConfiguration route_config = default_route_config_;
836  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
837  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
838  auto* weighted_cluster1 =
839  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
840  weighted_cluster1->set_name(kNewCluster1Name);
841  weighted_cluster1->mutable_weight()->set_value(kWeight75);
842  route1->mutable_route()
843  ->mutable_weighted_clusters()
844  ->mutable_total_weight()
845  ->set_value(kWeight75 + 1);
846  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
847  default_route->mutable_match()->set_prefix("");
848  default_route->mutable_route()->set_cluster(kDefaultClusterName);
849  SetRouteConfiguration(balancer_.get(), route_config);
850  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
851  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
852  EXPECT_THAT(response_state->error_message,
854  "RouteAction weighted_cluster has incorrect total weight"));
855 }
856 
857 TEST_P(LdsRdsTest, RouteActionWeightedClusterHasZeroTotalWeight) {
858  const char* kNewCluster1Name = "new_cluster_1";
859  RouteConfiguration route_config = default_route_config_;
860  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
861  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
862  auto* weighted_cluster1 =
863  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
864  weighted_cluster1->set_name(kNewCluster1Name);
865  weighted_cluster1->mutable_weight()->set_value(0);
866  route1->mutable_route()
867  ->mutable_weighted_clusters()
868  ->mutable_total_weight()
869  ->set_value(0);
870  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
871  default_route->mutable_match()->set_prefix("");
872  default_route->mutable_route()->set_cluster(kDefaultClusterName);
873  SetRouteConfiguration(balancer_.get(), route_config);
874  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
875  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
876  EXPECT_THAT(
877  response_state->error_message,
879  "RouteAction weighted_cluster has no valid clusters specified."));
880 }
881 
882 TEST_P(LdsRdsTest, RouteActionWeightedTargetClusterHasEmptyClusterName) {
883  const size_t kWeight75 = 75;
884  RouteConfiguration route_config = default_route_config_;
885  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
886  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
887  auto* weighted_cluster1 =
888  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
889  weighted_cluster1->set_name("");
890  weighted_cluster1->mutable_weight()->set_value(kWeight75);
891  route1->mutable_route()
892  ->mutable_weighted_clusters()
893  ->mutable_total_weight()
894  ->set_value(kWeight75);
895  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
896  default_route->mutable_match()->set_prefix("");
897  default_route->mutable_route()->set_cluster(kDefaultClusterName);
898  SetRouteConfiguration(balancer_.get(), route_config);
899  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
900  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
901  EXPECT_THAT(response_state->error_message,
902  ::testing::HasSubstr("RouteAction weighted_cluster cluster "
903  "contains empty cluster name."));
904 }
905 
906 TEST_P(LdsRdsTest, RouteActionWeightedTargetClusterHasNoWeight) {
907  const size_t kWeight75 = 75;
908  const char* kNewCluster1Name = "new_cluster_1";
909  RouteConfiguration route_config = default_route_config_;
910  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
911  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
912  auto* weighted_cluster1 =
913  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
914  weighted_cluster1->set_name(kNewCluster1Name);
915  route1->mutable_route()
916  ->mutable_weighted_clusters()
917  ->mutable_total_weight()
918  ->set_value(kWeight75);
919  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
920  default_route->mutable_match()->set_prefix("");
921  default_route->mutable_route()->set_cluster(kDefaultClusterName);
922  SetRouteConfiguration(balancer_.get(), route_config);
923  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
924  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
925  EXPECT_THAT(response_state->error_message,
927  "RouteAction weighted_cluster cluster missing weight"));
928 }
929 
930 TEST_P(LdsRdsTest, RouteHeaderMatchInvalidRegex) {
931  const char* kNewCluster1Name = "new_cluster_1";
932  RouteConfiguration route_config = default_route_config_;
933  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
934  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
935  auto* header_matcher1 = route1->mutable_match()->add_headers();
936  header_matcher1->set_name("header1");
937  header_matcher1->mutable_safe_regex_match()->set_regex("a[z-a]");
938  route1->mutable_route()->set_cluster(kNewCluster1Name);
939  SetRouteConfiguration(balancer_.get(), route_config);
940  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
941  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
942  EXPECT_THAT(
943  response_state->error_message,
945  "header matcher: Invalid regex string specified in matcher."));
946 }
947 
948 TEST_P(LdsRdsTest, RouteHeaderMatchInvalidRange) {
949  const char* kNewCluster1Name = "new_cluster_1";
950  RouteConfiguration route_config = default_route_config_;
951  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
952  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
953  auto* header_matcher1 = route1->mutable_match()->add_headers();
954  header_matcher1->set_name("header1");
955  header_matcher1->mutable_range_match()->set_start(1001);
956  header_matcher1->mutable_range_match()->set_end(1000);
957  route1->mutable_route()->set_cluster(kNewCluster1Name);
958  SetRouteConfiguration(balancer_.get(), route_config);
959  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
960  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
961  EXPECT_THAT(
962  response_state->error_message,
964  "header matcher: Invalid range specifier specified: end cannot be "
965  "smaller than start."));
966 }
967 
968 // Tests that LDS client should choose the default route (with no matching
969 // specified) after unable to find a match with previous routes.
970 TEST_P(LdsRdsTest, XdsRoutingPathMatching) {
971  CreateAndStartBackends(4);
972  const char* kNewCluster1Name = "new_cluster_1";
973  const char* kNewEdsService1Name = "new_eds_service_name_1";
974  const char* kNewCluster2Name = "new_cluster_2";
975  const char* kNewEdsService2Name = "new_eds_service_name_2";
976  const size_t kNumEcho1Rpcs = 10;
977  const size_t kNumEcho2Rpcs = 20;
978  const size_t kNumEchoRpcs = 30;
979  // Populate new EDS resources.
980  EdsResourceArgs args({
981  {"locality0", CreateEndpointsForBackends(0, 2)},
982  });
983  EdsResourceArgs args1({
984  {"locality0", CreateEndpointsForBackends(2, 3)},
985  });
986  EdsResourceArgs args2({
987  {"locality0", CreateEndpointsForBackends(3, 4)},
988  });
989  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
990  balancer_->ads_service()->SetEdsResource(
991  BuildEdsResource(args1, kNewEdsService1Name));
992  balancer_->ads_service()->SetEdsResource(
993  BuildEdsResource(args2, kNewEdsService2Name));
994  // Populate new CDS resources.
995  Cluster new_cluster1 = default_cluster_;
996  new_cluster1.set_name(kNewCluster1Name);
997  new_cluster1.mutable_eds_cluster_config()->set_service_name(
998  kNewEdsService1Name);
999  balancer_->ads_service()->SetCdsResource(new_cluster1);
1000  Cluster new_cluster2 = default_cluster_;
1001  new_cluster2.set_name(kNewCluster2Name);
1002  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1003  kNewEdsService2Name);
1004  balancer_->ads_service()->SetCdsResource(new_cluster2);
1005  // Populating Route Configurations for LDS.
1006  RouteConfiguration new_route_config = default_route_config_;
1007  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1008  route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service/Echo1");
1009  route1->mutable_route()->set_cluster(kNewCluster1Name);
1010  auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1011  route2->mutable_match()->set_path("/grpc.testing.EchoTest2Service/Echo2");
1012  route2->mutable_route()->set_cluster(kNewCluster2Name);
1013  auto* route3 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1014  route3->mutable_match()->set_path("/grpc.testing.EchoTest3Service/Echo3");
1015  route3->mutable_route()->set_cluster(kDefaultClusterName);
1016  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1017  default_route->mutable_match()->set_prefix("");
1018  default_route->mutable_route()->set_cluster(kDefaultClusterName);
1019  SetRouteConfiguration(balancer_.get(), new_route_config);
1020  WaitForAllBackends(DEBUG_LOCATION, 0, 2);
1021  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
1022  RpcOptions().set_wait_for_ready(true));
1023  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
1024  RpcOptions()
1025  .set_rpc_service(SERVICE_ECHO1)
1026  .set_rpc_method(METHOD_ECHO1)
1027  .set_wait_for_ready(true));
1028  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho2Rpcs,
1029  RpcOptions()
1030  .set_rpc_service(SERVICE_ECHO2)
1031  .set_rpc_method(METHOD_ECHO2)
1032  .set_wait_for_ready(true));
1033  // Make sure RPCs all go to the correct backend.
1034  for (size_t i = 0; i < 2; ++i) {
1035  EXPECT_EQ(kNumEchoRpcs / 2,
1036  backends_[i]->backend_service()->request_count());
1037  EXPECT_EQ(0, backends_[i]->backend_service1()->request_count());
1038  EXPECT_EQ(0, backends_[i]->backend_service2()->request_count());
1039  }
1040  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1041  EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
1042  EXPECT_EQ(0, backends_[2]->backend_service2()->request_count());
1043  EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1044  EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1045  EXPECT_EQ(kNumEcho2Rpcs, backends_[3]->backend_service2()->request_count());
1046 }
1047 
1048 TEST_P(LdsRdsTest, XdsRoutingPathMatchingCaseInsensitive) {
1049  CreateAndStartBackends(4);
1050  const char* kNewCluster1Name = "new_cluster_1";
1051  const char* kNewEdsService1Name = "new_eds_service_name_1";
1052  const char* kNewCluster2Name = "new_cluster_2";
1053  const char* kNewEdsService2Name = "new_eds_service_name_2";
1054  const size_t kNumEcho1Rpcs = 10;
1055  const size_t kNumEchoRpcs = 30;
1056  // Populate new EDS resources.
1057  EdsResourceArgs args({
1058  {"locality0", CreateEndpointsForBackends(0, 1)},
1059  });
1060  EdsResourceArgs args1({
1061  {"locality0", CreateEndpointsForBackends(1, 2)},
1062  });
1063  EdsResourceArgs args2({
1064  {"locality0", CreateEndpointsForBackends(2, 3)},
1065  });
1066  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1067  balancer_->ads_service()->SetEdsResource(
1068  BuildEdsResource(args1, kNewEdsService1Name));
1069  balancer_->ads_service()->SetEdsResource(
1070  BuildEdsResource(args2, kNewEdsService2Name));
1071  // Populate new CDS resources.
1072  Cluster new_cluster1 = default_cluster_;
1073  new_cluster1.set_name(kNewCluster1Name);
1074  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1075  kNewEdsService1Name);
1076  balancer_->ads_service()->SetCdsResource(new_cluster1);
1077  Cluster new_cluster2 = default_cluster_;
1078  new_cluster2.set_name(kNewCluster2Name);
1079  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1080  kNewEdsService2Name);
1081  balancer_->ads_service()->SetCdsResource(new_cluster2);
1082  // Populating Route Configurations for LDS.
1083  RouteConfiguration new_route_config = default_route_config_;
1084  // First route will not match, since it's case-sensitive.
1085  // Second route will match with same path.
1086  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1087  route1->mutable_match()->set_path("/GrPc.TeStInG.EcHoTeSt1SErViCe/EcHo1");
1088  route1->mutable_route()->set_cluster(kNewCluster1Name);
1089  auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1090  route2->mutable_match()->set_path("/GrPc.TeStInG.EcHoTeSt1SErViCe/EcHo1");
1091  route2->mutable_match()->mutable_case_sensitive()->set_value(false);
1092  route2->mutable_route()->set_cluster(kNewCluster2Name);
1093  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1094  default_route->mutable_match()->set_prefix("");
1095  default_route->mutable_route()->set_cluster(kDefaultClusterName);
1096  SetRouteConfiguration(balancer_.get(), new_route_config);
1097  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
1098  RpcOptions().set_wait_for_ready(true));
1099  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
1100  RpcOptions()
1101  .set_rpc_service(SERVICE_ECHO1)
1102  .set_rpc_method(METHOD_ECHO1)
1103  .set_wait_for_ready(true));
1104  // Make sure RPCs all go to the correct backend.
1105  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1106  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1107  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1108  EXPECT_EQ(0, backends_[1]->backend_service1()->request_count());
1109  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1110  EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
1111 }
1112 
1113 TEST_P(LdsRdsTest, XdsRoutingPrefixMatching) {
1114  CreateAndStartBackends(4);
1115  const char* kNewCluster1Name = "new_cluster_1";
1116  const char* kNewEdsService1Name = "new_eds_service_name_1";
1117  const char* kNewCluster2Name = "new_cluster_2";
1118  const char* kNewEdsService2Name = "new_eds_service_name_2";
1119  const size_t kNumEcho1Rpcs = 10;
1120  const size_t kNumEcho2Rpcs = 20;
1121  const size_t kNumEchoRpcs = 30;
1122  // Populate new EDS resources.
1123  EdsResourceArgs args({
1124  {"locality0", CreateEndpointsForBackends(0, 2)},
1125  });
1126  EdsResourceArgs args1({
1127  {"locality0", CreateEndpointsForBackends(2, 3)},
1128  });
1129  EdsResourceArgs args2({
1130  {"locality0", CreateEndpointsForBackends(3, 4)},
1131  });
1132  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1133  balancer_->ads_service()->SetEdsResource(
1134  BuildEdsResource(args1, kNewEdsService1Name));
1135  balancer_->ads_service()->SetEdsResource(
1136  BuildEdsResource(args2, kNewEdsService2Name));
1137  // Populate new CDS resources.
1138  Cluster new_cluster1 = default_cluster_;
1139  new_cluster1.set_name(kNewCluster1Name);
1140  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1141  kNewEdsService1Name);
1142  balancer_->ads_service()->SetCdsResource(new_cluster1);
1143  Cluster new_cluster2 = default_cluster_;
1144  new_cluster2.set_name(kNewCluster2Name);
1145  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1146  kNewEdsService2Name);
1147  balancer_->ads_service()->SetCdsResource(new_cluster2);
1148  // Populating Route Configurations for LDS.
1149  RouteConfiguration new_route_config = default_route_config_;
1150  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1151  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
1152  route1->mutable_route()->set_cluster(kNewCluster1Name);
1153  auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1154  route2->mutable_match()->set_prefix("/grpc.testing.EchoTest2Service/");
1155  route2->mutable_route()->set_cluster(kNewCluster2Name);
1156  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1157  default_route->mutable_match()->set_prefix("");
1158  default_route->mutable_route()->set_cluster(kDefaultClusterName);
1159  SetRouteConfiguration(balancer_.get(), new_route_config);
1160  WaitForAllBackends(DEBUG_LOCATION, 0, 2);
1161  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
1162  RpcOptions().set_wait_for_ready(true));
1163  CheckRpcSendOk(
1164  DEBUG_LOCATION, kNumEcho1Rpcs,
1165  RpcOptions().set_rpc_service(SERVICE_ECHO1).set_wait_for_ready(true));
1166  CheckRpcSendOk(
1167  DEBUG_LOCATION, kNumEcho2Rpcs,
1168  RpcOptions().set_rpc_service(SERVICE_ECHO2).set_wait_for_ready(true));
1169  // Make sure RPCs all go to the correct backend.
1170  for (size_t i = 0; i < 2; ++i) {
1171  EXPECT_EQ(kNumEchoRpcs / 2,
1172  backends_[i]->backend_service()->request_count());
1173  EXPECT_EQ(0, backends_[i]->backend_service1()->request_count());
1174  EXPECT_EQ(0, backends_[i]->backend_service2()->request_count());
1175  }
1176  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1177  EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
1178  EXPECT_EQ(0, backends_[2]->backend_service2()->request_count());
1179  EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1180  EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1181  EXPECT_EQ(kNumEcho2Rpcs, backends_[3]->backend_service2()->request_count());
1182 }
1183 
1184 TEST_P(LdsRdsTest, XdsRoutingPrefixMatchingCaseInsensitive) {
1185  CreateAndStartBackends(3);
1186  const char* kNewCluster1Name = "new_cluster_1";
1187  const char* kNewEdsService1Name = "new_eds_service_name_1";
1188  const char* kNewCluster2Name = "new_cluster_2";
1189  const char* kNewEdsService2Name = "new_eds_service_name_2";
1190  const size_t kNumEcho1Rpcs = 10;
1191  const size_t kNumEchoRpcs = 30;
1192  // Populate new EDS resources.
1193  EdsResourceArgs args({
1194  {"locality0", CreateEndpointsForBackends(0, 1)},
1195  });
1196  EdsResourceArgs args1({
1197  {"locality0", CreateEndpointsForBackends(1, 2)},
1198  });
1199  EdsResourceArgs args2({
1200  {"locality0", CreateEndpointsForBackends(2, 3)},
1201  });
1202  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1203  balancer_->ads_service()->SetEdsResource(
1204  BuildEdsResource(args1, kNewEdsService1Name));
1205  balancer_->ads_service()->SetEdsResource(
1206  BuildEdsResource(args2, kNewEdsService2Name));
1207  // Populate new CDS resources.
1208  Cluster new_cluster1 = default_cluster_;
1209  new_cluster1.set_name(kNewCluster1Name);
1210  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1211  kNewEdsService1Name);
1212  balancer_->ads_service()->SetCdsResource(new_cluster1);
1213  Cluster new_cluster2 = default_cluster_;
1214  new_cluster2.set_name(kNewCluster2Name);
1215  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1216  kNewEdsService2Name);
1217  balancer_->ads_service()->SetCdsResource(new_cluster2);
1218  // Populating Route Configurations for LDS.
1219  RouteConfiguration new_route_config = default_route_config_;
1220  // First route will not match, since it's case-sensitive.
1221  // Second route will match with same path.
1222  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1223  route1->mutable_match()->set_prefix("/GrPc.TeStInG.EcHoTeSt1SErViCe");
1224  route1->mutable_route()->set_cluster(kNewCluster1Name);
1225  auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1226  route2->mutable_match()->set_prefix("/GrPc.TeStInG.EcHoTeSt1SErViCe");
1227  route2->mutable_match()->mutable_case_sensitive()->set_value(false);
1228  route2->mutable_route()->set_cluster(kNewCluster2Name);
1229  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1230  default_route->mutable_match()->set_prefix("");
1231  default_route->mutable_route()->set_cluster(kDefaultClusterName);
1232  SetRouteConfiguration(balancer_.get(), new_route_config);
1233  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
1234  RpcOptions().set_wait_for_ready(true));
1235  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
1236  RpcOptions()
1237  .set_rpc_service(SERVICE_ECHO1)
1238  .set_rpc_method(METHOD_ECHO1)
1239  .set_wait_for_ready(true));
1240  // Make sure RPCs all go to the correct backend.
1241  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1242  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1243  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1244  EXPECT_EQ(0, backends_[1]->backend_service1()->request_count());
1245  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1246  EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
1247 }
1248 
1249 TEST_P(LdsRdsTest, XdsRoutingPathRegexMatching) {
1250  CreateAndStartBackends(4);
1251  const char* kNewCluster1Name = "new_cluster_1";
1252  const char* kNewEdsService1Name = "new_eds_service_name_1";
1253  const char* kNewCluster2Name = "new_cluster_2";
1254  const char* kNewEdsService2Name = "new_eds_service_name_2";
1255  const size_t kNumEcho1Rpcs = 10;
1256  const size_t kNumEcho2Rpcs = 20;
1257  const size_t kNumEchoRpcs = 30;
1258  // Populate new EDS resources.
1259  EdsResourceArgs args({
1260  {"locality0", CreateEndpointsForBackends(0, 2)},
1261  });
1262  EdsResourceArgs args1({
1263  {"locality0", CreateEndpointsForBackends(2, 3)},
1264  });
1265  EdsResourceArgs args2({
1266  {"locality0", CreateEndpointsForBackends(3, 4)},
1267  });
1268  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1269  balancer_->ads_service()->SetEdsResource(
1270  BuildEdsResource(args1, kNewEdsService1Name));
1271  balancer_->ads_service()->SetEdsResource(
1272  BuildEdsResource(args2, kNewEdsService2Name));
1273  // Populate new CDS resources.
1274  Cluster new_cluster1 = default_cluster_;
1275  new_cluster1.set_name(kNewCluster1Name);
1276  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1277  kNewEdsService1Name);
1278  balancer_->ads_service()->SetCdsResource(new_cluster1);
1279  Cluster new_cluster2 = default_cluster_;
1280  new_cluster2.set_name(kNewCluster2Name);
1281  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1282  kNewEdsService2Name);
1283  balancer_->ads_service()->SetCdsResource(new_cluster2);
1284  // Populating Route Configurations for LDS.
1285  RouteConfiguration new_route_config = default_route_config_;
1286  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1287  // Will match "/grpc.testing.EchoTest1Service/"
1288  route1->mutable_match()->mutable_safe_regex()->set_regex(".*1.*");
1289  route1->mutable_route()->set_cluster(kNewCluster1Name);
1290  auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1291  // Will match "/grpc.testing.EchoTest2Service/"
1292  route2->mutable_match()->mutable_safe_regex()->set_regex(".*2.*");
1293  route2->mutable_route()->set_cluster(kNewCluster2Name);
1294  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1295  default_route->mutable_match()->set_prefix("");
1296  default_route->mutable_route()->set_cluster(kDefaultClusterName);
1297  SetRouteConfiguration(balancer_.get(), new_route_config);
1298  WaitForAllBackends(DEBUG_LOCATION, 0, 2);
1299  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
1300  RpcOptions().set_wait_for_ready(true));
1301  CheckRpcSendOk(
1302  DEBUG_LOCATION, kNumEcho1Rpcs,
1303  RpcOptions().set_rpc_service(SERVICE_ECHO1).set_wait_for_ready(true));
1304  CheckRpcSendOk(
1305  DEBUG_LOCATION, kNumEcho2Rpcs,
1306  RpcOptions().set_rpc_service(SERVICE_ECHO2).set_wait_for_ready(true));
1307  // Make sure RPCs all go to the correct backend.
1308  for (size_t i = 0; i < 2; ++i) {
1309  EXPECT_EQ(kNumEchoRpcs / 2,
1310  backends_[i]->backend_service()->request_count());
1311  EXPECT_EQ(0, backends_[i]->backend_service1()->request_count());
1312  EXPECT_EQ(0, backends_[i]->backend_service2()->request_count());
1313  }
1314  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1315  EXPECT_EQ(kNumEcho1Rpcs, backends_[2]->backend_service1()->request_count());
1316  EXPECT_EQ(0, backends_[2]->backend_service2()->request_count());
1317  EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1318  EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1319  EXPECT_EQ(kNumEcho2Rpcs, backends_[3]->backend_service2()->request_count());
1320 }
1321 
1322 TEST_P(LdsRdsTest, XdsRoutingWeightedCluster) {
1323  CreateAndStartBackends(3);
1324  const char* kNewCluster1Name = "new_cluster_1";
1325  const char* kNewEdsService1Name = "new_eds_service_name_1";
1326  const char* kNewCluster2Name = "new_cluster_2";
1327  const char* kNewEdsService2Name = "new_eds_service_name_2";
1328  const char* kNotUsedClusterName = "not_used_cluster";
1329  const size_t kNumEchoRpcs = 10; // RPCs that will go to a fixed backend.
1330  const size_t kWeight75 = 75;
1331  const size_t kWeight25 = 25;
1332  const double kErrorTolerance = 0.05;
1333  const double kWeight75Percent = static_cast<double>(kWeight75) / 100;
1334  const double kWeight25Percent = static_cast<double>(kWeight25) / 100;
1335  const size_t kNumEcho1Rpcs =
1336  ComputeIdealNumRpcs(kWeight75Percent, kErrorTolerance);
1337  // Populate new EDS resources.
1338  EdsResourceArgs args({
1339  {"locality0", CreateEndpointsForBackends(0, 1)},
1340  });
1341  EdsResourceArgs args1({
1342  {"locality0", CreateEndpointsForBackends(1, 2)},
1343  });
1344  EdsResourceArgs args2({
1345  {"locality0", CreateEndpointsForBackends(2, 3)},
1346  });
1347  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1348  balancer_->ads_service()->SetEdsResource(
1349  BuildEdsResource(args1, kNewEdsService1Name));
1350  balancer_->ads_service()->SetEdsResource(
1351  BuildEdsResource(args2, kNewEdsService2Name));
1352  // Populate new CDS resources.
1353  Cluster new_cluster1 = default_cluster_;
1354  new_cluster1.set_name(kNewCluster1Name);
1355  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1356  kNewEdsService1Name);
1357  balancer_->ads_service()->SetCdsResource(new_cluster1);
1358  Cluster new_cluster2 = default_cluster_;
1359  new_cluster2.set_name(kNewCluster2Name);
1360  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1361  kNewEdsService2Name);
1362  balancer_->ads_service()->SetCdsResource(new_cluster2);
1363  // Populating Route Configurations for LDS.
1364  RouteConfiguration new_route_config = default_route_config_;
1365  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1366  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
1367  auto* weighted_cluster1 =
1368  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1369  weighted_cluster1->set_name(kNewCluster1Name);
1370  weighted_cluster1->mutable_weight()->set_value(kWeight75);
1371  auto* weighted_cluster2 =
1372  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1373  weighted_cluster2->set_name(kNewCluster2Name);
1374  weighted_cluster2->mutable_weight()->set_value(kWeight25);
1375  // Cluster with weight 0 will not be used.
1376  auto* weighted_cluster3 =
1377  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1378  weighted_cluster3->set_name(kNotUsedClusterName);
1379  weighted_cluster3->mutable_weight()->set_value(0);
1380  route1->mutable_route()
1381  ->mutable_weighted_clusters()
1382  ->mutable_total_weight()
1383  ->set_value(kWeight75 + kWeight25);
1384  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1385  default_route->mutable_match()->set_prefix("");
1386  default_route->mutable_route()->set_cluster(kDefaultClusterName);
1387  SetRouteConfiguration(balancer_.get(), new_route_config);
1388  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
1389  WaitForAllBackends(DEBUG_LOCATION, 1, 3, /*check_status=*/nullptr,
1390  WaitForBackendOptions(),
1391  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1392  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1393  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
1394  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1395  // Make sure RPCs all go to the correct backend.
1396  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1397  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1398  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1399  const int weight_75_request_count =
1400  backends_[1]->backend_service1()->request_count();
1401  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1402  const int weight_25_request_count =
1403  backends_[2]->backend_service1()->request_count();
1404  gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1405  weight_75_request_count, weight_25_request_count);
1406  EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEcho1Rpcs,
1407  ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1408  EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEcho1Rpcs,
1409  ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1410 }
1411 
1412 TEST_P(LdsRdsTest, RouteActionWeightedTargetDefaultRoute) {
1413  CreateAndStartBackends(3);
1414  const char* kNewCluster1Name = "new_cluster_1";
1415  const char* kNewEdsService1Name = "new_eds_service_name_1";
1416  const char* kNewCluster2Name = "new_cluster_2";
1417  const char* kNewEdsService2Name = "new_eds_service_name_2";
1418  const size_t kWeight75 = 75;
1419  const size_t kWeight25 = 25;
1420  const double kErrorTolerance = 0.05;
1421  const double kWeight75Percent = static_cast<double>(kWeight75) / 100;
1422  const double kWeight25Percent = static_cast<double>(kWeight25) / 100;
1423  const size_t kNumEchoRpcs =
1424  ComputeIdealNumRpcs(kWeight75Percent, kErrorTolerance);
1425  // Populate new EDS resources.
1426  EdsResourceArgs args({
1427  {"locality0", CreateEndpointsForBackends(0, 1)},
1428  });
1429  EdsResourceArgs args1({
1430  {"locality0", CreateEndpointsForBackends(1, 2)},
1431  });
1432  EdsResourceArgs args2({
1433  {"locality0", CreateEndpointsForBackends(2, 3)},
1434  });
1435  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1436  balancer_->ads_service()->SetEdsResource(
1437  BuildEdsResource(args1, kNewEdsService1Name));
1438  balancer_->ads_service()->SetEdsResource(
1439  BuildEdsResource(args2, kNewEdsService2Name));
1440  // Populate new CDS resources.
1441  Cluster new_cluster1 = default_cluster_;
1442  new_cluster1.set_name(kNewCluster1Name);
1443  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1444  kNewEdsService1Name);
1445  balancer_->ads_service()->SetCdsResource(new_cluster1);
1446  Cluster new_cluster2 = default_cluster_;
1447  new_cluster2.set_name(kNewCluster2Name);
1448  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1449  kNewEdsService2Name);
1450  balancer_->ads_service()->SetCdsResource(new_cluster2);
1451  // Populating Route Configurations for LDS.
1452  RouteConfiguration new_route_config = default_route_config_;
1453  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1454  route1->mutable_match()->set_prefix("");
1455  auto* weighted_cluster1 =
1456  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1457  weighted_cluster1->set_name(kNewCluster1Name);
1458  weighted_cluster1->mutable_weight()->set_value(kWeight75);
1459  auto* weighted_cluster2 =
1460  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1461  weighted_cluster2->set_name(kNewCluster2Name);
1462  weighted_cluster2->mutable_weight()->set_value(kWeight25);
1463  route1->mutable_route()
1464  ->mutable_weighted_clusters()
1465  ->mutable_total_weight()
1466  ->set_value(kWeight75 + kWeight25);
1467  SetRouteConfiguration(balancer_.get(), new_route_config);
1468  WaitForAllBackends(DEBUG_LOCATION, 1, 3);
1469  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1470  // Make sure RPCs all go to the correct backend.
1471  EXPECT_EQ(0, backends_[0]->backend_service()->request_count());
1472  const int weight_75_request_count =
1473  backends_[1]->backend_service()->request_count();
1474  const int weight_25_request_count =
1475  backends_[2]->backend_service()->request_count();
1476  gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1477  weight_75_request_count, weight_25_request_count);
1478  EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEchoRpcs,
1479  ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1480  EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEchoRpcs,
1481  ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1482 }
1483 
1484 TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateWeights) {
1485  CreateAndStartBackends(4);
1486  const char* kNewCluster1Name = "new_cluster_1";
1487  const char* kNewEdsService1Name = "new_eds_service_name_1";
1488  const char* kNewCluster2Name = "new_cluster_2";
1489  const char* kNewEdsService2Name = "new_eds_service_name_2";
1490  const char* kNewCluster3Name = "new_cluster_3";
1491  const char* kNewEdsService3Name = "new_eds_service_name_3";
1492  const size_t kNumEchoRpcs = 10;
1493  const size_t kWeight75 = 75;
1494  const size_t kWeight25 = 25;
1495  const size_t kWeight50 = 50;
1496  const double kErrorTolerance = 0.05;
1497  const double kWeight75Percent = static_cast<double>(kWeight75) / 100;
1498  const double kWeight25Percent = static_cast<double>(kWeight25) / 100;
1499  const double kWeight50Percent = static_cast<double>(kWeight50) / 100;
1500  const size_t kNumEcho1Rpcs7525 =
1501  ComputeIdealNumRpcs(kWeight75Percent, kErrorTolerance);
1502  const size_t kNumEcho1Rpcs5050 =
1503  ComputeIdealNumRpcs(kWeight50Percent, kErrorTolerance);
1504  // Populate new EDS resources.
1505  EdsResourceArgs args({
1506  {"locality0", CreateEndpointsForBackends(0, 1)},
1507  });
1508  EdsResourceArgs args1({
1509  {"locality0", CreateEndpointsForBackends(1, 2)},
1510  });
1511  EdsResourceArgs args2({
1512  {"locality0", CreateEndpointsForBackends(2, 3)},
1513  });
1514  EdsResourceArgs args3({
1515  {"locality0", CreateEndpointsForBackends(3, 4)},
1516  });
1517  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1518  balancer_->ads_service()->SetEdsResource(
1519  BuildEdsResource(args1, kNewEdsService1Name));
1520  balancer_->ads_service()->SetEdsResource(
1521  BuildEdsResource(args2, kNewEdsService2Name));
1522  balancer_->ads_service()->SetEdsResource(
1523  BuildEdsResource(args3, kNewEdsService3Name));
1524  // Populate new CDS resources.
1525  Cluster new_cluster1 = default_cluster_;
1526  new_cluster1.set_name(kNewCluster1Name);
1527  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1528  kNewEdsService1Name);
1529  balancer_->ads_service()->SetCdsResource(new_cluster1);
1530  Cluster new_cluster2 = default_cluster_;
1531  new_cluster2.set_name(kNewCluster2Name);
1532  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1533  kNewEdsService2Name);
1534  balancer_->ads_service()->SetCdsResource(new_cluster2);
1535  Cluster new_cluster3 = default_cluster_;
1536  new_cluster3.set_name(kNewCluster3Name);
1537  new_cluster3.mutable_eds_cluster_config()->set_service_name(
1538  kNewEdsService3Name);
1539  balancer_->ads_service()->SetCdsResource(new_cluster3);
1540  // Populating Route Configurations.
1541  RouteConfiguration new_route_config = default_route_config_;
1542  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1543  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
1544  auto* weighted_cluster1 =
1545  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1546  weighted_cluster1->set_name(kNewCluster1Name);
1547  weighted_cluster1->mutable_weight()->set_value(kWeight75);
1548  auto* weighted_cluster2 =
1549  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1550  weighted_cluster2->set_name(kNewCluster2Name);
1551  weighted_cluster2->mutable_weight()->set_value(kWeight25);
1552  route1->mutable_route()
1553  ->mutable_weighted_clusters()
1554  ->mutable_total_weight()
1555  ->set_value(kWeight75 + kWeight25);
1556  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1557  default_route->mutable_match()->set_prefix("");
1558  default_route->mutable_route()->set_cluster(kDefaultClusterName);
1559  SetRouteConfiguration(balancer_.get(), new_route_config);
1560  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
1561  WaitForAllBackends(DEBUG_LOCATION, 1, 3, /*check_status=*/nullptr,
1562  WaitForBackendOptions(),
1563  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1564  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1565  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs7525,
1566  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1567  // Make sure RPCs all go to the correct backend.
1568  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1569  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1570  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1571  const int weight_75_request_count =
1572  backends_[1]->backend_service1()->request_count();
1573  EXPECT_EQ(0, backends_[1]->backend_service2()->request_count());
1574  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1575  const int weight_25_request_count =
1576  backends_[2]->backend_service1()->request_count();
1577  EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1578  EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1579  gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1580  weight_75_request_count, weight_25_request_count);
1581  EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEcho1Rpcs7525,
1582  ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1583  EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEcho1Rpcs7525,
1584  ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1585  // Change Route Configurations: same clusters different weights.
1586  weighted_cluster1->mutable_weight()->set_value(kWeight50);
1587  weighted_cluster2->mutable_weight()->set_value(kWeight50);
1588  // Change default route to a new cluster to help to identify when new
1589  // polices are seen by the client.
1590  default_route->mutable_route()->set_cluster(kNewCluster3Name);
1591  SetRouteConfiguration(balancer_.get(), new_route_config);
1592  ResetBackendCounters();
1593  WaitForAllBackends(DEBUG_LOCATION, 3, 4);
1594  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1595  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs5050,
1596  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1597  // Make sure RPCs all go to the correct backend.
1598  EXPECT_EQ(0, backends_[0]->backend_service()->request_count());
1599  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1600  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1601  const int weight_50_request_count_1 =
1602  backends_[1]->backend_service1()->request_count();
1603  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1604  const int weight_50_request_count_2 =
1605  backends_[2]->backend_service1()->request_count();
1606  EXPECT_EQ(kNumEchoRpcs, backends_[3]->backend_service()->request_count());
1607  EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1608  EXPECT_THAT(
1609  static_cast<double>(weight_50_request_count_1) / kNumEcho1Rpcs5050,
1610  ::testing::DoubleNear(kWeight50Percent, kErrorTolerance));
1611  EXPECT_THAT(
1612  static_cast<double>(weight_50_request_count_2) / kNumEcho1Rpcs5050,
1613  ::testing::DoubleNear(kWeight50Percent, kErrorTolerance));
1614 }
1615 
1616 TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateClusters) {
1617  CreateAndStartBackends(4);
1618  const char* kNewCluster1Name = "new_cluster_1";
1619  const char* kNewEdsService1Name = "new_eds_service_name_1";
1620  const char* kNewCluster2Name = "new_cluster_2";
1621  const char* kNewEdsService2Name = "new_eds_service_name_2";
1622  const char* kNewCluster3Name = "new_cluster_3";
1623  const char* kNewEdsService3Name = "new_eds_service_name_3";
1624  const size_t kNumEchoRpcs = 10;
1625  const size_t kWeight75 = 75;
1626  const size_t kWeight25 = 25;
1627  const size_t kWeight50 = 50;
1628  const double kErrorTolerance = 0.05;
1629  const double kWeight75Percent = static_cast<double>(kWeight75) / 100;
1630  const double kWeight25Percent = static_cast<double>(kWeight25) / 100;
1631  const double kWeight50Percent = static_cast<double>(kWeight50) / 100;
1632  const size_t kNumEcho1Rpcs7525 =
1633  ComputeIdealNumRpcs(kWeight75Percent, kErrorTolerance);
1634  const size_t kNumEcho1Rpcs5050 =
1635  ComputeIdealNumRpcs(kWeight50Percent, kErrorTolerance);
1636  // Populate new EDS resources.
1637  EdsResourceArgs args({
1638  {"locality0", CreateEndpointsForBackends(0, 1)},
1639  });
1640  EdsResourceArgs args1({
1641  {"locality0", CreateEndpointsForBackends(1, 2)},
1642  });
1643  EdsResourceArgs args2({
1644  {"locality0", CreateEndpointsForBackends(2, 3)},
1645  });
1646  EdsResourceArgs args3({
1647  {"locality0", CreateEndpointsForBackends(3, 4)},
1648  });
1649  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1650  balancer_->ads_service()->SetEdsResource(
1651  BuildEdsResource(args1, kNewEdsService1Name));
1652  balancer_->ads_service()->SetEdsResource(
1653  BuildEdsResource(args2, kNewEdsService2Name));
1654  balancer_->ads_service()->SetEdsResource(
1655  BuildEdsResource(args3, kNewEdsService3Name));
1656  // Populate new CDS resources.
1657  Cluster new_cluster1 = default_cluster_;
1658  new_cluster1.set_name(kNewCluster1Name);
1659  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1660  kNewEdsService1Name);
1661  balancer_->ads_service()->SetCdsResource(new_cluster1);
1662  Cluster new_cluster2 = default_cluster_;
1663  new_cluster2.set_name(kNewCluster2Name);
1664  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1665  kNewEdsService2Name);
1666  balancer_->ads_service()->SetCdsResource(new_cluster2);
1667  Cluster new_cluster3 = default_cluster_;
1668  new_cluster3.set_name(kNewCluster3Name);
1669  new_cluster3.mutable_eds_cluster_config()->set_service_name(
1670  kNewEdsService3Name);
1671  balancer_->ads_service()->SetCdsResource(new_cluster3);
1672  // Populating Route Configurations.
1673  RouteConfiguration new_route_config = default_route_config_;
1674  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1675  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
1676  auto* weighted_cluster1 =
1677  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1678  weighted_cluster1->set_name(kNewCluster1Name);
1679  weighted_cluster1->mutable_weight()->set_value(kWeight75);
1680  auto* weighted_cluster2 =
1681  route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
1682  weighted_cluster2->set_name(kDefaultClusterName);
1683  weighted_cluster2->mutable_weight()->set_value(kWeight25);
1684  route1->mutable_route()
1685  ->mutable_weighted_clusters()
1686  ->mutable_total_weight()
1687  ->set_value(kWeight75 + kWeight25);
1688  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
1689  default_route->mutable_match()->set_prefix("");
1690  default_route->mutable_route()->set_cluster(kDefaultClusterName);
1691  SetRouteConfiguration(balancer_.get(), new_route_config);
1692  WaitForBackend(DEBUG_LOCATION, 0);
1693  WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
1694  WaitForBackendOptions(),
1695  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1696  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1697  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs7525,
1698  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1699  // Make sure RPCs all go to the correct backend.
1700  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1701  int weight_25_request_count =
1702  backends_[0]->backend_service1()->request_count();
1703  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1704  int weight_75_request_count =
1705  backends_[1]->backend_service1()->request_count();
1706  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1707  EXPECT_EQ(0, backends_[2]->backend_service1()->request_count());
1708  EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1709  EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1710  gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1711  weight_75_request_count, weight_25_request_count);
1712  EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEcho1Rpcs7525,
1713  ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1714  EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEcho1Rpcs7525,
1715  ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1716  // Change Route Configurations: new set of clusters with different weights.
1717  weighted_cluster1->mutable_weight()->set_value(kWeight50);
1718  weighted_cluster2->set_name(kNewCluster2Name);
1719  weighted_cluster2->mutable_weight()->set_value(kWeight50);
1720  SetRouteConfiguration(balancer_.get(), new_route_config);
1721  ResetBackendCounters();
1722  WaitForBackend(DEBUG_LOCATION, 2, /*check_status=*/nullptr,
1723  WaitForBackendOptions(),
1724  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1725  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1726  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs5050,
1727  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1728  // Make sure RPCs all go to the correct backend.
1729  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1730  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1731  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1732  const int weight_50_request_count_1 =
1733  backends_[1]->backend_service1()->request_count();
1734  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1735  const int weight_50_request_count_2 =
1736  backends_[2]->backend_service1()->request_count();
1737  EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1738  EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
1739  EXPECT_THAT(
1740  static_cast<double>(weight_50_request_count_1) / kNumEcho1Rpcs5050,
1741  ::testing::DoubleNear(kWeight50Percent, kErrorTolerance));
1742  EXPECT_THAT(
1743  static_cast<double>(weight_50_request_count_2) / kNumEcho1Rpcs5050,
1744  ::testing::DoubleNear(kWeight50Percent, kErrorTolerance));
1745  // Change Route Configurations.
1746  weighted_cluster1->mutable_weight()->set_value(kWeight75);
1747  weighted_cluster2->set_name(kNewCluster3Name);
1748  weighted_cluster2->mutable_weight()->set_value(kWeight25);
1749  SetRouteConfiguration(balancer_.get(), new_route_config);
1750  ResetBackendCounters();
1751  WaitForBackend(DEBUG_LOCATION, 3, /*check_status=*/nullptr,
1752  WaitForBackendOptions(),
1753  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1754  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1755  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs7525,
1756  RpcOptions().set_rpc_service(SERVICE_ECHO1));
1757  // Make sure RPCs all go to the correct backend.
1758  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1759  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
1760  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
1761  weight_75_request_count = backends_[1]->backend_service1()->request_count();
1762  EXPECT_EQ(0, backends_[2]->backend_service()->request_count());
1763  EXPECT_EQ(0, backends_[2]->backend_service1()->request_count());
1764  EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
1765  weight_25_request_count = backends_[3]->backend_service1()->request_count();
1766  gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
1767  weight_75_request_count, weight_25_request_count);
1768  EXPECT_THAT(static_cast<double>(weight_75_request_count) / kNumEcho1Rpcs7525,
1769  ::testing::DoubleNear(kWeight75Percent, kErrorTolerance));
1770  EXPECT_THAT(static_cast<double>(weight_25_request_count) / kNumEcho1Rpcs7525,
1771  ::testing::DoubleNear(kWeight25Percent, kErrorTolerance));
1772 }
1773 
1774 TEST_P(LdsRdsTest, XdsRoutingClusterUpdateClusters) {
1775  CreateAndStartBackends(2);
1776  const char* kNewClusterName = "new_cluster";
1777  const char* kNewEdsServiceName = "new_eds_service_name";
1778  const size_t kNumEchoRpcs = 5;
1779  // Populate new EDS resources.
1780  EdsResourceArgs args({
1781  {"locality0", CreateEndpointsForBackends(0, 1)},
1782  });
1783  EdsResourceArgs args1({
1784  {"locality0", CreateEndpointsForBackends(1, 2)},
1785  });
1786  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1787  balancer_->ads_service()->SetEdsResource(
1788  BuildEdsResource(args1, kNewEdsServiceName));
1789  // Populate new CDS resources.
1790  Cluster new_cluster = default_cluster_;
1791  new_cluster.set_name(kNewClusterName);
1792  new_cluster.mutable_eds_cluster_config()->set_service_name(
1793  kNewEdsServiceName);
1794  balancer_->ads_service()->SetCdsResource(new_cluster);
1795  // Send Route Configuration.
1796  RouteConfiguration new_route_config = default_route_config_;
1797  SetRouteConfiguration(balancer_.get(), new_route_config);
1798  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
1799  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1800  // Make sure RPCs all go to the correct backend.
1801  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
1802  // Change Route Configurations: new default cluster.
1803  auto* default_route =
1804  new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1805  default_route->mutable_route()->set_cluster(kNewClusterName);
1806  SetRouteConfiguration(balancer_.get(), new_route_config);
1807  WaitForAllBackends(DEBUG_LOCATION, 1, 2);
1808  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
1809  // Make sure RPCs all go to the correct backend.
1810  EXPECT_EQ(kNumEchoRpcs, backends_[1]->backend_service()->request_count());
1811 }
1812 
1813 TEST_P(LdsRdsTest, XdsRoutingClusterUpdateClustersWithPickingDelays) {
1814  // Start with only backend 1 up, but the default cluster pointing to
1815  // backend 0, which is down.
1816  CreateBackends(2);
1817  StartBackend(1);
1818  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
1819  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1820  // Start an RPC with wait_for_ready=true and no deadline. This will
1821  // stay pending until backend 0 is reachable.
1822  LongRunningRpc rpc;
1823  rpc.StartRpc(stub_.get(),
1824  RpcOptions().set_wait_for_ready(true).set_timeout_ms(0));
1825  // Send a non-wait_for_ready RPC, which should fail. This tells us
1826  // that the client has received the update and attempted to connect.
1827  constexpr char kErrorMessageRegex[] =
1828  "connections to all backends failing; last error: "
1829  "(UNKNOWN: Failed to connect to remote host: Connection refused|"
1830  "UNAVAILABLE: Failed to connect to remote host: FD shutdown)";
1831  CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
1832  kErrorMessageRegex);
1833  // Now create a new cluster, pointing to backend 1.
1834  const char* kNewClusterName = "new_cluster";
1835  const char* kNewEdsServiceName = "new_eds_service_name";
1836  EdsResourceArgs args1({{"locality0", CreateEndpointsForBackends(1, 2)}});
1837  balancer_->ads_service()->SetEdsResource(
1838  BuildEdsResource(args1, kNewEdsServiceName));
1839  // Populate new CDS resources.
1840  Cluster new_cluster = default_cluster_;
1841  new_cluster.set_name(kNewClusterName);
1842  new_cluster.mutable_eds_cluster_config()->set_service_name(
1843  kNewEdsServiceName);
1844  balancer_->ads_service()->SetCdsResource(new_cluster);
1845  // Send a update RouteConfiguration to use backend 1.
1846  RouteConfiguration new_route_config = default_route_config_;
1847  auto* default_route =
1848  new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1849  default_route->mutable_route()->set_cluster(kNewClusterName);
1850  SetRouteConfiguration(balancer_.get(), new_route_config);
1851  // Wait for RPCs to go to the new backend: 1, this ensures that the client
1852  // has processed the update.
1853  WaitForBackend(
1854  DEBUG_LOCATION, 1,
1855  [&](const RpcResult& result) {
1856  if (!result.status.ok()) {
1857  EXPECT_EQ(result.status.error_code(), StatusCode::UNAVAILABLE);
1858  EXPECT_THAT(result.status.error_message(),
1859  ::testing::MatchesRegex(kErrorMessageRegex));
1860  }
1861  },
1862  WaitForBackendOptions().set_reset_counters(false));
1863  // Bring up the backend 0. Yhis will allow the delayed RPC to finally
1864  // complete.
1865  StartBackend(0);
1866  Status status = rpc.GetStatus();
1867  EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
1868  << " message=" << status.error_message();
1869  // Make sure RPCs went to the correct backends.
1870  EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
1871  EXPECT_EQ(1, backends_[1]->backend_service()->request_count());
1872 }
1873 
1874 TEST_P(LdsRdsTest, XdsRoutingApplyXdsTimeout) {
1875  const int64_t kTimeoutMillis = 500;
1876  const int64_t kTimeoutNano = kTimeoutMillis * 1000000;
1877  const int64_t kTimeoutGrpcTimeoutHeaderMaxSecond = 1;
1878  const int64_t kTimeoutMaxStreamDurationSecond = 2;
1879  const int64_t kTimeoutHttpMaxStreamDurationSecond = 3;
1880  const int64_t kTimeoutApplicationSecond = 4;
1881  const char* kNewCluster1Name = "new_cluster_1";
1882  const char* kNewEdsService1Name = "new_eds_service_name_1";
1883  const char* kNewCluster2Name = "new_cluster_2";
1884  const char* kNewEdsService2Name = "new_eds_service_name_2";
1885  const char* kNewCluster3Name = "new_cluster_3";
1886  const char* kNewEdsService3Name = "new_eds_service_name_3";
1887  // Populate new EDS resources.
1888  EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
1889  EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}});
1890  EdsResourceArgs args2({{"locality0", {MakeNonExistantEndpoint()}}});
1891  EdsResourceArgs args3({{"locality0", {MakeNonExistantEndpoint()}}});
1892  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1893  balancer_->ads_service()->SetEdsResource(
1894  BuildEdsResource(args1, kNewEdsService1Name));
1895  balancer_->ads_service()->SetEdsResource(
1896  BuildEdsResource(args2, kNewEdsService2Name));
1897  balancer_->ads_service()->SetEdsResource(
1898  BuildEdsResource(args3, kNewEdsService3Name));
1899  // Populate new CDS resources.
1900  Cluster new_cluster1 = default_cluster_;
1901  new_cluster1.set_name(kNewCluster1Name);
1902  new_cluster1.mutable_eds_cluster_config()->set_service_name(
1903  kNewEdsService1Name);
1904  balancer_->ads_service()->SetCdsResource(new_cluster1);
1905  Cluster new_cluster2 = default_cluster_;
1906  new_cluster2.set_name(kNewCluster2Name);
1907  new_cluster2.mutable_eds_cluster_config()->set_service_name(
1908  kNewEdsService2Name);
1909  balancer_->ads_service()->SetCdsResource(new_cluster2);
1910  Cluster new_cluster3 = default_cluster_;
1911  new_cluster3.set_name(kNewCluster3Name);
1912  new_cluster3.mutable_eds_cluster_config()->set_service_name(
1913  kNewEdsService3Name);
1914  balancer_->ads_service()->SetCdsResource(new_cluster3);
1915  // Construct listener.
1916  auto listener = default_listener_;
1917  HttpConnectionManager http_connection_manager;
1918  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
1919  &http_connection_manager);
1920  // Set up HTTP max_stream_duration of 3.5 seconds
1921  auto* duration =
1922  http_connection_manager.mutable_common_http_protocol_options()
1923  ->mutable_max_stream_duration();
1924  duration->set_seconds(kTimeoutHttpMaxStreamDurationSecond);
1925  duration->set_nanos(kTimeoutNano);
1926  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
1927  http_connection_manager);
1928  // Construct route config.
1929  RouteConfiguration new_route_config = default_route_config_;
1930  // route 1: Set max_stream_duration of 2.5 seconds, Set
1931  // grpc_timeout_header_max of 1.5
1932  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
1933  route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service/Echo1");
1934  route1->mutable_route()->set_cluster(kNewCluster1Name);
1935  auto* max_stream_duration =
1936  route1->mutable_route()->mutable_max_stream_duration();
1937  duration = max_stream_duration->mutable_max_stream_duration();
1938  duration->set_seconds(kTimeoutMaxStreamDurationSecond);
1939  duration->set_nanos(kTimeoutNano);
1940  duration = max_stream_duration->mutable_grpc_timeout_header_max();
1941  duration->set_seconds(kTimeoutGrpcTimeoutHeaderMaxSecond);
1942  duration->set_nanos(kTimeoutNano);
1943  // route 2: Set max_stream_duration of 2.5 seconds
1944  auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1945  route2->mutable_match()->set_path("/grpc.testing.EchoTest2Service/Echo2");
1946  route2->mutable_route()->set_cluster(kNewCluster2Name);
1947  max_stream_duration = route2->mutable_route()->mutable_max_stream_duration();
1948  duration = max_stream_duration->mutable_max_stream_duration();
1949  duration->set_seconds(kTimeoutMaxStreamDurationSecond);
1950  duration->set_nanos(kTimeoutNano);
1951  // route 3: No timeout values in route configuration
1952  auto* route3 = new_route_config.mutable_virtual_hosts(0)->add_routes();
1953  route3->mutable_match()->set_path("/grpc.testing.EchoTestService/Echo");
1954  route3->mutable_route()->set_cluster(kNewCluster3Name);
1955  // Set listener and route config.
1956  SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
1957  new_route_config);
1958  // Test grpc_timeout_header_max of 1.5 seconds applied
1959  grpc_core::Timestamp t0 = NowFromCycleCounter();
1961  t0 + grpc_core::Duration::Seconds(kTimeoutGrpcTimeoutHeaderMaxSecond) +
1962  grpc_core::Duration::Milliseconds(kTimeoutMillis);
1964  t0 + grpc_core::Duration::Seconds(kTimeoutMaxStreamDurationSecond) +
1965  grpc_core::Duration::Milliseconds(kTimeoutMillis);
1966  CheckRpcSendFailure(
1967  DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
1968  RpcOptions()
1969  .set_rpc_service(SERVICE_ECHO1)
1970  .set_rpc_method(METHOD_ECHO1)
1971  .set_wait_for_ready(true)
1972  .set_timeout_ms(
1973  grpc_core::Duration::Seconds(kTimeoutApplicationSecond)
1974  .millis()));
1975  EXPECT_THAT(NowFromCycleCounter(), AdjustedClockInRange(t1, t2));
1976  // Test max_stream_duration of 2.5 seconds applied
1977  t0 = NowFromCycleCounter();
1978  t1 = t0 + grpc_core::Duration::Seconds(kTimeoutMaxStreamDurationSecond) +
1979  grpc_core::Duration::Milliseconds(kTimeoutMillis);
1980  t2 = t0 + grpc_core::Duration::Seconds(kTimeoutHttpMaxStreamDurationSecond) +
1981  grpc_core::Duration::Milliseconds(kTimeoutMillis);
1982  CheckRpcSendFailure(
1983  DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
1984  RpcOptions()
1985  .set_rpc_service(SERVICE_ECHO2)
1986  .set_rpc_method(METHOD_ECHO2)
1987  .set_wait_for_ready(true)
1988  .set_timeout_ms(
1989  grpc_core::Duration::Seconds(kTimeoutApplicationSecond)
1990  .millis()));
1991  EXPECT_THAT(NowFromCycleCounter(), AdjustedClockInRange(t1, t2));
1992  // Test http_stream_duration of 3.5 seconds applied
1993  t0 = NowFromCycleCounter();
1994  t1 = t0 + grpc_core::Duration::Seconds(kTimeoutHttpMaxStreamDurationSecond) +
1995  grpc_core::Duration::Milliseconds(kTimeoutMillis);
1996  t2 = t0 + grpc_core::Duration::Seconds(kTimeoutApplicationSecond) +
1997  grpc_core::Duration::Milliseconds(kTimeoutMillis);
1998  CheckRpcSendFailure(
1999  DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
2000  RpcOptions().set_wait_for_ready(true).set_timeout_ms(
2001  grpc_core::Duration::Seconds(kTimeoutApplicationSecond).millis()));
2002  EXPECT_THAT(NowFromCycleCounter(), AdjustedClockInRange(t1, t2));
2003 }
2004 
2005 TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit0) {
2006  const int64_t kTimeoutNano = 500000000;
2007  const int64_t kTimeoutMaxStreamDurationSecond = 2;
2008  const int64_t kTimeoutHttpMaxStreamDurationSecond = 3;
2009  const int64_t kTimeoutApplicationSecond = 4;
2010  const char* kNewCluster1Name = "new_cluster_1";
2011  const char* kNewEdsService1Name = "new_eds_service_name_1";
2012  const char* kNewCluster2Name = "new_cluster_2";
2013  const char* kNewEdsService2Name = "new_eds_service_name_2";
2014  // Populate new EDS resources.
2015  EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
2016  EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}});
2017  EdsResourceArgs args2({{"locality0", {MakeNonExistantEndpoint()}}});
2018  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2019  balancer_->ads_service()->SetEdsResource(
2020  BuildEdsResource(args1, kNewEdsService1Name));
2021  balancer_->ads_service()->SetEdsResource(
2022  BuildEdsResource(args2, kNewEdsService2Name));
2023  // Populate new CDS resources.
2024  Cluster new_cluster1 = default_cluster_;
2025  new_cluster1.set_name(kNewCluster1Name);
2026  new_cluster1.mutable_eds_cluster_config()->set_service_name(
2027  kNewEdsService1Name);
2028  balancer_->ads_service()->SetCdsResource(new_cluster1);
2029  Cluster new_cluster2 = default_cluster_;
2030  new_cluster2.set_name(kNewCluster2Name);
2031  new_cluster2.mutable_eds_cluster_config()->set_service_name(
2032  kNewEdsService2Name);
2033  balancer_->ads_service()->SetCdsResource(new_cluster2);
2034  // Construct listener.
2035  auto listener = default_listener_;
2036  HttpConnectionManager http_connection_manager;
2037  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
2038  &http_connection_manager);
2039  // Set up HTTP max_stream_duration of 3.5 seconds
2040  auto* duration =
2041  http_connection_manager.mutable_common_http_protocol_options()
2042  ->mutable_max_stream_duration();
2043  duration->set_seconds(kTimeoutHttpMaxStreamDurationSecond);
2044  duration->set_nanos(kTimeoutNano);
2045  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
2046  http_connection_manager);
2047  // Construct route config.
2048  RouteConfiguration new_route_config = default_route_config_;
2049  // route 1: Set max_stream_duration of 2.5 seconds, Set
2050  // grpc_timeout_header_max of 0
2051  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2052  route1->mutable_match()->set_path("/grpc.testing.EchoTest1Service/Echo1");
2053  route1->mutable_route()->set_cluster(kNewCluster1Name);
2054  auto* max_stream_duration =
2055  route1->mutable_route()->mutable_max_stream_duration();
2056  duration = max_stream_duration->mutable_max_stream_duration();
2057  duration->set_seconds(kTimeoutMaxStreamDurationSecond);
2058  duration->set_nanos(kTimeoutNano);
2059  duration = max_stream_duration->mutable_grpc_timeout_header_max();
2060  duration->set_seconds(0);
2061  duration->set_nanos(0);
2062  // route 2: Set max_stream_duration to 0
2063  auto* route2 = new_route_config.mutable_virtual_hosts(0)->add_routes();
2064  route2->mutable_match()->set_path("/grpc.testing.EchoTest2Service/Echo2");
2065  route2->mutable_route()->set_cluster(kNewCluster2Name);
2066  max_stream_duration = route2->mutable_route()->mutable_max_stream_duration();
2067  duration = max_stream_duration->mutable_max_stream_duration();
2068  duration->set_seconds(0);
2069  duration->set_nanos(0);
2070  // Set listener and route config.
2071  SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
2072  new_route_config);
2073  // Test application timeout is applied for route 1
2074  auto t0 = system_clock::now();
2075  CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED,
2076  "Deadline Exceeded",
2077  RpcOptions()
2078  .set_rpc_service(SERVICE_ECHO1)
2079  .set_rpc_method(METHOD_ECHO1)
2080  .set_wait_for_ready(true)
2081  .set_timeout_ms(kTimeoutApplicationSecond * 1000));
2082  auto ellapsed_nano_seconds =
2083  std::chrono::duration_cast<std::chrono::nanoseconds>(system_clock::now() -
2084  t0);
2085  EXPECT_GT(ellapsed_nano_seconds.count(),
2086  kTimeoutApplicationSecond * 1000000000);
2087  // Test application timeout is applied for route 2
2088  t0 = system_clock::now();
2089  CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED,
2090  "Deadline Exceeded",
2091  RpcOptions()
2092  .set_rpc_service(SERVICE_ECHO2)
2093  .set_rpc_method(METHOD_ECHO2)
2094  .set_wait_for_ready(true)
2095  .set_timeout_ms(kTimeoutApplicationSecond * 1000));
2096  ellapsed_nano_seconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
2097  system_clock::now() - t0);
2098  EXPECT_GT(ellapsed_nano_seconds.count(),
2099  kTimeoutApplicationSecond * 1000000000);
2100 }
2101 
2102 TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit0) {
2103  const int64_t kTimeoutApplicationSecond = 4;
2104  // Populate new EDS resources.
2105  EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
2106  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2107  auto listener = default_listener_;
2108  HttpConnectionManager http_connection_manager;
2109  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
2110  &http_connection_manager);
2111  // Set up HTTP max_stream_duration to be explicit 0
2112  auto* duration =
2113  http_connection_manager.mutable_common_http_protocol_options()
2114  ->mutable_max_stream_duration();
2115  duration->set_seconds(0);
2116  duration->set_nanos(0);
2117  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
2118  http_connection_manager);
2119  // Set listener and route config.
2120  SetListenerAndRouteConfiguration(balancer_.get(), std::move(listener),
2121  default_route_config_);
2122  // Test application timeout is applied for route 1
2123  auto t0 = system_clock::now();
2124  CheckRpcSendFailure(
2125  DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
2126  RpcOptions().set_wait_for_ready(true).set_timeout_ms(
2127  grpc_core::Duration::Seconds(kTimeoutApplicationSecond).millis()));
2128  auto ellapsed_nano_seconds =
2129  std::chrono::duration_cast<std::chrono::nanoseconds>(system_clock::now() -
2130  t0);
2131  EXPECT_GT(ellapsed_nano_seconds.count(),
2132  kTimeoutApplicationSecond * 1000000000);
2133 }
2134 
2135 // Test to ensure application-specified deadline won't be affected when
2136 // the xDS config does not specify a timeout.
2137 TEST_P(LdsRdsTest, XdsRoutingWithOnlyApplicationTimeout) {
2138  const int64_t kTimeoutApplicationSecond = 4;
2139  // Populate new EDS resources.
2140  EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}});
2141  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2142  auto t0 = system_clock::now();
2143  CheckRpcSendFailure(
2144  DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
2145  RpcOptions().set_wait_for_ready(true).set_timeout_ms(
2146  grpc_core::Duration::Seconds(kTimeoutApplicationSecond).millis()));
2147  auto ellapsed_nano_seconds =
2148  std::chrono::duration_cast<std::chrono::nanoseconds>(system_clock::now() -
2149  t0);
2150  EXPECT_GT(ellapsed_nano_seconds.count(),
2151  kTimeoutApplicationSecond * 1000000000);
2152 }
2153 
2154 TEST_P(LdsRdsTest, XdsRetryPolicyNumRetries) {
2155  CreateAndStartBackends(1);
2156  const size_t kNumRetries = 3;
2157  // Populate new EDS resources.
2158  EdsResourceArgs args({
2159  {"locality0", CreateEndpointsForBackends(0, 1)},
2160  });
2161  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2162  // Construct route config to set retry policy.
2163  RouteConfiguration new_route_config = default_route_config_;
2164  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2165  auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
2166  retry_policy->set_retry_on(
2167  "5xx,cancelled,deadline-exceeded,internal,resource-exhausted,"
2168  "unavailable");
2169  retry_policy->mutable_num_retries()->set_value(kNumRetries);
2170  SetRouteConfiguration(balancer_.get(), new_route_config);
2171  // Ensure we retried the correct number of times on all supported status.
2172  CheckRpcSendFailure(
2174  RpcOptions().set_server_expected_error(StatusCode::CANCELLED));
2175  EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
2176  ResetBackendCounters();
2177  CheckRpcSendFailure(
2179  RpcOptions().set_server_expected_error(StatusCode::DEADLINE_EXCEEDED));
2180  EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
2181  ResetBackendCounters();
2182  CheckRpcSendFailure(
2184  RpcOptions().set_server_expected_error(StatusCode::INTERNAL));
2185  EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
2186  ResetBackendCounters();
2187  CheckRpcSendFailure(
2189  RpcOptions().set_server_expected_error(StatusCode::RESOURCE_EXHAUSTED));
2190  EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
2191  ResetBackendCounters();
2192  CheckRpcSendFailure(
2194  RpcOptions().set_server_expected_error(StatusCode::UNAVAILABLE));
2195  EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
2196  ResetBackendCounters();
2197  // Ensure we don't retry on an unsupported status.
2198  CheckRpcSendFailure(
2200  RpcOptions().set_server_expected_error(StatusCode::UNAUTHENTICATED));
2201  EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
2202 }
2203 
2204 TEST_P(LdsRdsTest, XdsRetryPolicyAtVirtualHostLevel) {
2205  CreateAndStartBackends(1);
2206  const size_t kNumRetries = 3;
2207  // Populate new EDS resources.
2208  EdsResourceArgs args({
2209  {"locality0", CreateEndpointsForBackends(0, 1)},
2210  });
2211  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2212  // Construct route config to set retry policy.
2213  RouteConfiguration new_route_config = default_route_config_;
2214  auto* retry_policy =
2215  new_route_config.mutable_virtual_hosts(0)->mutable_retry_policy();
2216  retry_policy->set_retry_on(
2217  "cancelled,deadline-exceeded,internal,resource-exhausted,unavailable");
2218  retry_policy->mutable_num_retries()->set_value(kNumRetries);
2219  SetRouteConfiguration(balancer_.get(), new_route_config);
2220  // Ensure we retried the correct number of times on a supported status.
2221  CheckRpcSendFailure(
2223  RpcOptions().set_server_expected_error(StatusCode::DEADLINE_EXCEEDED));
2224  EXPECT_EQ(kNumRetries + 1, backends_[0]->backend_service()->request_count());
2225 }
2226 
2227 TEST_P(LdsRdsTest, XdsRetryPolicyLongBackOff) {
2228  CreateAndStartBackends(1);
2229  // Set num retries to 3, but due to longer back off, we expect only 1 retry
2230  // will take place.
2231  const size_t kNumRetries = 3;
2232  // Populate new EDS resources.
2233  EdsResourceArgs args({
2234  {"locality0", CreateEndpointsForBackends(0, 1)},
2235  });
2236  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2237  // Construct route config to set retry policy.
2238  RouteConfiguration new_route_config = default_route_config_;
2239  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2240  auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
2241  retry_policy->set_retry_on(
2242  "5xx,cancelled,deadline-exceeded,internal,resource-exhausted,"
2243  "unavailable");
2244  retry_policy->mutable_num_retries()->set_value(kNumRetries);
2245  auto base_interval =
2246  retry_policy->mutable_retry_back_off()->mutable_base_interval();
2247  // Set backoff to 1 second, 1/2 of rpc timeout of 2 second.
2248  base_interval->set_seconds(1 * grpc_test_slowdown_factor());
2249  base_interval->set_nanos(0);
2250  SetRouteConfiguration(balancer_.get(), new_route_config);
2251  // No need to set max interval and just let it be the default of 10x of base.
2252  // We expect 1 retry before the RPC times out with DEADLINE_EXCEEDED.
2253  CheckRpcSendFailure(
2254  DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
2255  RpcOptions().set_timeout_ms(2500).set_server_expected_error(
2257  EXPECT_EQ(1 + 1, backends_[0]->backend_service()->request_count());
2258 }
2259 
2260 TEST_P(LdsRdsTest, XdsRetryPolicyMaxBackOff) {
2261  CreateAndStartBackends(1);
2262  // Set num retries to 3, but due to longer back off, we expect only 2 retry
2263  // will take place, while the 2nd one will obey the max backoff.
2264  const size_t kNumRetries = 3;
2265  // Populate new EDS resources.
2266  EdsResourceArgs args({
2267  {"locality0", CreateEndpointsForBackends(0, 1)},
2268  });
2269  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2270  // Construct route config to set retry policy.
2271  RouteConfiguration new_route_config = default_route_config_;
2272  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2273  auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
2274  retry_policy->set_retry_on(
2275  "5xx,cancelled,deadline-exceeded,internal,resource-exhausted,"
2276  "unavailable");
2277  retry_policy->mutable_num_retries()->set_value(kNumRetries);
2278  auto base_interval =
2279  retry_policy->mutable_retry_back_off()->mutable_base_interval();
2280  // Set backoff to 1 second.
2281  base_interval->set_seconds(1 * grpc_test_slowdown_factor());
2282  base_interval->set_nanos(0);
2283  auto max_interval =
2284  retry_policy->mutable_retry_back_off()->mutable_max_interval();
2285  // Set max interval to be the same as base, so 2 retries will take 2 seconds
2286  // and both retries will take place before the 2.5 seconds rpc timeout.
2287  // Tested to ensure if max is not set, this test will be the same as
2288  // XdsRetryPolicyLongBackOff and we will only see 1 retry in that case.
2289  max_interval->set_seconds(1 * grpc_test_slowdown_factor());
2290  max_interval->set_nanos(0);
2291  SetRouteConfiguration(balancer_.get(), new_route_config);
2292  // We expect 2 retry before the RPC times out with DEADLINE_EXCEEDED.
2293  CheckRpcSendFailure(
2294  DEBUG_LOCATION, StatusCode::DEADLINE_EXCEEDED, "Deadline Exceeded",
2295  RpcOptions().set_timeout_ms(2500).set_server_expected_error(
2297  EXPECT_EQ(2 + 1, backends_[0]->backend_service()->request_count());
2298 }
2299 
2300 TEST_P(LdsRdsTest, XdsRetryPolicyUnsupportedStatusCode) {
2301  CreateAndStartBackends(1);
2302  const size_t kNumRetries = 3;
2303  // Populate new EDS resources.
2304  EdsResourceArgs args({
2305  {"locality0", CreateEndpointsForBackends(0, 1)},
2306  });
2307  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2308  // Construct route config to set retry policy.
2309  RouteConfiguration new_route_config = default_route_config_;
2310  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2311  auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
2312  retry_policy->set_retry_on("5xx");
2313  retry_policy->mutable_num_retries()->set_value(kNumRetries);
2314  SetRouteConfiguration(balancer_.get(), new_route_config);
2315  // We expect no retry.
2316  CheckRpcSendFailure(
2318  RpcOptions().set_server_expected_error(StatusCode::DEADLINE_EXCEEDED));
2319  EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
2320 }
2321 
2322 TEST_P(LdsRdsTest,
2323  XdsRetryPolicyUnsupportedStatusCodeWithVirtualHostLevelRetry) {
2324  CreateAndStartBackends(1);
2325  const size_t kNumRetries = 3;
2326  // Populate new EDS resources.
2327  EdsResourceArgs args({
2328  {"locality0", CreateEndpointsForBackends(0, 1)},
2329  });
2330  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2331  // Construct route config to set retry policy with no supported retry_on
2332  // statuses.
2333  RouteConfiguration new_route_config = default_route_config_;
2334  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2335  auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
2336  retry_policy->set_retry_on("5xx");
2337  retry_policy->mutable_num_retries()->set_value(kNumRetries);
2338  // Construct a virtual host level retry policy with supported statuses.
2339  auto* virtual_host_retry_policy =
2340  new_route_config.mutable_virtual_hosts(0)->mutable_retry_policy();
2341  virtual_host_retry_policy->set_retry_on(
2342  "cancelled,deadline-exceeded,internal,resource-exhausted,unavailable");
2343  virtual_host_retry_policy->mutable_num_retries()->set_value(kNumRetries);
2344  SetRouteConfiguration(balancer_.get(), new_route_config);
2345  // We expect no retry.
2346  CheckRpcSendFailure(
2348  RpcOptions().set_server_expected_error(StatusCode::DEADLINE_EXCEEDED));
2349  EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
2350 }
2351 
2352 TEST_P(LdsRdsTest, XdsRetryPolicyInvalidNumRetriesZero) {
2353  CreateAndStartBackends(1);
2354  // Populate new EDS resources.
2355  EdsResourceArgs args({
2356  {"locality0", CreateEndpointsForBackends(0, 1)},
2357  });
2358  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2359  // Construct route config to set retry policy.
2360  RouteConfiguration new_route_config = default_route_config_;
2361  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2362  auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
2363  retry_policy->set_retry_on("deadline-exceeded");
2364  // Setting num_retries to zero is not valid.
2365  retry_policy->mutable_num_retries()->set_value(0);
2366  SetRouteConfiguration(balancer_.get(), new_route_config);
2367  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2368  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2369  EXPECT_THAT(
2370  response_state->error_message,
2372  "RouteAction RetryPolicy num_retries set to invalid value 0."));
2373 }
2374 
2375 TEST_P(LdsRdsTest, XdsRetryPolicyRetryBackOffMissingBaseInterval) {
2376  CreateAndStartBackends(1);
2377  // Populate new EDS resources.
2378  EdsResourceArgs args({
2379  {"locality0", CreateEndpointsForBackends(0, 1)},
2380  });
2381  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2382  // Construct route config to set retry policy.
2383  RouteConfiguration new_route_config = default_route_config_;
2384  auto* route1 = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2385  auto* retry_policy = route1->mutable_route()->mutable_retry_policy();
2386  retry_policy->set_retry_on("deadline-exceeded");
2387  retry_policy->mutable_num_retries()->set_value(1);
2388  // RetryBackoff is there but base interval is missing.
2389  auto max_interval =
2390  retry_policy->mutable_retry_back_off()->mutable_max_interval();
2391  max_interval->set_seconds(0);
2392  max_interval->set_nanos(250000000);
2393  SetRouteConfiguration(balancer_.get(), new_route_config);
2394  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2395  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2396  EXPECT_THAT(
2397  response_state->error_message,
2399  "RouteAction RetryPolicy RetryBackoff missing base interval."));
2400 }
2401 
2402 TEST_P(LdsRdsTest, XdsRoutingHeadersMatching) {
2403  CreateAndStartBackends(2);
2404  const char* kNewClusterName = "new_cluster";
2405  const char* kNewEdsServiceName = "new_eds_service_name";
2406  const size_t kNumEcho1Rpcs = 100;
2407  const size_t kNumEchoRpcs = 5;
2408  // Populate new EDS resources.
2409  EdsResourceArgs args({
2410  {"locality0", CreateEndpointsForBackends(0, 1)},
2411  });
2412  EdsResourceArgs args1({
2413  {"locality0", CreateEndpointsForBackends(1, 2)},
2414  });
2415  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2416  balancer_->ads_service()->SetEdsResource(
2417  BuildEdsResource(args1, kNewEdsServiceName));
2418  // Populate new CDS resources.
2419  Cluster new_cluster = default_cluster_;
2420  new_cluster.set_name(kNewClusterName);
2421  new_cluster.mutable_eds_cluster_config()->set_service_name(
2422  kNewEdsServiceName);
2423  balancer_->ads_service()->SetCdsResource(new_cluster);
2424  // Populating Route Configurations for LDS.
2425  RouteConfiguration route_config = default_route_config_;
2426  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2427  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2428  auto* header_matcher1 = route1->mutable_match()->add_headers();
2429  header_matcher1->set_name("header1");
2430  header_matcher1->set_exact_match("POST,PUT,GET");
2431  auto* header_matcher2 = route1->mutable_match()->add_headers();
2432  header_matcher2->set_name("header2");
2433  header_matcher2->mutable_safe_regex_match()->set_regex("[a-z]*");
2434  auto* header_matcher3 = route1->mutable_match()->add_headers();
2435  header_matcher3->set_name("header3");
2436  header_matcher3->mutable_range_match()->set_start(1);
2437  header_matcher3->mutable_range_match()->set_end(1000);
2438  auto* header_matcher4 = route1->mutable_match()->add_headers();
2439  header_matcher4->set_name("header4");
2440  header_matcher4->set_present_match(false);
2441  auto* header_matcher5 = route1->mutable_match()->add_headers();
2442  header_matcher5->set_name("header5");
2443  header_matcher5->set_present_match(true);
2444  auto* header_matcher6 = route1->mutable_match()->add_headers();
2445  header_matcher6->set_name("header6");
2446  header_matcher6->set_prefix_match("/grpc");
2447  auto* header_matcher7 = route1->mutable_match()->add_headers();
2448  header_matcher7->set_name("header7");
2449  header_matcher7->set_suffix_match(".cc");
2450  header_matcher7->set_invert_match(true);
2451  route1->mutable_route()->set_cluster(kNewClusterName);
2452  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2453  default_route->mutable_match()->set_prefix("");
2454  default_route->mutable_route()->set_cluster(kDefaultClusterName);
2455  SetRouteConfiguration(balancer_.get(), route_config);
2456  std::vector<std::pair<std::string, std::string>> metadata = {
2457  {"header1", "POST"},
2458  {"header2", "blah"},
2459  {"header3", "1"},
2460  {"header5", "anything"},
2461  {"header6", "/grpc.testing.EchoTest1Service/"},
2462  {"header1", "PUT"},
2463  {"header7", "grpc.java"},
2464  {"header1", "GET"},
2465  };
2466  const auto header_match_rpc_options = RpcOptions()
2467  .set_rpc_service(SERVICE_ECHO1)
2468  .set_rpc_method(METHOD_ECHO1)
2469  .set_metadata(std::move(metadata));
2470  // Make sure all backends are up.
2471  WaitForBackend(DEBUG_LOCATION, 0);
2472  WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
2473  WaitForBackendOptions(), header_match_rpc_options);
2474  // Send RPCs.
2475  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
2476  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs, header_match_rpc_options);
2477  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
2478  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
2479  EXPECT_EQ(0, backends_[0]->backend_service2()->request_count());
2480  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2481  EXPECT_EQ(kNumEcho1Rpcs, backends_[1]->backend_service1()->request_count());
2482  EXPECT_EQ(0, backends_[1]->backend_service2()->request_count());
2483  auto response_state = RouteConfigurationResponseState(balancer_.get());
2484  ASSERT_TRUE(response_state.has_value());
2485  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2486 }
2487 
2488 TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialHeaderContentType) {
2489  CreateAndStartBackends(2);
2490  const char* kNewClusterName = "new_cluster";
2491  const char* kNewEdsServiceName = "new_eds_service_name";
2492  const size_t kNumEchoRpcs = 100;
2493  // Populate new EDS resources.
2494  EdsResourceArgs args({
2495  {"locality0", CreateEndpointsForBackends(0, 1)},
2496  });
2497  EdsResourceArgs args1({
2498  {"locality0", CreateEndpointsForBackends(1, 2)},
2499  });
2500  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2501  balancer_->ads_service()->SetEdsResource(
2502  BuildEdsResource(args1, kNewEdsServiceName));
2503  // Populate new CDS resources.
2504  Cluster new_cluster = default_cluster_;
2505  new_cluster.set_name(kNewClusterName);
2506  new_cluster.mutable_eds_cluster_config()->set_service_name(
2507  kNewEdsServiceName);
2508  balancer_->ads_service()->SetCdsResource(new_cluster);
2509  // Populating Route Configurations for LDS.
2510  RouteConfiguration route_config = default_route_config_;
2511  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2512  route1->mutable_match()->set_prefix("");
2513  auto* header_matcher1 = route1->mutable_match()->add_headers();
2514  header_matcher1->set_name("content-type");
2515  header_matcher1->set_exact_match("notapplication/grpc");
2516  route1->mutable_route()->set_cluster(kNewClusterName);
2517  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2518  default_route->mutable_match()->set_prefix("");
2519  auto* header_matcher2 = default_route->mutable_match()->add_headers();
2520  header_matcher2->set_name("content-type");
2521  header_matcher2->set_exact_match("application/grpc");
2522  default_route->mutable_route()->set_cluster(kDefaultClusterName);
2523  SetRouteConfiguration(balancer_.get(), route_config);
2524  // Make sure the backend is up.
2525  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
2526  // Send RPCs.
2527  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs);
2528  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
2529  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2530  auto response_state = RouteConfigurationResponseState(balancer_.get());
2531  ASSERT_TRUE(response_state.has_value());
2532  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2533 }
2534 
2535 TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialCasesToIgnore) {
2536  CreateAndStartBackends(2);
2537  const char* kNewCluster1Name = "new_cluster_1";
2538  const char* kNewEdsService1Name = "new_eds_service_name_1";
2539  const size_t kNumEchoRpcs = 100;
2540  // Populate new EDS resources.
2541  EdsResourceArgs args({
2542  {"locality0", CreateEndpointsForBackends(0, 1)},
2543  });
2544  EdsResourceArgs args1({
2545  {"locality0", CreateEndpointsForBackends(1, 2)},
2546  });
2547  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2548  balancer_->ads_service()->SetEdsResource(
2549  BuildEdsResource(args1, kNewEdsService1Name));
2550  // Populate new CDS resources.
2551  Cluster new_cluster1 = default_cluster_;
2552  new_cluster1.set_name(kNewCluster1Name);
2553  new_cluster1.mutable_eds_cluster_config()->set_service_name(
2554  kNewEdsService1Name);
2555  balancer_->ads_service()->SetCdsResource(new_cluster1);
2556  // Populating Route Configurations for LDS.
2557  RouteConfiguration route_config = default_route_config_;
2558  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2559  route1->mutable_match()->set_prefix("");
2560  auto* header_matcher1 = route1->mutable_match()->add_headers();
2561  header_matcher1->set_name("grpc-foo-bin");
2562  header_matcher1->set_present_match(true);
2563  route1->mutable_route()->set_cluster(kNewCluster1Name);
2564  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2565  default_route->mutable_match()->set_prefix("");
2566  default_route->mutable_route()->set_cluster(kDefaultClusterName);
2567  SetRouteConfiguration(balancer_.get(), route_config);
2568  // Send headers which will mismatch each route
2569  std::vector<std::pair<std::string, std::string>> metadata = {
2570  {"grpc-foo-bin", "grpc-foo-bin"},
2571  };
2572  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
2573  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
2574  RpcOptions().set_metadata(metadata));
2575  // Verify that only the default backend got RPCs since all previous routes
2576  // were mismatched.
2577  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
2578  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2579  auto response_state = RouteConfigurationResponseState(balancer_.get());
2580  ASSERT_TRUE(response_state.has_value());
2581  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2582 }
2583 
2584 TEST_P(LdsRdsTest, XdsRoutingRuntimeFractionMatching) {
2585  CreateAndStartBackends(2);
2586  const char* kNewClusterName = "new_cluster";
2587  const char* kNewEdsServiceName = "new_eds_service_name";
2588  const double kErrorTolerance = 0.05;
2589  const size_t kRouteMatchNumerator = 25;
2590  const double kRouteMatchPercent =
2591  static_cast<double>(kRouteMatchNumerator) / 100;
2592  const size_t kNumRpcs =
2593  ComputeIdealNumRpcs(kRouteMatchPercent, kErrorTolerance);
2594  // Populate new EDS resources.
2595  EdsResourceArgs args({
2596  {"locality0", CreateEndpointsForBackends(0, 1)},
2597  });
2598  EdsResourceArgs args1({
2599  {"locality0", CreateEndpointsForBackends(1, 2)},
2600  });
2601  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2602  balancer_->ads_service()->SetEdsResource(
2603  BuildEdsResource(args1, kNewEdsServiceName));
2604  // Populate new CDS resources.
2605  Cluster new_cluster = default_cluster_;
2606  new_cluster.set_name(kNewClusterName);
2607  new_cluster.mutable_eds_cluster_config()->set_service_name(
2608  kNewEdsServiceName);
2609  balancer_->ads_service()->SetCdsResource(new_cluster);
2610  // Populating Route Configurations for LDS.
2611  RouteConfiguration route_config = default_route_config_;
2612  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2613  route1->mutable_match()
2614  ->mutable_runtime_fraction()
2615  ->mutable_default_value()
2616  ->set_numerator(kRouteMatchNumerator);
2617  route1->mutable_route()->set_cluster(kNewClusterName);
2618  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2619  default_route->mutable_match()->set_prefix("");
2620  default_route->mutable_route()->set_cluster(kDefaultClusterName);
2621  SetRouteConfiguration(balancer_.get(), route_config);
2622  WaitForAllBackends(DEBUG_LOCATION, 0, 2);
2623  CheckRpcSendOk(DEBUG_LOCATION, kNumRpcs);
2624  const int default_backend_count =
2625  backends_[0]->backend_service()->request_count();
2626  const int matched_backend_count =
2627  backends_[1]->backend_service()->request_count();
2628  EXPECT_THAT(static_cast<double>(default_backend_count) / kNumRpcs,
2629  ::testing::DoubleNear(1 - kRouteMatchPercent, kErrorTolerance));
2630  EXPECT_THAT(static_cast<double>(matched_backend_count) / kNumRpcs,
2631  ::testing::DoubleNear(kRouteMatchPercent, kErrorTolerance));
2632  auto response_state = RouteConfigurationResponseState(balancer_.get());
2633  ASSERT_TRUE(response_state.has_value());
2634  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2635 }
2636 
2637 TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingUnmatchCases) {
2638  CreateAndStartBackends(4);
2639  const char* kNewCluster1Name = "new_cluster_1";
2640  const char* kNewEdsService1Name = "new_eds_service_name_1";
2641  const char* kNewCluster2Name = "new_cluster_2";
2642  const char* kNewEdsService2Name = "new_eds_service_name_2";
2643  const char* kNewCluster3Name = "new_cluster_3";
2644  const char* kNewEdsService3Name = "new_eds_service_name_3";
2645  const size_t kNumEcho1Rpcs = 100;
2646  const size_t kNumEchoRpcs = 5;
2647  // Populate new EDS resources.
2648  EdsResourceArgs args({
2649  {"locality0", CreateEndpointsForBackends(0, 1)},
2650  });
2651  EdsResourceArgs args1({
2652  {"locality0", CreateEndpointsForBackends(1, 2)},
2653  });
2654  EdsResourceArgs args2({
2655  {"locality0", CreateEndpointsForBackends(2, 3)},
2656  });
2657  EdsResourceArgs args3({
2658  {"locality0", CreateEndpointsForBackends(3, 4)},
2659  });
2660  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2661  balancer_->ads_service()->SetEdsResource(
2662  BuildEdsResource(args1, kNewEdsService1Name));
2663  balancer_->ads_service()->SetEdsResource(
2664  BuildEdsResource(args2, kNewEdsService2Name));
2665  balancer_->ads_service()->SetEdsResource(
2666  BuildEdsResource(args3, kNewEdsService3Name));
2667  // Populate new CDS resources.
2668  Cluster new_cluster1 = default_cluster_;
2669  new_cluster1.set_name(kNewCluster1Name);
2670  new_cluster1.mutable_eds_cluster_config()->set_service_name(
2671  kNewEdsService1Name);
2672  balancer_->ads_service()->SetCdsResource(new_cluster1);
2673  Cluster new_cluster2 = default_cluster_;
2674  new_cluster2.set_name(kNewCluster2Name);
2675  new_cluster2.mutable_eds_cluster_config()->set_service_name(
2676  kNewEdsService2Name);
2677  balancer_->ads_service()->SetCdsResource(new_cluster2);
2678  Cluster new_cluster3 = default_cluster_;
2679  new_cluster3.set_name(kNewCluster3Name);
2680  new_cluster3.mutable_eds_cluster_config()->set_service_name(
2681  kNewEdsService3Name);
2682  balancer_->ads_service()->SetCdsResource(new_cluster3);
2683  // Populating Route Configurations for LDS.
2684  RouteConfiguration route_config = default_route_config_;
2685  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2686  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2687  auto* header_matcher1 = route1->mutable_match()->add_headers();
2688  header_matcher1->set_name("header1");
2689  header_matcher1->set_exact_match("POST");
2690  route1->mutable_route()->set_cluster(kNewCluster1Name);
2691  auto route2 = route_config.mutable_virtual_hosts(0)->add_routes();
2692  route2->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2693  auto* header_matcher2 = route2->mutable_match()->add_headers();
2694  header_matcher2->set_name("header2");
2695  header_matcher2->mutable_range_match()->set_start(1);
2696  header_matcher2->mutable_range_match()->set_end(1000);
2697  route2->mutable_route()->set_cluster(kNewCluster2Name);
2698  auto route3 = route_config.mutable_virtual_hosts(0)->add_routes();
2699  route3->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2700  auto* header_matcher3 = route3->mutable_match()->add_headers();
2701  header_matcher3->set_name("header3");
2702  header_matcher3->mutable_safe_regex_match()->set_regex("[a-z]*");
2703  route3->mutable_route()->set_cluster(kNewCluster3Name);
2704  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2705  default_route->mutable_match()->set_prefix("");
2706  default_route->mutable_route()->set_cluster(kDefaultClusterName);
2707  SetRouteConfiguration(balancer_.get(), route_config);
2708  // Send headers which will mismatch each route
2709  std::vector<std::pair<std::string, std::string>> metadata = {
2710  {"header1", "POST"},
2711  {"header2", "1000"},
2712  {"header3", "123"},
2713  {"header1", "GET"},
2714  };
2715  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
2716  CheckRpcSendOk(DEBUG_LOCATION, kNumEchoRpcs,
2717  RpcOptions().set_metadata(metadata));
2718  CheckRpcSendOk(DEBUG_LOCATION, kNumEcho1Rpcs,
2719  RpcOptions()
2720  .set_rpc_service(SERVICE_ECHO1)
2721  .set_rpc_method(METHOD_ECHO1)
2722  .set_metadata(metadata));
2723  // Verify that only the default backend got RPCs since all previous routes
2724  // were mismatched.
2725  for (size_t i = 1; i < 4; ++i) {
2726  EXPECT_EQ(0, backends_[i]->backend_service()->request_count());
2727  EXPECT_EQ(0, backends_[i]->backend_service1()->request_count());
2728  EXPECT_EQ(0, backends_[i]->backend_service2()->request_count());
2729  }
2730  EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count());
2731  EXPECT_EQ(kNumEcho1Rpcs, backends_[0]->backend_service1()->request_count());
2732  EXPECT_EQ(0, backends_[0]->backend_service2()->request_count());
2733  auto response_state = RouteConfigurationResponseState(balancer_.get());
2734  ASSERT_TRUE(response_state.has_value());
2735  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2736 }
2737 
2738 TEST_P(LdsRdsTest, XdsRoutingChangeRoutesWithoutChangingClusters) {
2739  CreateAndStartBackends(2);
2740  const char* kNewClusterName = "new_cluster";
2741  const char* kNewEdsServiceName = "new_eds_service_name";
2742  // Populate new EDS resources.
2743  EdsResourceArgs args({
2744  {"locality0", CreateEndpointsForBackends(0, 1)},
2745  });
2746  EdsResourceArgs args1({
2747  {"locality0", CreateEndpointsForBackends(1, 2)},
2748  });
2749  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2750  balancer_->ads_service()->SetEdsResource(
2751  BuildEdsResource(args1, kNewEdsServiceName));
2752  // Populate new CDS resources.
2753  Cluster new_cluster = default_cluster_;
2754  new_cluster.set_name(kNewClusterName);
2755  new_cluster.mutable_eds_cluster_config()->set_service_name(
2756  kNewEdsServiceName);
2757  balancer_->ads_service()->SetCdsResource(new_cluster);
2758  // Populating Route Configurations for LDS.
2759  RouteConfiguration route_config = default_route_config_;
2760  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
2761  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
2762  route1->mutable_route()->set_cluster(kNewClusterName);
2763  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
2764  default_route->mutable_match()->set_prefix("");
2765  default_route->mutable_route()->set_cluster(kDefaultClusterName);
2766  SetRouteConfiguration(balancer_.get(), route_config);
2767  // Make sure all backends are up and that requests for each RPC
2768  // service go to the right backends.
2769  WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
2770  WaitForBackendOptions().set_reset_counters(false));
2771  WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
2772  WaitForBackendOptions().set_reset_counters(false),
2773  RpcOptions().set_rpc_service(SERVICE_ECHO1));
2774  WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
2775  WaitForBackendOptions().set_reset_counters(false),
2776  RpcOptions().set_rpc_service(SERVICE_ECHO2));
2777  // Requests for services Echo and Echo2 should have gone to backend 0.
2778  EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
2779  EXPECT_EQ(0, backends_[0]->backend_service1()->request_count());
2780  EXPECT_EQ(1, backends_[0]->backend_service2()->request_count());
2781  // Requests for service Echo1 should have gone to backend 1.
2782  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2783  EXPECT_EQ(1, backends_[1]->backend_service1()->request_count());
2784  EXPECT_EQ(0, backends_[1]->backend_service2()->request_count());
2785  // Now send an update that changes the first route to match a
2786  // different RPC service, and wait for the client to make the change.
2787  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest2Service/");
2788  SetRouteConfiguration(balancer_.get(), route_config);
2789  WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
2790  WaitForBackendOptions(),
2791  RpcOptions().set_rpc_service(SERVICE_ECHO2));
2792  // Now repeat the earlier test, making sure all traffic goes to the
2793  // right place.
2794  WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
2795  WaitForBackendOptions().set_reset_counters(false));
2796  WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr,
2797  WaitForBackendOptions().set_reset_counters(false),
2798  RpcOptions().set_rpc_service(SERVICE_ECHO1));
2799  WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr,
2800  WaitForBackendOptions().set_reset_counters(false),
2801  RpcOptions().set_rpc_service(SERVICE_ECHO2));
2802  // Requests for services Echo and Echo1 should have gone to backend 0.
2803  EXPECT_EQ(1, backends_[0]->backend_service()->request_count());
2804  EXPECT_EQ(1, backends_[0]->backend_service1()->request_count());
2805  EXPECT_EQ(0, backends_[0]->backend_service2()->request_count());
2806  // Requests for service Echo2 should have gone to backend 1.
2807  EXPECT_EQ(0, backends_[1]->backend_service()->request_count());
2808  EXPECT_EQ(0, backends_[1]->backend_service1()->request_count());
2809  EXPECT_EQ(1, backends_[1]->backend_service2()->request_count());
2810 }
2811 
2812 // Test that we NACK unknown filter types in VirtualHost.
2813 TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInVirtualHost) {
2814  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2815  RouteConfiguration route_config = default_route_config_;
2816  auto* per_filter_config =
2817  route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config();
2818  (*per_filter_config)["unknown"].PackFrom(Listener());
2819  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2820  route_config);
2821  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2822  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2823  EXPECT_THAT(response_state->error_message,
2824  ::testing::HasSubstr("no filter registered for config type "
2825  "envoy.config.listener.v3.Listener"));
2826 }
2827 
2828 // Test that we ignore optional unknown filter types in VirtualHost.
2829 TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInVirtualHost) {
2830  CreateAndStartBackends(1);
2831  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2832  RouteConfiguration route_config = default_route_config_;
2833  auto* per_filter_config =
2834  route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config();
2835  ::envoy::config::route::v3::FilterConfig filter_config;
2836  filter_config.mutable_config()->PackFrom(Listener());
2837  filter_config.set_is_optional(true);
2838  (*per_filter_config)["unknown"].PackFrom(filter_config);
2839  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2840  route_config);
2841  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
2842  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2843  WaitForAllBackends(DEBUG_LOCATION);
2844  auto response_state = RouteConfigurationResponseState(balancer_.get());
2845  ASSERT_TRUE(response_state.has_value());
2846  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2847 }
2848 
2849 // Test that we NACK filters without configs in VirtualHost.
2850 TEST_P(LdsRdsTest, RejectsHttpFilterWithoutConfigInVirtualHost) {
2851  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2852  RouteConfiguration route_config = default_route_config_;
2853  auto* per_filter_config =
2854  route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config();
2855  (*per_filter_config)["unknown"];
2856  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2857  route_config);
2858  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2859  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2860  EXPECT_THAT(response_state->error_message,
2862  "no filter config specified for filter name unknown"));
2863 }
2864 
2865 // Test that we NACK filters without configs in FilterConfig in VirtualHost.
2866 TEST_P(LdsRdsTest, RejectsHttpFilterWithoutConfigInFilterConfigInVirtualHost) {
2867  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2868  RouteConfiguration route_config = default_route_config_;
2869  auto* per_filter_config =
2870  route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config();
2871  (*per_filter_config)["unknown"].PackFrom(
2872  ::envoy::config::route::v3::FilterConfig());
2873  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2874  route_config);
2875  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2876  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2877  EXPECT_THAT(response_state->error_message,
2879  "no filter config specified for filter name unknown"));
2880 }
2881 
2882 // Test that we ignore optional filters without configs in VirtualHost.
2883 TEST_P(LdsRdsTest, IgnoresOptionalHttpFilterWithoutConfigInVirtualHost) {
2884  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2885  CreateAndStartBackends(1);
2886  RouteConfiguration route_config = default_route_config_;
2887  auto* per_filter_config =
2888  route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config();
2889  ::envoy::config::route::v3::FilterConfig filter_config;
2890  filter_config.set_is_optional(true);
2891  (*per_filter_config)["unknown"].PackFrom(filter_config);
2892  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2893  route_config);
2894  EdsResourceArgs args({
2895  {"locality0", CreateEndpointsForBackends()},
2896  });
2897  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2898  WaitForAllBackends(DEBUG_LOCATION);
2899  auto response_state = RouteConfigurationResponseState(balancer_.get());
2900  ASSERT_TRUE(response_state.has_value());
2901  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2902 }
2903 
2904 // Test that we NACK unparseable filter types in VirtualHost.
2905 TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInVirtualHost) {
2906  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2907  RouteConfiguration route_config = default_route_config_;
2908  auto* per_filter_config =
2909  route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config();
2910  (*per_filter_config)["unknown"].PackFrom(
2911  envoy::extensions::filters::http::router::v3::Router());
2912  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2913  route_config);
2914  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2915  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2916  EXPECT_THAT(
2917  response_state->error_message,
2918  ::testing::HasSubstr("router filter does not support config override"));
2919 }
2920 
2921 // Test that we NACK unknown filter types in Route.
2922 TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInRoute) {
2923  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2924  RouteConfiguration route_config = default_route_config_;
2925  auto* per_filter_config = route_config.mutable_virtual_hosts(0)
2926  ->mutable_routes(0)
2927  ->mutable_typed_per_filter_config();
2928  (*per_filter_config)["unknown"].PackFrom(Listener());
2929  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2930  route_config);
2931  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2932  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2933  EXPECT_THAT(response_state->error_message,
2934  ::testing::HasSubstr("no filter registered for config type "
2935  "envoy.config.listener.v3.Listener"));
2936 }
2937 
2938 // Test that we ignore optional unknown filter types in Route.
2939 TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInRoute) {
2940  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2941  CreateAndStartBackends(1);
2942  RouteConfiguration route_config = default_route_config_;
2943  auto* per_filter_config = route_config.mutable_virtual_hosts(0)
2944  ->mutable_routes(0)
2945  ->mutable_typed_per_filter_config();
2946  ::envoy::config::route::v3::FilterConfig filter_config;
2947  filter_config.mutable_config()->PackFrom(Listener());
2948  filter_config.set_is_optional(true);
2949  (*per_filter_config)["unknown"].PackFrom(filter_config);
2950  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2951  route_config);
2952  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
2953  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
2954  WaitForAllBackends(DEBUG_LOCATION);
2955  auto response_state = RouteConfigurationResponseState(balancer_.get());
2956  ASSERT_TRUE(response_state.has_value());
2957  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
2958 }
2959 
2960 // Test that we NACK filters without configs in Route.
2961 TEST_P(LdsRdsTest, RejectsHttpFilterWithoutConfigInRoute) {
2962  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2963  RouteConfiguration route_config = default_route_config_;
2964  auto* per_filter_config = route_config.mutable_virtual_hosts(0)
2965  ->mutable_routes(0)
2966  ->mutable_typed_per_filter_config();
2967  (*per_filter_config)["unknown"];
2968  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2969  route_config);
2970  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2971  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2972  EXPECT_THAT(response_state->error_message,
2974  "no filter config specified for filter name unknown"));
2975 }
2976 
2977 // Test that we NACK filters without configs in FilterConfig in Route.
2978 TEST_P(LdsRdsTest, RejectsHttpFilterWithoutConfigInFilterConfigInRoute) {
2979  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2980  RouteConfiguration route_config = default_route_config_;
2981  auto* per_filter_config = route_config.mutable_virtual_hosts(0)
2982  ->mutable_routes(0)
2983  ->mutable_typed_per_filter_config();
2984  (*per_filter_config)["unknown"].PackFrom(
2985  ::envoy::config::route::v3::FilterConfig());
2986  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
2987  route_config);
2988  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
2989  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
2990  EXPECT_THAT(response_state->error_message,
2992  "no filter config specified for filter name unknown"));
2993 }
2994 
2995 // Test that we ignore optional filters without configs in Route.
2996 TEST_P(LdsRdsTest, IgnoresOptionalHttpFilterWithoutConfigInRoute) {
2997  if (GetParam().use_v2()) return; // Filters supported in v3 only.
2998  CreateAndStartBackends(1);
2999  RouteConfiguration route_config = default_route_config_;
3000  auto* per_filter_config = route_config.mutable_virtual_hosts(0)
3001  ->mutable_routes(0)
3002  ->mutable_typed_per_filter_config();
3003  ::envoy::config::route::v3::FilterConfig filter_config;
3004  filter_config.set_is_optional(true);
3005  (*per_filter_config)["unknown"].PackFrom(filter_config);
3006  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
3007  route_config);
3008  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
3009  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
3010  WaitForAllBackends(DEBUG_LOCATION);
3011  auto response_state = RouteConfigurationResponseState(balancer_.get());
3012  ASSERT_TRUE(response_state.has_value());
3013  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
3014 }
3015 
3016 // Test that we NACK unparseable filter types in Route.
3017 TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInRoute) {
3018  if (GetParam().use_v2()) return; // Filters supported in v3 only.
3019  RouteConfiguration route_config = default_route_config_;
3020  auto* per_filter_config = route_config.mutable_virtual_hosts(0)
3021  ->mutable_routes(0)
3022  ->mutable_typed_per_filter_config();
3023  (*per_filter_config)["unknown"].PackFrom(
3024  envoy::extensions::filters::http::router::v3::Router());
3025  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
3026  route_config);
3027  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
3028  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
3029  EXPECT_THAT(
3030  response_state->error_message,
3031  ::testing::HasSubstr("router filter does not support config override"));
3032 }
3033 
3034 // Test that we NACK unknown filter types in ClusterWeight.
3035 TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInClusterWeight) {
3036  if (GetParam().use_v2()) return; // Filters supported in v3 only.
3037  RouteConfiguration route_config = default_route_config_;
3038  auto* cluster_weight = route_config.mutable_virtual_hosts(0)
3039  ->mutable_routes(0)
3040  ->mutable_route()
3041  ->mutable_weighted_clusters()
3042  ->add_clusters();
3043  cluster_weight->set_name(kDefaultClusterName);
3044  cluster_weight->mutable_weight()->set_value(100);
3045  auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config();
3046  (*per_filter_config)["unknown"].PackFrom(Listener());
3047  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
3048  route_config);
3049  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
3050  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
3051  EXPECT_THAT(response_state->error_message,
3052  ::testing::HasSubstr("no filter registered for config type "
3053  "envoy.config.listener.v3.Listener"));
3054 }
3055 
3056 // Test that we ignore optional unknown filter types in ClusterWeight.
3057 TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInClusterWeight) {
3058  if (GetParam().use_v2()) return; // Filters supported in v3 only.
3059  CreateAndStartBackends(1);
3060  RouteConfiguration route_config = default_route_config_;
3061  auto* cluster_weight = route_config.mutable_virtual_hosts(0)
3062  ->mutable_routes(0)
3063  ->mutable_route()
3064  ->mutable_weighted_clusters()
3065  ->add_clusters();
3066  cluster_weight->set_name(kDefaultClusterName);
3067  cluster_weight->mutable_weight()->set_value(100);
3068  auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config();
3069  ::envoy::config::route::v3::FilterConfig filter_config;
3070  filter_config.mutable_config()->PackFrom(Listener());
3071  filter_config.set_is_optional(true);
3072  (*per_filter_config)["unknown"].PackFrom(filter_config);
3073  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
3074  route_config);
3075  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
3076  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
3077  WaitForAllBackends(DEBUG_LOCATION);
3078  auto response_state = RouteConfigurationResponseState(balancer_.get());
3079  ASSERT_TRUE(response_state.has_value());
3080  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
3081 }
3082 
3083 // Test that we NACK filters without configs in ClusterWeight.
3084 TEST_P(LdsRdsTest, RejectsHttpFilterWithoutConfigInClusterWeight) {
3085  if (GetParam().use_v2()) return; // Filters supported in v3 only.
3086  RouteConfiguration route_config = default_route_config_;
3087  auto* cluster_weight = route_config.mutable_virtual_hosts(0)
3088  ->mutable_routes(0)
3089  ->mutable_route()
3090  ->mutable_weighted_clusters()
3091  ->add_clusters();
3092  cluster_weight->set_name(kDefaultClusterName);
3093  cluster_weight->mutable_weight()->set_value(100);
3094  auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config();
3095  (*per_filter_config)["unknown"];
3096  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
3097  route_config);
3098  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
3099  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
3100  EXPECT_THAT(response_state->error_message,
3102  "no filter config specified for filter name unknown"));
3103 }
3104 
3105 // Test that we NACK filters without configs in FilterConfig in ClusterWeight.
3106 TEST_P(LdsRdsTest,
3107  RejectsHttpFilterWithoutConfigInFilterConfigInClusterWeight) {
3108  if (GetParam().use_v2()) return; // Filters supported in v3 only.
3109  RouteConfiguration route_config = default_route_config_;
3110  auto* cluster_weight = route_config.mutable_virtual_hosts(0)
3111  ->mutable_routes(0)
3112  ->mutable_route()
3113  ->mutable_weighted_clusters()
3114  ->add_clusters();
3115  cluster_weight->set_name(kDefaultClusterName);
3116  cluster_weight->mutable_weight()->set_value(100);
3117  auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config();
3118  (*per_filter_config)["unknown"].PackFrom(
3119  ::envoy::config::route::v3::FilterConfig());
3120  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
3121  route_config);
3122  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
3123  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
3124  EXPECT_THAT(response_state->error_message,
3126  "no filter config specified for filter name unknown"));
3127 }
3128 
3129 // Test that we ignore optional filters without configs in ClusterWeight.
3130 TEST_P(LdsRdsTest, IgnoresOptionalHttpFilterWithoutConfigInClusterWeight) {
3131  if (GetParam().use_v2()) return; // Filters supported in v3 only.
3132  CreateAndStartBackends(1);
3133  RouteConfiguration route_config = default_route_config_;
3134  auto* cluster_weight = route_config.mutable_virtual_hosts(0)
3135  ->mutable_routes(0)
3136  ->mutable_route()
3137  ->mutable_weighted_clusters()
3138  ->add_clusters();
3139  cluster_weight->set_name(kDefaultClusterName);
3140  cluster_weight->mutable_weight()->set_value(100);
3141  auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config();
3142  ::envoy::config::route::v3::FilterConfig filter_config;
3143  filter_config.set_is_optional(true);
3144  (*per_filter_config)["unknown"].PackFrom(filter_config);
3145  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
3146  route_config);
3147  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
3148  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
3149  WaitForAllBackends(DEBUG_LOCATION);
3150  auto response_state = RouteConfigurationResponseState(balancer_.get());
3151  ASSERT_TRUE(response_state.has_value());
3152  EXPECT_EQ(response_state->state, AdsServiceImpl::ResponseState::ACKED);
3153 }
3154 
3155 // Test that we NACK unparseable filter types in ClusterWeight.
3156 TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInClusterWeight) {
3157  if (GetParam().use_v2()) return; // Filters supported in v3 only.
3158  RouteConfiguration route_config = default_route_config_;
3159  auto* cluster_weight = route_config.mutable_virtual_hosts(0)
3160  ->mutable_routes(0)
3161  ->mutable_route()
3162  ->mutable_weighted_clusters()
3163  ->add_clusters();
3164  cluster_weight->set_name(kDefaultClusterName);
3165  cluster_weight->mutable_weight()->set_value(100);
3166  auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config();
3167  (*per_filter_config)["unknown"].PackFrom(
3168  envoy::extensions::filters::http::router::v3::Router());
3169  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
3170  route_config);
3171  const auto response_state = WaitForRdsNack(DEBUG_LOCATION);
3172  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
3173  EXPECT_THAT(
3174  response_state->error_message,
3175  ::testing::HasSubstr("router filter does not support config override"));
3176 }
3177 
3178 } // namespace
3179 } // namespace testing
3180 } // namespace grpc
3181 
3182 int main(int argc, char** argv) {
3183  grpc::testing::TestEnvironment env(&argc, argv);
3184  ::testing::InitGoogleTest(&argc, argv);
3185  // Make the backup poller poll very frequently in order to pick up
3186  // updates from all the subchannels's FDs.
3187  GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1);
3188 #if TARGET_OS_IPHONE
3189  // Workaround Apple CFStream bug
3190  gpr_setenv("grpc_cfstream", "0");
3191 #endif
3192  grpc_init();
3194  absl::make_unique<grpc::testing::NoOpHttpFilter>(
3195  "grpc.testing.client_only_http_filter",
3196  /* supported_on_clients = */ true, /* supported_on_servers = */ false,
3197  /* is_terminal_filter */ false),
3198  {"grpc.testing.client_only_http_filter"});
3200  absl::make_unique<grpc::testing::NoOpHttpFilter>(
3201  "grpc.testing.server_only_http_filter",
3202  /* supported_on_clients = */ false, /* supported_on_servers = */ true,
3203  /* is_terminal_filter */ false),
3204  {"grpc.testing.server_only_http_filter"});
3206  absl::make_unique<grpc::testing::NoOpHttpFilter>(
3207  "grpc.testing.terminal_http_filter",
3208  /* supported_on_clients = */ true, /* supported_on_servers = */ true,
3209  /* is_terminal_filter */ true),
3210  {"grpc.testing.terminal_http_filter"});
3211  const auto result = RUN_ALL_TESTS();
3212  grpc_shutdown();
3213  return result;
3214 }
grpc::EXPECT_THAT
EXPECT_THAT(status.error_message(), ::testing::HasSubstr("subject_token_type"))
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
testing
Definition: aws_request_signer_test.cc:25
grpc::status
auto status
Definition: cpp/client/credentials_test.cc:200
now
static double now(void)
Definition: test/core/fling/client.cc:130
stub_
std::unique_ptr< grpc::testing::EchoTestService::Stub > stub_
Definition: client_channel_stress_test.cc:331
testing::Lt
internal::LtMatcher< Rhs > Lt(Rhs x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8603
generate.env
env
Definition: generate.py:37
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
metadata
Definition: cq_verifier.cc:48
grpc
Definition: grpcpp/alarm.h:33
route
XdsRouteConfigResource::Route route
Definition: xds_resolver.cc:337
testing::DoubleNear
internal::FloatingEqMatcher< double > DoubleNear(double rhs, double max_abs_error)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8647
backends_
std::vector< std::unique_ptr< BackendServiceImpl > > backends_
Definition: client_channel_stress_test.cc:333
Listener
::grpc_event_engine::experimental::EventEngine::Listener Listener
Definition: event_engine_test_utils.cc:42
grpc_core::Timestamp
Definition: src/core/lib/gprpp/time.h:62
EXPECT_GT
#define EXPECT_GT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2036
grpc_core::XdsHttpFilterRegistry::RegisterFilter
static void RegisterFilter(std::unique_ptr< XdsHttpFilterImpl > filter, const std::set< absl::string_view > &config_proto_type_names)
Definition: xds_http_filters.cc:89
testing::Ge
internal::GeMatcher< Rhs > Ge(Rhs x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8585
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
grpc.StatusCode.RESOURCE_EXHAUSTED
tuple RESOURCE_EXHAUSTED
Definition: src/python/grpcio/grpc/__init__.py:270
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
no_op_http_filter.h
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
ASSERT_LT
#define ASSERT_LT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2068
cluster
absl::string_view cluster
Definition: xds_resolver.cc:331
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
t0
static int64_t t0
Definition: bloaty/third_party/re2/util/benchmark.cc:44
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
grpc_timeout_milliseconds_to_deadline
gpr_timespec grpc_timeout_milliseconds_to_deadline(int64_t time_ms)
Definition: test/core/util/test_config.cc:89
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
grpc_test_slowdown_factor
int64_t grpc_test_slowdown_factor()
Definition: test/core/util/test_config.cc:76
channel_
RefCountedPtr< Channel > channel_
Definition: channel_connectivity.cc:209
main
int main(int argc, char **argv)
Definition: xds_routing_end2end_test.cc:3182
arg
Definition: cmdline.cc:40
xds_end2end_test_lib.h
grpc::testing::kLdsTypeUrl
constexpr char kLdsTypeUrl[]
Definition: xds_server.h:51
GPR_CLOCK_MONOTONIC
@ GPR_CLOCK_MONOTONIC
Definition: gpr_types.h:36
grpc::testing::INSTANTIATE_TEST_SUITE_P
INSTANTIATE_TEST_SUITE_P(HistogramTestCases, HistogramTest, ::testing::Range< int >(0, GRPC_STATS_HISTOGRAM_COUNT))
backup_poller.h
grpc.StatusCode.UNAUTHENTICATED
tuple UNAUTHENTICATED
Definition: src/python/grpcio/grpc/__init__.py:280
kNumRpcs
const int kNumRpcs
Definition: thread_stress_test.cc:50
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
gpr_now
GPRAPI gpr_timespec gpr_now(gpr_clock_type clock)
GPR_GLOBAL_CONFIG_SET
#define GPR_GLOBAL_CONFIG_SET(name, value)
Definition: global_config_generic.h:26
absl::Seconds
constexpr Duration Seconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:419
grpc_core::Duration::Milliseconds
static constexpr Duration Milliseconds(int64_t millis)
Definition: src/core/lib/gprpp/time.h:155
absl::Now
ABSL_NAMESPACE_BEGIN Time Now()
Definition: abseil-cpp/absl/time/clock.cc:39
grpc::testing::AdsServiceImpl::ResponseState::ACKED
@ ACKED
Definition: xds_server.h:73
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
testing::Values
internal::ValueArray< T... > Values(T... v)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:335
MATCHER_P2
#define MATCHER_P2(name, p0, p1, description)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-generated-matchers.h:364
grpc_core::Timestamp::FromCycleCounterRoundDown
static Timestamp FromCycleCounterRoundDown(gpr_cycle_counter c)
Definition: src/core/lib/gprpp/time.cc:152
testing::ExplainMatchResult
bool ExplainMatchResult(M matcher, const T &value, MatchResultListener *listener)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:9173
grpc_core::Timestamp::FromTimespecRoundDown
static Timestamp FromTimespecRoundDown(gpr_timespec t)
Definition: src/core/lib/gprpp/time.cc:141
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc_core::Duration::Seconds
static constexpr Duration Seconds(int64_t seconds)
Definition: src/core/lib/gprpp/time.h:151
grpc::protobuf::util::Status
GRPC_CUSTOM_UTIL_STATUS Status
Definition: include/grpcpp/impl/codegen/config_protobuf.h:93
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
ok
bool ok
Definition: async_end2end_test.cc:197
grpc::testing::EXPECT_EQ
EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange")
grpc.StatusCode.UNAVAILABLE
tuple UNAVAILABLE
Definition: src/python/grpcio/grpc/__init__.py:278
grpc.StatusCode.CANCELLED
tuple CANCELLED
Definition: src/python/grpcio/grpc/__init__.py:261
grpc::testing::TEST_P
TEST_P(HistogramTest, IncHistogram)
Definition: stats_test.cc:87
grpc::testing::EXPECT_TRUE
EXPECT_TRUE(grpc::experimental::StsCredentialsOptionsFromJson(minimum_valid_json, &options) .ok())
run_xds_tests.backend_service
def backend_service
Definition: run_xds_tests.py:3255
grpc_init
GRPCAPI void grpc_init(void)
Definition: init.cc:146
grpc.StatusCode.DEADLINE_EXCEEDED
tuple DEADLINE_EXCEEDED
Definition: src/python/grpcio/grpc/__init__.py:264
grpc.StatusCode.INTERNAL
tuple INTERNAL
Definition: src/python/grpcio/grpc/__init__.py:277
t1
Table t1
Definition: abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc:185
grpc::testing::SendRpc
static void SendRpc(grpc::testing::EchoTestService::Stub *stub, int num_rpcs, bool allow_exhaustion, gpr_atm *errors)
Definition: thread_stress_test.cc:277
testing::HasSubstr
PolymorphicMatcher< internal::HasSubstrMatcher< internal::string > > HasSubstr(const internal::string &substring)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8803
grpc_shutdown
GRPCAPI void grpc_shutdown(void)
Definition: init.cc:209
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
grpc::testing::XdsTestType::Name
static std::string Name(const ::testing::TestParamInfo< XdsTestType > &info)
Definition: xds_end2end_test_lib.h:143
gpr_setenv
void gpr_setenv(const char *name, const char *value)


grpc
Author(s):
autogenerated on Fri May 16 2025 03:01:00