diff --git a/CMakeLists.txt b/CMakeLists.txt index 8adb44e6730..dd466a84655 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16308,7 +16308,7 @@ add_executable(xds_credentials_end2end_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h test/cpp/end2end/test_service_impl.cc - test/cpp/end2end/xds/xds_credentials_end2end_test.cc + test/cpp/end2end/xds_credentials_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googlemock/src/gmock-all.cc ) @@ -16517,8 +16517,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.grpc.pb.h src/cpp/server/csds/csds.cc test/cpp/end2end/test_service_impl.cc - test/cpp/end2end/xds/xds_end2end_test.cc - test/cpp/end2end/xds/xds_server.cc + test/cpp/end2end/xds_end2end_test.cc third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googlemock/src/gmock-all.cc ) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index c2488ecdc5e..5408c7081e6 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -5989,7 +5989,6 @@ targets: run: false language: c++ headers: - - test/cpp/end2end/counted_service.h - test/cpp/end2end/test_service_impl.h src: - src/proto/grpc/lb/v1/load_balancer.proto @@ -8059,7 +8058,7 @@ targets: - src/proto/grpc/testing/echo_messages.proto - src/proto/grpc/testing/simple_messages.proto - test/cpp/end2end/test_service_impl.cc - - test/cpp/end2end/xds/xds_credentials_end2end_test.cc + - test/cpp/end2end/xds_credentials_end2end_test.cc deps: - grpc++_test_util - name: xds_credentials_test @@ -8078,9 +8077,7 @@ targets: language: c++ headers: - src/cpp/server/csds/csds.h - - test/cpp/end2end/counted_service.h - test/cpp/end2end/test_service_impl.h - - test/cpp/end2end/xds/xds_server.h src: - src/proto/grpc/testing/duplicate/echo_duplicate.proto - src/proto/grpc/testing/echo.proto @@ -8118,8 +8115,7 @@ targets: - src/proto/grpc/testing/xds/v3/tls.proto - src/cpp/server/csds/csds.cc - test/cpp/end2end/test_service_impl.cc - - test/cpp/end2end/xds/xds_end2end_test.cc - - test/cpp/end2end/xds/xds_server.cc + - test/cpp/end2end/xds_end2end_test.cc deps: - grpc++_test_config - grpc++_test_util diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index ecef2777045..c67548d4946 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -47,15 +47,6 @@ grpc_cc_library( ], ) -grpc_cc_library( - name = "counted_service", - testonly = True, - hdrs = ["counted_service.h"], - deps = [ - "//:grpc", - ], -) - grpc_cc_library( name = "interceptors_util", testonly = True, @@ -505,7 +496,6 @@ grpc_cc_test( flaky = True, # TODO(b/150567713) tags = ["no_windows"], # TODO(jtattermusch): fix test on windows deps = [ - ":counted_service", ":test_service_impl", "//:gpr", "//:grpc", @@ -521,6 +511,62 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "xds_end2end_test", + size = "large", + srcs = ["xds_end2end_test.cc"], + data = [ + "//src/core/tsi/test_creds:badclient.key", + "//src/core/tsi/test_creds:badclient.pem", + "//src/core/tsi/test_creds:ca.pem", + "//src/core/tsi/test_creds:client.key", + "//src/core/tsi/test_creds:client.pem", + "//src/core/tsi/test_creds:server1.key", + "//src/core/tsi/test_creds:server1.pem", + ], + external_deps = [ + "gtest", + ], + flaky = True, # TODO(b/144705388) + shard_count = 50, + tags = [ + "no_test_ios", + "no_windows", + ], # TODO(jtattermusch): fix test on windows + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//:grpc_resolver_fake", + "//:grpcpp_csds", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", + "//src/proto/grpc/testing/xds:ads_for_test_proto", + "//src/proto/grpc/testing/xds:cds_for_test_proto", + "//src/proto/grpc/testing/xds:eds_for_test_proto", + "//src/proto/grpc/testing/xds:lds_rds_for_test_proto", + "//src/proto/grpc/testing/xds:lrs_for_test_proto", + "//src/proto/grpc/testing/xds/v3:ads_proto", + "//src/proto/grpc/testing/xds/v3:aggregate_cluster_proto", + "//src/proto/grpc/testing/xds/v3:cluster_proto", + "//src/proto/grpc/testing/xds/v3:discovery_proto", + "//src/proto/grpc/testing/xds/v3:endpoint_proto", + "//src/proto/grpc/testing/xds/v3:fault_common_proto", + "//src/proto/grpc/testing/xds/v3:fault_proto", + "//src/proto/grpc/testing/xds/v3:http_connection_manager_proto", + "//src/proto/grpc/testing/xds/v3:listener_proto", + "//src/proto/grpc/testing/xds/v3:lrs_proto", + "//src/proto/grpc/testing/xds/v3:route_proto", + "//src/proto/grpc/testing/xds/v3:router_proto", + "//src/proto/grpc/testing/xds/v3:tls_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "proto_server_reflection_test", srcs = ["proto_server_reflection_test.cc"], @@ -812,6 +858,25 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "xds_credentials_end2end_test", + srcs = ["xds_credentials_end2end_test.cc"], + external_deps = [ + "gtest", + ], + tags = ["no_test_ios"], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "admin_services_end2end_test", srcs = ["admin_services_end2end_test.cc"], diff --git a/test/cpp/end2end/counted_service.h b/test/cpp/end2end/counted_service.h deleted file mode 100644 index 4d875acc65d..00000000000 --- a/test/cpp/end2end/counted_service.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright 2017 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#ifndef GRPC_TEST_CPP_END2END_COUNTED_SERVICE_H -#define GRPC_TEST_CPP_END2END_COUNTED_SERVICE_H - -#include "src/core/lib/gprpp/sync.h" - -namespace grpc { -namespace testing { - -// A wrapper around an RPC service implementation that provides request and -// response counting. -template -class CountedService : public ServiceType { - public: - size_t request_count() { - grpc_core::MutexLock lock(&mu_); - return request_count_; - } - - size_t response_count() { - grpc_core::MutexLock lock(&mu_); - return response_count_; - } - - void IncreaseResponseCount() { - grpc_core::MutexLock lock(&mu_); - ++response_count_; - } - void IncreaseRequestCount() { - grpc_core::MutexLock lock(&mu_); - ++request_count_; - } - - void ResetCounters() { - grpc_core::MutexLock lock(&mu_); - request_count_ = 0; - response_count_ = 0; - } - - private: - grpc_core::Mutex mu_; - size_t request_count_ ABSL_GUARDED_BY(mu_) = 0; - size_t response_count_ ABSL_GUARDED_BY(mu_) = 0; -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_END2END_COUNTED_SERVICE_H diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 11b8115e188..a11c684a829 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -58,7 +58,6 @@ #include "test/core/util/port.h" #include "test/core/util/resolve_localhost_ip46.h" #include "test/core/util/test_config.h" -#include "test/cpp/end2end/counted_service.h" #include "test/cpp/end2end/test_service_impl.h" #include "test/cpp/util/test_config.h" @@ -96,6 +95,42 @@ constexpr char kDefaultServiceConfig[] = " ]\n" "}"; +template +class CountedService : public ServiceType { + public: + size_t request_count() { + grpc::internal::MutexLock lock(&mu_); + return request_count_; + } + + size_t response_count() { + grpc::internal::MutexLock lock(&mu_); + return response_count_; + } + + void IncreaseResponseCount() { + grpc::internal::MutexLock lock(&mu_); + ++response_count_; + } + void IncreaseRequestCount() { + grpc::internal::MutexLock lock(&mu_); + ++request_count_; + } + + void ResetCounters() { + grpc::internal::MutexLock lock(&mu_); + request_count_ = 0; + response_count_ = 0; + } + + protected: + grpc::internal::Mutex mu_; + + private: + size_t request_count_ = 0; + size_t response_count_ = 0; +}; + using BackendService = CountedService; using BalancerService = CountedService; @@ -137,8 +172,9 @@ class BackendServiceImpl : public BackendService { clients_.insert(client); } + grpc::internal::Mutex mu_; grpc::internal::Mutex clients_mu_; - std::set clients_ ABSL_GUARDED_BY(&clients_mu_); + std::set clients_; }; std::string Ip4ToPackedString(const char* ip_str) { diff --git a/test/cpp/end2end/xds/BUILD b/test/cpp/end2end/xds/BUILD deleted file mode 100644 index 5db4b558a4c..00000000000 --- a/test/cpp/end2end/xds/BUILD +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2017 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") - -licenses(["notice"]) - -grpc_package( - name = "test/cpp/end2end/xds", - visibility = "public", -) # Allows external users to implement end2end tests. - -grpc_cc_library( - name = "xds_server", - testonly = True, - srcs = ["xds_server.cc"], - hdrs = ["xds_server.h"], - external_deps = [ - "gtest", - ], - deps = [ - "//:gpr", - "//:grpc", - "//:grpc++", - "//src/proto/grpc/testing/xds:ads_for_test_proto", - "//src/proto/grpc/testing/xds:lrs_for_test_proto", - "//src/proto/grpc/testing/xds/v3:ads_proto", - "//src/proto/grpc/testing/xds/v3:cluster_proto", - "//src/proto/grpc/testing/xds/v3:discovery_proto", - "//src/proto/grpc/testing/xds/v3:endpoint_proto", - "//src/proto/grpc/testing/xds/v3:listener_proto", - "//src/proto/grpc/testing/xds/v3:lrs_proto", - "//src/proto/grpc/testing/xds/v3:route_proto", - "//test/core/util:grpc_test_util", - "//test/cpp/end2end:counted_service", - ], -) - -grpc_cc_test( - name = "xds_end2end_test", - size = "large", - srcs = ["xds_end2end_test.cc"], - data = [ - "//src/core/tsi/test_creds:badclient.key", - "//src/core/tsi/test_creds:badclient.pem", - "//src/core/tsi/test_creds:ca.pem", - "//src/core/tsi/test_creds:client.key", - "//src/core/tsi/test_creds:client.pem", - "//src/core/tsi/test_creds:server1.key", - "//src/core/tsi/test_creds:server1.pem", - ], - external_deps = [ - "gtest", - ], - flaky = True, # TODO(b/144705388) - shard_count = 50, - tags = [ - "no_test_ios", - "no_windows", - ], # TODO(jtattermusch): fix test on windows - deps = [ - ":xds_server", - "//:gpr", - "//:grpc", - "//:grpc++", - "//:grpc_resolver_fake", - "//:grpcpp_csds", - "//src/proto/grpc/testing:echo_messages_proto", - "//src/proto/grpc/testing:echo_proto", - "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//src/proto/grpc/testing/xds:cds_for_test_proto", - "//src/proto/grpc/testing/xds:eds_for_test_proto", - "//src/proto/grpc/testing/xds:lds_rds_for_test_proto", - "//src/proto/grpc/testing/xds/v3:aggregate_cluster_proto", - "//src/proto/grpc/testing/xds/v3:cluster_proto", - "//src/proto/grpc/testing/xds/v3:endpoint_proto", - "//src/proto/grpc/testing/xds/v3:fault_common_proto", - "//src/proto/grpc/testing/xds/v3:fault_proto", - "//src/proto/grpc/testing/xds/v3:http_connection_manager_proto", - "//src/proto/grpc/testing/xds/v3:listener_proto", - "//src/proto/grpc/testing/xds/v3:route_proto", - "//src/proto/grpc/testing/xds/v3:router_proto", - "//src/proto/grpc/testing/xds/v3:tls_proto", - "//test/core/util:grpc_test_util", - "//test/cpp/end2end:counted_service", - "//test/cpp/end2end:test_service_impl", - "//test/cpp/util:test_config", - "//test/cpp/util:test_util", - ], -) - -grpc_cc_test( - name = "xds_credentials_end2end_test", - srcs = ["xds_credentials_end2end_test.cc"], - external_deps = [ - "gtest", - ], - tags = ["no_test_ios"], - deps = [ - "//:gpr", - "//:grpc", - "//:grpc++", - "//src/proto/grpc/testing:echo_messages_proto", - "//src/proto/grpc/testing:echo_proto", - "//test/core/util:grpc_test_util", - "//test/cpp/end2end:test_service_impl", - "//test/cpp/util:test_util", - ], -) diff --git a/test/cpp/end2end/xds/xds_server.cc b/test/cpp/end2end/xds/xds_server.cc deleted file mode 100644 index f9ac5a18f0c..00000000000 --- a/test/cpp/end2end/xds/xds_server.cc +++ /dev/null @@ -1,257 +0,0 @@ -// -// Copyright 2017 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include "test/cpp/end2end/xds/xds_server.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include "absl/types/optional.h" - -#include - -#include "src/core/lib/address_utils/parse_address.h" -#include "src/core/lib/gprpp/sync.h" -#include "src/proto/grpc/testing/xds/ads_for_test.grpc.pb.h" -#include "src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/ads.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/discovery.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/lrs.grpc.pb.h" - -namespace grpc { -namespace testing { - -// -// AdsServiceImpl -// - -void AdsServiceImpl::SetResource(google::protobuf::Any resource, - const std::string& type_url, - const std::string& name) { - grpc_core::MutexLock lock(&ads_mu_); - ResourceTypeState& resource_type_state = resource_map_[type_url]; - ++resource_type_state.resource_type_version; - ResourceState& resource_state = resource_type_state.resource_name_map[name]; - resource_state.resource_type_version = - resource_type_state.resource_type_version; - resource_state.resource = std::move(resource); - gpr_log(GPR_INFO, - "ADS[%p]: Updating %s resource %s; resource_type_version now %u", - this, type_url.c_str(), name.c_str(), - resource_type_state.resource_type_version); - for (SubscriptionState* subscription : resource_state.subscriptions) { - subscription->update_queue->emplace_back(type_url, name); - } -} - -void AdsServiceImpl::UnsetResource(const std::string& type_url, - const std::string& name) { - grpc_core::MutexLock lock(&ads_mu_); - ResourceTypeState& resource_type_state = resource_map_[type_url]; - ++resource_type_state.resource_type_version; - ResourceState& resource_state = resource_type_state.resource_name_map[name]; - resource_state.resource_type_version = - resource_type_state.resource_type_version; - resource_state.resource.reset(); - gpr_log(GPR_INFO, - "ADS[%p]: Unsetting %s resource %s; resource_type_version now %u", - this, type_url.c_str(), name.c_str(), - resource_type_state.resource_type_version); - for (SubscriptionState* subscription : resource_state.subscriptions) { - subscription->update_queue->emplace_back(type_url, name); - } -} - -// Checks whether the client needs to receive a newer version of -// the resource. -bool AdsServiceImpl::ClientNeedsResourceUpdate( - const ResourceTypeState& resource_type_state, - const ResourceState& resource_state, int client_resource_type_version) { - return client_resource_type_version < - resource_type_state.resource_type_version && - resource_state.resource_type_version <= - resource_type_state.resource_type_version; -} - -// Subscribes to a resource if not already subscribed: -// 1. Sets the update_queue field in subscription_state. -// 2. Adds subscription_state to resource_state->subscriptions. -bool AdsServiceImpl::MaybeSubscribe(const std::string& resource_type, - const std::string& resource_name, - SubscriptionState* subscription_state, - ResourceState* resource_state, - UpdateQueue* update_queue) { - // The update_queue will be null if we were not previously subscribed. - if (subscription_state->update_queue != nullptr) return false; - subscription_state->update_queue = update_queue; - resource_state->subscriptions.emplace(subscription_state); - gpr_log(GPR_INFO, "ADS[%p]: subscribe to resource type %s name %s state %p", - this, resource_type.c_str(), resource_name.c_str(), - &subscription_state); - return true; -} - -// Removes subscriptions for resources no longer present in the -// current request. -void AdsServiceImpl::ProcessUnsubscriptions( - const std::string& resource_type, - const std::set& resources_in_current_request, - SubscriptionNameMap* subscription_name_map, - ResourceNameMap* resource_name_map) { - for (auto it = subscription_name_map->begin(); - it != subscription_name_map->end();) { - const std::string& resource_name = it->first; - SubscriptionState& subscription_state = it->second; - if (resources_in_current_request.find(resource_name) != - resources_in_current_request.end()) { - ++it; - continue; - } - gpr_log(GPR_INFO, "ADS[%p]: Unsubscribe to type=%s name=%s state=%p", this, - resource_type.c_str(), resource_name.c_str(), &subscription_state); - auto resource_it = resource_name_map->find(resource_name); - GPR_ASSERT(resource_it != resource_name_map->end()); - auto& resource_state = resource_it->second; - resource_state.subscriptions.erase(&subscription_state); - if (resource_state.subscriptions.empty() && - !resource_state.resource.has_value()) { - resource_name_map->erase(resource_it); - } - it = subscription_name_map->erase(it); - } -} - -void AdsServiceImpl::Start() { - grpc_core::MutexLock lock(&ads_mu_); - ads_done_ = false; -} - -void AdsServiceImpl::Shutdown() { - { - grpc_core::MutexLock lock(&ads_mu_); - if (!ads_done_) { - ads_done_ = true; - ads_cond_.SignalAll(); - } - resource_type_response_state_.clear(); - } - gpr_log(GPR_INFO, "ADS[%p]: shut down", this); -} - -// -// LrsServiceImpl::ClientStats -// - -uint64_t LrsServiceImpl::ClientStats::total_successful_requests() const { - uint64_t sum = 0; - for (auto& p : locality_stats_) { - sum += p.second.total_successful_requests; - } - return sum; -} - -uint64_t LrsServiceImpl::ClientStats::total_requests_in_progress() const { - uint64_t sum = 0; - for (auto& p : locality_stats_) { - sum += p.second.total_requests_in_progress; - } - return sum; -} - -uint64_t LrsServiceImpl::ClientStats::total_error_requests() const { - uint64_t sum = 0; - for (auto& p : locality_stats_) { - sum += p.second.total_error_requests; - } - return sum; -} - -uint64_t LrsServiceImpl::ClientStats::total_issued_requests() const { - uint64_t sum = 0; - for (auto& p : locality_stats_) { - sum += p.second.total_issued_requests; - } - return sum; -} - -uint64_t LrsServiceImpl::ClientStats::dropped_requests( - const std::string& category) const { - auto iter = dropped_requests_.find(category); - GPR_ASSERT(iter != dropped_requests_.end()); - return iter->second; -} - -LrsServiceImpl::ClientStats& LrsServiceImpl::ClientStats::operator+=( - const ClientStats& other) { - for (const auto& p : other.locality_stats_) { - locality_stats_[p.first] += p.second; - } - total_dropped_requests_ += other.total_dropped_requests_; - for (const auto& p : other.dropped_requests_) { - dropped_requests_[p.first] += p.second; - } - return *this; -} - -// -// LrsServiceImpl -// - -void LrsServiceImpl::Start() { - { - grpc_core::MutexLock lock(&lrs_mu_); - lrs_done_ = false; - } - { - grpc_core::MutexLock lock(&load_report_mu_); - result_queue_.clear(); - } -} - -void LrsServiceImpl::Shutdown() { - { - grpc_core::MutexLock lock(&lrs_mu_); - if (!lrs_done_) { - lrs_done_ = true; - lrs_cv_.SignalAll(); - } - } - gpr_log(GPR_INFO, "LRS[%p]: shut down", this); -} - -std::vector LrsServiceImpl::WaitForLoadReport() { - grpc_core::MutexLock lock(&load_report_mu_); - grpc_core::CondVar cv; - if (result_queue_.empty()) { - load_report_cond_ = &cv; - while (result_queue_.empty()) { - cv.Wait(&load_report_mu_); - } - load_report_cond_ = nullptr; - } - std::vector result = std::move(result_queue_.front()); - result_queue_.pop_front(); - return result; -} - -} // namespace testing -} // namespace grpc diff --git a/test/cpp/end2end/xds/xds_server.h b/test/cpp/end2end/xds/xds_server.h deleted file mode 100644 index 32e0835f8ae..00000000000 --- a/test/cpp/end2end/xds/xds_server.h +++ /dev/null @@ -1,877 +0,0 @@ -// -// Copyright 2017 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#ifndef GRPC_TEST_CPP_END2END_XDS_XDS_SERVER_H -#define GRPC_TEST_CPP_END2END_XDS_XDS_SERVER_H - -#include -#include -#include -#include -#include - -#include -#include - -#include "absl/types/optional.h" - -#include - -#include "src/core/lib/address_utils/parse_address.h" -#include "src/core/lib/gprpp/sync.h" -#include "src/proto/grpc/testing/xds/ads_for_test.grpc.pb.h" -#include "src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/ads.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/cluster.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/discovery.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/listener.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/lrs.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/route.grpc.pb.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/counted_service.h" - -namespace grpc { -namespace testing { - -constexpr char kLdsTypeUrl[] = - "type.googleapis.com/envoy.config.listener.v3.Listener"; -constexpr char kRdsTypeUrl[] = - "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"; -constexpr char kCdsTypeUrl[] = - "type.googleapis.com/envoy.config.cluster.v3.Cluster"; -constexpr char kEdsTypeUrl[] = - "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"; - -constexpr char kLdsV2TypeUrl[] = "type.googleapis.com/envoy.api.v2.Listener"; -constexpr char kRdsV2TypeUrl[] = - "type.googleapis.com/envoy.api.v2.RouteConfiguration"; -constexpr char kCdsV2TypeUrl[] = "type.googleapis.com/envoy.api.v2.Cluster"; -constexpr char kEdsV2TypeUrl[] = - "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment"; - -// An ADS service implementation. -class AdsServiceImpl : public std::enable_shared_from_this { - public: - // State for a given xDS resource type. - struct ResponseState { - enum State { - NOT_SENT, // No response sent yet. - SENT, // Response was sent, but no ACK/NACK received. - ACKED, // ACK received. - NACKED, // NACK received; error_message will contain the error. - }; - State state = NOT_SENT; - std::string error_message; - }; - - AdsServiceImpl() - : v2_rpc_service_(this, /*is_v2=*/true), - v3_rpc_service_(this, /*is_v2=*/false) {} - - bool seen_v2_client() const { return seen_v2_client_; } - bool seen_v3_client() const { return seen_v3_client_; } - - ::envoy::service::discovery::v2::AggregatedDiscoveryService::Service* - v2_rpc_service() { - return &v2_rpc_service_; - } - - ::envoy::service::discovery::v3::AggregatedDiscoveryService::Service* - v3_rpc_service() { - return &v3_rpc_service_; - } - - // Sets a resource to a particular value, overwriting any previous value. - void SetResource(google::protobuf::Any resource, const std::string& type_url, - const std::string& name); - - // Removes a resource from the server's state. - void UnsetResource(const std::string& type_url, const std::string& name); - - void SetLdsResource(const ::envoy::config::listener::v3::Listener& listener) { - google::protobuf::Any resource; - resource.PackFrom(listener); - SetResource(std::move(resource), kLdsTypeUrl, listener.name()); - } - - void SetRdsResource( - const ::envoy::config::route::v3::RouteConfiguration& route) { - google::protobuf::Any resource; - resource.PackFrom(route); - SetResource(std::move(resource), kRdsTypeUrl, route.name()); - } - - void SetCdsResource(const ::envoy::config::cluster::v3::Cluster& cluster) { - google::protobuf::Any resource; - resource.PackFrom(cluster); - SetResource(std::move(resource), kCdsTypeUrl, cluster.name()); - } - - void SetEdsResource( - const ::envoy::config::endpoint::v3::ClusterLoadAssignment& assignment) { - google::protobuf::Any resource; - resource.PackFrom(assignment); - SetResource(std::move(resource), kEdsTypeUrl, assignment.cluster_name()); - } - - // Tells the server to ignore requests from the client for a given - // resource type. - void IgnoreResourceType(const std::string& type_url) { - grpc_core::MutexLock lock(&ads_mu_); - resource_types_to_ignore_.emplace(type_url); - } - - // Sets the minimum version that the server will accept for a given - // resource type. Will cause a gmock expectation failure if we see a - // lower version. - void SetResourceMinVersion(const std::string& type_url, int version) { - grpc_core::MutexLock lock(&ads_mu_); - resource_type_min_versions_[type_url] = version; - } - - // Get the latest response state for each resource type. - ResponseState GetResponseState(const std::string& type_url) { - grpc_core::MutexLock lock(&ads_mu_); - return resource_type_response_state_[type_url]; - } - ResponseState lds_response_state() { return GetResponseState(kLdsTypeUrl); } - ResponseState rds_response_state() { return GetResponseState(kRdsTypeUrl); } - ResponseState cds_response_state() { return GetResponseState(kCdsTypeUrl); } - ResponseState eds_response_state() { return GetResponseState(kEdsTypeUrl); } - - // Starts the service. - void Start(); - - // Shuts down the service. - void Shutdown(); - - // Returns the peer names of clients currently connected to the service. - std::set clients() { - grpc_core::MutexLock lock(&clients_mu_); - return clients_; - } - - private: - // A queue of resource type/name pairs that have changed since the client - // subscribed to them. - using UpdateQueue = std::deque< - std::pair>; - - // A struct representing a client's subscription to a particular resource. - struct SubscriptionState { - // The queue upon which to place updates when the resource is updated. - UpdateQueue* update_queue; - }; - - // A struct representing the a client's subscription to all the resources. - using SubscriptionNameMap = - std::map; - using SubscriptionMap = - std::map; - - // Sent state for a given resource type. - struct SentState { - int nonce = 0; - int resource_type_version = 0; - }; - - // A struct representing the current state for an individual resource. - struct ResourceState { - // The resource itself, if present. - absl::optional resource; - // The resource type version that this resource was last updated in. - int resource_type_version = 0; - // A list of subscriptions to this resource. - std::set subscriptions; - }; - - // The current state for all individual resources of a given type. - using ResourceNameMap = - std::map; - - struct ResourceTypeState { - int resource_type_version = 0; - ResourceNameMap resource_name_map; - }; - - using ResourceMap = std::map; - - // Templated RPC service implementation, works for both v2 and v3. - template - class RpcService : public RpcApi::Service { - public: - using Stream = ServerReaderWriter; - - RpcService(AdsServiceImpl* parent, bool is_v2) - : parent_(parent), is_v2_(is_v2) {} - - Status StreamAggregatedResources(ServerContext* context, - Stream* stream) override { - gpr_log(GPR_INFO, "ADS[%p]: StreamAggregatedResources starts", this); - parent_->AddClient(context->peer()); - if (is_v2_) { - parent_->seen_v2_client_ = true; - } else { - parent_->seen_v3_client_ = true; - } - // Take a reference of the AdsServiceImpl object, which will go - // out of scope when this request handler returns. This ensures - // that the parent won't be destroyed until this stream is complete. - std::shared_ptr ads_service_impl = - parent_->shared_from_this(); - // Resources (type/name pairs) that have changed since the client - // subscribed to them. - UpdateQueue update_queue; - // Resources that the client will be subscribed to keyed by resource type - // url. - SubscriptionMap subscription_map; - // Sent state for each resource type. - std::map sent_state_map; - // Spawn a thread to read requests from the stream. - // Requests will be delivered to this thread in a queue. - std::deque requests; - bool stream_closed = false; - std::thread reader(std::bind(&RpcService::BlockingRead, this, stream, - &requests, &stream_closed)); - // Main loop to process requests and updates. - while (true) { - // Boolean to keep track if the loop received any work to do: a - // request or an update; regardless whether a response was actually - // sent out. - bool did_work = false; - // Look for new requests and and decide what to handle. - absl::optional response; - { - grpc_core::MutexLock lock(&parent_->ads_mu_); - // If the stream has been closed or our parent is being shut - // down, stop immediately. - if (stream_closed || parent_->ads_done_) break; - // Otherwise, see if there's a request to read from the queue. - if (!requests.empty()) { - DiscoveryRequest request = std::move(requests.front()); - requests.pop_front(); - did_work = true; - gpr_log(GPR_INFO, - "ADS[%p]: Received request for type %s with content %s", - this, request.type_url().c_str(), - request.DebugString().c_str()); - const std::string v3_resource_type = - TypeUrlToV3(request.type_url()); - SentState& sent_state = sent_state_map[v3_resource_type]; - // Process request. - ProcessRequest(request, v3_resource_type, &update_queue, - &subscription_map, &sent_state, &response); - } - } - if (response.has_value()) { - gpr_log(GPR_INFO, "ADS[%p]: Sending response: %s", this, - response->DebugString().c_str()); - stream->Write(response.value()); - } - response.reset(); - // Look for updates and decide what to handle. - { - grpc_core::MutexLock lock(&parent_->ads_mu_); - if (!update_queue.empty()) { - const std::string resource_type = - std::move(update_queue.front().first); - const std::string resource_name = - std::move(update_queue.front().second); - update_queue.pop_front(); - did_work = true; - SentState& sent_state = sent_state_map[resource_type]; - ProcessUpdate(resource_type, resource_name, &subscription_map, - &sent_state, &response); - } - } - if (response.has_value()) { - gpr_log(GPR_INFO, "ADS[%p]: Sending update response: %s", this, - response->DebugString().c_str()); - stream->Write(response.value()); - } - { - grpc_core::MutexLock lock(&parent_->ads_mu_); - if (parent_->ads_done_) { - break; - } - } - // If we didn't find anything to do, delay before the next loop - // iteration; otherwise, check whether we should exit and then - // immediately continue. - gpr_sleep_until( - grpc_timeout_milliseconds_to_deadline(did_work ? 0 : 10)); - } - // Done with main loop. Clean up before returning. - // Join reader thread. - reader.join(); - // Clean up any subscriptions that were still active when the call - // finished. - { - grpc_core::MutexLock lock(&parent_->ads_mu_); - for (auto& p : subscription_map) { - const std::string& type_url = p.first; - SubscriptionNameMap& subscription_name_map = p.second; - for (auto& q : subscription_name_map) { - const std::string& resource_name = q.first; - SubscriptionState& subscription_state = q.second; - ResourceNameMap& resource_name_map = - parent_->resource_map_[type_url].resource_name_map; - ResourceState& resource_state = resource_name_map[resource_name]; - resource_state.subscriptions.erase(&subscription_state); - } - } - } - gpr_log(GPR_INFO, "ADS[%p]: StreamAggregatedResources done", this); - parent_->RemoveClient(context->peer()); - return Status::OK; - } - - private: - // NB: clang's annotalysis is confused by the use of inner template - // classes here and *ignores* the exclusive lock annotation on some - // functions. See https://bugs.llvm.org/show_bug.cgi?id=51368. - // - // This class is used for a dual purpose: - // - it convinces clang that the lock is held in a given scope - // - when used in a function that is annotated to require the inner lock it - // will cause compilation to fail if the upstream bug is fixed! - // - // If you arrive here because of a compilation failure, that might mean the - // clang bug is fixed! Please report that on the ticket. - // - // Since the buggy compiler will still need to be supported, consider - // wrapping this class in a compiler version #if and replace its usage - // with a macro whose expansion is conditional on the compiler version. In - // time (years? decades?) this code can be deleted altogether. - class ABSL_SCOPED_LOCKABLE NoopMutexLock { - public: - explicit NoopMutexLock(grpc_core::Mutex& mu) - ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) {} - ~NoopMutexLock() ABSL_UNLOCK_FUNCTION() {} - }; - // Processes a response read from the client. - // Populates response if needed. - void ProcessRequest(const DiscoveryRequest& request, - const std::string& v3_resource_type, - UpdateQueue* update_queue, - SubscriptionMap* subscription_map, - SentState* sent_state, - absl::optional* response) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_->ads_mu_) { - NoopMutexLock mu(parent_->ads_mu_); - // Check the nonce sent by the client, if any. - // (This will be absent on the first request on a stream.) - if (request.response_nonce().empty()) { - int client_resource_type_version = 0; - if (!request.version_info().empty()) { - GPR_ASSERT(absl::SimpleAtoi(request.version_info(), - &client_resource_type_version)); - } - EXPECT_GE(client_resource_type_version, - parent_->resource_type_min_versions_[v3_resource_type]) - << "resource_type: " << v3_resource_type; - } else { - int client_nonce; - GPR_ASSERT(absl::SimpleAtoi(request.response_nonce(), &client_nonce)); - // Ignore requests with stale nonces. - if (client_nonce < sent_state->nonce) return; - // Check for ACK or NACK. - auto it = parent_->resource_type_response_state_.find(v3_resource_type); - if (it != parent_->resource_type_response_state_.end()) { - if (!request.has_error_detail()) { - it->second.state = ResponseState::ACKED; - it->second.error_message.clear(); - gpr_log(GPR_INFO, - "ADS[%p]: client ACKed resource_type=%s version=%s", this, - request.type_url().c_str(), request.version_info().c_str()); - } else { - it->second.state = ResponseState::NACKED; - EXPECT_EQ(request.error_detail().code(), - GRPC_STATUS_INVALID_ARGUMENT); - it->second.error_message = request.error_detail().message(); - gpr_log(GPR_INFO, - "ADS[%p]: client NACKed resource_type=%s version=%s: %s", - this, request.type_url().c_str(), - request.version_info().c_str(), - it->second.error_message.c_str()); - } - } - } - // Ignore resource types as requested by tests. - if (parent_->resource_types_to_ignore_.find(v3_resource_type) != - parent_->resource_types_to_ignore_.end()) { - return; - } - // Look at all the resource names in the request. - auto& subscription_name_map = (*subscription_map)[v3_resource_type]; - auto& resource_type_state = parent_->resource_map_[v3_resource_type]; - auto& resource_name_map = resource_type_state.resource_name_map; - std::set resources_in_current_request; - std::set resources_added_to_response; - for (const std::string& resource_name : request.resource_names()) { - resources_in_current_request.emplace(resource_name); - auto& subscription_state = subscription_name_map[resource_name]; - auto& resource_state = resource_name_map[resource_name]; - // Subscribe if needed. - // Send the resource in the response if either (a) this is - // a new subscription or (b) there is an updated version of - // this resource to send. - if (parent_->MaybeSubscribe(v3_resource_type, resource_name, - &subscription_state, &resource_state, - update_queue) || - ClientNeedsResourceUpdate(resource_type_state, resource_state, - sent_state->resource_type_version)) { - gpr_log(GPR_INFO, "ADS[%p]: Sending update for type=%s name=%s", this, - request.type_url().c_str(), resource_name.c_str()); - resources_added_to_response.emplace(resource_name); - if (!response->has_value()) response->emplace(); - if (resource_state.resource.has_value()) { - auto* resource = (*response)->add_resources(); - resource->CopyFrom(resource_state.resource.value()); - if (is_v2_) { - resource->set_type_url(request.type_url()); - } - } - } else { - gpr_log(GPR_INFO, - "ADS[%p]: client does not need update for type=%s name=%s", - this, request.type_url().c_str(), resource_name.c_str()); - } - } - // Process unsubscriptions for any resource no longer - // present in the request's resource list. - parent_->ProcessUnsubscriptions( - v3_resource_type, resources_in_current_request, - &subscription_name_map, &resource_name_map); - // Construct response if needed. - if (!resources_added_to_response.empty()) { - CompleteBuildingDiscoveryResponse( - v3_resource_type, request.type_url(), - resource_type_state.resource_type_version, subscription_name_map, - resources_added_to_response, sent_state, &response->value()); - } - } - - // Processes a resource update from the test. - // Populates response if needed. - void ProcessUpdate(const std::string& resource_type, - const std::string& resource_name, - SubscriptionMap* subscription_map, SentState* sent_state, - absl::optional* response) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_->ads_mu_) { - NoopMutexLock mu(parent_->ads_mu_); - const std::string v2_resource_type = TypeUrlToV2(resource_type); - gpr_log(GPR_INFO, "ADS[%p]: Received update for type=%s name=%s", this, - resource_type.c_str(), resource_name.c_str()); - auto& subscription_name_map = (*subscription_map)[resource_type]; - auto& resource_type_state = parent_->resource_map_[resource_type]; - auto& resource_name_map = resource_type_state.resource_name_map; - auto it = subscription_name_map.find(resource_name); - if (it != subscription_name_map.end()) { - ResourceState& resource_state = resource_name_map[resource_name]; - if (ClientNeedsResourceUpdate(resource_type_state, resource_state, - sent_state->resource_type_version)) { - gpr_log(GPR_INFO, "ADS[%p]: Sending update for type=%s name=%s", this, - resource_type.c_str(), resource_name.c_str()); - response->emplace(); - if (resource_state.resource.has_value()) { - auto* resource = (*response)->add_resources(); - resource->CopyFrom(resource_state.resource.value()); - if (is_v2_) { - resource->set_type_url(v2_resource_type); - } - } - CompleteBuildingDiscoveryResponse( - resource_type, v2_resource_type, - resource_type_state.resource_type_version, subscription_name_map, - {resource_name}, sent_state, &response->value()); - } - } - } - - // Starting a thread to do blocking read on the stream until cancel. - void BlockingRead(Stream* stream, std::deque* requests, - bool* stream_closed) { - DiscoveryRequest request; - bool seen_first_request = false; - while (stream->Read(&request)) { - if (!seen_first_request) { - EXPECT_TRUE(request.has_node()); - ASSERT_FALSE(request.node().client_features().empty()); - EXPECT_EQ(request.node().client_features(0), - "envoy.lb.does_not_support_overprovisioning"); - CheckBuildVersion(request); - seen_first_request = true; - } - { - grpc_core::MutexLock lock(&parent_->ads_mu_); - requests->emplace_back(std::move(request)); - } - } - gpr_log(GPR_INFO, "ADS[%p]: Null read, stream closed", this); - grpc_core::MutexLock lock(&parent_->ads_mu_); - *stream_closed = true; - } - - // Completing the building a DiscoveryResponse by adding common information - // for all resources and by adding all subscribed resources for LDS and CDS. - void CompleteBuildingDiscoveryResponse( - const std::string& resource_type, const std::string& v2_resource_type, - const int version, const SubscriptionNameMap& subscription_name_map, - const std::set& resources_added_to_response, - SentState* sent_state, DiscoveryResponse* response) - ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_->ads_mu_) { - NoopMutexLock mu(parent_->ads_mu_); - auto& response_state = - parent_->resource_type_response_state_[resource_type]; - if (response_state.state == ResponseState::NOT_SENT) { - response_state.state = ResponseState::SENT; - } - response->set_type_url(is_v2_ ? v2_resource_type : resource_type); - response->set_version_info(std::to_string(version)); - response->set_nonce(std::to_string(++sent_state->nonce)); - if (resource_type == kLdsTypeUrl || resource_type == kCdsTypeUrl) { - // For LDS and CDS we must send back all subscribed resources - // (even the unchanged ones) - for (const auto& p : subscription_name_map) { - const std::string& resource_name = p.first; - if (resources_added_to_response.find(resource_name) == - resources_added_to_response.end()) { - ResourceNameMap& resource_name_map = - parent_->resource_map_[resource_type].resource_name_map; - const ResourceState& resource_state = - resource_name_map[resource_name]; - if (resource_state.resource.has_value()) { - auto* resource = response->add_resources(); - resource->CopyFrom(resource_state.resource.value()); - if (is_v2_) { - resource->set_type_url(v2_resource_type); - } - } - } - } - } - sent_state->resource_type_version = version; - } - - static std::string TypeUrlToV2(const std::string& resource_type) { - if (resource_type == kLdsTypeUrl) return kLdsV2TypeUrl; - if (resource_type == kRdsTypeUrl) return kRdsV2TypeUrl; - if (resource_type == kCdsTypeUrl) return kCdsV2TypeUrl; - if (resource_type == kEdsTypeUrl) return kEdsV2TypeUrl; - return resource_type; - } - - static std::string TypeUrlToV3(const std::string& resource_type) { - if (resource_type == kLdsV2TypeUrl) return kLdsTypeUrl; - if (resource_type == kRdsV2TypeUrl) return kRdsTypeUrl; - if (resource_type == kCdsV2TypeUrl) return kCdsTypeUrl; - if (resource_type == kEdsV2TypeUrl) return kEdsTypeUrl; - return resource_type; - } - - static void CheckBuildVersion( - const ::envoy::api::v2::DiscoveryRequest& request) { - EXPECT_FALSE(request.node().build_version().empty()); - } - - static void CheckBuildVersion( - const ::envoy::service::discovery::v3::DiscoveryRequest& /*request*/) {} - - AdsServiceImpl* parent_; - const bool is_v2_; - }; - - // Checks whether the client needs to receive a newer version of - // the resource. - static bool ClientNeedsResourceUpdate( - const ResourceTypeState& resource_type_state, - const ResourceState& resource_state, int client_resource_type_version); - - // Subscribes to a resource if not already subscribed: - // 1. Sets the update_queue field in subscription_state. - // 2. Adds subscription_state to resource_state->subscriptions. - bool MaybeSubscribe(const std::string& resource_type, - const std::string& resource_name, - SubscriptionState* subscription_state, - ResourceState* resource_state, UpdateQueue* update_queue); - - // Removes subscriptions for resources no longer present in the - // current request. - void ProcessUnsubscriptions( - const std::string& resource_type, - const std::set& resources_in_current_request, - SubscriptionNameMap* subscription_name_map, - ResourceNameMap* resource_name_map); - - void AddClient(const std::string& client) { - grpc_core::MutexLock lock(&clients_mu_); - clients_.insert(client); - } - - void RemoveClient(const std::string& client) { - grpc_core::MutexLock lock(&clients_mu_); - clients_.erase(client); - } - - RpcService<::envoy::service::discovery::v2::AggregatedDiscoveryService, - ::envoy::api::v2::DiscoveryRequest, - ::envoy::api::v2::DiscoveryResponse> - v2_rpc_service_; - RpcService<::envoy::service::discovery::v3::AggregatedDiscoveryService, - ::envoy::service::discovery::v3::DiscoveryRequest, - ::envoy::service::discovery::v3::DiscoveryResponse> - v3_rpc_service_; - - std::atomic_bool seen_v2_client_{false}; - std::atomic_bool seen_v3_client_{false}; - - grpc_core::CondVar ads_cond_; - grpc_core::Mutex ads_mu_; - bool ads_done_ ABSL_GUARDED_BY(ads_mu_) = false; - std::map - resource_type_response_state_ ABSL_GUARDED_BY(ads_mu_); - std::set resource_types_to_ignore_ - ABSL_GUARDED_BY(ads_mu_); - std::map resource_type_min_versions_ - ABSL_GUARDED_BY(ads_mu_); - // An instance data member containing the current state of all resources. - // Note that an entry will exist whenever either of the following is true: - // - The resource exists (i.e., has been created by SetResource() and has not - // yet been destroyed by UnsetResource()). - // - There is at least one subscription for the resource. - ResourceMap resource_map_ ABSL_GUARDED_BY(ads_mu_); - - grpc_core::Mutex clients_mu_; - std::set clients_ ABSL_GUARDED_BY(clients_mu_); -}; - -// An LRS service implementation. -class LrsServiceImpl : public std::enable_shared_from_this { - public: - // Stats reported by client. - class ClientStats { - public: - // Stats for a given locality. - struct LocalityStats { - LocalityStats() {} - - // Converts from proto message class. - template - explicit LocalityStats( - const UpstreamLocalityStats& upstream_locality_stats) - : total_successful_requests( - upstream_locality_stats.total_successful_requests()), - total_requests_in_progress( - upstream_locality_stats.total_requests_in_progress()), - total_error_requests( - upstream_locality_stats.total_error_requests()), - total_issued_requests( - upstream_locality_stats.total_issued_requests()) {} - - LocalityStats& operator+=(const LocalityStats& other) { - total_successful_requests += other.total_successful_requests; - total_requests_in_progress += other.total_requests_in_progress; - total_error_requests += other.total_error_requests; - total_issued_requests += other.total_issued_requests; - return *this; - } - - uint64_t total_successful_requests = 0; - uint64_t total_requests_in_progress = 0; - uint64_t total_error_requests = 0; - uint64_t total_issued_requests = 0; - }; - - ClientStats() {} - - // Converts from proto message class. - template - explicit ClientStats(const ClusterStats& cluster_stats) - : cluster_name_(cluster_stats.cluster_name()), - total_dropped_requests_(cluster_stats.total_dropped_requests()) { - for (const auto& input_locality_stats : - cluster_stats.upstream_locality_stats()) { - locality_stats_.emplace(input_locality_stats.locality().sub_zone(), - LocalityStats(input_locality_stats)); - } - for (const auto& input_dropped_requests : - cluster_stats.dropped_requests()) { - dropped_requests_.emplace(input_dropped_requests.category(), - input_dropped_requests.dropped_count()); - } - } - - const std::string& cluster_name() const { return cluster_name_; } - - const std::map& locality_stats() const { - return locality_stats_; - } - - uint64_t total_successful_requests() const; - uint64_t total_requests_in_progress() const; - uint64_t total_error_requests() const; - uint64_t total_issued_requests() const; - - uint64_t total_dropped_requests() const { return total_dropped_requests_; } - - uint64_t dropped_requests(const std::string& category) const; - - ClientStats& operator+=(const ClientStats& other); - - private: - std::string cluster_name_; - std::map locality_stats_; - uint64_t total_dropped_requests_ = 0; - std::map dropped_requests_; - }; - - LrsServiceImpl(int client_load_reporting_interval_seconds, - std::set cluster_names) - : v2_rpc_service_(this), - v3_rpc_service_(this), - client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds), - cluster_names_(std::move(cluster_names)) {} - - ::envoy::service::load_stats::v2::LoadReportingService::Service* - v2_rpc_service() { - return &v2_rpc_service_; - } - - ::envoy::service::load_stats::v3::LoadReportingService::Service* - v3_rpc_service() { - return &v3_rpc_service_; - } - - size_t request_count() { - return v2_rpc_service_.request_count() + v3_rpc_service_.request_count(); - } - - size_t response_count() { - return v2_rpc_service_.response_count() + v3_rpc_service_.response_count(); - } - - // Must be called before the LRS call is started. - void set_send_all_clusters(bool send_all_clusters) { - send_all_clusters_ = send_all_clusters; - } - void set_cluster_names(const std::set& cluster_names) { - cluster_names_ = cluster_names; - } - - void Start() ABSL_LOCKS_EXCLUDED(lrs_mu_, load_report_mu_); - - void Shutdown(); - - std::vector WaitForLoadReport(); - - private: - // Templated RPC service implementation, works for both v2 and v3. - template - class RpcService : public CountedService { - public: - using Stream = ServerReaderWriter; - - explicit RpcService(LrsServiceImpl* parent) : parent_(parent) {} - - Status StreamLoadStats(ServerContext* /*context*/, - Stream* stream) override { - gpr_log(GPR_INFO, "LRS[%p]: StreamLoadStats starts", this); - EXPECT_GT(parent_->client_load_reporting_interval_seconds_, 0); - // Take a reference of the LrsServiceImpl object, reference will go - // out of scope after this method exits. - std::shared_ptr lrs_service_impl = - parent_->shared_from_this(); - // Read initial request. - LoadStatsRequest request; - if (stream->Read(&request)) { - CountedService::IncreaseRequestCount(); - // Verify client features. - EXPECT_THAT( - request.node().client_features(), - ::testing::Contains("envoy.lrs.supports_send_all_clusters")); - // Send initial response. - LoadStatsResponse response; - if (parent_->send_all_clusters_) { - response.set_send_all_clusters(true); - } else { - for (const std::string& cluster_name : parent_->cluster_names_) { - response.add_clusters(cluster_name); - } - } - response.mutable_load_reporting_interval()->set_seconds( - parent_->client_load_reporting_interval_seconds_); - stream->Write(response); - CountedService::IncreaseResponseCount(); - // Wait for report. - request.Clear(); - while (stream->Read(&request)) { - gpr_log(GPR_INFO, "LRS[%p]: received client load report message: %s", - this, request.DebugString().c_str()); - std::vector stats; - for (const auto& cluster_stats : request.cluster_stats()) { - stats.emplace_back(cluster_stats); - } - grpc_core::MutexLock lock(&parent_->load_report_mu_); - parent_->result_queue_.emplace_back(std::move(stats)); - if (parent_->load_report_cond_ != nullptr) { - parent_->load_report_cond_->Signal(); - } - } - // Wait until notified done. - grpc_core::MutexLock lock(&parent_->lrs_mu_); - while (!parent_->lrs_done_) { - parent_->lrs_cv_.Wait(&parent_->lrs_mu_); - } - } - gpr_log(GPR_INFO, "LRS[%p]: StreamLoadStats done", this); - return Status::OK; - } - - private: - LrsServiceImpl* parent_; - }; - - RpcService<::envoy::service::load_stats::v2::LoadReportingService, - ::envoy::service::load_stats::v2::LoadStatsRequest, - ::envoy::service::load_stats::v2::LoadStatsResponse> - v2_rpc_service_; - RpcService<::envoy::service::load_stats::v3::LoadReportingService, - ::envoy::service::load_stats::v3::LoadStatsRequest, - ::envoy::service::load_stats::v3::LoadStatsResponse> - v3_rpc_service_; - - const int client_load_reporting_interval_seconds_; - bool send_all_clusters_ = false; - std::set cluster_names_; - - grpc_core::CondVar lrs_cv_; - grpc_core::Mutex lrs_mu_; - bool lrs_done_ ABSL_GUARDED_BY(lrs_mu_) = false; - - grpc_core::Mutex load_report_mu_; - grpc_core::CondVar* load_report_cond_ ABSL_GUARDED_BY(load_report_mu_) = - nullptr; - std::deque> result_queue_ - ABSL_GUARDED_BY(load_report_mu_); -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_END2END_XDS_XDS_SERVER_H diff --git a/test/cpp/end2end/xds/xds_credentials_end2end_test.cc b/test/cpp/end2end/xds_credentials_end2end_test.cc similarity index 100% rename from test/cpp/end2end/xds/xds_credentials_end2end_test.cc rename to test/cpp/end2end/xds_credentials_end2end_test.cc diff --git a/test/cpp/end2end/xds/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc similarity index 91% rename from test/cpp/end2end/xds/xds_end2end_test.cc rename to test/cpp/end2end/xds_end2end_test.cc index b79f291567c..b88a6addf8e 100644 --- a/test/cpp/end2end/xds/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -1,26 +1,20 @@ -// -// Copyright 2017 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -// TODO(roth): Split this file up into a common test framework and a set -// of test files that use that framework. Need to figure out the best -// way to split up the tests. One option would be to split it up by xDS -// resource type; another approach would be to have all of the "core" -// xDS functionality in one file and then move specific features to -// their own files (e.g., mTLS security, fault injection, circuit -// breaking, etc). +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ #include #include @@ -99,9 +93,7 @@ #include "test/core/util/port.h" #include "test/core/util/resolve_localhost_ip46.h" #include "test/core/util/test_config.h" -#include "test/cpp/end2end/counted_service.h" #include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/end2end/xds/xds_server.h" #include "test/cpp/util/test_config.h" #ifndef DISABLED_XDS_PROTO_IN_CC @@ -138,7 +130,21 @@ using ::envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext; using ::envoy::type::matcher::v3::StringMatcher; using ::envoy::type::v3::FractionalPercent; -using ClientStats = LrsServiceImpl::ClientStats; +constexpr char kLdsTypeUrl[] = + "type.googleapis.com/envoy.config.listener.v3.Listener"; +constexpr char kRdsTypeUrl[] = + "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"; +constexpr char kCdsTypeUrl[] = + "type.googleapis.com/envoy.config.cluster.v3.Cluster"; +constexpr char kEdsTypeUrl[] = + "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"; + +constexpr char kLdsV2TypeUrl[] = "type.googleapis.com/envoy.api.v2.Listener"; +constexpr char kRdsV2TypeUrl[] = + "type.googleapis.com/envoy.api.v2.RouteConfiguration"; +constexpr char kCdsV2TypeUrl[] = "type.googleapis.com/envoy.api.v2.Cluster"; +constexpr char kEdsV2TypeUrl[] = + "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment"; constexpr char kDefaultLocalityRegion[] = "xds_default_locality_region"; constexpr char kDefaultLocalityZone[] = "xds_default_locality_zone"; @@ -271,6 +277,40 @@ void WriteBootstrapFiles() { g_bootstrap_file_v2 = bootstrap_file; } +template +class CountedService : public ServiceType { + public: + size_t request_count() { + grpc_core::MutexLock lock(&mu_); + return request_count_; + } + + size_t response_count() { + grpc_core::MutexLock lock(&mu_); + return response_count_; + } + + void IncreaseResponseCount() { + grpc_core::MutexLock lock(&mu_); + ++response_count_; + } + void IncreaseRequestCount() { + grpc_core::MutexLock lock(&mu_); + ++request_count_; + } + + void ResetCounters() { + grpc_core::MutexLock lock(&mu_); + request_count_ = 0; + response_count_ = 0; + } + + private: + grpc_core::Mutex mu_; + size_t request_count_ ABSL_GUARDED_BY(mu_) = 0; + size_t response_count_ ABSL_GUARDED_BY(mu_) = 0; +}; + template class BackendServiceImpl : public CountedService> { @@ -325,6 +365,1000 @@ class BackendServiceImpl std::vector last_peer_identity_ ABSL_GUARDED_BY(mu_); }; +class ClientStats { + public: + struct LocalityStats { + LocalityStats() {} + + // Converts from proto message class. + template + explicit LocalityStats(const UpstreamLocalityStats& upstream_locality_stats) + : total_successful_requests( + upstream_locality_stats.total_successful_requests()), + total_requests_in_progress( + upstream_locality_stats.total_requests_in_progress()), + total_error_requests(upstream_locality_stats.total_error_requests()), + total_issued_requests( + upstream_locality_stats.total_issued_requests()) {} + + LocalityStats& operator+=(const LocalityStats& other) { + total_successful_requests += other.total_successful_requests; + total_requests_in_progress += other.total_requests_in_progress; + total_error_requests += other.total_error_requests; + total_issued_requests += other.total_issued_requests; + return *this; + } + + uint64_t total_successful_requests = 0; + uint64_t total_requests_in_progress = 0; + uint64_t total_error_requests = 0; + uint64_t total_issued_requests = 0; + }; + + ClientStats() {} + + // Converts from proto message class. + template + explicit ClientStats(const ClusterStats& cluster_stats) + : cluster_name_(cluster_stats.cluster_name()), + total_dropped_requests_(cluster_stats.total_dropped_requests()) { + for (const auto& input_locality_stats : + cluster_stats.upstream_locality_stats()) { + locality_stats_.emplace(input_locality_stats.locality().sub_zone(), + LocalityStats(input_locality_stats)); + } + for (const auto& input_dropped_requests : + cluster_stats.dropped_requests()) { + dropped_requests_.emplace(input_dropped_requests.category(), + input_dropped_requests.dropped_count()); + } + } + + const std::string& cluster_name() const { return cluster_name_; } + + const std::map& locality_stats() const { + return locality_stats_; + } + uint64_t total_successful_requests() const { + uint64_t sum = 0; + for (auto& p : locality_stats_) { + sum += p.second.total_successful_requests; + } + return sum; + } + uint64_t total_requests_in_progress() const { + uint64_t sum = 0; + for (auto& p : locality_stats_) { + sum += p.second.total_requests_in_progress; + } + return sum; + } + uint64_t total_error_requests() const { + uint64_t sum = 0; + for (auto& p : locality_stats_) { + sum += p.second.total_error_requests; + } + return sum; + } + uint64_t total_issued_requests() const { + uint64_t sum = 0; + for (auto& p : locality_stats_) { + sum += p.second.total_issued_requests; + } + return sum; + } + + uint64_t total_dropped_requests() const { return total_dropped_requests_; } + + uint64_t dropped_requests(const std::string& category) const { + auto iter = dropped_requests_.find(category); + GPR_ASSERT(iter != dropped_requests_.end()); + return iter->second; + } + + ClientStats& operator+=(const ClientStats& other) { + for (const auto& p : other.locality_stats_) { + locality_stats_[p.first] += p.second; + } + total_dropped_requests_ += other.total_dropped_requests_; + for (const auto& p : other.dropped_requests_) { + dropped_requests_[p.first] += p.second; + } + return *this; + } + + private: + std::string cluster_name_; + std::map locality_stats_; + uint64_t total_dropped_requests_ = 0; + std::map dropped_requests_; +}; + +class AdsServiceImpl : public std::enable_shared_from_this { + public: + struct ResponseState { + enum State { NOT_SENT, SENT, ACKED, NACKED }; + State state = NOT_SENT; + std::string error_message; + }; + + struct EdsResourceArgs { + struct Endpoint { + explicit Endpoint(int port, + HealthStatus health_status = HealthStatus::UNKNOWN, + int lb_weight = 1) + : port(port), health_status(health_status), lb_weight(lb_weight) {} + + int port; + HealthStatus health_status; + int lb_weight; + }; + + struct Locality { + Locality(std::string sub_zone, std::vector endpoints, + int lb_weight = kDefaultLocalityWeight, + int priority = kDefaultLocalityPriority) + : sub_zone(std::move(sub_zone)), + endpoints(std::move(endpoints)), + lb_weight(lb_weight), + priority(priority) {} + + const std::string sub_zone; + std::vector endpoints; + int lb_weight; + int priority; + }; + + EdsResourceArgs() = default; + explicit EdsResourceArgs(std::vector locality_list) + : locality_list(std::move(locality_list)) {} + + std::vector locality_list; + std::map drop_categories; + FractionalPercent::DenominatorType drop_denominator = + FractionalPercent::MILLION; + }; + + AdsServiceImpl() + : v2_rpc_service_(this, /*is_v2=*/true), + v3_rpc_service_(this, /*is_v2=*/false) {} + + bool seen_v2_client() const { return seen_v2_client_; } + bool seen_v3_client() const { return seen_v3_client_; } + + ::envoy::service::discovery::v2::AggregatedDiscoveryService::Service* + v2_rpc_service() { + return &v2_rpc_service_; + } + + ::envoy::service::discovery::v3::AggregatedDiscoveryService::Service* + v3_rpc_service() { + return &v3_rpc_service_; + } + + ResponseState lds_response_state() { + grpc_core::MutexLock lock(&ads_mu_); + return resource_type_response_state_[kLdsTypeUrl]; + } + + ResponseState rds_response_state() { + grpc_core::MutexLock lock(&ads_mu_); + return resource_type_response_state_[kRdsTypeUrl]; + } + + ResponseState cds_response_state() { + grpc_core::MutexLock lock(&ads_mu_); + return resource_type_response_state_[kCdsTypeUrl]; + } + + ResponseState eds_response_state() { + grpc_core::MutexLock lock(&ads_mu_); + return resource_type_response_state_[kEdsTypeUrl]; + } + + void SetResourceIgnore(const std::string& type_url) { + grpc_core::MutexLock lock(&ads_mu_); + resource_types_to_ignore_.emplace(type_url); + } + + void SetResourceMinVersion(const std::string& type_url, int version) { + grpc_core::MutexLock lock(&ads_mu_); + resource_type_min_versions_[type_url] = version; + } + + void UnsetResource(const std::string& type_url, const std::string& name) { + grpc_core::MutexLock lock(&ads_mu_); + ResourceTypeState& resource_type_state = resource_map_[type_url]; + ++resource_type_state.resource_type_version; + ResourceState& resource_state = resource_type_state.resource_name_map[name]; + resource_state.resource_type_version = + resource_type_state.resource_type_version; + resource_state.resource.reset(); + gpr_log(GPR_INFO, + "ADS[%p]: Unsetting %s resource %s; resource_type_version now %u", + this, type_url.c_str(), name.c_str(), + resource_type_state.resource_type_version); + for (SubscriptionState* subscription : resource_state.subscriptions) { + subscription->update_queue->emplace_back(type_url, name); + } + } + + void SetResource(google::protobuf::Any resource, const std::string& type_url, + const std::string& name) { + grpc_core::MutexLock lock(&ads_mu_); + ResourceTypeState& resource_type_state = resource_map_[type_url]; + ++resource_type_state.resource_type_version; + ResourceState& resource_state = resource_type_state.resource_name_map[name]; + resource_state.resource_type_version = + resource_type_state.resource_type_version; + resource_state.resource = std::move(resource); + gpr_log(GPR_INFO, + "ADS[%p]: Updating %s resource %s; resource_type_version now %u", + this, type_url.c_str(), name.c_str(), + resource_type_state.resource_type_version); + for (SubscriptionState* subscription : resource_state.subscriptions) { + subscription->update_queue->emplace_back(type_url, name); + } + } + + void SetLdsResource(const Listener& listener) { + google::protobuf::Any resource; + resource.PackFrom(listener); + SetResource(std::move(resource), kLdsTypeUrl, listener.name()); + } + + void SetRdsResource(const RouteConfiguration& route) { + google::protobuf::Any resource; + resource.PackFrom(route); + SetResource(std::move(resource), kRdsTypeUrl, route.name()); + } + + void SetCdsResource(const Cluster& cluster) { + google::protobuf::Any resource; + resource.PackFrom(cluster); + SetResource(std::move(resource), kCdsTypeUrl, cluster.name()); + } + + void SetEdsResource(const ClusterLoadAssignment& assignment) { + google::protobuf::Any resource; + resource.PackFrom(assignment); + SetResource(std::move(resource), kEdsTypeUrl, assignment.cluster_name()); + } + + void Start() { + grpc_core::MutexLock lock(&ads_mu_); + ads_done_ = false; + } + + void Shutdown() { + { + grpc_core::MutexLock lock(&ads_mu_); + NotifyDoneWithAdsCallLocked(); + resource_type_response_state_.clear(); + } + gpr_log(GPR_INFO, "ADS[%p]: shut down", this); + } + + void NotifyDoneWithAdsCall() { + grpc_core::MutexLock lock(&ads_mu_); + NotifyDoneWithAdsCallLocked(); + } + + void NotifyDoneWithAdsCallLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(ads_mu_) { + if (!ads_done_) { + ads_done_ = true; + ads_cond_.SignalAll(); + } + } + + std::set clients() { + grpc_core::MutexLock lock(&clients_mu_); + return clients_; + } + + private: + // A queue of resource type/name pairs that have changed since the client + // subscribed to them. + using UpdateQueue = std::deque< + std::pair>; + + // A struct representing a client's subscription to a particular resource. + struct SubscriptionState { + // The queue upon which to place updates when the resource is updated. + UpdateQueue* update_queue; + }; + + // A struct representing the a client's subscription to all the resources. + using SubscriptionNameMap = + std::map; + using SubscriptionMap = + std::map; + + // Sent state for a given resource type. + struct SentState { + int nonce = 0; + int resource_type_version = 0; + }; + + // A struct representing the current state for an individual resource. + struct ResourceState { + // The resource itself, if present. + absl::optional resource; + // The resource type version that this resource was last updated in. + int resource_type_version = 0; + // A list of subscriptions to this resource. + std::set subscriptions; + }; + + // The current state for all individual resources of a given type. + using ResourceNameMap = + std::map; + + struct ResourceTypeState { + int resource_type_version = 0; + ResourceNameMap resource_name_map; + }; + + using ResourceMap = std::map; + + template + class RpcService : public RpcApi::Service { + public: + using Stream = ServerReaderWriter; + + RpcService(AdsServiceImpl* parent, bool is_v2) + : parent_(parent), is_v2_(is_v2) {} + + Status StreamAggregatedResources(ServerContext* context, + Stream* stream) override { + gpr_log(GPR_INFO, "ADS[%p]: StreamAggregatedResources starts", this); + parent_->AddClient(context->peer()); + if (is_v2_) { + parent_->seen_v2_client_ = true; + } else { + parent_->seen_v3_client_ = true; + } + // Take a reference of the AdsServiceImpl object, which will go + // out of scope when this request handler returns. This ensures + // that the parent won't be destroyed until this stream is complete. + std::shared_ptr ads_service_impl = + parent_->shared_from_this(); + // Resources (type/name pairs) that have changed since the client + // subscribed to them. + UpdateQueue update_queue; + // Resources that the client will be subscribed to keyed by resource type + // url. + SubscriptionMap subscription_map; + // Sent state for each resource type. + std::map sent_state_map; + // Spawn a thread to read requests from the stream. + // Requests will be delivered to this thread in a queue. + std::deque requests; + bool stream_closed = false; + std::thread reader(std::bind(&RpcService::BlockingRead, this, stream, + &requests, &stream_closed)); + // Main loop to process requests and updates. + while (true) { + // Boolean to keep track if the loop received any work to do: a + // request or an update; regardless whether a response was actually + // sent out. + bool did_work = false; + // Look for new requests and and decide what to handle. + absl::optional response; + { + grpc_core::MutexLock lock(&parent_->ads_mu_); + // If the stream has been closed or our parent is being shut + // down, stop immediately. + if (stream_closed || parent_->ads_done_) break; + // Otherwise, see if there's a request to read from the queue. + if (!requests.empty()) { + DiscoveryRequest request = std::move(requests.front()); + requests.pop_front(); + did_work = true; + gpr_log(GPR_INFO, + "ADS[%p]: Received request for type %s with content %s", + this, request.type_url().c_str(), + request.DebugString().c_str()); + const std::string v3_resource_type = + TypeUrlToV3(request.type_url()); + SentState& sent_state = sent_state_map[v3_resource_type]; + // Process request. + ProcessRequest(request, v3_resource_type, &update_queue, + &subscription_map, &sent_state, &response); + } + } + if (response.has_value()) { + gpr_log(GPR_INFO, "ADS[%p]: Sending response: %s", this, + response->DebugString().c_str()); + stream->Write(response.value()); + } + response.reset(); + // Look for updates and decide what to handle. + { + grpc_core::MutexLock lock(&parent_->ads_mu_); + if (!update_queue.empty()) { + const std::string resource_type = + std::move(update_queue.front().first); + const std::string resource_name = + std::move(update_queue.front().second); + update_queue.pop_front(); + did_work = true; + SentState& sent_state = sent_state_map[resource_type]; + ProcessUpdate(resource_type, resource_name, &subscription_map, + &sent_state, &response); + } + } + if (response.has_value()) { + gpr_log(GPR_INFO, "ADS[%p]: Sending update response: %s", this, + response->DebugString().c_str()); + stream->Write(response.value()); + } + { + grpc_core::MutexLock lock(&parent_->ads_mu_); + if (parent_->ads_done_) { + break; + } + } + // If we didn't find anything to do, delay before the next loop + // iteration; otherwise, check whether we should exit and then + // immediately continue. + gpr_sleep_until( + grpc_timeout_milliseconds_to_deadline(did_work ? 0 : 10)); + } + // Done with main loop. Clean up before returning. + // Join reader thread. + reader.join(); + // Clean up any subscriptions that were still active when the call + // finished. + { + grpc_core::MutexLock lock(&parent_->ads_mu_); + for (auto& p : subscription_map) { + const std::string& type_url = p.first; + SubscriptionNameMap& subscription_name_map = p.second; + for (auto& q : subscription_name_map) { + const std::string& resource_name = q.first; + SubscriptionState& subscription_state = q.second; + ResourceNameMap& resource_name_map = + parent_->resource_map_[type_url].resource_name_map; + ResourceState& resource_state = resource_name_map[resource_name]; + resource_state.subscriptions.erase(&subscription_state); + } + } + } + gpr_log(GPR_INFO, "ADS[%p]: StreamAggregatedResources done", this); + parent_->RemoveClient(context->peer()); + return Status::OK; + } + + private: + // NB: clang's annotalysis is confused by the use of inner template + // classes here and *ignores* the exclusive lock annotation on some + // functions. See https://bugs.llvm.org/show_bug.cgi?id=51368. + // + // This class is used for a dual purpose: + // - it convinces clang that the lock is held in a given scope + // - when used in a function that is annotated to require the inner lock it + // will cause compilation to fail if the upstream bug is fixed! + // + // If you arrive here because of a compilation failure, that might mean the + // clang bug is fixed! Please report that on the ticket. + // + // Since the buggy compiler will still need to be supported, consider + // wrapping this class in a compiler version #if and replace its usage + // with a macro whose expansion is conditional on the compiler version. In + // time (years? decades?) this code can be deleted altogether. + class ABSL_SCOPED_LOCKABLE NoopMutexLock { + public: + explicit NoopMutexLock(grpc_core::Mutex& mu) + ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) {} + ~NoopMutexLock() ABSL_UNLOCK_FUNCTION() {} + }; + // Processes a response read from the client. + // Populates response if needed. + void ProcessRequest(const DiscoveryRequest& request, + const std::string& v3_resource_type, + UpdateQueue* update_queue, + SubscriptionMap* subscription_map, + SentState* sent_state, + absl::optional* response) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_->ads_mu_) { + NoopMutexLock mu(parent_->ads_mu_); + // Check the nonce sent by the client, if any. + // (This will be absent on the first request on a stream.) + if (request.response_nonce().empty()) { + int client_resource_type_version = 0; + if (!request.version_info().empty()) { + GPR_ASSERT(absl::SimpleAtoi(request.version_info(), + &client_resource_type_version)); + } + EXPECT_GE(client_resource_type_version, + parent_->resource_type_min_versions_[v3_resource_type]) + << "resource_type: " << v3_resource_type; + } else { + int client_nonce; + GPR_ASSERT(absl::SimpleAtoi(request.response_nonce(), &client_nonce)); + // Ignore requests with stale nonces. + if (client_nonce < sent_state->nonce) return; + // Check for ACK or NACK. + auto it = parent_->resource_type_response_state_.find(v3_resource_type); + if (it != parent_->resource_type_response_state_.end()) { + if (!request.has_error_detail()) { + it->second.state = ResponseState::ACKED; + it->second.error_message.clear(); + gpr_log(GPR_INFO, + "ADS[%p]: client ACKed resource_type=%s version=%s", this, + request.type_url().c_str(), request.version_info().c_str()); + } else { + it->second.state = ResponseState::NACKED; + EXPECT_EQ(request.error_detail().code(), + GRPC_STATUS_INVALID_ARGUMENT); + it->second.error_message = request.error_detail().message(); + gpr_log(GPR_INFO, + "ADS[%p]: client NACKed resource_type=%s version=%s: %s", + this, request.type_url().c_str(), + request.version_info().c_str(), + it->second.error_message.c_str()); + } + } + } + // Ignore resource types as requested by tests. + if (parent_->resource_types_to_ignore_.find(v3_resource_type) != + parent_->resource_types_to_ignore_.end()) { + return; + } + // Look at all the resource names in the request. + auto& subscription_name_map = (*subscription_map)[v3_resource_type]; + auto& resource_type_state = parent_->resource_map_[v3_resource_type]; + auto& resource_name_map = resource_type_state.resource_name_map; + std::set resources_in_current_request; + std::set resources_added_to_response; + for (const std::string& resource_name : request.resource_names()) { + resources_in_current_request.emplace(resource_name); + auto& subscription_state = subscription_name_map[resource_name]; + auto& resource_state = resource_name_map[resource_name]; + // Subscribe if needed. + // Send the resource in the response if either (a) this is + // a new subscription or (b) there is an updated version of + // this resource to send. + if (parent_->MaybeSubscribe(v3_resource_type, resource_name, + &subscription_state, &resource_state, + update_queue) || + ClientNeedsResourceUpdate(resource_type_state, resource_state, + sent_state->resource_type_version)) { + gpr_log(GPR_INFO, "ADS[%p]: Sending update for type=%s name=%s", this, + request.type_url().c_str(), resource_name.c_str()); + resources_added_to_response.emplace(resource_name); + if (!response->has_value()) response->emplace(); + if (resource_state.resource.has_value()) { + auto* resource = (*response)->add_resources(); + resource->CopyFrom(resource_state.resource.value()); + if (is_v2_) { + resource->set_type_url(request.type_url()); + } + } + } else { + gpr_log(GPR_INFO, + "ADS[%p]: client does not need update for type=%s name=%s", + this, request.type_url().c_str(), resource_name.c_str()); + } + } + // Process unsubscriptions for any resource no longer + // present in the request's resource list. + parent_->ProcessUnsubscriptions( + v3_resource_type, resources_in_current_request, + &subscription_name_map, &resource_name_map); + // Construct response if needed. + if (!resources_added_to_response.empty()) { + CompleteBuildingDiscoveryResponse( + v3_resource_type, request.type_url(), + resource_type_state.resource_type_version, subscription_name_map, + resources_added_to_response, sent_state, &response->value()); + } + } + + // Processes a resource update from the test. + // Populates response if needed. + void ProcessUpdate(const std::string& resource_type, + const std::string& resource_name, + SubscriptionMap* subscription_map, SentState* sent_state, + absl::optional* response) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_->ads_mu_) { + NoopMutexLock mu(parent_->ads_mu_); + const std::string v2_resource_type = TypeUrlToV2(resource_type); + gpr_log(GPR_INFO, "ADS[%p]: Received update for type=%s name=%s", this, + resource_type.c_str(), resource_name.c_str()); + auto& subscription_name_map = (*subscription_map)[resource_type]; + auto& resource_type_state = parent_->resource_map_[resource_type]; + auto& resource_name_map = resource_type_state.resource_name_map; + auto it = subscription_name_map.find(resource_name); + if (it != subscription_name_map.end()) { + ResourceState& resource_state = resource_name_map[resource_name]; + if (ClientNeedsResourceUpdate(resource_type_state, resource_state, + sent_state->resource_type_version)) { + gpr_log(GPR_INFO, "ADS[%p]: Sending update for type=%s name=%s", this, + resource_type.c_str(), resource_name.c_str()); + response->emplace(); + if (resource_state.resource.has_value()) { + auto* resource = (*response)->add_resources(); + resource->CopyFrom(resource_state.resource.value()); + if (is_v2_) { + resource->set_type_url(v2_resource_type); + } + } + CompleteBuildingDiscoveryResponse( + resource_type, v2_resource_type, + resource_type_state.resource_type_version, subscription_name_map, + {resource_name}, sent_state, &response->value()); + } + } + } + + // Starting a thread to do blocking read on the stream until cancel. + void BlockingRead(Stream* stream, std::deque* requests, + bool* stream_closed) { + DiscoveryRequest request; + bool seen_first_request = false; + while (stream->Read(&request)) { + if (!seen_first_request) { + EXPECT_TRUE(request.has_node()); + ASSERT_FALSE(request.node().client_features().empty()); + EXPECT_EQ(request.node().client_features(0), + "envoy.lb.does_not_support_overprovisioning"); + CheckBuildVersion(request); + seen_first_request = true; + } + { + grpc_core::MutexLock lock(&parent_->ads_mu_); + requests->emplace_back(std::move(request)); + } + } + gpr_log(GPR_INFO, "ADS[%p]: Null read, stream closed", this); + grpc_core::MutexLock lock(&parent_->ads_mu_); + *stream_closed = true; + } + + // Completing the building a DiscoveryResponse by adding common information + // for all resources and by adding all subscribed resources for LDS and CDS. + void CompleteBuildingDiscoveryResponse( + const std::string& resource_type, const std::string& v2_resource_type, + const int version, const SubscriptionNameMap& subscription_name_map, + const std::set& resources_added_to_response, + SentState* sent_state, DiscoveryResponse* response) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(parent_->ads_mu_) { + NoopMutexLock mu(parent_->ads_mu_); + auto& response_state = + parent_->resource_type_response_state_[resource_type]; + if (response_state.state == ResponseState::NOT_SENT) { + response_state.state = ResponseState::SENT; + } + response->set_type_url(is_v2_ ? v2_resource_type : resource_type); + response->set_version_info(std::to_string(version)); + response->set_nonce(std::to_string(++sent_state->nonce)); + if (resource_type == kLdsTypeUrl || resource_type == kCdsTypeUrl) { + // For LDS and CDS we must send back all subscribed resources + // (even the unchanged ones) + for (const auto& p : subscription_name_map) { + const std::string& resource_name = p.first; + if (resources_added_to_response.find(resource_name) == + resources_added_to_response.end()) { + ResourceNameMap& resource_name_map = + parent_->resource_map_[resource_type].resource_name_map; + const ResourceState& resource_state = + resource_name_map[resource_name]; + if (resource_state.resource.has_value()) { + auto* resource = response->add_resources(); + resource->CopyFrom(resource_state.resource.value()); + if (is_v2_) { + resource->set_type_url(v2_resource_type); + } + } + } + } + } + sent_state->resource_type_version = version; + } + + static std::string TypeUrlToV2(const std::string& resource_type) { + if (resource_type == kLdsTypeUrl) return kLdsV2TypeUrl; + if (resource_type == kRdsTypeUrl) return kRdsV2TypeUrl; + if (resource_type == kCdsTypeUrl) return kCdsV2TypeUrl; + if (resource_type == kEdsTypeUrl) return kEdsV2TypeUrl; + return resource_type; + } + + static std::string TypeUrlToV3(const std::string& resource_type) { + if (resource_type == kLdsV2TypeUrl) return kLdsTypeUrl; + if (resource_type == kRdsV2TypeUrl) return kRdsTypeUrl; + if (resource_type == kCdsV2TypeUrl) return kCdsTypeUrl; + if (resource_type == kEdsV2TypeUrl) return kEdsTypeUrl; + return resource_type; + } + + static void CheckBuildVersion( + const ::envoy::api::v2::DiscoveryRequest& request) { + EXPECT_FALSE(request.node().build_version().empty()); + } + + static void CheckBuildVersion( + const ::envoy::service::discovery::v3::DiscoveryRequest& /*request*/) {} + + AdsServiceImpl* parent_; + const bool is_v2_; + }; + + // Checks whether the client needs to receive a newer version of + // the resource. + static bool ClientNeedsResourceUpdate( + const ResourceTypeState& resource_type_state, + const ResourceState& resource_state, int client_resource_type_version) { + return client_resource_type_version < + resource_type_state.resource_type_version && + resource_state.resource_type_version <= + resource_type_state.resource_type_version; + } + + // Subscribes to a resource if not already subscribed: + // 1. Sets the update_queue field in subscription_state. + // 2. Adds subscription_state to resource_state->subscriptions. + bool MaybeSubscribe(const std::string& resource_type, + const std::string& resource_name, + SubscriptionState* subscription_state, + ResourceState* resource_state, + UpdateQueue* update_queue) { + // The update_queue will be null if we were not previously subscribed. + if (subscription_state->update_queue != nullptr) return false; + subscription_state->update_queue = update_queue; + resource_state->subscriptions.emplace(subscription_state); + gpr_log(GPR_INFO, "ADS[%p]: subscribe to resource type %s name %s state %p", + this, resource_type.c_str(), resource_name.c_str(), + &subscription_state); + return true; + } + + // Removes subscriptions for resources no longer present in the + // current request. + void ProcessUnsubscriptions( + const std::string& resource_type, + const std::set& resources_in_current_request, + SubscriptionNameMap* subscription_name_map, + ResourceNameMap* resource_name_map) { + for (auto it = subscription_name_map->begin(); + it != subscription_name_map->end();) { + const std::string& resource_name = it->first; + SubscriptionState& subscription_state = it->second; + if (resources_in_current_request.find(resource_name) != + resources_in_current_request.end()) { + ++it; + continue; + } + gpr_log(GPR_INFO, "ADS[%p]: Unsubscribe to type=%s name=%s state=%p", + this, resource_type.c_str(), resource_name.c_str(), + &subscription_state); + auto resource_it = resource_name_map->find(resource_name); + GPR_ASSERT(resource_it != resource_name_map->end()); + auto& resource_state = resource_it->second; + resource_state.subscriptions.erase(&subscription_state); + if (resource_state.subscriptions.empty() && + !resource_state.resource.has_value()) { + resource_name_map->erase(resource_it); + } + it = subscription_name_map->erase(it); + } + } + + void AddClient(const std::string& client) { + grpc_core::MutexLock lock(&clients_mu_); + clients_.insert(client); + } + + void RemoveClient(const std::string& client) { + grpc_core::MutexLock lock(&clients_mu_); + clients_.erase(client); + } + + RpcService<::envoy::service::discovery::v2::AggregatedDiscoveryService, + ::envoy::api::v2::DiscoveryRequest, + ::envoy::api::v2::DiscoveryResponse> + v2_rpc_service_; + RpcService<::envoy::service::discovery::v3::AggregatedDiscoveryService, + ::envoy::service::discovery::v3::DiscoveryRequest, + ::envoy::service::discovery::v3::DiscoveryResponse> + v3_rpc_service_; + + std::atomic_bool seen_v2_client_{false}; + std::atomic_bool seen_v3_client_{false}; + + grpc_core::CondVar ads_cond_; + grpc_core::Mutex ads_mu_; + bool ads_done_ ABSL_GUARDED_BY(ads_mu_) = false; + std::map + resource_type_response_state_ ABSL_GUARDED_BY(ads_mu_); + std::set resource_types_to_ignore_ + ABSL_GUARDED_BY(ads_mu_); + std::map resource_type_min_versions_ + ABSL_GUARDED_BY(ads_mu_); + // An instance data member containing the current state of all resources. + // Note that an entry will exist whenever either of the following is true: + // - The resource exists (i.e., has been created by SetResource() and has not + // yet been destroyed by UnsetResource()). + // - There is at least one subscription for the resource. + ResourceMap resource_map_ ABSL_GUARDED_BY(ads_mu_); + + grpc_core::Mutex clients_mu_; + std::set clients_ ABSL_GUARDED_BY(clients_mu_); +}; + +class LrsServiceImpl : public std::enable_shared_from_this { + public: + explicit LrsServiceImpl(int client_load_reporting_interval_seconds) + : v2_rpc_service_(this), + v3_rpc_service_(this), + client_load_reporting_interval_seconds_( + client_load_reporting_interval_seconds), + cluster_names_({kDefaultClusterName}) {} + + ::envoy::service::load_stats::v2::LoadReportingService::Service* + v2_rpc_service() { + return &v2_rpc_service_; + } + + ::envoy::service::load_stats::v3::LoadReportingService::Service* + v3_rpc_service() { + return &v3_rpc_service_; + } + + size_t request_count() { + return v2_rpc_service_.request_count() + v3_rpc_service_.request_count(); + } + + size_t response_count() { + return v2_rpc_service_.response_count() + v3_rpc_service_.response_count(); + } + + // Must be called before the LRS call is started. + void set_send_all_clusters(bool send_all_clusters) { + send_all_clusters_ = send_all_clusters; + } + void set_cluster_names(const std::set& cluster_names) { + cluster_names_ = cluster_names; + } + + void Start() ABSL_LOCKS_EXCLUDED(lrs_mu_, load_report_mu_) { + { + grpc_core::MutexLock lock(&lrs_mu_); + lrs_done_ = false; + } + { + grpc_core::MutexLock lock(&load_report_mu_); + result_queue_.clear(); + } + } + + void Shutdown() { + { + grpc_core::MutexLock lock(&lrs_mu_); + NotifyDoneWithLrsCallLocked(); + } + gpr_log(GPR_INFO, "LRS[%p]: shut down", this); + } + + std::vector WaitForLoadReport() { + grpc_core::MutexLock lock(&load_report_mu_); + grpc_core::CondVar cv; + if (result_queue_.empty()) { + load_report_cond_ = &cv; + while (result_queue_.empty()) { + cv.Wait(&load_report_mu_); + } + load_report_cond_ = nullptr; + } + std::vector result = std::move(result_queue_.front()); + result_queue_.pop_front(); + return result; + } + + void NotifyDoneWithLrsCall() { + grpc_core::MutexLock lock(&lrs_mu_); + NotifyDoneWithLrsCallLocked(); + } + + private: + template + class RpcService : public CountedService { + public: + using Stream = ServerReaderWriter; + + explicit RpcService(LrsServiceImpl* parent) : parent_(parent) {} + + Status StreamLoadStats(ServerContext* /*context*/, + Stream* stream) override { + gpr_log(GPR_INFO, "LRS[%p]: StreamLoadStats starts", this); + EXPECT_GT(parent_->client_load_reporting_interval_seconds_, 0); + // Take a reference of the LrsServiceImpl object, reference will go + // out of scope after this method exits. + std::shared_ptr lrs_service_impl = + parent_->shared_from_this(); + // Read initial request. + LoadStatsRequest request; + if (stream->Read(&request)) { + CountedService::IncreaseRequestCount(); + // Verify client features. + EXPECT_THAT( + request.node().client_features(), + ::testing::Contains("envoy.lrs.supports_send_all_clusters")); + // Send initial response. + LoadStatsResponse response; + if (parent_->send_all_clusters_) { + response.set_send_all_clusters(true); + } else { + for (const std::string& cluster_name : parent_->cluster_names_) { + response.add_clusters(cluster_name); + } + } + response.mutable_load_reporting_interval()->set_seconds( + parent_->client_load_reporting_interval_seconds_); + stream->Write(response); + CountedService::IncreaseResponseCount(); + // Wait for report. + request.Clear(); + while (stream->Read(&request)) { + gpr_log(GPR_INFO, "LRS[%p]: received client load report message: %s", + this, request.DebugString().c_str()); + std::vector stats; + for (const auto& cluster_stats : request.cluster_stats()) { + stats.emplace_back(cluster_stats); + } + grpc_core::MutexLock lock(&parent_->load_report_mu_); + parent_->result_queue_.emplace_back(std::move(stats)); + if (parent_->load_report_cond_ != nullptr) { + parent_->load_report_cond_->Signal(); + } + } + // Wait until notified done. + grpc_core::MutexLock lock(&parent_->lrs_mu_); + while (!parent_->lrs_done_) { + parent_->lrs_cv_.Wait(&parent_->lrs_mu_); + } + } + gpr_log(GPR_INFO, "LRS[%p]: StreamLoadStats done", this); + return Status::OK; + } + + private: + LrsServiceImpl* parent_; + }; + + void NotifyDoneWithLrsCallLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(lrs_mu_) { + if (!lrs_done_) { + lrs_done_ = true; + lrs_cv_.SignalAll(); + } + } + + RpcService<::envoy::service::load_stats::v2::LoadReportingService, + ::envoy::service::load_stats::v2::LoadStatsRequest, + ::envoy::service::load_stats::v2::LoadStatsResponse> + v2_rpc_service_; + RpcService<::envoy::service::load_stats::v3::LoadReportingService, + ::envoy::service::load_stats::v3::LoadStatsRequest, + ::envoy::service::load_stats::v3::LoadStatsResponse> + v3_rpc_service_; + + const int client_load_reporting_interval_seconds_; + bool send_all_clusters_ = false; + std::set cluster_names_; + + grpc_core::CondVar lrs_cv_; + grpc_core::Mutex lrs_mu_; + bool lrs_done_ ABSL_GUARDED_BY(lrs_mu_) = false; + + grpc_core::Mutex load_report_mu_; + grpc_core::CondVar* load_report_cond_ ABSL_GUARDED_BY(load_report_mu_) = + nullptr; + std::deque> result_queue_ + ABSL_GUARDED_BY(load_report_mu_); +}; + class TestType { public: enum FilterConfigSetup { @@ -1338,67 +2372,32 @@ class XdsEnd2endTest : public ::testing::TestWithParam { return listener; } - struct EdsResourceArgs { - struct Endpoint { - explicit Endpoint(int port, - HealthStatus health_status = HealthStatus::UNKNOWN, - int lb_weight = 1) - : port(port), health_status(health_status), lb_weight(lb_weight) {} - - int port; - HealthStatus health_status; - int lb_weight; - }; - - struct Locality { - Locality(std::string sub_zone, std::vector endpoints, - int lb_weight = kDefaultLocalityWeight, - int priority = kDefaultLocalityPriority) - : sub_zone(std::move(sub_zone)), - endpoints(std::move(endpoints)), - lb_weight(lb_weight), - priority(priority) {} - - const std::string sub_zone; - std::vector endpoints; - int lb_weight; - int priority; - }; - - EdsResourceArgs() = default; - explicit EdsResourceArgs(std::vector locality_list) - : locality_list(std::move(locality_list)) {} - - std::vector locality_list; - std::map drop_categories; - FractionalPercent::DenominatorType drop_denominator = - FractionalPercent::MILLION; - }; - - EdsResourceArgs::Endpoint CreateEndpoint( + AdsServiceImpl::EdsResourceArgs::Endpoint CreateEndpoint( size_t backend_idx, HealthStatus health_status = HealthStatus::UNKNOWN, int lb_weight = 1) { - return EdsResourceArgs::Endpoint(backends_[backend_idx]->port(), - health_status, lb_weight); + return AdsServiceImpl::EdsResourceArgs::Endpoint( + backends_[backend_idx]->port(), health_status, lb_weight); } - std::vector CreateEndpointsForBackends( - size_t start_index = 0, size_t stop_index = 0, - HealthStatus health_status = HealthStatus::UNKNOWN, int lb_weight = 1) { + std::vector + CreateEndpointsForBackends(size_t start_index = 0, size_t stop_index = 0, + HealthStatus health_status = HealthStatus::UNKNOWN, + int lb_weight = 1) { if (stop_index == 0) stop_index = backends_.size(); - std::vector endpoints; + std::vector endpoints; for (size_t i = start_index; i < stop_index; ++i) { endpoints.emplace_back(CreateEndpoint(i, health_status, lb_weight)); } return endpoints; } - EdsResourceArgs::Endpoint MakeNonExistantEndpoint() { - return EdsResourceArgs::Endpoint(grpc_pick_unused_port_or_die()); + AdsServiceImpl::EdsResourceArgs::Endpoint MakeNonExistantEndpoint() { + return AdsServiceImpl::EdsResourceArgs::Endpoint( + grpc_pick_unused_port_or_die()); } ClusterLoadAssignment BuildEdsResource( - const EdsResourceArgs& args, + const AdsServiceImpl::EdsResourceArgs& args, const char* eds_service_name = kDefaultEdsServiceName) { ClusterLoadAssignment assignment; assignment.set_cluster_name(eds_service_name); @@ -1708,8 +2707,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam { int client_load_reporting_interval = 0) : ServerThread(test_obj), ads_service_(new AdsServiceImpl()), - lrs_service_(new LrsServiceImpl(client_load_reporting_interval, - {kDefaultClusterName})) {} + lrs_service_(new LrsServiceImpl(client_load_reporting_interval)) {} AdsServiceImpl* ads_service() { return ads_service_.get(); } LrsServiceImpl* lrs_service() { return lrs_service_.get(); } @@ -1867,7 +2865,7 @@ TEST_P(BasicTest, Vanilla) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); const size_t kNumRpcsPerAddress = 100; - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -1896,7 +2894,7 @@ TEST_P(BasicTest, IgnoresUnhealthyEndpoints) { const size_t kNumRpcsPerAddress = 100; auto endpoints = CreateEndpointsForBackends(); endpoints[0].health_status = HealthStatus::DRAINING; - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", std::move(endpoints), kDefaultLocalityWeight, kDefaultLocalityPriority}, }); @@ -1923,7 +2921,7 @@ TEST_P(BasicTest, SameBackendListedMultipleTimes) { // Same backend listed twice. auto endpoints = CreateEndpointsForBackends(0, 1); endpoints.push_back(endpoints.front()); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", endpoints}, }); const size_t kNumRpcsPerAddress = 10; @@ -1948,14 +2946,14 @@ TEST_P(BasicTest, InitiallyEmptyServerlist) { const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); const int kCallDeadlineMs = kServerlistDelayMs * 2; // First response is an empty serverlist, sent right away. - EdsResourceArgs::Locality empty_locality("locality0", {}); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs::Locality empty_locality("locality0", {}); + AdsServiceImpl::EdsResourceArgs args({ empty_locality, }); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Send non-empty serverlist only after kServerlistDelayMs. - args = EdsResourceArgs({ + args = AdsServiceImpl::EdsResourceArgs({ {"locality0", CreateEndpointsForBackends()}, }); std::thread delayed_resource_setter(std::bind( @@ -1985,11 +2983,11 @@ TEST_P(BasicTest, AllServersUnreachableFailFast) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); const size_t kNumUnreachableServers = 5; - std::vector endpoints; + std::vector endpoints; for (size_t i = 0; i < kNumUnreachableServers; ++i) { endpoints.emplace_back(grpc_pick_unused_port_or_die()); } - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", endpoints}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2006,7 +3004,7 @@ TEST_P(BasicTest, AllServersUnreachableFailFast) { TEST_P(BasicTest, BackendsRestart) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2033,7 +3031,7 @@ TEST_P(BasicTest, IgnoresDuplicateUpdates) { const size_t kNumRpcsPerAddress = 100; SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2062,7 +3060,7 @@ using XdsResolverOnlyTest = BasicTest; TEST_P(XdsResolverOnlyTest, ResourceTypeVersionPersistsAcrossStreamRestarts) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2077,7 +3075,7 @@ TEST_P(XdsResolverOnlyTest, ResourceTypeVersionPersistsAcrossStreamRestarts) { balancers_[0]->ads_service()->SetResourceMinVersion(kEdsTypeUrl, 1); // Update backend, just so we can be sure that the client has // reconnected to the balancer. - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args2)); @@ -2093,14 +3091,14 @@ TEST_P(XdsResolverOnlyTest, ChangeClusters) { const char* kNewEdsServiceName = "new_eds_service_name"; SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); // We need to wait for all backends to come online. WaitForAllBackends(0, 2); // Populate new EDS resource. - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 4)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2128,7 +3126,7 @@ TEST_P(XdsResolverOnlyTest, ChangeClusters) { TEST_P(XdsResolverOnlyTest, ClusterRemoved) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2164,7 +3162,7 @@ TEST_P(XdsResolverOnlyTest, RestartsRequestsUponReconnection) { const char* kNewEdsServiceName = "new_eds_service_name"; SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2178,7 +3176,7 @@ TEST_P(XdsResolverOnlyTest, RestartsRequestsUponReconnection) { // Make sure things are still working. CheckRpcSendOk(100); // Populate new EDS resource. - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 4)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2211,7 +3209,7 @@ TEST_P(XdsResolverOnlyTest, DefaultRouteSpecifiesSlashPrefix) { SetListenerAndRouteConfiguration(0, default_listener_, route_config); SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2224,7 +3222,7 @@ TEST_P(XdsResolverOnlyTest, CircuitBreaking) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2266,7 +3264,7 @@ TEST_P(XdsResolverOnlyTest, CircuitBreaking) { TEST_P(XdsResolverOnlyTest, CircuitBreakingMultipleChannelsShareCallCounter) { constexpr size_t kMaxConcurrentRequests = 10; // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2327,7 +3325,7 @@ TEST_P(XdsResolverOnlyTest, CircuitBreakingMultipleChannelsShareCallCounter) { TEST_P(XdsResolverOnlyTest, ClusterChangeAfterAdsCallFails) { const char* kNewEdsResourceName = "new_eds_resource_name"; // Populate EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2338,7 +3336,7 @@ TEST_P(XdsResolverOnlyTest, ClusterChangeAfterAdsCallFails) { balancers_[0]->Shutdown(); balancers_[0]->Start(); // Create new EDS resource. - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2375,7 +3373,7 @@ TEST_P(GlobalXdsClientTest, MultipleChannelsShareXdsClient) { SetListenerAndRouteConfiguration(0, listener, default_route_config_); SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2401,7 +3399,7 @@ TEST_P(GlobalXdsClientTest, MultipleBadResources) { listener = default_listener_; listener.set_name(kServerName3); SetListenerAndRouteConfiguration(0, listener, default_route_config_); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2460,7 +3458,7 @@ TEST_P(GlobalXdsClientTest, MultipleBadResources) { // that was previously valid but is updated to be invalid. TEST_P(GlobalXdsClientTest, InvalidListenerStillExistsIfPreviouslyCached) { // Set up valid resources and check that the channel works. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -2500,12 +3498,12 @@ TEST_P(XdsResolverLoadReportingOnlyTest, ChangeClusters) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // cluster kDefaultClusterName -> locality0 -> backends 0 and 1 - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); // cluster kNewClusterName -> locality1 -> backends 2 and 3 - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality1", CreateEndpointsForBackends(2, 4)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2625,7 +3623,7 @@ using SecureNamingTest = BasicTest; TEST_P(SecureNamingTest, TargetNameIsExpected) { SetNextResolution({}); SetNextResolutionForLbChannel({balancers_[0]->port()}, nullptr, "xds_server"); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2639,7 +3637,7 @@ TEST_P(SecureNamingTest, TargetNameIsUnexpected) { SetNextResolution({}); SetNextResolutionForLbChannel({balancers_[0]->port()}, nullptr, "incorrect_server_name"); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2869,7 +3867,7 @@ TEST_P(LdsTest, IgnoresOptionalUnknownHttpFilterType) { listener.mutable_api_listener()->mutable_api_listener()->PackFrom( http_connection_manager); SetListenerAndRouteConfiguration(0, listener, default_route_config_); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -2919,7 +3917,7 @@ TEST_P(LdsTest, IgnoresOptionalHttpFilterWithoutConfig) { listener.mutable_api_listener()->mutable_api_listener()->PackFrom( http_connection_manager); SetListenerAndRouteConfiguration(0, listener, default_route_config_); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -3000,7 +3998,7 @@ TEST_P(LdsTest, IgnoresOptionalHttpFiltersNotSupportedOnClients) { listener.mutable_api_listener()->mutable_api_listener()->PackFrom( http_connection_manager); SetListenerAndRouteConfiguration(0, listener, default_route_config_); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -3028,7 +4026,7 @@ TEST_P(LdsV2Test, IgnoresHttpFilters) { listener.mutable_api_listener()->mutable_api_listener()->PackFrom( http_connection_manager); SetListenerAndRouteConfiguration(0, listener, default_route_config_); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -3058,7 +4056,7 @@ TEST_P(LdsRdsTest, Vanilla) { TEST_P(LdsRdsTest, ListenerRemoved) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -3521,13 +4519,13 @@ TEST_P(LdsRdsTest, XdsRoutingPathMatching) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 2)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(3, 4)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -3596,13 +4594,13 @@ TEST_P(LdsRdsTest, XdsRoutingPathMatchingCaseInsensitive) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -3661,13 +4659,13 @@ TEST_P(LdsRdsTest, XdsRoutingPrefixMatching) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 2)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(3, 4)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -3731,13 +4729,13 @@ TEST_P(LdsRdsTest, XdsRoutingPrefixMatchingCaseInsensitive) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -3796,13 +4794,13 @@ TEST_P(LdsRdsTest, XdsRoutingPathRegexMatching) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 2)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(3, 4)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -3875,13 +4873,13 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedCluster) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -3962,13 +4960,13 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetDefaultRoute) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4042,16 +5040,16 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateWeights) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); - EdsResourceArgs args3({ + AdsServiceImpl::EdsResourceArgs args3({ {"locality0", CreateEndpointsForBackends(3, 4)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4174,16 +5172,16 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateClusters) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); - EdsResourceArgs args3({ + AdsServiceImpl::EdsResourceArgs args3({ {"locality0", CreateEndpointsForBackends(3, 4)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4315,10 +5313,10 @@ TEST_P(LdsRdsTest, XdsRoutingClusterUpdateClusters) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4354,10 +5352,10 @@ TEST_P(LdsRdsTest, XdsRoutingClusterUpdateClustersWithPickingDelays) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4420,10 +5418,14 @@ TEST_P(LdsRdsTest, XdsRoutingApplyXdsTimeout) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}}); - EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}}); - EdsResourceArgs args2({{"locality0", {MakeNonExistantEndpoint()}}}); - EdsResourceArgs args3({{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args1( + {{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args2( + {{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args3( + {{"locality0", {MakeNonExistantEndpoint()}}}); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args1, kNewEdsService1Name)); @@ -4548,9 +5550,12 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit0) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}}); - EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}}); - EdsResourceArgs args2({{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args1( + {{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args2( + {{"locality0", {MakeNonExistantEndpoint()}}}); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args1, kNewEdsService1Name)); @@ -4643,7 +5648,8 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit0) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", {MakeNonExistantEndpoint()}}}); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); auto listener = default_listener_; HttpConnectionManager http_connection_manager; @@ -4681,7 +5687,8 @@ TEST_P(LdsRdsTest, XdsRoutingWithOnlyApplicationTimeout) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({{"locality0", {MakeNonExistantEndpoint()}}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", {MakeNonExistantEndpoint()}}}); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); auto t0 = system_clock::now(); CheckRpcSendFailure( @@ -4701,7 +5708,7 @@ TEST_P(LdsRdsTest, XdsRetryPolicyNumRetries) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4764,7 +5771,7 @@ TEST_P(LdsRdsTest, XdsRetryPolicyAtVirtualHostLevel) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4792,7 +5799,7 @@ TEST_P(LdsRdsTest, XdsRetryPolicyLongBackOff) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4828,7 +5835,7 @@ TEST_P(LdsRdsTest, XdsRetryPolicyMaxBackOff) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4869,7 +5876,7 @@ TEST_P(LdsRdsTest, XdsRetryPolicyUnsupportedStatusCode) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4895,7 +5902,7 @@ TEST_P(LdsRdsTest, SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4926,7 +5933,7 @@ TEST_P(LdsRdsTest, XdsRetryPolicyInvalidNumRetriesZero) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4951,7 +5958,7 @@ TEST_P(LdsRdsTest, XdsRetryPolicyRetryBackOffMissingBaseInterval) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -4984,10 +5991,10 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatching) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -5068,10 +6075,10 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialHeaderContentType) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -5115,10 +6122,10 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialCasesToIgnore) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -5168,10 +6175,10 @@ TEST_P(LdsRdsTest, XdsRoutingRuntimeFractionMatching) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -5221,16 +6228,16 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingUnmatchCases) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); - EdsResourceArgs args3({ + AdsServiceImpl::EdsResourceArgs args3({ {"locality0", CreateEndpointsForBackends(3, 4)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -5314,10 +6321,10 @@ TEST_P(LdsRdsTest, XdsRoutingChangeRoutesWithoutChangingClusters) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -5405,7 +6412,7 @@ TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInVirtualHost) { filter_config.set_is_optional(true); (*per_filter_config)["unknown"].PackFrom(filter_config); SetListenerAndRouteConfiguration(0, default_listener_, route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -5464,7 +6471,7 @@ TEST_P(LdsRdsTest, IgnoresOptionalHttpFilterWithoutConfigInVirtualHost) { filter_config.set_is_optional(true); (*per_filter_config)["unknown"].PackFrom(filter_config); SetListenerAndRouteConfiguration(0, default_listener_, route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -5526,7 +6533,7 @@ TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInRoute) { filter_config.set_is_optional(true); (*per_filter_config)["unknown"].PackFrom(filter_config); SetListenerAndRouteConfiguration(0, default_listener_, route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -5588,7 +6595,7 @@ TEST_P(LdsRdsTest, IgnoresOptionalHttpFilterWithoutConfigInRoute) { filter_config.set_is_optional(true); (*per_filter_config)["unknown"].PackFrom(filter_config); SetListenerAndRouteConfiguration(0, default_listener_, route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -5661,7 +6668,7 @@ TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInClusterWeight) { filter_config.set_is_optional(true); (*per_filter_config)["unknown"].PackFrom(filter_config); SetListenerAndRouteConfiguration(0, default_listener_, route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -5739,7 +6746,7 @@ TEST_P(LdsRdsTest, IgnoresOptionalHttpFilterWithoutConfigInClusterWeight) { filter_config.set_is_optional(true); (*per_filter_config)["unknown"].PackFrom(filter_config); SetListenerAndRouteConfiguration(0, default_listener_, route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6085,10 +7092,10 @@ TEST_P(CdsTest, AggregateClusterType) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Populate new EDS resources. - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6138,7 +7145,7 @@ TEST_P(CdsTest, AggregateClusterEdsToLogicalDns) { const char* kNewEdsService1Name = "new_eds_service_name_1"; const char* kLogicalDNSClusterName = "logical_dns_cluster"; // Populate new EDS resources. - EdsResourceArgs args1({ + AdsServiceImpl::EdsResourceArgs args1({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6202,7 +7209,7 @@ TEST_P(CdsTest, AggregateClusterLogicalDnsToEds) { const char* kNewEdsService2Name = "new_eds_service_name_2"; const char* kLogicalDNSClusterName = "logical_dns_cluster"; // Populate new EDS resources. - EdsResourceArgs args2({ + AdsServiceImpl::EdsResourceArgs args2({ {"locality0", CreateEndpointsForBackends(2, 3)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6346,7 +7353,7 @@ TEST_P(CdsTest, MultipleBadResources) { route->mutable_route()->set_cluster(kClusterName3); SetRouteConfiguration(0, route_config); // Add EDS resource. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -6382,7 +7389,7 @@ TEST_P(CdsTest, MultipleBadResources) { // Tests that we don't trigger does-not-exist callbacks for a resource // that was previously valid but is updated to be invalid. TEST_P(CdsTest, InvalidClusterStillExistsIfPreviouslyCached) { - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -6468,7 +7475,7 @@ TEST_P(CdsTest, RingHashChannelIdHashing) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_filter_state()->set_key("io.grpc.channel_id"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6498,7 +7505,7 @@ TEST_P(CdsTest, RingHashHeaderHashing) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_header()->set_header_name("address_hash"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6549,7 +7556,7 @@ TEST_P(CdsTest, RingHashHeaderHashingWithRegexRewrite) { hash_policy->mutable_header()->mutable_regex_rewrite()->set_substitution( "foo"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6596,7 +7603,8 @@ TEST_P(CdsTest, RingHashNoHashPolicy) { 100000); cluster.set_lb_policy(Cluster::RING_HASH); balancers_[0]->ads_service()->SetCdsResource(cluster); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 2)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 2)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); SetNextResolutionForLbChannelAllBalancers(); @@ -6627,7 +7635,8 @@ TEST_P(CdsTest, RingHashContinuesPastTerminalPolicyThatDoesNotProduceResult) { auto* hash_policy2 = route->mutable_route()->add_hash_policy(); hash_policy2->mutable_header()->set_header_name("address_hash"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 2)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 2)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); SetNextResolutionForLbChannelAllBalancers(); @@ -6658,7 +7667,8 @@ TEST_P(CdsTest, RingHashOnHeaderThatIsNotPresent) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_header()->set_header_name("header_not_present"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 2)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 2)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); SetNextResolutionForLbChannelAllBalancers(); @@ -6704,7 +7714,8 @@ TEST_P(CdsTest, RingHashUnsupportedHashPolicyDefaultToRandomHashing) { hash_policy_unsupported_3->mutable_query_parameter()->set_name( "query_parameter"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 2)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 2)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); SetNextResolutionForLbChannelAllBalancers(); @@ -6739,9 +7750,10 @@ TEST_P(CdsTest, RingHashRandomHashingDistributionAccordingToEndpointWeight) { 100000); cluster.set_lb_policy(Cluster::RING_HASH); balancers_[0]->ads_service()->SetCdsResource(cluster); - EdsResourceArgs args({{"locality0", - {CreateEndpoint(0, HealthStatus::UNKNOWN, 1), - CreateEndpoint(1, HealthStatus::UNKNOWN, 2)}}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", + {CreateEndpoint(0, HealthStatus::UNKNOWN, 1), + CreateEndpoint(1, HealthStatus::UNKNOWN, 2)}}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); SetNextResolutionForLbChannelAllBalancers(); @@ -6779,7 +7791,7 @@ TEST_P(CdsTest, 100000); cluster.set_lb_policy(Cluster::RING_HASH); balancers_[0]->ads_service()->SetCdsResource(cluster); - EdsResourceArgs args( + AdsServiceImpl::EdsResourceArgs args( {{"locality0", {CreateEndpoint(0, HealthStatus::UNKNOWN, 1)}, 1}, {"locality1", {CreateEndpoint(1, HealthStatus::UNKNOWN, 2)}, 2}}); balancers_[0]->ads_service()->SetEdsResource( @@ -6816,7 +7828,7 @@ TEST_P(CdsTest, RingHashEndpointWeightDoesNotImpactWeightedRoundRobin) { const size_t kNumRpcs = ComputeIdealNumRpcs(kLocalityWeightRate0, kErrorTolerance); // ADS response contains 2 localities, each of which contains 1 backend. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", {CreateEndpoint(0, HealthStatus::UNKNOWN, 8)}, kLocalityWeight0}, @@ -6858,7 +7870,7 @@ TEST_P(CdsTest, RingHashFixedHashingTerminalPolicy) { auto* hash_policy_to_be_ignored = route->mutable_route()->add_hash_policy(); hash_policy_to_be_ignored->mutable_header()->set_header_name("random_string"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6894,7 +7906,7 @@ TEST_P(CdsTest, RingHashIdleToReady) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_filter_state()->set_key("io.grpc.channel_id"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6916,11 +7928,11 @@ TEST_P(CdsTest, RingHashTransientFailureCheckNextOne) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_header()->set_header_name("address_hash"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - std::vector endpoints; + std::vector endpoints; const int unused_port = grpc_pick_unused_port_or_die(); endpoints.emplace_back(unused_port); endpoints.emplace_back(backends_[1]->port()); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", std::move(endpoints)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -6948,7 +7960,7 @@ TEST_P(CdsTest, RingHashSwitchToLowerPrioirtyAndThenBack) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_header()->set_header_name("address_hash"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 0}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -6982,10 +7994,10 @@ TEST_P(CdsTest, RingHashAllFailReattempt) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_header()->set_header_name("address_hash"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - std::vector endpoints; + std::vector endpoints; endpoints.emplace_back(grpc_pick_unused_port_or_die()); endpoints.emplace_back(backends_[1]->port()); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", std::move(endpoints)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -7015,13 +8027,13 @@ TEST_P(CdsTest, RingHashTransientFailureSkipToAvailableReady) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_header()->set_header_name("address_hash"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - std::vector endpoints; + std::vector endpoints; // Make sure we include some unused ports to fill the ring. endpoints.emplace_back(backends_[0]->port()); endpoints.emplace_back(backends_[1]->port()); endpoints.emplace_back(grpc_pick_unused_port_or_die()); endpoints.emplace_back(grpc_pick_unused_port_or_die()); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", std::move(endpoints)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -7079,7 +8091,7 @@ TEST_P(CdsTest, RingHashUnsupportedHashPolicyUntilChannelIdHashing) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_filter_state()->set_key("io.grpc.channel_id"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -7111,7 +8123,7 @@ TEST_P(CdsTest, RingHashPolicyHasInvalidHashFunction) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_filter_state()->set_key("io.grpc.channel_id"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -7138,7 +8150,7 @@ TEST_P(CdsTest, RingHashPolicyHasInvalidMinimumRingSize) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_filter_state()->set_key("io.grpc.channel_id"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -7165,7 +8177,7 @@ TEST_P(CdsTest, RingHashPolicyHasInvalidMaxmumRingSize) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_filter_state()->set_key("io.grpc.channel_id"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -7194,7 +8206,7 @@ TEST_P(CdsTest, RingHashPolicyHasInvalidRingSizeMinGreaterThanMax) { auto* hash_policy = route->mutable_route()->add_hash_policy(); hash_policy->mutable_filter_state()->set_key("io.grpc.channel_id"); SetListenerAndRouteConfiguration(0, default_listener_, new_route_config); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -7235,7 +8247,7 @@ class XdsSecurityTest : public BasicTest { fallback_authenticated_identity_ = {"*.test.google.fr", "waterzooi.test.google.be", "*.test.youtube.com", "192.168.1.3"}; - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -8145,7 +9157,7 @@ class XdsEnabledServerTest : public XdsEnd2endTest { void SetUp() override { XdsEnd2endTest::SetUp(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -8373,7 +9385,7 @@ class XdsServerSecurityTest : public XdsEnd2endTest { client_authenticated_identity_ = {"*.test.google.fr", "waterzooi.test.google.be", "*.test.youtube.com", "192.168.1.3"}; - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -9813,7 +10825,7 @@ using EdsTest = BasicTest; TEST_P(EdsTest, NacksSparsePriorityList) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(), kDefaultLocalityWeight, 1}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); @@ -9831,7 +10843,7 @@ TEST_P(EdsTest, NacksSparsePriorityList) { // this test to make sure that the EDS resource name defaults to the // cluster name if not specified in the CDS resource. TEST_P(EdsTest, EdsServiceNameDefaultsToClusterName) { - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -9854,14 +10866,14 @@ class TimeoutTest : public BasicTest { // Tests that LDS client times out when no response received. TEST_P(TimeoutTest, Lds) { - balancers_[0]->ads_service()->IgnoreResourceType(kLdsTypeUrl); + balancers_[0]->ads_service()->SetResourceIgnore(kLdsTypeUrl); SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); } TEST_P(TimeoutTest, Rds) { - balancers_[0]->ads_service()->IgnoreResourceType(kRdsTypeUrl); + balancers_[0]->ads_service()->SetResourceIgnore(kRdsTypeUrl); SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); @@ -9869,14 +10881,14 @@ TEST_P(TimeoutTest, Rds) { // Tests that CDS client times out when no response received. TEST_P(TimeoutTest, Cds) { - balancers_[0]->ads_service()->IgnoreResourceType(kCdsTypeUrl); + balancers_[0]->ads_service()->SetResourceIgnore(kCdsTypeUrl); SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); } TEST_P(TimeoutTest, Eds) { - balancers_[0]->ads_service()->IgnoreResourceType(kEdsTypeUrl); + balancers_[0]->ads_service()->SetResourceIgnore(kEdsTypeUrl); SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); @@ -9900,7 +10912,7 @@ TEST_P(LocalityMapTest, WeightedRoundRobin) { const size_t kNumRpcs = ComputeIdealNumRpcs(kLocalityWeightRate0, kErrorTolerance); // ADS response contains 2 localities, each of which contains 1 backend. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kLocalityWeight0}, {"locality1", CreateEndpointsForBackends(1, 2), kLocalityWeight1}, }); @@ -9929,7 +10941,7 @@ TEST_P(LocalityMapTest, LocalityContainingNoEndpoints) { SetNextResolutionForLbChannelAllBalancers(); const size_t kNumRpcs = 5000; // EDS response contains 2 localities, one with no endpoints. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, {"locality1", {}}, }); @@ -9970,16 +10982,17 @@ TEST_P(LocalityMapTest, StressTest) { const uint32_t kRpcTimeoutMs = 5000; // The first ADS response contains kNumLocalities localities, each of which // contains backend 0. - EdsResourceArgs args; + AdsServiceImpl::EdsResourceArgs args; for (size_t i = 0; i < kNumLocalities; ++i) { std::string name = absl::StrCat("locality", i); - EdsResourceArgs::Locality locality(name, CreateEndpointsForBackends(0, 1)); + AdsServiceImpl::EdsResourceArgs::Locality locality( + name, CreateEndpointsForBackends(0, 1)); args.locality_list.emplace_back(std::move(locality)); } balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // The second ADS response contains 1 locality, which contains backend 1. - args = EdsResourceArgs({ + args = AdsServiceImpl::EdsResourceArgs({ {"locality0", CreateEndpointsForBackends(1, 2)}, }); std::thread delayed_resource_setter( @@ -10021,7 +11034,7 @@ TEST_P(LocalityMapTest, UpdateMap) { for (int weight : kLocalityWeights1) { locality_weight_rate_1.push_back(weight / kTotalLocalityWeight1); } - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), 2}, {"locality1", CreateEndpointsForBackends(1, 2), 3}, {"locality2", CreateEndpointsForBackends(2, 3), 4}, @@ -10052,7 +11065,7 @@ TEST_P(LocalityMapTest, UpdateMap) { ::testing::Ge(locality_weight_rate_0[i] * (1 - kErrorTolerance)), ::testing::Le(locality_weight_rate_0[i] * (1 + kErrorTolerance)))); } - args = EdsResourceArgs({ + args = AdsServiceImpl::EdsResourceArgs({ {"locality1", CreateEndpointsForBackends(1, 2), 3}, {"locality2", CreateEndpointsForBackends(2, 3), 2}, {"locality3", CreateEndpointsForBackends(3, 4), 6}, @@ -10094,12 +11107,12 @@ TEST_P(LocalityMapTest, UpdateMap) { TEST_P(LocalityMapTest, ReplaceAllLocalitiesInPriority) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1)}, }); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); - args = EdsResourceArgs({ + args = AdsServiceImpl::EdsResourceArgs({ {"locality1", CreateEndpointsForBackends(1, 2)}, }); std::thread delayed_resource_setter( @@ -10126,7 +11139,7 @@ class FailoverTest : public BasicTest { TEST_P(FailoverTest, ChooseHighestPriority) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 1}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -10148,7 +11161,7 @@ TEST_P(FailoverTest, ChooseHighestPriority) { TEST_P(FailoverTest, DoesNotUsePriorityWithNoEndpoints) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 1}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -10169,7 +11182,7 @@ TEST_P(FailoverTest, DoesNotUsePriorityWithNoEndpoints) { TEST_P(FailoverTest, DoesNotUseLocalityWithNoEndpoints) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", {}, kDefaultLocalityWeight, 0}, {"locality1", CreateEndpointsForBackends(), kDefaultLocalityWeight, 0}, }); @@ -10186,7 +11199,7 @@ TEST_P(FailoverTest, DoesNotUseLocalityWithNoEndpoints) { TEST_P(FailoverTest, Failover) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 1}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -10213,7 +11226,7 @@ TEST_P(FailoverTest, SwitchBackToHigherPriority) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); const size_t kNumRpcs = 100; - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 1}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -10246,7 +11259,7 @@ TEST_P(FailoverTest, SwitchBackToHigherPriority) { TEST_P(FailoverTest, UpdateInitialUnavailable) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 0}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -10254,7 +11267,7 @@ TEST_P(FailoverTest, UpdateInitialUnavailable) { }); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); - args = EdsResourceArgs({ + args = AdsServiceImpl::EdsResourceArgs({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 0}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -10291,7 +11304,7 @@ TEST_P(FailoverTest, UpdatePriority) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); const size_t kNumRpcs = 100; - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 1}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -10303,7 +11316,7 @@ TEST_P(FailoverTest, UpdatePriority) { }); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); - args = EdsResourceArgs({ + args = AdsServiceImpl::EdsResourceArgs({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 2}, {"locality1", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight, @@ -10334,7 +11347,7 @@ TEST_P(FailoverTest, MoveAllLocalitiesInCurrentPriorityToHigherPriority) { // - Priority 0 is locality 0, containing backend 0, which is down. // - Priority 1 is locality 1, containing backends 1 and 2, which are up. ShutdownBackend(0); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 0}, {"locality1", CreateEndpointsForBackends(1, 3), kDefaultLocalityWeight, @@ -10347,7 +11360,7 @@ TEST_P(FailoverTest, MoveAllLocalitiesInCurrentPriorityToHigherPriority) { // - Priority 1 is not present. // - We add backend 3 to locality 1, just so we have a way to know // when the update has been seen by the client. - args = EdsResourceArgs({ + args = AdsServiceImpl::EdsResourceArgs({ {"locality0", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight, 0}, {"locality1", CreateEndpointsForBackends(1, 4), kDefaultLocalityWeight, @@ -10385,7 +11398,7 @@ TEST_P(DropTest, Vanilla) { const size_t kNumRpcs = ComputeIdealNumRpcs(kDropRateForLbAndThrottle, kErrorTolerance); // The ADS response contains two drop categories. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, @@ -10422,7 +11435,7 @@ TEST_P(DropTest, DropPerHundred) { const double kErrorTolerance = 0.05; const size_t kNumRpcs = ComputeIdealNumRpcs(kDropRateForLb, kErrorTolerance); // The ADS response contains one drop category. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); args.drop_categories = {{kLbDropType, kDropPerHundredForLb}}; @@ -10459,7 +11472,7 @@ TEST_P(DropTest, DropPerTenThousand) { const double kErrorTolerance = 0.05; const size_t kNumRpcs = ComputeIdealNumRpcs(kDropRateForLb, kErrorTolerance); // The ADS response contains one drop category. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); args.drop_categories = {{kLbDropType, kDropPerTenThousandForLb}}; @@ -10503,7 +11516,7 @@ TEST_P(DropTest, Update) { const size_t kNumRpcsBoth = ComputeIdealNumRpcs(kDropRateForLbAndThrottle, kErrorTolerance); // The first ADS response contains one drop category. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); args.drop_categories = {{kLbDropType, kDropPerMillionForLb}}; @@ -10587,7 +11600,7 @@ TEST_P(DropTest, DropAll) { const uint32_t kDropPerMillionForLb = 100000; const uint32_t kDropPerMillionForThrottle = 1000000; // The ADS response contains two drop categories. - EdsResourceArgs args; + AdsServiceImpl::EdsResourceArgs args; args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, {kThrottleDropType, kDropPerMillionForThrottle}}; balancers_[0]->ads_service()->SetEdsResource( @@ -10612,10 +11625,12 @@ class BalancerUpdateTest : public XdsEnd2endTest { TEST_P(BalancerUpdateTest, UpdateBalancersButKeepUsingOriginalBalancer) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 1)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); - args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}}); + args = AdsServiceImpl::EdsResourceArgs( + {{"locality0", CreateEndpointsForBackends(1, 2)}}); balancers_[1]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Wait until the first backend is ready. @@ -10671,10 +11686,12 @@ TEST_P(BalancerUpdateTest, UpdateBalancersButKeepUsingOriginalBalancer) { TEST_P(BalancerUpdateTest, Repeated) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 1)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); - args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}}); + args = AdsServiceImpl::EdsResourceArgs( + {{"locality0", CreateEndpointsForBackends(1, 2)}}); balancers_[1]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Wait until the first backend is ready. @@ -10737,10 +11754,12 @@ TEST_P(BalancerUpdateTest, Repeated) { TEST_P(BalancerUpdateTest, DeadUpdate) { SetNextResolution({}); SetNextResolutionForLbChannel({balancers_[0]->port()}); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 1)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); - args = EdsResourceArgs({{"locality0", CreateEndpointsForBackends(1, 2)}}); + args = AdsServiceImpl::EdsResourceArgs( + {{"locality0", CreateEndpointsForBackends(1, 2)}}); balancers_[1]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Start servers and send 10 RPCs per server. @@ -10828,7 +11847,7 @@ TEST_P(ClientLoadReportingTest, Vanilla) { const size_t kNumFailuresPerAddress = 3; // TODO(juanlishen): Partition the backends after multiple localities is // tested. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -10876,7 +11895,7 @@ TEST_P(ClientLoadReportingTest, SendAllClusters) { const size_t kNumFailuresPerAddress = 3; // TODO(juanlishen): Partition the backends after multiple localities is // tested. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -10922,7 +11941,7 @@ TEST_P(ClientLoadReportingTest, HonorsClustersRequestedByLrsServer) { SetNextResolution({}); SetNextResolutionForLbChannel({balancers_[0]->port()}); const size_t kNumRpcsPerAddress = 100; - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -10959,7 +11978,7 @@ TEST_P(ClientLoadReportingTest, BalancerRestart) { const size_t kNumBackendsFirstPass = backends_.size() / 2; const size_t kNumBackendsSecondPass = backends_.size() - kNumBackendsFirstPass; - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends(0, kNumBackendsFirstPass)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -10997,7 +12016,7 @@ TEST_P(ClientLoadReportingTest, BalancerRestart) { /* start_index */ 0, /* stop_index */ kNumBackendsFirstPass)); // Now restart the balancer, this time pointing to the new backends. balancers_[0]->Start(); - args = EdsResourceArgs({ + args = AdsServiceImpl::EdsResourceArgs({ {"locality0", CreateEndpointsForBackends(kNumBackendsFirstPass)}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11042,7 +12061,7 @@ TEST_P(ClientLoadReportingWithDropTest, Vanilla) { const size_t kNumRpcs = ComputeIdealNumRpcs(kDropRateForLbAndThrottle, kErrorTolerance); // The ADS response contains two drop categories. - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, @@ -11176,7 +12195,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionWithoutListenerFilter) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11204,7 +12223,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionPercentageAbort) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11241,7 +12260,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionPercentageAbortViaHeaders) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11283,7 +12302,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionPercentageDelay) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11333,7 +12352,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionPercentageDelayViaHeaders) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11381,7 +12400,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionAbortAfterDelayForStreamCall) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11425,7 +12444,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionAlwaysDelayPercentageAbort) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11489,7 +12508,7 @@ TEST_P(FaultInjectionTest, SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11545,7 +12564,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionMaxFault) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11584,7 +12603,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionBidiStreamDelayOk) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11619,7 +12638,7 @@ TEST_P(FaultInjectionTest, XdsFaultInjectionBidiStreamDelayError) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); // Create an EDS resource - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -11652,7 +12671,7 @@ class BootstrapSourceTest : public XdsEnd2endTest { TEST_P(BootstrapSourceTest, Vanilla) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({ + AdsServiceImpl::EdsResourceArgs args({ {"locality0", CreateEndpointsForBackends()}, }); balancers_[0]->ads_service()->SetEdsResource( @@ -12031,7 +13050,8 @@ TEST_P(ClientStatusDiscoveryServiceTest, XdsConfigDumpVanilla) { const size_t kNumRpcs = 5; SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 1)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Send several RPCs to ensure the xDS setup works @@ -12101,7 +13121,8 @@ TEST_P(ClientStatusDiscoveryServiceTest, XdsConfigDumpListenerError) { int kFetchIntervalMilliseconds = 200; SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 1)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Ensure the xDS resolver has working configs. @@ -12147,7 +13168,8 @@ TEST_P(ClientStatusDiscoveryServiceTest, XdsConfigDumpRouteError) { int kFetchIntervalMilliseconds = 200; SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 1)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Ensure the xDS resolver has working configs. @@ -12202,7 +13224,8 @@ TEST_P(ClientStatusDiscoveryServiceTest, XdsConfigDumpClusterError) { int kFetchIntervalMilliseconds = 200; SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 1)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Ensure the xDS resolver has working configs. @@ -12240,7 +13263,8 @@ TEST_P(ClientStatusDiscoveryServiceTest, XdsConfigDumpEndpointError) { int kFetchIntervalMilliseconds = 200; SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - EdsResourceArgs args({{"locality0", CreateEndpointsForBackends(0, 1)}}); + AdsServiceImpl::EdsResourceArgs args( + {{"locality0", CreateEndpointsForBackends(0, 1)}}); balancers_[0]->ads_service()->SetEdsResource( BuildEdsResource(args, DefaultEdsServiceName())); // Ensure the xDS resolver has working configs.