mirror of https://github.com/grpc/grpc.git
RLS LB policy (#27352)
* RLS LB policy plugin implementation * Add RLS tests * rls proto * generate projects * Fix adding child policy to child policy map * Fix issues * Fix rotten bits * generate projects * revert some strange changes * First batch of fixes * second batch of addressing comments * generate_projects * 3rd batch of fixes * generate_projects * 4th batch of fix * 5th batch of fix * Empty commit to trigger github PR refresh * Add insecure build * generate project * update picker in a closure * mutex guard audit * clang-format * Aggregate child policy states * Use OrphanablePtr on ChildPolicyOwner() * More fixes on comments * Remove include grpc_security from rls.cc * Fix key builder test as we removed RlsFindPathFromMetadata * Update rls proto and add multi-target capability * code changes to fix build after merging master * remove support for insecure builds * WIP * add LB policy metadata lookup API * add API for creating errors from C++ strings * add missing include * finished updating JSON parsing * use DualRefCounted<> for ChildPolicyWrapper * use grpc_core::Mutex instead of std::recursive_mutex * add lock annotations and fix some lifetime issues * misc fixes and cleanups * simplify child policy connectivity state machine * add comment about hopping into ExecCtx * don't use wait_for_ready for RLS call * extraKeys and constantKeys support * add lock annotations for child policy wrapper connectivity state * improve logging * simplify child policy state handling in picker * use C++ style comments * remove rls_config.proto, since it's not needed * rewrote tests * fix build * fix copyright headers * clang-format * appease clang-tidy * remove unnecessary dependendency on grpclb * buildifier * remove illegal term * remove unneeded includes * clang-format * fix clang-tidy * fix build * move class declaration into .cc file * clang-tidy again * fix build * reorganize code and misc cleanups * clang-format * fixed a bunch of asan bugs; still some left to debug * fix asan problem * make test work on IPv6-only machines * move LRU list handling into Cache::Entry and add lock annotations * use preincrement instead of postincrement * fix deadlock * add more FIXMEs * clean up backoff timer logic * fix build from merge * clang-format * fix include path to work on podspec builds * clean up picker logic * clang-format * update rls.proto * populate reason and stale_header_data in RLS request * improve logging and fix some cache size type issues * clang-format * add some TODOs about a better way to expose channel creds to LB policies * centralize handling of channel's default authority * clang-format * fix backup poller bug * fix handling of call creds and authority on RLS channel * remove unused params * clang-format * use two-phase update for child policies to avoid deadlocks * fix portability issue * minor cleanups * update for change in grpc_error_get_status() API * change test to store RLS requests and responses in proto form * clang-format * account for test slowdown factor in timeouts * fix tsan failure and channelz linkage * fix RLS authority death test * fix test to not try to connect to target that should not work * remove illegal term * cacheSizeBytes is a required field * add missing BUILD deps from merge * add tests for connectivity state reporting and fix bugs found * fix BUILD sanity * buildifier * fix BUILD package path * fix bugs related to child policy lifetime and updates * remove unnecessary srand() call from grpc_init() * add test for two cache entries with the same target * update rls.proto * change RLS config parser test to support GRPC_ERROR_IS_ABSEIL_STATUS * update upb codegen * fix include path * add env var guard * avoid duplication of CountedService * generate_projects * add upper limit for cacheSizeBytes * fix build Co-authored-by: Muxi Yan <mxyan@google.com>pull/27705/head
parent
d1297bcc17
commit
84ddc3289f
37 changed files with 5384 additions and 7 deletions
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,55 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* src/proto/grpc/lookup/v1/rls.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#include <stddef.h> |
||||
#include "upb/msg_internal.h" |
||||
#include "src/proto/grpc/lookup/v1/rls.upb.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
static const upb_msglayout *const grpc_lookup_v1_RouteLookupRequest_submsgs[1] = { |
||||
&grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field grpc_lookup_v1_RouteLookupRequest__fields[4] = { |
||||
{3, UPB_SIZE(4, 8), 0, 0, 9, _UPB_MODE_SCALAR}, |
||||
{4, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_MAP}, |
||||
{5, UPB_SIZE(0, 0), 0, 0, 14, _UPB_MODE_SCALAR}, |
||||
{6, UPB_SIZE(12, 24), 0, 0, 9, _UPB_MODE_SCALAR}, |
||||
}; |
||||
|
||||
const upb_msglayout grpc_lookup_v1_RouteLookupRequest_msginit = { |
||||
&grpc_lookup_v1_RouteLookupRequest_submsgs[0], |
||||
&grpc_lookup_v1_RouteLookupRequest__fields[0], |
||||
UPB_SIZE(24, 48), 4, false, 0, 255, |
||||
}; |
||||
|
||||
static const upb_msglayout_field grpc_lookup_v1_RouteLookupRequest_KeyMapEntry__fields[2] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 9, _UPB_MODE_SCALAR}, |
||||
{2, UPB_SIZE(8, 16), 0, 0, 9, _UPB_MODE_SCALAR}, |
||||
}; |
||||
|
||||
const upb_msglayout grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_msginit = { |
||||
NULL, |
||||
&grpc_lookup_v1_RouteLookupRequest_KeyMapEntry__fields[0], |
||||
UPB_SIZE(16, 32), 2, false, 2, 255, |
||||
}; |
||||
|
||||
static const upb_msglayout_field grpc_lookup_v1_RouteLookupResponse__fields[2] = { |
||||
{2, UPB_SIZE(0, 0), 0, 0, 9, _UPB_MODE_SCALAR}, |
||||
{3, UPB_SIZE(8, 16), 0, 0, 9, _UPB_MODE_ARRAY}, |
||||
}; |
||||
|
||||
const upb_msglayout grpc_lookup_v1_RouteLookupResponse_msginit = { |
||||
NULL, |
||||
&grpc_lookup_v1_RouteLookupResponse__fields[0], |
||||
UPB_SIZE(16, 32), 2, false, 0, 255, |
||||
}; |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
@ -0,0 +1,154 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* src/proto/grpc/lookup/v1/rls.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#ifndef SRC_PROTO_GRPC_LOOKUP_V1_RLS_PROTO_UPB_H_ |
||||
#define SRC_PROTO_GRPC_LOOKUP_V1_RLS_PROTO_UPB_H_ |
||||
|
||||
#include "upb/msg_internal.h" |
||||
#include "upb/decode.h" |
||||
#include "upb/decode_fast.h" |
||||
#include "upb/encode.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct grpc_lookup_v1_RouteLookupRequest; |
||||
struct grpc_lookup_v1_RouteLookupRequest_KeyMapEntry; |
||||
struct grpc_lookup_v1_RouteLookupResponse; |
||||
typedef struct grpc_lookup_v1_RouteLookupRequest grpc_lookup_v1_RouteLookupRequest; |
||||
typedef struct grpc_lookup_v1_RouteLookupRequest_KeyMapEntry grpc_lookup_v1_RouteLookupRequest_KeyMapEntry; |
||||
typedef struct grpc_lookup_v1_RouteLookupResponse grpc_lookup_v1_RouteLookupResponse; |
||||
extern const upb_msglayout grpc_lookup_v1_RouteLookupRequest_msginit; |
||||
extern const upb_msglayout grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_msginit; |
||||
extern const upb_msglayout grpc_lookup_v1_RouteLookupResponse_msginit; |
||||
|
||||
typedef enum { |
||||
grpc_lookup_v1_RouteLookupRequest_REASON_UNKNOWN = 0, |
||||
grpc_lookup_v1_RouteLookupRequest_REASON_MISS = 1, |
||||
grpc_lookup_v1_RouteLookupRequest_REASON_STALE = 2 |
||||
} grpc_lookup_v1_RouteLookupRequest_Reason; |
||||
|
||||
|
||||
/* grpc.lookup.v1.RouteLookupRequest */ |
||||
|
||||
UPB_INLINE grpc_lookup_v1_RouteLookupRequest *grpc_lookup_v1_RouteLookupRequest_new(upb_arena *arena) { |
||||
return (grpc_lookup_v1_RouteLookupRequest *)_upb_msg_new(&grpc_lookup_v1_RouteLookupRequest_msginit, arena); |
||||
} |
||||
UPB_INLINE grpc_lookup_v1_RouteLookupRequest *grpc_lookup_v1_RouteLookupRequest_parse(const char *buf, size_t size, |
||||
upb_arena *arena) { |
||||
grpc_lookup_v1_RouteLookupRequest *ret = grpc_lookup_v1_RouteLookupRequest_new(arena); |
||||
if (!ret) return NULL; |
||||
if (!upb_decode(buf, size, ret, &grpc_lookup_v1_RouteLookupRequest_msginit, arena)) return NULL; |
||||
return ret; |
||||
} |
||||
UPB_INLINE grpc_lookup_v1_RouteLookupRequest *grpc_lookup_v1_RouteLookupRequest_parse_ex(const char *buf, size_t size, |
||||
const upb_extreg *extreg, int options, |
||||
upb_arena *arena) { |
||||
grpc_lookup_v1_RouteLookupRequest *ret = grpc_lookup_v1_RouteLookupRequest_new(arena); |
||||
if (!ret) return NULL; |
||||
if (!_upb_decode(buf, size, ret, &grpc_lookup_v1_RouteLookupRequest_msginit, extreg, options, arena)) { |
||||
return NULL; |
||||
} |
||||
return ret; |
||||
} |
||||
UPB_INLINE char *grpc_lookup_v1_RouteLookupRequest_serialize(const grpc_lookup_v1_RouteLookupRequest *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &grpc_lookup_v1_RouteLookupRequest_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE upb_strview grpc_lookup_v1_RouteLookupRequest_target_type(const grpc_lookup_v1_RouteLookupRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } |
||||
UPB_INLINE bool grpc_lookup_v1_RouteLookupRequest_has_key_map(const grpc_lookup_v1_RouteLookupRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } |
||||
UPB_INLINE size_t grpc_lookup_v1_RouteLookupRequest_key_map_size(const grpc_lookup_v1_RouteLookupRequest *msg) {return _upb_msg_map_size(msg, UPB_SIZE(20, 40)); } |
||||
UPB_INLINE bool grpc_lookup_v1_RouteLookupRequest_key_map_get(const grpc_lookup_v1_RouteLookupRequest *msg, upb_strview key, upb_strview *val) { return _upb_msg_map_get(msg, UPB_SIZE(20, 40), &key, 0, val, 0); } |
||||
UPB_INLINE const grpc_lookup_v1_RouteLookupRequest_KeyMapEntry* grpc_lookup_v1_RouteLookupRequest_key_map_next(const grpc_lookup_v1_RouteLookupRequest *msg, size_t* iter) { return (const grpc_lookup_v1_RouteLookupRequest_KeyMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(20, 40), iter); } |
||||
UPB_INLINE int32_t grpc_lookup_v1_RouteLookupRequest_reason(const grpc_lookup_v1_RouteLookupRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); } |
||||
UPB_INLINE upb_strview grpc_lookup_v1_RouteLookupRequest_stale_header_data(const grpc_lookup_v1_RouteLookupRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } |
||||
|
||||
UPB_INLINE void grpc_lookup_v1_RouteLookupRequest_set_target_type(grpc_lookup_v1_RouteLookupRequest *msg, upb_strview value) { |
||||
*UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; |
||||
} |
||||
UPB_INLINE void grpc_lookup_v1_RouteLookupRequest_key_map_clear(grpc_lookup_v1_RouteLookupRequest *msg) { _upb_msg_map_clear(msg, UPB_SIZE(20, 40)); } |
||||
UPB_INLINE bool grpc_lookup_v1_RouteLookupRequest_key_map_set(grpc_lookup_v1_RouteLookupRequest *msg, upb_strview key, upb_strview val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(20, 40), &key, 0, &val, 0, a); } |
||||
UPB_INLINE bool grpc_lookup_v1_RouteLookupRequest_key_map_delete(grpc_lookup_v1_RouteLookupRequest *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(20, 40), &key, 0); } |
||||
UPB_INLINE grpc_lookup_v1_RouteLookupRequest_KeyMapEntry* grpc_lookup_v1_RouteLookupRequest_key_map_nextmutable(grpc_lookup_v1_RouteLookupRequest *msg, size_t* iter) { return (grpc_lookup_v1_RouteLookupRequest_KeyMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(20, 40), iter); } |
||||
UPB_INLINE void grpc_lookup_v1_RouteLookupRequest_set_reason(grpc_lookup_v1_RouteLookupRequest *msg, int32_t value) { |
||||
*UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value; |
||||
} |
||||
UPB_INLINE void grpc_lookup_v1_RouteLookupRequest_set_stale_header_data(grpc_lookup_v1_RouteLookupRequest *msg, upb_strview value) { |
||||
*UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value; |
||||
} |
||||
|
||||
/* grpc.lookup.v1.RouteLookupRequest.KeyMapEntry */ |
||||
|
||||
UPB_INLINE upb_strview grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_key(const grpc_lookup_v1_RouteLookupRequest_KeyMapEntry *msg) { |
||||
upb_strview ret; |
||||
_upb_msg_map_key(msg, &ret, 0); |
||||
return ret; |
||||
} |
||||
UPB_INLINE upb_strview grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_value(const grpc_lookup_v1_RouteLookupRequest_KeyMapEntry *msg) { |
||||
upb_strview ret; |
||||
_upb_msg_map_value(msg, &ret, 0); |
||||
return ret; |
||||
} |
||||
|
||||
UPB_INLINE void grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_set_value(grpc_lookup_v1_RouteLookupRequest_KeyMapEntry *msg, upb_strview value) { |
||||
_upb_msg_map_set_value(msg, &value, 0); |
||||
} |
||||
|
||||
/* grpc.lookup.v1.RouteLookupResponse */ |
||||
|
||||
UPB_INLINE grpc_lookup_v1_RouteLookupResponse *grpc_lookup_v1_RouteLookupResponse_new(upb_arena *arena) { |
||||
return (grpc_lookup_v1_RouteLookupResponse *)_upb_msg_new(&grpc_lookup_v1_RouteLookupResponse_msginit, arena); |
||||
} |
||||
UPB_INLINE grpc_lookup_v1_RouteLookupResponse *grpc_lookup_v1_RouteLookupResponse_parse(const char *buf, size_t size, |
||||
upb_arena *arena) { |
||||
grpc_lookup_v1_RouteLookupResponse *ret = grpc_lookup_v1_RouteLookupResponse_new(arena); |
||||
if (!ret) return NULL; |
||||
if (!upb_decode(buf, size, ret, &grpc_lookup_v1_RouteLookupResponse_msginit, arena)) return NULL; |
||||
return ret; |
||||
} |
||||
UPB_INLINE grpc_lookup_v1_RouteLookupResponse *grpc_lookup_v1_RouteLookupResponse_parse_ex(const char *buf, size_t size, |
||||
const upb_extreg *extreg, int options, |
||||
upb_arena *arena) { |
||||
grpc_lookup_v1_RouteLookupResponse *ret = grpc_lookup_v1_RouteLookupResponse_new(arena); |
||||
if (!ret) return NULL; |
||||
if (!_upb_decode(buf, size, ret, &grpc_lookup_v1_RouteLookupResponse_msginit, extreg, options, arena)) { |
||||
return NULL; |
||||
} |
||||
return ret; |
||||
} |
||||
UPB_INLINE char *grpc_lookup_v1_RouteLookupResponse_serialize(const grpc_lookup_v1_RouteLookupResponse *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &grpc_lookup_v1_RouteLookupResponse_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE upb_strview grpc_lookup_v1_RouteLookupResponse_header_data(const grpc_lookup_v1_RouteLookupResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); } |
||||
UPB_INLINE upb_strview const* grpc_lookup_v1_RouteLookupResponse_targets(const grpc_lookup_v1_RouteLookupResponse *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } |
||||
|
||||
UPB_INLINE void grpc_lookup_v1_RouteLookupResponse_set_header_data(grpc_lookup_v1_RouteLookupResponse *msg, upb_strview value) { |
||||
*UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value; |
||||
} |
||||
UPB_INLINE upb_strview* grpc_lookup_v1_RouteLookupResponse_mutable_targets(grpc_lookup_v1_RouteLookupResponse *msg, size_t *len) { |
||||
return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); |
||||
} |
||||
UPB_INLINE upb_strview* grpc_lookup_v1_RouteLookupResponse_resize_targets(grpc_lookup_v1_RouteLookupResponse *msg, size_t len, upb_arena *arena) { |
||||
return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(3, 4), arena); |
||||
} |
||||
UPB_INLINE bool grpc_lookup_v1_RouteLookupResponse_add_targets(grpc_lookup_v1_RouteLookupResponse *msg, upb_strview val, upb_arena *arena) { |
||||
return _upb_array_append_accessor2(msg, UPB_SIZE(8, 16), UPB_SIZE(3, 4), &val, |
||||
arena); |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* SRC_PROTO_GRPC_LOOKUP_V1_RLS_PROTO_UPB_H_ */ |
@ -0,0 +1,63 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* src/proto/grpc/lookup/v1/rls.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#include "upb/def.h" |
||||
#include "src/proto/grpc/lookup/v1/rls.upbdefs.h" |
||||
|
||||
extern const upb_msglayout grpc_lookup_v1_RouteLookupRequest_msginit; |
||||
extern const upb_msglayout grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_msginit; |
||||
extern const upb_msglayout grpc_lookup_v1_RouteLookupResponse_msginit; |
||||
|
||||
static const upb_msglayout *layouts[3] = { |
||||
&grpc_lookup_v1_RouteLookupRequest_msginit, |
||||
&grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_msginit, |
||||
&grpc_lookup_v1_RouteLookupResponse_msginit, |
||||
}; |
||||
|
||||
static const char descriptor[737] = {'\n', '\"', 's', 'r', 'c', '/', 'p', 'r', 'o', 't', 'o', '/', 'g', 'r', 'p', 'c', '/', 'l', 'o', 'o', 'k', 'u', 'p', '/', 'v',
|
||||
'1', '/', 'r', 'l', 's', '.', 'p', 'r', 'o', 't', 'o', '\022', '\016', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.',
|
||||
'v', '1', '\"', '\203', '\003', '\n', '\022', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o', 'k', 'u', 'p', 'R', 'e', 'q', 'u', 'e', 's', 't',
|
||||
'\022', '\037', '\n', '\013', 't', 'a', 'r', 'g', 'e', 't', '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\n', 't', 'a',
|
||||
'r', 'g', 'e', 't', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\006', 'r', 'e', 'a', 's', 'o', 'n', '\030', '\005', ' ', '\001', '(', '\016', '2',
|
||||
')', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o',
|
||||
'k', 'u', 'p', 'R', 'e', 'q', 'u', 'e', 's', 't', '.', 'R', 'e', 'a', 's', 'o', 'n', 'R', '\006', 'r', 'e', 'a', 's', 'o', 'n',
|
||||
'\022', '*', '\n', '\021', 's', 't', 'a', 'l', 'e', '_', 'h', 'e', 'a', 'd', 'e', 'r', '_', 'd', 'a', 't', 'a', '\030', '\006', ' ', '\001',
|
||||
'(', '\t', 'R', '\017', 's', 't', 'a', 'l', 'e', 'H', 'e', 'a', 'd', 'e', 'r', 'D', 'a', 't', 'a', '\022', 'G', '\n', '\007', 'k', 'e',
|
||||
'y', '_', 'm', 'a', 'p', '\030', '\004', ' ', '\003', '(', '\013', '2', '.', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p',
|
||||
'.', 'v', '1', '.', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o', 'k', 'u', 'p', 'R', 'e', 'q', 'u', 'e', 's', 't', '.', 'K', 'e',
|
||||
'y', 'M', 'a', 'p', 'E', 'n', 't', 'r', 'y', 'R', '\006', 'k', 'e', 'y', 'M', 'a', 'p', '\032', '9', '\n', '\013', 'K', 'e', 'y', 'M',
|
||||
'a', 'p', 'E', 'n', 't', 'r', 'y', '\022', '\020', '\n', '\003', 'k', 'e', 'y', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\003', 'k', 'e', 'y',
|
||||
'\022', '\024', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\005', 'v', 'a', 'l', 'u', 'e', ':', '\002', '8',
|
||||
'\001', '\"', '?', '\n', '\006', 'R', 'e', 'a', 's', 'o', 'n', '\022', '\022', '\n', '\016', 'R', 'E', 'A', 'S', 'O', 'N', '_', 'U', 'N', 'K',
|
||||
'N', 'O', 'W', 'N', '\020', '\000', '\022', '\017', '\n', '\013', 'R', 'E', 'A', 'S', 'O', 'N', '_', 'M', 'I', 'S', 'S', '\020', '\001', '\022', '\020',
|
||||
'\n', '\014', 'R', 'E', 'A', 'S', 'O', 'N', '_', 'S', 'T', 'A', 'L', 'E', '\020', '\002', 'J', '\004', '\010', '\001', '\020', '\002', 'J', '\004', '\010',
|
||||
'\002', '\020', '\003', 'R', '\006', 's', 'e', 'r', 'v', 'e', 'r', 'R', '\004', 'p', 'a', 't', 'h', '\"', '^', '\n', '\023', 'R', 'o', 'u', 't',
|
||||
'e', 'L', 'o', 'o', 'k', 'u', 'p', 'R', 'e', 's', 'p', 'o', 'n', 's', 'e', '\022', '\030', '\n', '\007', 't', 'a', 'r', 'g', 'e', 't',
|
||||
's', '\030', '\003', ' ', '\003', '(', '\t', 'R', '\007', 't', 'a', 'r', 'g', 'e', 't', 's', '\022', '\037', '\n', '\013', 'h', 'e', 'a', 'd', 'e',
|
||||
'r', '_', 'd', 'a', 't', 'a', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 'h', 'e', 'a', 'd', 'e', 'r', 'D', 'a', 't', 'a', 'J',
|
||||
'\004', '\010', '\001', '\020', '\002', 'R', '\006', 't', 'a', 'r', 'g', 'e', 't', '2', 'n', '\n', '\022', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o',
|
||||
'k', 'u', 'p', 'S', 'e', 'r', 'v', 'i', 'c', 'e', '\022', 'X', '\n', '\013', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o', 'k', 'u', 'p',
|
||||
'\022', '\"', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'R', 'o', 'u', 't', 'e', 'L', 'o',
|
||||
'o', 'k', 'u', 'p', 'R', 'e', 'q', 'u', 'e', 's', 't', '\032', '#', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p',
|
||||
'.', 'v', '1', '.', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o', 'k', 'u', 'p', 'R', 'e', 's', 'p', 'o', 'n', 's', 'e', '\"', '\000',
|
||||
'B', 'M', '\n', '\021', 'i', 'o', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', 'B', '\010', 'R', 'l',
|
||||
's', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', ',', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o',
|
||||
'r', 'g', '/', 'g', 'r', 'p', 'c', '/', 'l', 'o', 'o', 'k', 'u', 'p', '/', 'g', 'r', 'p', 'c', '_', 'l', 'o', 'o', 'k', 'u',
|
||||
'p', '_', 'v', '1', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3',
|
||||
}; |
||||
|
||||
static upb_def_init *deps[1] = { |
||||
NULL |
||||
}; |
||||
|
||||
upb_def_init src_proto_grpc_lookup_v1_rls_proto_upbdefinit = { |
||||
deps, |
||||
layouts, |
||||
"src/proto/grpc/lookup/v1/rls.proto", |
||||
UPB_STRVIEW_INIT(descriptor, 737) |
||||
}; |
@ -0,0 +1,45 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* src/proto/grpc/lookup/v1/rls.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#ifndef SRC_PROTO_GRPC_LOOKUP_V1_RLS_PROTO_UPBDEFS_H_ |
||||
#define SRC_PROTO_GRPC_LOOKUP_V1_RLS_PROTO_UPBDEFS_H_ |
||||
|
||||
#include "upb/def.h" |
||||
#include "upb/port_def.inc" |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#include "upb/def.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
extern upb_def_init src_proto_grpc_lookup_v1_rls_proto_upbdefinit; |
||||
|
||||
UPB_INLINE const upb_msgdef *grpc_lookup_v1_RouteLookupRequest_getmsgdef(upb_symtab *s) { |
||||
_upb_symtab_loaddefinit(s, &src_proto_grpc_lookup_v1_rls_proto_upbdefinit); |
||||
return upb_symtab_lookupmsg(s, "grpc.lookup.v1.RouteLookupRequest"); |
||||
} |
||||
|
||||
UPB_INLINE const upb_msgdef *grpc_lookup_v1_RouteLookupRequest_KeyMapEntry_getmsgdef(upb_symtab *s) { |
||||
_upb_symtab_loaddefinit(s, &src_proto_grpc_lookup_v1_rls_proto_upbdefinit); |
||||
return upb_symtab_lookupmsg(s, "grpc.lookup.v1.RouteLookupRequest.KeyMapEntry"); |
||||
} |
||||
|
||||
UPB_INLINE const upb_msgdef *grpc_lookup_v1_RouteLookupResponse_getmsgdef(upb_symtab *s) { |
||||
_upb_symtab_loaddefinit(s, &src_proto_grpc_lookup_v1_rls_proto_upbdefinit); |
||||
return upb_symtab_lookupmsg(s, "grpc.lookup.v1.RouteLookupResponse"); |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* SRC_PROTO_GRPC_LOOKUP_V1_RLS_PROTO_UPBDEFS_H_ */ |
@ -0,0 +1,28 @@ |
||||
# Copyright 2020 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
licenses(["notice"]) |
||||
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_package", "grpc_proto_library") |
||||
|
||||
grpc_package( |
||||
name = "src/proto/grpc/lookup/v1", |
||||
visibility = "public", |
||||
) |
||||
|
||||
grpc_proto_library( |
||||
name = "rls_proto", |
||||
srcs = ["rls.proto"], |
||||
well_known_protos = True, |
||||
) |
@ -0,0 +1,62 @@ |
||||
// Copyright 2020 The gRPC Authors |
||||
// |
||||
// Licensed under the Apache License, Version 2.0 (the "License"); |
||||
// you may not use this file except in compliance with the License. |
||||
// You may obtain a copy of the License at |
||||
// |
||||
// http://www.apache.org/licenses/LICENSE-2.0 |
||||
// |
||||
// Unless required by applicable law or agreed to in writing, software |
||||
// distributed under the License is distributed on an "AS IS" BASIS, |
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
// See the License for the specific language governing permissions and |
||||
// limitations under the License. |
||||
|
||||
syntax = "proto3"; |
||||
|
||||
package grpc.lookup.v1; |
||||
|
||||
option go_package = "google.golang.org/grpc/lookup/grpc_lookup_v1"; |
||||
option java_multiple_files = true; |
||||
option java_package = "io.grpc.lookup.v1"; |
||||
option java_outer_classname = "RlsProto"; |
||||
|
||||
message RouteLookupRequest { |
||||
// Target type allows the client to specify what kind of target format it |
||||
// would like from RLS to allow it to find the regional server, e.g. "grpc". |
||||
string target_type = 3; |
||||
// Possible reasons for making a request. |
||||
enum Reason { |
||||
REASON_UNKNOWN = 0; // Unused |
||||
REASON_MISS = 1; // No data available in local cache |
||||
REASON_STALE = 2; // Data in local cache is stale |
||||
} |
||||
// Reason for making this request. |
||||
Reason reason = 5; |
||||
// For REASON_STALE, the header_data from the stale response, if any. |
||||
string stale_header_data = 6; |
||||
// Map of key values extracted via key builders for the gRPC or HTTP request. |
||||
map<string, string> key_map = 4; |
||||
|
||||
reserved 1, 2; |
||||
reserved "server", "path"; |
||||
} |
||||
|
||||
message RouteLookupResponse { |
||||
// Prioritized list (best one first) of addressable entities to use |
||||
// for routing, using syntax requested by the request target_type. |
||||
// The targets will be tried in order until a healthy one is found. |
||||
repeated string targets = 3; |
||||
// Optional header value to pass along to AFE in the X-Google-RLS-Data header. |
||||
// Cached with "target" and sent with all requests that match the request key. |
||||
// Allows the RLS to pass its work product to the eventual target. |
||||
string header_data = 2; |
||||
|
||||
reserved 1; |
||||
reserved "target"; |
||||
} |
||||
|
||||
service RouteLookupService { |
||||
// Lookup returns a target for a single key. |
||||
rpc RouteLookup(RouteLookupRequest) returns (RouteLookupResponse) {} |
||||
} |
@ -0,0 +1,550 @@ |
||||
//
|
||||
// Copyright 2021 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include <gmock/gmock.h> |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include <grpc/grpc.h> |
||||
|
||||
#include "src/core/ext/service_config/service_config.h" |
||||
#include "src/core/lib/gpr/env.h" |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
// A regular expression to enter referenced or child errors.
|
||||
#ifdef GRPC_ERROR_IS_ABSEIL_STATUS |
||||
#define CHILD_ERROR_TAG ".*children.*" |
||||
#else |
||||
#define CHILD_ERROR_TAG ".*referenced_errors.*" |
||||
#endif |
||||
|
||||
namespace grpc_core { |
||||
namespace { |
||||
|
||||
class RlsConfigParsingTest : public ::testing::Test { |
||||
public: |
||||
static void SetUpTestSuite() { |
||||
gpr_setenv("GRPC_EXPERIMENTAL_ENABLE_RLS_LB_POLICY", "true"); |
||||
grpc_init(); |
||||
} |
||||
|
||||
static void TearDownTestSuite() { |
||||
grpc_shutdown_blocking(); |
||||
gpr_unsetenv("GRPC_EXPERIMENTAL_ENABLE_RLS_LB_POLICY"); |
||||
} |
||||
}; |
||||
|
||||
TEST_F(RlsConfigParsingTest, ValidConfig) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"lookupService\":\"rls.example.com:80\",\n" |
||||
" \"cacheSizeBytes\":1,\n" |
||||
" \"grpcKeybuilders\":[\n" |
||||
" {\n" |
||||
" \"names\":[\n" |
||||
" {\"service\":\"foo\"}\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" },\n" |
||||
" \"childPolicy\":[\n" |
||||
" {\"unknown\":{}},\n" // Okay, since the next one exists.
|
||||
" {\"grpclb\":{}}\n" |
||||
" ],\n" |
||||
" \"childPolicyConfigTargetFieldName\":\"target\"\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error); |
||||
EXPECT_NE(service_config, nullptr); |
||||
} |
||||
|
||||
//
|
||||
// top-level fields
|
||||
//
|
||||
|
||||
TEST_F(RlsConfigParsingTest, TopLevelRequiredFieldsMissing) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig error:does not exist.*" |
||||
"field:childPolicyConfigTargetFieldName error:does not exist.*" |
||||
"field:childPolicy error:does not exist")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, TopLevelFieldsWrongTypes) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":1,\n" |
||||
" \"childPolicy\":1,\n" |
||||
" \"childPolicyConfigTargetFieldName\":1\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig error:type should be OBJECT.*" |
||||
"field:childPolicyConfigTargetFieldName error:type should be STRING.*" |
||||
"field:childPolicy error:type should be ARRAY")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, TopLevelFieldsInvalidValues) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"childPolicy\":[\n" |
||||
" {\"unknown\":{}}\n" |
||||
" ],\n" |
||||
" \"childPolicyConfigTargetFieldName\":\"\"\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:childPolicyConfigTargetFieldName error:must be non-empty.*" |
||||
"field:childPolicy" CHILD_ERROR_TAG |
||||
"No known policies in list: unknown")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, InvalidChildPolicyConfig) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"childPolicy\":[\n" |
||||
" {\"grpclb\":{\"childPolicy\":1}}\n" |
||||
" ],\n" |
||||
" \"childPolicyConfigTargetFieldName\":\"serviceName\"\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:childPolicy" CHILD_ERROR_TAG "GrpcLb Parser" CHILD_ERROR_TAG |
||||
"field:childPolicy" CHILD_ERROR_TAG "type should be array")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
//
|
||||
// routeLookupConfig fields
|
||||
//
|
||||
|
||||
TEST_F(RlsConfigParsingTest, RouteLookupConfigRequiredFieldsMissing) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT(grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders error:does not exist.*" |
||||
"field:lookupService error:does not exist")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsWrongTypes) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"grpcKeybuilders\":1,\n" |
||||
" \"name\":1,\n" |
||||
" \"lookupService\":1,\n" |
||||
" \"lookupServiceTimeout\":{},\n" |
||||
" \"maxAge\":{},\n" |
||||
" \"staleAge\":{},\n" |
||||
" \"cacheSizeBytes\":\"xxx\",\n" |
||||
" \"defaultTarget\":1\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT(grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders error:type should be ARRAY.*" |
||||
"field:lookupService error:type should be STRING.*" |
||||
"field:maxAge error:type should be STRING.*" |
||||
"field:staleAge error:type should be STRING.*" |
||||
"field:cacheSizeBytes error:type should be NUMBER.*" |
||||
"field:defaultTarget error:type should be STRING")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsInvalidValues) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"lookupService\":\"\",\n" |
||||
" \"cacheSizeBytes\":0\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT(grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:lookupService error:must be valid gRPC target URI.*" |
||||
"field:cacheSizeBytes error:must be greater than 0")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
//
|
||||
// grpcKeybuilder fields
|
||||
//
|
||||
|
||||
TEST_F(RlsConfigParsingTest, GrpcKeybuilderRequiredFieldsMissing) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"grpcKeybuilders\":[\n" |
||||
" {\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG |
||||
"field:names error:does not exist")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, GrpcKeybuilderWrongFieldTypes) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"grpcKeybuilders\":[\n" |
||||
" {\n" |
||||
" \"names\":1,\n" |
||||
" \"headers\":1,\n" |
||||
" \"extraKeys\":1,\n" |
||||
" \"constantKeys\":1\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG |
||||
"field:names error:type should be ARRAY.*" |
||||
"field:headers error:type should be ARRAY.*" |
||||
"field:extraKeys error:type should be OBJECT.*" |
||||
"field:constantKeys error:type should be OBJECT")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidValues) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"grpcKeybuilders\":[\n" |
||||
" {\n" |
||||
" \"names\":[],\n" |
||||
" \"extraKeys\":{\n" |
||||
" \"host\":1,\n" |
||||
" \"service\":1,\n" |
||||
" \"method\":1\n" |
||||
" },\n" |
||||
" \"constantKeys\":{\n" |
||||
" \"key\":1\n" |
||||
" }\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT(grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders" CHILD_ERROR_TAG |
||||
"index:0" CHILD_ERROR_TAG "field:names error:list is empty.*" |
||||
"field:extraKeys" CHILD_ERROR_TAG |
||||
"field:host error:type should be STRING.*" |
||||
"field:service error:type should be STRING.*" |
||||
"field:method error:type should be STRING.*" |
||||
"field:constantKeys" CHILD_ERROR_TAG |
||||
"field:key error:type should be STRING")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidHeaders) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"grpcKeybuilders\":[\n" |
||||
" {\n" |
||||
" \"headers\":[\n" |
||||
" 1,\n" |
||||
" {\n" |
||||
" \"key\":1,\n" |
||||
" \"names\":1\n" |
||||
" },\n" |
||||
" {\n" |
||||
" \"names\":[]\n" |
||||
" },\n" |
||||
" {\n" |
||||
" \"key\":\"\",\n" |
||||
" \"names\":[1, \"\"]\n" |
||||
" }\n" |
||||
" ],\n" |
||||
" \"extraKeys\":{\n" |
||||
" \"host\": \"\"\n" |
||||
" },\n" |
||||
" \"constantKeys\":{\n" |
||||
" \"\":\"foo\"\n" |
||||
" }\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG |
||||
"field:headers index:0 error:type should be OBJECT.*" |
||||
"field:headers index:1" CHILD_ERROR_TAG |
||||
"field:key error:type should be STRING.*" |
||||
"field:names error:type should be ARRAY.*" |
||||
"field:headers index:2" CHILD_ERROR_TAG |
||||
"field:key error:does not exist.*" |
||||
"field:names error:list is empty.*" |
||||
"field:headers index:3" CHILD_ERROR_TAG |
||||
"field:key error:must be non-empty.*" |
||||
"field:names index:0 error:type should be STRING.*" |
||||
"field:names index:1 error:header name must be non-empty.*" |
||||
"field:extraKeys" CHILD_ERROR_TAG |
||||
"field:host error:must be non-empty.*" |
||||
"field:constantKeys" CHILD_ERROR_TAG "error:keys must be non-empty")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, GrpcKeybuilderNameWrongFieldTypes) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"grpcKeybuilders\":[\n" |
||||
" {\n" |
||||
" \"names\":[\n" |
||||
" 1,\n" |
||||
" {\n" |
||||
" \"service\":1,\n" |
||||
" \"method\":1\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG |
||||
"field:names index:0 error:type should be OBJECT.*" |
||||
"field:names index:1" CHILD_ERROR_TAG |
||||
"field:service error:type should be STRING.*" |
||||
"field:method error:type should be STRING")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInSameKeyBuilder) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"grpcKeybuilders\":[\n" |
||||
" {\n" |
||||
" \"names\":[\n" |
||||
" {\n" |
||||
" \"service\":\"foo\",\n" |
||||
" \"method\":\"bar\"\n" |
||||
" },\n" |
||||
" {\n" |
||||
" \"service\":\"foo\",\n" |
||||
" \"method\":\"bar\"\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG |
||||
"field:names error:duplicate entry for /foo/bar")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInDifferentKeyBuilders) { |
||||
const char* service_config_json = |
||||
"{\n" |
||||
" \"loadBalancingConfig\":[{\n" |
||||
" \"rls\":{\n" |
||||
" \"routeLookupConfig\":{\n" |
||||
" \"grpcKeybuilders\":[\n" |
||||
" {\n" |
||||
" \"names\":[\n" |
||||
" {\n" |
||||
" \"service\":\"foo\",\n" |
||||
" \"method\":\"bar\"\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" },\n" |
||||
" {\n" |
||||
" \"names\":[\n" |
||||
" {\n" |
||||
" \"service\":\"foo\",\n" |
||||
" \"method\":\"bar\"\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" ]\n" |
||||
" }\n" |
||||
" }\n" |
||||
" }]\n" |
||||
"}\n"; |
||||
grpc_error_handle error = GRPC_ERROR_NONE; |
||||
auto service_config = ServiceConfig::Create( |
||||
/*args=*/nullptr, service_config_json, &error); |
||||
EXPECT_THAT( |
||||
grpc_error_std_string(error), |
||||
::testing::ContainsRegex( |
||||
"errors parsing RLS LB policy config" CHILD_ERROR_TAG |
||||
"field:routeLookupConfig" CHILD_ERROR_TAG |
||||
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:1" CHILD_ERROR_TAG |
||||
"field:names error:duplicate entry for /foo/bar")); |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
} // namespace
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) { |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
grpc::testing::TestEnvironment env(argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue