rls_lb_config_parser_test.cc
Go to the documentation of this file.
1 //
2 // Copyright 2021 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 
20 #include <grpc/grpc.h>
21 
22 #include "src/core/lib/gpr/env.h"
25 
26 // A regular expression to enter referenced or child errors.
27 #ifdef GRPC_ERROR_IS_ABSEIL_STATUS
28 #define CHILD_ERROR_TAG ".*children.*"
29 #else
30 #define CHILD_ERROR_TAG ".*referenced_errors.*"
31 #endif
32 
33 namespace grpc_core {
34 namespace {
35 
36 class RlsConfigParsingTest : public ::testing::Test {
37  public:
38  static void SetUpTestSuite() { grpc_init(); }
39 
40  static void TearDownTestSuite() { grpc_shutdown_blocking(); }
41 };
42 
43 TEST_F(RlsConfigParsingTest, ValidConfig) {
44  const char* service_config_json =
45  "{\n"
46  " \"loadBalancingConfig\":[{\n"
47  " \"rls_experimental\":{\n"
48  " \"routeLookupConfig\":{\n"
49  " \"lookupService\":\"rls.example.com:80\",\n"
50  " \"cacheSizeBytes\":1,\n"
51  " \"grpcKeybuilders\":[\n"
52  " {\n"
53  " \"names\":[\n"
54  " {\"service\":\"foo\"}\n"
55  " ]\n"
56  " }\n"
57  " ]\n"
58  " },\n"
59  " \"routeLookupChannelServiceConfig\": {\n"
60  " \"loadBalancingPolicy\": \"ROUND_ROBIN\"\n"
61  " },\n"
62  " \"childPolicy\":[\n"
63  " {\"unknown\":{}},\n" // Okay, since the next one exists.
64  " {\"grpclb\":{}}\n"
65  " ],\n"
66  " \"childPolicyConfigTargetFieldName\":\"target\"\n"
67  " }\n"
68  " }]\n"
69  "}\n";
71  auto service_config = ServiceConfigImpl::Create(
72  /*args=*/nullptr, service_config_json, &error);
74  EXPECT_NE(service_config, nullptr);
75 }
76 
77 //
78 // top-level fields
79 //
80 
81 TEST_F(RlsConfigParsingTest, TopLevelRequiredFieldsMissing) {
82  const char* service_config_json =
83  "{\n"
84  " \"loadBalancingConfig\":[{\n"
85  " \"rls_experimental\":{\n"
86  " }\n"
87  " }]\n"
88  "}\n";
90  auto service_config = ServiceConfigImpl::Create(
91  /*args=*/nullptr, service_config_json, &error);
95  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
96  "field:routeLookupConfig error:does not exist.*"
97  "field:childPolicyConfigTargetFieldName error:does not exist.*"
98  "field:childPolicy error:does not exist"));
100 }
101 
102 TEST_F(RlsConfigParsingTest, TopLevelFieldsWrongTypes) {
103  const char* service_config_json =
104  "{\n"
105  " \"loadBalancingConfig\":[{\n"
106  " \"rls_experimental\":{\n"
107  " \"routeLookupConfig\":1,\n"
108  " \"routeLookupChannelServiceConfig\": 1,\n"
109  " \"childPolicy\":1,\n"
110  " \"childPolicyConfigTargetFieldName\":1\n"
111  " }\n"
112  " }]\n"
113  "}\n";
115  auto service_config = ServiceConfigImpl::Create(
116  /*args=*/nullptr, service_config_json, &error);
117  EXPECT_THAT(
120  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
121  "field:routeLookupConfig error:type should be OBJECT.*"
122  "field:routeLookupChannelServiceConfig error:type should be OBJECT.*"
123  "field:childPolicyConfigTargetFieldName error:type should be STRING.*"
124  "field:childPolicy error:type should be ARRAY"));
126 }
127 
128 TEST_F(RlsConfigParsingTest, TopLevelFieldsInvalidValues) {
129  const char* service_config_json =
130  "{\n"
131  " \"loadBalancingConfig\":[{\n"
132  " \"rls_experimental\":{\n"
133  " \"childPolicy\":[\n"
134  " {\"unknown\":{}}\n"
135  " ],\n"
136  " \"childPolicyConfigTargetFieldName\":\"\"\n"
137  " }\n"
138  " }]\n"
139  "}\n";
141  auto service_config = ServiceConfigImpl::Create(
142  /*args=*/nullptr, service_config_json, &error);
143  EXPECT_THAT(
146  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
147  "field:childPolicyConfigTargetFieldName error:must be non-empty.*"
148  "field:childPolicy" CHILD_ERROR_TAG
149  "No known policies in list: unknown"));
151 }
152 
153 TEST_F(RlsConfigParsingTest, InvalidChildPolicyConfig) {
154  const char* service_config_json =
155  "{\n"
156  " \"loadBalancingConfig\":[{\n"
157  " \"rls_experimental\":{\n"
158  " \"childPolicy\":[\n"
159  " {\"grpclb\":{\"childPolicy\":1}}\n"
160  " ],\n"
161  " \"childPolicyConfigTargetFieldName\":\"serviceName\"\n"
162  " }\n"
163  " }]\n"
164  "}\n";
166  auto service_config = ServiceConfigImpl::Create(
167  /*args=*/nullptr, service_config_json, &error);
168  EXPECT_THAT(
171  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
172  "field:childPolicy" CHILD_ERROR_TAG "GrpcLb Parser" CHILD_ERROR_TAG
173  "field:childPolicy" CHILD_ERROR_TAG "type should be array"));
175 }
176 
177 TEST_F(RlsConfigParsingTest, InvalidRlsChannelServiceConfig) {
178  const char* service_config_json =
179  "{\n"
180  " \"loadBalancingConfig\":[{\n"
181  " \"rls_experimental\":{\n"
182  " \"routeLookupChannelServiceConfig\": {\n"
183  " \"loadBalancingPolicy\": \"unknown\"\n"
184  " },\n"
185  " \"childPolicy\":[\n"
186  " {\"grpclb\":{}}\n"
187  " ],\n"
188  " \"childPolicyConfigTargetFieldName\":\"serviceName\"\n"
189  " }\n"
190  " }]\n"
191  "}\n";
193  auto service_config = ServiceConfigImpl::Create(
194  /*args=*/nullptr, service_config_json, &error);
197  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
198  "field:routeLookupChannelServiceConfig" CHILD_ERROR_TAG
199  "Service config parsing error" CHILD_ERROR_TAG
200  "Global Params" CHILD_ERROR_TAG
201  "Client channel global parser" CHILD_ERROR_TAG
202  "field:loadBalancingPolicy error:Unknown lb policy"));
204 }
205 
206 //
207 // routeLookupConfig fields
208 //
209 
210 TEST_F(RlsConfigParsingTest, RouteLookupConfigRequiredFieldsMissing) {
211  const char* service_config_json =
212  "{\n"
213  " \"loadBalancingConfig\":[{\n"
214  " \"rls_experimental\":{\n"
215  " \"routeLookupConfig\":{\n"
216  " }\n"
217  " }\n"
218  " }]\n"
219  "}\n";
221  auto service_config = ServiceConfigImpl::Create(
222  /*args=*/nullptr, service_config_json, &error);
225  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
226  "field:routeLookupConfig" CHILD_ERROR_TAG
227  "field:grpcKeybuilders error:does not exist.*"
228  "field:lookupService error:does not exist"));
230 }
231 
232 TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsWrongTypes) {
233  const char* service_config_json =
234  "{\n"
235  " \"loadBalancingConfig\":[{\n"
236  " \"rls_experimental\":{\n"
237  " \"routeLookupConfig\":{\n"
238  " \"grpcKeybuilders\":1,\n"
239  " \"name\":1,\n"
240  " \"lookupService\":1,\n"
241  " \"lookupServiceTimeout\":{},\n"
242  " \"maxAge\":{},\n"
243  " \"staleAge\":{},\n"
244  " \"cacheSizeBytes\":\"xxx\",\n"
245  " \"defaultTarget\":1\n"
246  " }\n"
247  " }\n"
248  " }]\n"
249  "}\n";
251  auto service_config = ServiceConfigImpl::Create(
252  /*args=*/nullptr, service_config_json, &error);
255  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
256  "field:routeLookupConfig" CHILD_ERROR_TAG
257  "field:grpcKeybuilders error:type should be ARRAY.*"
258  "field:lookupService error:type should be STRING.*"
259  "field:maxAge error:type should be STRING.*"
260  "field:staleAge error:type should be STRING.*"
261  "field:cacheSizeBytes error:failed to parse.*"
262  "field:defaultTarget error:type should be STRING"));
264 }
265 
266 TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsInvalidValues) {
267  const char* service_config_json =
268  "{\n"
269  " \"loadBalancingConfig\":[{\n"
270  " \"rls_experimental\":{\n"
271  " \"routeLookupConfig\":{\n"
272  " \"lookupService\":\"\",\n"
273  " \"cacheSizeBytes\":0\n"
274  " }\n"
275  " }\n"
276  " }]\n"
277  "}\n";
279  auto service_config = ServiceConfigImpl::Create(
280  /*args=*/nullptr, service_config_json, &error);
283  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
284  "field:routeLookupConfig" CHILD_ERROR_TAG
285  "field:lookupService error:must be valid gRPC target URI.*"
286  "field:cacheSizeBytes error:must be greater than 0"));
288 }
289 
290 //
291 // grpcKeybuilder fields
292 //
293 
294 TEST_F(RlsConfigParsingTest, GrpcKeybuilderRequiredFieldsMissing) {
295  const char* service_config_json =
296  "{\n"
297  " \"loadBalancingConfig\":[{\n"
298  " \"rls_experimental\":{\n"
299  " \"routeLookupConfig\":{\n"
300  " \"grpcKeybuilders\":[\n"
301  " {\n"
302  " }\n"
303  " ]\n"
304  " }\n"
305  " }\n"
306  " }]\n"
307  "}\n";
309  auto service_config = ServiceConfigImpl::Create(
310  /*args=*/nullptr, service_config_json, &error);
311  EXPECT_THAT(
314  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
315  "field:routeLookupConfig" CHILD_ERROR_TAG
316  "field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG
317  "field:names error:does not exist"));
319 }
320 
321 TEST_F(RlsConfigParsingTest, GrpcKeybuilderWrongFieldTypes) {
322  const char* service_config_json =
323  "{\n"
324  " \"loadBalancingConfig\":[{\n"
325  " \"rls_experimental\":{\n"
326  " \"routeLookupConfig\":{\n"
327  " \"grpcKeybuilders\":[\n"
328  " {\n"
329  " \"names\":1,\n"
330  " \"headers\":1,\n"
331  " \"extraKeys\":1,\n"
332  " \"constantKeys\":1\n"
333  " }\n"
334  " ]\n"
335  " }\n"
336  " }\n"
337  " }]\n"
338  "}\n";
340  auto service_config = ServiceConfigImpl::Create(
341  /*args=*/nullptr, service_config_json, &error);
342  EXPECT_THAT(
345  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
346  "field:routeLookupConfig" CHILD_ERROR_TAG
347  "field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG
348  "field:names error:type should be ARRAY.*"
349  "field:headers error:type should be ARRAY.*"
350  "field:extraKeys error:type should be OBJECT.*"
351  "field:constantKeys error:type should be OBJECT"));
353 }
354 
355 TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidValues) {
356  const char* service_config_json =
357  "{\n"
358  " \"loadBalancingConfig\":[{\n"
359  " \"rls_experimental\":{\n"
360  " \"routeLookupConfig\":{\n"
361  " \"grpcKeybuilders\":[\n"
362  " {\n"
363  " \"names\":[],\n"
364  " \"extraKeys\":{\n"
365  " \"host\":1,\n"
366  " \"service\":1,\n"
367  " \"method\":1\n"
368  " },\n"
369  " \"constantKeys\":{\n"
370  " \"key\":1\n"
371  " }\n"
372  " }\n"
373  " ]\n"
374  " }\n"
375  " }\n"
376  " }]\n"
377  "}\n";
379  auto service_config = ServiceConfigImpl::Create(
380  /*args=*/nullptr, service_config_json, &error);
383  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
384  "field:routeLookupConfig" CHILD_ERROR_TAG
385  "field:grpcKeybuilders" CHILD_ERROR_TAG
386  "index:0" CHILD_ERROR_TAG "field:names error:list is empty.*"
387  "field:extraKeys" CHILD_ERROR_TAG
388  "field:host error:type should be STRING.*"
389  "field:service error:type should be STRING.*"
390  "field:method error:type should be STRING.*"
391  "field:constantKeys" CHILD_ERROR_TAG
392  "field:key error:type should be STRING"));
394 }
395 
396 TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidHeaders) {
397  const char* service_config_json =
398  "{\n"
399  " \"loadBalancingConfig\":[{\n"
400  " \"rls_experimental\":{\n"
401  " \"routeLookupConfig\":{\n"
402  " \"grpcKeybuilders\":[\n"
403  " {\n"
404  " \"headers\":[\n"
405  " 1,\n"
406  " {\n"
407  " \"key\":1,\n"
408  " \"names\":1\n"
409  " },\n"
410  " {\n"
411  " \"names\":[]\n"
412  " },\n"
413  " {\n"
414  " \"key\":\"\",\n"
415  " \"names\":[1, \"\"]\n"
416  " }\n"
417  " ],\n"
418  " \"extraKeys\":{\n"
419  " \"host\": \"\"\n"
420  " },\n"
421  " \"constantKeys\":{\n"
422  " \"\":\"foo\"\n"
423  " }\n"
424  " }\n"
425  " ]\n"
426  " }\n"
427  " }\n"
428  " }]\n"
429  "}\n";
431  auto service_config = ServiceConfigImpl::Create(
432  /*args=*/nullptr, service_config_json, &error);
433  EXPECT_THAT(
436  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
437  "field:routeLookupConfig" CHILD_ERROR_TAG
438  "field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG
439  "field:headers index:0 error:type should be OBJECT.*"
440  "field:headers index:1" CHILD_ERROR_TAG
441  "field:key error:type should be STRING.*"
442  "field:names error:type should be ARRAY.*"
443  "field:headers index:2" CHILD_ERROR_TAG
444  "field:key error:does not exist.*"
445  "field:names error:list is empty.*"
446  "field:headers index:3" CHILD_ERROR_TAG
447  "field:key error:must be non-empty.*"
448  "field:names index:0 error:type should be STRING.*"
449  "field:names index:1 error:header name must be non-empty.*"
450  "field:extraKeys" CHILD_ERROR_TAG
451  "field:host error:must be non-empty.*"
452  "field:constantKeys" CHILD_ERROR_TAG "error:keys must be non-empty"));
454 }
455 
456 TEST_F(RlsConfigParsingTest, GrpcKeybuilderNameWrongFieldTypes) {
457  const char* service_config_json =
458  "{\n"
459  " \"loadBalancingConfig\":[{\n"
460  " \"rls_experimental\":{\n"
461  " \"routeLookupConfig\":{\n"
462  " \"grpcKeybuilders\":[\n"
463  " {\n"
464  " \"names\":[\n"
465  " 1,\n"
466  " {\n"
467  " \"service\":1,\n"
468  " \"method\":1\n"
469  " }\n"
470  " ]\n"
471  " }\n"
472  " ]\n"
473  " }\n"
474  " }\n"
475  " }]\n"
476  "}\n";
478  auto service_config = ServiceConfigImpl::Create(
479  /*args=*/nullptr, service_config_json, &error);
480  EXPECT_THAT(
483  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
484  "field:routeLookupConfig" CHILD_ERROR_TAG
485  "field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG
486  "field:names index:0 error:type should be OBJECT.*"
487  "field:names index:1" CHILD_ERROR_TAG
488  "field:service error:type should be STRING.*"
489  "field:method error:type should be STRING"));
491 }
492 
493 TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInSameKeyBuilder) {
494  const char* service_config_json =
495  "{\n"
496  " \"loadBalancingConfig\":[{\n"
497  " \"rls_experimental\":{\n"
498  " \"routeLookupConfig\":{\n"
499  " \"grpcKeybuilders\":[\n"
500  " {\n"
501  " \"names\":[\n"
502  " {\n"
503  " \"service\":\"foo\",\n"
504  " \"method\":\"bar\"\n"
505  " },\n"
506  " {\n"
507  " \"service\":\"foo\",\n"
508  " \"method\":\"bar\"\n"
509  " }\n"
510  " ]\n"
511  " }\n"
512  " ]\n"
513  " }\n"
514  " }\n"
515  " }]\n"
516  "}\n";
518  auto service_config = ServiceConfigImpl::Create(
519  /*args=*/nullptr, service_config_json, &error);
520  EXPECT_THAT(
523  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
524  "field:routeLookupConfig" CHILD_ERROR_TAG
525  "field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG
526  "field:names error:duplicate entry for /foo/bar"));
528 }
529 
530 TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInDifferentKeyBuilders) {
531  const char* service_config_json =
532  "{\n"
533  " \"loadBalancingConfig\":[{\n"
534  " \"rls_experimental\":{\n"
535  " \"routeLookupConfig\":{\n"
536  " \"grpcKeybuilders\":[\n"
537  " {\n"
538  " \"names\":[\n"
539  " {\n"
540  " \"service\":\"foo\",\n"
541  " \"method\":\"bar\"\n"
542  " }\n"
543  " ]\n"
544  " },\n"
545  " {\n"
546  " \"names\":[\n"
547  " {\n"
548  " \"service\":\"foo\",\n"
549  " \"method\":\"bar\"\n"
550  " }\n"
551  " ]\n"
552  " }\n"
553  " ]\n"
554  " }\n"
555  " }\n"
556  " }]\n"
557  "}\n";
559  auto service_config = ServiceConfigImpl::Create(
560  /*args=*/nullptr, service_config_json, &error);
561  EXPECT_THAT(
564  "errors parsing RLS LB policy config" CHILD_ERROR_TAG
565  "field:routeLookupConfig" CHILD_ERROR_TAG
566  "field:grpcKeybuilders" CHILD_ERROR_TAG "index:1" CHILD_ERROR_TAG
567  "field:names error:duplicate entry for /foo/bar"));
569 }
570 
571 } // namespace
572 } // namespace grpc_core
573 
574 int main(int argc, char** argv) {
575  ::testing::InitGoogleTest(&argc, argv);
576  grpc::testing::TestEnvironment env(&argc, argv);
577  return RUN_ALL_TESTS();
578 }
testing::ContainsRegex
PolymorphicMatcher< internal::MatchesRegexMatcher > ContainsRegex(const internal::RE *regex)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8835
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
generate.env
env
Definition: generate.py:37
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
grpc_shutdown_blocking
GRPCAPI void grpc_shutdown_blocking(void)
Definition: init.cc:238
grpc_core
Definition: call_metric_recorder.h:31
error
grpc_error_handle error
Definition: retry_filter.cc:499
env.h
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
main
int main(int argc, char **argv)
Definition: rls_lb_config_parser_test.cc:574
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
grpc.h
grpc_core::TEST_F
TEST_F(AuthorizationMatchersTest, AlwaysAuthorizationMatcher)
Definition: authorization_matchers_test.cc:35
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
grpc_core::ServiceConfigImpl::Create
static RefCountedPtr< ServiceConfig > Create(const grpc_channel_args *args, absl::string_view json_string, grpc_error_handle *error)
Definition: service_config_impl.cc:41
test_config.h
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
grpc_error_std_string
std::string grpc_error_std_string(grpc_error_handle error)
Definition: error.cc:944
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
service_config_impl.h
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
grpc_init
GRPCAPI void grpc_init(void)
Definition: init.cc:146
grpc_error
Definition: error_internal.h:42
CHILD_ERROR_TAG
#define CHILD_ERROR_TAG
Definition: rls_lb_config_parser_test.cc:30


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:06