Merge pull request #22232 from markdroth/service_config_parsing_update

update service config parsing as per recent spec change
reviewable/pr22117/r3^2
Mark D. Roth 5 years ago committed by GitHub
commit 3590c04d14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/core/ext/filters/client_channel/client_channel.cc
  2. 15
      src/core/ext/filters/client_channel/resolver_result_parsing.cc
  3. 8
      src/core/ext/filters/client_channel/resolver_result_parsing.h
  4. 160
      src/core/ext/filters/client_channel/service_config.cc
  5. 26
      src/core/ext/filters/client_channel/service_config.h
  6. 14
      src/core/lib/slice/slice_internal.h
  7. 638
      test/core/client_channel/service_config_test.cc
  8. 2
      test/cpp/naming/resolver_component_tests_runner.py
  9. 4
      test/cpp/naming/resolver_test_record_groups.yaml

@ -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);

@ -317,7 +317,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const Json& json,
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
std::vector<grpc_error*> error_list;
RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config;
grpc_core::UniquePtr<char> lb_policy_name;
std::string lb_policy_name;
Optional<ClientChannelGlobalParsedConfig::RetryThrottling> 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);
}

@ -46,7 +46,7 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig {
ClientChannelGlobalParsedConfig(
RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config,
grpc_core::UniquePtr<char> parsed_deprecated_lb_policy,
std::string parsed_deprecated_lb_policy,
const Optional<RetryThrottling>& 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<LoadBalancingPolicy::Config> parsed_lb_config_;
grpc_core::UniquePtr<char> parsed_deprecated_lb_policy_;
std::string parsed_deprecated_lb_policy_;
Optional<RetryThrottling> retry_throttling_;
const char* health_check_service_name_;
};

@ -20,6 +20,8 @@
#include <string.h>
#include "absl/strings/str_cat.h"
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@ -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<grpc_error*> 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<SliceHashTable<const ParsedConfigVector*>::Entry, 10>*
entries) {
grpc_error* ServiceConfig::ParseJsonMethodConfig(const Json& json) {
// Parse method config with each registered parser.
auto objs_vector = absl::make_unique<ParsedConfigVector>();
InlinedVector<grpc_error*, 4> 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<UniquePtr<char>, 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<char> 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<SliceHashTable<const ParsedConfigVector*>::Entry, 10> entries;
std::vector<grpc_error*> 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<const ParsedConfigVector*>::Create(
entries.size(), entries.data(), nullptr);
}
return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list);
}
UniquePtr<char> 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<char>(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<char> 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> parser) {

@ -19,6 +19,8 @@
#include <grpc/support/port_platform.h>
#include <unordered_map>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/string_util.h>
@ -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<ServiceConfig> {
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<ServiceConfig> {
/// 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<ServiceConfig> {
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<char> 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<SliceHashTable<const ParsedConfigVector*>::Entry, 10>*
entries);
grpc_error* ParseJsonMethodConfig(const Json& json);
std::string json_string_;
Json json_;
@ -180,8 +180,10 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
// 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<SliceHashTable<const ParsedConfigVector*>>
parsed_method_configs_table_;
std::unordered_map<grpc_slice, const ParsedConfigVector*, SliceHash>
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<std::unique_ptr<ParsedConfigVector>, 32>

@ -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 */

@ -18,6 +18,8 @@
#include <regex>
#include "absl/strings/str_cat.h"
#include <gtest/gtest.h>
#include <grpc/grpc.h>
@ -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<TestParser1>()) == 0);
EXPECT_TRUE(
ServiceConfig::RegisterParser(absl::make_unique<TestParser2>()) == 1);
EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique<TestParser1>()),
0);
EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique<TestParser2>()),
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<TestParsedConfig1*>(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<TestParsedConfig1*>(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<TestParsedConfig1*>(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<TestParsedConfig1*>(svc_cfg->GetGlobalParsedConfig(0)))
->value() == 1000);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
EXPECT_EQ((static_cast<TestParsedConfig1*>(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<TestParsedConfig1*>(parsed_config)->value() == 5);
EXPECT_EQ(static_cast<TestParsedConfig1*>(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<ErrorParser>()) == 0);
EXPECT_TRUE(
ServiceConfig::RegisterParser(absl::make_unique<ErrorParser>()) == 1);
EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique<ErrorParser>()),
0);
EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique<ErrorParser>()),
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<internal::ClientChannelServiceConfigParser>()) ==
absl::make_unique<internal::ClientChannelServiceConfigParser>()),
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<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
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<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
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<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
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<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
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<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
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<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
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<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
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<grpc_core::internal::ClientChannelMethodParsedConfig*>(
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<grpc_core::internal::ClientChannelMethodParsedConfig*>(
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<grpc_core::internal::ClientChannelMethodParsedConfig*>(
((*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<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
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<MessageSizeParser>()) == 0);
EXPECT_EQ(
ServiceConfig::RegisterParser(absl::make_unique<MessageSizeParser>()),
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<MessageSizeParsedConfig*>(((*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

@ -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',

@ -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:

Loading…
Cancel
Save