service_config_test.cc 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129
  1. /*
  2. *
  3. * Copyright 2019 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include "absl/strings/str_cat.h"
  19. #include <gmock/gmock.h>
  20. #include <gtest/gtest.h>
  21. #include <grpc/grpc.h>
  22. #include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
  23. #include "src/core/ext/filters/client_channel/retry_service_config.h"
  24. #include "src/core/ext/filters/client_channel/service_config.h"
  25. #include "src/core/ext/filters/client_channel/service_config_parser.h"
  26. #include "src/core/ext/filters/message_size/message_size_filter.h"
  27. #include "src/core/lib/gpr/string.h"
  28. #include "test/core/util/port.h"
  29. #include "test/core/util/test_config.h"
  30. namespace grpc_core {
  31. namespace testing {
  32. //
  33. // ServiceConfig tests
  34. //
  35. // Set this channel arg to true to disable parsing.
  36. #define GRPC_ARG_DISABLE_PARSING "disable_parsing"
  37. class TestParsedConfig1 : public ServiceConfigParser::ParsedConfig {
  38. public:
  39. explicit TestParsedConfig1(int value) : value_(value) {}
  40. int value() const { return value_; }
  41. private:
  42. int value_;
  43. };
  44. class TestParser1 : public ServiceConfigParser::Parser {
  45. public:
  46. std::unique_ptr<ServiceConfigParser::ParsedConfig> ParseGlobalParams(
  47. const grpc_channel_args* args, const Json& json,
  48. grpc_error** error) override {
  49. GPR_DEBUG_ASSERT(error != nullptr);
  50. if (grpc_channel_args_find_bool(args, GRPC_ARG_DISABLE_PARSING, false)) {
  51. return nullptr;
  52. }
  53. auto it = json.object_value().find("global_param");
  54. if (it != json.object_value().end()) {
  55. if (it->second.type() != Json::Type::NUMBER) {
  56. *error =
  57. GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidTypeErrorMessage());
  58. return nullptr;
  59. }
  60. int value = gpr_parse_nonnegative_int(it->second.string_value().c_str());
  61. if (value == -1) {
  62. *error =
  63. GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage());
  64. return nullptr;
  65. }
  66. return absl::make_unique<TestParsedConfig1>(value);
  67. }
  68. return nullptr;
  69. }
  70. static const char* InvalidTypeErrorMessage() {
  71. return "global_param value type should be a number";
  72. }
  73. static const char* InvalidValueErrorMessage() {
  74. return "global_param value type should be non-negative";
  75. }
  76. };
  77. class TestParser2 : public ServiceConfigParser::Parser {
  78. public:
  79. std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
  80. const grpc_channel_args* args, const Json& json,
  81. grpc_error** error) override {
  82. GPR_DEBUG_ASSERT(error != nullptr);
  83. if (grpc_channel_args_find_bool(args, GRPC_ARG_DISABLE_PARSING, false)) {
  84. return nullptr;
  85. }
  86. auto it = json.object_value().find("method_param");
  87. if (it != json.object_value().end()) {
  88. if (it->second.type() != Json::Type::NUMBER) {
  89. *error =
  90. GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidTypeErrorMessage());
  91. return nullptr;
  92. }
  93. int value = gpr_parse_nonnegative_int(it->second.string_value().c_str());
  94. if (value == -1) {
  95. *error =
  96. GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage());
  97. return nullptr;
  98. }
  99. return absl::make_unique<TestParsedConfig1>(value);
  100. }
  101. return nullptr;
  102. }
  103. static const char* InvalidTypeErrorMessage() {
  104. return "method_param value type should be a number";
  105. }
  106. static const char* InvalidValueErrorMessage() {
  107. return "method_param value type should be non-negative";
  108. }
  109. };
  110. // This parser always adds errors
  111. class ErrorParser : public ServiceConfigParser::Parser {
  112. public:
  113. std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
  114. const grpc_channel_args* /*arg*/, const Json& /*json*/,
  115. grpc_error** error) override {
  116. GPR_DEBUG_ASSERT(error != nullptr);
  117. *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(MethodError());
  118. return nullptr;
  119. }
  120. std::unique_ptr<ServiceConfigParser::ParsedConfig> ParseGlobalParams(
  121. const grpc_channel_args* /*arg*/, const Json& /*json*/,
  122. grpc_error** error) override {
  123. GPR_DEBUG_ASSERT(error != nullptr);
  124. *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(GlobalError());
  125. return nullptr;
  126. }
  127. static const char* MethodError() { return "ErrorParser : methodError"; }
  128. static const char* GlobalError() { return "ErrorParser : globalError"; }
  129. };
  130. class ServiceConfigTest : public ::testing::Test {
  131. protected:
  132. void SetUp() override {
  133. ServiceConfigParser::Shutdown();
  134. ServiceConfigParser::Init();
  135. EXPECT_EQ(
  136. ServiceConfigParser::RegisterParser(absl::make_unique<TestParser1>()),
  137. 0);
  138. EXPECT_EQ(
  139. ServiceConfigParser::RegisterParser(absl::make_unique<TestParser2>()),
  140. 1);
  141. }
  142. };
  143. TEST_F(ServiceConfigTest, ErrorCheck1) {
  144. const char* test_json = "";
  145. grpc_error* error = GRPC_ERROR_NONE;
  146. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  147. EXPECT_THAT(grpc_error_string(error),
  148. ::testing::ContainsRegex("JSON parse error"));
  149. GRPC_ERROR_UNREF(error);
  150. }
  151. TEST_F(ServiceConfigTest, BasicTest1) {
  152. const char* test_json = "{}";
  153. grpc_error* error = GRPC_ERROR_NONE;
  154. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  155. EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  156. }
  157. TEST_F(ServiceConfigTest, SkipMethodConfigWithNoNameOrEmptyName) {
  158. const char* test_json =
  159. "{\"methodConfig\": ["
  160. " {\"method_param\":1},"
  161. " {\"name\":[], \"method_param\":1},"
  162. " {\"name\":[{\"service\":\"TestServ\"}], \"method_param\":2}"
  163. "]}";
  164. grpc_error* error = GRPC_ERROR_NONE;
  165. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  166. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  167. const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector(
  168. grpc_slice_from_static_string("/TestServ/TestMethod"));
  169. ASSERT_NE(vector_ptr, nullptr);
  170. auto parsed_config = ((*vector_ptr)[1]).get();
  171. EXPECT_EQ(static_cast<TestParsedConfig1*>(parsed_config)->value(), 2);
  172. }
  173. TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNames) {
  174. const char* test_json =
  175. "{\"methodConfig\": ["
  176. " {\"name\":[{\"service\":\"TestServ\"}]},"
  177. " {\"name\":[{\"service\":\"TestServ\"}]}"
  178. "]}";
  179. grpc_error* error = GRPC_ERROR_NONE;
  180. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  181. EXPECT_THAT(
  182. grpc_error_string(error),
  183. ::testing::ContainsRegex("Service config parsing error.*referenced_errors"
  184. ".*Method Params.*referenced_errors"
  185. ".*methodConfig.*referenced_errors"
  186. ".*multiple method configs with same name"));
  187. GRPC_ERROR_UNREF(error);
  188. }
  189. TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNamesWithNullMethod) {
  190. const char* test_json =
  191. "{\"methodConfig\": ["
  192. " {\"name\":[{\"service\":\"TestServ\",\"method\":null}]},"
  193. " {\"name\":[{\"service\":\"TestServ\"}]}"
  194. "]}";
  195. grpc_error* error = GRPC_ERROR_NONE;
  196. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  197. EXPECT_THAT(
  198. grpc_error_string(error),
  199. ::testing::ContainsRegex("Service config parsing error.*referenced_errors"
  200. ".*Method Params.*referenced_errors"
  201. ".*methodConfig.*referenced_errors"
  202. ".*multiple method configs with same name"));
  203. GRPC_ERROR_UNREF(error);
  204. }
  205. TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNamesWithEmptyMethod) {
  206. const char* test_json =
  207. "{\"methodConfig\": ["
  208. " {\"name\":[{\"service\":\"TestServ\",\"method\":\"\"}]},"
  209. " {\"name\":[{\"service\":\"TestServ\"}]}"
  210. "]}";
  211. grpc_error* error = GRPC_ERROR_NONE;
  212. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  213. EXPECT_THAT(
  214. grpc_error_string(error),
  215. ::testing::ContainsRegex("Service config parsing error.*referenced_errors"
  216. ".*Method Params.*referenced_errors"
  217. ".*methodConfig.*referenced_errors"
  218. ".*multiple method configs with same name"));
  219. GRPC_ERROR_UNREF(error);
  220. }
  221. TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigs) {
  222. const char* test_json =
  223. "{\"methodConfig\": ["
  224. " {\"name\":[{}]},"
  225. " {\"name\":[{}]}"
  226. "]}";
  227. grpc_error* error = GRPC_ERROR_NONE;
  228. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  229. EXPECT_THAT(
  230. grpc_error_string(error),
  231. ::testing::ContainsRegex("Service config parsing error.*referenced_errors"
  232. ".*Method Params.*referenced_errors"
  233. ".*methodConfig.*referenced_errors"
  234. ".*multiple default method configs"));
  235. GRPC_ERROR_UNREF(error);
  236. }
  237. TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigsWithNullService) {
  238. const char* test_json =
  239. "{\"methodConfig\": ["
  240. " {\"name\":[{\"service\":null}]},"
  241. " {\"name\":[{}]}"
  242. "]}";
  243. grpc_error* error = GRPC_ERROR_NONE;
  244. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  245. EXPECT_THAT(
  246. grpc_error_string(error),
  247. ::testing::ContainsRegex("Service config parsing error.*referenced_errors"
  248. ".*Method Params.*referenced_errors"
  249. ".*methodConfig.*referenced_errors"
  250. ".*multiple default method configs"));
  251. GRPC_ERROR_UNREF(error);
  252. }
  253. TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigsWithEmptyService) {
  254. const char* test_json =
  255. "{\"methodConfig\": ["
  256. " {\"name\":[{\"service\":\"\"}]},"
  257. " {\"name\":[{}]}"
  258. "]}";
  259. grpc_error* error = GRPC_ERROR_NONE;
  260. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  261. EXPECT_THAT(
  262. grpc_error_string(error),
  263. ::testing::ContainsRegex("Service config parsing error.*referenced_errors"
  264. ".*Method Params.*referenced_errors"
  265. ".*methodConfig.*referenced_errors"
  266. ".*multiple default method configs"));
  267. GRPC_ERROR_UNREF(error);
  268. }
  269. TEST_F(ServiceConfigTest, ValidMethodConfig) {
  270. const char* test_json =
  271. "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}]}]}";
  272. grpc_error* error = GRPC_ERROR_NONE;
  273. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  274. EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  275. }
  276. TEST_F(ServiceConfigTest, Parser1BasicTest1) {
  277. const char* test_json = "{\"global_param\":5}";
  278. grpc_error* error = GRPC_ERROR_NONE;
  279. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  280. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  281. EXPECT_EQ((static_cast<TestParsedConfig1*>(svc_cfg->GetGlobalParsedConfig(0)))
  282. ->value(),
  283. 5);
  284. EXPECT_EQ(svc_cfg->GetMethodParsedConfigVector(
  285. grpc_slice_from_static_string("/TestServ/TestMethod")),
  286. nullptr);
  287. }
  288. TEST_F(ServiceConfigTest, Parser1BasicTest2) {
  289. const char* test_json = "{\"global_param\":1000}";
  290. grpc_error* error = GRPC_ERROR_NONE;
  291. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  292. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  293. EXPECT_EQ((static_cast<TestParsedConfig1*>(svc_cfg->GetGlobalParsedConfig(0)))
  294. ->value(),
  295. 1000);
  296. }
  297. TEST_F(ServiceConfigTest, Parser1DisabledViaChannelArg) {
  298. grpc_arg arg = grpc_channel_arg_integer_create(
  299. const_cast<char*>(GRPC_ARG_DISABLE_PARSING), 1);
  300. grpc_channel_args args = {1, &arg};
  301. const char* test_json = "{\"global_param\":5}";
  302. grpc_error* error = GRPC_ERROR_NONE;
  303. auto svc_cfg = ServiceConfig::Create(&args, test_json, &error);
  304. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  305. EXPECT_EQ(svc_cfg->GetGlobalParsedConfig(0), nullptr);
  306. }
  307. TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) {
  308. const char* test_json = "{\"global_param\":\"5\"}";
  309. grpc_error* error = GRPC_ERROR_NONE;
  310. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  311. EXPECT_THAT(grpc_error_string(error),
  312. ::testing::ContainsRegex(absl::StrCat(
  313. "Service config parsing error.*referenced_errors.*"
  314. "Global Params.*referenced_errors.*",
  315. TestParser1::InvalidTypeErrorMessage())));
  316. GRPC_ERROR_UNREF(error);
  317. }
  318. TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) {
  319. const char* test_json = "{\"global_param\":-5}";
  320. grpc_error* error = GRPC_ERROR_NONE;
  321. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  322. EXPECT_THAT(grpc_error_string(error),
  323. ::testing::ContainsRegex(absl::StrCat(
  324. "Service config parsing error.*referenced_errors.*"
  325. "Global Params.*referenced_errors.*",
  326. TestParser1::InvalidValueErrorMessage())));
  327. GRPC_ERROR_UNREF(error);
  328. }
  329. TEST_F(ServiceConfigTest, Parser2BasicTest) {
  330. const char* test_json =
  331. "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], "
  332. "\"method_param\":5}]}";
  333. grpc_error* error = GRPC_ERROR_NONE;
  334. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  335. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  336. const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector(
  337. grpc_slice_from_static_string("/TestServ/TestMethod"));
  338. ASSERT_NE(vector_ptr, nullptr);
  339. auto parsed_config = ((*vector_ptr)[1]).get();
  340. EXPECT_EQ(static_cast<TestParsedConfig1*>(parsed_config)->value(), 5);
  341. }
  342. TEST_F(ServiceConfigTest, Parser2DisabledViaChannelArg) {
  343. grpc_arg arg = grpc_channel_arg_integer_create(
  344. const_cast<char*>(GRPC_ARG_DISABLE_PARSING), 1);
  345. grpc_channel_args args = {1, &arg};
  346. const char* test_json =
  347. "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], "
  348. "\"method_param\":5}]}";
  349. grpc_error* error = GRPC_ERROR_NONE;
  350. auto svc_cfg = ServiceConfig::Create(&args, test_json, &error);
  351. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  352. const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector(
  353. grpc_slice_from_static_string("/TestServ/TestMethod"));
  354. ASSERT_NE(vector_ptr, nullptr);
  355. auto parsed_config = ((*vector_ptr)[1]).get();
  356. EXPECT_EQ(parsed_config, nullptr);
  357. }
  358. TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) {
  359. const char* test_json =
  360. "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], "
  361. "\"method_param\":\"5\"}]}";
  362. grpc_error* error = GRPC_ERROR_NONE;
  363. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  364. EXPECT_THAT(grpc_error_string(error),
  365. ::testing::ContainsRegex(absl::StrCat(
  366. "Service config parsing error.*referenced_errors\":\\[.*"
  367. "Method Params.*referenced_errors.*methodConfig.*"
  368. "referenced_errors.*",
  369. TestParser2::InvalidTypeErrorMessage())));
  370. GRPC_ERROR_UNREF(error);
  371. }
  372. TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) {
  373. const char* test_json =
  374. "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], "
  375. "\"method_param\":-5}]}";
  376. grpc_error* error = GRPC_ERROR_NONE;
  377. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  378. EXPECT_THAT(grpc_error_string(error),
  379. ::testing::ContainsRegex(absl::StrCat(
  380. "Service config parsing error.*referenced_errors\":\\[.*"
  381. "Method Params.*referenced_errors.*methodConfig.*"
  382. "referenced_errors.*",
  383. TestParser2::InvalidValueErrorMessage())));
  384. GRPC_ERROR_UNREF(error);
  385. }
  386. // Test parsing with ErrorParsers which always add errors
  387. class ErroredParsersScopingTest : public ::testing::Test {
  388. protected:
  389. void SetUp() override {
  390. ServiceConfigParser::Shutdown();
  391. ServiceConfigParser::Init();
  392. EXPECT_EQ(
  393. ServiceConfigParser::RegisterParser(absl::make_unique<ErrorParser>()),
  394. 0);
  395. EXPECT_EQ(
  396. ServiceConfigParser::RegisterParser(absl::make_unique<ErrorParser>()),
  397. 1);
  398. }
  399. };
  400. TEST_F(ErroredParsersScopingTest, GlobalParams) {
  401. const char* test_json = "{}";
  402. grpc_error* error = GRPC_ERROR_NONE;
  403. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  404. EXPECT_THAT(
  405. grpc_error_string(error),
  406. ::testing::ContainsRegex(absl::StrCat(
  407. "Service config parsing error.*referenced_errors\":\\[.*"
  408. "Global Params.*referenced_errors.*",
  409. ErrorParser::GlobalError(), ".*", ErrorParser::GlobalError())));
  410. GRPC_ERROR_UNREF(error);
  411. }
  412. TEST_F(ErroredParsersScopingTest, MethodParams) {
  413. const char* test_json = "{\"methodConfig\": [{}]}";
  414. grpc_error* error = GRPC_ERROR_NONE;
  415. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  416. EXPECT_THAT(
  417. grpc_error_string(error),
  418. ::testing::ContainsRegex(absl::StrCat(
  419. "Service config parsing error.*referenced_errors\":\\[.*"
  420. "Global Params.*referenced_errors.*",
  421. ErrorParser::GlobalError(), ".*", ErrorParser::GlobalError(),
  422. ".*Method Params.*referenced_errors.*methodConfig.*"
  423. "referenced_errors.*",
  424. ErrorParser::MethodError(), ".*", ErrorParser::MethodError())));
  425. GRPC_ERROR_UNREF(error);
  426. }
  427. //
  428. // client_channel parser tests
  429. //
  430. class ClientChannelParserTest : public ::testing::Test {
  431. protected:
  432. void SetUp() override {
  433. ServiceConfigParser::Shutdown();
  434. ServiceConfigParser::Init();
  435. EXPECT_EQ(
  436. ServiceConfigParser::RegisterParser(
  437. absl::make_unique<internal::ClientChannelServiceConfigParser>()),
  438. 0);
  439. }
  440. };
  441. TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigPickFirst) {
  442. const char* test_json = "{\"loadBalancingConfig\": [{\"pick_first\":{}}]}";
  443. grpc_error* error = GRPC_ERROR_NONE;
  444. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  445. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  446. const auto* parsed_config =
  447. static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
  448. svc_cfg->GetGlobalParsedConfig(0));
  449. auto lb_config = parsed_config->parsed_lb_config();
  450. EXPECT_STREQ(lb_config->name(), "pick_first");
  451. }
  452. TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) {
  453. const char* test_json =
  454. "{\"loadBalancingConfig\": [{\"round_robin\":{}}, {}]}";
  455. grpc_error* error = GRPC_ERROR_NONE;
  456. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  457. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  458. auto parsed_config =
  459. static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
  460. svc_cfg->GetGlobalParsedConfig(0));
  461. auto lb_config = parsed_config->parsed_lb_config();
  462. EXPECT_STREQ(lb_config->name(), "round_robin");
  463. }
  464. TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) {
  465. const char* test_json =
  466. "{\"loadBalancingConfig\": "
  467. "[{\"grpclb\":{\"childPolicy\":[{\"pick_first\":{}}]}}]}";
  468. grpc_error* error = GRPC_ERROR_NONE;
  469. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  470. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  471. const auto* parsed_config =
  472. static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
  473. svc_cfg->GetGlobalParsedConfig(0));
  474. auto lb_config = parsed_config->parsed_lb_config();
  475. EXPECT_STREQ(lb_config->name(), "grpclb");
  476. }
  477. TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) {
  478. const char* test_json =
  479. "{\n"
  480. " \"loadBalancingConfig\":[\n"
  481. " { \"does_not_exist\":{} },\n"
  482. " { \"xds_cluster_resolver_experimental\":{\n"
  483. " \"discoveryMechanisms\": [\n"
  484. " { \"clusterName\": \"foo\",\n"
  485. " \"type\": \"EDS\"\n"
  486. " } ]\n"
  487. " } }\n"
  488. " ]\n"
  489. "}";
  490. grpc_error* error = GRPC_ERROR_NONE;
  491. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  492. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  493. const auto* parsed_config =
  494. static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
  495. svc_cfg->GetGlobalParsedConfig(0));
  496. auto lb_config = parsed_config->parsed_lb_config();
  497. EXPECT_STREQ(lb_config->name(), "xds_cluster_resolver_experimental");
  498. }
  499. TEST_F(ClientChannelParserTest, UnknownLoadBalancingConfig) {
  500. const char* test_json = "{\"loadBalancingConfig\": [{\"unknown\":{}}]}";
  501. grpc_error* error = GRPC_ERROR_NONE;
  502. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  503. EXPECT_THAT(grpc_error_string(error),
  504. ::testing::ContainsRegex(
  505. "Service config parsing error.*referenced_errors.*"
  506. "Global Params.*referenced_errors.*"
  507. "Client channel global parser.*referenced_errors.*"
  508. "field:loadBalancingConfig.*referenced_errors.*"
  509. "No known policies in list: unknown"));
  510. GRPC_ERROR_UNREF(error);
  511. }
  512. TEST_F(ClientChannelParserTest, InvalidGrpclbLoadBalancingConfig) {
  513. const char* test_json =
  514. "{\"loadBalancingConfig\": ["
  515. " {\"grpclb\":{\"childPolicy\":1}},"
  516. " {\"round_robin\":{}}"
  517. "]}";
  518. grpc_error* error = GRPC_ERROR_NONE;
  519. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  520. EXPECT_THAT(grpc_error_string(error),
  521. ::testing::ContainsRegex(
  522. "Service config parsing error.*referenced_errors.*"
  523. "Global Params.*referenced_errors.*"
  524. "Client channel global parser.*referenced_errors.*"
  525. "field:loadBalancingConfig.*referenced_errors.*"
  526. "GrpcLb Parser.*referenced_errors.*"
  527. "field:childPolicy.*referenced_errors.*"
  528. "type should be array"));
  529. GRPC_ERROR_UNREF(error);
  530. }
  531. TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) {
  532. const char* test_json = "{\"loadBalancingPolicy\":\"pick_first\"}";
  533. grpc_error* error = GRPC_ERROR_NONE;
  534. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  535. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  536. const auto* parsed_config =
  537. static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
  538. svc_cfg->GetGlobalParsedConfig(0));
  539. EXPECT_EQ(parsed_config->parsed_deprecated_lb_policy(), "pick_first");
  540. }
  541. TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicyAllCaps) {
  542. const char* test_json = "{\"loadBalancingPolicy\":\"PICK_FIRST\"}";
  543. grpc_error* error = GRPC_ERROR_NONE;
  544. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  545. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  546. const auto* parsed_config =
  547. static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
  548. svc_cfg->GetGlobalParsedConfig(0));
  549. EXPECT_EQ(parsed_config->parsed_deprecated_lb_policy(), "pick_first");
  550. }
  551. TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) {
  552. const char* test_json = "{\"loadBalancingPolicy\":\"unknown\"}";
  553. grpc_error* error = GRPC_ERROR_NONE;
  554. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  555. EXPECT_THAT(grpc_error_string(error),
  556. ::testing::ContainsRegex(
  557. "Service config parsing error.*referenced_errors.*"
  558. "Global Params.*referenced_errors.*"
  559. "Client channel global parser.*referenced_errors.*"
  560. "field:loadBalancingPolicy error:Unknown lb policy"));
  561. GRPC_ERROR_UNREF(error);
  562. }
  563. TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) {
  564. const char* test_json =
  565. "{\"loadBalancingPolicy\":\"xds_cluster_resolver_experimental\"}";
  566. grpc_error* error = GRPC_ERROR_NONE;
  567. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  568. EXPECT_THAT(grpc_error_string(error),
  569. ::testing::ContainsRegex(
  570. "Service config parsing error.*referenced_errors.*"
  571. "Global Params.*referenced_errors.*"
  572. "Client channel global parser.*referenced_errors.*"
  573. "field:loadBalancingPolicy "
  574. "error:xds_cluster_resolver_experimental requires "
  575. "a config. Please use loadBalancingConfig instead."));
  576. GRPC_ERROR_UNREF(error);
  577. }
  578. TEST_F(ClientChannelParserTest, ValidTimeout) {
  579. const char* test_json =
  580. "{\n"
  581. " \"methodConfig\": [ {\n"
  582. " \"name\": [\n"
  583. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  584. " ],\n"
  585. " \"timeout\": \"5s\"\n"
  586. " } ]\n"
  587. "}";
  588. grpc_error* error = GRPC_ERROR_NONE;
  589. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  590. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  591. const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector(
  592. grpc_slice_from_static_string("/TestServ/TestMethod"));
  593. ASSERT_NE(vector_ptr, nullptr);
  594. auto parsed_config = ((*vector_ptr)[0]).get();
  595. EXPECT_EQ((static_cast<grpc_core::internal::ClientChannelMethodParsedConfig*>(
  596. parsed_config))
  597. ->timeout(),
  598. 5000);
  599. }
  600. TEST_F(ClientChannelParserTest, InvalidTimeout) {
  601. const char* test_json =
  602. "{\n"
  603. " \"methodConfig\": [ {\n"
  604. " \"name\": [\n"
  605. " { \"service\": \"service\", \"method\": \"method\" }\n"
  606. " ],\n"
  607. " \"timeout\": \"5sec\"\n"
  608. " } ]\n"
  609. "}";
  610. grpc_error* error = GRPC_ERROR_NONE;
  611. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  612. EXPECT_THAT(grpc_error_string(error),
  613. ::testing::ContainsRegex(
  614. "Service config parsing error.*referenced_errors.*"
  615. "Method Params.*referenced_errors.*"
  616. "methodConfig.*referenced_errors.*"
  617. "Client channel parser.*referenced_errors.*"
  618. "field:timeout error:type should be STRING of the form given "
  619. "by google.proto.Duration"));
  620. GRPC_ERROR_UNREF(error);
  621. }
  622. TEST_F(ClientChannelParserTest, ValidWaitForReady) {
  623. const char* test_json =
  624. "{\n"
  625. " \"methodConfig\": [ {\n"
  626. " \"name\": [\n"
  627. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  628. " ],\n"
  629. " \"waitForReady\": true\n"
  630. " } ]\n"
  631. "}";
  632. grpc_error* error = GRPC_ERROR_NONE;
  633. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  634. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  635. const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector(
  636. grpc_slice_from_static_string("/TestServ/TestMethod"));
  637. ASSERT_NE(vector_ptr, nullptr);
  638. auto parsed_config = ((*vector_ptr)[0]).get();
  639. ASSERT_TRUE(
  640. (static_cast<grpc_core::internal::ClientChannelMethodParsedConfig*>(
  641. parsed_config))
  642. ->wait_for_ready()
  643. .has_value());
  644. EXPECT_TRUE(
  645. (static_cast<grpc_core::internal::ClientChannelMethodParsedConfig*>(
  646. parsed_config))
  647. ->wait_for_ready()
  648. .value());
  649. }
  650. TEST_F(ClientChannelParserTest, InvalidWaitForReady) {
  651. const char* test_json =
  652. "{\n"
  653. " \"methodConfig\": [ {\n"
  654. " \"name\": [\n"
  655. " { \"service\": \"service\", \"method\": \"method\" }\n"
  656. " ],\n"
  657. " \"waitForReady\": \"true\"\n"
  658. " } ]\n"
  659. "}";
  660. grpc_error* error = GRPC_ERROR_NONE;
  661. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  662. EXPECT_THAT(grpc_error_string(error),
  663. ::testing::ContainsRegex(
  664. "Service config parsing error.*referenced_errors.*"
  665. "Method Params.*referenced_errors.*"
  666. "methodConfig.*referenced_errors.*"
  667. "Client channel parser.*referenced_errors.*"
  668. "field:waitForReady error:Type should be true/false"));
  669. GRPC_ERROR_UNREF(error);
  670. }
  671. TEST_F(ClientChannelParserTest, ValidHealthCheck) {
  672. const char* test_json =
  673. "{\n"
  674. " \"healthCheckConfig\": {\n"
  675. " \"serviceName\": \"health_check_service_name\"\n"
  676. " }\n"
  677. "}";
  678. grpc_error* error = GRPC_ERROR_NONE;
  679. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  680. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  681. const auto* parsed_config =
  682. static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
  683. svc_cfg->GetGlobalParsedConfig(0));
  684. ASSERT_NE(parsed_config, nullptr);
  685. EXPECT_EQ(parsed_config->health_check_service_name(),
  686. "health_check_service_name");
  687. }
  688. TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) {
  689. const char* test_json =
  690. "{\n"
  691. " \"healthCheckConfig\": {\n"
  692. " \"serviceName\": \"health_check_service_name\"\n"
  693. " },\n"
  694. " \"healthCheckConfig\": {\n"
  695. " \"serviceName\": \"health_check_service_name1\"\n"
  696. " }\n"
  697. "}";
  698. grpc_error* error = GRPC_ERROR_NONE;
  699. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  700. EXPECT_THAT(grpc_error_string(error),
  701. ::testing::ContainsRegex(
  702. "JSON parsing failed.*referenced_errors.*"
  703. "duplicate key \"healthCheckConfig\" at index 104"));
  704. GRPC_ERROR_UNREF(error);
  705. }
  706. //
  707. // retry parser tests
  708. //
  709. class RetryParserTest : public ::testing::Test {
  710. protected:
  711. void SetUp() override {
  712. ServiceConfigParser::Shutdown();
  713. ServiceConfigParser::Init();
  714. EXPECT_EQ(ServiceConfigParser::RegisterParser(
  715. absl::make_unique<internal::RetryServiceConfigParser>()),
  716. 0);
  717. }
  718. };
  719. TEST_F(RetryParserTest, ValidRetryThrottling) {
  720. const char* test_json =
  721. "{\n"
  722. " \"retryThrottling\": {\n"
  723. " \"maxTokens\": 2,\n"
  724. " \"tokenRatio\": 1.0\n"
  725. " }\n"
  726. "}";
  727. grpc_error* error = GRPC_ERROR_NONE;
  728. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  729. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  730. const auto* parsed_config =
  731. static_cast<grpc_core::internal::RetryGlobalConfig*>(
  732. svc_cfg->GetGlobalParsedConfig(0));
  733. ASSERT_NE(parsed_config, nullptr);
  734. EXPECT_EQ(parsed_config->max_milli_tokens(), 2000);
  735. EXPECT_EQ(parsed_config->milli_token_ratio(), 1000);
  736. }
  737. TEST_F(RetryParserTest, RetryThrottlingMissingFields) {
  738. const char* test_json =
  739. "{\n"
  740. " \"retryThrottling\": {\n"
  741. " }\n"
  742. "}";
  743. grpc_error* error = GRPC_ERROR_NONE;
  744. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  745. EXPECT_THAT(grpc_error_string(error),
  746. ::testing::ContainsRegex(
  747. "Service config parsing error.*referenced_errors.*"
  748. "Global Params.*referenced_errors.*"
  749. "retryThrottling.*referenced_errors.*"
  750. "field:retryThrottling field:maxTokens error:Not found.*"
  751. "field:retryThrottling field:tokenRatio error:Not found"));
  752. GRPC_ERROR_UNREF(error);
  753. }
  754. TEST_F(RetryParserTest, InvalidRetryThrottlingNegativeMaxTokens) {
  755. const char* test_json =
  756. "{\n"
  757. " \"retryThrottling\": {\n"
  758. " \"maxTokens\": -2,\n"
  759. " \"tokenRatio\": 1.0\n"
  760. " }\n"
  761. "}";
  762. grpc_error* error = GRPC_ERROR_NONE;
  763. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  764. EXPECT_THAT(grpc_error_string(error),
  765. ::testing::ContainsRegex(
  766. "Service config parsing error.*referenced_errors.*"
  767. "Global Params.*referenced_errors.*"
  768. "retryThrottling.*referenced_errors.*"
  769. "field:retryThrottling field:maxTokens error:should "
  770. "be greater than zero"));
  771. GRPC_ERROR_UNREF(error);
  772. }
  773. TEST_F(RetryParserTest, InvalidRetryThrottlingInvalidTokenRatio) {
  774. const char* test_json =
  775. "{\n"
  776. " \"retryThrottling\": {\n"
  777. " \"maxTokens\": 2,\n"
  778. " \"tokenRatio\": -1\n"
  779. " }\n"
  780. "}";
  781. grpc_error* error = GRPC_ERROR_NONE;
  782. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  783. EXPECT_THAT(grpc_error_string(error),
  784. ::testing::ContainsRegex(
  785. "Service config parsing error.*referenced_errors.*"
  786. "Global Params.*referenced_errors.*"
  787. "retryThrottling.*referenced_errors.*"
  788. "field:retryThrottling field:tokenRatio "
  789. "error:Failed parsing"));
  790. GRPC_ERROR_UNREF(error);
  791. }
  792. TEST_F(RetryParserTest, ValidRetryPolicy) {
  793. const char* test_json =
  794. "{\n"
  795. " \"methodConfig\": [ {\n"
  796. " \"name\": [\n"
  797. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  798. " ],\n"
  799. " \"retryPolicy\": {\n"
  800. " \"maxAttempts\": 3,\n"
  801. " \"initialBackoff\": \"1s\",\n"
  802. " \"maxBackoff\": \"120s\",\n"
  803. " \"backoffMultiplier\": 1.6,\n"
  804. " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
  805. " }\n"
  806. " } ]\n"
  807. "}";
  808. grpc_error* error = GRPC_ERROR_NONE;
  809. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  810. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  811. const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector(
  812. grpc_slice_from_static_string("/TestServ/TestMethod"));
  813. ASSERT_NE(vector_ptr, nullptr);
  814. const auto* parsed_config =
  815. static_cast<grpc_core::internal::RetryMethodConfig*>(
  816. ((*vector_ptr)[0]).get());
  817. ASSERT_NE(parsed_config, nullptr);
  818. EXPECT_EQ(parsed_config->max_attempts(), 3);
  819. EXPECT_EQ(parsed_config->initial_backoff(), 1000);
  820. EXPECT_EQ(parsed_config->max_backoff(), 120000);
  821. EXPECT_EQ(parsed_config->backoff_multiplier(), 1.6f);
  822. EXPECT_TRUE(
  823. parsed_config->retryable_status_codes().Contains(GRPC_STATUS_ABORTED));
  824. }
  825. TEST_F(RetryParserTest, InvalidRetryPolicyMaxAttempts) {
  826. const char* test_json =
  827. "{\n"
  828. " \"methodConfig\": [ {\n"
  829. " \"name\": [\n"
  830. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  831. " ],\n"
  832. " \"retryPolicy\": {\n"
  833. " \"maxAttempts\": 1,\n"
  834. " \"initialBackoff\": \"1s\",\n"
  835. " \"maxBackoff\": \"120s\",\n"
  836. " \"backoffMultiplier\": 1.6,\n"
  837. " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
  838. " }\n"
  839. " } ]\n"
  840. "}";
  841. grpc_error* error = GRPC_ERROR_NONE;
  842. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  843. EXPECT_THAT(grpc_error_string(error),
  844. ::testing::ContainsRegex(
  845. "Service config parsing error.*referenced_errors.*"
  846. "Method Params.*referenced_errors.*"
  847. "methodConfig.*referenced_errors.*"
  848. "retryPolicy.*referenced_errors.*"
  849. "field:maxAttempts error:should be at least 2"));
  850. GRPC_ERROR_UNREF(error);
  851. }
  852. TEST_F(RetryParserTest, InvalidRetryPolicyInitialBackoff) {
  853. const char* test_json =
  854. "{\n"
  855. " \"methodConfig\": [ {\n"
  856. " \"name\": [\n"
  857. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  858. " ],\n"
  859. " \"retryPolicy\": {\n"
  860. " \"maxAttempts\": 1,\n"
  861. " \"initialBackoff\": \"1sec\",\n"
  862. " \"maxBackoff\": \"120s\",\n"
  863. " \"backoffMultiplier\": 1.6,\n"
  864. " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
  865. " }\n"
  866. " } ]\n"
  867. "}";
  868. grpc_error* error = GRPC_ERROR_NONE;
  869. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  870. EXPECT_THAT(grpc_error_string(error),
  871. ::testing::ContainsRegex(
  872. "Service config parsing error.*referenced_errors.*"
  873. "Method Params.*referenced_errors.*"
  874. "methodConfig.*referenced_errors.*"
  875. "retryPolicy.*referenced_errors.*"
  876. "field:initialBackoff error:type should be STRING of the "
  877. "form given by google.proto.Duration"));
  878. GRPC_ERROR_UNREF(error);
  879. }
  880. TEST_F(RetryParserTest, InvalidRetryPolicyMaxBackoff) {
  881. const char* test_json =
  882. "{\n"
  883. " \"methodConfig\": [ {\n"
  884. " \"name\": [\n"
  885. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  886. " ],\n"
  887. " \"retryPolicy\": {\n"
  888. " \"maxAttempts\": 1,\n"
  889. " \"initialBackoff\": \"1s\",\n"
  890. " \"maxBackoff\": \"120sec\",\n"
  891. " \"backoffMultiplier\": 1.6,\n"
  892. " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
  893. " }\n"
  894. " } ]\n"
  895. "}";
  896. grpc_error* error = GRPC_ERROR_NONE;
  897. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  898. EXPECT_THAT(grpc_error_string(error),
  899. ::testing::ContainsRegex(
  900. "Service config parsing error.*referenced_errors.*"
  901. "Method Params.*referenced_errors.*"
  902. "methodConfig.*referenced_errors.*"
  903. "retryPolicy.*referenced_errors.*"
  904. "field:maxBackoff error:type should be STRING of the form "
  905. "given by google.proto.Duration"));
  906. GRPC_ERROR_UNREF(error);
  907. }
  908. TEST_F(RetryParserTest, InvalidRetryPolicyBackoffMultiplier) {
  909. const char* test_json =
  910. "{\n"
  911. " \"methodConfig\": [ {\n"
  912. " \"name\": [\n"
  913. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  914. " ],\n"
  915. " \"retryPolicy\": {\n"
  916. " \"maxAttempts\": 1,\n"
  917. " \"initialBackoff\": \"1s\",\n"
  918. " \"maxBackoff\": \"120s\",\n"
  919. " \"backoffMultiplier\": \"1.6\",\n"
  920. " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
  921. " }\n"
  922. " } ]\n"
  923. "}";
  924. grpc_error* error = GRPC_ERROR_NONE;
  925. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  926. EXPECT_THAT(grpc_error_string(error),
  927. ::testing::ContainsRegex(
  928. "Service config parsing error.*referenced_errors.*"
  929. "Method Params.*referenced_errors.*"
  930. "methodConfig.*referenced_errors.*"
  931. "retryPolicy.*referenced_errors.*"
  932. "field:backoffMultiplier error:should be of type number"));
  933. GRPC_ERROR_UNREF(error);
  934. }
  935. TEST_F(RetryParserTest, InvalidRetryPolicyRetryableStatusCodes) {
  936. const char* test_json =
  937. "{\n"
  938. " \"methodConfig\": [ {\n"
  939. " \"name\": [\n"
  940. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  941. " ],\n"
  942. " \"retryPolicy\": {\n"
  943. " \"maxAttempts\": 1,\n"
  944. " \"initialBackoff\": \"1s\",\n"
  945. " \"maxBackoff\": \"120s\",\n"
  946. " \"backoffMultiplier\": \"1.6\",\n"
  947. " \"retryableStatusCodes\": []\n"
  948. " }\n"
  949. " } ]\n"
  950. "}";
  951. grpc_error* error = GRPC_ERROR_NONE;
  952. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  953. EXPECT_THAT(grpc_error_string(error),
  954. ::testing::ContainsRegex(
  955. "Service config parsing error.*referenced_errors.*"
  956. "Method Params.*referenced_errors.*"
  957. "methodConfig.*referenced_errors.*"
  958. "retryPolicy.*referenced_errors.*"
  959. "field:retryableStatusCodes error:should be non-empty"));
  960. GRPC_ERROR_UNREF(error);
  961. }
  962. //
  963. // message_size parser tests
  964. //
  965. class MessageSizeParserTest : public ::testing::Test {
  966. protected:
  967. void SetUp() override {
  968. ServiceConfigParser::Shutdown();
  969. ServiceConfigParser::Init();
  970. EXPECT_EQ(ServiceConfigParser::RegisterParser(
  971. absl::make_unique<MessageSizeParser>()),
  972. 0);
  973. }
  974. };
  975. TEST_F(MessageSizeParserTest, Valid) {
  976. const char* test_json =
  977. "{\n"
  978. " \"methodConfig\": [ {\n"
  979. " \"name\": [\n"
  980. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  981. " ],\n"
  982. " \"maxRequestMessageBytes\": 1024,\n"
  983. " \"maxResponseMessageBytes\": 1024\n"
  984. " } ]\n"
  985. "}";
  986. grpc_error* error = GRPC_ERROR_NONE;
  987. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  988. ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
  989. const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector(
  990. grpc_slice_from_static_string("/TestServ/TestMethod"));
  991. ASSERT_NE(vector_ptr, nullptr);
  992. auto parsed_config =
  993. static_cast<MessageSizeParsedConfig*>(((*vector_ptr)[0]).get());
  994. ASSERT_NE(parsed_config, nullptr);
  995. EXPECT_EQ(parsed_config->limits().max_send_size, 1024);
  996. EXPECT_EQ(parsed_config->limits().max_recv_size, 1024);
  997. }
  998. TEST_F(MessageSizeParserTest, InvalidMaxRequestMessageBytes) {
  999. const char* test_json =
  1000. "{\n"
  1001. " \"methodConfig\": [ {\n"
  1002. " \"name\": [\n"
  1003. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  1004. " ],\n"
  1005. " \"maxRequestMessageBytes\": -1024\n"
  1006. " } ]\n"
  1007. "}";
  1008. grpc_error* error = GRPC_ERROR_NONE;
  1009. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  1010. EXPECT_THAT(grpc_error_string(error),
  1011. ::testing::ContainsRegex(
  1012. "Service config parsing error.*referenced_errors.*"
  1013. "Method Params.*referenced_errors.*"
  1014. "methodConfig.*referenced_errors.*"
  1015. "Message size parser.*referenced_errors.*"
  1016. "field:maxRequestMessageBytes error:should be non-negative"));
  1017. GRPC_ERROR_UNREF(error);
  1018. }
  1019. TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) {
  1020. const char* test_json =
  1021. "{\n"
  1022. " \"methodConfig\": [ {\n"
  1023. " \"name\": [\n"
  1024. " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n"
  1025. " ],\n"
  1026. " \"maxResponseMessageBytes\": {}\n"
  1027. " } ]\n"
  1028. "}";
  1029. grpc_error* error = GRPC_ERROR_NONE;
  1030. auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
  1031. EXPECT_THAT(grpc_error_string(error),
  1032. ::testing::ContainsRegex(
  1033. "Service config parsing error.*referenced_errors.*"
  1034. "Method Params.*referenced_errors.*"
  1035. "methodConfig.*referenced_errors.*"
  1036. "Message size parser.*referenced_errors.*"
  1037. "field:maxResponseMessageBytes error:should be of type "
  1038. "number"));
  1039. GRPC_ERROR_UNREF(error);
  1040. }
  1041. } // namespace testing
  1042. } // namespace grpc_core
  1043. int main(int argc, char** argv) {
  1044. ::testing::InitGoogleTest(&argc, argv);
  1045. grpc::testing::TestEnvironment env(argc, argv);
  1046. grpc_init();
  1047. int ret = RUN_ALL_TESTS();
  1048. grpc_shutdown();
  1049. return ret;
  1050. }