| 
					
				 | 
			
			
				@@ -259,6 +259,36 @@ class BackendServiceImpl : public BackendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Status Echo1(ServerContext* context, const EchoRequest* request, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               EchoResponse* response) override { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Backend should receive the call credentials metadata. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto call_credentials_entry = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        context->client_metadata().find(g_kCallCredsMdKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    EXPECT_NE(call_credentials_entry, context->client_metadata().end()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (call_credentials_entry != context->client_metadata().end()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    echo1_request_count_++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const auto status = TestServiceImpl::Echo1(context, request, response); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AddClient(context->peer()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Status Echo2(ServerContext* context, const EchoRequest* request, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               EchoResponse* response) override { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Backend should receive the call credentials metadata. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto call_credentials_entry = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        context->client_metadata().find(g_kCallCredsMdKey); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    EXPECT_NE(call_credentials_entry, context->client_metadata().end()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (call_credentials_entry != context->client_metadata().end()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    echo2_request_count_++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const auto status = TestServiceImpl::Echo2(context, request, response); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    AddClient(context->peer()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void Start() {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void Shutdown() {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -267,6 +297,10 @@ class BackendServiceImpl : public BackendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return clients_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  size_t Echo1RequestCount() { return echo1_request_count_; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  size_t Echo2RequestCount() { return echo2_request_count_; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void AddClient(const grpc::string& client) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_core::MutexLock lock(&clients_mu_); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -276,6 +310,8 @@ class BackendServiceImpl : public BackendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_core::Mutex mu_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_core::Mutex clients_mu_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   std::set<grpc::string> clients_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  size_t echo1_request_count_ = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  size_t echo2_request_count_ = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class ClientStats { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1356,6 +1392,34 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Status SendEcho1Rpc(EchoResponse* response = nullptr, int timeout_ms = 1000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      bool wait_for_ready = false) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const bool local_response = (response == nullptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (local_response) response = new EchoResponse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    EchoRequest request; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    request.set_message(kRequestMessage_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ClientContext context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (wait_for_ready) context.set_wait_for_ready(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Status status = stub_->Echo1(&context, request, response); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (local_response) delete response; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Status SendEcho2Rpc(EchoResponse* response = nullptr, int timeout_ms = 1000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      bool wait_for_ready = false) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const bool local_response = (response == nullptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (local_response) response = new EchoResponse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    EchoRequest request; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    request.set_message(kRequestMessage_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ClientContext context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (wait_for_ready) context.set_wait_for_ready(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Status status = stub_->Echo2(&context, request, response); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (local_response) delete response; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                       bool wait_for_ready = false) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for (size_t i = 0; i < times; ++i) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1372,6 +1436,28 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     EXPECT_FALSE(status.ok()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void CheckEcho1RpcSendOk(const size_t times = 1, const int timeout_ms = 1000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           bool wait_for_ready = false) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (size_t i = 0; i < times; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EchoResponse response; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const Status status = SendEcho1Rpc(&response, timeout_ms, wait_for_ready); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_TRUE(status.ok()) << "code=" << status.error_code() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                               << " message=" << status.error_message(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_EQ(response.message(), kRequestMessage_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void CheckEcho2RpcSendOk(const size_t times = 1, const int timeout_ms = 1000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           bool wait_for_ready = false) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (size_t i = 0; i < times; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EchoResponse response; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const Status status = SendEcho2Rpc(&response, timeout_ms, wait_for_ready); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_TRUE(status.ok()) << "code=" << status.error_code() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                               << " message=" << status.error_message(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_EQ(response.message(), kRequestMessage_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // This method could benefit test subclasses; to make it accessible 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // via bind with a qualified name, it needs to be public. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2129,26 +2215,26 @@ TEST_P(LdsTest, Timeout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   CheckRpcSendFailure(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Tests that LDS client should choose the default route (with no matching 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// specified) after unable to find a match with previous routes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 TEST_P(LdsTest, XdsRoutingPathMatching) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const char* kNewCluster1Name = "new_cluster_1"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const char* kNewCluster2Name = "new_cluster_2"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const size_t kNumRpcs = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SetNextResolution({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SetNextResolutionForLbChannelAllBalancers(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Populate new EDS resources. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AdsServiceImpl::EdsResourceArgs args({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       {"locality0", GetBackendPorts(0, 2)}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  balancers_[0]->ads_service()->SetEdsResource( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // We need to wait for all backends to come online. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  WaitForAllBackends(0, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Populate new EDS resources. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AdsServiceImpl::EdsResourceArgs args1({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       {"locality0", GetBackendPorts(2, 3)}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AdsServiceImpl::EdsResourceArgs args2({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       {"locality0", GetBackendPorts(3, 4)}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  balancers_[0]->ads_service()->SetEdsResource( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   balancers_[0]->ads_service()->SetEdsResource( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       AdsServiceImpl::BuildEdsResource(args1, kNewCluster1Name), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       kNewCluster1Name); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2163,28 +2249,34 @@ TEST_P(LdsTest, XdsRoutingPathMatching) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   new_cluster2.set_name(kNewCluster2Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   balancers_[0]->ads_service()->SetCdsResource(new_cluster2, kNewCluster2Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Change RDS resource to set up prefix matching to direct traffic to the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // first new cluster. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // second new cluster. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   RouteConfiguration new_route_config = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       balancers_[0]->ads_service()->default_route_config(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  auto* mismatched_route = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  auto* mismatched_route1 = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       new_route_config.mutable_virtual_hosts(0)->mutable_routes(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  mismatched_route->mutable_match()->set_path( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      "/grpc.testing.EchoTestService/Echo"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  mismatched_route->mutable_route()->set_cluster(kNewCluster1Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  auto* matched_route = new_route_config.mutable_virtual_hosts(0)->add_routes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  matched_route->mutable_match()->set_path( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      "/grpc.testing.EchoTestService/NewMethod"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  matched_route->mutable_route()->set_cluster(kNewCluster2Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mismatched_route1->mutable_match()->set_path( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "/grpc.testing.EchoTestService/Echo1"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mismatched_route1->mutable_route()->set_cluster(kNewCluster1Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  auto* mismatched_route2 = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      new_route_config.mutable_virtual_hosts(0)->add_routes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mismatched_route2->mutable_match()->set_path( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "/grpc.testing.EchoTestService/Echo2"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  mismatched_route2->mutable_route()->set_cluster(kNewCluster2Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  default_route->mutable_match()->set_prefix(""); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  default_route->mutable_match()->set_path(""); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  default_route->mutable_route()->set_cluster(kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Listener listener = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       balancers_[0]->ads_service()->BuildListener(new_route_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   balancers_[0]->ads_service()->SetLdsResource(listener, kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Wait for the new backend to come up. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  WaitForAllBackends(2, 3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  CheckRpcSendOk(kNumRpcs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CheckEcho1RpcSendOk(kNumRpcs, 1000, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CheckEcho2RpcSendOk(kNumRpcs, 1000, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Make sure RPCs all go to the correct backend. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (size_t i = 0; i < 4; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (i == 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->request_count()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->Echo1RequestCount()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (i == 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->Echo2RequestCount()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       EXPECT_EQ(0, backends_[i]->backend_service()->request_count()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2197,13 +2289,6 @@ TEST_P(LdsTest, XdsRoutingPrefixMatching) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const size_t kNumRpcs = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SetNextResolution({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SetNextResolutionForLbChannelAllBalancers(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  AdsServiceImpl::EdsResourceArgs args({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      {"locality0", GetBackendPorts(0, 2)}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  balancers_[0]->ads_service()->SetEdsResource( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // We need to wait for all backends to come online. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  WaitForAllBackends(0, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Populate new EDS resources. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AdsServiceImpl::EdsResourceArgs args1({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       {"locality0", GetBackendPorts(2, 3)}, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2239,15 +2324,13 @@ TEST_P(LdsTest, XdsRoutingPrefixMatching) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Listener listener = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       balancers_[0]->ads_service()->BuildListener(new_route_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   balancers_[0]->ads_service()->SetLdsResource(listener, kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Wait for the new backend to come up. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  WaitForAllBackends(3, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  CheckRpcSendOk(kNumRpcs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CheckEcho1RpcSendOk(kNumRpcs, 1000, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Make sure RPCs all go to the correct backend. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (size_t i = 0; i < 4; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (i == 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->request_count()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_EQ(kNumRpcs, backends_[i]->backend_service()->Echo1RequestCount()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      EXPECT_EQ(0, backends_[i]->backend_service()->request_count()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      EXPECT_EQ(0, backends_[i]->backend_service()->Echo1RequestCount()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2260,20 +2343,18 @@ TEST_P(LdsTest, XdsRoutingDefaultRoute) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   const size_t kNumRpcs = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SetNextResolution({}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   SetNextResolutionForLbChannelAllBalancers(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Populate new EDS resources. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AdsServiceImpl::EdsResourceArgs args({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       {"locality0", GetBackendPorts(0, 2)}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  balancers_[0]->ads_service()->SetEdsResource( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // We need to wait for all backends to come online. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  WaitForAllBackends(0, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Populate new EDS resources. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AdsServiceImpl::EdsResourceArgs args1({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       {"locality0", GetBackendPorts(2, 3)}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   AdsServiceImpl::EdsResourceArgs args2({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       {"locality0", GetBackendPorts(3, 4)}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  balancers_[0]->ads_service()->SetEdsResource( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   balancers_[0]->ads_service()->SetEdsResource( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       AdsServiceImpl::BuildEdsResource(args1, kNewCluster1Name), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       kNewCluster1Name); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2287,8 +2368,8 @@ TEST_P(LdsTest, XdsRoutingDefaultRoute) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Cluster new_cluster2 = balancers_[0]->ads_service()->default_cluster(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   new_cluster2.set_name(kNewCluster2Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   balancers_[0]->ads_service()->SetCdsResource(new_cluster2, kNewCluster2Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Change RDS resource to set up prefix matching to direct traffic to the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // second new cluster. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Change RDS resource to set up prefix matching and path matching that do 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // match the traffic, so traffic goes to the default cluster. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   RouteConfiguration new_route_config = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       balancers_[0]->ads_service()->default_route_config(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   auto* mismatched_route1 = 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2299,7 +2380,7 @@ TEST_P(LdsTest, XdsRoutingDefaultRoute) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   auto* mismatched_route2 = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       new_route_config.mutable_virtual_hosts(0)->add_routes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   mismatched_route2->mutable_match()->set_path( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      "/grpc.testing.EchoTestService/EchoMismatch"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      "/grpc.testing.EchoTestService/Echo1"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   mismatched_route2->mutable_route()->set_cluster(kNewCluster2Name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   default_route->mutable_match()->set_prefix(""); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2308,7 +2389,6 @@ TEST_P(LdsTest, XdsRoutingDefaultRoute) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Listener listener = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       balancers_[0]->ads_service()->BuildListener(new_route_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   balancers_[0]->ads_service()->SetLdsResource(listener, kDefaultResourceName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Wait for the new backend to come up. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   WaitForAllBackends(0, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   CheckRpcSendOk(kNumRpcs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Make sure RPCs all go to the correct backend. 
			 |