From d4fb5ea436f4c3d98fc3be45018d243c4630dc11 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 25 Mar 2020 10:45:41 -0700 Subject: [PATCH] update service config parsing as per recent spec change --- .../filters/client_channel/client_channel.cc | 4 +- .../client_channel/resolver_result_parsing.cc | 15 +- .../client_channel/resolver_result_parsing.h | 8 +- .../filters/client_channel/service_config.cc | 160 ++--- .../filters/client_channel/service_config.h | 26 +- src/core/lib/slice/slice_internal.h | 14 + .../client_channel/service_config_test.cc | 638 +++++++++--------- .../naming/resolver_component_tests_runner.py | 2 +- .../naming/resolver_test_record_groups.yaml | 4 +- 9 files changed, 455 insertions(+), 416 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index a815e1933a6..a48a8a01d70 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1630,8 +1630,8 @@ void ChannelData::ProcessLbPolicy( // If not, try the setting from channel args. const char* policy_name = nullptr; if (parsed_service_config != nullptr && - parsed_service_config->parsed_deprecated_lb_policy() != nullptr) { - policy_name = parsed_service_config->parsed_deprecated_lb_policy(); + !parsed_service_config->parsed_deprecated_lb_policy().empty()) { + policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str(); } else { const grpc_arg* channel_arg = grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME); diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 080ecd354e6..d87890d1c97 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -317,7 +317,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const Json& json, GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); std::vector error_list; RefCountedPtr parsed_lb_config; - grpc_core::UniquePtr lb_policy_name; + std::string lb_policy_name; Optional retry_throttling; const char* health_check_service_name = nullptr; // Parse LB config. @@ -340,16 +340,13 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const Json& json, error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:type should be string")); } else { - lb_policy_name.reset(gpr_strdup(it->second.string_value().c_str())); - char* lb_policy = lb_policy_name.get(); - if (lb_policy != nullptr) { - for (size_t i = 0; i < strlen(lb_policy); ++i) { - lb_policy[i] = tolower(lb_policy[i]); - } + lb_policy_name = it->second.string_value(); + for (size_t i = 0; i < lb_policy_name.size(); ++i) { + lb_policy_name[i] = tolower(lb_policy_name[i]); } bool requires_config = false; if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( - lb_policy, &requires_config)) { + lb_policy_name.c_str(), &requires_config)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Unknown lb policy")); } else if (requires_config) { @@ -357,7 +354,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const Json& json, gpr_asprintf(&error_msg, "field:loadBalancingPolicy error:%s requires a config. " "Please use loadBalancingConfig instead.", - lb_policy); + lb_policy_name.c_str()); error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg)); gpr_free(error_msg); } diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 27d7f6f1396..1f928cfd551 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -46,7 +46,7 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { ClientChannelGlobalParsedConfig( RefCountedPtr parsed_lb_config, - grpc_core::UniquePtr parsed_deprecated_lb_policy, + std::string parsed_deprecated_lb_policy, const Optional& retry_throttling, const char* health_check_service_name) : parsed_lb_config_(std::move(parsed_lb_config)), @@ -62,8 +62,8 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { return parsed_lb_config_; } - const char* parsed_deprecated_lb_policy() const { - return parsed_deprecated_lb_policy_.get(); + const std::string& parsed_deprecated_lb_policy() const { + return parsed_deprecated_lb_policy_; } const char* health_check_service_name() const { @@ -72,7 +72,7 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { private: RefCountedPtr parsed_lb_config_; - grpc_core::UniquePtr parsed_deprecated_lb_policy_; + std::string parsed_deprecated_lb_policy_; Optional retry_throttling_; const char* health_check_service_name_; }; diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 884f68f2090..f08ebe1a37d 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -20,6 +20,8 @@ #include +#include "absl/strings/str_cat.h" + #include #include #include @@ -27,9 +29,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/json/json.h" -#include "src/core/lib/slice/slice_hash_table.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" namespace grpc_core { @@ -77,6 +77,12 @@ ServiceConfig::ServiceConfig(std::string json_string, Json json, } } +ServiceConfig::~ServiceConfig() { + for (auto& p : parsed_method_configs_map_) { + grpc_slice_unref_internal(p.first); + } +} + grpc_error* ServiceConfig::ParseGlobalParams() { std::vector error_list; for (size_t i = 0; i < g_registered_parsers->size(); i++) { @@ -91,10 +97,8 @@ grpc_error* ServiceConfig::ParseGlobalParams() { return GRPC_ERROR_CREATE_FROM_VECTOR("Global Params", &error_list); } -grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigVectorTable( - const Json& json, - InlinedVector::Entry, 10>* - entries) { +grpc_error* ServiceConfig::ParseJsonMethodConfig(const Json& json) { + // Parse method config with each registered parser. auto objs_vector = absl::make_unique(); InlinedVector error_list; for (size_t i = 0; i < g_registered_parsers->size(); i++) { @@ -108,8 +112,8 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigVectorTable( } parsed_method_config_vectors_storage_.push_back(std::move(objs_vector)); const auto* vector_ptr = parsed_method_config_vectors_storage_.back().get(); - // Construct list of paths. - InlinedVector, 10> paths; + // Add an entry for each path. + bool found_name = false; auto it = json.object_value().find("name"); if (it != json.object_value().end()) { if (it->second.type() != Json::Type::ARRAY) { @@ -120,29 +124,42 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigVectorTable( const Json::Array& name_array = it->second.array_value(); for (const Json& name : name_array) { grpc_error* parse_error = GRPC_ERROR_NONE; - UniquePtr path = ParseJsonMethodName(name, &parse_error); - if (path == nullptr) { + std::string path = ParseJsonMethodName(name, &parse_error); + if (parse_error != GRPC_ERROR_NONE) { error_list.push_back(parse_error); } else { - GPR_DEBUG_ASSERT(parse_error == GRPC_ERROR_NONE); - paths.push_back(std::move(path)); + found_name = true; + if (path.empty()) { + if (default_method_config_vector_ != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:multiple default method configs")); + } + default_method_config_vector_ = vector_ptr; + } else { + grpc_slice key = grpc_slice_from_copied_string(path.c_str()); + // If the key is not already present in the map, this will + // store a ref to the key in the map. + auto& value = parsed_method_configs_map_[key]; + if (value != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:multiple method configs with same name")); + // The map entry already existed, so we need to unref the + // key we just created. + grpc_slice_unref_internal(key); + } else { + value = vector_ptr; + } + } } } } - if (paths.size() == 0) { - error_list.push_back( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No names specified")); - } - // Add entry for each path. - for (size_t i = 0; i < paths.size(); ++i) { - entries->push_back( - {grpc_slice_from_copied_string(paths[i].get()), vector_ptr}); + if (!found_name) { + parsed_method_config_vectors_storage_.pop_back(); } return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list); } grpc_error* ServiceConfig::ParsePerMethodParams() { - InlinedVector::Entry, 10> entries; std::vector error_list; auto it = json_.object_value().find("methodConfig"); if (it != json_.object_value().end()) { @@ -156,91 +173,80 @@ grpc_error* ServiceConfig::ParsePerMethodParams() { "field:methodConfig error:not of type Object")); continue; } - grpc_error* error = ParseJsonMethodConfigToServiceConfigVectorTable( - method_config, &entries); + grpc_error* error = ParseJsonMethodConfig(method_config); if (error != GRPC_ERROR_NONE) { error_list.push_back(error); } } } - if (!entries.empty()) { - parsed_method_configs_table_ = - SliceHashTable::Create( - entries.size(), entries.data(), nullptr); - } return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list); } -UniquePtr ServiceConfig::ParseJsonMethodName(const Json& json, - grpc_error** error) { +std::string ServiceConfig::ParseJsonMethodName(const Json& json, + grpc_error** error) { if (json.type() != Json::Type::OBJECT) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:name error:type is not object"); - return nullptr; + return ""; } // Find service name. + const std::string* service_name = nullptr; auto it = json.object_value().find("service"); - if (it == json.object_value().end()) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:name error: field:service error:not found"); - return nullptr; // Required field. - } - if (it->second.type() != Json::Type::STRING) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:name error: field:service error:not of type string"); - return nullptr; - } - if (it->second.string_value().empty()) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:name error: field:service error:empty value"); - return nullptr; + if (it != json.object_value().end() && + it->second.type() != Json::Type::JSON_NULL) { + if (it->second.type() != Json::Type::STRING) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error: field:service error:not of type string"); + return ""; + } + if (!it->second.string_value().empty()) { + service_name = &it->second.string_value(); + } } - const char* service_name = it->second.string_value().c_str(); - const char* method_name = nullptr; + const std::string* method_name = nullptr; // Find method name. it = json.object_value().find("method"); - if (it != json.object_value().end()) { + if (it != json.object_value().end() && + it->second.type() != Json::Type::JSON_NULL) { if (it->second.type() != Json::Type::STRING) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:name error: field:method error:not of type string"); - return nullptr; + return ""; + } + if (!it->second.string_value().empty()) { + method_name = &it->second.string_value(); } - if (it->second.string_value().empty()) { + } + // If neither service nor method are specified, it's the default. + // Method name may not be specified without service name. + if (service_name == nullptr) { + if (method_name != nullptr) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:name error: field:method error:empty value"); - return nullptr; + "field:name error:method name populated without service name"); } - method_name = it->second.string_value().c_str(); + return ""; } - char* path; - gpr_asprintf(&path, "/%s/%s", service_name, - method_name == nullptr ? "" : method_name); - return grpc_core::UniquePtr(path); + // Construct path. + return absl::StrCat("/", *service_name, "/", + method_name == nullptr ? "" : *method_name); } const ServiceConfig::ParsedConfigVector* -ServiceConfig::GetMethodParsedConfigVector(const grpc_slice& path) { - if (parsed_method_configs_table_.get() == nullptr) { - return nullptr; - } - const auto* value = parsed_method_configs_table_->Get(path); +ServiceConfig::GetMethodParsedConfigVector(const grpc_slice& path) const { + // Try looking up the full path in the map. + auto it = parsed_method_configs_map_.find(path); + if (it != parsed_method_configs_map_.end()) return it->second; // If we didn't find a match for the path, try looking for a wildcard // entry (i.e., change "/service/method" to "/service/"). - if (value == nullptr) { - char* path_str = grpc_slice_to_c_string(path); - const char* sep = strrchr(path_str, '/') + 1; - const size_t len = (size_t)(sep - path_str); - char* buf = (char*)gpr_malloc(len + 1); // trailing NUL - memcpy(buf, path_str, len); - buf[len] = '\0'; - grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); - gpr_free(buf); - value = parsed_method_configs_table_->Get(wildcard_path); - grpc_slice_unref_internal(wildcard_path); - gpr_free(path_str); - if (value == nullptr) return nullptr; - } - return *value; + UniquePtr path_str(grpc_slice_to_c_string(path)); + char* sep = strrchr(path_str.get(), '/') + 1; + if (sep == nullptr) return nullptr; // Shouldn't ever happen. + *sep = '\0'; + grpc_slice wildcard_path = grpc_slice_from_static_string(path_str.get()); + it = parsed_method_configs_map_.find(wildcard_path); + if (it != parsed_method_configs_map_.end()) return it->second; + // Try default method config, if set. + return default_method_config_vector_; } size_t ServiceConfig::RegisterParser(std::unique_ptr parser) { diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 6e9ead52af9..3bba4ec1010 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -19,6 +19,8 @@ #include +#include + #include #include @@ -27,7 +29,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/json/json.h" -#include "src/core/lib/slice/slice_hash_table.h" +#include "src/core/lib/slice/slice_internal.h" // The main purpose of the code here is to parse the service config in // JSON form, which will look like this: @@ -129,6 +131,7 @@ class ServiceConfig : public RefCounted { grpc_error** error); ServiceConfig(std::string json_string, Json json, grpc_error** error); + ~ServiceConfig(); const std::string& json_string() const { return json_string_; } @@ -143,7 +146,8 @@ class ServiceConfig : public RefCounted { /// Retrieves the vector of parsed configs for the method identified /// by \a path. The lifetime of the returned vector and contained objects /// is tied to the lifetime of the ServiceConfig object. - const ParsedConfigVector* GetMethodParsedConfigVector(const grpc_slice& path); + const ParsedConfigVector* GetMethodParsedConfigVector( + const grpc_slice& path) const; /// Globally register a service config parser. On successful registration, it /// returns the index at which the parser was registered. On failure, -1 is @@ -162,15 +166,11 @@ class ServiceConfig : public RefCounted { grpc_error* ParseGlobalParams(); grpc_error* ParsePerMethodParams(); - // Returns a path string for the JSON name object specified by \a json. - // Returns null on error, and stores error in \a error. - static UniquePtr ParseJsonMethodName(const Json& json, - grpc_error** error); + // Returns a path string for the JSON name object specified by json. + // Sets *error on error. + static std::string ParseJsonMethodName(const Json& json, grpc_error** error); - grpc_error* ParseJsonMethodConfigToServiceConfigVectorTable( - const Json& json, - InlinedVector::Entry, 10>* - entries); + grpc_error* ParseJsonMethodConfig(const Json& json); std::string json_string_; Json json_; @@ -180,8 +180,10 @@ class ServiceConfig : public RefCounted { // A map from the method name to the parsed config vector. Note that we are // using a raw pointer and not a unique pointer so that we can use the same // vector for multiple names. - RefCountedPtr> - parsed_method_configs_table_; + std::unordered_map + parsed_method_configs_map_; + // Default method config. + const ParsedConfigVector* default_method_config_vector_ = nullptr; // Storage for all the vectors that are being used in // parsed_method_configs_table_. InlinedVector, 32> diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index e74aba94145..5148aad5055 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -347,4 +347,18 @@ size_t grpc_slice_memory_usage(grpc_slice s); grpc_core::UnmanagedMemorySlice grpc_slice_sub_no_ref( const grpc_core::UnmanagedMemorySlice& source, size_t begin, size_t end); +namespace grpc_core { + +struct SliceHash { + std::size_t operator()(const grpc_slice& slice) const { + return grpc_slice_hash_internal(slice); + } +}; + +} // namespace grpc_core + +inline bool operator==(const grpc_slice& s1, const grpc_slice& s2) { + return grpc_slice_eq(s1, s2); +} + #endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */ diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index ad874736ffb..d659fbeb51d 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -18,6 +18,8 @@ #include +#include "absl/strings/str_cat.h" + #include #include @@ -127,10 +129,10 @@ class ErrorParser : public ServiceConfig::Parser { static const char* GlobalError() { return "ErrorParser : globalError"; } }; -void VerifyRegexMatch(grpc_error* error, const std::regex& e) { +void VerifyRegexMatch(grpc_error* error, const std::regex& regex) { std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); + std::string error_str = grpc_error_string(error); + EXPECT_TRUE(std::regex_search(error_str, match, regex)) << error_str; GRPC_ERROR_UNREF(error); } @@ -139,10 +141,10 @@ class ServiceConfigTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE( - ServiceConfig::RegisterParser(absl::make_unique()) == 0); - EXPECT_TRUE( - ServiceConfig::RegisterParser(absl::make_unique()) == 1); + EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique()), + 0); + EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique()), + 1); } }; @@ -150,46 +152,128 @@ TEST_F(ServiceConfigTest, ErrorCheck1) { const char* test_json = ""; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string("JSON parse error")); - VerifyRegexMatch(error, e); + std::regex regex(std::string("JSON parse error")); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, BasicTest1) { const char* test_json = "{}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); +} + +TEST_F(ServiceConfigTest, SkipMethodConfigWithNoNameOrEmptyName) { + const char* test_json = + "{\"methodConfig\": [" + " {\"method_param\":1}," + " {\"name\":[], \"method_param\":1}," + " {\"name\":[{\"service\":\"TestServ\"}], \"method_param\":2}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); + const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + ASSERT_NE(vector_ptr, nullptr); + auto parsed_config = ((*vector_ptr)[1]).get(); + EXPECT_EQ(static_cast(parsed_config)->value(), 2); +} + +TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNames) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{\"service\":\"TestServ\"}]}," + " {\"name\":[{\"service\":\"TestServ\"}]}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple method configs with same name")); + VerifyRegexMatch(error, regex); } -TEST_F(ServiceConfigTest, ErrorNoNames) { - const char* test_json = "{\"methodConfig\": [{\"blah\":1}]}"; +TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNamesWithNullMethod) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{\"service\":\"TestServ\",\"method\":null}]}," + " {\"name\":[{\"service\":\"TestServ\"}]}" + "]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing error)(.*)(referenced_errors)" - "(.*)(Method Params)(.*)(referenced_errors)" - "(.*)(methodConfig)(.*)(referenced_errors)" - "(.*)(No names specified)")); - VerifyRegexMatch(error, e); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple method configs with same name")); + VerifyRegexMatch(error, regex); } -TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { +TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNamesWithEmptyMethod) { const char* test_json = - "{\"methodConfig\": [{}, {\"name\":[{\"service\":\"TestServ\"}]}]}"; + "{\"methodConfig\": [" + " {\"name\":[{\"service\":\"TestServ\",\"method\":\"\"}]}," + " {\"name\":[{\"service\":\"TestServ\"}]}" + "]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing error)(.*)(referenced_errors)" - "(.*)(Method Params)(.*)(referenced_errors)" - "(.*)(methodConfig)(.*)(referenced_errors)" - "(.*)(No names specified)")); - VerifyRegexMatch(error, e); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple method configs with same name")); + VerifyRegexMatch(error, regex); +} + +TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigs) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{}]}," + " {\"name\":[{}]}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple default method configs")); + VerifyRegexMatch(error, regex); +} + +TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigsWithNullService) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{\"service\":null}]}," + " {\"name\":[{}]}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple default method configs")); + VerifyRegexMatch(error, regex); +} + +TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigsWithEmptyService) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{\"service\":\"\"}]}," + " {\"name\":[{}]}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple default method configs")); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, ValidMethodConfig) { @@ -197,56 +281,52 @@ TEST_F(ServiceConfigTest, ValidMethodConfig) { "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}]}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); } TEST_F(ServiceConfigTest, Parser1BasicTest1) { const char* test_json = "{\"global_param\":5}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); - EXPECT_TRUE( - (static_cast(svc_cfg->GetGlobalParsedConfig(0))) - ->value() == 5); - EXPECT_TRUE(svc_cfg->GetMethodParsedConfigVector( - grpc_slice_from_static_string("/TestServ/TestMethod")) == - nullptr); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); + EXPECT_EQ((static_cast(svc_cfg->GetGlobalParsedConfig(0))) + ->value(), + 5); + EXPECT_EQ(svc_cfg->GetMethodParsedConfigVector( + grpc_slice_from_static_string("/TestServ/TestMethod")), + nullptr); } TEST_F(ServiceConfigTest, Parser1BasicTest2) { const char* test_json = "{\"global_param\":1000}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); - EXPECT_TRUE( - (static_cast(svc_cfg->GetGlobalParsedConfig(0))) - ->value() == 1000); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); + EXPECT_EQ((static_cast(svc_cfg->GetGlobalParsedConfig(0))) + ->value(), + 1000); } TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) { const char* test_json = "{\"global_param\":\"5\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)") + - TestParser1::InvalidTypeErrorMessage()); - VerifyRegexMatch(error, e); + std::regex regex( + absl::StrCat("Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*", + TestParser1::InvalidTypeErrorMessage())); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { const char* test_json = "{\"global_param\":-5}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)") + - TestParser1::InvalidValueErrorMessage()); - VerifyRegexMatch(error, e); + std::regex regex( + absl::StrCat("Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*", + TestParser1::InvalidValueErrorMessage())); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, Parser2BasicTest) { @@ -255,12 +335,12 @@ TEST_F(ServiceConfigTest, Parser2BasicTest) { "\"method_param\":5}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); auto parsed_config = ((*vector_ptr)[1]).get(); - EXPECT_TRUE(static_cast(parsed_config)->value() == 5); + EXPECT_EQ(static_cast(parsed_config)->value(), 5); } TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { @@ -269,14 +349,12 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { "\"method_param\":\"5\"}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors\":\\[)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(" - ".*)(referenced_errors)(.*)") + - TestParser2::InvalidTypeErrorMessage()); - VerifyRegexMatch(error, e); + std::regex regex( + absl::StrCat("Service config parsing error.*referenced_errors\":\\[.*" + "Method Params.*referenced_errors.*methodConfig.*" + "referenced_errors.*", + TestParser2::InvalidTypeErrorMessage())); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { @@ -285,14 +363,12 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { "\"method_param\":-5}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors\":\\[)(.*)(Method " - "Params)(.*)(referenced_errors)()(.*)(methodConfig)(" - ".*)(referenced_errors)(.*)") + - TestParser2::InvalidValueErrorMessage()); - VerifyRegexMatch(error, e); + std::regex regex( + absl::StrCat("Service config parsing error.*referenced_errors\":\\[.*" + "Method Params.*referenced_errors.*methodConfig.*" + "referenced_errors.*", + TestParser2::InvalidValueErrorMessage())); + VerifyRegexMatch(error, regex); } // Test parsing with ErrorParsers which always add errors @@ -301,10 +377,10 @@ class ErroredParsersScopingTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE( - ServiceConfig::RegisterParser(absl::make_unique()) == 0); - EXPECT_TRUE( - ServiceConfig::RegisterParser(absl::make_unique()) == 1); + EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique()), + 0); + EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique()), + 1); } }; @@ -312,33 +388,24 @@ TEST_F(ErroredParsersScopingTest, GlobalParams) { const char* test_json = "{}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors\":\\[)(.*)(Global " - "Params)(.*)(referenced_errors)()(.*)") + - ErrorParser::GlobalError() + std::string("(.*)") + - ErrorParser::GlobalError()); - VerifyRegexMatch(error, e); + std::regex regex(absl::StrCat( + "Service config parsing error.*referenced_errors\":\\[.*" + "Global Params.*referenced_errors.*", + ErrorParser::GlobalError(), ".*", ErrorParser::GlobalError())); + VerifyRegexMatch(error, regex); } TEST_F(ErroredParsersScopingTest, MethodParams) { const char* test_json = "{\"methodConfig\": [{}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors\":\\[)(.*)(Global " - "Params)(.*)(referenced_errors)()(.*)") + - ErrorParser::GlobalError() + std::string("(.*)") + - ErrorParser::GlobalError() + - std::string("(.*)(Method Params)(.*)(referenced_errors)" - "(.*)(methodConfig)(.*)(referenced_errors)(.*)") + - ErrorParser::MethodError() + std::string("(.*)") + - ErrorParser::MethodError() + - std::string("(.*)(No names specified)")); - VerifyRegexMatch(error, e); + std::regex regex(absl::StrCat( + "Service config parsing error.*referenced_errors\":\\[.*" + "Global Params.*referenced_errors.*", + ErrorParser::GlobalError(), ".*", ErrorParser::GlobalError(), + ".*Method Params.*referenced_errors.*methodConfig.*referenced_errors.*", + ErrorParser::MethodError(), ".*", ErrorParser::MethodError())); + VerifyRegexMatch(error, regex); } class ClientChannelParserTest : public ::testing::Test { @@ -346,9 +413,9 @@ class ClientChannelParserTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE( + EXPECT_EQ( ServiceConfig::RegisterParser( - absl::make_unique()) == + absl::make_unique()), 0); } }; @@ -357,12 +424,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigPickFirst) { const char* test_json = "{\"loadBalancingConfig\": [{\"pick_first\":{}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); auto lb_config = parsed_config->parsed_lb_config(); - EXPECT_TRUE(strcmp(lb_config->name(), "pick_first") == 0); + EXPECT_STREQ(lb_config->name(), "pick_first"); } TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) { @@ -370,12 +437,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) { "{\"loadBalancingConfig\": [{\"round_robin\":{}}, {}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); auto parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); auto lb_config = parsed_config->parsed_lb_config(); - EXPECT_TRUE(strcmp(lb_config->name(), "round_robin") == 0); + EXPECT_STREQ(lb_config->name(), "round_robin"); } TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) { @@ -384,12 +451,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) { "[{\"grpclb\":{\"childPolicy\":[{\"pick_first\":{}}]}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); auto lb_config = parsed_config->parsed_lb_config(); - EXPECT_TRUE(strcmp(lb_config->name(), "grpclb") == 0); + EXPECT_STREQ(lb_config->name(), "grpclb"); } TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) { @@ -402,105 +469,91 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); auto lb_config = parsed_config->parsed_lb_config(); - EXPECT_TRUE(strcmp(lb_config->name(), "xds_experimental") == 0); + EXPECT_STREQ(lb_config->name(), "xds_experimental"); } TEST_F(ClientChannelParserTest, UnknownLoadBalancingConfig) { const char* test_json = "{\"loadBalancingConfig\": [{\"unknown\":{}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing error)(.*)(referenced_errors)" - "(.*)(Global Params)(.*)(referenced_errors)" - "(.*)(Client channel global parser)(.*)(referenced_errors)" - "(.*)(field:loadBalancingConfig)(.*)(referenced_errors)" - "(.*)(No known policy)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:loadBalancingConfig.*referenced_errors.*" + "No known policy"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidGrpclbLoadBalancingConfig) { const char* test_json = - "{\"loadBalancingConfig\": " - "[{\"grpclb\":{\"childPolicy\":[{\"unknown\":{}}]}}]}"; + "{\"loadBalancingConfig\": [" + " {\"grpclb\":{\"childPolicy\":1}}," + " {\"round_robin\":{}}" + "]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing error)(.*)(referenced_errors)" - "(.*)(Global Params)(.*)(referenced_errors)" - "(.*)(Client channel global parser)(.*)(referenced_errors)" - "(.*)(field:loadBalancingConfig)(.*)(referenced_errors)" - "(.*)(GrpcLb Parser)(.*)(referenced_errors)" - "(.*)(field:childPolicy)(.*)(referenced_errors)" - "(.*)(No known policy)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:loadBalancingConfig.*referenced_errors.*" + "GrpcLb Parser.*referenced_errors.*" + "field:childPolicy.*referenced_errors.*" + "type should be array"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) { const char* test_json = "{\"loadBalancingPolicy\":\"pick_first\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); - const auto* lb_policy = parsed_config->parsed_deprecated_lb_policy(); - ASSERT_TRUE(lb_policy != nullptr); - EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); + EXPECT_EQ(parsed_config->parsed_deprecated_lb_policy(), "pick_first"); } TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicyAllCaps) { const char* test_json = "{\"loadBalancingPolicy\":\"PICK_FIRST\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); - const auto* lb_policy = parsed_config->parsed_deprecated_lb_policy(); - ASSERT_TRUE(lb_policy != nullptr); - EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); + EXPECT_EQ(parsed_config->parsed_deprecated_lb_policy(), "pick_first"); } TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) { const char* test_json = "{\"loadBalancingPolicy\":\"unknown\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:" - "loadBalancingPolicy error:Unknown lb policy)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:loadBalancingPolicy error:Unknown lb policy"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { const char* test_json = "{\"loadBalancingPolicy\":\"xds_experimental\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:" - "loadBalancingPolicy error:xds_experimental requires a " - "config. Please use loadBalancingConfig instead.)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:loadBalancingPolicy error:xds_experimental requires " + "a config. Please use loadBalancingConfig instead."); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidRetryThrottling) { @@ -513,8 +566,7 @@ TEST_F(ClientChannelParserTest, ValidRetryThrottling) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); @@ -532,16 +584,13 @@ TEST_F(ClientChannelParserTest, RetryThrottlingMissingFields) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " - "field:maxTokens error:Not found)(.*)(field:retryThrottling " - "field:tokenRatio error:Not found)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:retryThrottling field:maxTokens error:Not found.*" + "field:retryThrottling field:tokenRatio error:Not found"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { @@ -554,15 +603,13 @@ TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " - "field:maxTokens error:should be greater than zero)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:retryThrottling field:maxTokens error:should " + "be greater than zero"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { @@ -575,15 +622,13 @@ TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " - "field:tokenRatio error:Failed parsing)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:retryThrottling field:tokenRatio " + "error:Failed parsing"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidTimeout) { @@ -598,10 +643,10 @@ TEST_F(ClientChannelParserTest, ValidTimeout) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); auto parsed_config = ((*vector_ptr)[0]).get(); EXPECT_EQ((static_cast( parsed_config)) @@ -621,16 +666,13 @@ TEST_F(ClientChannelParserTest, InvalidTimeout) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" - "referenced_errors)(.*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(field:timeout " - "error:Failed parsing)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "field:timeout error:Failed parsing"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidWaitForReady) { @@ -645,12 +687,12 @@ TEST_F(ClientChannelParserTest, ValidWaitForReady) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); auto parsed_config = ((*vector_ptr)[0]).get(); - EXPECT_TRUE( + ASSERT_TRUE( (static_cast( parsed_config)) ->wait_for_ready() @@ -674,16 +716,13 @@ TEST_F(ClientChannelParserTest, InvalidWaitForReady) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" - "referenced_errors)(.*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(field:waitForReady " - "error:Type should be true/false)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "field:waitForReady error:Type should be true/false"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidRetryPolicy) { @@ -704,15 +743,14 @@ TEST_F(ClientChannelParserTest, ValidRetryPolicy) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); const auto* parsed_config = static_cast( ((*vector_ptr)[0]).get()); - EXPECT_TRUE(parsed_config->retry_policy() != nullptr); + ASSERT_NE(parsed_config->retry_policy(), nullptr); EXPECT_EQ(parsed_config->retry_policy()->max_attempts, 3); EXPECT_EQ(parsed_config->retry_policy()->initial_backoff, 1000); EXPECT_EQ(parsed_config->retry_policy()->max_backoff, 120000); @@ -739,16 +777,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxAttempts) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:maxAttempts error:should be at least 2)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:maxAttempts error:should be at least 2"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { @@ -769,16 +805,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:initialBackoff error:Failed to parse)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:initialBackoff error:Failed to parse"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { @@ -799,16 +833,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:maxBackoff error:failed to parse)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:maxBackoff error:failed to parse"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { @@ -829,16 +861,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:backoffMultiplier error:should be of type number)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:backoffMultiplier error:should be of type number"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { @@ -859,16 +889,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:retryableStatusCodes error:should be non-empty)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:retryableStatusCodes error:should be non-empty"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidHealthCheck) { @@ -880,14 +908,13 @@ TEST_F(ClientChannelParserTest, ValidHealthCheck) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); - ASSERT_TRUE(parsed_config != nullptr); - EXPECT_EQ(strcmp(parsed_config->health_check_service_name(), - "health_check_service_name"), - 0); + ASSERT_NE(parsed_config, nullptr); + EXPECT_STREQ(parsed_config->health_check_service_name(), + "health_check_service_name"); } TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) { @@ -902,12 +929,10 @@ TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(JSON parsing failed)(.*)(referenced_errors)" - "(.*)(duplicate key \"healthCheckConfig\" at index 104)")); - VerifyRegexMatch(error, e); + std::regex regex( + "JSON parsing failed.*referenced_errors.*" + "duplicate key \"healthCheckConfig\" at index 104"); + VerifyRegexMatch(error, regex); } class MessageSizeParserTest : public ::testing::Test { @@ -915,8 +940,9 @@ class MessageSizeParserTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser( - absl::make_unique()) == 0); + EXPECT_EQ( + ServiceConfig::RegisterParser(absl::make_unique()), + 0); } }; @@ -933,14 +959,13 @@ TEST_F(MessageSizeParserTest, Valid) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); auto parsed_config = static_cast(((*vector_ptr)[0]).get()); - ASSERT_TRUE(parsed_config != nullptr); + ASSERT_NE(parsed_config, nullptr); EXPECT_EQ(parsed_config->limits().max_send_size, 1024); EXPECT_EQ(parsed_config->limits().max_recv_size, 1024); } @@ -957,16 +982,13 @@ TEST_F(MessageSizeParserTest, InvalidMaxRequestMessageBytes) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" - "referenced_errors)(.*)(Message size " - "parser)(.*)(referenced_errors)(.*)(field:" - "maxRequestMessageBytes error:should be non-negative)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Message size parser.*referenced_errors.*" + "field:maxRequestMessageBytes error:should be non-negative"); + VerifyRegexMatch(error, regex); } TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { @@ -981,16 +1003,14 @@ TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" - "referenced_errors)(.*)(Message size " - "parser)(.*)(referenced_errors)(.*)(field:" - "maxResponseMessageBytes error:should be of type number)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Message size parser.*referenced_errors.*" + "field:maxResponseMessageBytes error:should be of type " + "number"); + VerifyRegexMatch(error, regex); } } // namespace testing diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 53d9364a35b..274c9a1b345 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -331,7 +331,7 @@ current_test_subprocess = subprocess.Popen([ args.test_bin_path, '--target_name', 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', - '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true}]}', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThirteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFourteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFifteen","service":"SimpleService"}],"waitForReady":true}]}', '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', diff --git a/test/cpp/naming/resolver_test_record_groups.yaml b/test/cpp/naming/resolver_test_record_groups.yaml index a1d932ae2b7..c44c39faecc 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -205,7 +205,7 @@ resolver_component_tests: - {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} - expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true}]}' + expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThirteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFourteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFifteen","service":"SimpleService"}],"waitForReady":true}]}' expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true @@ -216,7 +216,7 @@ resolver_component_tests: ipv4-config-causing-fallback-to-tcp: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-config-causing-fallback-to-tcp: - - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThirteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFourteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFifteen","service":"SimpleService"}],"waitForReady":true}]}}]', type: TXT} # Tests for which we don't enable SRV queries - expected_addrs: