xds_core_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 
16 #include <memory>
17 #include <string>
18 #include <vector>
19 
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include "absl/strings/str_cat.h"
24 
27 
28 namespace grpc {
29 namespace testing {
30 namespace {
31 
32 using ClientStats = LrsServiceImpl::ClientStats;
33 
34 //
35 // XdsClientTest - basic tests of XdsClient functionality
36 //
37 
38 using XdsClientTest = XdsEnd2endTest;
39 
40 INSTANTIATE_TEST_SUITE_P(XdsTest, XdsClientTest,
41  ::testing::Values(XdsTestType()), &XdsTestType::Name);
42 
43 // Tests that the client can handle resource wrapped in a Resource message.
44 TEST_P(XdsClientTest, ResourceWrappedInResourceMessage) {
45  CreateAndStartBackends(1);
46  balancer_->ads_service()->set_wrap_resources(true);
47  const size_t kNumRpcsPerAddress = 100;
48  EdsResourceArgs args({
49  {"locality0", CreateEndpointsForBackends()},
50  });
51  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
52  // Make sure that trying to connect works without a call.
53  channel_->GetState(true /* try_to_connect */);
54  // We need to wait for all backends to come online.
55  WaitForAllBackends(DEBUG_LOCATION);
56  // Send kNumRpcsPerAddress RPCs per server.
57  CheckRpcSendOk(DEBUG_LOCATION, kNumRpcsPerAddress * backends_.size());
58  // Each backend should have gotten 100 requests.
59  for (size_t i = 0; i < backends_.size(); ++i) {
60  EXPECT_EQ(kNumRpcsPerAddress,
61  backends_[i]->backend_service()->request_count());
62  }
63  // Check LB policy name for the channel.
64  EXPECT_EQ("xds_cluster_manager_experimental",
65  channel_->GetLoadBalancingPolicyName());
66 }
67 
68 TEST_P(XdsClientTest, ResourceTypeVersionPersistsAcrossStreamRestarts) {
69  CreateAndStartBackends(2);
70  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
71  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
72  // Wait for backends to come online.
73  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
74  // Stop balancer.
75  balancer_->Shutdown();
76  // Tell balancer to require minimum version 1 for all resource types.
77  balancer_->ads_service()->SetResourceMinVersion(kLdsTypeUrl, 1);
78  balancer_->ads_service()->SetResourceMinVersion(kRdsTypeUrl, 1);
79  balancer_->ads_service()->SetResourceMinVersion(kCdsTypeUrl, 1);
80  balancer_->ads_service()->SetResourceMinVersion(kEdsTypeUrl, 1);
81  // Update backend, just so we can be sure that the client has
82  // reconnected to the balancer.
83  args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
84  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
85  // Restart balancer.
86  balancer_->Start();
87  // Make sure client has reconnected.
88  WaitForAllBackends(DEBUG_LOCATION, 1, 2);
89 }
90 
91 // Tests that we restart all xDS requests when we reestablish the ADS call.
92 TEST_P(XdsClientTest, RestartsRequestsUponReconnection) {
93  CreateAndStartBackends(2);
94  // Manually configure use of RDS.
95  auto listener = default_listener_;
96  HttpConnectionManager http_connection_manager;
97  listener.mutable_api_listener()->mutable_api_listener()->UnpackTo(
98  &http_connection_manager);
99  auto* rds = http_connection_manager.mutable_rds();
100  rds->set_route_config_name(kDefaultRouteConfigurationName);
101  rds->mutable_config_source()->mutable_self();
102  listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
103  http_connection_manager);
104  balancer_->ads_service()->SetLdsResource(listener);
105  balancer_->ads_service()->SetRdsResource(default_route_config_);
106  const char* kNewClusterName = "new_cluster_name";
107  const char* kNewEdsServiceName = "new_eds_service_name";
108  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
109  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
110  // We need to wait for all backends to come online.
111  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
112  // Now shut down and restart the balancer. When the client
113  // reconnects, it should automatically restart the requests for all
114  // resource types.
115  balancer_->Shutdown();
116  balancer_->Start();
117  // Make sure things are still working.
118  CheckRpcSendOk(DEBUG_LOCATION, 100);
119  // Populate new EDS resource.
120  args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
121  balancer_->ads_service()->SetEdsResource(
122  BuildEdsResource(args, kNewEdsServiceName));
123  // Populate new CDS resource.
124  Cluster new_cluster = default_cluster_;
125  new_cluster.set_name(kNewClusterName);
126  new_cluster.mutable_eds_cluster_config()->set_service_name(
127  kNewEdsServiceName);
128  balancer_->ads_service()->SetCdsResource(new_cluster);
129  // Change RDS resource to point to new cluster.
130  RouteConfiguration new_route_config = default_route_config_;
131  new_route_config.mutable_virtual_hosts(0)
132  ->mutable_routes(0)
133  ->mutable_route()
134  ->set_cluster(kNewClusterName);
135  balancer_->ads_service()->SetRdsResource(new_route_config);
136  // Wait for all new backends to be used.
137  WaitForAllBackends(DEBUG_LOCATION, 1, 2);
138 }
139 
140 // Tests that the NACK for multiple bad resources includes both errors.
141 TEST_P(XdsClientTest, MultipleBadCdsResources) {
142  constexpr char kClusterName2[] = "cluster_name_2";
143  constexpr char kClusterName3[] = "cluster_name_3";
144  CreateAndStartBackends(1);
145  // Add cluster with unsupported type.
146  auto cluster = default_cluster_;
147  cluster.set_name(kClusterName2);
148  cluster.set_type(Cluster::STATIC);
149  balancer_->ads_service()->SetCdsResource(cluster);
150  // Add second cluster with the same error.
151  cluster.set_name(kClusterName3);
152  balancer_->ads_service()->SetCdsResource(cluster);
153  // Change RouteConfig to point to all clusters.
154  RouteConfiguration route_config = default_route_config_;
155  route_config.mutable_virtual_hosts(0)->clear_routes();
156  // First route: default cluster, selected based on header.
157  auto* route = route_config.mutable_virtual_hosts(0)->add_routes();
158  route->mutable_match()->set_prefix("");
159  auto* header_matcher = route->mutable_match()->add_headers();
160  header_matcher->set_name("cluster");
161  header_matcher->set_exact_match(kDefaultClusterName);
162  route->mutable_route()->set_cluster(kDefaultClusterName);
163  // Second route: cluster 2, selected based on header.
164  route = route_config.mutable_virtual_hosts(0)->add_routes();
165  route->mutable_match()->set_prefix("");
166  header_matcher = route->mutable_match()->add_headers();
167  header_matcher->set_name("cluster");
168  header_matcher->set_exact_match(kClusterName2);
169  route->mutable_route()->set_cluster(kClusterName2);
170  // Third route: cluster 3, used by default.
171  route = route_config.mutable_virtual_hosts(0)->add_routes();
172  route->mutable_match()->set_prefix("");
173  route->mutable_route()->set_cluster(kClusterName3);
174  SetRouteConfiguration(balancer_.get(), route_config);
175  // Add EDS resource.
176  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
177  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
178  // Send RPC.
179  const auto response_state = WaitForCdsNack(DEBUG_LOCATION);
180  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
181  EXPECT_THAT(
182  response_state->error_message,
183  ::testing::ContainsRegex(absl::StrCat(kClusterName2,
184  ": validation error.*"
185  "DiscoveryType is not valid.*",
186  kClusterName3,
187  ": validation error.*"
188  "DiscoveryType is not valid")));
189  // RPCs for default cluster should succeed.
190  std::vector<std::pair<std::string, std::string>> metadata_default_cluster = {
191  {"cluster", kDefaultClusterName},
192  };
193  CheckRpcSendOk(
194  DEBUG_LOCATION, 1,
195  RpcOptions().set_metadata(std::move(metadata_default_cluster)));
196  // RPCs for cluster 2 should fail.
197  std::vector<std::pair<std::string, std::string>> metadata_cluster_2 = {
198  {"cluster", kClusterName2},
199  };
200  CheckRpcSendFailure(
202  "cluster_name_2: UNAVAILABLE: invalid resource: INVALID_ARGUMENT:.*"
203  "errors parsing CDS resource.*DiscoveryType is not valid.*",
204  RpcOptions().set_metadata(std::move(metadata_cluster_2)));
205 }
206 
207 TEST_P(XdsClientTest, XdsStreamErrorPropagation) {
208  const std::string kErrorMessage = "test forced ADS stream failure";
209  balancer_->ads_service()->ForceADSFailure(
211  auto status = SendRpc();
213  "XdsStreamErrorPropagation test: RPC got error: code=%d message=%s",
214  status.error_code(), status.error_message().c_str());
216  EXPECT_THAT(status.error_message(), ::testing::HasSubstr(kErrorMessage));
217  EXPECT_THAT(status.error_message(),
218  ::testing::HasSubstr("(node ID:xds_end2end_test)"));
219 }
220 
221 //
222 // GlobalXdsClientTest - tests that need to run with a global XdsClient
223 // (this is the default in production)
224 //
225 
226 using GlobalXdsClientTest = XdsEnd2endTest;
227 
228 // Get bootstrap from env var, so that there's a global XdsClient.
229 INSTANTIATE_TEST_SUITE_P(XdsTest, GlobalXdsClientTest,
230  ::testing::Values(XdsTestType().set_bootstrap_source(
233 
234 TEST_P(GlobalXdsClientTest, MultipleChannelsShareXdsClient) {
235  CreateAndStartBackends(1);
236  const char* kNewServerName = "new-server.example.com";
237  Listener listener = default_listener_;
238  listener.set_name(kNewServerName);
239  SetListenerAndRouteConfiguration(balancer_.get(), listener,
240  default_route_config_);
241  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
242  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
243  WaitForAllBackends(DEBUG_LOCATION);
244  // Create second channel and tell it to connect to kNewServerName.
245  auto channel2 = CreateChannel(/*failover_timeout_ms=*/0, kNewServerName);
246  channel2->GetState(/*try_to_connect=*/true);
247  ASSERT_TRUE(
248  channel2->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100)));
249  // Make sure there's only one client connected.
250  EXPECT_EQ(1UL, balancer_->ads_service()->clients().size());
251 }
252 
253 TEST_P(
254  GlobalXdsClientTest,
255  MultipleChannelsShareXdsClientWithResourceUpdateAfterOneChannelGoesAway) {
256  CreateAndStartBackends(2);
257  // Test for https://github.com/grpc/grpc/issues/28468. Makes sure that the
258  // XdsClient properly handles the case where there are multiple watchers on
259  // the same resource and one of them unsubscribes.
260  const char* kNewServerName = "new-server.example.com";
261  Listener listener = default_listener_;
262  listener.set_name(kNewServerName);
263  SetListenerAndRouteConfiguration(balancer_.get(), listener,
264  default_route_config_);
265  balancer_->ads_service()->SetEdsResource(BuildEdsResource(EdsResourceArgs({
266  {"locality0", CreateEndpointsForBackends(0, 1)},
267  })));
268  WaitForBackend(DEBUG_LOCATION, 0);
269  // Create second channel and tell it to connect to kNewServerName.
270  auto channel2 = CreateChannel(/*failover_timeout_ms=*/0, kNewServerName);
271  channel2->GetState(/*try_to_connect=*/true);
272  ASSERT_TRUE(
273  channel2->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100)));
274  // Now, destroy the new channel, send an EDS update to use a different backend
275  // and test that the channel switches to that backend.
276  channel2.reset();
277  // This sleep is needed to be able to reproduce the bug and to give time for
278  // the buggy unsubscription to take place.
279  // TODO(yashykt): Figure out a way to do this without the sleep.
281  balancer_->ads_service()->SetEdsResource(BuildEdsResource(EdsResourceArgs({
282  {"locality0", CreateEndpointsForBackends(1, 2)},
283  })));
284  WaitForBackend(DEBUG_LOCATION, 1);
285 }
286 
287 // Tests that the NACK for multiple bad LDS resources includes both errors.
288 // This needs to be in GlobalXdsClientTest because the only way to request
289 // two LDS resources in the same XdsClient is for two channels to share
290 // the same XdsClient.
291 TEST_P(GlobalXdsClientTest, MultipleBadLdsResources) {
292  CreateAndStartBackends(1);
293  constexpr char kServerName2[] = "server.other.com";
294  constexpr char kServerName3[] = "server.another.com";
295  auto listener = default_listener_;
296  listener.clear_api_listener();
297  balancer_->ads_service()->SetLdsResource(listener);
298  listener.set_name(kServerName2);
299  balancer_->ads_service()->SetLdsResource(listener);
300  listener = default_listener_;
301  listener.set_name(kServerName3);
302  SetListenerAndRouteConfiguration(balancer_.get(), listener,
303  default_route_config_);
304  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
305  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
306  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
307  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
308  EXPECT_THAT(response_state->error_message,
310  kServerName,
311  ": validation error.*"
312  "Listener has neither address nor ApiListener.*")));
313  // Need to create a second channel to subscribe to a second LDS resource.
314  auto channel2 = CreateChannel(0, kServerName2);
315  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
316  {
317  ClientContext context;
318  EchoRequest request;
319  request.set_message(kRequestMessage);
320  EchoResponse response;
321  grpc::Status status = stub2->Echo(&context, request, &response);
322  EXPECT_FALSE(status.ok());
323  // Wait for second NACK to be reported to xDS server.
324  const auto response_state = WaitForLdsNack(DEBUG_LOCATION);
325  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
326  EXPECT_THAT(response_state->error_message,
328  kServerName,
329  ": validation error.*"
330  "Listener has neither address nor ApiListener.*")));
331  EXPECT_THAT(response_state->error_message,
333  kServerName2,
334  ": validation error.*"
335  "Listener has neither address nor ApiListener.*")));
336  }
337  // Now start a new channel with a third server name, this one with a
338  // valid resource.
339  auto channel3 = CreateChannel(0, kServerName3);
340  auto stub3 = grpc::testing::EchoTestService::NewStub(channel3);
341  {
342  ClientContext context;
343  EchoRequest request;
344  request.set_message(kRequestMessage);
345  EchoResponse response;
346  grpc::Status status = stub3->Echo(&context, request, &response);
347  EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
348  << " message=" << status.error_message();
349  }
350 }
351 
352 // Tests that we don't trigger does-not-exist callbacks for a resource
353 // that was previously valid but is updated to be invalid.
354 TEST_P(GlobalXdsClientTest, InvalidListenerStillExistsIfPreviouslyCached) {
355  CreateAndStartBackends(1);
356  // Set up valid resources and check that the channel works.
357  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
358  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
359  CheckRpcSendOk(DEBUG_LOCATION);
360  // Now send an update changing the Listener to be invalid.
361  auto listener = default_listener_;
362  listener.clear_api_listener();
363  balancer_->ads_service()->SetLdsResource(listener);
364  const auto response_state = WaitForLdsNack(DEBUG_LOCATION, StatusCode::OK);
365  ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
366  EXPECT_THAT(response_state->error_message,
368  kServerName,
369  ": validation error.*"
370  "Listener has neither address nor ApiListener")));
371  CheckRpcSendOk(DEBUG_LOCATION);
372 }
373 
374 //
375 // TimeoutTest - tests xDS initial timeout handling
376 //
377 
378 class TimeoutTest : public XdsEnd2endTest {
379  protected:
380  void SetUp() override {
381  InitClient(BootstrapBuilder(), /*lb_expected_authority=*/"",
382  /*xds_resource_does_not_exist_timeout_ms=*/2000);
383  }
384 };
385 
386 // Enable RDS, so that we can test all resource types.
387 // Run with bootstrap from env var so that multiple channels share the same
388 // XdsClient (needed for testing the timeout for the 2nd LDS and RDS resource).
390  XdsTest, TimeoutTest,
391  ::testing::Values(
392  XdsTestType().set_enable_rds_testing().set_bootstrap_source(
395 
396 TEST_P(TimeoutTest, LdsServerIgnoresRequest) {
397  balancer_->ads_service()->IgnoreResourceType(kLdsTypeUrl);
398  CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
399  absl::StrCat("empty address list: ", kServerName,
400  ": xDS listener resource does not exist"),
401  RpcOptions().set_timeout_ms(4000));
402 }
403 
404 TEST_P(TimeoutTest, LdsResourceNotPresentInRequest) {
405  balancer_->ads_service()->UnsetResource(kLdsTypeUrl, kServerName);
406  CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
407  absl::StrCat("empty address list: ", kServerName,
408  ": xDS listener resource does not exist"),
409  RpcOptions().set_timeout_ms(4000));
410 }
411 
412 TEST_P(TimeoutTest, LdsSecondResourceNotPresentInRequest) {
413  ASSERT_NE(GetParam().bootstrap_source(),
415  << "This test cannot use bootstrap from channel args, because it "
416  "needs two channels to use the same XdsClient instance.";
417  CreateAndStartBackends(1);
418  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
419  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
420  CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
421  // Create second channel for a new server name.
422  // This should fail because there is no LDS resource for this server name.
423  const char* kNewServerName = "new-server.example.com";
424  auto channel2 = CreateChannel(/*failover_timeout_ms=*/0, kNewServerName);
425  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
426  ClientContext context;
427  EchoRequest request;
428  EchoResponse response;
429  RpcOptions rpc_options;
430  rpc_options.set_timeout_ms(4000).SetupRpc(&context, &request);
431  auto status =
432  SendRpcMethod(stub2.get(), rpc_options, &context, request, &response);
434  EXPECT_THAT(status.error_message(),
435  absl::StrCat("empty address list: ", kNewServerName,
436  ": xDS listener resource does not exist"));
437 }
438 
439 TEST_P(TimeoutTest, RdsServerIgnoresRequest) {
440  balancer_->ads_service()->IgnoreResourceType(kRdsTypeUrl);
441  CheckRpcSendFailure(
443  absl::StrCat("empty address list: ", kDefaultRouteConfigurationName,
444  ": xDS route configuration resource does not exist"),
445  RpcOptions().set_timeout_ms(4000));
446 }
447 
448 TEST_P(TimeoutTest, RdsResourceNotPresentInRequest) {
449  balancer_->ads_service()->UnsetResource(kRdsTypeUrl,
450  kDefaultRouteConfigurationName);
451  CheckRpcSendFailure(
453  absl::StrCat("empty address list: ", kDefaultRouteConfigurationName,
454  ": xDS route configuration resource does not exist"),
455  RpcOptions().set_timeout_ms(4000));
456 }
457 
458 TEST_P(TimeoutTest, RdsSecondResourceNotPresentInRequest) {
459  ASSERT_NE(GetParam().bootstrap_source(),
461  << "This test cannot use bootstrap from channel args, because it "
462  "needs two channels to use the same XdsClient instance.";
463  CreateAndStartBackends(1);
464  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
465  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
466  CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
467  // Add listener for 2nd channel, but no RDS resource.
468  const char* kNewServerName = "new-server.example.com";
469  const char* kNewRouteConfigName = "rds_resource_does_not_exist";
470  Listener listener = default_listener_;
471  listener.set_name(kNewServerName);
472  HttpConnectionManager http_connection_manager =
473  ClientHcmAccessor().Unpack(listener);
474  auto* rds = http_connection_manager.mutable_rds();
475  rds->set_route_config_name(kNewRouteConfigName);
476  rds->mutable_config_source()->mutable_self();
477  ClientHcmAccessor().Pack(http_connection_manager, &listener);
478  balancer_->ads_service()->SetLdsResource(listener);
479  // Create second channel for a new server name.
480  // This should fail because the LDS resource points to a non-existent RDS
481  // resource.
482  auto channel2 = CreateChannel(/*failover_timeout_ms=*/0, kNewServerName);
483  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
484  ClientContext context;
485  EchoRequest request;
486  EchoResponse response;
487  RpcOptions rpc_options;
488  rpc_options.set_timeout_ms(4000).SetupRpc(&context, &request);
489  auto status =
490  SendRpcMethod(stub2.get(), rpc_options, &context, request, &response);
492  EXPECT_THAT(
493  status.error_message(),
494  absl::StrCat("empty address list: ", kNewRouteConfigName,
495  ": xDS route configuration resource does not exist"));
496 }
497 
498 TEST_P(TimeoutTest, CdsServerIgnoresRequest) {
499  balancer_->ads_service()->IgnoreResourceType(kCdsTypeUrl);
500  CheckRpcSendFailure(
502  absl::StrCat("CDS resource \"", kDefaultClusterName, "\" does not exist"),
503  RpcOptions().set_timeout_ms(4000));
504 }
505 
506 TEST_P(TimeoutTest, CdsResourceNotPresentInRequest) {
507  balancer_->ads_service()->UnsetResource(kCdsTypeUrl, kDefaultClusterName);
508  CheckRpcSendFailure(
510  absl::StrCat("CDS resource \"", kDefaultClusterName, "\" does not exist"),
511  RpcOptions().set_timeout_ms(4000));
512 }
513 
514 TEST_P(TimeoutTest, CdsSecondResourceNotPresentInRequest) {
515  CreateAndStartBackends(1);
516  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
517  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
518  CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
519  // Change route config to point to non-existing cluster.
520  const char* kNewClusterName = "new_cluster_name";
521  RouteConfiguration route_config = default_route_config_;
522  route_config.mutable_virtual_hosts(0)
523  ->mutable_routes(0)
524  ->mutable_route()
525  ->set_cluster(kNewClusterName);
526  balancer_->ads_service()->SetRdsResource(route_config);
527  // New cluster times out.
528  // May need to wait a bit for the change to propagate to the client.
529  SendRpcsUntil(
531  [&](const RpcResult& result) {
532  if (result.status.ok()) return true; // Keep going.
533  EXPECT_EQ(StatusCode::UNAVAILABLE, result.status.error_code());
534  EXPECT_EQ(absl::StrCat("CDS resource \"", kNewClusterName,
535  "\" does not exist"),
536  result.status.error_message());
537  return false;
538  },
539  /*timeout_ms=*/30000, RpcOptions().set_timeout_ms(4000));
540 }
541 
542 TEST_P(TimeoutTest, EdsServerIgnoresRequest) {
543  balancer_->ads_service()->IgnoreResourceType(kEdsTypeUrl);
544  CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
545  // TODO(roth): Improve this error message as part of
546  // https://github.com/grpc/grpc/issues/22883.
547  "no children in weighted_target policy: ",
548  RpcOptions().set_timeout_ms(4000));
549 }
550 
551 TEST_P(TimeoutTest, EdsResourceNotPresentInRequest) {
552  // No need to remove EDS resource, since the test suite does not add it
553  // by default.
554  CheckRpcSendFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
555  // TODO(roth): Improve this error message as part of
556  // https://github.com/grpc/grpc/issues/22883.
557  "no children in weighted_target policy: ",
558  RpcOptions().set_timeout_ms(4000));
559 }
560 
561 TEST_P(TimeoutTest, EdsSecondResourceNotPresentInRequest) {
562  CreateAndStartBackends(1);
563  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
564  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
565  CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
566  // New cluster that points to a non-existant EDS resource.
567  const char* kNewClusterName = "new_cluster_name";
568  Cluster cluster = default_cluster_;
569  cluster.set_name(kNewClusterName);
570  cluster.mutable_eds_cluster_config()->set_service_name(
571  "eds_service_name_does_not_exist");
572  balancer_->ads_service()->SetCdsResource(cluster);
573  // Now add a route pointing to the new cluster.
574  RouteConfiguration route_config = default_route_config_;
575  auto* route = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
576  *route_config.mutable_virtual_hosts(0)->add_routes() = *route;
577  route->mutable_match()->set_path("/grpc.testing.EchoTestService/Echo1");
578  route->mutable_route()->set_cluster(kNewClusterName);
579  balancer_->ads_service()->SetRdsResource(route_config);
580  // New EDS resource times out.
581  // May need to wait a bit for the RDS change to propagate to the client.
582  SendRpcsUntil(
584  [](const RpcResult& result) {
585  if (result.status.ok()) return true; // Keep going.
586  EXPECT_EQ(StatusCode::UNAVAILABLE, result.status.error_code());
587  EXPECT_EQ(result.status.error_message(),
588  // TODO(roth): Improve this error message as part of
589  // https://github.com/grpc/grpc/issues/22883.
590  "no children in weighted_target policy: ");
591  return false;
592  },
593  /*timeout_ms=*/30000,
594  RpcOptions().set_rpc_method(METHOD_ECHO1).set_timeout_ms(4000));
595 }
596 
597 TEST_P(TimeoutTest, ServerDoesNotResendAfterAdsStreamRestart) {
598  CreateAndStartBackends(1);
599  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
600  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
601  CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(4000));
602  // Stop balancer.
603  balancer_->Shutdown();
604  // Tell balancer to require minimum version 1 for all resource types
605  // and to not reply to the requests.
606  balancer_->ads_service()->SetResourceMinVersion(kLdsTypeUrl, 1);
607  balancer_->ads_service()->IgnoreResourceType(kLdsTypeUrl);
608  balancer_->ads_service()->SetResourceMinVersion(kRdsTypeUrl, 1);
609  balancer_->ads_service()->IgnoreResourceType(kRdsTypeUrl);
610  balancer_->ads_service()->SetResourceMinVersion(kCdsTypeUrl, 1);
611  balancer_->ads_service()->IgnoreResourceType(kCdsTypeUrl);
612  balancer_->ads_service()->SetResourceMinVersion(kEdsTypeUrl, 1);
613  balancer_->ads_service()->IgnoreResourceType(kEdsTypeUrl);
614  // Restart balancer.
615  balancer_->Start();
616  // Send RPCs for long enough to cover the ADS stream restart delay,
617  // the stream restart, and then the resulting timeout period, just to
618  // be sure that the channel continues to use the resources from before
619  // the restart.
620  absl::Time deadline =
622  do {
623  CheckRpcSendOk(DEBUG_LOCATION);
624  } while (absl::Now() < deadline);
625 }
626 
627 //
628 // BootstrapSourceTest - tests different bootstrap sources
629 //
630 
631 using BootstrapSourceTest = XdsEnd2endTest;
632 
634  XdsTest, BootstrapSourceTest,
635  ::testing::Values(
636  XdsTestType().set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
637  XdsTestType().set_bootstrap_source(XdsTestType::kBootstrapFromFile)),
639 
640 TEST_P(BootstrapSourceTest, Vanilla) {
641  CreateAndStartBackends(1);
642  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
643  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
644  // Increase timeout, since kBootstrapFromFile takes more time on busy
645  // test machines. (We've seen at least one occurrence where it's
646  // taken over 10 seconds.)
647  CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(15000));
648 }
649 
650 //
651 // XdsFederationTest - tests xDS federation
652 //
653 
654 class XdsFederationTest : public XdsEnd2endTest {
655  protected:
656  XdsFederationTest() : authority_balancer_(CreateAndStartBalancer()) {}
657 
658  void SetUp() override {
659  // Each test will use a slightly different bootstrap config,
660  // so SetUp() is intentionally empty here, and the real
661  // setup (calling of InitClient()) is moved into each test.
662  }
663 
664  void TearDown() override {
665  authority_balancer_->Shutdown();
667  }
668 
669  std::unique_ptr<BalancerServerThread> authority_balancer_;
670 };
671 
672 // Get bootstrap from env var, so that there's a global XdsClient.
673 // Runs with RDS so that we know all resource types work properly.
675  XdsTest, XdsFederationTest,
676  ::testing::Values(
677  XdsTestType()
678  .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar)
679  .set_enable_rds_testing()),
681 
682 // Channel is created with URI "xds:server.example.com".
683 // Bootstrap config default client listener template uses new-style name with
684 // authority "xds.example.com".
685 TEST_P(XdsFederationTest, FederationTargetNoAuthorityWithResourceTemplate) {
686  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
687  const char* kAuthority = "xds.example.com";
688  const char* kNewListenerTemplate =
689  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
690  "client/%s?psm_project_id=1234";
691  const char* kNewListenerName =
692  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
693  "client/server.example.com?psm_project_id=1234";
694  const char* kNewRouteConfigName =
695  "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
696  "new_route_config_name";
697  const char* kNewEdsServiceName =
698  "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
699  "new_edsservice_name";
700  const char* kNewClusterName =
701  "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
702  "new_cluster_name";
703  BootstrapBuilder builder = BootstrapBuilder();
704  builder.SetClientDefaultListenerResourceNameTemplate(kNewListenerTemplate);
705  builder.AddAuthority(
706  kAuthority, absl::StrCat("localhost:", authority_balancer_->port()),
707  // Note we will not use the client_listener_resource_name_template field
708  // in the authority.
709  "xdstp://xds.example.com/envoy.config.listener.v3.Listener"
710  "client/%s?client_listener_resource_name_template_not_in_use");
711  InitClient(builder);
712  CreateAndStartBackends(2, /*xds_enabled=*/true);
713  // Eds for the new authority balancer.
714  EdsResourceArgs args =
715  EdsResourceArgs({{"locality0", CreateEndpointsForBackends()}});
716  authority_balancer_->ads_service()->SetEdsResource(
717  BuildEdsResource(args, kNewEdsServiceName));
718  // New cluster
719  Cluster new_cluster = default_cluster_;
720  new_cluster.set_name(kNewClusterName);
721  new_cluster.mutable_eds_cluster_config()->set_service_name(
722  kNewEdsServiceName);
723  authority_balancer_->ads_service()->SetCdsResource(new_cluster);
724  // New Route
725  RouteConfiguration new_route_config = default_route_config_;
726  new_route_config.set_name(kNewRouteConfigName);
727  new_route_config.mutable_virtual_hosts(0)
728  ->mutable_routes(0)
729  ->mutable_route()
730  ->set_cluster(kNewClusterName);
731  // New Listener
732  Listener listener = default_listener_;
733  listener.set_name(kNewListenerName);
734  SetListenerAndRouteConfiguration(authority_balancer_.get(), listener,
735  new_route_config);
736  WaitForAllBackends(DEBUG_LOCATION);
737 }
738 
739 // Channel is created with URI "xds://xds.example.com/server.example.com".
740 // In bootstrap config, authority has no client listener template, so we use the
741 // default.
742 TEST_P(XdsFederationTest, FederationTargetAuthorityDefaultResourceTemplate) {
743  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
744  const char* kAuthority = "xds.example.com";
745  const char* kNewServerName = "whee%/server.example.com";
746  const char* kNewListenerName =
747  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
748  "whee%25/server.example.com";
749  const char* kNewRouteConfigName =
750  "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
751  "new_route_config_name";
752  const char* kNewEdsServiceName =
753  "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
754  "edsservice_name";
755  const char* kNewClusterName =
756  "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
757  "cluster_name";
758  BootstrapBuilder builder = BootstrapBuilder();
759  builder.AddAuthority(kAuthority,
760  absl::StrCat("localhost:", authority_balancer_->port()));
761  InitClient(builder);
762  CreateAndStartBackends(2, /*xds_enabled=*/true);
763  // Eds for 2 balancers to ensure RPCs sent using current stub go to backend 0
764  // and RPCs sent using the new stub go to backend 1.
765  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
766  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
767  args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
768  authority_balancer_->ads_service()->SetEdsResource(
769  BuildEdsResource(args, kNewEdsServiceName));
770  // New cluster
771  Cluster new_cluster = default_cluster_;
772  new_cluster.set_name(kNewClusterName);
773  new_cluster.mutable_eds_cluster_config()->set_service_name(
774  kNewEdsServiceName);
775  authority_balancer_->ads_service()->SetCdsResource(new_cluster);
776  // New Route
777  RouteConfiguration new_route_config = default_route_config_;
778  new_route_config.set_name(kNewRouteConfigName);
779  new_route_config.mutable_virtual_hosts(0)
780  ->mutable_routes(0)
781  ->mutable_route()
782  ->set_cluster(kNewClusterName);
783  // New Listener
784  Listener listener = default_listener_;
785  listener.set_name(kNewListenerName);
786  SetListenerAndRouteConfiguration(authority_balancer_.get(), listener,
787  new_route_config);
788  // Ensure update has reached and send 10 RPCs to the current stub.
789  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
790  // Create second channel to new target uri and send 1 RPC.
791  auto channel2 =
792  CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority);
793  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
794  ClientContext context;
795  EchoRequest request;
796  RpcOptions().SetupRpc(&context, &request);
797  EchoResponse response;
798  grpc::Status status = stub2->Echo(&context, request, &response);
799  EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
800  << " message=" << status.error_message();
801  // We should be reaching backend 1, not 0, as balanced by the authority xds
802  // server.
803  EXPECT_EQ(0U, backends_[0]->backend_service()->request_count());
804  EXPECT_EQ(1U, backends_[1]->backend_service()->request_count());
805 }
806 
807 // Channel is created with URI "xds://xds.example.com/server.example.com".
808 // Bootstrap entry for that authority specifies a client listener name template.
809 TEST_P(XdsFederationTest, FederationTargetAuthorityWithResourceTemplate) {
810  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
811  const char* kAuthority = "xds.example.com";
812  const char* kNewServerName = "whee%/server.example.com";
813  const char* kNewListenerTemplate =
814  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
815  "client/%s?psm_project_id=1234";
816  const char* kNewListenerName =
817  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
818  "client/whee%25/server.example.com?psm_project_id=1234";
819  const char* kNewRouteConfigName =
820  "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
821  "new_route_config_name";
822  const char* kNewEdsServiceName =
823  "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
824  "edsservice_name";
825  const char* kNewClusterName =
826  "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
827  "cluster_name";
828  BootstrapBuilder builder = BootstrapBuilder();
829  builder.AddAuthority(kAuthority,
830  absl::StrCat("localhost:", authority_balancer_->port()),
831  kNewListenerTemplate);
832  InitClient(builder);
833  CreateAndStartBackends(2, /*xds_enabled=*/true);
834  // Eds for 2 balancers to ensure RPCs sent using current stub go to backend 0
835  // and RPCs sent using the new stub go to backend 1.
836  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
837  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
838  args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
839  authority_balancer_->ads_service()->SetEdsResource(
840  BuildEdsResource(args, kNewEdsServiceName));
841  // New cluster
842  Cluster new_cluster = default_cluster_;
843  new_cluster.set_name(kNewClusterName);
844  new_cluster.mutable_eds_cluster_config()->set_service_name(
845  kNewEdsServiceName);
846  authority_balancer_->ads_service()->SetCdsResource(new_cluster);
847  // New Route
848  RouteConfiguration new_route_config = default_route_config_;
849  new_route_config.set_name(kNewRouteConfigName);
850  new_route_config.mutable_virtual_hosts(0)
851  ->mutable_routes(0)
852  ->mutable_route()
853  ->set_cluster(kNewClusterName);
854  // New Listener
855  Listener listener = default_listener_;
856  listener.set_name(kNewListenerName);
857  SetListenerAndRouteConfiguration(authority_balancer_.get(), listener,
858  new_route_config);
859  // Ensure update has reached and send 10 RPCs to the current stub.
860  WaitForAllBackends(DEBUG_LOCATION, 0, 1);
861  // Create second channel to new target uri and send 1 RPC.
862  auto channel2 =
863  CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority);
864  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
865  ClientContext context;
866  EchoRequest request;
867  RpcOptions().SetupRpc(&context, &request);
868  EchoResponse response;
869  grpc::Status status = stub2->Echo(&context, request, &response);
870  EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
871  << " message=" << status.error_message();
872  // We should be reaching backend 1, not 0, as balanced by the authority xds
873  // server.
874  EXPECT_EQ(0U, backends_[0]->backend_service()->request_count());
875  EXPECT_EQ(1U, backends_[1]->backend_service()->request_count());
876 }
877 
878 TEST_P(XdsFederationTest, TargetUriAuthorityUnknown) {
879  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
880  const char* kAuthority = "xds.example.com";
881  const char* kNewServerName = "whee%/server.example.com";
882  const char* kNewListenerTemplate =
883  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
884  "client/%s?psm_project_id=1234";
885  BootstrapBuilder builder = BootstrapBuilder();
886  builder.AddAuthority(
887  kAuthority, absl::StrCat("localhost:", grpc_pick_unused_port_or_die()),
888  kNewListenerTemplate);
889  InitClient(builder);
890  auto channel2 = CreateChannel(
891  /*failover_timeout_ms=*/0, kNewServerName, "xds.unknown.com");
892  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
893  ClientContext context;
894  EchoRequest request;
895  RpcOptions().SetupRpc(&context, &request);
896  EchoResponse response;
897  grpc::Status status = stub2->Echo(&context, request, &response);
899  EXPECT_EQ(status.error_message(),
900  "Invalid target URI -- authority not found for xds.unknown.com");
901  ASSERT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel2->GetState(false));
902 }
903 
904 TEST_P(XdsFederationTest, RdsResourceNameAuthorityUnknown) {
905  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
906  const char* kAuthority = "xds.example.com";
907  const char* kNewServerName = "whee%/server.example.com";
908  const char* kNewListenerTemplate =
909  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
910  "client/%s?psm_project_id=1234";
911  const char* kNewListenerName =
912  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
913  "client/whee%25/server.example.com?psm_project_id=1234";
914  const char* kNewRouteConfigName =
915  "xdstp://xds.unknown.com/envoy.config.route.v3.RouteConfiguration/"
916  "new_route_config_name";
917  BootstrapBuilder builder = BootstrapBuilder();
918  builder.AddAuthority(kAuthority,
919  absl::StrCat("localhost:", authority_balancer_->port()),
920  kNewListenerTemplate);
921  InitClient(builder);
922  // New RouteConfig
923  RouteConfiguration new_route_config = default_route_config_;
924  new_route_config.set_name(kNewRouteConfigName);
925  // New Listener
926  Listener listener = default_listener_;
927  listener.set_name(kNewListenerName);
928  SetListenerAndRouteConfiguration(authority_balancer_.get(), listener,
929  new_route_config);
930  // Channel should report TRANSIENT_FAILURE.
931  auto channel2 =
932  CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority);
933  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
934  ClientContext context;
935  EchoRequest request;
936  RpcOptions().SetupRpc(&context, &request);
937  EchoResponse response;
938  grpc::Status status = stub2->Echo(&context, request, &response);
940  EXPECT_EQ(status.error_message(),
941  absl::StrCat(
942  kNewRouteConfigName,
943  ": UNAVAILABLE: authority \"xds.unknown.com\" not present in "
944  "bootstrap config"));
945  ASSERT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel2->GetState(false));
946 }
947 
948 TEST_P(XdsFederationTest, CdsResourceNameAuthorityUnknown) {
949  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
950  const char* kAuthority = "xds.example.com";
951  const char* kNewServerName = "whee%/server.example.com";
952  const char* kNewListenerTemplate =
953  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
954  "client/%s?psm_project_id=1234";
955  const char* kNewListenerName =
956  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
957  "client/whee%25/server.example.com?psm_project_id=1234";
958  const char* kNewRouteConfigName =
959  "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
960  "new_route_config_name";
961  const char* kNewClusterName =
962  "xdstp://xds.unknown.com/envoy.config.cluster.v3.Cluster/"
963  "cluster_name";
964  BootstrapBuilder builder = BootstrapBuilder();
965  builder.AddAuthority(kAuthority,
966  absl::StrCat("localhost:", authority_balancer_->port()),
967  kNewListenerTemplate);
968  InitClient(builder);
969  // New Route
970  RouteConfiguration new_route_config = default_route_config_;
971  new_route_config.set_name(kNewRouteConfigName);
972  new_route_config.mutable_virtual_hosts(0)
973  ->mutable_routes(0)
974  ->mutable_route()
975  ->set_cluster(kNewClusterName);
976  // New Listener
977  Listener listener = default_listener_;
978  listener.set_name(kNewListenerName);
979  SetListenerAndRouteConfiguration(authority_balancer_.get(), listener,
980  new_route_config);
981  // Channel should report TRANSIENT_FAILURE.
982  auto channel2 =
983  CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority);
984  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
985  ClientContext context;
986  EchoRequest request;
987  RpcOptions().SetupRpc(&context, &request);
988  EchoResponse response;
989  grpc::Status status = stub2->Echo(&context, request, &response);
991  EXPECT_EQ(status.error_message(),
992  absl::StrCat(
993  kNewClusterName,
994  ": UNAVAILABLE: authority \"xds.unknown.com\" not present in "
995  "bootstrap config"));
996  ASSERT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel2->GetState(false));
997 }
998 
999 TEST_P(XdsFederationTest, EdsResourceNameAuthorityUnknown) {
1000  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
1001  const char* kAuthority = "xds.example.com";
1002  const char* kNewServerName = "whee%/server.example.com";
1003  const char* kNewListenerTemplate =
1004  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1005  "client/%s?psm_project_id=1234";
1006  const char* kNewListenerName =
1007  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1008  "client/whee%25/server.example.com?psm_project_id=1234";
1009  const char* kNewRouteConfigName =
1010  "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
1011  "new_route_config_name";
1012  const char* kNewEdsServiceName =
1013  "xdstp://xds.unknown.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
1014  "edsservice_name";
1015  const char* kNewClusterName =
1016  "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
1017  "cluster_name";
1018  BootstrapBuilder builder = BootstrapBuilder();
1019  builder.AddAuthority(kAuthority,
1020  absl::StrCat("localhost:", authority_balancer_->port()),
1021  kNewListenerTemplate);
1022  InitClient(builder);
1023  // New cluster
1024  Cluster new_cluster = default_cluster_;
1025  new_cluster.set_name(kNewClusterName);
1026  new_cluster.mutable_eds_cluster_config()->set_service_name(
1027  kNewEdsServiceName);
1028  authority_balancer_->ads_service()->SetCdsResource(new_cluster);
1029  // New Route
1030  RouteConfiguration new_route_config = default_route_config_;
1031  new_route_config.set_name(kNewRouteConfigName);
1032  new_route_config.mutable_virtual_hosts(0)
1033  ->mutable_routes(0)
1034  ->mutable_route()
1035  ->set_cluster(kNewClusterName);
1036  // New Listener
1037  Listener listener = default_listener_;
1038  listener.set_name(kNewListenerName);
1039  SetListenerAndRouteConfiguration(authority_balancer_.get(), listener,
1040  new_route_config);
1041  // Channel should report TRANSIENT_FAILURE.
1042  auto channel2 =
1043  CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority);
1044  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
1045  ClientContext context;
1046  EchoRequest request;
1047  RpcOptions().SetupRpc(&context, &request);
1048  EchoResponse response;
1049  grpc::Status status = stub2->Echo(&context, request, &response);
1050  EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE);
1051  EXPECT_EQ(status.error_message(),
1052  // TODO(roth): Improve this error message as part of
1053  // https://github.com/grpc/grpc/issues/22883.
1054  "no children in weighted_target policy: ");
1055  ASSERT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel2->GetState(false));
1056 }
1057 
1058 // Setting server_listener_resource_name_template to start with "xdstp:" and
1059 // look up xds server under an authority map.
1060 TEST_P(XdsFederationTest, FederationServer) {
1061  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
1062  const char* kAuthority = "xds.example.com";
1063  const char* kNewListenerTemplate =
1064  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1065  "client/%s?psm_project_id=1234";
1066  const char* kNewServerListenerTemplate =
1067  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1068  "server/%s?psm_project_id=1234";
1069  const char* kNewListenerName =
1070  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1071  "client/server.example.com?psm_project_id=1234";
1072  const char* kNewRouteConfigName =
1073  "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
1074  "new_route_config_name";
1075  const char* kNewEdsServiceName =
1076  "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
1077  "new_edsservice_name";
1078  const char* kNewClusterName =
1079  "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
1080  "new_cluster_name";
1081  BootstrapBuilder builder = BootstrapBuilder();
1082  builder.SetClientDefaultListenerResourceNameTemplate(kNewListenerTemplate);
1083  builder.SetServerListenerResourceNameTemplate(kNewServerListenerTemplate);
1084  builder.AddAuthority(
1085  kAuthority, absl::StrCat("localhost:", authority_balancer_->port()),
1086  // Note we will not use the client_listener_resource_name_template field
1087  // in the authority.
1088  "xdstp://xds.example.com/envoy.config.listener.v3.Listener"
1089  "client/%s?client_listener_resource_name_template_not_in_use");
1090  InitClient(builder);
1091  CreateAndStartBackends(2, /*xds_enabled=*/true);
1092  // Eds for new authority balancer.
1093  EdsResourceArgs args =
1094  EdsResourceArgs({{"locality0", CreateEndpointsForBackends()}});
1095  authority_balancer_->ads_service()->SetEdsResource(
1096  BuildEdsResource(args, kNewEdsServiceName));
1097  // New cluster
1098  Cluster new_cluster = default_cluster_;
1099  new_cluster.set_name(kNewClusterName);
1100  new_cluster.mutable_eds_cluster_config()->set_service_name(
1101  kNewEdsServiceName);
1102  authority_balancer_->ads_service()->SetCdsResource(new_cluster);
1103  // New Route
1104  RouteConfiguration new_route_config = default_route_config_;
1105  new_route_config.set_name(kNewRouteConfigName);
1106  new_route_config.mutable_virtual_hosts(0)
1107  ->mutable_routes(0)
1108  ->mutable_route()
1109  ->set_cluster(kNewClusterName);
1110  // New Listener
1111  Listener listener = default_listener_;
1112  listener.set_name(kNewListenerName);
1113  SetListenerAndRouteConfiguration(authority_balancer_.get(), listener,
1114  new_route_config);
1115  // New Server Listeners
1116  for (int port : GetBackendPorts()) {
1117  Listener server_listener = default_server_listener_;
1118  server_listener.set_name(absl::StrCat(
1119  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/server/",
1120  ipv6_only_ ? "%5B::1%5D:" : "127.0.0.1:", port,
1121  "?psm_project_id=1234"));
1122  server_listener.mutable_address()->mutable_socket_address()->set_port_value(
1123  port);
1124  authority_balancer_->ads_service()->SetLdsResource(server_listener);
1125  }
1126  WaitForAllBackends(DEBUG_LOCATION);
1127 }
1128 
1129 //
1130 // XdsFederationDisabledTest
1131 //
1132 
1133 using XdsFederationDisabledTest = XdsEnd2endTest;
1134 
1135 // Runs with RDS so that we know all resource types work properly.
1137  XdsTest, XdsFederationDisabledTest,
1138  ::testing::Values(XdsTestType().set_enable_rds_testing()),
1140 
1141 TEST_P(XdsFederationDisabledTest, FederationDisabledWithNewStyleNames) {
1142  const char* kNewRouteConfigName =
1143  "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
1144  "new_route_config_name";
1145  const char* kNewClusterName =
1146  "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
1147  "cluster_name";
1148  const char* kNewEdsResourceName =
1149  "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
1150  "edsservice_name";
1151  InitClient();
1152  CreateAndStartBackends(1);
1153  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends()}});
1154  balancer_->ads_service()->SetEdsResource(
1155  BuildEdsResource(args, kNewEdsResourceName));
1156  // New cluster
1157  Cluster new_cluster = default_cluster_;
1158  new_cluster.set_name(kNewClusterName);
1159  new_cluster.mutable_eds_cluster_config()->set_service_name(
1160  kNewEdsResourceName);
1161  balancer_->ads_service()->SetCdsResource(new_cluster);
1162  // New RouteConfig
1163  RouteConfiguration new_route_config = default_route_config_;
1164  new_route_config.set_name(kNewRouteConfigName);
1165  new_route_config.mutable_virtual_hosts(0)
1166  ->mutable_routes(0)
1167  ->mutable_route()
1168  ->set_cluster(kNewClusterName);
1169  SetListenerAndRouteConfiguration(balancer_.get(), default_listener_,
1170  new_route_config);
1171  // Channel should work.
1172  CheckRpcSendOk(DEBUG_LOCATION);
1173 }
1174 
1175 //
1176 // XdsFederationLoadReportingTest - xDS federation and load reporting
1177 //
1178 
1179 using XdsFederationLoadReportingTest = XdsFederationTest;
1180 
1181 // Get bootstrap from env var, so that there's a global XdsClient.
1182 // Runs with and without RDS.
1184  XdsTest, XdsFederationLoadReportingTest,
1185  ::testing::Values(
1186  XdsTestType()
1187  .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar)
1188  .set_enable_load_reporting(),
1189  XdsTestType()
1190  .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar)
1191  .set_enable_load_reporting()
1192  .set_enable_rds_testing()),
1194 
1195 // Channel is created with URI "xds://xds.example.com/server.example.com".
1196 // Bootstrap entry for that authority specifies a client listener name template.
1197 // Sending traffic to both default balancer and authority balancer and checking
1198 // load reporting with each one.
1199 TEST_P(XdsFederationLoadReportingTest, FederationMultipleLoadReportingTest) {
1200  ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_FEDERATION");
1201  const char* kAuthority = "xds.example.com";
1202  const char* kNewServerName = "whee%/server.example.com";
1203  const char* kNewListenerTemplate =
1204  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1205  "client/%s?psm_project_id=1234";
1206  const char* kNewListenerName =
1207  "xdstp://xds.example.com/envoy.config.listener.v3.Listener/"
1208  "client/whee%25/server.example.com?psm_project_id=1234";
1209  const char* kNewRouteConfigName =
1210  "xdstp://xds.example.com/envoy.config.route.v3.RouteConfiguration/"
1211  "new_route_config_name";
1212  const char* kNewEdsServiceName =
1213  "xdstp://xds.example.com/envoy.config.endpoint.v3.ClusterLoadAssignment/"
1214  "edsservice_name";
1215  const char* kNewClusterName =
1216  "xdstp://xds.example.com/envoy.config.cluster.v3.Cluster/"
1217  "cluster_name";
1218  const size_t kNumRpcsToDefaultBalancer = 5;
1219  const size_t kNumRpcsToAuthorityBalancer = 10;
1220  BootstrapBuilder builder = BootstrapBuilder();
1221  builder.AddAuthority(kAuthority,
1222  absl::StrCat("localhost:", authority_balancer_->port()),
1223  kNewListenerTemplate);
1224  InitClient(builder);
1225  CreateAndStartBackends(2, /*xds_enabled=*/true);
1226  // Eds for 2 balancers to ensure RPCs sent using current stub go to backend 0
1227  // and RPCs sent using the new stub go to backend 1.
1228  EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}});
1229  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1230  args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}});
1231  authority_balancer_->ads_service()->SetEdsResource(
1232  BuildEdsResource(args, kNewEdsServiceName));
1233  authority_balancer_->lrs_service()->set_cluster_names({kNewClusterName});
1234  // New cluster
1235  Cluster new_cluster = default_cluster_;
1236  new_cluster.set_name(kNewClusterName);
1237  new_cluster.mutable_lrs_server()->mutable_self();
1238  new_cluster.mutable_eds_cluster_config()->set_service_name(
1239  kNewEdsServiceName);
1240  authority_balancer_->ads_service()->SetCdsResource(new_cluster);
1241  // New Route
1242  RouteConfiguration new_route_config = default_route_config_;
1243  new_route_config.set_name(kNewRouteConfigName);
1244  new_route_config.mutable_virtual_hosts(0)
1245  ->mutable_routes(0)
1246  ->mutable_route()
1247  ->set_cluster(kNewClusterName);
1248  // New Listener
1249  Listener listener = default_listener_;
1250  listener.set_name(kNewListenerName);
1251  SetListenerAndRouteConfiguration(authority_balancer_.get(), listener,
1252  new_route_config);
1253  // Send kNumRpcsToDefaultBalancer RPCs to the current stub.
1254  CheckRpcSendOk(DEBUG_LOCATION, kNumRpcsToDefaultBalancer);
1255  // Create second channel to new target uri.
1256  auto channel2 =
1257  CreateChannel(/*failover_timeout_ms=*/0, kNewServerName, kAuthority);
1258  auto stub2 = grpc::testing::EchoTestService::NewStub(channel2);
1259  // Send kNumRpcsToAuthorityBalancer on the second channel.
1260  for (size_t i = 0; i < kNumRpcsToAuthorityBalancer; ++i) {
1261  ClientContext context;
1262  EchoRequest request;
1263  RpcOptions().SetupRpc(&context, &request);
1264  EchoResponse response;
1265  grpc::Status status = stub2->Echo(&context, request, &response);
1266  EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
1267  << " message=" << status.error_message();
1268  }
1269  // Each backend should have received the expected number of RPCs,
1270  // and the load report also reflect the correct numbers.
1271  EXPECT_EQ(kNumRpcsToAuthorityBalancer,
1272  backends_[1]->backend_service()->request_count());
1273  EXPECT_EQ(kNumRpcsToDefaultBalancer,
1274  backends_[0]->backend_service()->request_count());
1275  // Load report for authority LRS.
1276  std::vector<ClientStats> authority_load_report =
1277  authority_balancer_->lrs_service()->WaitForLoadReport();
1278  ASSERT_EQ(authority_load_report.size(), 1UL);
1279  ClientStats& authority_client_stats = authority_load_report.front();
1280  EXPECT_EQ(kNumRpcsToAuthorityBalancer,
1281  authority_client_stats.total_successful_requests());
1282  EXPECT_EQ(0U, authority_client_stats.total_requests_in_progress());
1283  EXPECT_EQ(kNumRpcsToAuthorityBalancer,
1284  authority_client_stats.total_issued_requests());
1285  EXPECT_EQ(0U, authority_client_stats.total_error_requests());
1286  EXPECT_EQ(0U, authority_client_stats.total_dropped_requests());
1287  EXPECT_EQ(1U, authority_balancer_->lrs_service()->request_count());
1288  EXPECT_EQ(1U, authority_balancer_->lrs_service()->response_count());
1289  // Load report for default LRS.
1290  std::vector<ClientStats> default_load_report =
1291  balancer_->lrs_service()->WaitForLoadReport();
1292  ASSERT_EQ(default_load_report.size(), 1UL);
1293  ClientStats& default_client_stats = default_load_report.front();
1294  EXPECT_EQ(kNumRpcsToDefaultBalancer,
1295  default_client_stats.total_successful_requests());
1296  EXPECT_EQ(0U, default_client_stats.total_requests_in_progress());
1297  EXPECT_EQ(kNumRpcsToDefaultBalancer,
1298  default_client_stats.total_issued_requests());
1299  EXPECT_EQ(0U, default_client_stats.total_error_requests());
1300  EXPECT_EQ(0U, default_client_stats.total_dropped_requests());
1301  EXPECT_EQ(1U, balancer_->lrs_service()->request_count());
1302  EXPECT_EQ(1U, balancer_->lrs_service()->response_count());
1303 }
1304 
1305 //
1306 // SecureNamingTest - test that the right authority is used for the xDS server
1307 //
1308 
1309 class SecureNamingTest : public XdsEnd2endTest {
1310  public:
1311  void SetUp() override {
1312  // Each test calls InitClient() on its own.
1313  }
1314 };
1315 
1316 INSTANTIATE_TEST_SUITE_P(XdsTest, SecureNamingTest,
1317  ::testing::Values(XdsTestType()), &XdsTestType::Name);
1318 
1319 // Tests that secure naming check passes if target name is expected.
1320 TEST_P(SecureNamingTest, TargetNameIsExpected) {
1321  InitClient(BootstrapBuilder(), /*lb_expected_authority=*/"localhost:%d");
1322  CreateAndStartBackends(4);
1323  EdsResourceArgs args({
1324  {"locality0", CreateEndpointsForBackends()},
1325  });
1326  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1327  CheckRpcSendOk(DEBUG_LOCATION);
1328 }
1329 
1330 // Tests that secure naming check fails if target name is unexpected.
1331 TEST_P(SecureNamingTest, TargetNameIsUnexpected) {
1332  GTEST_FLAG_SET(death_test_style, "threadsafe");
1333  InitClient(BootstrapBuilder(),
1334  /*lb_expected_authority=*/"incorrect_server_name");
1335  CreateAndStartBackends(4);
1336  EdsResourceArgs args({
1337  {"locality0", CreateEndpointsForBackends()},
1338  });
1339  balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
1340  // Make sure that we blow up (via abort() from the security connector) when
1341  // the name from the balancer doesn't match expectations.
1342  ASSERT_DEATH_IF_SUPPORTED({ CheckRpcSendOk(DEBUG_LOCATION); }, "");
1343 }
1344 
1345 } // namespace
1346 } // namespace testing
1347 } // namespace grpc
1348 
1349 int main(int argc, char** argv) {
1350  grpc::testing::TestEnvironment env(&argc, argv);
1351  ::testing::InitGoogleTest(&argc, argv);
1352  // Make the backup poller poll very frequently in order to pick up
1353  // updates from all the subchannels's FDs.
1354  GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1);
1355 #if TARGET_OS_IPHONE
1356  // Workaround Apple CFStream bug
1357  gpr_setenv("grpc_cfstream", "0");
1358 #endif
1359  grpc_init();
1360  const auto result = RUN_ALL_TESTS();
1361  grpc_shutdown();
1362  return result;
1363 }
grpc::EXPECT_THAT
EXPECT_THAT(status.error_message(), ::testing::HasSubstr("subject_token_type"))
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
grpc::testing::XdsEnd2endTest::TearDown
void TearDown() override
Definition: xds_end2end_test_lib.cc:519
_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
testing::ContainsRegex
PolymorphicMatcher< internal::MatchesRegexMatcher > ContainsRegex(const internal::RE *regex)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8835
GTEST_FLAG_SET
#define GTEST_FLAG_SET(name, value)
Definition: googletest/googletest/include/gtest/internal/gtest-port.h:2219
grpc::testing::XdsTestType::kBootstrapFromEnvVar
@ kBootstrapFromEnvVar
Definition: xds_end2end_test_lib.h:64
ipv6_only_
bool ipv6_only_
Definition: client_lb_end2end_test.cc:217
env_var
Definition: win/process.c:40
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
grpc::testing::kCdsTypeUrl
constexpr char kCdsTypeUrl[]
Definition: xds_server.h:55
absl::Time
Definition: third_party/abseil-cpp/absl/time/time.h:642
grpc
Definition: grpcpp/alarm.h:33
route
XdsRouteConfigResource::Route route
Definition: xds_resolver.cc:337
grpc::testing::kRdsTypeUrl
constexpr char kRdsTypeUrl[]
Definition: xds_server.h:53
grpc::testing::XdsTestType::kBootstrapFromChannelArg
@ kBootstrapFromChannelArg
Definition: xds_end2end_test_lib.h:62
backends_
std::vector< std::unique_ptr< BackendServiceImpl > > backends_
Definition: client_channel_stress_test.cc:333
grpc::ASSERT_EQ
ASSERT_EQ(sizeof(valid_json), fwrite(valid_json, 1, sizeof(valid_json), creds_file))
Listener
Definition: transport_common.h:31
benchmark.request
request
Definition: benchmark.py:77
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
GRPC_CHANNEL_TRANSIENT_FAILURE
@ GRPC_CHANNEL_TRANSIENT_FAILURE
Definition: include/grpc/impl/codegen/connectivity_state.h:38
grpc::testing::kErrorMessage
const char * kErrorMessage
Definition: exception_test.cc:38
grpc::testing::kEdsTypeUrl
constexpr char kEdsTypeUrl[]
Definition: xds_server.h:57
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
profile_analyzer.builder
builder
Definition: profile_analyzer.py:159
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
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
grpc.StatusCode.OK
tuple OK
Definition: src/python/grpcio/grpc/__init__.py:260
cluster
absl::string_view cluster
Definition: xds_resolver.cc:331
ASSERT_DEATH_IF_SUPPORTED
#define ASSERT_DEATH_IF_SUPPORTED(statement, regex)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-death-test.h:337
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
gpr_sleep_until
GPRAPI void gpr_sleep_until(gpr_timespec until)
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
xds_end2end_test_lib.h
grpc::testing::kLdsTypeUrl
constexpr char kLdsTypeUrl[]
Definition: xds_server.h:51
grpc::testing::INSTANTIATE_TEST_SUITE_P
INSTANTIATE_TEST_SUITE_P(HistogramTestCases, HistogramTest, ::testing::Range< int >(0, GRPC_STATS_HISTOGRAM_COUNT))
backup_poller.h
grpc::CreateChannel
std::shared_ptr< Channel > CreateChannel(const grpc::string &target, const std::shared_ptr< ChannelCredentials > &creds)
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
grpc_pick_unused_port_or_die
int grpc_pick_unused_port_or_die(void)
grpc::ASSERT_NE
ASSERT_NE(creds_file_name, nullptr)
GPR_GLOBAL_CONFIG_SET
#define GPR_GLOBAL_CONFIG_SET(name, value)
Definition: global_config_generic.h:26
tests.unit._exit_scenarios.port
port
Definition: _exit_scenarios.py:179
absl::Seconds
constexpr Duration Seconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:419
grpc::testing::XdsTestType::kBootstrapFromFile
@ kBootstrapFromFile
Definition: xds_end2end_test_lib.h:63
absl::Now
ABSL_NAMESPACE_BEGIN Time Now()
Definition: abseil-cpp/absl/time/clock.cc:39
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
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc::protobuf::util::Status
GRPC_CUSTOM_UTIL_STATUS Status
Definition: include/grpcpp/impl/codegen/config_protobuf.h:93
main
int main(int argc, char **argv)
Definition: xds_core_end2end_test.cc:1349
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
grpc::Status
Definition: include/grpcpp/impl/codegen/status.h:35
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
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
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::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
authority_balancer_
std::unique_ptr< BalancerServerThread > authority_balancer_
Definition: xds_core_end2end_test.cc:669
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:00:58