diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/libs/grpc/test | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'contrib/libs/grpc/test')
105 files changed, 0 insertions, 31649 deletions
diff --git a/contrib/libs/grpc/test/core/util/.yandex_meta/licenses.list.txt b/contrib/libs/grpc/test/core/util/.yandex_meta/licenses.list.txt deleted file mode 100644 index b31c8995b8..0000000000 --- a/contrib/libs/grpc/test/core/util/.yandex_meta/licenses.list.txt +++ /dev/null @@ -1,72 +0,0 @@ -====================Apache-2.0==================== - * 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. - - -====================Apache-2.0==================== -# 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. - - -====================Apache-2.0==================== -// 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. - - -====================COPYRIGHT==================== - * Copyright 2015 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2015-2016 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2016 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2017 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2018 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2020 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2020 the gRPC authors. - - -====================COPYRIGHT==================== -// Copyright 2021 gRPC authors. diff --git a/contrib/libs/grpc/test/core/util/cmdline.cc b/contrib/libs/grpc/test/core/util/cmdline.cc deleted file mode 100644 index c031ef8b4c..0000000000 --- a/contrib/libs/grpc/test/core/util/cmdline.cc +++ /dev/null @@ -1,321 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/util/cmdline.h" - -#include <limits.h> -#include <stdio.h> -#include <string.h> - -#include <vector> - -#include "y_absl/strings/str_cat.h" -#include "y_absl/strings/str_format.h" -#include "y_absl/strings/str_join.h" - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> - -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/memory.h" - -typedef enum { ARGTYPE_INT, ARGTYPE_BOOL, ARGTYPE_STRING } argtype; - -typedef struct arg { - const char* name; - const char* help; - argtype type; - void* value; - struct arg* next; -} arg; - -struct gpr_cmdline { - const char* description; - arg* args; - const char* argv0; - - const char* extra_arg_name; - const char* extra_arg_help; - void (*extra_arg)(void* user_data, const char* arg); - void* extra_arg_user_data; - - int (*state)(gpr_cmdline* cl, char* arg); - arg* cur_arg; - - int survive_failure; -}; - -static int normal_state(gpr_cmdline* cl, char* str); - -gpr_cmdline* gpr_cmdline_create(const char* description) { - gpr_cmdline* cl = grpc_core::Zalloc<gpr_cmdline>(); - - cl->description = description; - cl->state = normal_state; - - return cl; -} - -void gpr_cmdline_set_survive_failure(gpr_cmdline* cl) { - cl->survive_failure = 1; -} - -void gpr_cmdline_destroy(gpr_cmdline* cl) { - while (cl->args) { - arg* a = cl->args; - cl->args = a->next; - gpr_free(a); - } - gpr_free(cl); -} - -static void add_arg(gpr_cmdline* cl, const char* name, const char* help, - argtype type, void* value) { - arg* a; - - for (a = cl->args; a; a = a->next) { - GPR_ASSERT(0 != strcmp(a->name, name)); - } - - a = static_cast<arg*>(gpr_zalloc(sizeof(arg))); - a->name = name; - a->help = help; - a->type = type; - a->value = value; - a->next = cl->args; - cl->args = a; -} - -void gpr_cmdline_add_int(gpr_cmdline* cl, const char* name, const char* help, - int* value) { - add_arg(cl, name, help, ARGTYPE_INT, value); -} - -void gpr_cmdline_add_flag(gpr_cmdline* cl, const char* name, const char* help, - int* value) { - add_arg(cl, name, help, ARGTYPE_BOOL, value); -} - -void gpr_cmdline_add_string(gpr_cmdline* cl, const char* name, const char* help, - const char** value) { - add_arg(cl, name, help, ARGTYPE_STRING, value); -} - -void gpr_cmdline_on_extra_arg( - gpr_cmdline* cl, const char* name, const char* help, - void (*on_extra_arg)(void* user_data, const char* arg), void* user_data) { - GPR_ASSERT(!cl->extra_arg); - GPR_ASSERT(on_extra_arg); - - cl->extra_arg = on_extra_arg; - cl->extra_arg_user_data = user_data; - cl->extra_arg_name = name; - cl->extra_arg_help = help; -} - -/* recursively descend argument list, adding the last element - to s first - so that arguments are added in the order they were - added to the list by api calls */ -static void add_args_to_usage(arg* a, std::vector<TString>* s) { - if (a == nullptr) return; - add_args_to_usage(a->next, s); - switch (a->type) { - case ARGTYPE_BOOL: - s->push_back(y_absl::StrFormat(" [--%s|--no-%s]", a->name, a->name)); - break; - case ARGTYPE_STRING: - s->push_back(y_absl::StrFormat(" [--%s=string]", a->name)); - break; - case ARGTYPE_INT: - s->push_back(y_absl::StrFormat(" [--%s=int]", a->name)); - break; - } -} - -TString gpr_cmdline_usage_string(gpr_cmdline* cl, const char* argv0) { - const char* name = strrchr(argv0, '/'); - if (name != nullptr) { - name++; - } else { - name = argv0; - } - - std::vector<TString> s; - s.push_back(y_absl::StrCat("Usage: ", name)); - add_args_to_usage(cl->args, &s); - if (cl->extra_arg) { - s.push_back(y_absl::StrFormat(" [%s...]", cl->extra_arg_name)); - } - s.push_back("\n"); - return y_absl::StrJoin(s, ""); -} - -static int print_usage_and_die(gpr_cmdline* cl) { - fprintf(stderr, "%s", gpr_cmdline_usage_string(cl, cl->argv0).c_str()); - if (!cl->survive_failure) { - exit(1); - } - return 0; -} - -static int extra_state(gpr_cmdline* cl, char* str) { - if (!cl->extra_arg) { - return print_usage_and_die(cl); - } - cl->extra_arg(cl->extra_arg_user_data, str); - return 1; -} - -static arg* find_arg(gpr_cmdline* cl, char* name) { - arg* a; - - for (a = cl->args; a; a = a->next) { - if (0 == strcmp(a->name, name)) { - break; - } - } - - if (!a) { - fprintf(stderr, "Unknown argument: %s\n", name); - return nullptr; - } - - return a; -} - -static int value_state(gpr_cmdline* cl, char* str) { - long intval; - char* end; - - GPR_ASSERT(cl->cur_arg); - - switch (cl->cur_arg->type) { - case ARGTYPE_INT: - intval = strtol(str, &end, 0); - if (*end || intval < INT_MIN || intval > INT_MAX) { - fprintf(stderr, "expected integer, got '%s' for %s\n", str, - cl->cur_arg->name); - return print_usage_and_die(cl); - } - *static_cast<int*>(cl->cur_arg->value) = static_cast<int>(intval); - break; - case ARGTYPE_BOOL: - if (0 == strcmp(str, "1") || 0 == strcmp(str, "true")) { - *static_cast<int*>(cl->cur_arg->value) = 1; - } else if (0 == strcmp(str, "0") || 0 == strcmp(str, "false")) { - *static_cast<int*>(cl->cur_arg->value) = 0; - } else { - fprintf(stderr, "expected boolean, got '%s' for %s\n", str, - cl->cur_arg->name); - return print_usage_and_die(cl); - } - break; - case ARGTYPE_STRING: - *static_cast<char**>(cl->cur_arg->value) = str; - break; - } - - cl->state = normal_state; - return 1; -} - -static int normal_state(gpr_cmdline* cl, char* str) { - char* eq = nullptr; - char* tmp = nullptr; - char* arg_name = nullptr; - int r = 1; - - if (0 == strcmp(str, "-help") || 0 == strcmp(str, "--help") || - 0 == strcmp(str, "-h")) { - return print_usage_and_die(cl); - } - - cl->cur_arg = nullptr; - - if (str[0] == '-') { - if (str[1] == '-') { - if (str[2] == 0) { - /* handle '--' to move to just extra args */ - cl->state = extra_state; - return 1; - } - str += 2; - } else { - str += 1; - } - /* first byte of str is now past the leading '-' or '--' */ - if (str[0] == 'n' && str[1] == 'o' && str[2] == '-') { - /* str is of the form '--no-foo' - it's a flag disable */ - str += 3; - cl->cur_arg = find_arg(cl, str); - if (cl->cur_arg == nullptr) { - return print_usage_and_die(cl); - } - if (cl->cur_arg->type != ARGTYPE_BOOL) { - fprintf(stderr, "%s is not a flag argument\n", str); - return print_usage_and_die(cl); - } - *static_cast<int*>(cl->cur_arg->value) = 0; - return 1; /* early out */ - } - eq = strchr(str, '='); - if (eq != nullptr) { - /* copy the string into a temp buffer and extract the name */ - tmp = arg_name = - static_cast<char*>(gpr_malloc(static_cast<size_t>(eq - str + 1))); - memcpy(arg_name, str, static_cast<size_t>(eq - str)); - arg_name[eq - str] = 0; - } else { - arg_name = str; - } - cl->cur_arg = find_arg(cl, arg_name); - if (cl->cur_arg == nullptr) { - return print_usage_and_die(cl); - } - if (eq != nullptr) { - /* str was of the type --foo=value, parse the value */ - r = value_state(cl, eq + 1); - } else if (cl->cur_arg->type != ARGTYPE_BOOL) { - /* flag types don't have a '--foo value' variant, other types do */ - cl->state = value_state; - } else { - /* flag parameter: just set the value */ - *static_cast<int*>(cl->cur_arg->value) = 1; - } - } else { - r = extra_state(cl, str); - } - - gpr_free(tmp); - return r; -} - -int gpr_cmdline_parse(gpr_cmdline* cl, int argc, char** argv) { - int i; - - GPR_ASSERT(argc >= 1); - cl->argv0 = argv[0]; - - for (i = 1; i < argc; i++) { - if (!cl->state(cl, argv[i])) { - return 0; - } - } - return 1; -} diff --git a/contrib/libs/grpc/test/core/util/cmdline.h b/contrib/libs/grpc/test/core/util/cmdline.h deleted file mode 100644 index cc75a8974e..0000000000 --- a/contrib/libs/grpc/test/core/util/cmdline.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_CMDLINE_H -#define GRPC_TEST_CORE_UTIL_CMDLINE_H - -#include <grpc/support/port_platform.h> - -#include <util/generic/string.h> - -/** Simple command line parser. - - Supports flags that can be specified as -foo, --foo, --no-foo, -no-foo, etc - And integers, strings that can be specified as -foo=4, -foo blah, etc - - No support for short command line options (but we may get that in the - future.) - - Usage (for a program with a single flag argument 'foo'): - - int main(int argc, char **argv) { - gpr_cmdline *cl; - int verbose = 0; - - cl = gpr_cmdline_create("My cool tool"); - gpr_cmdline_add_int(cl, "verbose", "Produce verbose output?", &verbose); - gpr_cmdline_parse(cl, argc, argv); - gpr_cmdline_destroy(cl); - - if (verbose) { - gpr_log(GPR_INFO, "Goodbye cruel world!"); - } - - return 0; - } */ - -typedef struct gpr_cmdline gpr_cmdline; - -/** Construct a command line parser: takes a short description of the tool - doing the parsing */ -gpr_cmdline* gpr_cmdline_create(const char* description); -/** Add an integer parameter, with a name (used on the command line) and some - helpful text (used in the command usage) */ -void gpr_cmdline_add_int(gpr_cmdline* cl, const char* name, const char* help, - int* value); -/** The same, for a boolean flag */ -void gpr_cmdline_add_flag(gpr_cmdline* cl, const char* name, const char* help, - int* value); -/** And for a string */ -void gpr_cmdline_add_string(gpr_cmdline* cl, const char* name, const char* help, - const char** value); -/** Set a callback for non-named arguments */ -void gpr_cmdline_on_extra_arg( - gpr_cmdline* cl, const char* name, const char* help, - void (*on_extra_arg)(void* user_data, const char* arg), void* user_data); -/** Enable surviving failure: default behavior is to exit the process */ -void gpr_cmdline_set_survive_failure(gpr_cmdline* cl); -/** Parse the command line; returns 1 on success, on failure either dies - (by default) or returns 0 if gpr_cmdline_set_survive_failure() has been - called */ -int gpr_cmdline_parse(gpr_cmdline* cl, int argc, char** argv); -/** Destroy the parser */ -void gpr_cmdline_destroy(gpr_cmdline* cl); -/** Get a string describing usage */ -TString gpr_cmdline_usage_string(gpr_cmdline* cl, const char* argv0); - -#endif /* GRPC_TEST_CORE_UTIL_CMDLINE_H */ diff --git a/contrib/libs/grpc/test/core/util/cmdline_test.cc b/contrib/libs/grpc/test/core/util/cmdline_test.cc deleted file mode 100644 index 32f9a156a1..0000000000 --- a/contrib/libs/grpc/test/core/util/cmdline_test.cc +++ /dev/null @@ -1,494 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/util/cmdline.h" - -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> - -#include "src/core/lib/gpr/useful.h" -#include "test/core/util/test_config.h" - -#define LOG_TEST() gpr_log(GPR_INFO, "test at %s:%d", __FILE__, __LINE__) - -static void test_simple_int(void) { - int x = 1; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("-foo"), - const_cast<char*>("3")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_int(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 1); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 3); - gpr_cmdline_destroy(cl); -} - -static void test_eq_int(void) { - int x = 1; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("-foo=3")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_int(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 1); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 3); - gpr_cmdline_destroy(cl); -} - -static void test_2dash_int(void) { - int x = 1; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo"), - const_cast<char*>("3")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_int(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 1); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 3); - gpr_cmdline_destroy(cl); -} - -static void test_2dash_eq_int(void) { - int x = 1; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=3")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_int(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 1); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 3); - gpr_cmdline_destroy(cl); -} - -static void test_simple_string(void) { - const char* x = nullptr; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("-foo"), - const_cast<char*>("3")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_string(cl, "foo", nullptr, &x); - GPR_ASSERT(x == nullptr); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(0 == strcmp(x, "3")); - gpr_cmdline_destroy(cl); -} - -static void test_eq_string(void) { - const char* x = nullptr; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("-foo=3")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_string(cl, "foo", nullptr, &x); - GPR_ASSERT(x == nullptr); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(0 == strcmp(x, "3")); - gpr_cmdline_destroy(cl); -} - -static void test_2dash_string(void) { - const char* x = nullptr; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo"), - const_cast<char*>("3")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_string(cl, "foo", nullptr, &x); - GPR_ASSERT(x == nullptr); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(0 == strcmp(x, "3")); - gpr_cmdline_destroy(cl); -} - -static void test_2dash_eq_string(void) { - const char* x = nullptr; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=3")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_string(cl, "foo", nullptr, &x); - GPR_ASSERT(x == nullptr); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(0 == strcmp(x, "3")); - gpr_cmdline_destroy(cl); -} - -static void test_flag_on(void) { - int x = 2; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_flag(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 2); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 1); - gpr_cmdline_destroy(cl); -} - -static void test_flag_no(void) { - int x = 2; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--no-foo")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_flag(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 2); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 0); - gpr_cmdline_destroy(cl); -} - -static void test_flag_val_1(void) { - int x = 2; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=1")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_flag(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 2); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 1); - gpr_cmdline_destroy(cl); -} - -static void test_flag_val_0(void) { - int x = 2; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=0")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_flag(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 2); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 0); - gpr_cmdline_destroy(cl); -} - -static void test_flag_val_true(void) { - int x = 2; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=true")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_flag(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 2); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 1); - gpr_cmdline_destroy(cl); -} - -static void test_flag_val_false(void) { - int x = 2; - gpr_cmdline* cl; - char* args[] = {const_cast<char*>(__FILE__), - const_cast<char*>("--foo=false")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_flag(cl, "foo", nullptr, &x); - GPR_ASSERT(x == 2); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 0); - gpr_cmdline_destroy(cl); -} - -static void test_many(void) { - const char* str = nullptr; - int x = 0; - int flag = 2; - gpr_cmdline* cl; - - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--str"), - const_cast<char*>("hello"), const_cast<char*>("-x=4"), - const_cast<char*>("-no-flag")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_string(cl, "str", nullptr, &str); - gpr_cmdline_add_int(cl, "x", nullptr, &x); - gpr_cmdline_add_flag(cl, "flag", nullptr, &flag); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(x == 4); - GPR_ASSERT(0 == strcmp(str, "hello")); - GPR_ASSERT(flag == 0); - gpr_cmdline_destroy(cl); -} - -static void extra_arg_cb(void* user_data, const char* arg) { - int* count = static_cast<int*>(user_data); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(strlen(arg) == 1); - GPR_ASSERT(arg[0] == 'a' + *count); - ++*count; -} - -static void test_extra(void) { - gpr_cmdline* cl; - int count = 0; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("a"), - const_cast<char*>("b"), const_cast<char*>("c")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb, - &count); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(count == 3); - gpr_cmdline_destroy(cl); -} - -static void test_extra_dashdash(void) { - gpr_cmdline* cl; - int count = 0; - char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--"), - const_cast<char*>("a"), const_cast<char*>("b"), - const_cast<char*>("c")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb, - &count); - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(args), args); - GPR_ASSERT(count == 3); - gpr_cmdline_destroy(cl); -} - -static void test_usage(void) { - gpr_cmdline* cl; - - const char* str = nullptr; - int x = 0; - int flag = 2; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_add_string(cl, "str", nullptr, &str); - gpr_cmdline_add_int(cl, "x", nullptr, &x); - gpr_cmdline_add_flag(cl, "flag", nullptr, &flag); - gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb, - nullptr); - - TString usage = gpr_cmdline_usage_string(cl, "test"); - GPR_ASSERT(usage == - "Usage: test [--str=string] [--x=int] " - "[--flag|--no-flag] [file...]\n"); - - usage = gpr_cmdline_usage_string(cl, "/foo/test"); - GPR_ASSERT(usage == - "Usage: test [--str=string] [--x=int] " - "[--flag|--no-flag] [file...]\n"); - - gpr_cmdline_destroy(cl); -} - -static void test_help(void) { - gpr_cmdline* cl; - - const char* str = nullptr; - int x = 0; - int flag = 2; - - char* help[] = {const_cast<char*>(__FILE__), const_cast<char*>("-h")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_set_survive_failure(cl); - gpr_cmdline_add_string(cl, "str", nullptr, &str); - gpr_cmdline_add_int(cl, "x", nullptr, &x); - gpr_cmdline_add_flag(cl, "flag", nullptr, &flag); - gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb, - nullptr); - - GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(help), help)); - - gpr_cmdline_destroy(cl); -} - -static void test_badargs1(void) { - gpr_cmdline* cl; - - const char* str = nullptr; - int x = 0; - int flag = 2; - - char* bad_arg_name[] = {const_cast<char*>(__FILE__), - const_cast<char*>("--y")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_set_survive_failure(cl); - gpr_cmdline_add_string(cl, "str", nullptr, &str); - gpr_cmdline_add_int(cl, "x", nullptr, &x); - gpr_cmdline_add_flag(cl, "flag", nullptr, &flag); - gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb, - nullptr); - - GPR_ASSERT(0 == - gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_arg_name), bad_arg_name)); - - gpr_cmdline_destroy(cl); -} - -static void test_badargs2(void) { - gpr_cmdline* cl; - - const char* str = nullptr; - int x = 0; - int flag = 2; - - char* bad_int_value[] = {const_cast<char*>(__FILE__), - const_cast<char*>("--x"), - const_cast<char*>("henry")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_set_survive_failure(cl); - gpr_cmdline_add_string(cl, "str", nullptr, &str); - gpr_cmdline_add_int(cl, "x", nullptr, &x); - gpr_cmdline_add_flag(cl, "flag", nullptr, &flag); - gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb, - nullptr); - - GPR_ASSERT( - 0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_int_value), bad_int_value)); - - gpr_cmdline_destroy(cl); -} - -static void test_badargs3(void) { - gpr_cmdline* cl; - - const char* str = nullptr; - int x = 0; - int flag = 2; - - char* bad_bool_value[] = {const_cast<char*>(__FILE__), - const_cast<char*>("--flag=henry")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_set_survive_failure(cl); - gpr_cmdline_add_string(cl, "str", nullptr, &str); - gpr_cmdline_add_int(cl, "x", nullptr, &x); - gpr_cmdline_add_flag(cl, "flag", nullptr, &flag); - gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb, - nullptr); - - GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_bool_value), - bad_bool_value)); - - gpr_cmdline_destroy(cl); -} - -static void test_badargs4(void) { - gpr_cmdline* cl; - - const char* str = nullptr; - int x = 0; - int flag = 2; - - char* bad_bool_value[] = {const_cast<char*>(__FILE__), - const_cast<char*>("--no-str")}; - - LOG_TEST(); - - cl = gpr_cmdline_create(nullptr); - gpr_cmdline_set_survive_failure(cl); - gpr_cmdline_add_string(cl, "str", nullptr, &str); - gpr_cmdline_add_int(cl, "x", nullptr, &x); - gpr_cmdline_add_flag(cl, "flag", nullptr, &flag); - gpr_cmdline_on_extra_arg(cl, "file", "filenames to process", extra_arg_cb, - nullptr); - - GPR_ASSERT(0 == gpr_cmdline_parse(cl, GPR_ARRAY_SIZE(bad_bool_value), - bad_bool_value)); - - gpr_cmdline_destroy(cl); -} - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - test_simple_int(); - test_eq_int(); - test_2dash_int(); - test_2dash_eq_int(); - test_simple_string(); - test_eq_string(); - test_2dash_string(); - test_2dash_eq_string(); - test_flag_on(); - test_flag_no(); - test_flag_val_1(); - test_flag_val_0(); - test_flag_val_true(); - test_flag_val_false(); - test_many(); - test_extra(); - test_extra_dashdash(); - test_usage(); - test_help(); - test_badargs1(); - test_badargs2(); - test_badargs3(); - test_badargs4(); - return 0; -} diff --git a/contrib/libs/grpc/test/core/util/evaluate_args_test_util.h b/contrib/libs/grpc/test/core/util/evaluate_args_test_util.h deleted file mode 100644 index 37541c89f4..0000000000 --- a/contrib/libs/grpc/test/core/util/evaluate_args_test_util.h +++ /dev/null @@ -1,68 +0,0 @@ -// 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. - -#ifndef GRPC_TEST_CORE_UTIL_EVALUATE_ARGS_TEST_UTIL_H -#define GRPC_TEST_CORE_UTIL_EVALUATE_ARGS_TEST_UTIL_H - -#include <grpc/support/port_platform.h> - -#include <list> - -#include <gtest/gtest.h> - -#include "src/core/lib/security/authorization/evaluate_args.h" -#include "test/core/util/mock_authorization_endpoint.h" - -namespace grpc_core { - -class EvaluateArgsTestUtil { - public: - EvaluateArgsTestUtil() = default; - - ~EvaluateArgsTestUtil() { delete channel_args_; } - - void AddPairToMetadata(const char* key, const char* value) { - metadata_.Append( - key, Slice(grpc_slice_intern(grpc_slice_from_static_string(value)))); - } - - void SetLocalEndpoint(y_absl::string_view local_uri) { - endpoint_.SetLocalAddress(local_uri); - } - - void SetPeerEndpoint(y_absl::string_view peer_uri) { - endpoint_.SetPeer(peer_uri); - } - - void AddPropertyToAuthContext(const char* name, const char* value) { - auth_context_.add_cstring_property(name, value); - } - - EvaluateArgs MakeEvaluateArgs() { - channel_args_ = - new EvaluateArgs::PerChannelArgs(&auth_context_, &endpoint_); - return EvaluateArgs(&metadata_, channel_args_); - } - - private: - ScopedArenaPtr arena_ = MakeScopedArena(1024); - grpc_metadata_batch metadata_{arena_.get()}; - MockAuthorizationEndpoint endpoint_{/*local_uri=*/"", /*peer_uri=*/""}; - grpc_auth_context auth_context_{nullptr}; - EvaluateArgs::PerChannelArgs* channel_args_ = nullptr; -}; - -} // namespace grpc_core - -#endif // GRPC_TEST_CORE_UTIL_EVALUATE_ARGS_TEST_UTIL_H diff --git a/contrib/libs/grpc/test/core/util/fuzzer_corpus_test.cc b/contrib/libs/grpc/test/core/util/fuzzer_corpus_test.cc deleted file mode 100644 index 8037e68aca..0000000000 --- a/contrib/libs/grpc/test/core/util/fuzzer_corpus_test.cc +++ /dev/null @@ -1,166 +0,0 @@ -/* - * - * Copyright 2016 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 <dirent.h> -#include <stdbool.h> -#include <stdio.h> -#include <sys/types.h> - -#include <gtest/gtest.h> - -#include "y_absl/flags/flag.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/load_file.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/test_config.h" - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); -extern bool squelch; -extern bool leak_check; - -Y_ABSL_FLAG(TString, file, "", "Use this file as test data"); -Y_ABSL_FLAG(TString, directory, "", "Use this directory as test data"); - -class FuzzerCorpusTest : public ::testing::TestWithParam<TString> {}; - -TEST_P(FuzzerCorpusTest, RunOneExample) { - // Need to call grpc_init() here to use a slice, but need to shut it - // down before calling LLVMFuzzerTestOneInput(), because most - // implementations of that function will initialize and shutdown gRPC - // internally. - grpc_init(); - gpr_log(GPR_INFO, "Example file: %s", GetParam().c_str()); - grpc_slice buffer; - squelch = false; - leak_check = false; - GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(GetParam().c_str(), 0, &buffer))); - size_t length = GRPC_SLICE_LENGTH(buffer); - void* data = gpr_malloc(length); - memcpy(data, GPR_SLICE_START_PTR(buffer), length); - grpc_slice_unref(buffer); - grpc_shutdown(); - LLVMFuzzerTestOneInput(static_cast<uint8_t*>(data), length); - gpr_free(data); -} - -class ExampleGenerator - : public ::testing::internal::ParamGeneratorInterface<TString> { - public: - ::testing::internal::ParamIteratorInterface<TString>* Begin() - const override; - ::testing::internal::ParamIteratorInterface<TString>* End() - const override; - - private: - void Materialize() const { - if (examples_.empty()) { - if (!y_absl::GetFlag(FLAGS_file).empty()) { - examples_.push_back(y_absl::GetFlag(FLAGS_file)); - } - if (!y_absl::GetFlag(FLAGS_directory).empty()) { - char* test_srcdir = gpr_getenv("TEST_SRCDIR"); - gpr_log(GPR_DEBUG, "test_srcdir=\"%s\"", test_srcdir); - TString directory = y_absl::GetFlag(FLAGS_directory); - if (test_srcdir != nullptr) { - directory = - test_srcdir + TString("/com_github_grpc_grpc/") + directory; - } - gpr_log(GPR_DEBUG, "Using corpus directory: %s", directory.c_str()); - DIR* dp; - struct dirent* ep; - dp = opendir(directory.c_str()); - - if (dp != nullptr) { - while ((ep = readdir(dp)) != nullptr) { - if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0) { - examples_.push_back(directory + "/" + ep->d_name); - } - } - - (void)closedir(dp); - } else { - perror("Couldn't open the directory"); - abort(); - } - gpr_free(test_srcdir); - } - } - // Make sure we don't succeed without doing anything, which caused - // us to be blind to our fuzzers not running for 9 months. - GPR_ASSERT(!examples_.empty()); - } - - mutable std::vector<TString> examples_; -}; - -class ExampleIterator - : public ::testing::internal::ParamIteratorInterface<TString> { - public: - ExampleIterator(const ExampleGenerator& base_, - std::vector<TString>::const_iterator begin) - : base_(base_), begin_(begin), current_(begin) {} - - const ExampleGenerator* BaseGenerator() const override { return &base_; } - - void Advance() override { current_++; } - ExampleIterator* Clone() const override { return new ExampleIterator(*this); } - const TString* Current() const override { return &*current_; } - - bool Equals(const ParamIteratorInterface<TString>& other) const override { - return &base_ == other.BaseGenerator() && - current_ == dynamic_cast<const ExampleIterator*>(&other)->current_; - } - - private: - ExampleIterator(const ExampleIterator& other) - : base_(other.base_), begin_(other.begin_), current_(other.current_) {} - - const ExampleGenerator& base_; - const std::vector<TString>::const_iterator begin_; - std::vector<TString>::const_iterator current_; -}; - -::testing::internal::ParamIteratorInterface<TString>* -ExampleGenerator::Begin() const { - Materialize(); - return new ExampleIterator(*this, examples_.begin()); -} - -::testing::internal::ParamIteratorInterface<TString>* -ExampleGenerator::End() const { - Materialize(); - return new ExampleIterator(*this, examples_.end()); -} - -INSTANTIATE_TEST_SUITE_P( - CorpusExamples, FuzzerCorpusTest, - ::testing::internal::ParamGenerator<TString>(new ExampleGenerator)); - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - grpc::testing::InitTest(&argc, &argv, true); - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/core/util/fuzzer_one_entry_runner.sh b/contrib/libs/grpc/test/core/util/fuzzer_one_entry_runner.sh deleted file mode 100755 index 7c471afcc2..0000000000 --- a/contrib/libs/grpc/test/core/util/fuzzer_one_entry_runner.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# Test runner for fuzzer tests from bazel - -# Copyright 2017 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. -"$1" "$2" diff --git a/contrib/libs/grpc/test/core/util/fuzzer_util.cc b/contrib/libs/grpc/test/core/util/fuzzer_util.cc deleted file mode 100644 index ffd8832a51..0000000000 --- a/contrib/libs/grpc/test/core/util/fuzzer_util.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * Copyright 2018 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 "test/core/util/fuzzer_util.h" - -#include <algorithm> - -#include <grpc/support/alloc.h> - -#include "src/core/lib/gpr/useful.h" - -namespace grpc_core { -namespace testing { - -uint8_t grpc_fuzzer_get_next_byte(input_stream* inp) { - if (inp->cur == inp->end) { - return 0; - } - return *inp->cur++; -} - -char* grpc_fuzzer_get_next_string(input_stream* inp, bool* special) { - char* str = nullptr; - size_t cap = 0; - size_t sz = 0; - char c; - do { - if (cap == sz) { - cap = std::max(3 * cap / 2, cap + 8); - str = static_cast<char*>(gpr_realloc(str, cap)); - } - c = static_cast<char>(grpc_fuzzer_get_next_byte(inp)); - str[sz++] = c; - } while (c != 0 && c != 1); - if (special != nullptr) { - *special = (c == 1); - } - if (c == 1) { - str[sz - 1] = 0; - } - return str; -} - -uint32_t grpc_fuzzer_get_next_uint32(input_stream* inp) { - uint8_t b = grpc_fuzzer_get_next_byte(inp); - uint32_t x = b & 0x7f; - if (b & 0x80) { - x <<= 7; - b = grpc_fuzzer_get_next_byte(inp); - x |= b & 0x7f; - if (b & 0x80) { - x <<= 7; - b = grpc_fuzzer_get_next_byte(inp); - x |= b & 0x7f; - if (b & 0x80) { - x <<= 7; - b = grpc_fuzzer_get_next_byte(inp); - x |= b & 0x7f; - if (b & 0x80) { - x = (x << 4) | (grpc_fuzzer_get_next_byte(inp) & 0x0f); - } - } - } - } - return x; -} - -} // namespace testing -} // namespace grpc_core diff --git a/contrib/libs/grpc/test/core/util/fuzzer_util.h b/contrib/libs/grpc/test/core/util/fuzzer_util.h deleted file mode 100644 index 0e938399a1..0000000000 --- a/contrib/libs/grpc/test/core/util/fuzzer_util.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Copyright 2018 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_FUZZER_UTIL_H -#define GRPC_TEST_CORE_UTIL_FUZZER_UTIL_H - -#include <stdint.h> - -namespace grpc_core { - -namespace testing { - -// Main struct for input_stream. It allows easy access to input -// bytes, and allows reading a little past the end(avoiding -// needing to check everywhere). -typedef struct { - const uint8_t* cur; - const uint8_t* end; -} input_stream; - -// get a byte from an input stream. -uint8_t grpc_fuzzer_get_next_byte(input_stream* inp); - -// get a string and boolean values (if special is not null) from an input -// stream. -char* grpc_fuzzer_get_next_string(input_stream* inp, bool* special); - -// get a uint32 value from an input stream. -uint32_t grpc_fuzzer_get_next_uint32(input_stream* inp); - -} // namespace testing -} // namespace grpc_core - -#endif /* GRPC_TEST_CORE_UTIL_FUZZER_UTIL_H */ diff --git a/contrib/libs/grpc/test/core/util/grpc_fuzzer.bzl b/contrib/libs/grpc/test/core/util/grpc_fuzzer.bzl deleted file mode 100644 index 8ae71b61f3..0000000000 --- a/contrib/libs/grpc/test/core/util/grpc_fuzzer.bzl +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright 2016 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. - -""" -Includes fuzzer rules. -""" - -load("//bazel:grpc_build_system.bzl", "grpc_cc_test") -load("@rules_proto//proto:defs.bzl", "proto_library") -load("@rules_cc//cc:defs.bzl", "cc_proto_library") - -def grpc_fuzzer(name, corpus, srcs = [], deps = [], data = [], size = "large", **kwargs): - """Instantiates a fuzzer test. - - Args: - name: The name of the test. - corpus: The corpus for the test. - srcs: The source files for the test. - deps: The dependencies of the test. - data: The data dependencies of the test. - size: The size of the test. - **kwargs: Other arguments to supply to the test. - """ - CORPUS_DIR = native.package_name() + "/" + corpus - grpc_cc_test( - name = name, - srcs = srcs, - deps = deps + select({ - "//:grpc_build_fuzzers": [], - "//conditions:default": ["//test/core/util:fuzzer_corpus_test"], - }), - data = data + native.glob([corpus + "/**"]), - external_deps = [ - "gtest", - ], - size = size, - args = select({ - "//:grpc_build_fuzzers": [CORPUS_DIR], - "//conditions:default": ["--directory=" + CORPUS_DIR], - }), - **kwargs - ) - -def grpc_proto_fuzzer(name, corpus, proto, srcs = [], deps = [], data = [], size = "large", **kwargs): - """Instantiates a protobuf mutator fuzzer test. - - Args: - name: The name of the test. - corpus: The corpus for the test. - proto: The proto for the test. - srcs: The source files for the test. - deps: The dependencies of the test. - data: The data dependencies of the test. - size: The size of the test. - **kwargs: Other arguments to supply to the test. - """ - PROTO_LIBRARY = "_%s_proto" % name - CC_PROTO_LIBRARY = "_%s_cc_proto" % name - CORPUS_DIR = native.package_name() + "/" + corpus - - proto_library( - name = PROTO_LIBRARY, - srcs = [proto], - ) - - cc_proto_library( - name = CC_PROTO_LIBRARY, - deps = [PROTO_LIBRARY], - ) - - grpc_cc_test( - name = name, - srcs = srcs, - deps = deps + [ - "@com_google_libprotobuf_mutator//:libprotobuf_mutator", - CC_PROTO_LIBRARY, - ] + select({ - "//:grpc_build_fuzzers": [], - "//conditions:default": ["//test/core/util:fuzzer_corpus_test"], - }), - data = data + native.glob([corpus + "/**"]), - external_deps = [ - "gtest", - ], - size = size, - args = select({ - "//:grpc_build_fuzzers": [CORPUS_DIR], - "//conditions:default": ["--directory=" + CORPUS_DIR], - }), - **kwargs - ) diff --git a/contrib/libs/grpc/test/core/util/grpc_profiler.cc b/contrib/libs/grpc/test/core/util/grpc_profiler.cc deleted file mode 100644 index 88f233598b..0000000000 --- a/contrib/libs/grpc/test/core/util/grpc_profiler.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/util/grpc_profiler.h" - -#if GRPC_HAVE_PERFTOOLS -#include <gperftools/profiler.h> - -void grpc_profiler_start(const char* filename) { ProfilerStart(filename); } - -void grpc_profiler_stop() { ProfilerStop(); } -#else -#include <grpc/support/log.h> - -void grpc_profiler_start(const char* filename) { - static int printed_warning = 0; - if (!printed_warning) { - gpr_log(GPR_DEBUG, - "You do not have google-perftools installed, profiling is disabled " - "[for %s]", - filename); - gpr_log(GPR_DEBUG, - "To install on ubuntu: sudo apt-get install google-perftools " - "libgoogle-perftools-dev"); - printed_warning = 1; - } -} - -void grpc_profiler_stop(void) {} -#endif diff --git a/contrib/libs/grpc/test/core/util/grpc_profiler.h b/contrib/libs/grpc/test/core/util/grpc_profiler.h deleted file mode 100644 index f9ddd2242e..0000000000 --- a/contrib/libs/grpc/test/core/util/grpc_profiler.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_GRPC_PROFILER_H -#define GRPC_TEST_CORE_UTIL_GRPC_PROFILER_H - -void grpc_profiler_start(const char* filename); -void grpc_profiler_stop(); - -#endif /* GRPC_TEST_CORE_UTIL_GRPC_PROFILER_H */ diff --git a/contrib/libs/grpc/test/core/util/histogram.cc b/contrib/libs/grpc/test/core/util/histogram.cc deleted file mode 100644 index fc3e21c5b4..0000000000 --- a/contrib/libs/grpc/test/core/util/histogram.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* - * - * Copyright 2015 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 <grpc/support/port_platform.h> - -#include "test/core/util/histogram.h" - -#include <math.h> -#include <stddef.h> -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> - -#include "src/core/lib/gpr/useful.h" - -/* Histograms are stored with exponentially increasing bucket sizes. - The first bucket is [0, m) where m = 1 + resolution - Bucket n (n>=1) contains [m**n, m**(n+1)) - There are sufficient buckets to reach max_bucket_start */ - -struct grpc_histogram { - /* Sum of all values seen so far */ - double sum; - /* Sum of squares of all values seen so far */ - double sum_of_squares; - /* number of values seen so far */ - double count; - /* m in the description */ - double multiplier; - double one_on_log_multiplier; - /* minimum value seen */ - double min_seen; - /* maximum value seen */ - double max_seen; - /* maximum representable value */ - double max_possible; - /* number of buckets */ - size_t num_buckets; - /* the buckets themselves */ - uint32_t* buckets; -}; - -/* determine a bucket index given a value - does no bounds checking */ -static size_t bucket_for_unchecked(grpc_histogram* h, double x) { - return static_cast<size_t>(log(x) * h->one_on_log_multiplier); -} - -/* bounds checked version of the above */ -static size_t bucket_for(grpc_histogram* h, double x) { - size_t bucket = - bucket_for_unchecked(h, grpc_core::Clamp(x, 1.0, h->max_possible)); - GPR_ASSERT(bucket < h->num_buckets); - return bucket; -} - -/* at what value does a bucket start? */ -static double bucket_start(grpc_histogram* h, double x) { - return pow(h->multiplier, x); -} - -grpc_histogram* grpc_histogram_create(double resolution, - double max_bucket_start) { - grpc_histogram* h = - static_cast<grpc_histogram*>(gpr_malloc(sizeof(grpc_histogram))); - GPR_ASSERT(resolution > 0.0); - GPR_ASSERT(max_bucket_start > resolution); - h->sum = 0.0; - h->sum_of_squares = 0.0; - h->multiplier = 1.0 + resolution; - h->one_on_log_multiplier = 1.0 / log(1.0 + resolution); - h->max_possible = max_bucket_start; - h->count = 0.0; - h->min_seen = max_bucket_start; - h->max_seen = 0.0; - h->num_buckets = bucket_for_unchecked(h, max_bucket_start) + 1; - GPR_ASSERT(h->num_buckets > 1); - GPR_ASSERT(h->num_buckets < 100000000); - h->buckets = - static_cast<uint32_t*>(gpr_zalloc(sizeof(uint32_t) * h->num_buckets)); - return h; -} - -void grpc_histogram_destroy(grpc_histogram* h) { - gpr_free(h->buckets); - gpr_free(h); -} - -void grpc_histogram_add(grpc_histogram* h, double x) { - h->sum += x; - h->sum_of_squares += x * x; - h->count++; - if (x < h->min_seen) { - h->min_seen = x; - } - if (x > h->max_seen) { - h->max_seen = x; - } - h->buckets[bucket_for(h, x)]++; -} - -int grpc_histogram_merge(grpc_histogram* dst, const grpc_histogram* src) { - if ((dst->num_buckets != src->num_buckets) || - (dst->multiplier != src->multiplier)) { - /* Fail because these histograms don't match */ - return 0; - } - grpc_histogram_merge_contents(dst, src->buckets, src->num_buckets, - src->min_seen, src->max_seen, src->sum, - src->sum_of_squares, src->count); - return 1; -} - -void grpc_histogram_merge_contents(grpc_histogram* histogram, - const uint32_t* data, size_t data_count, - double min_seen, double max_seen, double sum, - double sum_of_squares, double count) { - size_t i; - GPR_ASSERT(histogram->num_buckets == data_count); - histogram->sum += sum; - histogram->sum_of_squares += sum_of_squares; - histogram->count += count; - if (min_seen < histogram->min_seen) { - histogram->min_seen = min_seen; - } - if (max_seen > histogram->max_seen) { - histogram->max_seen = max_seen; - } - for (i = 0; i < histogram->num_buckets; i++) { - histogram->buckets[i] += data[i]; - } -} - -static double threshold_for_count_below(grpc_histogram* h, double count_below) { - double count_so_far; - double lower_bound; - double upper_bound; - size_t lower_idx; - size_t upper_idx; - - if (h->count == 0) { - return 0.0; - } - - if (count_below <= 0) { - return h->min_seen; - } - if (count_below >= h->count) { - return h->max_seen; - } - - /* find the lowest bucket that gets us above count_below */ - count_so_far = 0.0; - for (lower_idx = 0; lower_idx < h->num_buckets; lower_idx++) { - count_so_far += h->buckets[lower_idx]; - if (count_so_far >= count_below) { - break; - } - } - if (count_so_far == count_below) { - /* this bucket hits the threshold exactly... we should be midway through - any run of zero values following the bucket */ - for (upper_idx = lower_idx + 1; upper_idx < h->num_buckets; upper_idx++) { - if (h->buckets[upper_idx]) { - break; - } - } - return (bucket_start(h, static_cast<double>(lower_idx)) + - bucket_start(h, static_cast<double>(upper_idx))) / - 2.0; - } else { - /* treat values as uniform throughout the bucket, and find where this value - should lie */ - lower_bound = bucket_start(h, static_cast<double>(lower_idx)); - upper_bound = bucket_start(h, static_cast<double>(lower_idx + 1)); - return grpc_core::Clamp(upper_bound - (upper_bound - lower_bound) * - (count_so_far - count_below) / - h->buckets[lower_idx], - h->min_seen, h->max_seen); - } -} - -double grpc_histogram_percentile(grpc_histogram* h, double percentile) { - return threshold_for_count_below(h, h->count * percentile / 100.0); -} - -double grpc_histogram_mean(grpc_histogram* h) { - GPR_ASSERT(h->count != 0); - return h->sum / h->count; -} - -double grpc_histogram_stddev(grpc_histogram* h) { - return sqrt(grpc_histogram_variance(h)); -} - -double grpc_histogram_variance(grpc_histogram* h) { - if (h->count == 0) return 0.0; - return (h->sum_of_squares * h->count - h->sum * h->sum) / - (h->count * h->count); -} - -double grpc_histogram_maximum(grpc_histogram* h) { return h->max_seen; } - -double grpc_histogram_minimum(grpc_histogram* h) { return h->min_seen; } - -double grpc_histogram_count(grpc_histogram* h) { return h->count; } - -double grpc_histogram_sum(grpc_histogram* h) { return h->sum; } - -double grpc_histogram_sum_of_squares(grpc_histogram* h) { - return h->sum_of_squares; -} - -const uint32_t* grpc_histogram_get_contents(grpc_histogram* histogram, - size_t* count) { - *count = histogram->num_buckets; - return histogram->buckets; -} diff --git a/contrib/libs/grpc/test/core/util/histogram.h b/contrib/libs/grpc/test/core/util/histogram.h deleted file mode 100644 index 9e872869bf..0000000000 --- a/contrib/libs/grpc/test/core/util/histogram.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_SUPPORT_HISTOGRAM_H -#define GRPC_SUPPORT_HISTOGRAM_H - -#include <grpc/support/port_platform.h> - -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct grpc_histogram grpc_histogram; - -grpc_histogram* grpc_histogram_create(double resolution, - double max_bucket_start); -void grpc_histogram_destroy(grpc_histogram* h); -void grpc_histogram_add(grpc_histogram* h, double x); - -/** The following merges the second histogram into the first. It only works - if they have the same buckets and resolution. Returns 0 on failure, 1 - on success */ -int grpc_histogram_merge(grpc_histogram* dst, const grpc_histogram* src); - -double grpc_histogram_percentile(grpc_histogram* histogram, double percentile); -double grpc_histogram_mean(grpc_histogram* histogram); -double grpc_histogram_stddev(grpc_histogram* histogram); -double grpc_histogram_variance(grpc_histogram* histogram); -double grpc_histogram_maximum(grpc_histogram* histogram); -double grpc_histogram_minimum(grpc_histogram* histogram); -double grpc_histogram_count(grpc_histogram* histogram); -double grpc_histogram_sum(grpc_histogram* histogram); -double grpc_histogram_sum_of_squares(grpc_histogram* histogram); - -const uint32_t* grpc_histogram_get_contents(grpc_histogram* histogram, - size_t* count); -void grpc_histogram_merge_contents(grpc_histogram* histogram, - const uint32_t* data, size_t data_count, - double min_seen, double max_seen, double sum, - double sum_of_squares, double count); - -#ifdef __cplusplus -} -#endif - -#endif /* GRPC_SUPPORT_HISTOGRAM_H */ diff --git a/contrib/libs/grpc/test/core/util/histogram_test.cc b/contrib/libs/grpc/test/core/util/histogram_test.cc deleted file mode 100644 index 3ff92a31e1..0000000000 --- a/contrib/libs/grpc/test/core/util/histogram_test.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/util/histogram.h" - -#include <grpc/support/log.h> - -#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x); - -static void test_no_op(void) { - grpc_histogram_destroy(grpc_histogram_create(0.01, 60e9)); -} - -static void expect_percentile(grpc_histogram* h, double percentile, - double min_expect, double max_expect) { - double got = grpc_histogram_percentile(h, percentile); - gpr_log(GPR_INFO, "@%f%%, expect %f <= %f <= %f", percentile, min_expect, got, - max_expect); - GPR_ASSERT(min_expect <= got); - GPR_ASSERT(got <= max_expect); -} - -static void test_simple(void) { - grpc_histogram* h; - - LOG_TEST("test_simple"); - - h = grpc_histogram_create(0.01, 60e9); - grpc_histogram_add(h, 10000); - grpc_histogram_add(h, 10000); - grpc_histogram_add(h, 11000); - grpc_histogram_add(h, 11000); - - expect_percentile(h, 50, 10001, 10999); - GPR_ASSERT(grpc_histogram_mean(h) == 10500); - - grpc_histogram_destroy(h); -} - -static void test_percentile(void) { - grpc_histogram* h; - double last; - double i; - double cur; - - LOG_TEST("test_percentile"); - - h = grpc_histogram_create(0.05, 1e9); - grpc_histogram_add(h, 2.5); - grpc_histogram_add(h, 2.5); - grpc_histogram_add(h, 8); - grpc_histogram_add(h, 4); - - GPR_ASSERT(grpc_histogram_count(h) == 4); - GPR_ASSERT(grpc_histogram_minimum(h) == 2.5); - GPR_ASSERT(grpc_histogram_maximum(h) == 8); - GPR_ASSERT(grpc_histogram_sum(h) == 17); - GPR_ASSERT(grpc_histogram_sum_of_squares(h) == 92.5); - GPR_ASSERT(grpc_histogram_mean(h) == 4.25); - GPR_ASSERT(grpc_histogram_variance(h) == 5.0625); - GPR_ASSERT(grpc_histogram_stddev(h) == 2.25); - - expect_percentile(h, -10, 2.5, 2.5); - expect_percentile(h, 0, 2.5, 2.5); - expect_percentile(h, 12.5, 2.5, 2.5); - expect_percentile(h, 25, 2.5, 2.5); - expect_percentile(h, 37.5, 2.5, 2.8); - expect_percentile(h, 50, 3.0, 3.5); - expect_percentile(h, 62.5, 3.5, 4.5); - expect_percentile(h, 75, 5, 7.9); - expect_percentile(h, 100, 8, 8); - expect_percentile(h, 110, 8, 8); - - /* test monotonicity */ - last = 0.0; - for (i = 0; i < 100.0; i += 0.01) { - cur = grpc_histogram_percentile(h, i); - GPR_ASSERT(cur >= last); - last = cur; - } - - grpc_histogram_destroy(h); -} - -static void test_merge(void) { - grpc_histogram *h1, *h2; - double last; - double i; - double cur; - - LOG_TEST("test_merge"); - - h1 = grpc_histogram_create(0.05, 1e9); - grpc_histogram_add(h1, 2.5); - grpc_histogram_add(h1, 2.5); - grpc_histogram_add(h1, 8); - grpc_histogram_add(h1, 4); - - h2 = grpc_histogram_create(0.01, 1e9); - GPR_ASSERT(grpc_histogram_merge(h1, h2) == 0); - grpc_histogram_destroy(h2); - - h2 = grpc_histogram_create(0.05, 1e10); - GPR_ASSERT(grpc_histogram_merge(h1, h2) == 0); - grpc_histogram_destroy(h2); - - h2 = grpc_histogram_create(0.05, 1e9); - GPR_ASSERT(grpc_histogram_merge(h1, h2) == 1); - GPR_ASSERT(grpc_histogram_count(h1) == 4); - GPR_ASSERT(grpc_histogram_minimum(h1) == 2.5); - GPR_ASSERT(grpc_histogram_maximum(h1) == 8); - GPR_ASSERT(grpc_histogram_sum(h1) == 17); - GPR_ASSERT(grpc_histogram_sum_of_squares(h1) == 92.5); - GPR_ASSERT(grpc_histogram_mean(h1) == 4.25); - GPR_ASSERT(grpc_histogram_variance(h1) == 5.0625); - GPR_ASSERT(grpc_histogram_stddev(h1) == 2.25); - grpc_histogram_destroy(h2); - - h2 = grpc_histogram_create(0.05, 1e9); - grpc_histogram_add(h2, 7.0); - grpc_histogram_add(h2, 17.0); - grpc_histogram_add(h2, 1.0); - GPR_ASSERT(grpc_histogram_merge(h1, h2) == 1); - GPR_ASSERT(grpc_histogram_count(h1) == 7); - GPR_ASSERT(grpc_histogram_minimum(h1) == 1.0); - GPR_ASSERT(grpc_histogram_maximum(h1) == 17.0); - GPR_ASSERT(grpc_histogram_sum(h1) == 42.0); - GPR_ASSERT(grpc_histogram_sum_of_squares(h1) == 431.5); - GPR_ASSERT(grpc_histogram_mean(h1) == 6.0); - - /* test monotonicity */ - last = 0.0; - for (i = 0; i < 100.0; i += 0.01) { - cur = grpc_histogram_percentile(h1, i); - GPR_ASSERT(cur >= last); - last = cur; - } - - grpc_histogram_destroy(h1); - grpc_histogram_destroy(h2); -} - -int main(void) { - test_no_op(); - test_simple(); - test_percentile(); - test_merge(); - return 0; -} diff --git a/contrib/libs/grpc/test/core/util/memory_counters.cc b/contrib/libs/grpc/test/core/util/memory_counters.cc deleted file mode 100644 index 0deb1a4d37..0000000000 --- a/contrib/libs/grpc/test/core/util/memory_counters.cc +++ /dev/null @@ -1,169 +0,0 @@ -/* - * - * Copyright 2016 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 "test/core/util/memory_counters.h" - -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/sync.h> -#include <grpc/support/time.h> - -#include "src/core/lib/gpr/alloc.h" -#include "src/core/lib/surface/init.h" - -static struct grpc_memory_counters g_memory_counters; -static bool g_memory_counter_enabled; - -#ifdef GPR_LOW_LEVEL_COUNTERS -/* hide these from the microbenchmark atomic stats */ -#define NO_BARRIER_FETCH_ADD(x, sz) \ - __atomic_fetch_add((x), (sz), __ATOMIC_RELAXED) -#define NO_BARRIER_LOAD(x) __atomic_load_n((x), __ATOMIC_RELAXED) -#else -#define NO_BARRIER_FETCH_ADD(x, sz) gpr_atm_no_barrier_fetch_add(x, sz) -#define NO_BARRIER_LOAD(x) gpr_atm_no_barrier_load(x) -#endif - -// Memory counter uses --wrap=symbol feature from ld. To use this, -// `GPR_WRAP_MEMORY_COUNTER` needs to be defined. following options should be -// passed to the compiler. -// -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=realloc -Wl,--wrap=free -// * Reference: https://linux.die.net/man/1/ld) -#if GPR_WRAP_MEMORY_COUNTER - -extern "C" { -void* __real_malloc(size_t size); -void* __real_calloc(size_t size); -void* __real_realloc(void* ptr, size_t size); -void __real_free(void* ptr); - -void* __wrap_malloc(size_t size); -void* __wrap_calloc(size_t size); -void* __wrap_realloc(void* ptr, size_t size); -void __wrap_free(void* ptr); -} - -void* __wrap_malloc(size_t size) { - if (!size) return nullptr; - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1); - void* ptr = - __real_malloc(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); - *static_cast<size_t*>(ptr) = size; - return static_cast<char*>(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); -} - -void* __wrap_calloc(size_t size) { - if (!size) return nullptr; - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1); - void* ptr = - __real_calloc(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); - *static_cast<size_t*>(ptr) = size; - return static_cast<char*>(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); -} - -void* __wrap_realloc(void* ptr, size_t size) { - if (ptr == nullptr) { - return __wrap_malloc(size); - } - if (size == 0) { - __wrap_free(ptr); - return nullptr; - } - void* rptr = - static_cast<char*>(ptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, - -*static_cast<gpr_atm*>(rptr)); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); - void* new_ptr = - __real_realloc(rptr, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); - *static_cast<size_t*>(new_ptr) = size; - return static_cast<char*>(new_ptr) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); -} - -void __wrap_free(void* ptr) { - if (ptr == nullptr) return; - void* rptr = - static_cast<char*>(ptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size_t)); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, - -*static_cast<gpr_atm*>(rptr)); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1); - __real_free(rptr); -} - -#endif // GPR_WRAP_MEMORY_COUNTER - -void grpc_memory_counters_init() { - memset(&g_memory_counters, 0, sizeof(g_memory_counters)); - g_memory_counter_enabled = true; -} - -void grpc_memory_counters_destroy() { g_memory_counter_enabled = false; } - -struct grpc_memory_counters grpc_memory_counters_snapshot() { - struct grpc_memory_counters counters; - counters.total_size_relative = - NO_BARRIER_LOAD(&g_memory_counters.total_size_relative); - counters.total_size_absolute = - NO_BARRIER_LOAD(&g_memory_counters.total_size_absolute); - counters.total_allocs_relative = - NO_BARRIER_LOAD(&g_memory_counters.total_allocs_relative); - counters.total_allocs_absolute = - NO_BARRIER_LOAD(&g_memory_counters.total_allocs_absolute); - return counters; -} - -namespace grpc_core { -namespace testing { - -LeakDetector::LeakDetector(bool enable) : enabled_(enable) { - if (enabled_) { - grpc_memory_counters_init(); - } -} - -LeakDetector::~LeakDetector() { - // Wait for grpc_shutdown() to finish its async work. - grpc_maybe_wait_for_async_shutdown(); - if (enabled_) { - struct grpc_memory_counters counters = grpc_memory_counters_snapshot(); - if (counters.total_size_relative != 0) { - gpr_log(GPR_ERROR, "Leaking %" PRIuPTR " bytes", - static_cast<uintptr_t>(counters.total_size_relative)); - GPR_ASSERT(0); - } - grpc_memory_counters_destroy(); - } -} - -} // namespace testing -} // namespace grpc_core diff --git a/contrib/libs/grpc/test/core/util/memory_counters.h b/contrib/libs/grpc/test/core/util/memory_counters.h deleted file mode 100644 index c92a001ff1..0000000000 --- a/contrib/libs/grpc/test/core/util/memory_counters.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_MEMORY_COUNTERS_H -#define GRPC_TEST_CORE_UTIL_MEMORY_COUNTERS_H - -#include <grpc/support/atm.h> - -struct grpc_memory_counters { - gpr_atm total_size_relative; - gpr_atm total_size_absolute; - gpr_atm total_allocs_relative; - gpr_atm total_allocs_absolute; -}; - -void grpc_memory_counters_init(); -void grpc_memory_counters_destroy(); -struct grpc_memory_counters grpc_memory_counters_snapshot(); - -namespace grpc_core { -namespace testing { - -// At destruction time, it will check there is no memory leak. -// The object should be created before grpc_init() is called and destroyed after -// grpc_shutdown() is returned. -class LeakDetector { - public: - explicit LeakDetector(bool enable); - ~LeakDetector(); - - private: - const bool enabled_; -}; - -} // namespace testing -} // namespace grpc_core - -#endif diff --git a/contrib/libs/grpc/test/core/util/mock_authorization_endpoint.h b/contrib/libs/grpc/test/core/util/mock_authorization_endpoint.h deleted file mode 100644 index b0404f7f05..0000000000 --- a/contrib/libs/grpc/test/core/util/mock_authorization_endpoint.h +++ /dev/null @@ -1,62 +0,0 @@ -// 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. - -#ifndef GRPC_TEST_CORE_UTIL_MOCK_AUTHORIZATION_ENDPOINT_H -#define GRPC_TEST_CORE_UTIL_MOCK_AUTHORIZATION_ENDPOINT_H - -#include <grpc/support/port_platform.h> - -#include "src/core/lib/iomgr/endpoint.h" - -namespace grpc_core { - -class MockAuthorizationEndpoint : public grpc_endpoint { - public: - MockAuthorizationEndpoint(y_absl::string_view local_uri, - y_absl::string_view peer_uri) - : local_address_(local_uri), peer_address_(peer_uri) { - static constexpr grpc_endpoint_vtable vtable = { - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, GetPeer, GetLocalAddress, nullptr, nullptr}; - grpc_endpoint::vtable = &vtable; - } - - static y_absl::string_view GetPeer(grpc_endpoint* ep) { - MockAuthorizationEndpoint* m = - reinterpret_cast<MockAuthorizationEndpoint*>(ep); - return m->peer_address_; - } - - static y_absl::string_view GetLocalAddress(grpc_endpoint* ep) { - MockAuthorizationEndpoint* m = - reinterpret_cast<MockAuthorizationEndpoint*>(ep); - return m->local_address_; - } - - void SetPeer(y_absl::string_view peer_address) { - peer_address_ = TString(peer_address); - } - - void SetLocalAddress(y_absl::string_view local_address) { - local_address_ = TString(local_address); - } - - private: - TString local_address_; - TString peer_address_; -}; - -} // namespace grpc_core - -#endif // GRPC_TEST_CORE_UTIL_MOCK_AUTHORIZATION_ENDPOINT_H diff --git a/contrib/libs/grpc/test/core/util/mock_endpoint.cc b/contrib/libs/grpc/test/core/util/mock_endpoint.cc deleted file mode 100644 index 34ce7ffbf7..0000000000 --- a/contrib/libs/grpc/test/core/util/mock_endpoint.cc +++ /dev/null @@ -1,138 +0,0 @@ -/* - * - * Copyright 2016 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 "test/core/util/mock_endpoint.h" - -#include <inttypes.h> - -#include <util/generic/string.h> - -#include "y_absl/strings/str_format.h" - -#include <grpc/support/alloc.h> -#include <grpc/support/string_util.h> - -#include "src/core/lib/iomgr/sockaddr.h" - -typedef struct mock_endpoint { - grpc_endpoint base; - gpr_mu mu; - void (*on_write)(grpc_slice slice); - grpc_slice_buffer read_buffer; - grpc_slice_buffer* on_read_out; - grpc_closure* on_read; -} mock_endpoint; - -static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, bool /*urgent*/) { - mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); - gpr_mu_lock(&m->mu); - if (m->read_buffer.count > 0) { - grpc_slice_buffer_swap(&m->read_buffer, slices); - grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, GRPC_ERROR_NONE); - } else { - m->on_read = cb; - m->on_read_out = slices; - } - gpr_mu_unlock(&m->mu); -} - -static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* /*arg*/) { - mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); - for (size_t i = 0; i < slices->count; i++) { - m->on_write(slices->slices[i]); - } - grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, GRPC_ERROR_NONE); -} - -static void me_add_to_pollset(grpc_endpoint* /*ep*/, - grpc_pollset* /*pollset*/) {} - -static void me_add_to_pollset_set(grpc_endpoint* /*ep*/, - grpc_pollset_set* /*pollset*/) {} - -static void me_delete_from_pollset_set(grpc_endpoint* /*ep*/, - grpc_pollset_set* /*pollset*/) {} - -static void me_shutdown(grpc_endpoint* ep, grpc_error_handle why) { - mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); - gpr_mu_lock(&m->mu); - if (m->on_read) { - grpc_core::ExecCtx::Run(DEBUG_LOCATION, m->on_read, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Endpoint Shutdown", &why, 1)); - m->on_read = nullptr; - } - gpr_mu_unlock(&m->mu); - GRPC_ERROR_UNREF(why); -} - -static void me_destroy(grpc_endpoint* ep) { - mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); - grpc_slice_buffer_destroy(&m->read_buffer); - gpr_mu_destroy(&m->mu); - gpr_free(m); -} - -static y_absl::string_view me_get_peer(grpc_endpoint* /*ep*/) { - return "fake:mock_endpoint"; -} - -static y_absl::string_view me_get_local_address(grpc_endpoint* /*ep*/) { - return "fake:mock_endpoint"; -} - -static int me_get_fd(grpc_endpoint* /*ep*/) { return -1; } - -static bool me_can_track_err(grpc_endpoint* /*ep*/) { return false; } - -static const grpc_endpoint_vtable vtable = {me_read, - me_write, - me_add_to_pollset, - me_add_to_pollset_set, - me_delete_from_pollset_set, - me_shutdown, - me_destroy, - me_get_peer, - me_get_local_address, - me_get_fd, - me_can_track_err}; - -grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice)) { - mock_endpoint* m = static_cast<mock_endpoint*>(gpr_malloc(sizeof(*m))); - m->base.vtable = &vtable; - grpc_slice_buffer_init(&m->read_buffer); - gpr_mu_init(&m->mu); - m->on_write = on_write; - m->on_read = nullptr; - return &m->base; -} - -void grpc_mock_endpoint_put_read(grpc_endpoint* ep, grpc_slice slice) { - mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); - gpr_mu_lock(&m->mu); - if (m->on_read != nullptr) { - grpc_slice_buffer_add(m->on_read_out, slice); - grpc_core::ExecCtx::Run(DEBUG_LOCATION, m->on_read, GRPC_ERROR_NONE); - m->on_read = nullptr; - } else { - grpc_slice_buffer_add(&m->read_buffer, slice); - } - gpr_mu_unlock(&m->mu); -} diff --git a/contrib/libs/grpc/test/core/util/mock_endpoint.h b/contrib/libs/grpc/test/core/util/mock_endpoint.h deleted file mode 100644 index 6d52390e09..0000000000 --- a/contrib/libs/grpc/test/core/util/mock_endpoint.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef MOCK_ENDPOINT_H -#define MOCK_ENDPOINT_H - -#include "src/core/lib/iomgr/endpoint.h" - -grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice)); -void grpc_mock_endpoint_put_read(grpc_endpoint* ep, grpc_slice slice); - -#endif diff --git a/contrib/libs/grpc/test/core/util/one_corpus_entry_fuzzer.cc b/contrib/libs/grpc/test/core/util/one_corpus_entry_fuzzer.cc deleted file mode 100644 index fa0f04f025..0000000000 --- a/contrib/libs/grpc/test/core/util/one_corpus_entry_fuzzer.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2016 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 <stdbool.h> - -#include <grpc/grpc.h> -#include <grpc/support/log.h> - -#include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/iomgr/load_file.h" - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); - -extern bool squelch; -extern bool leak_check; - -int main(int argc, char** argv) { - grpc_slice buffer; - squelch = false; - leak_check = false; - /* TODO(yashkt) Calling grpc_init breaks tests. Fix the tests and replace - * grpc_core::ExecCtx::GlobalInit with grpc_init and GlobalShutdown with - * grpc_shutdown */ - GPR_ASSERT(argc > 1); /* Make sure that we have a filename argument */ - GPR_ASSERT( - GRPC_LOG_IF_ERROR("load_file", grpc_load_file(argv[1], 0, &buffer))); - LLVMFuzzerTestOneInput(GRPC_SLICE_START_PTR(buffer), - GRPC_SLICE_LENGTH(buffer)); - grpc_core::ExecCtx::GlobalInit(); - grpc_slice_unref(buffer); - grpc_core::ExecCtx::GlobalShutdown(); - return 0; -} diff --git a/contrib/libs/grpc/test/core/util/parse_hexstring.cc b/contrib/libs/grpc/test/core/util/parse_hexstring.cc deleted file mode 100644 index a65ef99951..0000000000 --- a/contrib/libs/grpc/test/core/util/parse_hexstring.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/util/parse_hexstring.h" - -#include <grpc/support/log.h> - -grpc_slice parse_hexstring(const char* hexstring) { - size_t nibbles = 0; - const char* p = nullptr; - uint8_t* out; - uint8_t temp; - grpc_slice slice; - - for (p = hexstring; *p; p++) { - nibbles += (*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f'); - } - - GPR_ASSERT((nibbles & 1) == 0); - - slice = grpc_slice_malloc(nibbles / 2); - out = GRPC_SLICE_START_PTR(slice); - - nibbles = 0; - temp = 0; - for (p = hexstring; *p; p++) { - if (*p >= '0' && *p <= '9') { - temp = static_cast<uint8_t>(temp << 4) | static_cast<uint8_t>(*p - '0'); - nibbles++; - } else if (*p >= 'a' && *p <= 'f') { - temp = - static_cast<uint8_t>(temp << 4) | static_cast<uint8_t>(*p - 'a' + 10); - nibbles++; - } - if (nibbles == 2) { - *out++ = temp; - nibbles = 0; - } - } - - return slice; -} diff --git a/contrib/libs/grpc/test/core/util/parse_hexstring.h b/contrib/libs/grpc/test/core/util/parse_hexstring.h deleted file mode 100644 index b7d54c1711..0000000000 --- a/contrib/libs/grpc/test/core/util/parse_hexstring.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_PARSE_HEXSTRING_H -#define GRPC_TEST_CORE_UTIL_PARSE_HEXSTRING_H - -#include <grpc/slice.h> - -grpc_slice parse_hexstring(const char* hexstring); - -#endif /* GRPC_TEST_CORE_UTIL_PARSE_HEXSTRING_H */ diff --git a/contrib/libs/grpc/test/core/util/passthru_endpoint.cc b/contrib/libs/grpc/test/core/util/passthru_endpoint.cc deleted file mode 100644 index 080076bcb5..0000000000 --- a/contrib/libs/grpc/test/core/util/passthru_endpoint.cc +++ /dev/null @@ -1,497 +0,0 @@ -/* - * - * Copyright 2016 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 "test/core/util/passthru_endpoint.h" - -#include <inttypes.h> -#include <string.h> - -#include <util/generic/string.h> - -#include "y_absl/strings/str_format.h" - -#include <grpc/support/alloc.h> -#include <grpc/support/string_util.h> - -#include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/iomgr/timer.h" -#include "src/core/lib/slice/slice_internal.h" - -typedef struct passthru_endpoint passthru_endpoint; - -typedef struct { - bool is_armed; - grpc_endpoint* ep; - grpc_slice_buffer* slices; - grpc_closure* cb; -} pending_op; - -typedef struct { - grpc_timer timer; - uint64_t allowed_write_bytes; - uint64_t allowed_read_bytes; - std::vector<grpc_passthru_endpoint_channel_action> actions; - std::function<void()> on_complete; -} grpc_passthru_endpoint_channel_effects; - -typedef struct { - grpc_endpoint base; - passthru_endpoint* parent; - grpc_slice_buffer read_buffer; - grpc_slice_buffer write_buffer; - grpc_slice_buffer* on_read_out; - grpc_closure* on_read; - pending_op pending_read_op; - pending_op pending_write_op; - uint64_t bytes_read_so_far; - uint64_t bytes_written_so_far; -} half; - -struct passthru_endpoint { - gpr_mu mu; - int halves; - grpc_passthru_endpoint_stats* stats; - grpc_passthru_endpoint_channel_effects* channel_effects; - bool simulate_channel_actions; - bool shutdown; - half client; - half server; -}; - -static void do_pending_read_op_locked(half* m, grpc_error_handle error) { - GPR_ASSERT(m->pending_read_op.is_armed); - GPR_ASSERT(m->bytes_read_so_far <= - m->parent->channel_effects->allowed_read_bytes); - if (m->parent->shutdown) { - grpc_core::ExecCtx::Run( - DEBUG_LOCATION, m->pending_read_op.cb, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already shutdown")); - grpc_slice_buffer_reset_and_unref(&m->read_buffer); - m->pending_read_op.is_armed = false; - return; - } - - if (m->bytes_read_so_far == m->parent->channel_effects->allowed_read_bytes) { - // Keep it in pending state. - return; - } - // This delayed processing should only be invoked when read_buffer has - // something in it. - GPR_ASSERT(m->read_buffer.count > 0); - uint64_t readable_length = std::min<uint64_t>( - m->read_buffer.length, - m->parent->channel_effects->allowed_read_bytes - m->bytes_read_so_far); - GPR_ASSERT(readable_length > 0); - grpc_slice_buffer_move_first_no_ref(&m->read_buffer, readable_length, - m->pending_read_op.slices); - grpc_core::ExecCtx::Run(DEBUG_LOCATION, m->pending_read_op.cb, error); - if (m->parent->simulate_channel_actions) { - m->bytes_read_so_far += readable_length; - } - m->pending_read_op.is_armed = false; -} - -static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, bool /*urgent*/) { - half* m = reinterpret_cast<half*>(ep); - gpr_mu_lock(&m->parent->mu); - if (m->parent->shutdown) { - grpc_core::ExecCtx::Run( - DEBUG_LOCATION, cb, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already shutdown")); - } else if (m->read_buffer.count > 0) { - GPR_ASSERT(!m->pending_read_op.is_armed); - GPR_ASSERT(!m->on_read); - m->pending_read_op.is_armed = true; - m->pending_read_op.cb = cb; - m->pending_read_op.ep = ep; - m->pending_read_op.slices = slices; - do_pending_read_op_locked(m, GRPC_ERROR_NONE); - } else { - GPR_ASSERT(!m->pending_read_op.is_armed); - m->on_read = cb; - m->on_read_out = slices; - } - gpr_mu_unlock(&m->parent->mu); -} - -// Copy src slice and split the copy at n bytes into two separate slices -void grpc_slice_copy_split(grpc_slice src, uint64_t n, grpc_slice& split1, - grpc_slice& split2) { - GPR_ASSERT(n <= GRPC_SLICE_LENGTH(src)); - if (n == GRPC_SLICE_LENGTH(src)) { - split1 = grpc_slice_copy(src); - split2 = grpc_empty_slice(); - return; - } - split1 = GRPC_SLICE_MALLOC(n); - memcpy(GRPC_SLICE_START_PTR(split1), GRPC_SLICE_START_PTR(src), n); - split2 = GRPC_SLICE_MALLOC(GRPC_SLICE_LENGTH(src) - n); - memcpy(GRPC_SLICE_START_PTR(split2), GRPC_SLICE_START_PTR(src) + n, - GRPC_SLICE_LENGTH(src) - n); -} - -static half* other_half(half* h) { - if (h == &h->parent->client) return &h->parent->server; - return &h->parent->client; -} - -static void do_pending_write_op_locked(half* m, grpc_error_handle error) { - GPR_ASSERT(m->pending_write_op.is_armed); - GPR_ASSERT(m->bytes_written_so_far <= - m->parent->channel_effects->allowed_write_bytes); - if (m->parent->shutdown) { - grpc_core::ExecCtx::Run( - DEBUG_LOCATION, m->pending_write_op.cb, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Already shutdown")); - m->pending_write_op.is_armed = false; - grpc_slice_buffer_reset_and_unref(m->pending_write_op.slices); - return; - } - if (m->bytes_written_so_far == - m->parent->channel_effects->allowed_write_bytes) { - // Keep it in pending state. - return; - } - - half* other = other_half(m); - uint64_t max_writable = - std::min<uint64_t>(m->pending_write_op.slices->length, - m->parent->channel_effects->allowed_write_bytes - - m->bytes_written_so_far); - uint64_t max_readable = other->parent->channel_effects->allowed_read_bytes - - other->bytes_read_so_far; - uint64_t immediate_bytes_read = - other->on_read != nullptr ? std::min<uint64_t>(max_readable, max_writable) - : 0; - - GPR_ASSERT(max_writable > 0); - GPR_ASSERT(max_readable >= 0); - // At the end of this process, we should have written max_writable bytes; - if (m->parent->simulate_channel_actions) { - m->bytes_written_so_far += max_writable; - } - // Estimate if the original write would still be pending at the end of this - // process - bool would_write_be_pending = - max_writable < m->pending_write_op.slices->length; - if (!m->parent->simulate_channel_actions) { - GPR_ASSERT(!would_write_be_pending); - } - grpc_slice_buffer* slices = m->pending_write_op.slices; - grpc_slice_buffer* dest = - other->on_read != nullptr ? other->on_read_out : &other->read_buffer; - while (max_writable > 0) { - grpc_slice slice = grpc_slice_buffer_take_first(slices); - uint64_t slice_length = GPR_SLICE_LENGTH(slice); - GPR_ASSERT(slice_length > 0); - grpc_slice split1, split2; - uint64_t split_length = 0; - if (slice_length <= max_readable) { - split_length = std::min<uint64_t>(slice_length, max_writable); - } else if (max_readable > 0) { - // slice_length > max_readable - split_length = std::min<uint64_t>(max_readable, max_writable); - } else { - // slice_length still > max_readable but max_readable is 0. - // In this case put the bytes into other->read_buffer. During a future - // read if max_readable still remains zero at the time of read, the - // pending read logic will kick in. - dest = &other->read_buffer; - split_length = std::min<uint64_t>(slice_length, max_writable); - } - - grpc_slice_copy_split(slice, split_length, split1, split2); - grpc_slice_unref_internal(slice); - // Write a copy of the slice to the destination to be read - grpc_slice_buffer_add_indexed(dest, split1); - // Re-insert split2 into source for next iteration. - if (GPR_SLICE_LENGTH(split2) > 0) { - grpc_slice_buffer_undo_take_first(slices, split2); - } else { - grpc_slice_unref_internal(split2); - } - - if (max_readable > 0) { - GPR_ASSERT(max_readable >= static_cast<uint64_t>(split_length)); - max_readable -= split_length; - } - - GPR_ASSERT(max_writable >= static_cast<uint64_t>(split_length)); - max_writable -= split_length; - } - - if (immediate_bytes_read > 0) { - GPR_ASSERT(!other->pending_read_op.is_armed); - if (m->parent->simulate_channel_actions) { - other->bytes_read_so_far += immediate_bytes_read; - } - grpc_core::ExecCtx::Run(DEBUG_LOCATION, other->on_read, error); - other->on_read = nullptr; - } - - if (!would_write_be_pending) { - // No slices should be left - GPR_ASSERT(m->pending_write_op.slices->count == 0); - grpc_slice_buffer_reset_and_unref(m->pending_write_op.slices); - m->pending_write_op.is_armed = false; - grpc_core::ExecCtx::Run(DEBUG_LOCATION, m->pending_write_op.cb, error); - } -} - -static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* /*arg*/) { - half* m = reinterpret_cast<half*>(ep); - gpr_mu_lock(&m->parent->mu); - gpr_atm_no_barrier_fetch_add(&m->parent->stats->num_writes, (gpr_atm)1); - if (m->parent->shutdown) { - grpc_core::ExecCtx::Run( - DEBUG_LOCATION, cb, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Endpoint already shutdown")); - } else { - GPR_ASSERT(!m->pending_write_op.is_armed); - // Copy slices into m->pending_write_op.slices - m->pending_write_op.slices = &m->write_buffer; - GPR_ASSERT(m->pending_write_op.slices->count == 0); - for (int i = 0; i < static_cast<int>(slices->count); i++) { - if (GPR_SLICE_LENGTH(slices->slices[i]) > 0) { - grpc_slice_buffer_add_indexed(m->pending_write_op.slices, - grpc_slice_copy(slices->slices[i])); - } - } - if (m->pending_write_op.slices->count > 0) { - m->pending_write_op.is_armed = true; - m->pending_write_op.cb = cb; - m->pending_write_op.ep = ep; - do_pending_write_op_locked(m, GRPC_ERROR_NONE); - } else { - // There is nothing to write. Schedule callback to be run right away. - grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, GRPC_ERROR_NONE); - } - } - gpr_mu_unlock(&m->parent->mu); -} - -void flush_pending_ops_locked(half* m, grpc_error_handle error) { - if (m->pending_read_op.is_armed) { - do_pending_read_op_locked(m, error); - } - if (m->pending_write_op.is_armed) { - do_pending_write_op_locked(m, error); - } -} - -static void me_add_to_pollset(grpc_endpoint* /*ep*/, - grpc_pollset* /*pollset*/) {} - -static void me_add_to_pollset_set(grpc_endpoint* /*ep*/, - grpc_pollset_set* /*pollset*/) {} - -static void me_delete_from_pollset_set(grpc_endpoint* /*ep*/, - grpc_pollset_set* /*pollset*/) {} - -static void me_shutdown(grpc_endpoint* ep, grpc_error_handle why) { - half* m = reinterpret_cast<half*>(ep); - gpr_mu_lock(&m->parent->mu); - m->parent->shutdown = true; - flush_pending_ops_locked(m, GRPC_ERROR_NONE); - if (m->on_read) { - grpc_core::ExecCtx::Run( - DEBUG_LOCATION, m->on_read, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Shutdown", &why, 1)); - m->on_read = nullptr; - } - m = other_half(m); - flush_pending_ops_locked(m, GRPC_ERROR_NONE); - if (m->on_read) { - grpc_core::ExecCtx::Run( - DEBUG_LOCATION, m->on_read, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Shutdown", &why, 1)); - m->on_read = nullptr; - } - gpr_mu_unlock(&m->parent->mu); - GRPC_ERROR_UNREF(why); -} - -void grpc_passthru_endpoint_destroy(passthru_endpoint* p) { - gpr_mu_destroy(&p->mu); - grpc_passthru_endpoint_stats_destroy(p->stats); - delete p->channel_effects; - grpc_slice_buffer_destroy_internal(&p->client.read_buffer); - grpc_slice_buffer_destroy_internal(&p->server.read_buffer); - grpc_slice_buffer_destroy_internal(&p->client.write_buffer); - grpc_slice_buffer_destroy_internal(&p->server.write_buffer); - gpr_free(p); -} - -static void me_destroy(grpc_endpoint* ep) { - passthru_endpoint* p = (reinterpret_cast<half*>(ep))->parent; - gpr_mu_lock(&p->mu); - if (0 == --p->halves && p->channel_effects->actions.empty()) { - // no pending channel actions exist - gpr_mu_unlock(&p->mu); - grpc_passthru_endpoint_destroy(p); - } else { - if (p->halves == 0 && p->simulate_channel_actions) { - grpc_timer_cancel(&p->channel_effects->timer); - } - gpr_mu_unlock(&p->mu); - } -} - -static y_absl::string_view me_get_peer(grpc_endpoint* ep) { - passthru_endpoint* p = (reinterpret_cast<half*>(ep))->parent; - return (reinterpret_cast<half*>(ep)) == &p->client - ? "fake:mock_client_endpoint" - : "fake:mock_server_endpoint"; -} - -static y_absl::string_view me_get_local_address(grpc_endpoint* ep) { - passthru_endpoint* p = (reinterpret_cast<half*>(ep))->parent; - return (reinterpret_cast<half*>(ep)) == &p->client - ? "fake:mock_client_endpoint" - : "fake:mock_server_endpoint"; -} - -static int me_get_fd(grpc_endpoint* /*ep*/) { return -1; } - -static bool me_can_track_err(grpc_endpoint* /*ep*/) { return false; } - -static const grpc_endpoint_vtable vtable = { - me_read, - me_write, - me_add_to_pollset, - me_add_to_pollset_set, - me_delete_from_pollset_set, - me_shutdown, - me_destroy, - me_get_peer, - me_get_local_address, - me_get_fd, - me_can_track_err, -}; - -static void half_init(half* m, passthru_endpoint* parent, - const char* half_name) { - m->base.vtable = &vtable; - m->parent = parent; - grpc_slice_buffer_init(&m->read_buffer); - grpc_slice_buffer_init(&m->write_buffer); - m->pending_write_op.slices = nullptr; - m->on_read = nullptr; - m->bytes_read_so_far = 0; - m->bytes_written_so_far = 0; - m->pending_write_op.is_armed = false; - m->pending_read_op.is_armed = false; - TString name = - y_absl::StrFormat("passthru_endpoint_%s_%p", half_name, parent); -} - -void grpc_passthru_endpoint_create(grpc_endpoint** client, - grpc_endpoint** server, - grpc_passthru_endpoint_stats* stats, - bool simulate_channel_actions) { - passthru_endpoint* m = - static_cast<passthru_endpoint*>(gpr_malloc(sizeof(*m))); - m->halves = 2; - m->shutdown = false; - if (stats == nullptr) { - m->stats = grpc_passthru_endpoint_stats_create(); - } else { - gpr_ref(&stats->refs); - m->stats = stats; - } - m->channel_effects = new grpc_passthru_endpoint_channel_effects(); - m->simulate_channel_actions = simulate_channel_actions; - if (!simulate_channel_actions) { - m->channel_effects->allowed_read_bytes = UINT64_MAX; - m->channel_effects->allowed_write_bytes = UINT64_MAX; - } - half_init(&m->client, m, "client"); - half_init(&m->server, m, "server"); - gpr_mu_init(&m->mu); - *client = &m->client.base; - *server = &m->server.base; -} - -grpc_passthru_endpoint_stats* grpc_passthru_endpoint_stats_create() { - grpc_passthru_endpoint_stats* stats = - static_cast<grpc_passthru_endpoint_stats*>( - gpr_malloc(sizeof(grpc_passthru_endpoint_stats))); - memset(stats, 0, sizeof(*stats)); - gpr_ref_init(&stats->refs, 1); - return stats; -} - -void grpc_passthru_endpoint_stats_destroy(grpc_passthru_endpoint_stats* stats) { - if (gpr_unref(&stats->refs)) { - gpr_free(stats); - } -} - -static void sched_next_channel_action_locked(half* m); - -static void do_next_sched_channel_action(void* arg, grpc_error_handle error) { - half* m = reinterpret_cast<half*>(arg); - gpr_mu_lock(&m->parent->mu); - GPR_ASSERT(!m->parent->channel_effects->actions.empty()); - if (m->parent->halves == 0) { - gpr_mu_unlock(&m->parent->mu); - grpc_passthru_endpoint_destroy(m->parent); - return; - } - auto curr_action = m->parent->channel_effects->actions[0]; - m->parent->channel_effects->actions.erase( - m->parent->channel_effects->actions.begin()); - m->parent->channel_effects->allowed_read_bytes += - curr_action.add_n_readable_bytes; - m->parent->channel_effects->allowed_write_bytes += - curr_action.add_n_writable_bytes; - flush_pending_ops_locked(m, error); - flush_pending_ops_locked(other_half(m), error); - sched_next_channel_action_locked(m); - gpr_mu_unlock(&m->parent->mu); -} - -static void sched_next_channel_action_locked(half* m) { - if (m->parent->channel_effects->actions.empty()) { - m->parent->channel_effects->on_complete(); - return; - } - grpc_timer_init(&m->parent->channel_effects->timer, - m->parent->channel_effects->actions[0].wait_ms + - grpc_core::ExecCtx::Get()->Now(), - GRPC_CLOSURE_CREATE(do_next_sched_channel_action, m, - grpc_schedule_on_exec_ctx)); -} - -void start_scheduling_grpc_passthru_endpoint_channel_effects( - grpc_endpoint* ep, - const std::vector<grpc_passthru_endpoint_channel_action>& actions, - std::function<void()> on_complete) { - half* m = reinterpret_cast<half*>(ep); - gpr_mu_lock(&m->parent->mu); - if (!m->parent->simulate_channel_actions || m->parent->shutdown) { - gpr_mu_unlock(&m->parent->mu); - return; - } - m->parent->channel_effects->actions = actions; - m->parent->channel_effects->on_complete = std::move(on_complete); - sched_next_channel_action_locked(m); - gpr_mu_unlock(&m->parent->mu); -} diff --git a/contrib/libs/grpc/test/core/util/passthru_endpoint.h b/contrib/libs/grpc/test/core/util/passthru_endpoint.h deleted file mode 100644 index b34cbc25f9..0000000000 --- a/contrib/libs/grpc/test/core/util/passthru_endpoint.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef PASSTHRU_ENDPOINT_H -#define PASSTHRU_ENDPOINT_H - -#include <grpc/support/atm.h> - -#include "src/core/lib/iomgr/endpoint.h" - -/* The struct is refcounted, always use grpc_passthru_endpoint_stats_create and - * grpc_passthru_endpoint_stats_destroy, rather then embedding it in your - * objects by value. */ -typedef struct { - gpr_refcount refs; - gpr_atm num_writes; -} grpc_passthru_endpoint_stats; - -typedef struct { - uint64_t wait_ms; - uint64_t add_n_writable_bytes; - uint64_t add_n_readable_bytes; -} grpc_passthru_endpoint_channel_action; - -void grpc_passthru_endpoint_create(grpc_endpoint** client, - grpc_endpoint** server, - grpc_passthru_endpoint_stats* stats, - bool simulate_channel_actions = false); - -grpc_passthru_endpoint_stats* grpc_passthru_endpoint_stats_create(); - -void grpc_passthru_endpoint_stats_destroy(grpc_passthru_endpoint_stats* stats); - -void start_scheduling_grpc_passthru_endpoint_channel_effects( - grpc_endpoint* ep, - const std::vector<grpc_passthru_endpoint_channel_action>& actions, - std::function<void()> on_complete); - -#endif // PASSTHRU_ENDPOINT_H diff --git a/contrib/libs/grpc/test/core/util/port_isolated_runtime_environment.cc b/contrib/libs/grpc/test/core/util/port_isolated_runtime_environment.cc deleted file mode 100644 index 6d32aeb4cd..0000000000 --- a/contrib/libs/grpc/test/core/util/port_isolated_runtime_environment.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * Copyright 2017 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. - * - */ - -/* When individual tests run in an isolated runtime environment (e.g. each test - * runs in a separate container) the framework takes a round-robin pick of a - * port within certain range. There is no need to recycle ports. - */ -#include <stdlib.h> - -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> - -#include "src/core/lib/iomgr/port.h" -#include "test/core/util/test_config.h" -#if defined(GRPC_PORT_ISOLATED_RUNTIME) - -#include "test/core/util/port.h" - -#define MIN_PORT 1025 -#define MAX_PORT 32766 - -static int get_random_port_offset() { - srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); - double rnd = static_cast<double>(rand()) / - (static_cast<double>(RAND_MAX) + 1.0); // values from [0,1) - return static_cast<int>(rnd * (MAX_PORT - MIN_PORT + 1)); -} - -static int s_initial_offset = get_random_port_offset(); -static gpr_atm s_pick_counter = 0; - -static int grpc_pick_unused_port_or_die_impl(void) { - int orig_counter_val = - static_cast<int>(gpr_atm_full_fetch_add(&s_pick_counter, 1)); - GPR_ASSERT(orig_counter_val < (MAX_PORT - MIN_PORT + 1)); - return MIN_PORT + - (s_initial_offset + orig_counter_val) % (MAX_PORT - MIN_PORT + 1); -} - -int grpc_pick_unused_port_or_die(void) { - while (true) { - int port = grpc_pick_unused_port_or_die_impl(); - // 5985 cannot be bound on Windows RBE and results in - // WSA_ERROR 10013: "An attempt was made to access a socket in a way - // forbidden by its access permissions." - if (port == 5985) { - continue; - } - return port; - } -} - -void grpc_recycle_unused_port(int port) { (void)port; } - -#endif /* GRPC_PORT_ISOLATED_RUNTIME */ diff --git a/contrib/libs/grpc/test/core/util/reconnect_server.cc b/contrib/libs/grpc/test/core/util/reconnect_server.cc deleted file mode 100644 index 7ce4b6fbe8..0000000000 --- a/contrib/libs/grpc/test/core/util/reconnect_server.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/util/reconnect_server.h" - -#include <string.h> - -#include "y_absl/strings/string_view.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpc/support/sync.h> -#include <grpc/support/time.h> - -#include "src/core/lib/iomgr/endpoint.h" -#include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/iomgr/tcp_server.h" -#include "test/core/util/port.h" -#include "test/core/util/test_tcp_server.h" - -static void pretty_print_backoffs(reconnect_server* server) { - gpr_timespec diff; - int i = 1; - double expected_backoff = 1000.0, backoff; - timestamp_list* head = server->head; - gpr_log(GPR_INFO, "reconnect server: new connection"); - for (head = server->head; head && head->next; head = head->next, i++) { - diff = gpr_time_sub(head->next->timestamp, head->timestamp); - backoff = gpr_time_to_millis(diff); - gpr_log(GPR_INFO, - "retry %2d:backoff %6.2fs,expected backoff %6.2fs, jitter %4.2f%%", - i, backoff / 1000.0, expected_backoff / 1000.0, - (backoff - expected_backoff) * 100.0 / expected_backoff); - expected_backoff *= 1.6; - int max_reconnect_backoff_ms = 120 * 1000; - if (server->max_reconnect_backoff_ms > 0) { - max_reconnect_backoff_ms = server->max_reconnect_backoff_ms; - } - if (expected_backoff > max_reconnect_backoff_ms) { - expected_backoff = max_reconnect_backoff_ms; - } - } -} - -static void on_connect(void* arg, grpc_endpoint* tcp, - grpc_pollset* /*accepting_pollset*/, - grpc_tcp_server_acceptor* acceptor) { - gpr_free(acceptor); - y_absl::string_view peer; - y_absl::string_view::size_type last_colon; - reconnect_server* server = static_cast<reconnect_server*>(arg); - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - timestamp_list* new_tail; - peer = grpc_endpoint_get_peer(tcp); - grpc_endpoint_shutdown(tcp, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected")); - grpc_endpoint_destroy(tcp); - last_colon = peer.rfind(':'); - if (server->peer == nullptr) { - server->peer = new TString(peer); - } else { - if (last_colon == TString::npos) { - gpr_log(GPR_ERROR, "peer does not contain a ':'"); - } else if (peer.compare(0, static_cast<size_t>(last_colon), - *server->peer) != 0) { - gpr_log(GPR_ERROR, "mismatched peer! %s vs %s", server->peer->c_str(), - TString(peer).c_str()); - } - } - new_tail = static_cast<timestamp_list*>(gpr_malloc(sizeof(timestamp_list))); - new_tail->timestamp = now; - new_tail->next = nullptr; - if (server->tail == nullptr) { - server->head = new_tail; - server->tail = new_tail; - } else { - server->tail->next = new_tail; - server->tail = new_tail; - } - pretty_print_backoffs(server); -} - -void reconnect_server_init(reconnect_server* server) { - test_tcp_server_init(&server->tcp_server, on_connect, server); - server->head = nullptr; - server->tail = nullptr; - server->peer = nullptr; - server->max_reconnect_backoff_ms = 0; -} - -void reconnect_server_start(reconnect_server* server, int port) { - test_tcp_server_start(&server->tcp_server, port); -} - -void reconnect_server_poll(reconnect_server* server, int seconds) { - test_tcp_server_poll(&server->tcp_server, 1000 * seconds); -} - -void reconnect_server_clear_timestamps(reconnect_server* server) { - timestamp_list* new_head = server->head; - while (server->head) { - new_head = server->head->next; - gpr_free(server->head); - server->head = new_head; - } - server->tail = nullptr; - delete server->peer; - server->peer = nullptr; -} - -void reconnect_server_destroy(reconnect_server* server) { - reconnect_server_clear_timestamps(server); - test_tcp_server_destroy(&server->tcp_server); -} diff --git a/contrib/libs/grpc/test/core/util/reconnect_server.h b/contrib/libs/grpc/test/core/util/reconnect_server.h deleted file mode 100644 index 6f63f9293d..0000000000 --- a/contrib/libs/grpc/test/core/util/reconnect_server.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Copyright 2015-2016 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_RECONNECT_SERVER_H -#define GRPC_TEST_CORE_UTIL_RECONNECT_SERVER_H - -#include <grpc/support/sync.h> -#include <grpc/support/time.h> - -#include "test/core/util/test_tcp_server.h" - -typedef struct timestamp_list { - gpr_timespec timestamp; - struct timestamp_list* next; -} timestamp_list; - -typedef struct reconnect_server { - test_tcp_server tcp_server; - timestamp_list* head; - timestamp_list* tail; - TString* peer; - int max_reconnect_backoff_ms; -} reconnect_server; - -void reconnect_server_init(reconnect_server* server); -void reconnect_server_start(reconnect_server* server, int port); -void reconnect_server_poll(reconnect_server* server, int seconds); -void reconnect_server_destroy(reconnect_server* server); -void reconnect_server_clear_timestamps(reconnect_server* server); - -#endif /* GRPC_TEST_CORE_UTIL_RECONNECT_SERVER_H */ diff --git a/contrib/libs/grpc/test/core/util/resolve_localhost_ip46.cc b/contrib/libs/grpc/test/core/util/resolve_localhost_ip46.cc deleted file mode 100644 index bf3f621c17..0000000000 --- a/contrib/libs/grpc/test/core/util/resolve_localhost_ip46.cc +++ /dev/null @@ -1,58 +0,0 @@ -// -// -// 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. -// -// - -#include "test/core/util/resolve_localhost_ip46.h" - -#include <grpc/support/log.h> - -#include "src/core/lib/iomgr/port.h" -#include "src/core/lib/iomgr/resolve_address.h" -#include "src/core/lib/iomgr/sockaddr.h" - -namespace grpc_core { -namespace { - -bool localhost_to_ipv4 = false; -bool localhost_to_ipv6 = false; -gpr_once g_resolve_localhost_ipv46 = GPR_ONCE_INIT; - -void InitResolveLocalhost() { - grpc_resolved_addresses* addresses; - grpc_error_handle err = - grpc_blocking_resolve_address("localhost", "https", &addresses); - GPR_ASSERT(err == GRPC_ERROR_NONE); - for (size_t i = 0; i < addresses->naddrs; i++) { - grpc_sockaddr* addr = - reinterpret_cast<grpc_sockaddr*>(addresses->addrs[i].addr); - if (addr->sa_family == GRPC_AF_INET) { - localhost_to_ipv4 = true; - } else if (addr->sa_family == GRPC_AF_INET6) { - localhost_to_ipv6 = true; - } - } - grpc_resolved_addresses_destroy(addresses); -} -} // namespace - -void LocalhostResolves(bool* ipv4, bool* ipv6) { - gpr_once_init(&g_resolve_localhost_ipv46, InitResolveLocalhost); - *ipv4 = localhost_to_ipv4; - *ipv6 = localhost_to_ipv6; -} - -} // namespace grpc_core diff --git a/contrib/libs/grpc/test/core/util/resolve_localhost_ip46.h b/contrib/libs/grpc/test/core/util/resolve_localhost_ip46.h deleted file mode 100644 index d8f7883adf..0000000000 --- a/contrib/libs/grpc/test/core/util/resolve_localhost_ip46.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// -// 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. -// -// - -#ifndef GRPC_TEST_CORE_UTIL_RESOLVE_LOCALHOST_IP46_H_ -#define GRPC_TEST_CORE_UTIL_RESOLVE_LOCALHOST_IP46_H_ - -namespace grpc_core { - -// Test whether localhost resolves to ipv4 and/or ipv6 -void LocalhostResolves(bool* ipv4, bool* ipv6); - -} // namespace grpc_core - -#endif // GRPC_TEST_CORE_UTIL_RESOLVE_LOCALHOST_IP46_H_ diff --git a/contrib/libs/grpc/test/core/util/run_with_poller.sh b/contrib/libs/grpc/test/core/util/run_with_poller.sh deleted file mode 100755 index 382a63e8ae..0000000000 --- a/contrib/libs/grpc/test/core/util/run_with_poller.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# Copyright 2017 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. - -set -ex -export GRPC_POLL_STRATEGY=$1 -shift -"$@" diff --git a/contrib/libs/grpc/test/core/util/slice_splitter.cc b/contrib/libs/grpc/test/core/util/slice_splitter.cc deleted file mode 100644 index 82864d6abf..0000000000 --- a/contrib/libs/grpc/test/core/util/slice_splitter.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/util/slice_splitter.h" - -#include <string.h> - -#include <algorithm> - -#include <grpc/support/alloc.h> - -#include "src/core/lib/gpr/useful.h" - -const char* grpc_slice_split_mode_name(grpc_slice_split_mode mode) { - switch (mode) { - case GRPC_SLICE_SPLIT_IDENTITY: - return "identity"; - case GRPC_SLICE_SPLIT_MERGE_ALL: - return "merge_all"; - case GRPC_SLICE_SPLIT_ONE_BYTE: - return "one_byte"; - } - return "error"; -} - -void grpc_split_slices(grpc_slice_split_mode mode, grpc_slice* src_slices, - size_t src_slice_count, grpc_slice** dst_slices, - size_t* dst_slice_count) { - size_t i, j; - size_t length; - - switch (mode) { - case GRPC_SLICE_SPLIT_IDENTITY: - *dst_slice_count = src_slice_count; - *dst_slices = static_cast<grpc_slice*>( - gpr_malloc(sizeof(grpc_slice) * src_slice_count)); - for (i = 0; i < src_slice_count; i++) { - (*dst_slices)[i] = src_slices[i]; - grpc_slice_ref((*dst_slices)[i]); - } - break; - case GRPC_SLICE_SPLIT_MERGE_ALL: - *dst_slice_count = 1; - length = 0; - for (i = 0; i < src_slice_count; i++) { - length += GRPC_SLICE_LENGTH(src_slices[i]); - } - *dst_slices = static_cast<grpc_slice*>(gpr_malloc(sizeof(grpc_slice))); - **dst_slices = grpc_slice_malloc(length); - length = 0; - for (i = 0; i < src_slice_count; i++) { - memcpy(GRPC_SLICE_START_PTR(**dst_slices) + length, - GRPC_SLICE_START_PTR(src_slices[i]), - GRPC_SLICE_LENGTH(src_slices[i])); - length += GRPC_SLICE_LENGTH(src_slices[i]); - } - break; - case GRPC_SLICE_SPLIT_ONE_BYTE: - length = 0; - for (i = 0; i < src_slice_count; i++) { - length += GRPC_SLICE_LENGTH(src_slices[i]); - } - *dst_slice_count = length; - *dst_slices = - static_cast<grpc_slice*>(gpr_malloc(sizeof(grpc_slice) * length)); - length = 0; - for (i = 0; i < src_slice_count; i++) { - for (j = 0; j < GRPC_SLICE_LENGTH(src_slices[i]); j++) { - (*dst_slices)[length] = grpc_slice_sub(src_slices[i], j, j + 1); - length++; - } - } - break; - } -} - -void grpc_split_slices_to_buffer(grpc_slice_split_mode mode, - grpc_slice* src_slices, size_t src_slice_count, - grpc_slice_buffer* dst) { - grpc_slice* slices; - size_t nslices; - size_t i; - grpc_split_slices(mode, src_slices, src_slice_count, &slices, &nslices); - for (i = 0; i < nslices; i++) { - /* add indexed to avoid re-merging split slices */ - grpc_slice_buffer_add_indexed(dst, slices[i]); - } - gpr_free(slices); -} - -void grpc_split_slice_buffer(grpc_slice_split_mode mode, grpc_slice_buffer* src, - grpc_slice_buffer* dst) { - grpc_split_slices_to_buffer(mode, src->slices, src->count, dst); -} - -grpc_slice grpc_slice_merge(grpc_slice* slices, size_t nslices) { - uint8_t* out = nullptr; - size_t length = 0; - size_t capacity = 0; - size_t i; - - for (i = 0; i < nslices; i++) { - if (GRPC_SLICE_LENGTH(slices[i]) + length > capacity) { - capacity = std::max(capacity * 2, GRPC_SLICE_LENGTH(slices[i]) + length); - out = static_cast<uint8_t*>(gpr_realloc(out, capacity)); - } - memcpy(out + length, GRPC_SLICE_START_PTR(slices[i]), - GRPC_SLICE_LENGTH(slices[i])); - length += GRPC_SLICE_LENGTH(slices[i]); - } - - return grpc_slice_new(out, length, gpr_free); -} diff --git a/contrib/libs/grpc/test/core/util/slice_splitter.h b/contrib/libs/grpc/test/core/util/slice_splitter.h deleted file mode 100644 index 65b9f6f7df..0000000000 --- a/contrib/libs/grpc/test/core/util/slice_splitter.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_SLICE_SPLITTER_H -#define GRPC_TEST_CORE_UTIL_SLICE_SPLITTER_H - -/* utility function to split/merge slices together to help create test - cases */ - -#include <grpc/slice.h> -#include <grpc/slice_buffer.h> - -typedef enum { - /* merge all input slices into a single slice */ - GRPC_SLICE_SPLIT_MERGE_ALL, - /* leave slices as is */ - GRPC_SLICE_SPLIT_IDENTITY, - /* split slices into one byte chunks */ - GRPC_SLICE_SPLIT_ONE_BYTE -} grpc_slice_split_mode; - -/* allocates *dst_slices; caller must unref all slices in dst_slices then free - it */ -void grpc_split_slices(grpc_slice_split_mode mode, grpc_slice* src_slices, - size_t src_slice_count, grpc_slice** dst_slices, - size_t* dst_slice_count); - -void grpc_split_slices_to_buffer(grpc_slice_split_mode mode, - grpc_slice* src_slices, size_t src_slice_count, - grpc_slice_buffer* dst); -void grpc_split_slice_buffer(grpc_slice_split_mode mode, grpc_slice_buffer* src, - grpc_slice_buffer* dst); - -grpc_slice grpc_slice_merge(grpc_slice* slices, size_t nslices); - -const char* grpc_slice_split_mode_name(grpc_slice_split_mode mode); - -#endif /* GRPC_TEST_CORE_UTIL_SLICE_SPLITTER_H */ diff --git a/contrib/libs/grpc/test/core/util/stack_tracer_test.cc b/contrib/libs/grpc/test/core/util/stack_tracer_test.cc deleted file mode 100644 index c610c96841..0000000000 --- a/contrib/libs/grpc/test/core/util/stack_tracer_test.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * 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. - * - */ - -#include "test/core/util/stack_tracer.h" - -#include <util/generic/string.h> - -#include <gtest/gtest.h> - -#include "y_absl/debugging/symbolize.h" -#include "y_absl/strings/match.h" - -#include <grpc/support/log.h> - -#include "test/core/util/test_config.h" - -TEST(StackTracerTest, Basic) { - TString stack_trace = grpc_core::testing::GetCurrentStackTrace(); - gpr_log(GPR_INFO, "stack_trace=%s", stack_trace.c_str()); -#if !defined(NDEBUG) && !defined(GPR_MUSL_LIBC_COMPAT) - EXPECT_TRUE(y_absl::StrContains(stack_trace, "Basic")); -#endif -} - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/core/util/subprocess.h b/contrib/libs/grpc/test/core/util/subprocess.h deleted file mode 100644 index c7fe9af435..0000000000 --- a/contrib/libs/grpc/test/core/util/subprocess.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_SUBPROCESS_H -#define GRPC_TEST_CORE_UTIL_SUBPROCESS_H - -#include <grpc/support/port_platform.h> - -typedef struct gpr_subprocess gpr_subprocess; - -/** .exe on windows, empty on unices */ -const char* gpr_subprocess_binary_extension(); - -gpr_subprocess* gpr_subprocess_create(int argc, const char** argv); -/** if subprocess has not been joined, kill it */ -void gpr_subprocess_destroy(gpr_subprocess* p); -/** returns exit status; can be called at most once */ -int gpr_subprocess_join(gpr_subprocess* p); -void gpr_subprocess_interrupt(gpr_subprocess* p); - -#endif /* GRPC_TEST_CORE_UTIL_SUBPROCESS_H */ diff --git a/contrib/libs/grpc/test/core/util/subprocess_posix.cc b/contrib/libs/grpc/test/core/util/subprocess_posix.cc deleted file mode 100644 index 6136314293..0000000000 --- a/contrib/libs/grpc/test/core/util/subprocess_posix.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - * - * Copyright 2015 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 <grpc/support/port_platform.h> - -#ifdef GPR_POSIX_SUBPROCESS - -#include <assert.h> -#include <errno.h> -#include <signal.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> - -#include "src/core/lib/gprpp/memory.h" -#include "test/core/util/subprocess.h" - -struct gpr_subprocess { - int pid; - bool joined; -}; - -const char* gpr_subprocess_binary_extension() { return ""; } - -gpr_subprocess* gpr_subprocess_create(int argc, const char** argv) { - gpr_subprocess* r; - int pid; - char** exec_args; - - pid = fork(); - if (pid == -1) { - return nullptr; - } else if (pid == 0) { - exec_args = static_cast<char**>( - gpr_malloc((static_cast<size_t>(argc) + 1) * sizeof(char*))); - memcpy(exec_args, argv, static_cast<size_t>(argc) * sizeof(char*)); - exec_args[argc] = nullptr; - execv(exec_args[0], exec_args); - /* if we reach here, an error has occurred */ - gpr_log(GPR_ERROR, "execv '%s' failed: %s", exec_args[0], strerror(errno)); - _exit(1); - } else { - r = grpc_core::Zalloc<gpr_subprocess>(); - r->pid = pid; - return r; - } -} - -void gpr_subprocess_destroy(gpr_subprocess* p) { - if (!p->joined) { - kill(p->pid, SIGKILL); - gpr_subprocess_join(p); - } - gpr_free(p); -} - -int gpr_subprocess_join(gpr_subprocess* p) { - int status; -retry: - if (waitpid(p->pid, &status, 0) == -1) { - if (errno == EINTR) { - goto retry; - } - gpr_log(GPR_ERROR, "waitpid failed for pid %d: %s", p->pid, - strerror(errno)); - return -1; - } - p->joined = true; - return status; -} - -void gpr_subprocess_interrupt(gpr_subprocess* p) { - if (!p->joined) { - kill(p->pid, SIGINT); - } -} - -#endif /* GPR_POSIX_SUBPROCESS */ diff --git a/contrib/libs/grpc/test/core/util/subprocess_windows.cc b/contrib/libs/grpc/test/core/util/subprocess_windows.cc deleted file mode 100644 index 7d69af1368..0000000000 --- a/contrib/libs/grpc/test/core/util/subprocess_windows.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* - * - * Copyright 2016 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 <grpc/support/port_platform.h> - -#ifdef GPR_WINDOWS_SUBPROCESS - -#include <string.h> -#include <tchar.h> -#include <windows.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> - -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gpr/string_windows.h" -#include "test/core/util/subprocess.h" - -struct gpr_subprocess { - PROCESS_INFORMATION pi; - int joined; - int interrupted; -}; - -const char* gpr_subprocess_binary_extension() { return ".exe"; } - -gpr_subprocess* gpr_subprocess_create(int argc, const char** argv) { - gpr_subprocess* r; - - STARTUPINFO si; - PROCESS_INFORMATION pi; - - char* args = gpr_strjoin_sep(argv, (size_t)argc, " ", NULL); - TCHAR* args_tchar; - - args_tchar = gpr_char_to_tchar(args); - gpr_free(args); - - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - memset(&pi, 0, sizeof(pi)); - - if (!CreateProcess(NULL, args_tchar, NULL, NULL, FALSE, - CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) { - gpr_free(args_tchar); - return NULL; - } - gpr_free(args_tchar); - - r = (gpr_subprocess*)gpr_malloc(sizeof(gpr_subprocess)); - memset(r, 0, sizeof(*r)); - r->pi = pi; - return r; -} - -void gpr_subprocess_destroy(gpr_subprocess* p) { - if (p) { - if (!p->joined) { - gpr_subprocess_interrupt(p); - gpr_subprocess_join(p); - } - if (p->pi.hProcess) { - CloseHandle(p->pi.hProcess); - } - if (p->pi.hThread) { - CloseHandle(p->pi.hThread); - } - gpr_free(p); - } -} - -int gpr_subprocess_join(gpr_subprocess* p) { - DWORD dwExitCode; - if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { - if (dwExitCode == STILL_ACTIVE) { - if (WaitForSingleObject(p->pi.hProcess, INFINITE) == WAIT_OBJECT_0) { - p->joined = 1; - goto getExitCode; - } - return -1; // failed to join - } else { - goto getExitCode; - } - } else { - return -1; // failed to get exit code - } - -getExitCode: - if (p->interrupted) { - return 0; - } - if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { - return (int)dwExitCode; - } else { - return -1; // failed to get exit code - } -} - -void gpr_subprocess_interrupt(gpr_subprocess* p) { - DWORD dwExitCode; - if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { - if (dwExitCode == STILL_ACTIVE) { - gpr_log(GPR_INFO, "sending ctrl-break"); - GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, p->pi.dwProcessId); - p->joined = 1; - p->interrupted = 1; - } - } - return; -} - -#endif /* GPR_WINDOWS_SUBPROCESS */ diff --git a/contrib/libs/grpc/test/core/util/test_tcp_server.cc b/contrib/libs/grpc/test/core/util/test_tcp_server.cc deleted file mode 100644 index 57d6c21374..0000000000 --- a/contrib/libs/grpc/test/core/util/test_tcp_server.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * - * Copyright 2015 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 "test/core/util/test_tcp_server.h" - -#include <string.h> - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/sync.h> -#include <grpc/support/time.h> - -#include "src/core/lib/iomgr/endpoint.h" -#include "src/core/lib/iomgr/resolve_address.h" -#include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/iomgr/socket_utils.h" -#include "src/core/lib/iomgr/tcp_server.h" -#include "src/core/lib/resource_quota/api.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -static void on_server_destroyed(void* data, grpc_error_handle /*error*/) { - test_tcp_server* server = static_cast<test_tcp_server*>(data); - server->shutdown = true; -} - -void test_tcp_server_init(test_tcp_server* server, - grpc_tcp_server_cb on_connect, void* user_data) { - grpc_init(); - GRPC_CLOSURE_INIT(&server->shutdown_complete, on_server_destroyed, server, - grpc_schedule_on_exec_ctx); - - grpc_pollset* pollset = - static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); - grpc_pollset_init(pollset, &server->mu); - server->pollset.push_back(pollset); - server->on_connect = on_connect; - server->cb_data = user_data; -} - -void test_tcp_server_start(test_tcp_server* server, int port) { - grpc_resolved_address resolved_addr; - grpc_sockaddr_in* addr = - reinterpret_cast<grpc_sockaddr_in*>(resolved_addr.addr); - int port_added; - grpc_core::ExecCtx exec_ctx; - - addr->sin_family = GRPC_AF_INET; - addr->sin_port = grpc_htons(static_cast<uint16_t>(port)); - memset(&addr->sin_addr, 0, sizeof(addr->sin_addr)); - resolved_addr.len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in)); - - const grpc_channel_args* args = grpc_core::CoreConfiguration::Get() - .channel_args_preconditioning() - .PreconditionChannelArgs(nullptr); - grpc_error_handle error = grpc_tcp_server_create(&server->shutdown_complete, - args, &server->tcp_server); - grpc_channel_args_destroy(args); - GPR_ASSERT(error == GRPC_ERROR_NONE); - error = - grpc_tcp_server_add_port(server->tcp_server, &resolved_addr, &port_added); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(port_added == port); - - grpc_tcp_server_start(server->tcp_server, &server->pollset, - server->on_connect, server->cb_data); - gpr_log(GPR_INFO, "test tcp server listening on 0.0.0.0:%d", port); -} - -void test_tcp_server_poll(test_tcp_server* server, int milliseconds) { - grpc_pollset_worker* worker = nullptr; - grpc_core::ExecCtx exec_ctx; - grpc_millis deadline = grpc_timespec_to_millis_round_up( - grpc_timeout_milliseconds_to_deadline(milliseconds)); - gpr_mu_lock(server->mu); - GRPC_LOG_IF_ERROR("pollset_work", - grpc_pollset_work(server->pollset[0], &worker, deadline)); - gpr_mu_unlock(server->mu); -} - -static void do_nothing(void* /*arg*/, grpc_error_handle /*error*/) {} -static void finish_pollset(void* arg, grpc_error_handle /*error*/) { - grpc_pollset_destroy(static_cast<grpc_pollset*>(arg)); -} - -void test_tcp_server_destroy(test_tcp_server* server) { - grpc_core::ExecCtx exec_ctx; - gpr_timespec shutdown_deadline; - grpc_closure do_nothing_cb; - grpc_tcp_server_unref(server->tcp_server); - GRPC_CLOSURE_INIT(&do_nothing_cb, do_nothing, nullptr, - grpc_schedule_on_exec_ctx); - shutdown_deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(5, GPR_TIMESPAN)); - grpc_core::ExecCtx::Get()->Flush(); - while (!server->shutdown && - gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) { - test_tcp_server_poll(server, 1000); - } - grpc_pollset_shutdown(server->pollset[0], - GRPC_CLOSURE_CREATE(finish_pollset, server->pollset[0], - grpc_schedule_on_exec_ctx)); - grpc_core::ExecCtx::Get()->Flush(); - gpr_free(server->pollset[0]); - grpc_shutdown(); -} diff --git a/contrib/libs/grpc/test/core/util/test_tcp_server.h b/contrib/libs/grpc/test/core/util/test_tcp_server.h deleted file mode 100644 index a06dde8ace..0000000000 --- a/contrib/libs/grpc/test/core/util/test_tcp_server.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_TEST_TCP_SERVER_H -#define GRPC_TEST_CORE_UTIL_TEST_TCP_SERVER_H - -#include <vector> - -#include <grpc/support/sync.h> - -#include "src/core/lib/iomgr/tcp_server.h" - -// test_tcp_server should be stack-allocated or new'ed, never gpr_malloc'ed -// since it contains C++ objects. -struct test_tcp_server { - grpc_tcp_server* tcp_server = nullptr; - grpc_closure shutdown_complete; - bool shutdown = false; - // mu is filled in by grpc_pollset_init and controls the pollset. - // TODO(unknown): Switch this to a Mutex once pollset_init can provide a Mutex - gpr_mu* mu; - std::vector<grpc_pollset*> pollset; - grpc_tcp_server_cb on_connect; - void* cb_data; -}; - -void test_tcp_server_init(test_tcp_server* server, - grpc_tcp_server_cb on_connect, void* user_data); -void test_tcp_server_start(test_tcp_server* server, int port); -void test_tcp_server_poll(test_tcp_server* server, int milliseconds); -void test_tcp_server_destroy(test_tcp_server* server); - -#endif /* GRPC_TEST_CORE_UTIL_TEST_TCP_SERVER_H */ diff --git a/contrib/libs/grpc/test/core/util/tls_utils.cc b/contrib/libs/grpc/test/core/util/tls_utils.cc deleted file mode 100644 index 7f2fd0c126..0000000000 --- a/contrib/libs/grpc/test/core/util/tls_utils.cc +++ /dev/null @@ -1,172 +0,0 @@ -// -// 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. -// - -#include "test/core/util/tls_utils.h" - -#include <grpc/support/log.h> - -#include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/iomgr/load_file.h" -#include "src/core/lib/slice/slice_internal.h" - -namespace grpc_core { - -namespace testing { - -TmpFile::TmpFile(y_absl::string_view data) { - name_ = CreateTmpFileAndWriteData(data); - GPR_ASSERT(!name_.empty()); -} - -TmpFile::~TmpFile() { GPR_ASSERT(remove(name_.c_str()) == 0); } - -void TmpFile::RewriteFile(y_absl::string_view data) { - // Create a new file containing new data. - TString new_name = CreateTmpFileAndWriteData(data); - GPR_ASSERT(!new_name.empty()); - // Remove the old file. - GPR_ASSERT(remove(name_.c_str()) == 0); - // Rename the new file to the original name. - GPR_ASSERT(rename(new_name.c_str(), name_.c_str()) == 0); -} - -TString TmpFile::CreateTmpFileAndWriteData(y_absl::string_view data) { - char* name = nullptr; - FILE* file_descriptor = gpr_tmpfile("test", &name); - GPR_ASSERT(fwrite(data.data(), 1, data.size(), file_descriptor) == - data.size()); - GPR_ASSERT(fclose(file_descriptor) == 0); - GPR_ASSERT(file_descriptor != nullptr); - GPR_ASSERT(name != nullptr); - TString name_to_return = name; - gpr_free(name); - return name_to_return; -} - -PemKeyCertPairList MakeCertKeyPairs(y_absl::string_view private_key, - y_absl::string_view certs) { - if (private_key.empty() && certs.empty()) { - return {}; - } - return PemKeyCertPairList{PemKeyCertPair(private_key, certs)}; -} - -TString GetFileContents(const char* path) { - grpc_slice slice = grpc_empty_slice(); - GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", grpc_load_file(path, 0, &slice))); - TString data = TString(StringViewFromSlice(slice)); - grpc_slice_unref(slice); - return data; -} - -int SyncExternalVerifier::Verify(void* user_data, - grpc_tls_custom_verification_check_request*, - grpc_tls_on_custom_verification_check_done_cb, - void*, grpc_status_code* sync_status, - char** sync_error_details) { - auto* self = static_cast<SyncExternalVerifier*>(user_data); - if (self->success_) { - *sync_status = GRPC_STATUS_OK; - return true; // Synchronous call - } - *sync_status = GRPC_STATUS_UNAUTHENTICATED; - *sync_error_details = gpr_strdup("SyncExternalVerifier failed"); - return true; // Synchronous call -} - -void SyncExternalVerifier::Destruct(void* user_data) { - auto* self = static_cast<SyncExternalVerifier*>(user_data); - delete self; -} - -AsyncExternalVerifier::~AsyncExternalVerifier() { - // Tell the thread to shut down. - { - MutexLock lock(&mu_); - queue_.push_back(Request{nullptr, nullptr, nullptr, true}); - } - // Wait for thread to exit. - thread_.Join(); - grpc_shutdown(); -} - -int AsyncExternalVerifier::Verify( - void* user_data, grpc_tls_custom_verification_check_request* request, - grpc_tls_on_custom_verification_check_done_cb callback, void* callback_arg, - grpc_status_code*, char**) { - auto* self = static_cast<AsyncExternalVerifier*>(user_data); - // Add request to queue to be picked up by worker thread. - MutexLock lock(&self->mu_); - self->queue_.push_back(Request{request, callback, callback_arg, false}); - return false; // Asynchronous call -} - -namespace { - -void DestroyExternalVerifier(void* arg) { - auto* verifier = static_cast<AsyncExternalVerifier*>(arg); - delete verifier; -} - -} // namespace - -void AsyncExternalVerifier::Destruct(void* user_data) { - auto* self = static_cast<AsyncExternalVerifier*>(user_data); - // Spawn a detached thread to destroy the verifier, to make sure that we don't - // try to join the worker thread from within the worker thread. - Thread destroy_thread("DestroyExternalVerifier", DestroyExternalVerifier, - self, nullptr, Thread::Options().set_joinable(false)); - destroy_thread.Start(); -} - -void AsyncExternalVerifier::WorkerThread(void* arg) { - auto* self = static_cast<AsyncExternalVerifier*>(arg); - while (true) { - // Check queue for work. - bool got_request = false; - Request request; - { - MutexLock lock(&self->mu_); - if (!self->queue_.empty()) { - got_request = true; - request = self->queue_.front(); - self->queue_.pop_front(); - } - } - // If nothing found in the queue, sleep for a bit and try again. - if (!got_request) { - gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100)); - continue; - } - // If we're being told to shut down, return. - if (request.shutdown) { - return; - } - // Process the request. - if (self->success_) { - request.callback(request.request, request.callback_arg, GRPC_STATUS_OK, - ""); - } else { - request.callback(request.request, request.callback_arg, - GRPC_STATUS_UNAUTHENTICATED, - "AsyncExternalVerifier failed"); - } - } -} - -} // namespace testing - -} // namespace grpc_core diff --git a/contrib/libs/grpc/test/core/util/tls_utils.h b/contrib/libs/grpc/test/core/util/tls_utils.h deleted file mode 100644 index be88a804e3..0000000000 --- a/contrib/libs/grpc/test/core/util/tls_utils.h +++ /dev/null @@ -1,136 +0,0 @@ -// -// 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. -// - -#include <deque> - -#include "src/core/lib/gprpp/thd.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" -#include "test/core/util/test_config.h" - -namespace grpc_core { - -namespace testing { - -class TmpFile { - public: - // Create a temporary file with |data| written in. - explicit TmpFile(y_absl::string_view data); - - ~TmpFile(); - - const TString& name() { return name_; } - - // Rewrite |data| to the temporary file, in an atomic way. - void RewriteFile(y_absl::string_view data); - - private: - TString CreateTmpFileAndWriteData(y_absl::string_view data); - - TString name_; -}; - -PemKeyCertPairList MakeCertKeyPairs(y_absl::string_view private_key, - y_absl::string_view certs); - -TString GetFileContents(const char* path); - -// A synchronous external verifier implementation that simply returns -// verification results based on users' inputs. Note that it will delete itself -// in Destruct(), so create it like -// ``` -// auto* sync_verifier_ = new SyncExternalVerifier(false); -// ``` -// and no need to delete it later. This is basically to keep consistent with the -// semantics in AsyncExternalVerifier. -class SyncExternalVerifier { - public: - explicit SyncExternalVerifier(bool success) - : success_(success), base_{this, Verify, Cancel, Destruct} {} - - grpc_tls_certificate_verifier_external* base() { return &base_; } - - private: - static int Verify(void* user_data, - grpc_tls_custom_verification_check_request* request, - grpc_tls_on_custom_verification_check_done_cb callback, - void* callback_arg, grpc_status_code* sync_status, - char** sync_error_details); - - static void Cancel(void*, grpc_tls_custom_verification_check_request*) {} - - static void Destruct(void* user_data); - - bool success_ = false; - grpc_tls_certificate_verifier_external base_; -}; - -// An asynchronous external verifier implementation that runs a thread and -// process each request received from the verifier sequentially. Note that it -// will delete itself in Destruct(), so create it like -// ``` -// auto* async_verifier = new AsyncExternalVerifier(true, &event); -// auto* core_external_verifier = -// new ExternalCertificateVerifier(async_verifier->base()); -// ``` -// and no need to delete it later. -// We delete AsyncExternalVerifier in Destruct() instead of its dtor because we -// wanted AsyncExternalVerifier to outlive the underlying core -// ExternalCertificateVerifier implementation. -class AsyncExternalVerifier { - public: - explicit AsyncExternalVerifier(bool success) - : success_(success), - thread_("AsyncExternalVerifierWorkerThread", WorkerThread, this), - base_{this, Verify, Cancel, Destruct} { - grpc_init(); - thread_.Start(); - } - - ~AsyncExternalVerifier(); - - grpc_tls_certificate_verifier_external* base() { return &base_; } - - private: - // A request to pass to the worker thread. - struct Request { - grpc_tls_custom_verification_check_request* request; - grpc_tls_on_custom_verification_check_done_cb callback; - void* callback_arg; - bool shutdown; // If true, thread will exit. - }; - - static int Verify(void* user_data, - grpc_tls_custom_verification_check_request* request, - grpc_tls_on_custom_verification_check_done_cb callback, - void* callback_arg, grpc_status_code* sync_status, - char** sync_error_details); - - static void Cancel(void*, grpc_tls_custom_verification_check_request*) {} - - static void Destruct(void* user_data); - - static void WorkerThread(void* arg); - - bool success_ = false; - Thread thread_; - grpc_tls_certificate_verifier_external base_; - Mutex mu_; - std::deque<Request> queue_ Y_ABSL_GUARDED_BY(mu_); -}; - -} // namespace testing - -} // namespace grpc_core diff --git a/contrib/libs/grpc/test/core/util/tracer_util.cc b/contrib/libs/grpc/test/core/util/tracer_util.cc deleted file mode 100644 index df42eb921e..0000000000 --- a/contrib/libs/grpc/test/core/util/tracer_util.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Copyright 2015 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 "src/core/lib/debug/trace.h" -#include "test/core/util/test_config.h" - -namespace grpc_core { -namespace testing { - -void grpc_tracer_enable_flag(TraceFlag* flag) { flag->set_enabled(true); } - -} // namespace testing -} // namespace grpc_core diff --git a/contrib/libs/grpc/test/core/util/tracer_util.h b/contrib/libs/grpc/test/core/util/tracer_util.h deleted file mode 100644 index 7f9aa151ed..0000000000 --- a/contrib/libs/grpc/test/core/util/tracer_util.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_TEST_CORE_UTIL_TRACER_UTIL_H -#define GRPC_TEST_CORE_UTIL_TRACER_UTIL_H - -namespace grpc_core { -class TraceFlag; - -namespace testing { -// enables the TraceFlag passed to it. Used for testing purposes. -void grpc_tracer_enable_flag(TraceFlag* flag); - -} // namespace testing -} // namespace grpc_core - -#endif /* GRPC_TEST_CORE_UTIL_TRACER_UTIL_H */ diff --git a/contrib/libs/grpc/test/cpp/end2end/.yandex_meta/licenses.list.txt b/contrib/libs/grpc/test/cpp/end2end/.yandex_meta/licenses.list.txt deleted file mode 100644 index 4851cba93f..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/.yandex_meta/licenses.list.txt +++ /dev/null @@ -1,58 +0,0 @@ -====================Apache-2.0==================== - * 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. - - -====================Apache-2.0==================== -// 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. - - -====================COPYRIGHT==================== - * Copyright 2015 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2016 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2017 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2018 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2019 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2020 gRPC authors. - - -====================COPYRIGHT==================== -// Copyright 2019 The gRPC Authors - - -====================COPYRIGHT==================== -// Copyright 2021 gRPC authors. diff --git a/contrib/libs/grpc/test/cpp/end2end/admin_services_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/admin_services_end2end_test.cc deleted file mode 100644 index 79bac431ae..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/admin_services_end2end_test.cc +++ /dev/null @@ -1,101 +0,0 @@ -// -// -// 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 "y_absl/strings/str_cat.h" - -#include <grpcpp/ext/admin_services.h> -#include <grpcpp/ext/proto_server_reflection_plugin.h> -#include <grpcpp/grpcpp.h> - -#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -namespace grpc { -namespace testing { - -class AdminServicesTest : public ::testing::Test { - public: - void SetUp() override { - TString address = - y_absl::StrCat("localhost:", grpc_pick_unused_port_or_die()); - // Create admin server - grpc::reflection::InitProtoReflectionServerBuilderPlugin(); - ServerBuilder builder; - builder.AddListeningPort(address, InsecureServerCredentials()); - ::grpc::AddAdminServices(&builder); - server_ = builder.BuildAndStart(); - // Create channel - auto reflection_stub = reflection::v1alpha::ServerReflection::NewStub( - CreateChannel(address, InsecureChannelCredentials())); - stream_ = reflection_stub->ServerReflectionInfo(&reflection_ctx_); - } - - std::vector<TString> GetServiceList() { - std::vector<TString> services; - reflection::v1alpha::ServerReflectionRequest request; - reflection::v1alpha::ServerReflectionResponse response; - request.set_list_services(""); - stream_->Write(request); - stream_->Read(&response); - for (auto& service : response.list_services_response().service()) { - services.push_back(service.name()); - } - return services; - } - - private: - std::unique_ptr<Server> server_; - ClientContext reflection_ctx_; - std::shared_ptr< - ClientReaderWriter<reflection::v1alpha::ServerReflectionRequest, - reflection::v1alpha::ServerReflectionResponse>> - stream_; -}; - -TEST_F(AdminServicesTest, ValidateRegisteredServices) { - // Using Contains here, because the server builder might register other - // services in certain environments. - EXPECT_THAT( - GetServiceList(), - ::testing::AllOf( - ::testing::Contains("grpc.channelz.v1.Channelz"), - ::testing::Contains("grpc.reflection.v1alpha.ServerReflection"))); -#if defined(GRPC_NO_XDS) || defined(DISABLED_XDS_PROTO_IN_CC) - EXPECT_THAT(GetServiceList(), - ::testing::Not(::testing::Contains( - "envoy.service.status.v3.ClientStatusDiscoveryService"))); -#else - EXPECT_THAT(GetServiceList(), - ::testing::Contains( - "envoy.service.status.v3.ClientStatusDiscoveryService")); -#endif // GRPC_NO_XDS or DISABLED_XDS_PROTO_IN_CC -} - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/async_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/async_end2end_test.cc deleted file mode 100644 index 24bc20fc17..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/async_end2end_test.cc +++ /dev/null @@ -1,1953 +0,0 @@ -/* - * - * Copyright 2015 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 <cinttypes> -#include <memory> -#include <thread> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/ext/health_check_service_server_builder_option.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/lib/gpr/tls.h" -#include "src/core/lib/iomgr/port.h" -#include "src/proto/grpc/health/v1/health.grpc.pb.h" -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/string_ref_helper.h" -#include "test/cpp/util/test_credentials_provider.h" - -#ifdef GRPC_POSIX_SOCKET_EV -#include "src/core/lib/iomgr/ev_posix.h" -#endif // GRPC_POSIX_SOCKET_EV - -#include <gtest/gtest.h> - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using std::chrono::system_clock; - -namespace grpc { -namespace testing { - -namespace { - -void* tag(int t) { return reinterpret_cast<void*>(t); } -int detag(void* p) { return static_cast<int>(reinterpret_cast<intptr_t>(p)); } - -class Verifier { - public: - Verifier() : lambda_run_(false) {} - // Expect sets the expected ok value for a specific tag - Verifier& Expect(int i, bool expect_ok) { - return ExpectUnless(i, expect_ok, false); - } - // ExpectUnless sets the expected ok value for a specific tag - // unless the tag was already marked seen (as a result of ExpectMaybe) - Verifier& ExpectUnless(int i, bool expect_ok, bool seen) { - if (!seen) { - expectations_[tag(i)] = expect_ok; - } - return *this; - } - // ExpectMaybe sets the expected ok value for a specific tag, but does not - // require it to appear - // If it does, sets *seen to true - Verifier& ExpectMaybe(int i, bool expect_ok, bool* seen) { - if (!*seen) { - maybe_expectations_[tag(i)] = MaybeExpect{expect_ok, seen}; - } - return *this; - } - - // Next waits for 1 async tag to complete, checks its - // expectations, and returns the tag - int Next(CompletionQueue* cq, bool ignore_ok) { - bool ok; - void* got_tag; - EXPECT_TRUE(cq->Next(&got_tag, &ok)); - GotTag(got_tag, ok, ignore_ok); - return detag(got_tag); - } - - template <typename T> - CompletionQueue::NextStatus DoOnceThenAsyncNext( - CompletionQueue* cq, void** got_tag, bool* ok, T deadline, - std::function<void(void)> lambda) { - if (lambda_run_) { - return cq->AsyncNext(got_tag, ok, deadline); - } else { - lambda_run_ = true; - return cq->DoThenAsyncNext(lambda, got_tag, ok, deadline); - } - } - - // Verify keeps calling Next until all currently set - // expected tags are complete - void Verify(CompletionQueue* cq) { Verify(cq, false); } - - // This version of Verify allows optionally ignoring the - // outcome of the expectation - void Verify(CompletionQueue* cq, bool ignore_ok) { - GPR_ASSERT(!expectations_.empty() || !maybe_expectations_.empty()); - while (!expectations_.empty()) { - Next(cq, ignore_ok); - } - maybe_expectations_.clear(); - } - - // This version of Verify stops after a certain deadline - void Verify(CompletionQueue* cq, - std::chrono::system_clock::time_point deadline) { - if (expectations_.empty()) { - bool ok; - void* got_tag; - EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), - CompletionQueue::TIMEOUT); - } else { - while (!expectations_.empty()) { - bool ok; - void* got_tag; - EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), - CompletionQueue::GOT_EVENT); - GotTag(got_tag, ok, false); - } - } - maybe_expectations_.clear(); - } - - // This version of Verify stops after a certain deadline, and uses the - // DoThenAsyncNext API - // to call the lambda - void Verify(CompletionQueue* cq, - std::chrono::system_clock::time_point deadline, - const std::function<void(void)>& lambda) { - if (expectations_.empty()) { - bool ok; - void* got_tag; - EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda), - CompletionQueue::TIMEOUT); - } else { - while (!expectations_.empty()) { - bool ok; - void* got_tag; - EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda), - CompletionQueue::GOT_EVENT); - GotTag(got_tag, ok, false); - } - } - maybe_expectations_.clear(); - } - - private: - void GotTag(void* got_tag, bool ok, bool ignore_ok) { - auto it = expectations_.find(got_tag); - if (it != expectations_.end()) { - if (!ignore_ok) { - EXPECT_EQ(it->second, ok); - } - expectations_.erase(it); - } else { - auto it2 = maybe_expectations_.find(got_tag); - if (it2 != maybe_expectations_.end()) { - if (it2->second.seen != nullptr) { - EXPECT_FALSE(*it2->second.seen); - *it2->second.seen = true; - } - if (!ignore_ok) { - EXPECT_EQ(it2->second.ok, ok); - } - maybe_expectations_.erase(it2); - } else { - gpr_log(GPR_ERROR, "Unexpected tag: %p", got_tag); - abort(); - } - } - } - - struct MaybeExpect { - bool ok; - bool* seen; - }; - - std::map<void*, bool> expectations_; - std::map<void*, MaybeExpect> maybe_expectations_; - bool lambda_run_; -}; - -bool plugin_has_sync_methods(std::unique_ptr<ServerBuilderPlugin>& plugin) { - return plugin->has_sync_methods(); -} - -// This class disables the server builder plugins that may add sync services to -// the server. If there are sync services, UnimplementedRpc test will triger -// the sync unknown rpc routine on the server side, rather than the async one -// that needs to be tested here. -class ServerBuilderSyncPluginDisabler : public ::grpc::ServerBuilderOption { - public: - void UpdateArguments(ChannelArguments* /*arg*/) override {} - - void UpdatePlugins( - std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) override { - plugins->erase(std::remove_if(plugins->begin(), plugins->end(), - plugin_has_sync_methods), - plugins->end()); - } -}; - -class TestScenario { - public: - TestScenario(bool inproc_stub, const TString& creds_type, bool hcs, - const TString& content) - : inproc(inproc_stub), - health_check_service(hcs), - credentials_type(creds_type), - message_content(content) {} - void Log() const; - bool inproc; - bool health_check_service; - const TString credentials_type; - const TString message_content; -}; - -std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { - return out << "TestScenario{inproc=" << (scenario.inproc ? "true" : "false") - << ", credentials='" << scenario.credentials_type - << ", health_check_service=" - << (scenario.health_check_service ? "true" : "false") - << "', message_size=" << scenario.message_content.size() << "}"; -} - -void TestScenario::Log() const { - std::ostringstream out; - out << *this; - gpr_log(GPR_DEBUG, "%s", out.str().c_str()); -} - -class HealthCheck : public health::v1::Health::Service {}; - -class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> { - protected: - AsyncEnd2endTest() { GetParam().Log(); } - - void SetUp() override { - port_ = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port_; - - // Setup server - BuildAndStartServer(); - } - - void TearDown() override { - server_->Shutdown(); - void* ignored_tag; - bool ignored_ok; - cq_->Shutdown(); - while (cq_->Next(&ignored_tag, &ignored_ok)) { - } - stub_.reset(); - grpc_recycle_unused_port(port_); - } - - void BuildAndStartServer() { - ServerBuilder builder; - auto server_creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - builder.AddListeningPort(server_address_.str(), server_creds); - service_ = - y_absl::make_unique<grpc::testing::EchoTestService::AsyncService>(); - builder.RegisterService(service_.get()); - if (GetParam().health_check_service) { - builder.RegisterService(&health_check_); - } - cq_ = builder.AddCompletionQueue(); - - // TODO(zyc): make a test option to choose wheather sync plugins should be - // deleted - std::unique_ptr<ServerBuilderOption> sync_plugin_disabler( - new ServerBuilderSyncPluginDisabler()); - builder.SetOption(move(sync_plugin_disabler)); - server_ = builder.BuildAndStart(); - } - - void ResetStub() { - ChannelArguments args; - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - std::shared_ptr<Channel> channel = - !(GetParam().inproc) ? ::grpc::CreateCustomChannel( - server_address_.str(), channel_creds, args) - : server_->InProcessChannel(args); - stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - - void SendRpc(int num_rpcs) { - for (int i = 0; i < num_rpcs; i++) { - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, - cq_.get(), cq_.get(), tag(2)); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } - } - - std::unique_ptr<ServerCompletionQueue> cq_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::unique_ptr<grpc::testing::EchoTestService::AsyncService> service_; - HealthCheck health_check_; - std::ostringstream server_address_; - int port_; -}; - -TEST_P(AsyncEnd2endTest, SimpleRpc) { - ResetStub(); - SendRpc(1); -} - -TEST_P(AsyncEnd2endTest, SimpleRpcWithExpectedError) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - ErrorStatus error_status; - - send_request.set_message(GetParam().message_content); - error_status.set_code(1); // CANCELLED - error_status.set_error_message("cancel error message"); - *send_request.mutable_param()->mutable_expected_error() = error_status; - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - srv_ctx.AsyncNotifyWhenDone(tag(5)); - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - response_writer.Finish( - send_response, - Status( - static_cast<StatusCode>(recv_request.param().expected_error().code()), - recv_request.param().expected_error().error_message()), - tag(3)); - Verifier().Expect(3, true).Expect(4, true).Expect(5, true).Verify(cq_.get()); - - EXPECT_EQ(recv_response.message(), ""); - EXPECT_EQ(recv_status.error_code(), error_status.code()); - EXPECT_EQ(recv_status.error_message(), error_status.error_message()); - EXPECT_FALSE(srv_ctx.IsCancelled()); -} - -TEST_P(AsyncEnd2endTest, SequentialRpcs) { - ResetStub(); - SendRpc(10); -} - -TEST_P(AsyncEnd2endTest, ReconnectChannel) { - // GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS is set to 100ms in main() - if (GetParam().inproc) { - return; - } - int poller_slowdown_factor = 1; -#ifdef GRPC_POSIX_SOCKET_EV - // It needs 2 pollset_works to reconnect the channel with polling engine - // "poll" - grpc_core::UniquePtr<char> poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); - if (0 == strcmp(poller.get(), "poll")) { - poller_slowdown_factor = 2; - } -#endif // GRPC_POSIX_SOCKET_EV - ResetStub(); - SendRpc(1); - server_->Shutdown(); - void* ignored_tag; - bool ignored_ok; - cq_->Shutdown(); - while (cq_->Next(&ignored_tag, &ignored_ok)) { - } - BuildAndStartServer(); - // It needs more than GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS time to - // reconnect the channel. - gpr_sleep_until(gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis( - 300 * poller_slowdown_factor * grpc_test_slowdown_factor(), - GPR_TIMESPAN))); - SendRpc(1); -} - -// We do not need to protect notify because the use is synchronized. -void ServerWait(Server* server, int* notify) { - server->Wait(); - *notify = 1; -} -TEST_P(AsyncEnd2endTest, WaitAndShutdownTest) { - int notify = 0; - std::thread wait_thread(&ServerWait, server_.get(), ¬ify); - ResetStub(); - SendRpc(1); - EXPECT_EQ(0, notify); - server_->Shutdown(); - wait_thread.join(); - EXPECT_EQ(1, notify); -} - -TEST_P(AsyncEnd2endTest, ShutdownThenWait) { - ResetStub(); - SendRpc(1); - std::thread t([this]() { server_->Shutdown(); }); - server_->Wait(); - t.join(); -} - -// Test a simple RPC using the async version of Next -TEST_P(AsyncEnd2endTest, AsyncNextRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - std::chrono::system_clock::time_point time_now( - std::chrono::system_clock::now()); - std::chrono::system_clock::time_point time_limit( - std::chrono::system_clock::now() + std::chrono::seconds(10)); - Verifier().Verify(cq_.get(), time_now); - Verifier().Verify(cq_.get(), time_now); - - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - - Verifier().Expect(2, true).Verify(cq_.get(), time_limit); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - Verifier().Expect(3, true).Expect(4, true).Verify( - cq_.get(), std::chrono::system_clock::time_point::max()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -// Test a simple RPC using the async version of Next -TEST_P(AsyncEnd2endTest, DoThenAsyncNextRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - - std::chrono::system_clock::time_point time_now( - std::chrono::system_clock::now()); - std::chrono::system_clock::time_point time_limit( - std::chrono::system_clock::now() + std::chrono::seconds(10)); - Verifier().Verify(cq_.get(), time_now); - Verifier().Verify(cq_.get(), time_now); - - auto resp_writer_ptr = &response_writer; - auto lambda_2 = [&, this, resp_writer_ptr]() { - service_->RequestEcho(&srv_ctx, &recv_request, resp_writer_ptr, cq_.get(), - cq_.get(), tag(2)); - }; - response_reader->Finish(&recv_response, &recv_status, tag(4)); - - Verifier().Expect(2, true).Verify(cq_.get(), time_limit, lambda_2); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - auto lambda_3 = [resp_writer_ptr, send_response]() { - resp_writer_ptr->Finish(send_response, Status::OK, tag(3)); - }; - Verifier().Expect(3, true).Expect(4, true).Verify( - cq_.get(), std::chrono::system_clock::time_point::max(), lambda_3); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -// Two pings and a final pong. -TEST_P(AsyncEnd2endTest, SimpleClientStreaming) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream( - stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1))); - - service_->RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - Verifier().Expect(2, true).Expect(1, true).Verify(cq_.get()); - - cli_stream->Write(send_request, tag(3)); - srv_stream.Read(&recv_request, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - cli_stream->Write(send_request, tag(5)); - srv_stream.Read(&recv_request, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - - EXPECT_EQ(send_request.message(), recv_request.message()); - cli_stream->WritesDone(tag(7)); - srv_stream.Read(&recv_request, tag(8)); - Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); - - send_response.set_message(recv_request.message()); - srv_stream.Finish(send_response, Status::OK, tag(9)); - cli_stream->Finish(&recv_status, tag(10)); - Verifier().Expect(9, true).Expect(10, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -// Two pings and a final pong. -TEST_P(AsyncEnd2endTest, SimpleClientStreamingWithCoalescingApi) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - cli_ctx.set_initial_metadata_corked(true); - // tag:1 never comes up since no op is performed - std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream( - stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1))); - - service_->RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - cli_stream->Write(send_request, tag(3)); - - bool seen3 = false; - - Verifier().Expect(2, true).ExpectMaybe(3, true, &seen3).Verify(cq_.get()); - - srv_stream.Read(&recv_request, tag(4)); - - Verifier().ExpectUnless(3, true, seen3).Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(send_request.message(), recv_request.message()); - - cli_stream->WriteLast(send_request, WriteOptions(), tag(5)); - srv_stream.Read(&recv_request, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - srv_stream.Read(&recv_request, tag(7)); - Verifier().Expect(7, false).Verify(cq_.get()); - - send_response.set_message(recv_request.message()); - srv_stream.Finish(send_response, Status::OK, tag(8)); - cli_stream->Finish(&recv_status, tag(9)); - Verifier().Expect(8, true).Expect(9, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -// One ping, two pongs. -TEST_P(AsyncEnd2endTest, SimpleServerStreaming) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream( - stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1))); - - service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, - cq_.get(), cq_.get(), tag(2)); - - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - srv_stream.Write(send_response, tag(3)); - cli_stream->Read(&recv_response, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - srv_stream.Write(send_response, tag(5)); - cli_stream->Read(&recv_response, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - srv_stream.Finish(Status::OK, tag(7)); - cli_stream->Read(&recv_response, tag(8)); - Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(9)); - Verifier().Expect(9, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// One ping, two pongs. Using WriteAndFinish API -TEST_P(AsyncEnd2endTest, SimpleServerStreamingWithCoalescingApiWAF) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream( - stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1))); - - service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, - cq_.get(), cq_.get(), tag(2)); - - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - srv_stream.Write(send_response, tag(3)); - cli_stream->Read(&recv_response, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - srv_stream.WriteAndFinish(send_response, WriteOptions(), Status::OK, tag(5)); - cli_stream->Read(&recv_response, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - cli_stream->Read(&recv_response, tag(7)); - Verifier().Expect(7, false).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(8)); - Verifier().Expect(8, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// One ping, two pongs. Using WriteLast API -TEST_P(AsyncEnd2endTest, SimpleServerStreamingWithCoalescingApiWL) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream( - stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1))); - - service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, - cq_.get(), cq_.get(), tag(2)); - - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - srv_stream.Write(send_response, tag(3)); - cli_stream->Read(&recv_response, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - srv_stream.WriteLast(send_response, WriteOptions(), tag(5)); - cli_stream->Read(&recv_response, tag(6)); - srv_stream.Finish(Status::OK, tag(7)); - Verifier().Expect(5, true).Expect(6, true).Expect(7, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - cli_stream->Read(&recv_response, tag(8)); - Verifier().Expect(8, false).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(9)); - Verifier().Expect(9, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// One ping, one pong. -TEST_P(AsyncEnd2endTest, SimpleBidiStreaming) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>> - cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1))); - - service_->RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - - cli_stream->Write(send_request, tag(3)); - srv_stream.Read(&recv_request, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - srv_stream.Write(send_response, tag(5)); - cli_stream->Read(&recv_response, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - cli_stream->WritesDone(tag(7)); - srv_stream.Read(&recv_request, tag(8)); - Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); - - srv_stream.Finish(Status::OK, tag(9)); - cli_stream->Finish(&recv_status, tag(10)); - Verifier().Expect(9, true).Expect(10, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// One ping, one pong. Using server:WriteAndFinish api -TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWAF) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - cli_ctx.set_initial_metadata_corked(true); - std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>> - cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1))); - - service_->RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - cli_stream->WriteLast(send_request, WriteOptions(), tag(3)); - - bool seen3 = false; - - Verifier().Expect(2, true).ExpectMaybe(3, true, &seen3).Verify(cq_.get()); - - srv_stream.Read(&recv_request, tag(4)); - - Verifier().ExpectUnless(3, true, seen3).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - srv_stream.Read(&recv_request, tag(5)); - Verifier().Expect(5, false).Verify(cq_.get()); - - send_response.set_message(recv_request.message()); - srv_stream.WriteAndFinish(send_response, WriteOptions(), Status::OK, tag(6)); - cli_stream->Read(&recv_response, tag(7)); - Verifier().Expect(6, true).Expect(7, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - cli_stream->Finish(&recv_status, tag(8)); - Verifier().Expect(8, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// One ping, one pong. Using server:WriteLast api -TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWL) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - cli_ctx.set_initial_metadata_corked(true); - std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>> - cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1))); - - service_->RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - cli_stream->WriteLast(send_request, WriteOptions(), tag(3)); - - bool seen3 = false; - - Verifier().Expect(2, true).ExpectMaybe(3, true, &seen3).Verify(cq_.get()); - - srv_stream.Read(&recv_request, tag(4)); - - Verifier().ExpectUnless(3, true, seen3).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - srv_stream.Read(&recv_request, tag(5)); - Verifier().Expect(5, false).Verify(cq_.get()); - - send_response.set_message(recv_request.message()); - srv_stream.WriteLast(send_response, WriteOptions(), tag(6)); - srv_stream.Finish(Status::OK, tag(7)); - cli_stream->Read(&recv_response, tag(8)); - Verifier().Expect(6, true).Expect(7, true).Expect(8, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - cli_stream->Finish(&recv_status, tag(9)); - Verifier().Expect(9, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// Metadata tests -TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::pair<TString, TString> meta1("key1", "val1"); - std::pair<TString, TString> meta2("key2", "val2"); - std::pair<TString, TString> meta3("g.r.d-bin", "xyz"); - cli_ctx.AddMetadata(meta1.first, meta1.second); - cli_ctx.AddMetadata(meta2.first, meta2.second); - cli_ctx.AddMetadata(meta3.first, meta3.second); - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - const auto& client_initial_metadata = srv_ctx.client_metadata(); - EXPECT_EQ(meta1.second, - ToString(client_initial_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(client_initial_metadata.find(meta2.first)->second)); - EXPECT_EQ(meta3.second, - ToString(client_initial_metadata.find(meta3.first)->second)); - EXPECT_GE(client_initial_metadata.size(), static_cast<size_t>(2)); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -TEST_P(AsyncEnd2endTest, ServerInitialMetadataRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::pair<TString, TString> meta1("key1", "val1"); - std::pair<TString, TString> meta2("key2", "val2"); - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - response_reader->ReadInitialMetadata(tag(4)); - - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - srv_ctx.AddInitialMetadata(meta1.first, meta1.second); - srv_ctx.AddInitialMetadata(meta2.first, meta2.second); - response_writer.SendInitialMetadata(tag(3)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - const auto& server_initial_metadata = cli_ctx.GetServerInitialMetadata(); - EXPECT_EQ(meta1.second, - ToString(server_initial_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(server_initial_metadata.find(meta2.first)->second)); - EXPECT_EQ(static_cast<size_t>(2), server_initial_metadata.size()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(5)); - response_reader->Finish(&recv_response, &recv_status, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -// 1 ping, 2 pongs. -TEST_P(AsyncEnd2endTest, ServerInitialMetadataServerStreaming) { - ResetStub(); - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); - - std::pair<::TString, ::TString> meta1("key1", "val1"); - std::pair<::TString, ::TString> meta2("key2", "val2"); - - std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream( - stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1))); - cli_stream->ReadInitialMetadata(tag(11)); - service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, - cq_.get(), cq_.get(), tag(2)); - - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - - srv_ctx.AddInitialMetadata(meta1.first, meta1.second); - srv_ctx.AddInitialMetadata(meta2.first, meta2.second); - srv_stream.SendInitialMetadata(tag(10)); - Verifier().Expect(10, true).Expect(11, true).Verify(cq_.get()); - auto server_initial_metadata = cli_ctx.GetServerInitialMetadata(); - EXPECT_EQ(meta1.second, - ToString(server_initial_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(server_initial_metadata.find(meta2.first)->second)); - EXPECT_EQ(static_cast<size_t>(2), server_initial_metadata.size()); - - srv_stream.Write(send_response, tag(3)); - - cli_stream->Read(&recv_response, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - - srv_stream.Write(send_response, tag(5)); - cli_stream->Read(&recv_response, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - - srv_stream.Finish(Status::OK, tag(7)); - cli_stream->Read(&recv_response, tag(8)); - Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(9)); - Verifier().Expect(9, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -// 1 ping, 2 pongs. -// Test for server initial metadata being sent implicitly -TEST_P(AsyncEnd2endTest, ServerInitialMetadataServerStreamingImplicit) { - ResetStub(); - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::pair<::TString, ::TString> meta1("key1", "val1"); - std::pair<::TString, ::TString> meta2("key2", "val2"); - - std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream( - stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1))); - service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, - cq_.get(), cq_.get(), tag(2)); - - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - srv_ctx.AddInitialMetadata(meta1.first, meta1.second); - srv_ctx.AddInitialMetadata(meta2.first, meta2.second); - send_response.set_message(recv_request.message()); - srv_stream.Write(send_response, tag(3)); - - cli_stream->Read(&recv_response, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_response.message(), recv_response.message()); - - auto server_initial_metadata = cli_ctx.GetServerInitialMetadata(); - EXPECT_EQ(meta1.second, - ToString(server_initial_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(server_initial_metadata.find(meta2.first)->second)); - EXPECT_EQ(static_cast<size_t>(2), server_initial_metadata.size()); - - srv_stream.Write(send_response, tag(5)); - cli_stream->Read(&recv_response, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - - srv_stream.Finish(Status::OK, tag(7)); - cli_stream->Read(&recv_response, tag(8)); - Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(9)); - Verifier().Expect(9, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status.ok()); -} - -TEST_P(AsyncEnd2endTest, ServerTrailingMetadataRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::pair<TString, TString> meta1("key1", "val1"); - std::pair<TString, TString> meta2("key2", "val2"); - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - response_reader->Finish(&recv_response, &recv_status, tag(5)); - - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - response_writer.SendInitialMetadata(tag(3)); - Verifier().Expect(3, true).Verify(cq_.get()); - - send_response.set_message(recv_request.message()); - srv_ctx.AddTrailingMetadata(meta1.first, meta1.second); - srv_ctx.AddTrailingMetadata(meta2.first, meta2.second); - response_writer.Finish(send_response, Status::OK, tag(4)); - - Verifier().Expect(4, true).Expect(5, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - const auto& server_trailing_metadata = cli_ctx.GetServerTrailingMetadata(); - EXPECT_EQ(meta1.second, - ToString(server_trailing_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(server_trailing_metadata.find(meta2.first)->second)); - EXPECT_EQ(static_cast<size_t>(2), server_trailing_metadata.size()); -} - -TEST_P(AsyncEnd2endTest, MetadataRpc) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::pair<TString, TString> meta1("key1", "val1"); - std::pair<TString, TString> meta2( - "key2-bin", - TString("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", 13)); - std::pair<TString, TString> meta3("key3", "val3"); - std::pair<TString, TString> meta6( - "key4-bin", - TString("\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", - 14)); - std::pair<TString, TString> meta5("key5", "val5"); - std::pair<TString, TString> meta4( - "key6-bin", - TString( - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", 15)); - - cli_ctx.AddMetadata(meta1.first, meta1.second); - cli_ctx.AddMetadata(meta2.first, meta2.second); - - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - response_reader->ReadInitialMetadata(tag(4)); - - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - const auto& client_initial_metadata = srv_ctx.client_metadata(); - EXPECT_EQ(meta1.second, - ToString(client_initial_metadata.find(meta1.first)->second)); - EXPECT_EQ(meta2.second, - ToString(client_initial_metadata.find(meta2.first)->second)); - EXPECT_GE(client_initial_metadata.size(), static_cast<size_t>(2)); - - srv_ctx.AddInitialMetadata(meta3.first, meta3.second); - srv_ctx.AddInitialMetadata(meta4.first, meta4.second); - response_writer.SendInitialMetadata(tag(3)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - const auto& server_initial_metadata = cli_ctx.GetServerInitialMetadata(); - EXPECT_EQ(meta3.second, - ToString(server_initial_metadata.find(meta3.first)->second)); - EXPECT_EQ(meta4.second, - ToString(server_initial_metadata.find(meta4.first)->second)); - EXPECT_GE(server_initial_metadata.size(), static_cast<size_t>(2)); - - send_response.set_message(recv_request.message()); - srv_ctx.AddTrailingMetadata(meta5.first, meta5.second); - srv_ctx.AddTrailingMetadata(meta6.first, meta6.second); - response_writer.Finish(send_response, Status::OK, tag(5)); - response_reader->Finish(&recv_response, &recv_status, tag(6)); - - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - const auto& server_trailing_metadata = cli_ctx.GetServerTrailingMetadata(); - EXPECT_EQ(meta5.second, - ToString(server_trailing_metadata.find(meta5.first)->second)); - EXPECT_EQ(meta6.second, - ToString(server_trailing_metadata.find(meta6.first)->second)); - EXPECT_GE(server_trailing_metadata.size(), static_cast<size_t>(2)); -} - -// Server uses AsyncNotifyWhenDone API to check for cancellation -TEST_P(AsyncEnd2endTest, ServerCheckCancellation) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - - srv_ctx.AsyncNotifyWhenDone(tag(5)); - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - cli_ctx.TryCancel(); - Verifier().Expect(5, true).Expect(4, true).Verify(cq_.get()); - EXPECT_TRUE(srv_ctx.IsCancelled()); - - EXPECT_EQ(StatusCode::CANCELLED, recv_status.error_code()); -} - -// Server uses AsyncNotifyWhenDone API to check for normal finish -TEST_P(AsyncEnd2endTest, ServerCheckDone) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - - srv_ctx.AsyncNotifyWhenDone(tag(5)); - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), - cq_.get(), tag(2)); - - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - Verifier().Expect(3, true).Expect(4, true).Expect(5, true).Verify(cq_.get()); - EXPECT_FALSE(srv_ctx.IsCancelled()); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -TEST_P(AsyncEnd2endTest, UnimplementedRpc) { - ChannelArguments args; - const auto& channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - std::shared_ptr<Channel> channel = - !(GetParam().inproc) ? ::grpc::CreateCustomChannel(server_address_.str(), - channel_creds, args) - : server_->InProcessChannel(args); - std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub; - stub = grpc::testing::UnimplementedEchoService::NewStub(channel); - EchoRequest send_request; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - send_request.set_message(GetParam().message_content); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub->AsyncUnimplemented(&cli_ctx, send_request, cq_.get())); - - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier().Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(StatusCode::UNIMPLEMENTED, recv_status.error_code()); - EXPECT_EQ("", recv_status.error_message()); -} - -// This class is for testing scenarios where RPCs are cancelled on the server -// by calling ServerContext::TryCancel(). Server uses AsyncNotifyWhenDone -// API to check for cancellation -class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { - protected: - typedef enum { - DO_NOT_CANCEL = 0, - CANCEL_BEFORE_PROCESSING, - CANCEL_DURING_PROCESSING, - CANCEL_AFTER_PROCESSING - } ServerTryCancelRequestPhase; - - // Helper for testing client-streaming RPCs which are cancelled on the server. - // Depending on the value of server_try_cancel parameter, this will test one - // of the following three scenarios: - // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading - // any messages from the client - // - // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading - // messages from the client - // - // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading all - // messages from the client (but before sending any status back to the - // client) - void TestClientStreamingServerCancel( - ServerTryCancelRequestPhase server_try_cancel) { - ResetStub(); - - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - // Initiate the 'RequestStream' call on client - CompletionQueue cli_cq; - - std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream( - stub_->AsyncRequestStream(&cli_ctx, &recv_response, &cli_cq, tag(1))); - - // On the server, request to be notified of 'RequestStream' calls - // and receive the 'RequestStream' call just made by the client - srv_ctx.AsyncNotifyWhenDone(tag(11)); - service_->RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - std::thread t1([&cli_cq] { Verifier().Expect(1, true).Verify(&cli_cq); }); - Verifier().Expect(2, true).Verify(cq_.get()); - t1.join(); - - bool expected_server_cq_result = true; - bool expected_client_cq_result = true; - - if (server_try_cancel == CANCEL_BEFORE_PROCESSING) { - srv_ctx.TryCancel(); - Verifier().Expect(11, true).Verify(cq_.get()); - EXPECT_TRUE(srv_ctx.IsCancelled()); - - // Since cancellation is done before server reads any results, we know - // for sure that all server cq results will return false from this - // point forward - expected_server_cq_result = false; - expected_client_cq_result = false; - } - - bool ignore_client_cq_result = - (server_try_cancel == CANCEL_DURING_PROCESSING) || - (server_try_cancel == CANCEL_BEFORE_PROCESSING); - - std::thread cli_thread([&cli_cq, &cli_stream, &expected_client_cq_result, - &ignore_client_cq_result] { - EchoRequest send_request; - // Client sends 3 messages (tags 3, 4 and 5) - for (int tag_idx = 3; tag_idx <= 5; tag_idx++) { - send_request.set_message("Ping " + ToString(tag_idx)); - cli_stream->Write(send_request, tag(tag_idx)); - Verifier() - .Expect(tag_idx, expected_client_cq_result) - .Verify(&cli_cq, ignore_client_cq_result); - } - cli_stream->WritesDone(tag(6)); - // Ignore ok on WritesDone since cancel can affect it - Verifier() - .Expect(6, expected_client_cq_result) - .Verify(&cli_cq, ignore_client_cq_result); - }); - - bool ignore_cq_result = false; - bool want_done_tag = false; - std::thread* server_try_cancel_thd = nullptr; - - auto verif = Verifier(); - - if (server_try_cancel == CANCEL_DURING_PROCESSING) { - server_try_cancel_thd = - new std::thread([&srv_ctx] { srv_ctx.TryCancel(); }); - // Server will cancel the RPC in a parallel thread while reading the - // requests from the client. Since the cancellation can happen at anytime, - // some of the cq results (i.e those until cancellation) might be true but - // its non deterministic. So better to ignore the cq results - ignore_cq_result = true; - // Expect that we might possibly see the done tag that - // indicates cancellation completion in this case - want_done_tag = true; - verif.Expect(11, true); - } - - // Server reads 3 messages (tags 6, 7 and 8) - // But if want_done_tag is true, we might also see tag 11 - for (int tag_idx = 6; tag_idx <= 8; tag_idx++) { - srv_stream.Read(&recv_request, tag(tag_idx)); - // Note that we'll add something to the verifier and verify that - // something was seen, but it might be tag 11 and not what we - // just added - int got_tag = verif.Expect(tag_idx, expected_server_cq_result) - .Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == tag_idx) || (got_tag == 11 && want_done_tag)); - if (got_tag == 11) { - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - // Now get the other entry that we were waiting on - EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), tag_idx); - } - } - - cli_thread.join(); - - if (server_try_cancel_thd != nullptr) { - server_try_cancel_thd->join(); - delete server_try_cancel_thd; - } - - if (server_try_cancel == CANCEL_AFTER_PROCESSING) { - srv_ctx.TryCancel(); - want_done_tag = true; - verif.Expect(11, true); - } - - if (want_done_tag) { - verif.Verify(cq_.get()); - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - } - - // The RPC has been cancelled at this point for sure (i.e irrespective of - // the value of `server_try_cancel` is). So, from this point forward, we - // know that cq results are supposed to return false on server. - - // Server sends the final message and cancelled status (but the RPC is - // already cancelled at this point. So we expect the operation to fail) - srv_stream.Finish(send_response, Status::CANCELLED, tag(9)); - Verifier().Expect(9, false).Verify(cq_.get()); - - // Client will see the cancellation - cli_stream->Finish(&recv_status, tag(10)); - Verifier().Expect(10, true).Verify(&cli_cq); - EXPECT_FALSE(recv_status.ok()); - EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code()); - - cli_cq.Shutdown(); - void* phony_tag; - bool phony_ok; - while (cli_cq.Next(&phony_tag, &phony_ok)) { - } - } - - // Helper for testing server-streaming RPCs which are cancelled on the server. - // Depending on the value of server_try_cancel parameter, this will test one - // of the following three scenarios: - // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before sending - // any messages to the client - // - // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while sending - // messages to the client - // - // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after sending all - // messages to the client (but before sending any status back to the - // client) - void TestServerStreamingServerCancel( - ServerTryCancelRequestPhase server_try_cancel) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); - - send_request.set_message("Ping"); - // Initiate the 'ResponseStream' call on the client - CompletionQueue cli_cq; - std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream( - stub_->AsyncResponseStream(&cli_ctx, send_request, &cli_cq, tag(1))); - // On the server, request to be notified of 'ResponseStream' calls and - // receive the call just made by the client - srv_ctx.AsyncNotifyWhenDone(tag(11)); - service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, - cq_.get(), cq_.get(), tag(2)); - - std::thread t1([&cli_cq] { Verifier().Expect(1, true).Verify(&cli_cq); }); - Verifier().Expect(2, true).Verify(cq_.get()); - t1.join(); - - EXPECT_EQ(send_request.message(), recv_request.message()); - - bool expected_cq_result = true; - bool ignore_cq_result = false; - bool want_done_tag = false; - bool expected_client_cq_result = true; - bool ignore_client_cq_result = - (server_try_cancel != CANCEL_BEFORE_PROCESSING); - - if (server_try_cancel == CANCEL_BEFORE_PROCESSING) { - srv_ctx.TryCancel(); - Verifier().Expect(11, true).Verify(cq_.get()); - EXPECT_TRUE(srv_ctx.IsCancelled()); - - // We know for sure that all cq results will be false from this point - // since the server cancelled the RPC - expected_cq_result = false; - expected_client_cq_result = false; - } - - std::thread cli_thread([&cli_cq, &cli_stream, &expected_client_cq_result, - &ignore_client_cq_result] { - // Client attempts to read the three messages from the server - for (int tag_idx = 6; tag_idx <= 8; tag_idx++) { - EchoResponse recv_response; - cli_stream->Read(&recv_response, tag(tag_idx)); - Verifier() - .Expect(tag_idx, expected_client_cq_result) - .Verify(&cli_cq, ignore_client_cq_result); - } - }); - - std::thread* server_try_cancel_thd = nullptr; - - auto verif = Verifier(); - - if (server_try_cancel == CANCEL_DURING_PROCESSING) { - server_try_cancel_thd = - new std::thread([&srv_ctx] { srv_ctx.TryCancel(); }); - - // Server will cancel the RPC in a parallel thread while writing responses - // to the client. Since the cancellation can happen at anytime, some of - // the cq results (i.e those until cancellation) might be true but it is - // non deterministic. So better to ignore the cq results - ignore_cq_result = true; - // Expect that we might possibly see the done tag that - // indicates cancellation completion in this case - want_done_tag = true; - verif.Expect(11, true); - } - - // Server sends three messages (tags 3, 4 and 5) - // But if want_done tag is true, we might also see tag 11 - for (int tag_idx = 3; tag_idx <= 5; tag_idx++) { - send_response.set_message("Pong " + ToString(tag_idx)); - srv_stream.Write(send_response, tag(tag_idx)); - // Note that we'll add something to the verifier and verify that - // something was seen, but it might be tag 11 and not what we - // just added - int got_tag = verif.Expect(tag_idx, expected_cq_result) - .Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == tag_idx) || (got_tag == 11 && want_done_tag)); - if (got_tag == 11) { - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - // Now get the other entry that we were waiting on - EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), tag_idx); - } - } - - if (server_try_cancel_thd != nullptr) { - server_try_cancel_thd->join(); - delete server_try_cancel_thd; - } - - if (server_try_cancel == CANCEL_AFTER_PROCESSING) { - srv_ctx.TryCancel(); - want_done_tag = true; - verif.Expect(11, true); - } - - if (want_done_tag) { - verif.Verify(cq_.get()); - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - } - - cli_thread.join(); - - // The RPC has been cancelled at this point for sure (i.e irrespective of - // the value of `server_try_cancel` is). So, from this point forward, we - // know that cq results are supposed to return false on server. - - // Server finishes the stream (but the RPC is already cancelled) - srv_stream.Finish(Status::CANCELLED, tag(9)); - Verifier().Expect(9, false).Verify(cq_.get()); - - // Client will see the cancellation - cli_stream->Finish(&recv_status, tag(10)); - Verifier().Expect(10, true).Verify(&cli_cq); - EXPECT_FALSE(recv_status.ok()); - EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code()); - - cli_cq.Shutdown(); - void* phony_tag; - bool phony_ok; - while (cli_cq.Next(&phony_tag, &phony_ok)) { - } - } - - // Helper for testing bidirectinal-streaming RPCs which are cancelled on the - // server. - // - // Depending on the value of server_try_cancel parameter, this will - // test one of the following three scenarios: - // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading/ - // writing any messages from/to the client - // - // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading - // messages from the client - // - // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading all - // messages from the client (but before sending any status back to the - // client) - void TestBidiStreamingServerCancel( - ServerTryCancelRequestPhase server_try_cancel) { - ResetStub(); - - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - ServerContext srv_ctx; - ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - - // Initiate the call from the client side - std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>> - cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1))); - - // On the server, request to be notified of the 'BidiStream' call and - // receive the call just made by the client - srv_ctx.AsyncNotifyWhenDone(tag(11)); - service_->RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - - auto verif = Verifier(); - - // Client sends the first and the only message - send_request.set_message("Ping"); - cli_stream->Write(send_request, tag(3)); - verif.Expect(3, true); - - bool expected_cq_result = true; - bool ignore_cq_result = false; - bool want_done_tag = false; - - int got_tag, got_tag2; - bool tag_3_done = false; - - if (server_try_cancel == CANCEL_BEFORE_PROCESSING) { - srv_ctx.TryCancel(); - verif.Expect(11, true); - // We know for sure that all server cq results will be false from - // this point since the server cancelled the RPC. However, we can't - // say for sure about the client - expected_cq_result = false; - ignore_cq_result = true; - - do { - got_tag = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT(((got_tag == 3) && !tag_3_done) || (got_tag == 11)); - if (got_tag == 3) { - tag_3_done = true; - } - } while (got_tag != 11); - EXPECT_TRUE(srv_ctx.IsCancelled()); - } - - std::thread* server_try_cancel_thd = nullptr; - - if (server_try_cancel == CANCEL_DURING_PROCESSING) { - server_try_cancel_thd = - new std::thread([&srv_ctx] { srv_ctx.TryCancel(); }); - - // Since server is going to cancel the RPC in a parallel thread, some of - // the cq results (i.e those until the cancellation) might be true. Since - // that number is non-deterministic, it is better to ignore the cq results - ignore_cq_result = true; - // Expect that we might possibly see the done tag that - // indicates cancellation completion in this case - want_done_tag = true; - verif.Expect(11, true); - } - - srv_stream.Read(&recv_request, tag(4)); - verif.Expect(4, expected_cq_result); - got_tag = tag_3_done ? 3 : verif.Next(cq_.get(), ignore_cq_result); - got_tag2 = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == 3) || (got_tag == 4) || - (got_tag == 11 && want_done_tag)); - GPR_ASSERT((got_tag2 == 3) || (got_tag2 == 4) || - (got_tag2 == 11 && want_done_tag)); - // If we get 3 and 4, we don't need to wait for 11, but if - // we get 11, we should also clear 3 and 4 - if (got_tag + got_tag2 != 7) { - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - got_tag = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == 3) || (got_tag == 4)); - } - - send_response.set_message("Pong"); - srv_stream.Write(send_response, tag(5)); - verif.Expect(5, expected_cq_result); - - cli_stream->Read(&recv_response, tag(6)); - verif.Expect(6, expected_cq_result); - got_tag = verif.Next(cq_.get(), ignore_cq_result); - got_tag2 = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == 5) || (got_tag == 6) || - (got_tag == 11 && want_done_tag)); - GPR_ASSERT((got_tag2 == 5) || (got_tag2 == 6) || - (got_tag2 == 11 && want_done_tag)); - // If we get 5 and 6, we don't need to wait for 11, but if - // we get 11, we should also clear 5 and 6 - if (got_tag + got_tag2 != 11) { - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - got_tag = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == 5) || (got_tag == 6)); - } - - // This is expected to succeed in all cases - cli_stream->WritesDone(tag(7)); - verif.Expect(7, true); - // TODO(vjpai): Consider whether the following is too flexible - // or whether it should just be reset to ignore_cq_result - bool ignore_cq_wd_result = - ignore_cq_result || (server_try_cancel == CANCEL_BEFORE_PROCESSING); - got_tag = verif.Next(cq_.get(), ignore_cq_wd_result); - GPR_ASSERT((got_tag == 7) || (got_tag == 11 && want_done_tag)); - if (got_tag == 11) { - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - // Now get the other entry that we were waiting on - EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_wd_result), 7); - } - - // This is expected to fail in all cases i.e for all values of - // server_try_cancel. This is because at this point, either there are no - // more msgs from the client (because client called WritesDone) or the RPC - // is cancelled on the server - srv_stream.Read(&recv_request, tag(8)); - verif.Expect(8, false); - got_tag = verif.Next(cq_.get(), ignore_cq_result); - GPR_ASSERT((got_tag == 8) || (got_tag == 11 && want_done_tag)); - if (got_tag == 11) { - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - // Now get the other entry that we were waiting on - EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 8); - } - - if (server_try_cancel_thd != nullptr) { - server_try_cancel_thd->join(); - delete server_try_cancel_thd; - } - - if (server_try_cancel == CANCEL_AFTER_PROCESSING) { - srv_ctx.TryCancel(); - want_done_tag = true; - verif.Expect(11, true); - } - - if (want_done_tag) { - verif.Verify(cq_.get()); - EXPECT_TRUE(srv_ctx.IsCancelled()); - want_done_tag = false; - } - - // The RPC has been cancelled at this point for sure (i.e irrespective of - // the value of `server_try_cancel` is). So, from this point forward, we - // know that cq results are supposed to return false on server. - - srv_stream.Finish(Status::CANCELLED, tag(9)); - Verifier().Expect(9, false).Verify(cq_.get()); - - cli_stream->Finish(&recv_status, tag(10)); - Verifier().Expect(10, true).Verify(cq_.get()); - EXPECT_FALSE(recv_status.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, recv_status.error_code()); - } -}; - -TEST_P(AsyncEnd2endServerTryCancelTest, ClientStreamingServerTryCancelBefore) { - TestClientStreamingServerCancel(CANCEL_BEFORE_PROCESSING); -} - -TEST_P(AsyncEnd2endServerTryCancelTest, ClientStreamingServerTryCancelDuring) { - TestClientStreamingServerCancel(CANCEL_DURING_PROCESSING); -} - -TEST_P(AsyncEnd2endServerTryCancelTest, ClientStreamingServerTryCancelAfter) { - TestClientStreamingServerCancel(CANCEL_AFTER_PROCESSING); -} - -TEST_P(AsyncEnd2endServerTryCancelTest, ServerStreamingServerTryCancelBefore) { - TestServerStreamingServerCancel(CANCEL_BEFORE_PROCESSING); -} - -TEST_P(AsyncEnd2endServerTryCancelTest, ServerStreamingServerTryCancelDuring) { - TestServerStreamingServerCancel(CANCEL_DURING_PROCESSING); -} - -TEST_P(AsyncEnd2endServerTryCancelTest, ServerStreamingServerTryCancelAfter) { - TestServerStreamingServerCancel(CANCEL_AFTER_PROCESSING); -} - -TEST_P(AsyncEnd2endServerTryCancelTest, ServerBidiStreamingTryCancelBefore) { - TestBidiStreamingServerCancel(CANCEL_BEFORE_PROCESSING); -} - -TEST_P(AsyncEnd2endServerTryCancelTest, ServerBidiStreamingTryCancelDuring) { - TestBidiStreamingServerCancel(CANCEL_DURING_PROCESSING); -} - -TEST_P(AsyncEnd2endServerTryCancelTest, ServerBidiStreamingTryCancelAfter) { - TestBidiStreamingServerCancel(CANCEL_AFTER_PROCESSING); -} - -std::vector<TestScenario> CreateTestScenarios(bool /*test_secure*/, - bool test_message_size_limit) { - std::vector<TestScenario> scenarios; - std::vector<TString> credentials_types; - std::vector<TString> messages; - - auto insec_ok = [] { - // Only allow insecure credentials type when it is registered with the - // provider. User may create providers that do not have insecure. - return GetCredentialsProvider()->GetChannelCredentials( - kInsecureCredentialsType, nullptr) != nullptr; - }; - - if (insec_ok()) { - credentials_types.push_back(kInsecureCredentialsType); - } - auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); - for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { - credentials_types.push_back(*sec); - } - GPR_ASSERT(!credentials_types.empty()); - - messages.push_back("Hello"); - if (test_message_size_limit) { - for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; - k *= 32) { - TString big_msg; - for (size_t i = 0; i < k * 1024; ++i) { - char c = 'a' + (i % 26); - big_msg += c; - } - messages.push_back(big_msg); - } - if (!BuiltUnderMsan()) { - // 4MB message processing with SSL is very slow under msan - // (causes timeouts) and doesn't really increase the signal from tests. - // Reserve 100 bytes for other fields of the message proto. - messages.push_back( - TString(GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH - 100, 'a')); - } - } - - // TODO (sreek) Renable tests with health check service after the issue - // https://github.com/grpc/grpc/issues/11223 is resolved - for (auto health_check_service : {false}) { - for (auto msg = messages.begin(); msg != messages.end(); msg++) { - for (auto cred = credentials_types.begin(); - cred != credentials_types.end(); ++cred) { - scenarios.emplace_back(false, *cred, health_check_service, *msg); - } - if (insec_ok()) { - scenarios.emplace_back(true, kInsecureCredentialsType, - health_check_service, *msg); - } - } - } - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P(AsyncEnd2end, AsyncEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(true, true))); -INSTANTIATE_TEST_SUITE_P(AsyncEnd2endServerTryCancel, - AsyncEnd2endServerTryCancelTest, - ::testing::ValuesIn(CreateTestScenarios(false, - false))); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - // Change the backup poll interval from 5s to 100ms to speed up the - // ReconnectChannel test - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 100); - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/cfstream_test.cc b/contrib/libs/grpc/test/cpp/end2end/cfstream_test.cc deleted file mode 100644 index 8a8dcd4804..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/cfstream_test.cc +++ /dev/null @@ -1,478 +0,0 @@ -/* - * - * Copyright 2019 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. - * - */ - -#include <algorithm> -#include <memory> -#include <mutex> -#include <random> -#include <thread> - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/health_check_service_interface.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> - -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/port.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_credentials_provider.h" - -#ifdef GRPC_CFSTREAM -using grpc::ClientAsyncResponseReader; -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using grpc::testing::RequestParams; -using std::chrono::system_clock; - -namespace grpc { -namespace testing { -namespace { - -struct TestScenario { - TestScenario(const TString& creds_type, const TString& content) - : credentials_type(creds_type), message_content(content) {} - const TString credentials_type; - const TString message_content; -}; - -class CFStreamTest : public ::testing::TestWithParam<TestScenario> { - protected: - CFStreamTest() - : server_host_("grpctest"), - interface_("lo0"), - ipv4_address_("10.0.0.1") {} - - void DNSUp() { - std::ostringstream cmd; - // Add DNS entry for server_host_ in /etc/hosts - cmd << "echo '" << ipv4_address_ << " " << server_host_ - << " ' | sudo tee -a /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DNSDown() { - std::ostringstream cmd; - // Remove DNS entry for server_host_ in /etc/hosts - cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void InterfaceUp() { - std::ostringstream cmd; - cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_; - std::system(cmd.str().c_str()); - } - - void InterfaceDown() { - std::ostringstream cmd; - cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_; - std::system(cmd.str().c_str()); - } - - void NetworkUp() { - gpr_log(GPR_DEBUG, "Bringing network up"); - InterfaceUp(); - DNSUp(); - } - - void NetworkDown() { - gpr_log(GPR_DEBUG, "Bringing network down"); - InterfaceDown(); - DNSDown(); - } - - void SetUp() override { - NetworkUp(); - grpc_init(); - StartServer(); - } - - void TearDown() override { - NetworkDown(); - StopServer(); - grpc_shutdown(); - } - - void StartServer() { - port_ = grpc_pick_unused_port_or_die(); - server_.reset(new ServerData(port_, GetParam().credentials_type)); - server_->Start(server_host_); - } - void StopServer() { server_->Shutdown(); } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( - const std::shared_ptr<Channel>& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr<Channel> BuildChannel() { - std::ostringstream server_address; - server_address << server_host_ << ":" << port_; - ChannelArguments args; - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - return CreateCustomChannel(server_address.str(), channel_creds, args); - } - - void SendRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - bool expect_success = false) { - auto response = std::unique_ptr<EchoResponse>(new EchoResponse()); - EchoRequest request; - auto& msg = GetParam().message_content; - request.set_message(msg); - ClientContext context; - Status status = stub->Echo(&context, request, response.get()); - if (status.ok()) { - gpr_log(GPR_DEBUG, "RPC with succeeded"); - EXPECT_EQ(msg, response->message()); - } else { - gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); - } - if (expect_success) { - EXPECT_TRUE(status.ok()); - } - } - void SendAsyncRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - RequestParams param = RequestParams()) { - EchoRequest request; - request.set_message(GetParam().message_content); - *request.mutable_param() = std::move(param); - AsyncClientCall* call = new AsyncClientCall; - - call->response_reader = - stub->PrepareAsyncEcho(&call->context, request, &cq_); - - call->response_reader->StartCall(); - call->response_reader->Finish(&call->reply, &call->status, (void*)call); - } - - void ShutdownCQ() { cq_.Shutdown(); } - - bool CQNext(void** tag, bool* ok) { - auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(10); - auto ret = cq_.AsyncNext(tag, ok, deadline); - if (ret == grpc::CompletionQueue::GOT_EVENT) { - return true; - } else if (ret == grpc::CompletionQueue::SHUTDOWN) { - return false; - } else { - GPR_ASSERT(ret == grpc::CompletionQueue::TIMEOUT); - // This can happen if we hit the Apple CFStream bug which results in the - // read stream freezing. We are ignoring hangs and timeouts, but these - // tests are still useful as they can catch memory memory corruptions, - // crashes and other bugs that don't result in test freeze/timeout. - return false; - } - } - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(false /* try_to_connect */)) == - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(true /* try_to_connect */)) != - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - struct AsyncClientCall { - EchoResponse reply; - ClientContext context; - Status status; - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader; - }; - - private: - struct ServerData { - int port_; - const TString creds_; - std::unique_ptr<Server> server_; - TestServiceImpl service_; - std::unique_ptr<std::thread> thread_; - bool server_ready_ = false; - - ServerData(int port, const TString& creds) - : port_(port), creds_(creds) {} - - void Start(const TString& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - std::mutex mu; - std::unique_lock<std::mutex> lock(mu); - std::condition_variable cond; - thread_.reset(new std::thread( - std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); - cond.wait(lock, [this] { return server_ready_; }); - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - - void Serve(const TString& server_host, std::mutex* mu, - std::condition_variable* cond) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - auto server_creds = - GetCredentialsProvider()->GetServerCredentials(creds_); - builder.AddListeningPort(server_address.str(), server_creds); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - std::lock_guard<std::mutex> lock(*mu); - server_ready_ = true; - cond->notify_one(); - } - - void Shutdown(bool join = true) { - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - if (join) thread_->join(); - } - }; - - CompletionQueue cq_; - const TString server_host_; - const TString interface_; - const TString ipv4_address_; - std::unique_ptr<ServerData> server_; - int port_; -}; - -std::vector<TestScenario> CreateTestScenarios() { - std::vector<TestScenario> scenarios; - std::vector<TString> credentials_types; - std::vector<TString> messages; - - credentials_types.push_back(kInsecureCredentialsType); - auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); - for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { - credentials_types.push_back(*sec); - } - - messages.push_back("🖖"); - for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { - TString big_msg; - for (size_t i = 0; i < k * 1024; ++i) { - char c = 'a' + (i % 26); - big_msg += c; - } - messages.push_back(big_msg); - } - for (auto cred = credentials_types.begin(); cred != credentials_types.end(); - ++cred) { - for (auto msg = messages.begin(); msg != messages.end(); msg++) { - scenarios.emplace_back(*cred, *msg); - } - } - - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P(CFStreamTest, CFStreamTest, - ::testing::ValuesIn(CreateTestScenarios())); - -// gRPC should automatically detech network flaps (without enabling keepalives) -// when CFStream is enabled -TEST_P(CFStreamTest, NetworkTransition) { - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - SendRpc(stub, /*expect_success=*/true); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // bring down network - NetworkDown(); - - // network going down should be detected by cfstream - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - - // bring network interface back up - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - NetworkUp(); - - // channel should reconnect - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); -} - -// Network flaps while RPCs are in flight -TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) { - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - std::atomic_int rpcs_sent{0}; - - // Channel should be in READY state after we send some RPCs - for (int i = 0; i < 10; ++i) { - RequestParams param; - param.set_skip_cancelled_check(true); - SendAsyncRpc(stub, param); - ++rpcs_sent; - } - EXPECT_TRUE(WaitForChannelReady(channel.get())); - - // Bring down the network - NetworkDown(); - - std::thread thd = std::thread([this, &rpcs_sent]() { - void* got_tag; - bool ok = false; - bool network_down = true; - int total_completions = 0; - - while (CQNext(&got_tag, &ok)) { - ++total_completions; - GPR_ASSERT(ok); - AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag); - if (!call->status.ok()) { - gpr_log(GPR_DEBUG, "RPC failed with error: %s", - call->status.error_message().c_str()); - // Bring network up when RPCs start failing - if (network_down) { - NetworkUp(); - network_down = false; - } - } else { - gpr_log(GPR_DEBUG, "RPC succeeded"); - } - delete call; - } - // Remove line below and uncomment the following line after Apple CFStream - // bug has been fixed. - (void)rpcs_sent; - // EXPECT_EQ(total_completions, rpcs_sent); - }); - - for (int i = 0; i < 100; ++i) { - RequestParams param; - param.set_skip_cancelled_check(true); - SendAsyncRpc(stub, param); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ++rpcs_sent; - } - - ShutdownCQ(); - - thd.join(); -} - -// Send a bunch of RPCs, some of which are expected to fail. -// We should get back a response for all RPCs -TEST_P(CFStreamTest, ConcurrentRpc) { - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - std::atomic_int rpcs_sent{0}; - std::thread thd = std::thread([this, &rpcs_sent]() { - void* got_tag; - bool ok = false; - int total_completions = 0; - - while (CQNext(&got_tag, &ok)) { - ++total_completions; - GPR_ASSERT(ok); - AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag); - if (!call->status.ok()) { - gpr_log(GPR_DEBUG, "RPC failed with error: %s", - call->status.error_message().c_str()); - // Bring network up when RPCs start failing - } else { - gpr_log(GPR_DEBUG, "RPC succeeded"); - } - delete call; - } - // Remove line below and uncomment the following line after Apple CFStream - // bug has been fixed. - (void)rpcs_sent; - // EXPECT_EQ(total_completions, rpcs_sent); - }); - - for (int i = 0; i < 10; ++i) { - if (i % 3 == 0) { - RequestParams param; - ErrorStatus* error = param.mutable_expected_error(); - error->set_code(StatusCode::INTERNAL); - error->set_error_message("internal error"); - SendAsyncRpc(stub, param); - } else if (i % 5 == 0) { - RequestParams param; - param.set_echo_metadata(true); - DebugInfo* info = param.mutable_debug_info(); - info->add_stack_entries("stack_entry1"); - info->add_stack_entries("stack_entry2"); - info->set_detail("detailed debug info"); - SendAsyncRpc(stub, param); - } else { - SendAsyncRpc(stub); - } - ++rpcs_sent; - } - - ShutdownCQ(); - - thd.join(); -} - -} // namespace -} // namespace testing -} // namespace grpc -#endif // GRPC_CFSTREAM - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(argc, argv); - gpr_setenv("grpc_cfstream", "1"); - const auto result = RUN_ALL_TESTS(); - return result; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/channelz_service_test.cc b/contrib/libs/grpc/test/cpp/end2end/channelz_service_test.cc deleted file mode 100644 index a52533280a..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/channelz_service_test.cc +++ /dev/null @@ -1,937 +0,0 @@ -/* - * - * Copyright 2018 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 <grpc/support/port_platform.h> - -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpc/grpc_security.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/ext/channelz_service_plugin.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/load_file.h" -#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h" -#include "src/core/lib/security/security_connector/ssl_utils.h" -#include "src/core/lib/slice/slice_utils.h" -#include "src/cpp/client/secure_credentials.h" -#include "src/proto/grpc/channelz/channelz.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_credentials_provider.h" - -using grpc::channelz::v1::Address; -using grpc::channelz::v1::GetChannelRequest; -using grpc::channelz::v1::GetChannelResponse; -using grpc::channelz::v1::GetServerRequest; -using grpc::channelz::v1::GetServerResponse; -using grpc::channelz::v1::GetServerSocketsRequest; -using grpc::channelz::v1::GetServerSocketsResponse; -using grpc::channelz::v1::GetServersRequest; -using grpc::channelz::v1::GetServersResponse; -using grpc::channelz::v1::GetSocketRequest; -using grpc::channelz::v1::GetSocketResponse; -using grpc::channelz::v1::GetSubchannelRequest; -using grpc::channelz::v1::GetSubchannelResponse; -using grpc::channelz::v1::GetTopChannelsRequest; -using grpc::channelz::v1::GetTopChannelsResponse; - -namespace grpc { -namespace testing { -namespace { - -bool ValidateAddress(const Address& address) { - if (address.address_case() != Address::kTcpipAddress) { - return true; - } - return address.tcpip_address().ip_address().size() == 4 || - address.tcpip_address().ip_address().size() == 16; -} - -// Proxy service supports N backends. Sends RPC to backend dictated by -// request->backend_channel_idx(). -class Proxy : public ::grpc::testing::EchoTestService::Service { - public: - Proxy() {} - - void AddChannelToBackend(const std::shared_ptr<Channel>& channel) { - stubs_.push_back(grpc::testing::EchoTestService::NewStub(channel)); - } - - Status Echo(ServerContext* server_context, const EchoRequest* request, - EchoResponse* response) override { - std::unique_ptr<ClientContext> client_context = - ClientContext::FromServerContext(*server_context); - size_t idx = request->param().backend_channel_idx(); - GPR_ASSERT(idx < stubs_.size()); - return stubs_[idx]->Echo(client_context.get(), *request, response); - } - - Status BidiStream(ServerContext* server_context, - ServerReaderWriter<EchoResponse, EchoRequest>* - stream_from_client) override { - EchoRequest request; - EchoResponse response; - std::unique_ptr<ClientContext> client_context = - ClientContext::FromServerContext(*server_context); - - // always use the first proxy for streaming - auto stream_to_backend = stubs_[0]->BidiStream(client_context.get()); - while (stream_from_client->Read(&request)) { - stream_to_backend->Write(request); - stream_to_backend->Read(&response); - stream_from_client->Write(response); - } - - stream_to_backend->WritesDone(); - return stream_to_backend->Finish(); - } - - private: - std::vector<std::unique_ptr<::grpc::testing::EchoTestService::Stub>> stubs_; -}; - -enum class CredentialsType { - kInsecure = 0, - kTls = 1, - kMtls = 2, -}; - -constexpr char kCaCertPath[] = "src/core/tsi/test_creds/ca.pem"; -constexpr char kServerCertPath[] = "src/core/tsi/test_creds/server1.pem"; -constexpr char kServerKeyPath[] = "src/core/tsi/test_creds/server1.key"; -constexpr char kClientCertPath[] = "src/core/tsi/test_creds/client.pem"; -constexpr char kClientKeyPath[] = "src/core/tsi/test_creds/client.key"; - -TString ReadFile(const char* file_path) { - grpc_slice slice; - GPR_ASSERT( - GRPC_LOG_IF_ERROR("load_file", grpc_load_file(file_path, 0, &slice))); - TString file_contents(grpc_core::StringViewFromSlice(slice)); - grpc_slice_unref(slice); - return file_contents; -} - -grpc_core::PemKeyCertPairList ReadTlsIdentityPair(const char* key_path, - const char* cert_path) { - return grpc_core::PemKeyCertPairList{ - grpc_core::PemKeyCertPair(ReadFile(key_path), ReadFile(cert_path))}; -} - -std::shared_ptr<grpc::ChannelCredentials> GetChannelCredentials( - CredentialsType type, ChannelArguments* args) { - if (type == CredentialsType::kInsecure) { - return InsecureChannelCredentials(); - } - args->SetSslTargetNameOverride("foo.test.google.fr"); - std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs = { - {ReadFile(kClientKeyPath), ReadFile(kClientCertPath)}}; - grpc::experimental::TlsChannelCredentialsOptions options; - options.set_certificate_provider( - std::make_shared<grpc::experimental::StaticDataCertificateProvider>( - ReadFile(kCaCertPath), identity_key_cert_pairs)); - if (type == CredentialsType::kMtls) { - options.watch_identity_key_cert_pairs(); - } - options.watch_root_certs(); - return grpc::experimental::TlsCredentials(options); -} - -std::shared_ptr<grpc::ServerCredentials> GetServerCredentials( - CredentialsType type) { - if (type == CredentialsType::kInsecure) { - return InsecureServerCredentials(); - } - std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs = { - {ReadFile(kServerKeyPath), ReadFile(kServerCertPath)}}; - auto certificate_provider = - std::make_shared<grpc::experimental::StaticDataCertificateProvider>( - ReadFile(kCaCertPath), identity_key_cert_pairs); - grpc::experimental::TlsServerCredentialsOptions options(certificate_provider); - options.watch_root_certs(); - options.watch_identity_key_cert_pairs(); - options.set_cert_request_type(GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY); - return grpc::experimental::TlsServerCredentials(options); -} - -TString RemoveWhitespaces(TString input) { - input.erase(remove_if(input.begin(), input.end(), isspace), input.end()); - return input; -} - -class ChannelzServerTest : public ::testing::TestWithParam<CredentialsType> { - public: - ChannelzServerTest() {} - static void SetUpTestCase() { -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - } - void SetUp() override { - // ensure channel server is brought up on all severs we build. - ::grpc::channelz::experimental::InitChannelzService(); - - // We set up a proxy server with channelz enabled. - proxy_port_ = grpc_pick_unused_port_or_die(); - ServerBuilder proxy_builder; - TString proxy_server_address = "localhost:" + to_string(proxy_port_); - proxy_builder.AddListeningPort(proxy_server_address, - GetServerCredentials(GetParam())); - // forces channelz and channel tracing to be enabled. - proxy_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 1); - proxy_builder.AddChannelArgument( - GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024); - proxy_builder.RegisterService(&proxy_service_); - proxy_server_ = proxy_builder.BuildAndStart(); - } - - // Sets the proxy up to have an arbitrary number of backends. - void ConfigureProxy(size_t num_backends) { - backends_.resize(num_backends); - for (size_t i = 0; i < num_backends; ++i) { - // create a new backend. - backends_[i].port = grpc_pick_unused_port_or_die(); - ServerBuilder backend_builder; - TString backend_server_address = - "localhost:" + to_string(backends_[i].port); - backend_builder.AddListeningPort(backend_server_address, - GetServerCredentials(GetParam())); - backends_[i].service = y_absl::make_unique<TestServiceImpl>(); - // ensure that the backend itself has channelz disabled. - backend_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 0); - backend_builder.RegisterService(backends_[i].service.get()); - backends_[i].server = backend_builder.BuildAndStart(); - // set up a channel to the backend. We ensure that this channel has - // channelz enabled since these channels (proxy outbound to backends) - // are the ones that our test will actually be validating. - ChannelArguments args; - args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1); - args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024); - std::shared_ptr<Channel> channel_to_backend = ::grpc::CreateCustomChannel( - backend_server_address, GetChannelCredentials(GetParam(), &args), - args); - proxy_service_.AddChannelToBackend(channel_to_backend); - } - } - - void ResetStubs() { - string target = "dns:localhost:" + to_string(proxy_port_); - ChannelArguments args; - // disable channelz. We only want to focus on proxy to backend outbound. - args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); - std::shared_ptr<Channel> channel = ::grpc::CreateCustomChannel( - target, GetChannelCredentials(GetParam(), &args), args); - channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel); - echo_stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> NewEchoStub() { - string target = "dns:localhost:" + to_string(proxy_port_); - ChannelArguments args; - // disable channelz. We only want to focus on proxy to backend outbound. - args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); - // This ensures that gRPC will not do connection sharing. - args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, true); - std::shared_ptr<Channel> channel = ::grpc::CreateCustomChannel( - target, GetChannelCredentials(GetParam(), &args), args); - return grpc::testing::EchoTestService::NewStub(channel); - } - - void SendSuccessfulEcho(int channel_idx) { - EchoRequest request; - EchoResponse response; - request.set_message("Hello channelz"); - request.mutable_param()->set_backend_channel_idx(channel_idx); - ClientContext context; - Status s = echo_stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - } - - void SendSuccessfulStream(int num_messages) { - EchoRequest request; - EchoResponse response; - request.set_message("Hello channelz"); - ClientContext context; - auto stream_to_proxy = echo_stub_->BidiStream(&context); - for (int i = 0; i < num_messages; ++i) { - EXPECT_TRUE(stream_to_proxy->Write(request)); - EXPECT_TRUE(stream_to_proxy->Read(&response)); - } - stream_to_proxy->WritesDone(); - Status s = stream_to_proxy->Finish(); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - } - - void SendFailedEcho(int channel_idx) { - EchoRequest request; - EchoResponse response; - request.set_message("Hello channelz"); - request.mutable_param()->set_backend_channel_idx(channel_idx); - auto* error = request.mutable_param()->mutable_expected_error(); - error->set_code(13); // INTERNAL - error->set_error_message("error"); - ClientContext context; - Status s = echo_stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - } - - // Uses GetTopChannels to return the channel_id of a particular channel, - // so that the unit tests may test GetChannel call. - intptr_t GetChannelId(int channel_idx) { - GetTopChannelsRequest request; - GetTopChannelsResponse response; - request.set_start_channel_id(0); - ClientContext context; - Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_GT(response.channel_size(), channel_idx); - return response.channel(channel_idx).ref().channel_id(); - } - - static string to_string(const int number) { - std::stringstream strs; - strs << number; - return strs.str(); - } - - protected: - // package of data needed for each backend server. - struct BackendData { - std::unique_ptr<Server> server; - int port; - std::unique_ptr<TestServiceImpl> service; - }; - - std::unique_ptr<grpc::channelz::v1::Channelz::Stub> channelz_stub_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> echo_stub_; - - // proxy server to ping with channelz requests. - std::unique_ptr<Server> proxy_server_; - int proxy_port_; - Proxy proxy_service_; - - // backends. All implement the echo service. - std::vector<BackendData> backends_; -}; - -TEST_P(ChannelzServerTest, BasicTest) { - ResetStubs(); - ConfigureProxy(1); - GetTopChannelsRequest request; - GetTopChannelsResponse response; - request.set_start_channel_id(0); - ClientContext context; - Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel_size(), 1); -} - -TEST_P(ChannelzServerTest, HighStartId) { - ResetStubs(); - ConfigureProxy(1); - GetTopChannelsRequest request; - GetTopChannelsResponse response; - request.set_start_channel_id(10000); - ClientContext context; - Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel_size(), 0); -} - -TEST_P(ChannelzServerTest, SuccessfulRequestTest) { - ResetStubs(); - ConfigureProxy(1); - SendSuccessfulEcho(0); - GetChannelRequest request; - GetChannelResponse response; - request.set_channel_id(GetChannelId(0)); - ClientContext context; - Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel().data().calls_started(), 1); - EXPECT_EQ(response.channel().data().calls_succeeded(), 1); - EXPECT_EQ(response.channel().data().calls_failed(), 0); -} - -TEST_P(ChannelzServerTest, FailedRequestTest) { - ResetStubs(); - ConfigureProxy(1); - SendFailedEcho(0); - GetChannelRequest request; - GetChannelResponse response; - request.set_channel_id(GetChannelId(0)); - ClientContext context; - Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel().data().calls_started(), 1); - EXPECT_EQ(response.channel().data().calls_succeeded(), 0); - EXPECT_EQ(response.channel().data().calls_failed(), 1); -} - -TEST_P(ChannelzServerTest, ManyRequestsTest) { - ResetStubs(); - ConfigureProxy(1); - // send some RPCs - const int kNumSuccess = 10; - const int kNumFailed = 11; - for (int i = 0; i < kNumSuccess; ++i) { - SendSuccessfulEcho(0); - } - for (int i = 0; i < kNumFailed; ++i) { - SendFailedEcho(0); - } - GetChannelRequest request; - GetChannelResponse response; - request.set_channel_id(GetChannelId(0)); - ClientContext context; - Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel().data().calls_started(), - kNumSuccess + kNumFailed); - EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); - EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); -} - -TEST_P(ChannelzServerTest, ManyChannels) { - ResetStubs(); - const int kNumChannels = 4; - ConfigureProxy(kNumChannels); - GetTopChannelsRequest request; - GetTopChannelsResponse response; - request.set_start_channel_id(0); - ClientContext context; - Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel_size(), kNumChannels); -} - -TEST_P(ChannelzServerTest, ManyRequestsManyChannels) { - ResetStubs(); - const int kNumChannels = 4; - ConfigureProxy(kNumChannels); - const int kNumSuccess = 10; - const int kNumFailed = 11; - for (int i = 0; i < kNumSuccess; ++i) { - SendSuccessfulEcho(0); - SendSuccessfulEcho(2); - } - for (int i = 0; i < kNumFailed; ++i) { - SendFailedEcho(1); - SendFailedEcho(2); - } - - // the first channel saw only successes - { - GetChannelRequest request; - GetChannelResponse response; - request.set_channel_id(GetChannelId(0)); - ClientContext context; - Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess); - EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); - EXPECT_EQ(response.channel().data().calls_failed(), 0); - } - - // the second channel saw only failures - { - GetChannelRequest request; - GetChannelResponse response; - request.set_channel_id(GetChannelId(1)); - ClientContext context; - Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel().data().calls_started(), kNumFailed); - EXPECT_EQ(response.channel().data().calls_succeeded(), 0); - EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); - } - - // the third channel saw both - { - GetChannelRequest request; - GetChannelResponse response; - request.set_channel_id(GetChannelId(2)); - ClientContext context; - Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel().data().calls_started(), - kNumSuccess + kNumFailed); - EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); - EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); - } - - // the fourth channel saw nothing - { - GetChannelRequest request; - GetChannelResponse response; - request.set_channel_id(GetChannelId(3)); - ClientContext context; - Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.channel().data().calls_started(), 0); - EXPECT_EQ(response.channel().data().calls_succeeded(), 0); - EXPECT_EQ(response.channel().data().calls_failed(), 0); - } -} - -TEST_P(ChannelzServerTest, ManySubchannels) { - ResetStubs(); - const int kNumChannels = 4; - ConfigureProxy(kNumChannels); - const int kNumSuccess = 10; - const int kNumFailed = 11; - for (int i = 0; i < kNumSuccess; ++i) { - SendSuccessfulEcho(0); - SendSuccessfulEcho(2); - } - for (int i = 0; i < kNumFailed; ++i) { - SendFailedEcho(1); - SendFailedEcho(2); - } - GetTopChannelsRequest gtc_request; - GetTopChannelsResponse gtc_response; - gtc_request.set_start_channel_id(0); - ClientContext context; - Status s = - channelz_stub_->GetTopChannels(&context, gtc_request, >c_response); - EXPECT_TRUE(s.ok()) << s.error_message(); - EXPECT_EQ(gtc_response.channel_size(), kNumChannels); - for (int i = 0; i < gtc_response.channel_size(); ++i) { - // if the channel sent no RPCs, then expect no subchannels to have been - // created. - if (gtc_response.channel(i).data().calls_started() == 0) { - EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 0); - continue; - } - // The resolver must return at least one address. - ASSERT_GT(gtc_response.channel(i).subchannel_ref_size(), 0); - GetSubchannelRequest gsc_request; - GetSubchannelResponse gsc_response; - gsc_request.set_subchannel_id( - gtc_response.channel(i).subchannel_ref(0).subchannel_id()); - ClientContext context; - Status s = - channelz_stub_->GetSubchannel(&context, gsc_request, &gsc_response); - EXPECT_TRUE(s.ok()) << s.error_message(); - EXPECT_EQ(gtc_response.channel(i).data().calls_started(), - gsc_response.subchannel().data().calls_started()); - EXPECT_EQ(gtc_response.channel(i).data().calls_succeeded(), - gsc_response.subchannel().data().calls_succeeded()); - EXPECT_EQ(gtc_response.channel(i).data().calls_failed(), - gsc_response.subchannel().data().calls_failed()); - } -} - -TEST_P(ChannelzServerTest, BasicServerTest) { - ResetStubs(); - ConfigureProxy(1); - GetServersRequest request; - GetServersResponse response; - request.set_start_server_id(0); - ClientContext context; - Status s = channelz_stub_->GetServers(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.server_size(), 1); -} - -TEST_P(ChannelzServerTest, BasicGetServerTest) { - ResetStubs(); - ConfigureProxy(1); - GetServersRequest get_servers_request; - GetServersResponse get_servers_response; - get_servers_request.set_start_server_id(0); - ClientContext get_servers_context; - Status s = channelz_stub_->GetServers( - &get_servers_context, get_servers_request, &get_servers_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_servers_response.server_size(), 1); - GetServerRequest get_server_request; - GetServerResponse get_server_response; - get_server_request.set_server_id( - get_servers_response.server(0).ref().server_id()); - ClientContext get_server_context; - s = channelz_stub_->GetServer(&get_server_context, get_server_request, - &get_server_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_servers_response.server(0).ref().server_id(), - get_server_response.server().ref().server_id()); -} - -TEST_P(ChannelzServerTest, ServerCallTest) { - ResetStubs(); - ConfigureProxy(1); - const int kNumSuccess = 10; - const int kNumFailed = 11; - for (int i = 0; i < kNumSuccess; ++i) { - SendSuccessfulEcho(0); - } - for (int i = 0; i < kNumFailed; ++i) { - SendFailedEcho(0); - } - GetServersRequest request; - GetServersResponse response; - request.set_start_server_id(0); - ClientContext context; - Status s = channelz_stub_->GetServers(&context, request, &response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(response.server_size(), 1); - EXPECT_EQ(response.server(0).data().calls_succeeded(), kNumSuccess); - EXPECT_EQ(response.server(0).data().calls_failed(), kNumFailed); - // This is success+failure+1 because the call that retrieved this information - // will be counted as started. It will not track success/failure until after - // it has returned, so that is not included in the response. - EXPECT_EQ(response.server(0).data().calls_started(), - kNumSuccess + kNumFailed + 1); -} - -TEST_P(ChannelzServerTest, ManySubchannelsAndSockets) { - ResetStubs(); - const int kNumChannels = 4; - ConfigureProxy(kNumChannels); - const int kNumSuccess = 10; - const int kNumFailed = 11; - for (int i = 0; i < kNumSuccess; ++i) { - SendSuccessfulEcho(0); - SendSuccessfulEcho(2); - } - for (int i = 0; i < kNumFailed; ++i) { - SendFailedEcho(1); - SendFailedEcho(2); - } - GetTopChannelsRequest gtc_request; - GetTopChannelsResponse gtc_response; - gtc_request.set_start_channel_id(0); - ClientContext context; - Status s = - channelz_stub_->GetTopChannels(&context, gtc_request, >c_response); - EXPECT_TRUE(s.ok()) << s.error_message(); - EXPECT_EQ(gtc_response.channel_size(), kNumChannels); - for (int i = 0; i < gtc_response.channel_size(); ++i) { - // if the channel sent no RPCs, then expect no subchannels to have been - // created. - if (gtc_response.channel(i).data().calls_started() == 0) { - EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 0); - continue; - } - // The resolver must return at least one address. - ASSERT_GT(gtc_response.channel(i).subchannel_ref_size(), 0); - // First grab the subchannel - GetSubchannelRequest get_subchannel_req; - GetSubchannelResponse get_subchannel_resp; - get_subchannel_req.set_subchannel_id( - gtc_response.channel(i).subchannel_ref(0).subchannel_id()); - ClientContext get_subchannel_ctx; - Status s = channelz_stub_->GetSubchannel( - &get_subchannel_ctx, get_subchannel_req, &get_subchannel_resp); - EXPECT_TRUE(s.ok()) << s.error_message(); - EXPECT_EQ(get_subchannel_resp.subchannel().socket_ref_size(), 1); - // Now grab the socket. - GetSocketRequest get_socket_req; - GetSocketResponse get_socket_resp; - ClientContext get_socket_ctx; - get_socket_req.set_socket_id( - get_subchannel_resp.subchannel().socket_ref(0).socket_id()); - s = channelz_stub_->GetSocket(&get_socket_ctx, get_socket_req, - &get_socket_resp); - EXPECT_TRUE( - get_subchannel_resp.subchannel().socket_ref(0).name().find("http")); - EXPECT_TRUE(s.ok()) << s.error_message(); - // calls started == streams started AND stream succeeded. Since none of - // these RPCs were canceled, all of the streams will succeeded even though - // the RPCs they represent might have failed. - EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(), - get_socket_resp.socket().data().streams_started()); - EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(), - get_socket_resp.socket().data().streams_succeeded()); - // All of the calls were unary, so calls started == messages sent. - EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(), - get_socket_resp.socket().data().messages_sent()); - // We only get responses when the RPC was successful, so - // calls succeeded == messages received. - EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_succeeded(), - get_socket_resp.socket().data().messages_received()); - switch (GetParam()) { - case CredentialsType::kInsecure: - EXPECT_FALSE(get_socket_resp.socket().has_security()); - break; - case CredentialsType::kTls: - case CredentialsType::kMtls: - EXPECT_TRUE(get_socket_resp.socket().has_security()); - EXPECT_TRUE(get_socket_resp.socket().security().has_tls()); - EXPECT_EQ( - RemoveWhitespaces( - get_socket_resp.socket().security().tls().remote_certificate()), - RemoveWhitespaces(ReadFile(kServerCertPath))); - break; - } - } -} - -TEST_P(ChannelzServerTest, StreamingRPC) { - ResetStubs(); - ConfigureProxy(1); - const int kNumMessages = 5; - SendSuccessfulStream(kNumMessages); - // Get the channel - GetChannelRequest get_channel_request; - GetChannelResponse get_channel_response; - get_channel_request.set_channel_id(GetChannelId(0)); - ClientContext get_channel_context; - Status s = channelz_stub_->GetChannel( - &get_channel_context, get_channel_request, &get_channel_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_channel_response.channel().data().calls_started(), 1); - EXPECT_EQ(get_channel_response.channel().data().calls_succeeded(), 1); - EXPECT_EQ(get_channel_response.channel().data().calls_failed(), 0); - // Get the subchannel - ASSERT_GT(get_channel_response.channel().subchannel_ref_size(), 0); - GetSubchannelRequest get_subchannel_request; - GetSubchannelResponse get_subchannel_response; - ClientContext get_subchannel_context; - get_subchannel_request.set_subchannel_id( - get_channel_response.channel().subchannel_ref(0).subchannel_id()); - s = channelz_stub_->GetSubchannel(&get_subchannel_context, - get_subchannel_request, - &get_subchannel_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_subchannel_response.subchannel().data().calls_started(), 1); - EXPECT_EQ(get_subchannel_response.subchannel().data().calls_succeeded(), 1); - EXPECT_EQ(get_subchannel_response.subchannel().data().calls_failed(), 0); - // Get the socket - ASSERT_GT(get_subchannel_response.subchannel().socket_ref_size(), 0); - GetSocketRequest get_socket_request; - GetSocketResponse get_socket_response; - ClientContext get_socket_context; - get_socket_request.set_socket_id( - get_subchannel_response.subchannel().socket_ref(0).socket_id()); - EXPECT_TRUE( - get_subchannel_response.subchannel().socket_ref(0).name().find("http")); - s = channelz_stub_->GetSocket(&get_socket_context, get_socket_request, - &get_socket_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_socket_response.socket().data().streams_started(), 1); - EXPECT_EQ(get_socket_response.socket().data().streams_succeeded(), 1); - EXPECT_EQ(get_socket_response.socket().data().streams_failed(), 0); - EXPECT_EQ(get_socket_response.socket().data().messages_sent(), kNumMessages); - EXPECT_EQ(get_socket_response.socket().data().messages_received(), - kNumMessages); - switch (GetParam()) { - case CredentialsType::kInsecure: - EXPECT_FALSE(get_socket_response.socket().has_security()); - break; - case CredentialsType::kTls: - case CredentialsType::kMtls: - EXPECT_TRUE(get_socket_response.socket().has_security()); - EXPECT_TRUE(get_socket_response.socket().security().has_tls()); - EXPECT_EQ(RemoveWhitespaces(get_socket_response.socket() - .security() - .tls() - .remote_certificate()), - RemoveWhitespaces(ReadFile(kServerCertPath))); - break; - } -} - -TEST_P(ChannelzServerTest, GetServerSocketsTest) { - ResetStubs(); - ConfigureProxy(1); - GetServersRequest get_server_request; - GetServersResponse get_server_response; - get_server_request.set_start_server_id(0); - ClientContext get_server_context; - Status s = channelz_stub_->GetServers(&get_server_context, get_server_request, - &get_server_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_server_response.server_size(), 1); - GetServerSocketsRequest get_server_sockets_request; - GetServerSocketsResponse get_server_sockets_response; - get_server_sockets_request.set_server_id( - get_server_response.server(0).ref().server_id()); - get_server_sockets_request.set_start_socket_id(0); - ClientContext get_server_sockets_context; - s = channelz_stub_->GetServerSockets(&get_server_sockets_context, - get_server_sockets_request, - &get_server_sockets_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_server_sockets_response.socket_ref_size(), 1); - EXPECT_TRUE(get_server_sockets_response.socket_ref(0).name().find("http")); - // Get the socket to verify security information. - GetSocketRequest get_socket_request; - GetSocketResponse get_socket_response; - ClientContext get_socket_context; - get_socket_request.set_socket_id( - get_server_sockets_response.socket_ref(0).socket_id()); - s = channelz_stub_->GetSocket(&get_socket_context, get_socket_request, - &get_socket_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_TRUE(ValidateAddress(get_socket_response.socket().remote())); - EXPECT_TRUE(ValidateAddress(get_socket_response.socket().local())); - switch (GetParam()) { - case CredentialsType::kInsecure: - EXPECT_FALSE(get_socket_response.socket().has_security()); - break; - case CredentialsType::kTls: - case CredentialsType::kMtls: - EXPECT_TRUE(get_socket_response.socket().has_security()); - EXPECT_TRUE(get_socket_response.socket().security().has_tls()); - if (GetParam() == CredentialsType::kMtls) { - EXPECT_EQ(RemoveWhitespaces(get_socket_response.socket() - .security() - .tls() - .remote_certificate()), - RemoveWhitespaces(ReadFile(kClientCertPath))); - } else { - EXPECT_TRUE(get_socket_response.socket() - .security() - .tls() - .remote_certificate() - .empty()); - } - break; - } -} - -TEST_P(ChannelzServerTest, GetServerSocketsPaginationTest) { - ResetStubs(); - ConfigureProxy(1); - std::vector<std::unique_ptr<grpc::testing::EchoTestService::Stub>> stubs; - const int kNumServerSocketsCreated = 20; - for (int i = 0; i < kNumServerSocketsCreated; ++i) { - stubs.push_back(NewEchoStub()); - EchoRequest request; - EchoResponse response; - request.set_message("Hello channelz"); - request.mutable_param()->set_backend_channel_idx(0); - ClientContext context; - Status s = stubs.back()->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - } - GetServersRequest get_server_request; - GetServersResponse get_server_response; - get_server_request.set_start_server_id(0); - ClientContext get_server_context; - Status s = channelz_stub_->GetServers(&get_server_context, get_server_request, - &get_server_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_server_response.server_size(), 1); - // Make a request that gets all of the serversockets - { - GetServerSocketsRequest get_server_sockets_request; - GetServerSocketsResponse get_server_sockets_response; - get_server_sockets_request.set_server_id( - get_server_response.server(0).ref().server_id()); - get_server_sockets_request.set_start_socket_id(0); - ClientContext get_server_sockets_context; - s = channelz_stub_->GetServerSockets(&get_server_sockets_context, - get_server_sockets_request, - &get_server_sockets_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - // We add one to account the channelz stub that will end up creating - // a serversocket. - EXPECT_EQ(get_server_sockets_response.socket_ref_size(), - kNumServerSocketsCreated + 1); - EXPECT_TRUE(get_server_sockets_response.end()); - } - // Now we make a request that exercises pagination. - { - GetServerSocketsRequest get_server_sockets_request; - GetServerSocketsResponse get_server_sockets_response; - get_server_sockets_request.set_server_id( - get_server_response.server(0).ref().server_id()); - get_server_sockets_request.set_start_socket_id(0); - const int kMaxResults = 10; - get_server_sockets_request.set_max_results(kMaxResults); - ClientContext get_server_sockets_context; - s = channelz_stub_->GetServerSockets(&get_server_sockets_context, - get_server_sockets_request, - &get_server_sockets_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_server_sockets_response.socket_ref_size(), kMaxResults); - EXPECT_FALSE(get_server_sockets_response.end()); - } -} - -TEST_P(ChannelzServerTest, GetServerListenSocketsTest) { - ResetStubs(); - ConfigureProxy(1); - GetServersRequest get_server_request; - GetServersResponse get_server_response; - get_server_request.set_start_server_id(0); - ClientContext get_server_context; - Status s = channelz_stub_->GetServers(&get_server_context, get_server_request, - &get_server_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - EXPECT_EQ(get_server_response.server_size(), 1); - // The resolver might return one or two addresses depending on the - // configuration, one for ipv4 and one for ipv6. - int listen_socket_size = get_server_response.server(0).listen_socket_size(); - EXPECT_TRUE(listen_socket_size == 1 || listen_socket_size == 2); - GetSocketRequest get_socket_request; - GetSocketResponse get_socket_response; - get_socket_request.set_socket_id( - get_server_response.server(0).listen_socket(0).socket_id()); - EXPECT_TRUE( - get_server_response.server(0).listen_socket(0).name().find("http")); - ClientContext get_socket_context_1; - s = channelz_stub_->GetSocket(&get_socket_context_1, get_socket_request, - &get_socket_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - - EXPECT_TRUE(ValidateAddress(get_socket_response.socket().remote())); - EXPECT_TRUE(ValidateAddress(get_socket_response.socket().local())); - if (listen_socket_size == 2) { - get_socket_request.set_socket_id( - get_server_response.server(0).listen_socket(1).socket_id()); - ClientContext get_socket_context_2; - EXPECT_TRUE( - get_server_response.server(0).listen_socket(1).name().find("http")); - s = channelz_stub_->GetSocket(&get_socket_context_2, get_socket_request, - &get_socket_response); - EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - } -} - -INSTANTIATE_TEST_SUITE_P(ChannelzServer, ChannelzServerTest, - ::testing::ValuesIn(std::vector<CredentialsType>( - {CredentialsType::kInsecure, CredentialsType::kTls, - CredentialsType::kMtls}))); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/client_callback_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/client_callback_end2end_test.cc deleted file mode 100644 index 157dcfa94a..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/client_callback_end2end_test.cc +++ /dev/null @@ -1,1577 +0,0 @@ -/* - * - * Copyright 2018 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 <algorithm> -#include <condition_variable> -#include <functional> -#include <mutex> -#include <sstream> -#include <thread> - -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/generic/generic_stub.h> -#include <grpcpp/impl/codegen/proto_utils.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/client_callback.h> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/iomgr.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/interceptors_util.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/byte_buffer_proto_helper.h" -#include "test/cpp/util/string_ref_helper.h" -#include "test/cpp/util/test_credentials_provider.h" - -namespace grpc { -namespace testing { -namespace { - -enum class Protocol { INPROC, TCP }; - -class TestScenario { - public: - TestScenario(bool serve_callback, Protocol protocol, bool intercept, - const TString& creds_type) - : callback_server(serve_callback), - protocol(protocol), - use_interceptors(intercept), - credentials_type(creds_type) {} - void Log() const; - bool callback_server; - Protocol protocol; - bool use_interceptors; - const TString credentials_type; -}; - -std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { - return out << "TestScenario{callback_server=" - << (scenario.callback_server ? "true" : "false") << ",protocol=" - << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") - << ",intercept=" << (scenario.use_interceptors ? "true" : "false") - << ",creds=" << scenario.credentials_type << "}"; -} - -void TestScenario::Log() const { - std::ostringstream out; - out << *this; - gpr_log(GPR_DEBUG, "%s", out.str().c_str()); -} - -class ClientCallbackEnd2endTest - : public ::testing::TestWithParam<TestScenario> { - protected: - ClientCallbackEnd2endTest() { GetParam().Log(); } - - void SetUp() override { - ServerBuilder builder; - - auto server_creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - // TODO(vjpai): Support testing of AuthMetadataProcessor - - if (GetParam().protocol == Protocol::TCP) { - picked_port_ = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << picked_port_; - builder.AddListeningPort(server_address_.str(), server_creds); - } - if (!GetParam().callback_server) { - builder.RegisterService(&service_); - } else { - builder.RegisterService(&callback_service_); - } - - if (GetParam().use_interceptors) { - std::vector< - std::unique_ptr<experimental::ServerInterceptorFactoryInterface>> - creators; - // Add 20 phony server interceptors - creators.reserve(20); - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - builder.experimental().SetInterceptorCreators(std::move(creators)); - } - - server_ = builder.BuildAndStart(); - is_server_started_ = true; - } - - void ResetStub( - std::unique_ptr<experimental::ClientInterceptorFactoryInterface> - interceptor = nullptr) { - ChannelArguments args; - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - auto interceptors = CreatePhonyClientInterceptors(); - if (interceptor != nullptr) interceptors.push_back(std::move(interceptor)); - switch (GetParam().protocol) { - case Protocol::TCP: - if (!GetParam().use_interceptors) { - channel_ = ::grpc::CreateCustomChannel(server_address_.str(), - channel_creds, args); - } else { - channel_ = CreateCustomChannelWithInterceptors( - server_address_.str(), channel_creds, args, - std::move(interceptors)); - } - break; - case Protocol::INPROC: - if (!GetParam().use_interceptors) { - channel_ = server_->InProcessChannel(args); - } else { - channel_ = server_->experimental().InProcessChannelWithInterceptors( - args, std::move(interceptors)); - } - break; - default: - assert(false); - } - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - generic_stub_ = y_absl::make_unique<GenericStub>(channel_); - PhonyInterceptor::Reset(); - } - - void TearDown() override { - if (is_server_started_) { - // Although we would normally do an explicit shutdown, the server - // should also work correctly with just a destructor call. The regular - // end2end test uses explicit shutdown, so let this one just do reset. - server_.reset(); - } - if (picked_port_ > 0) { - grpc_recycle_unused_port(picked_port_); - } - } - - void SendRpcs(int num_rpcs, bool with_binary_metadata) { - TString test_string(""); - for (int i = 0; i < num_rpcs; i++) { - EchoRequest request; - EchoResponse response; - ClientContext cli_ctx; - - test_string += "Hello world. "; - request.set_message(test_string); - TString val; - if (with_binary_metadata) { - request.mutable_param()->set_echo_metadata(true); - char bytes[8] = {'\0', '\1', '\2', '\3', - '\4', '\5', '\6', static_cast<char>(i)}; - val = TString(bytes, 8); - cli_ctx.AddMetadata("custom-bin", val); - } - - cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); - - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub_->async()->Echo( - &cli_ctx, &request, &response, - [&cli_ctx, &request, &response, &done, &mu, &cv, val, - with_binary_metadata](Status s) { - GPR_ASSERT(s.ok()); - - EXPECT_EQ(request.message(), response.message()); - if (with_binary_metadata) { - EXPECT_EQ( - 1u, cli_ctx.GetServerTrailingMetadata().count("custom-bin")); - EXPECT_EQ(val, ToString(cli_ctx.GetServerTrailingMetadata() - .find("custom-bin") - ->second)); - } - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } - } - } - - void SendRpcsGeneric(int num_rpcs, bool maybe_except, - const char* suffix_for_stats) { - const TString kMethodName("/grpc.testing.EchoTestService/Echo"); - TString test_string(""); - for (int i = 0; i < num_rpcs; i++) { - EchoRequest request; - std::unique_ptr<ByteBuffer> send_buf; - ByteBuffer recv_buf; - ClientContext cli_ctx; - - test_string += "Hello world. "; - request.set_message(test_string); - send_buf = SerializeToByteBuffer(&request); - - std::mutex mu; - std::condition_variable cv; - bool done = false; - StubOptions options(suffix_for_stats); - generic_stub_->UnaryCall( - &cli_ctx, kMethodName, options, send_buf.get(), &recv_buf, - [&request, &recv_buf, &done, &mu, &cv, maybe_except](Status s) { - GPR_ASSERT(s.ok()); - - EchoResponse response; - EXPECT_TRUE(ParseFromByteBuffer(&recv_buf, &response)); - EXPECT_EQ(request.message(), response.message()); - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); -#if GRPC_ALLOW_EXCEPTIONS - if (maybe_except) { - throw -1; - } -#else - GPR_ASSERT(!maybe_except); -#endif - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } - } - } - - void SendGenericEchoAsBidi(int num_rpcs, int reuses, bool do_writes_done, - const char* suffix_for_stats) { - const TString kMethodName("/grpc.testing.EchoTestService/Echo"); - TString test_string(""); - for (int i = 0; i < num_rpcs; i++) { - test_string += "Hello world. "; - class Client : public grpc::ClientBidiReactor<ByteBuffer, ByteBuffer> { - public: - Client(ClientCallbackEnd2endTest* test, const TString& method_name, - const char* suffix_for_stats, const TString& test_str, - int reuses, bool do_writes_done) - : reuses_remaining_(reuses), do_writes_done_(do_writes_done) { - activate_ = [this, test, method_name, suffix_for_stats, test_str] { - if (reuses_remaining_ > 0) { - cli_ctx_ = y_absl::make_unique<ClientContext>(); - reuses_remaining_--; - StubOptions options(suffix_for_stats); - test->generic_stub_->PrepareBidiStreamingCall( - cli_ctx_.get(), method_name, options, this); - request_.set_message(test_str); - send_buf_ = SerializeToByteBuffer(&request_); - StartWrite(send_buf_.get()); - StartRead(&recv_buf_); - StartCall(); - } else { - std::unique_lock<std::mutex> l(mu_); - done_ = true; - cv_.notify_one(); - } - }; - activate_(); - } - void OnWriteDone(bool /*ok*/) override { - if (do_writes_done_) { - StartWritesDone(); - } - } - void OnReadDone(bool /*ok*/) override { - EchoResponse response; - EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response)); - EXPECT_EQ(request_.message(), response.message()); - }; - void OnDone(const Status& s) override { - EXPECT_TRUE(s.ok()); - activate_(); - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - EchoRequest request_; - std::unique_ptr<ByteBuffer> send_buf_; - ByteBuffer recv_buf_; - std::unique_ptr<ClientContext> cli_ctx_; - int reuses_remaining_; - std::function<void()> activate_; - std::mutex mu_; - std::condition_variable cv_; - bool done_ = false; - const bool do_writes_done_; - }; - - Client rpc(this, kMethodName, suffix_for_stats, test_string, reuses, - do_writes_done); - - rpc.Await(); - } - } - bool is_server_started_{false}; - int picked_port_{0}; - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<grpc::GenericStub> generic_stub_; - TestServiceImpl service_; - CallbackTestServiceImpl callback_service_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; -}; - -TEST_P(ClientCallbackEnd2endTest, SimpleRpc) { - ResetStub(); - SendRpcs(1, false); -} - -TEST_P(ClientCallbackEnd2endTest, SimpleRpcExpectedError) { - ResetStub(); - - EchoRequest request; - EchoResponse response; - ClientContext cli_ctx; - ErrorStatus error_status; - - request.set_message("Hello failure"); - error_status.set_code(1); // CANCELLED - error_status.set_error_message("cancel error message"); - *request.mutable_param()->mutable_expected_error() = error_status; - - std::mutex mu; - std::condition_variable cv; - bool done = false; - - stub_->async()->Echo(&cli_ctx, &request, &response, - [&response, &done, &mu, &cv, &error_status](Status s) { - EXPECT_EQ("", response.message()); - EXPECT_EQ(error_status.code(), s.error_code()); - EXPECT_EQ(error_status.error_message(), - s.error_message()); - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } -} - -TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { - ResetStub(); - - // The request/response state associated with an RPC and the synchronization - // variables needed to notify its completion. - struct RpcState { - std::mutex mu; - std::condition_variable cv; - bool done = false; - EchoRequest request; - EchoResponse response; - ClientContext cli_ctx; - - RpcState() = default; - ~RpcState() { - // Grab the lock to prevent destruction while another is still holding - // lock - std::lock_guard<std::mutex> lock(mu); - } - }; - std::vector<RpcState> rpc_state(3); - for (size_t i = 0; i < rpc_state.size(); i++) { - TString message = "Hello locked world"; - message += ToString(i); - rpc_state[i].request.set_message(message); - } - - // Grab a lock and then start an RPC whose callback grabs the same lock and - // then calls this function to start the next RPC under lock (up to a limit of - // the size of the rpc_state vector). - std::function<void(int)> nested_call = [this, &nested_call, - &rpc_state](int index) { - std::lock_guard<std::mutex> l(rpc_state[index].mu); - stub_->async()->Echo(&rpc_state[index].cli_ctx, &rpc_state[index].request, - &rpc_state[index].response, - [index, &nested_call, &rpc_state](Status s) { - std::lock_guard<std::mutex> l1(rpc_state[index].mu); - EXPECT_TRUE(s.ok()); - rpc_state[index].done = true; - rpc_state[index].cv.notify_all(); - // Call the next level of nesting if possible - if (index + 1 < int(rpc_state.size())) { - nested_call(index + 1); - } - }); - }; - - nested_call(0); - - // Wait for completion notifications from all RPCs. Order doesn't matter. - for (RpcState& state : rpc_state) { - std::unique_lock<std::mutex> l(state.mu); - while (!state.done) { - state.cv.wait(l); - } - EXPECT_EQ(state.request.message(), state.response.message()); - } -} - -TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) { - ResetStub(); - std::mutex mu; - std::condition_variable cv; - bool done = false; - EchoRequest request; - request.set_message("Hello locked world."); - EchoResponse response; - ClientContext cli_ctx; - { - std::lock_guard<std::mutex> l(mu); - stub_->async()->Echo(&cli_ctx, &request, &response, - [&mu, &cv, &done, &request, &response](Status s) { - std::lock_guard<std::mutex> l(mu); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(request.message(), response.message()); - done = true; - cv.notify_one(); - }); - } - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } -} - -TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) { - ResetStub(); - SendRpcs(10, false); -} - -TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { - ResetStub(); - SimpleRequest request; - SimpleResponse response; - ClientContext cli_ctx; - - cli_ctx.AddMetadata(kCheckClientInitialMetadataKey, - kCheckClientInitialMetadataVal); - - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub_->async()->CheckClientInitialMetadata( - &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) { - GPR_ASSERT(s.ok()); - - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } -} - -TEST_P(ClientCallbackEnd2endTest, SimpleRpcWithBinaryMetadata) { - ResetStub(); - SendRpcs(1, true); -} - -TEST_P(ClientCallbackEnd2endTest, SequentialRpcsWithVariedBinaryMetadataValue) { - ResetStub(); - SendRpcs(10, true); -} - -TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcs) { - ResetStub(y_absl::make_unique<TestInterceptorFactory>( - "/grpc.testing.EchoTestService/Echo", nullptr)); - SendRpcsGeneric(10, false, /*suffix_for_stats=*/nullptr); -} - -TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsWithSuffix) { - ResetStub(y_absl::make_unique<TestInterceptorFactory>( - "/grpc.testing.EchoTestService/Echo", "TestSuffix")); - SendRpcsGeneric(10, false, "TestSuffix"); -} - -TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidi) { - ResetStub(y_absl::make_unique<TestInterceptorFactory>( - "/grpc.testing.EchoTestService/Echo", nullptr)); - SendGenericEchoAsBidi(10, 1, /*do_writes_done=*/true, - /*suffix_for_stats=*/nullptr); -} - -TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidiWithSuffix) { - ResetStub(y_absl::make_unique<TestInterceptorFactory>( - "/grpc.testing.EchoTestService/Echo", "TestSuffix")); - SendGenericEchoAsBidi(10, 1, /*do_writes_done=*/true, "TestSuffix"); -} - -TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidiWithReactorReuse) { - ResetStub(); - SendGenericEchoAsBidi(10, 10, /*do_writes_done=*/true, - /*suffix_for_stats=*/nullptr); -} - -TEST_P(ClientCallbackEnd2endTest, GenericRpcNoWritesDone) { - ResetStub(); - SendGenericEchoAsBidi(1, 1, /*do_writes_done=*/false, - /*suffix_for_stats=*/nullptr); -} - -#if GRPC_ALLOW_EXCEPTIONS -TEST_P(ClientCallbackEnd2endTest, ExceptingRpc) { - ResetStub(); - SendRpcsGeneric(10, true, nullptr); -} -#endif - -TEST_P(ClientCallbackEnd2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { - ResetStub(); - std::vector<std::thread> threads; - threads.reserve(10); - for (int i = 0; i < 10; ++i) { - threads.emplace_back([this] { SendRpcs(10, true); }); - } - for (int i = 0; i < 10; ++i) { - threads[i].join(); - } -} - -TEST_P(ClientCallbackEnd2endTest, MultipleRpcs) { - ResetStub(); - std::vector<std::thread> threads; - threads.reserve(10); - for (int i = 0; i < 10; ++i) { - threads.emplace_back([this] { SendRpcs(10, false); }); - } - for (int i = 0; i < 10; ++i) { - threads[i].join(); - } -} - -TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - context.TryCancel(); - - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub_->async()->Echo(&context, &request, &response, - [&response, &done, &mu, &cv](Status s) { - EXPECT_EQ("", response.message()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, RequestEchoServerCancel) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - context.AddMetadata(kServerTryCancelRequest, - ToString(CANCEL_BEFORE_PROCESSING)); - - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub_->async()->Echo(&context, &request, &response, - [&done, &mu, &cv](Status s) { - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } -} - -struct ClientCancelInfo { - bool cancel{false}; - int ops_before_cancel; - - ClientCancelInfo() : cancel{false} {} - explicit ClientCancelInfo(int ops) : cancel{true}, ops_before_cancel{ops} {} -}; - -class WriteClient : public grpc::ClientWriteReactor<EchoRequest> { - public: - WriteClient(grpc::testing::EchoTestService::Stub* stub, - ServerTryCancelRequestPhase server_try_cancel, - int num_msgs_to_send, ClientCancelInfo client_cancel = {}) - : server_try_cancel_(server_try_cancel), - num_msgs_to_send_(num_msgs_to_send), - client_cancel_{client_cancel} { - TString msg{"Hello server."}; - for (int i = 0; i < num_msgs_to_send; i++) { - desired_ += msg; - } - if (server_try_cancel != DO_NOT_CANCEL) { - // Send server_try_cancel value in the client metadata - context_.AddMetadata(kServerTryCancelRequest, - ToString(server_try_cancel)); - } - context_.set_initial_metadata_corked(true); - stub->async()->RequestStream(&context_, &response_, this); - StartCall(); - request_.set_message(msg); - MaybeWrite(); - } - void OnWriteDone(bool ok) override { - if (ok) { - num_msgs_sent_++; - MaybeWrite(); - } - } - void OnDone(const Status& s) override { - gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent_); - int num_to_send = - (client_cancel_.cancel) - ? std::min(num_msgs_to_send_, client_cancel_.ops_before_cancel) - : num_msgs_to_send_; - switch (server_try_cancel_) { - case CANCEL_BEFORE_PROCESSING: - case CANCEL_DURING_PROCESSING: - // If the RPC is canceled by server before / during messages from the - // client, it means that the client most likely did not get a chance to - // send all the messages it wanted to send. i.e num_msgs_sent <= - // num_msgs_to_send - EXPECT_LE(num_msgs_sent_, num_to_send); - break; - case DO_NOT_CANCEL: - case CANCEL_AFTER_PROCESSING: - // If the RPC was not canceled or canceled after all messages were read - // by the server, the client did get a chance to send all its messages - EXPECT_EQ(num_msgs_sent_, num_to_send); - break; - default: - assert(false); - break; - } - if ((server_try_cancel_ == DO_NOT_CANCEL) && !client_cancel_.cancel) { - EXPECT_TRUE(s.ok()); - EXPECT_EQ(response_.message(), desired_); - } else { - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - } - std::unique_lock<std::mutex> l(mu_); - done_ = true; - cv_.notify_one(); - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - private: - void MaybeWrite() { - if (client_cancel_.cancel && - num_msgs_sent_ == client_cancel_.ops_before_cancel) { - context_.TryCancel(); - } else if (num_msgs_to_send_ > num_msgs_sent_ + 1) { - StartWrite(&request_); - } else if (num_msgs_to_send_ == num_msgs_sent_ + 1) { - StartWriteLast(&request_, WriteOptions()); - } - } - EchoRequest request_; - EchoResponse response_; - ClientContext context_; - const ServerTryCancelRequestPhase server_try_cancel_; - int num_msgs_sent_{0}; - const int num_msgs_to_send_; - TString desired_; - const ClientCancelInfo client_cancel_; - std::mutex mu_; - std::condition_variable cv_; - bool done_ = false; -}; - -TEST_P(ClientCallbackEnd2endTest, RequestStream) { - ResetStub(); - WriteClient test{stub_.get(), DO_NOT_CANCEL, 3}; - test.Await(); - // Make sure that the server interceptors were not notified to cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(0, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, ClientCancelsRequestStream) { - ResetStub(); - WriteClient test{stub_.get(), DO_NOT_CANCEL, 3, ClientCancelInfo{2}}; - test.Await(); - // Make sure that the server interceptors got the cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Server to cancel before doing reading the request -TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelBeforeReads) { - ResetStub(); - WriteClient test{stub_.get(), CANCEL_BEFORE_PROCESSING, 1}; - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Server to cancel while reading a request from the stream in parallel -TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelDuringRead) { - ResetStub(); - WriteClient test{stub_.get(), CANCEL_DURING_PROCESSING, 10}; - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Server to cancel after reading all the requests but before returning to the -// client -TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelAfterReads) { - ResetStub(); - WriteClient test{stub_.get(), CANCEL_AFTER_PROCESSING, 4}; - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, UnaryReactor) { - ResetStub(); - class UnaryClient : public grpc::ClientUnaryReactor { - public: - explicit UnaryClient(grpc::testing::EchoTestService::Stub* stub) { - cli_ctx_.AddMetadata("key1", "val1"); - cli_ctx_.AddMetadata("key2", "val2"); - request_.mutable_param()->set_echo_metadata_initially(true); - request_.set_message("Hello metadata"); - stub->async()->Echo(&cli_ctx_, &request_, &response_, this); - StartCall(); - } - void OnReadInitialMetadataDone(bool ok) override { - EXPECT_TRUE(ok); - EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key1")); - EXPECT_EQ( - "val1", - ToString(cli_ctx_.GetServerInitialMetadata().find("key1")->second)); - EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key2")); - EXPECT_EQ( - "val2", - ToString(cli_ctx_.GetServerInitialMetadata().find("key2")->second)); - initial_metadata_done_ = true; - } - void OnDone(const Status& s) override { - EXPECT_TRUE(initial_metadata_done_); - EXPECT_EQ(0u, cli_ctx_.GetServerTrailingMetadata().size()); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(request_.message(), response_.message()); - std::unique_lock<std::mutex> l(mu_); - done_ = true; - cv_.notify_one(); - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - private: - EchoRequest request_; - EchoResponse response_; - ClientContext cli_ctx_; - std::mutex mu_; - std::condition_variable cv_; - bool done_{false}; - bool initial_metadata_done_{false}; - }; - - UnaryClient test{stub_.get()}; - test.Await(); - // Make sure that the server interceptors were not notified of a cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(0, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, GenericUnaryReactor) { - const TString kMethodName("/grpc.testing.EchoTestService/Echo"); - constexpr char kSuffixForStats[] = "TestSuffixForStats"; - ResetStub( - y_absl::make_unique<TestInterceptorFactory>(kMethodName, kSuffixForStats)); - class UnaryClient : public grpc::ClientUnaryReactor { - public: - UnaryClient(grpc::GenericStub* stub, const TString& method_name, - const char* suffix_for_stats) { - cli_ctx_.AddMetadata("key1", "val1"); - cli_ctx_.AddMetadata("key2", "val2"); - request_.mutable_param()->set_echo_metadata_initially(true); - request_.set_message("Hello metadata"); - send_buf_ = SerializeToByteBuffer(&request_); - - StubOptions options(suffix_for_stats); - stub->PrepareUnaryCall(&cli_ctx_, method_name, options, send_buf_.get(), - &recv_buf_, this); - StartCall(); - } - void OnReadInitialMetadataDone(bool ok) override { - EXPECT_TRUE(ok); - EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key1")); - EXPECT_EQ( - "val1", - ToString(cli_ctx_.GetServerInitialMetadata().find("key1")->second)); - EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key2")); - EXPECT_EQ( - "val2", - ToString(cli_ctx_.GetServerInitialMetadata().find("key2")->second)); - initial_metadata_done_ = true; - } - void OnDone(const Status& s) override { - EXPECT_TRUE(initial_metadata_done_); - EXPECT_EQ(0u, cli_ctx_.GetServerTrailingMetadata().size()); - EXPECT_TRUE(s.ok()); - EchoResponse response; - EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response)); - EXPECT_EQ(request_.message(), response.message()); - std::unique_lock<std::mutex> l(mu_); - done_ = true; - cv_.notify_one(); - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - private: - EchoRequest request_; - std::unique_ptr<ByteBuffer> send_buf_; - ByteBuffer recv_buf_; - ClientContext cli_ctx_; - std::mutex mu_; - std::condition_variable cv_; - bool done_{false}; - bool initial_metadata_done_{false}; - }; - - UnaryClient test{generic_stub_.get(), kMethodName, kSuffixForStats}; - test.Await(); - // Make sure that the server interceptors were not notified of a cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(0, PhonyInterceptor::GetNumTimesCancel()); - } -} - -class ReadClient : public grpc::ClientReadReactor<EchoResponse> { - public: - ReadClient(grpc::testing::EchoTestService::Stub* stub, - ServerTryCancelRequestPhase server_try_cancel, - ClientCancelInfo client_cancel = {}) - : server_try_cancel_(server_try_cancel), client_cancel_{client_cancel} { - if (server_try_cancel_ != DO_NOT_CANCEL) { - // Send server_try_cancel value in the client metadata - context_.AddMetadata(kServerTryCancelRequest, - ToString(server_try_cancel)); - } - request_.set_message("Hello client "); - stub->async()->ResponseStream(&context_, &request_, this); - if (client_cancel_.cancel && - reads_complete_ == client_cancel_.ops_before_cancel) { - context_.TryCancel(); - } - // Even if we cancel, read until failure because there might be responses - // pending - StartRead(&response_); - StartCall(); - } - void OnReadDone(bool ok) override { - if (!ok) { - if (server_try_cancel_ == DO_NOT_CANCEL && !client_cancel_.cancel) { - EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); - } - } else { - EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); - EXPECT_EQ(response_.message(), - request_.message() + ToString(reads_complete_)); - reads_complete_++; - if (client_cancel_.cancel && - reads_complete_ == client_cancel_.ops_before_cancel) { - context_.TryCancel(); - } - // Even if we cancel, read until failure because there might be responses - // pending - StartRead(&response_); - } - } - void OnDone(const Status& s) override { - gpr_log(GPR_INFO, "Read %d messages", reads_complete_); - switch (server_try_cancel_) { - case DO_NOT_CANCEL: - if (!client_cancel_.cancel || client_cancel_.ops_before_cancel > - kServerDefaultResponseStreamsToSend) { - EXPECT_TRUE(s.ok()); - EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); - } else { - EXPECT_GE(reads_complete_, client_cancel_.ops_before_cancel); - EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); - // Status might be ok or cancelled depending on whether server - // sent status before client cancel went through - if (!s.ok()) { - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - } - } - break; - case CANCEL_BEFORE_PROCESSING: - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - EXPECT_EQ(reads_complete_, 0); - break; - case CANCEL_DURING_PROCESSING: - case CANCEL_AFTER_PROCESSING: - // If server canceled while writing messages, client must have read - // less than or equal to the expected number of messages. Even if the - // server canceled after writing all messages, the RPC may be canceled - // before the Client got a chance to read all the messages. - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); - break; - default: - assert(false); - } - std::unique_lock<std::mutex> l(mu_); - done_ = true; - cv_.notify_one(); - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - private: - EchoRequest request_; - EchoResponse response_; - ClientContext context_; - const ServerTryCancelRequestPhase server_try_cancel_; - int reads_complete_{0}; - const ClientCancelInfo client_cancel_; - std::mutex mu_; - std::condition_variable cv_; - bool done_ = false; -}; - -TEST_P(ClientCallbackEnd2endTest, ResponseStream) { - ResetStub(); - ReadClient test{stub_.get(), DO_NOT_CANCEL}; - test.Await(); - // Make sure that the server interceptors were not notified of a cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(0, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, ClientCancelsResponseStream) { - ResetStub(); - ReadClient test{stub_.get(), DO_NOT_CANCEL, ClientCancelInfo{2}}; - test.Await(); - // Because cancel in this case races with server finish, we can't be sure that - // server interceptors even see cancellation -} - -// Server to cancel before sending any response messages -TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelBefore) { - ResetStub(); - ReadClient test{stub_.get(), CANCEL_BEFORE_PROCESSING}; - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Server to cancel while writing a response to the stream in parallel -TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelDuring) { - ResetStub(); - ReadClient test{stub_.get(), CANCEL_DURING_PROCESSING}; - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Server to cancel after writing all the respones to the stream but before -// returning to the client -TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelAfter) { - ResetStub(); - ReadClient test{stub_.get(), CANCEL_AFTER_PROCESSING}; - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -class BidiClient : public grpc::ClientBidiReactor<EchoRequest, EchoResponse> { - public: - BidiClient(grpc::testing::EchoTestService::Stub* stub, - ServerTryCancelRequestPhase server_try_cancel, - int num_msgs_to_send, bool cork_metadata, bool first_write_async, - ClientCancelInfo client_cancel = {}) - : server_try_cancel_(server_try_cancel), - msgs_to_send_{num_msgs_to_send}, - client_cancel_{client_cancel} { - if (server_try_cancel_ != DO_NOT_CANCEL) { - // Send server_try_cancel value in the client metadata - context_.AddMetadata(kServerTryCancelRequest, - ToString(server_try_cancel)); - } - request_.set_message("Hello fren "); - context_.set_initial_metadata_corked(cork_metadata); - stub->async()->BidiStream(&context_, this); - MaybeAsyncWrite(first_write_async); - StartRead(&response_); - StartCall(); - } - void OnReadDone(bool ok) override { - if (!ok) { - if (server_try_cancel_ == DO_NOT_CANCEL) { - if (!client_cancel_.cancel) { - EXPECT_EQ(reads_complete_, msgs_to_send_); - } else { - EXPECT_LE(reads_complete_, writes_complete_); - } - } - } else { - EXPECT_LE(reads_complete_, msgs_to_send_); - EXPECT_EQ(response_.message(), request_.message()); - reads_complete_++; - StartRead(&response_); - } - } - void OnWriteDone(bool ok) override { - if (async_write_thread_.joinable()) { - async_write_thread_.join(); - RemoveHold(); - } - if (server_try_cancel_ == DO_NOT_CANCEL) { - EXPECT_TRUE(ok); - } else if (!ok) { - return; - } - writes_complete_++; - MaybeWrite(); - } - void OnDone(const Status& s) override { - gpr_log(GPR_INFO, "Sent %d messages", writes_complete_); - gpr_log(GPR_INFO, "Read %d messages", reads_complete_); - switch (server_try_cancel_) { - case DO_NOT_CANCEL: - if (!client_cancel_.cancel || - client_cancel_.ops_before_cancel > msgs_to_send_) { - EXPECT_TRUE(s.ok()); - EXPECT_EQ(writes_complete_, msgs_to_send_); - EXPECT_EQ(reads_complete_, writes_complete_); - } else { - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - EXPECT_EQ(writes_complete_, client_cancel_.ops_before_cancel); - EXPECT_LE(reads_complete_, writes_complete_); - } - break; - case CANCEL_BEFORE_PROCESSING: - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - // The RPC is canceled before the server did any work or returned any - // reads, but it's possible that some writes took place first from the - // client - EXPECT_LE(writes_complete_, msgs_to_send_); - EXPECT_EQ(reads_complete_, 0); - break; - case CANCEL_DURING_PROCESSING: - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - EXPECT_LE(writes_complete_, msgs_to_send_); - EXPECT_LE(reads_complete_, writes_complete_); - break; - case CANCEL_AFTER_PROCESSING: - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - EXPECT_EQ(writes_complete_, msgs_to_send_); - // The Server canceled after reading the last message and after writing - // the message to the client. However, the RPC cancellation might have - // taken effect before the client actually read the response. - EXPECT_LE(reads_complete_, writes_complete_); - break; - default: - assert(false); - } - std::unique_lock<std::mutex> l(mu_); - done_ = true; - cv_.notify_one(); - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - private: - void MaybeAsyncWrite(bool first_write_async) { - if (first_write_async) { - // Make sure that we have a write to issue. - // TODO(vjpai): Make this work with 0 writes case as well. - assert(msgs_to_send_ >= 1); - - AddHold(); - async_write_thread_ = std::thread([this] { - std::unique_lock<std::mutex> lock(async_write_thread_mu_); - async_write_thread_cv_.wait( - lock, [this] { return async_write_thread_start_; }); - MaybeWrite(); - }); - std::lock_guard<std::mutex> lock(async_write_thread_mu_); - async_write_thread_start_ = true; - async_write_thread_cv_.notify_one(); - return; - } - MaybeWrite(); - } - void MaybeWrite() { - if (client_cancel_.cancel && - writes_complete_ == client_cancel_.ops_before_cancel) { - context_.TryCancel(); - } else if (writes_complete_ == msgs_to_send_) { - StartWritesDone(); - } else { - StartWrite(&request_); - } - } - EchoRequest request_; - EchoResponse response_; - ClientContext context_; - const ServerTryCancelRequestPhase server_try_cancel_; - int reads_complete_{0}; - int writes_complete_{0}; - const int msgs_to_send_; - const ClientCancelInfo client_cancel_; - std::mutex mu_; - std::condition_variable cv_; - bool done_ = false; - std::thread async_write_thread_; - bool async_write_thread_start_ = false; - std::mutex async_write_thread_mu_; - std::condition_variable async_write_thread_cv_; -}; - -TEST_P(ClientCallbackEnd2endTest, BidiStream) { - ResetStub(); - BidiClient test(stub_.get(), DO_NOT_CANCEL, - kServerDefaultResponseStreamsToSend, - /*cork_metadata=*/false, /*first_write_async=*/false); - test.Await(); - // Make sure that the server interceptors were not notified of a cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(0, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, BidiStreamFirstWriteAsync) { - ResetStub(); - BidiClient test(stub_.get(), DO_NOT_CANCEL, - kServerDefaultResponseStreamsToSend, - /*cork_metadata=*/false, /*first_write_async=*/true); - test.Await(); - // Make sure that the server interceptors were not notified of a cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(0, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, BidiStreamCorked) { - ResetStub(); - BidiClient test(stub_.get(), DO_NOT_CANCEL, - kServerDefaultResponseStreamsToSend, - /*cork_metadata=*/true, /*first_write_async=*/false); - test.Await(); - // Make sure that the server interceptors were not notified of a cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(0, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, BidiStreamCorkedFirstWriteAsync) { - ResetStub(); - BidiClient test(stub_.get(), DO_NOT_CANCEL, - kServerDefaultResponseStreamsToSend, - /*cork_metadata=*/true, /*first_write_async=*/true); - test.Await(); - // Make sure that the server interceptors were not notified of a cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(0, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, ClientCancelsBidiStream) { - ResetStub(); - BidiClient test(stub_.get(), DO_NOT_CANCEL, - kServerDefaultResponseStreamsToSend, - /*cork_metadata=*/false, /*first_write_async=*/false, - ClientCancelInfo(2)); - test.Await(); - // Make sure that the server interceptors were notified of a cancel - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Server to cancel before reading/writing any requests/responses on the stream -TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelBefore) { - ResetStub(); - BidiClient test(stub_.get(), CANCEL_BEFORE_PROCESSING, /*num_msgs_to_send=*/2, - /*cork_metadata=*/false, /*first_write_async=*/false); - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Server to cancel while reading/writing requests/responses on the stream in -// parallel -TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelDuring) { - ResetStub(); - BidiClient test(stub_.get(), CANCEL_DURING_PROCESSING, - /*num_msgs_to_send=*/10, /*cork_metadata=*/false, - /*first_write_async=*/false); - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Server to cancel after reading/writing all requests/responses on the stream -// but before returning to the client -TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelAfter) { - ResetStub(); - BidiClient test(stub_.get(), CANCEL_AFTER_PROCESSING, /*num_msgs_to_send=*/5, - /*cork_metadata=*/false, /*first_write_async=*/false); - test.Await(); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(ClientCallbackEnd2endTest, SimultaneousReadAndWritesDone) { - ResetStub(); - class Client : public grpc::ClientBidiReactor<EchoRequest, EchoResponse> { - public: - explicit Client(grpc::testing::EchoTestService::Stub* stub) { - request_.set_message("Hello bidi "); - stub->async()->BidiStream(&context_, this); - StartWrite(&request_); - StartCall(); - } - void OnReadDone(bool ok) override { - EXPECT_TRUE(ok); - EXPECT_EQ(response_.message(), request_.message()); - } - void OnWriteDone(bool ok) override { - EXPECT_TRUE(ok); - // Now send out the simultaneous Read and WritesDone - StartWritesDone(); - StartRead(&response_); - } - void OnDone(const Status& s) override { - EXPECT_TRUE(s.ok()); - EXPECT_EQ(response_.message(), request_.message()); - std::unique_lock<std::mutex> l(mu_); - done_ = true; - cv_.notify_one(); - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - private: - EchoRequest request_; - EchoResponse response_; - ClientContext context_; - std::mutex mu_; - std::condition_variable cv_; - bool done_ = false; - } test{stub_.get()}; - - test.Await(); -} - -TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) { - ChannelArguments args; - const auto& channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - std::shared_ptr<Channel> channel = - (GetParam().protocol == Protocol::TCP) - ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, - args) - : server_->InProcessChannel(args); - std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub; - stub = grpc::testing::UnimplementedEchoService::NewStub(channel); - EchoRequest request; - EchoResponse response; - ClientContext cli_ctx; - request.set_message("Hello world."); - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub->async()->Unimplemented( - &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) { - EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code()); - EXPECT_EQ("", s.error_message()); - - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } -} - -TEST_P(ClientCallbackEnd2endTest, TestTrailersOnlyOnError) { - // Note that trailers-only is an HTTP/2 concept so we shouldn't do this test - // for any other transport such as inproc. - if (GetParam().protocol != Protocol::TCP) { - return; - } - - ResetStub(); - class Reactor : public grpc::ClientBidiReactor<EchoRequest, EchoResponse> { - public: - explicit Reactor(grpc::testing::EchoTestService::Stub* stub) { - stub->async()->UnimplementedBidi(&context_, this); - StartCall(); - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - done_cv_.wait(l); - } - } - - private: - void OnReadInitialMetadataDone(bool ok) override { EXPECT_FALSE(ok); } - void OnDone(const Status& s) override { - EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED); - EXPECT_EQ(s.error_message(), ""); - std::unique_lock<std::mutex> l(mu_); - done_ = true; - done_cv_.notify_one(); - } - - ClientContext context_; - std::mutex mu_; - std::condition_variable done_cv_; - bool done_ = false; - } client(stub_.get()); - - client.Await(); -} - -TEST_P(ClientCallbackEnd2endTest, - ResponseStreamExtraReactionFlowReadsUntilDone) { - ResetStub(); - class ReadAllIncomingDataClient - : public grpc::ClientReadReactor<EchoResponse> { - public: - explicit ReadAllIncomingDataClient( - grpc::testing::EchoTestService::Stub* stub) { - request_.set_message("Hello client "); - stub->async()->ResponseStream(&context_, &request_, this); - } - bool WaitForReadDone() { - std::unique_lock<std::mutex> l(mu_); - while (!read_done_) { - read_cv_.wait(l); - } - read_done_ = false; - return read_ok_; - } - void Await() { - std::unique_lock<std::mutex> l(mu_); - while (!done_) { - done_cv_.wait(l); - } - } - // RemoveHold under the same lock used for OnDone to make sure that we don't - // call OnDone directly or indirectly from the RemoveHold function. - void RemoveHoldUnderLock() { - std::unique_lock<std::mutex> l(mu_); - RemoveHold(); - } - const Status& status() { - std::unique_lock<std::mutex> l(mu_); - return status_; - } - - private: - void OnReadDone(bool ok) override { - std::unique_lock<std::mutex> l(mu_); - read_ok_ = ok; - read_done_ = true; - read_cv_.notify_one(); - } - void OnDone(const Status& s) override { - std::unique_lock<std::mutex> l(mu_); - done_ = true; - status_ = s; - done_cv_.notify_one(); - } - - EchoRequest request_; - EchoResponse response_; - ClientContext context_; - bool read_ok_ = false; - bool read_done_ = false; - std::mutex mu_; - std::condition_variable read_cv_; - std::condition_variable done_cv_; - bool done_ = false; - Status status_; - } client{stub_.get()}; - - int reads_complete = 0; - client.AddHold(); - client.StartCall(); - - EchoResponse response; - bool read_ok = true; - while (read_ok) { - client.StartRead(&response); - read_ok = client.WaitForReadDone(); - if (read_ok) { - ++reads_complete; - } - } - client.RemoveHoldUnderLock(); - client.Await(); - - EXPECT_EQ(kServerDefaultResponseStreamsToSend, reads_complete); - EXPECT_EQ(client.status().error_code(), grpc::StatusCode::OK); -} - -std::vector<TestScenario> CreateTestScenarios(bool test_insecure) { -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - - std::vector<TestScenario> scenarios; - std::vector<TString> credentials_types{ - GetCredentialsProvider()->GetSecureCredentialsTypeList()}; - auto insec_ok = [] { - // Only allow insecure credentials type when it is registered with the - // provider. User may create providers that do not have insecure. - return GetCredentialsProvider()->GetChannelCredentials( - kInsecureCredentialsType, nullptr) != nullptr; - }; - if (test_insecure && insec_ok()) { - credentials_types.push_back(kInsecureCredentialsType); - } - GPR_ASSERT(!credentials_types.empty()); - - bool barr[]{false, true}; - Protocol parr[]{Protocol::INPROC, Protocol::TCP}; - for (Protocol p : parr) { - for (const auto& cred : credentials_types) { - // TODO(vjpai): Test inproc with secure credentials when feasible - if (p == Protocol::INPROC && - (cred != kInsecureCredentialsType || !insec_ok())) { - continue; - } - for (bool callback_server : barr) { - for (bool use_interceptors : barr) { - scenarios.emplace_back(callback_server, p, use_interceptors, cred); - } - } - } - } - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(true))); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(argc, argv); - grpc_init(); - int ret = RUN_ALL_TESTS(); - grpc_shutdown(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/client_crash_test.cc b/contrib/libs/grpc/test/cpp/end2end/client_crash_test.cc deleted file mode 100644 index bdb10d476e..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/client_crash_test.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* - * - * Copyright 2015 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 <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/subprocess.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -static TString g_root; - -namespace grpc { -namespace testing { - -namespace { - -class CrashTest : public ::testing::Test { - protected: - CrashTest() {} - - std::unique_ptr<grpc::testing::EchoTestService::Stub> CreateServerAndStub() { - auto port = grpc_pick_unused_port_or_die(); - std::ostringstream addr_stream; - addr_stream << "localhost:" << port; - auto addr = addr_stream.str(); - server_ = y_absl::make_unique<SubProcess>(std::vector<TString>({ - g_root + "/client_crash_test_server", - "--address=" + addr, - })); - GPR_ASSERT(server_); - return grpc::testing::EchoTestService::NewStub( - grpc::CreateChannel(addr, InsecureChannelCredentials())); - } - - void KillServer() { server_.reset(); } - - private: - std::unique_ptr<SubProcess> server_; -}; - -TEST_F(CrashTest, KillBeforeWrite) { - auto stub = CreateServerAndStub(); - - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_wait_for_ready(true); - - auto stream = stub->BidiStream(&context); - - request.set_message("Hello"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - KillServer(); - - request.set_message("You should be dead"); - // This may succeed or fail depending on the state of the TCP connection - stream->Write(request); - // But the read will definitely fail - EXPECT_FALSE(stream->Read(&response)); - - EXPECT_FALSE(stream->Finish().ok()); -} - -TEST_F(CrashTest, KillAfterWrite) { - auto stub = CreateServerAndStub(); - - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_wait_for_ready(true); - - auto stream = stub->BidiStream(&context); - - request.set_message("Hello"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - request.set_message("I'm going to kill you"); - EXPECT_TRUE(stream->Write(request)); - - KillServer(); - - // This may succeed or fail depending on how quick the server was - stream->Read(&response); - - EXPECT_FALSE(stream->Finish().ok()); -} - -} // namespace - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - TString me = argv[0]; - auto lslash = me.rfind('/'); - if (lslash != TString::npos) { - g_root = me.substr(0, lslash); - } else { - g_root = "."; - } - - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - // Order seems to matter on these tests: run three times to eliminate that - for (int i = 0; i < 3; i++) { - if (RUN_ALL_TESTS() != 0) { - return 1; - } - } - return 0; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/client_crash_test_server.cc b/contrib/libs/grpc/test/cpp/end2end/client_crash_test_server.cc deleted file mode 100644 index d08d296430..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/client_crash_test_server.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * Copyright 2015 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 <iostream> -#include <memory> -#include <util/generic/string.h> - -#include "y_absl/flags/flag.h" - -#include <grpc/support/log.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/cpp/util/test_config.h" - -Y_ABSL_FLAG(TString, address, "", "Address to bind to"); - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { - -class ServiceImpl final : public ::grpc::testing::EchoTestService::Service { - Status BidiStream( - ServerContext* /*context*/, - ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { - EchoRequest request; - EchoResponse response; - while (stream->Read(&request)) { - gpr_log(GPR_INFO, "recv msg %s", request.message().c_str()); - response.set_message(request.message()); - stream->Write(response); - } - return Status::OK; - } -}; - -void RunServer() { - ServiceImpl service; - - ServerBuilder builder; - builder.AddListeningPort(y_absl::GetFlag(FLAGS_address), - grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr<Server> server(builder.BuildAndStart()); - std::cout << "Server listening on " << y_absl::GetFlag(FLAGS_address) - << std::endl; - server->Wait(); -} -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); - grpc::testing::RunServer(); - - return 0; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/client_interceptors_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/client_interceptors_end2end_test.cc deleted file mode 100644 index 4b9a030227..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/client_interceptors_end2end_test.cc +++ /dev/null @@ -1,1244 +0,0 @@ -/* - * - * Copyright 2018 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 <memory> -#include <vector> - -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/create_channel_posix.h> -#include <grpcpp/generic/generic_stub.h> -#include <grpcpp/impl/codegen/proto_utils.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/server_posix.h> -#include <grpcpp/support/client_interceptor.h> - -#include "src/core/lib/iomgr/port.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/interceptors_util.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/byte_buffer_proto_helper.h" -#include "test/cpp/util/string_ref_helper.h" - -#ifdef GRPC_POSIX_SOCKET -#include <fcntl.h> - -#include "src/core/lib/iomgr/socket_utils_posix.h" -#endif /* GRPC_POSIX_SOCKET */ - -namespace grpc { -namespace testing { -namespace { - -enum class RPCType { - kSyncUnary, - kSyncClientStreaming, - kSyncServerStreaming, - kSyncBidiStreaming, - kAsyncCQUnary, - kAsyncCQClientStreaming, - kAsyncCQServerStreaming, - kAsyncCQBidiStreaming, -}; - -enum class ChannelType { - kHttpChannel, - kFdChannel, -}; - -/* Hijacks Echo RPC and fills in the expected values */ -class HijackingInterceptor : public experimental::Interceptor { - public: - explicit HijackingInterceptor(experimental::ClientRpcInfo* info) { - info_ = info; - // Make sure it is the right method - EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0); - EXPECT_EQ(info->suffix_for_stats(), nullptr); - EXPECT_EQ(info->type(), experimental::ClientRpcInfo::Type::UNARY); - } - - void Intercept(experimental::InterceptorBatchMethods* methods) override { - bool hijack = false; - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { - auto* map = methods->GetSendInitialMetadata(); - // Check that we can see the test metadata - ASSERT_EQ(map->size(), static_cast<unsigned>(1)); - auto iterator = map->begin(); - EXPECT_EQ("testkey", iterator->first); - EXPECT_EQ("testvalue", iterator->second); - hijack = true; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EchoRequest req; - auto* buffer = methods->GetSerializedSendMessage(); - auto copied_buffer = *buffer; - EXPECT_TRUE( - SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req) - .ok()); - EXPECT_EQ(req.message(), "Hello"); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { - // Got nothing to do here for now - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) { - auto* map = methods->GetRecvInitialMetadata(); - // Got nothing better to do here for now - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { - EchoResponse* resp = - static_cast<EchoResponse*>(methods->GetRecvMessage()); - // Check that we got the hijacked message, and re-insert the expected - // message - EXPECT_EQ(resp->message(), "Hello1"); - resp->set_message("Hello"); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_STATUS)) { - auto* map = methods->GetRecvTrailingMetadata(); - bool found = false; - // Check that we received the metadata as an echo - for (const auto& pair : *map) { - found = pair.first.starts_with("testkey") && - pair.second.starts_with("testvalue"); - if (found) break; - } - EXPECT_EQ(found, true); - auto* status = methods->GetRecvStatus(); - EXPECT_EQ(status->ok(), true); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_INITIAL_METADATA)) { - auto* map = methods->GetRecvInitialMetadata(); - // Got nothing better to do here at the moment - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { - // Insert a different message than expected - EchoResponse* resp = - static_cast<EchoResponse*>(methods->GetRecvMessage()); - resp->set_message("Hello1"); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { - auto* map = methods->GetRecvTrailingMetadata(); - // insert the metadata that we want - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - map->insert(std::make_pair("testkey", "testvalue")); - auto* status = methods->GetRecvStatus(); - *status = Status(StatusCode::OK, ""); - } - if (hijack) { - methods->Hijack(); - } else { - methods->Proceed(); - } - } - - private: - experimental::ClientRpcInfo* info_; -}; - -class HijackingInterceptorFactory - : public experimental::ClientInterceptorFactoryInterface { - public: - experimental::Interceptor* CreateClientInterceptor( - experimental::ClientRpcInfo* info) override { - return new HijackingInterceptor(info); - } -}; - -class HijackingInterceptorMakesAnotherCall : public experimental::Interceptor { - public: - explicit HijackingInterceptorMakesAnotherCall( - experimental::ClientRpcInfo* info) { - info_ = info; - // Make sure it is the right method - EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0); - EXPECT_EQ(strcmp("TestSuffixForStats", info->suffix_for_stats()), 0); - } - - void Intercept(experimental::InterceptorBatchMethods* methods) override { - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { - auto* map = methods->GetSendInitialMetadata(); - // Check that we can see the test metadata - ASSERT_EQ(map->size(), static_cast<unsigned>(1)); - auto iterator = map->begin(); - EXPECT_EQ("testkey", iterator->first); - EXPECT_EQ("testvalue", iterator->second); - // Make a copy of the map - metadata_map_ = *map; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EchoRequest req; - auto* buffer = methods->GetSerializedSendMessage(); - auto copied_buffer = *buffer; - EXPECT_TRUE( - SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req) - .ok()); - EXPECT_EQ(req.message(), "Hello"); - req_ = req; - stub_ = grpc::testing::EchoTestService::NewStub( - methods->GetInterceptedChannel()); - ctx_.AddMetadata(metadata_map_.begin()->first, - metadata_map_.begin()->second); - stub_->async()->Echo(&ctx_, &req_, &resp_, [this, methods](Status s) { - EXPECT_EQ(s.ok(), true); - EXPECT_EQ(resp_.message(), "Hello"); - methods->Hijack(); - }); - // This is a Unary RPC and we have got nothing interesting to do in the - // PRE_SEND_CLOSE interception hook point for this interceptor, so let's - // return here. (We do not want to call methods->Proceed(). When the new - // RPC returns, we will call methods->Hijack() instead.) - return; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { - // Got nothing to do here for now - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) { - auto* map = methods->GetRecvInitialMetadata(); - // Got nothing better to do here for now - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { - EchoResponse* resp = - static_cast<EchoResponse*>(methods->GetRecvMessage()); - // Check that we got the hijacked message, and re-insert the expected - // message - EXPECT_EQ(resp->message(), "Hello"); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_STATUS)) { - auto* map = methods->GetRecvTrailingMetadata(); - bool found = false; - // Check that we received the metadata as an echo - for (const auto& pair : *map) { - found = pair.first.starts_with("testkey") && - pair.second.starts_with("testvalue"); - if (found) break; - } - EXPECT_EQ(found, true); - auto* status = methods->GetRecvStatus(); - EXPECT_EQ(status->ok(), true); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_INITIAL_METADATA)) { - auto* map = methods->GetRecvInitialMetadata(); - // Got nothing better to do here at the moment - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { - // Insert a different message than expected - EchoResponse* resp = - static_cast<EchoResponse*>(methods->GetRecvMessage()); - resp->set_message(resp_.message()); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { - auto* map = methods->GetRecvTrailingMetadata(); - // insert the metadata that we want - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - map->insert(std::make_pair("testkey", "testvalue")); - auto* status = methods->GetRecvStatus(); - *status = Status(StatusCode::OK, ""); - } - - methods->Proceed(); - } - - private: - experimental::ClientRpcInfo* info_; - std::multimap<TString, TString> metadata_map_; - ClientContext ctx_; - EchoRequest req_; - EchoResponse resp_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; -}; - -class HijackingInterceptorMakesAnotherCallFactory - : public experimental::ClientInterceptorFactoryInterface { - public: - experimental::Interceptor* CreateClientInterceptor( - experimental::ClientRpcInfo* info) override { - return new HijackingInterceptorMakesAnotherCall(info); - } -}; - -class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor { - public: - explicit BidiStreamingRpcHijackingInterceptor( - experimental::ClientRpcInfo* info) { - info_ = info; - EXPECT_EQ(info->suffix_for_stats(), nullptr); - } - - void Intercept(experimental::InterceptorBatchMethods* methods) override { - bool hijack = false; - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { - CheckMetadata(*methods->GetSendInitialMetadata(), "testkey", "testvalue"); - hijack = true; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EchoRequest req; - auto* buffer = methods->GetSerializedSendMessage(); - auto copied_buffer = *buffer; - EXPECT_TRUE( - SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req) - .ok()); - EXPECT_EQ(req.message().find("Hello"), 0u); - msg = req.message(); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { - // Got nothing to do here for now - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_STATUS)) { - CheckMetadata(*methods->GetRecvTrailingMetadata(), "testkey", - "testvalue"); - auto* status = methods->GetRecvStatus(); - EXPECT_EQ(status->ok(), true); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { - EchoResponse* resp = - static_cast<EchoResponse*>(methods->GetRecvMessage()); - resp->set_message(msg); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { - EXPECT_EQ(static_cast<EchoResponse*>(methods->GetRecvMessage()) - ->message() - .find("Hello"), - 0u); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { - auto* map = methods->GetRecvTrailingMetadata(); - // insert the metadata that we want - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - map->insert(std::make_pair("testkey", "testvalue")); - auto* status = methods->GetRecvStatus(); - *status = Status(StatusCode::OK, ""); - } - if (hijack) { - methods->Hijack(); - } else { - methods->Proceed(); - } - } - - private: - experimental::ClientRpcInfo* info_; - TString msg; -}; - -class ClientStreamingRpcHijackingInterceptor - : public experimental::Interceptor { - public: - explicit ClientStreamingRpcHijackingInterceptor( - experimental::ClientRpcInfo* info) { - info_ = info; - EXPECT_EQ( - strcmp("/grpc.testing.EchoTestService/RequestStream", info->method()), - 0); - EXPECT_EQ(strcmp("TestSuffixForStats", info->suffix_for_stats()), 0); - } - void Intercept(experimental::InterceptorBatchMethods* methods) override { - bool hijack = false; - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { - hijack = true; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - if (++count_ > 10) { - methods->FailHijackedSendMessage(); - } - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_SEND_MESSAGE)) { - EXPECT_FALSE(got_failed_send_); - got_failed_send_ = !methods->GetSendMessageStatus(); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { - auto* status = methods->GetRecvStatus(); - *status = Status(StatusCode::UNAVAILABLE, "Done sending 10 messages"); - } - if (hijack) { - methods->Hijack(); - } else { - methods->Proceed(); - } - } - - static bool GotFailedSend() { return got_failed_send_; } - - private: - experimental::ClientRpcInfo* info_; - int count_ = 0; - static bool got_failed_send_; -}; - -bool ClientStreamingRpcHijackingInterceptor::got_failed_send_ = false; - -class ClientStreamingRpcHijackingInterceptorFactory - : public experimental::ClientInterceptorFactoryInterface { - public: - experimental::Interceptor* CreateClientInterceptor( - experimental::ClientRpcInfo* info) override { - return new ClientStreamingRpcHijackingInterceptor(info); - } -}; - -class ServerStreamingRpcHijackingInterceptor - : public experimental::Interceptor { - public: - explicit ServerStreamingRpcHijackingInterceptor( - experimental::ClientRpcInfo* info) { - info_ = info; - got_failed_message_ = false; - EXPECT_EQ(info->suffix_for_stats(), nullptr); - } - - void Intercept(experimental::InterceptorBatchMethods* methods) override { - bool hijack = false; - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { - auto* map = methods->GetSendInitialMetadata(); - // Check that we can see the test metadata - ASSERT_EQ(map->size(), static_cast<unsigned>(1)); - auto iterator = map->begin(); - EXPECT_EQ("testkey", iterator->first); - EXPECT_EQ("testvalue", iterator->second); - hijack = true; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EchoRequest req; - auto* buffer = methods->GetSerializedSendMessage(); - auto copied_buffer = *buffer; - EXPECT_TRUE( - SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req) - .ok()); - EXPECT_EQ(req.message(), "Hello"); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { - // Got nothing to do here for now - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_STATUS)) { - auto* map = methods->GetRecvTrailingMetadata(); - bool found = false; - // Check that we received the metadata as an echo - for (const auto& pair : *map) { - found = pair.first.starts_with("testkey") && - pair.second.starts_with("testvalue"); - if (found) break; - } - EXPECT_EQ(found, true); - auto* status = methods->GetRecvStatus(); - EXPECT_EQ(status->ok(), true); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { - if (++count_ > 10) { - methods->FailHijackedRecvMessage(); - } - EchoResponse* resp = - static_cast<EchoResponse*>(methods->GetRecvMessage()); - resp->set_message("Hello"); - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { - // Only the last message will be a failure - EXPECT_FALSE(got_failed_message_); - got_failed_message_ = methods->GetRecvMessage() == nullptr; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { - auto* map = methods->GetRecvTrailingMetadata(); - // insert the metadata that we want - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - map->insert(std::make_pair("testkey", "testvalue")); - auto* status = methods->GetRecvStatus(); - *status = Status(StatusCode::OK, ""); - } - if (hijack) { - methods->Hijack(); - } else { - methods->Proceed(); - } - } - - static bool GotFailedMessage() { return got_failed_message_; } - - private: - experimental::ClientRpcInfo* info_; - static bool got_failed_message_; - int count_ = 0; -}; - -bool ServerStreamingRpcHijackingInterceptor::got_failed_message_ = false; - -class ServerStreamingRpcHijackingInterceptorFactory - : public experimental::ClientInterceptorFactoryInterface { - public: - experimental::Interceptor* CreateClientInterceptor( - experimental::ClientRpcInfo* info) override { - return new ServerStreamingRpcHijackingInterceptor(info); - } -}; - -class BidiStreamingRpcHijackingInterceptorFactory - : public experimental::ClientInterceptorFactoryInterface { - public: - experimental::Interceptor* CreateClientInterceptor( - experimental::ClientRpcInfo* info) override { - return new BidiStreamingRpcHijackingInterceptor(info); - } -}; - -// The logging interceptor is for testing purposes only. It is used to verify -// that all the appropriate hook points are invoked for an RPC. The counts are -// reset each time a new object of LoggingInterceptor is created, so only a -// single RPC should be made on the channel before calling the Verify methods. -class LoggingInterceptor : public experimental::Interceptor { - public: - explicit LoggingInterceptor(experimental::ClientRpcInfo* /*info*/) { - pre_send_initial_metadata_ = false; - pre_send_message_count_ = 0; - pre_send_close_ = false; - post_recv_initial_metadata_ = false; - post_recv_message_count_ = 0; - post_recv_status_ = false; - } - - void Intercept(experimental::InterceptorBatchMethods* methods) override { - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { - auto* map = methods->GetSendInitialMetadata(); - // Check that we can see the test metadata - ASSERT_EQ(map->size(), static_cast<unsigned>(1)); - auto iterator = map->begin(); - EXPECT_EQ("testkey", iterator->first); - EXPECT_EQ("testvalue", iterator->second); - ASSERT_FALSE(pre_send_initial_metadata_); - pre_send_initial_metadata_ = true; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { - EchoRequest req; - auto* send_msg = methods->GetSendMessage(); - if (send_msg == nullptr) { - // We did not get the non-serialized form of the message. Get the - // serialized form. - auto* buffer = methods->GetSerializedSendMessage(); - auto copied_buffer = *buffer; - EchoRequest req; - EXPECT_TRUE( - SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req) - .ok()); - EXPECT_EQ(req.message(), "Hello"); - } else { - EXPECT_EQ( - static_cast<const EchoRequest*>(send_msg)->message().find("Hello"), - 0u); - } - auto* buffer = methods->GetSerializedSendMessage(); - auto copied_buffer = *buffer; - EXPECT_TRUE( - SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req) - .ok()); - EXPECT_TRUE(req.message().find("Hello") == 0u); - pre_send_message_count_++; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { - // Got nothing to do here for now - pre_send_close_ = true; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) { - auto* map = methods->GetRecvInitialMetadata(); - // Got nothing better to do here for now - EXPECT_EQ(map->size(), static_cast<unsigned>(0)); - post_recv_initial_metadata_ = true; - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { - EchoResponse* resp = - static_cast<EchoResponse*>(methods->GetRecvMessage()); - if (resp != nullptr) { - EXPECT_TRUE(resp->message().find("Hello") == 0u); - post_recv_message_count_++; - } - } - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_STATUS)) { - auto* map = methods->GetRecvTrailingMetadata(); - bool found = false; - // Check that we received the metadata as an echo - for (const auto& pair : *map) { - found = pair.first.starts_with("testkey") && - pair.second.starts_with("testvalue"); - if (found) break; - } - EXPECT_EQ(found, true); - auto* status = methods->GetRecvStatus(); - EXPECT_EQ(status->ok(), true); - post_recv_status_ = true; - } - methods->Proceed(); - } - - static void VerifyCall(RPCType type) { - switch (type) { - case RPCType::kSyncUnary: - case RPCType::kAsyncCQUnary: - VerifyUnaryCall(); - break; - case RPCType::kSyncClientStreaming: - case RPCType::kAsyncCQClientStreaming: - VerifyClientStreamingCall(); - break; - case RPCType::kSyncServerStreaming: - case RPCType::kAsyncCQServerStreaming: - VerifyServerStreamingCall(); - break; - case RPCType::kSyncBidiStreaming: - case RPCType::kAsyncCQBidiStreaming: - VerifyBidiStreamingCall(); - break; - } - } - - static void VerifyCallCommon() { - EXPECT_TRUE(pre_send_initial_metadata_); - EXPECT_TRUE(pre_send_close_); - EXPECT_TRUE(post_recv_initial_metadata_); - EXPECT_TRUE(post_recv_status_); - } - - static void VerifyUnaryCall() { - VerifyCallCommon(); - EXPECT_EQ(pre_send_message_count_, 1); - EXPECT_EQ(post_recv_message_count_, 1); - } - - static void VerifyClientStreamingCall() { - VerifyCallCommon(); - EXPECT_EQ(pre_send_message_count_, kNumStreamingMessages); - EXPECT_EQ(post_recv_message_count_, 1); - } - - static void VerifyServerStreamingCall() { - VerifyCallCommon(); - EXPECT_EQ(pre_send_message_count_, 1); - EXPECT_EQ(post_recv_message_count_, kNumStreamingMessages); - } - - static void VerifyBidiStreamingCall() { - VerifyCallCommon(); - EXPECT_EQ(pre_send_message_count_, kNumStreamingMessages); - EXPECT_EQ(post_recv_message_count_, kNumStreamingMessages); - } - - private: - static bool pre_send_initial_metadata_; - static int pre_send_message_count_; - static bool pre_send_close_; - static bool post_recv_initial_metadata_; - static int post_recv_message_count_; - static bool post_recv_status_; -}; - -bool LoggingInterceptor::pre_send_initial_metadata_; -int LoggingInterceptor::pre_send_message_count_; -bool LoggingInterceptor::pre_send_close_; -bool LoggingInterceptor::post_recv_initial_metadata_; -int LoggingInterceptor::post_recv_message_count_; -bool LoggingInterceptor::post_recv_status_; - -class LoggingInterceptorFactory - : public experimental::ClientInterceptorFactoryInterface { - public: - experimental::Interceptor* CreateClientInterceptor( - experimental::ClientRpcInfo* info) override { - return new LoggingInterceptor(info); - } -}; - -class TestScenario { - public: - explicit TestScenario(const ChannelType& channel_type, - const RPCType& rpc_type) - : channel_type_(channel_type), rpc_type_(rpc_type) {} - - ChannelType channel_type() const { return channel_type_; } - - RPCType rpc_type() const { return rpc_type_; } - - private: - const ChannelType channel_type_; - const RPCType rpc_type_; -}; - -std::vector<TestScenario> CreateTestScenarios() { - std::vector<TestScenario> scenarios; - std::vector<RPCType> rpc_types; - rpc_types.emplace_back(RPCType::kSyncUnary); - rpc_types.emplace_back(RPCType::kSyncClientStreaming); - rpc_types.emplace_back(RPCType::kSyncServerStreaming); - rpc_types.emplace_back(RPCType::kSyncBidiStreaming); - rpc_types.emplace_back(RPCType::kAsyncCQUnary); - rpc_types.emplace_back(RPCType::kAsyncCQServerStreaming); - for (const auto& rpc_type : rpc_types) { - scenarios.emplace_back(ChannelType::kHttpChannel, rpc_type); -// TODO(yashykt): Maybe add support for non-posix sockets too -#ifdef GRPC_POSIX_SOCKET - scenarios.emplace_back(ChannelType::kFdChannel, rpc_type); -#endif /* GRPC_POSIX_SOCKET */ - } - return scenarios; -} - -class ParameterizedClientInterceptorsEnd2endTest - : public ::testing::TestWithParam<TestScenario> { - protected: - ParameterizedClientInterceptorsEnd2endTest() { - ServerBuilder builder; - builder.RegisterService(&service_); - if (GetParam().channel_type() == ChannelType::kHttpChannel) { - int port = grpc_pick_unused_port_or_die(); - server_address_ = "localhost:" + ToString(port); - builder.AddListeningPort(server_address_, InsecureServerCredentials()); - server_ = builder.BuildAndStart(); - } -#ifdef GRPC_POSIX_SOCKET - else if (GetParam().channel_type() == ChannelType::kFdChannel) { - int flags; - GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv_) == 0); - flags = fcntl(sv_[0], F_GETFL, 0); - GPR_ASSERT(fcntl(sv_[0], F_SETFL, flags | O_NONBLOCK) == 0); - flags = fcntl(sv_[1], F_GETFL, 0); - GPR_ASSERT(fcntl(sv_[1], F_SETFL, flags | O_NONBLOCK) == 0); - GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv_[0]) == - GRPC_ERROR_NONE); - GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv_[1]) == - GRPC_ERROR_NONE); - server_ = builder.BuildAndStart(); - AddInsecureChannelFromFd(server_.get(), sv_[1]); - } -#endif /* GRPC_POSIX_SOCKET */ - } - - ~ParameterizedClientInterceptorsEnd2endTest() override { - server_->Shutdown(); - } - - std::shared_ptr<grpc::Channel> CreateClientChannel( - std::vector<std::unique_ptr< - grpc::experimental::ClientInterceptorFactoryInterface>> - creators) { - if (GetParam().channel_type() == ChannelType::kHttpChannel) { - return experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), ChannelArguments(), - std::move(creators)); - } -#ifdef GRPC_POSIX_SOCKET - else if (GetParam().channel_type() == ChannelType::kFdChannel) { - return experimental::CreateCustomInsecureChannelWithInterceptorsFromFd( - "", sv_[0], ChannelArguments(), std::move(creators)); - } -#endif /* GRPC_POSIX_SOCKET */ - return nullptr; - } - - void SendRPC(const std::shared_ptr<Channel>& channel) { - switch (GetParam().rpc_type()) { - case RPCType::kSyncUnary: - MakeCall(channel); - break; - case RPCType::kSyncClientStreaming: - MakeClientStreamingCall(channel); - break; - case RPCType::kSyncServerStreaming: - MakeServerStreamingCall(channel); - break; - case RPCType::kSyncBidiStreaming: - MakeBidiStreamingCall(channel); - break; - case RPCType::kAsyncCQUnary: - MakeAsyncCQCall(channel); - break; - case RPCType::kAsyncCQClientStreaming: - // TODO(yashykt) : Fill this out - break; - case RPCType::kAsyncCQServerStreaming: - MakeAsyncCQServerStreamingCall(channel); - break; - case RPCType::kAsyncCQBidiStreaming: - // TODO(yashykt) : Fill this out - break; - } - } - - TString server_address_; - int sv_[2]; - EchoTestServiceStreamingImpl service_; - std::unique_ptr<Server> server_; -}; - -TEST_P(ParameterizedClientInterceptorsEnd2endTest, - ClientInterceptorLoggingTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back(y_absl::make_unique<LoggingInterceptorFactory>()); - // Add 20 phony interceptors - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = CreateClientChannel(std::move(creators)); - SendRPC(channel); - LoggingInterceptor::VerifyCall(GetParam().rpc_type()); - // Make sure all 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); -} - -INSTANTIATE_TEST_SUITE_P(ParameterizedClientInterceptorsEnd2end, - ParameterizedClientInterceptorsEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios())); - -class ClientInterceptorsEnd2endTest - : public ::testing::TestWithParam<TestScenario> { - protected: - ClientInterceptorsEnd2endTest() { - int port = grpc_pick_unused_port_or_die(); - - ServerBuilder builder; - server_address_ = "localhost:" + ToString(port); - builder.AddListeningPort(server_address_, InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - ~ClientInterceptorsEnd2endTest() override { server_->Shutdown(); } - - TString server_address_; - TestServiceImpl service_; - std::unique_ptr<Server> server_; -}; - -TEST_F(ClientInterceptorsEnd2endTest, - LameChannelClientInterceptorHijackingTest) { - ChannelArguments args; - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back(y_absl::make_unique<HijackingInterceptorFactory>()); - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, nullptr, args, std::move(creators)); - MakeCall(channel); -} - -TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - // Add 20 phony interceptors before hijacking interceptor - creators.reserve(20); - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - creators.push_back(y_absl::make_unique<HijackingInterceptorFactory>()); - // Add 20 phony interceptors after hijacking interceptor - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeCall(channel); - // Make sure only 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); -} - -TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLogThenHijackTest) { - ChannelArguments args; - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back(y_absl::make_unique<LoggingInterceptorFactory>()); - creators.push_back(y_absl::make_unique<HijackingInterceptorFactory>()); - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeCall(channel); - LoggingInterceptor::VerifyUnaryCall(); -} - -TEST_F(ClientInterceptorsEnd2endTest, - ClientInterceptorHijackingMakesAnotherCallTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - // Add 5 phony interceptors before hijacking interceptor - creators.reserve(5); - for (auto i = 0; i < 5; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - creators.push_back( - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>( - new HijackingInterceptorMakesAnotherCallFactory())); - // Add 7 phony interceptors after hijacking interceptor - for (auto i = 0; i < 7; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = server_->experimental().InProcessChannelWithInterceptors( - args, std::move(creators)); - - MakeCall(channel, StubOptions("TestSuffixForStats")); - // Make sure all interceptors were run once, since the hijacking interceptor - // makes an RPC on the intercepted channel - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 12); -} - -class ClientInterceptorsCallbackEnd2endTest : public ::testing::Test { - protected: - ClientInterceptorsCallbackEnd2endTest() { - int port = grpc_pick_unused_port_or_die(); - - ServerBuilder builder; - server_address_ = "localhost:" + ToString(port); - builder.AddListeningPort(server_address_, InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - ~ClientInterceptorsCallbackEnd2endTest() override { server_->Shutdown(); } - - TString server_address_; - TestServiceImpl service_; - std::unique_ptr<Server> server_; -}; - -TEST_F(ClientInterceptorsCallbackEnd2endTest, - ClientInterceptorLoggingTestWithCallback) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back(y_absl::make_unique<LoggingInterceptorFactory>()); - // Add 20 phony interceptors - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = server_->experimental().InProcessChannelWithInterceptors( - args, std::move(creators)); - MakeCallbackCall(channel); - LoggingInterceptor::VerifyUnaryCall(); - // Make sure all 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); -} - -TEST_F(ClientInterceptorsCallbackEnd2endTest, - ClientInterceptorFactoryAllowsNullptrReturn) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back(y_absl::make_unique<LoggingInterceptorFactory>()); - // Add 20 phony interceptors and 20 null interceptors - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - creators.push_back(y_absl::make_unique<NullInterceptorFactory>()); - } - auto channel = server_->experimental().InProcessChannelWithInterceptors( - args, std::move(creators)); - MakeCallbackCall(channel); - LoggingInterceptor::VerifyUnaryCall(); - // Make sure all 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); -} - -class ClientInterceptorsStreamingEnd2endTest : public ::testing::Test { - protected: - ClientInterceptorsStreamingEnd2endTest() { - int port = grpc_pick_unused_port_or_die(); - - ServerBuilder builder; - server_address_ = "localhost:" + ToString(port); - builder.AddListeningPort(server_address_, InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - ~ClientInterceptorsStreamingEnd2endTest() override { server_->Shutdown(); } - - TString server_address_; - EchoTestServiceStreamingImpl service_; - std::unique_ptr<Server> server_; -}; - -TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back(y_absl::make_unique<LoggingInterceptorFactory>()); - // Add 20 phony interceptors - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeClientStreamingCall(channel); - LoggingInterceptor::VerifyClientStreamingCall(); - // Make sure all 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); -} - -TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back(y_absl::make_unique<LoggingInterceptorFactory>()); - // Add 20 phony interceptors - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeServerStreamingCall(channel); - LoggingInterceptor::VerifyServerStreamingCall(); - // Make sure all 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); -} - -TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) { - ChannelArguments args; - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back( - y_absl::make_unique<ClientStreamingRpcHijackingInterceptorFactory>()); - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - - auto stub = grpc::testing::EchoTestService::NewStub( - channel, StubOptions("TestSuffixForStats")); - ClientContext ctx; - EchoRequest req; - EchoResponse resp; - req.mutable_param()->set_echo_metadata(true); - req.set_message("Hello"); - string expected_resp = ""; - auto writer = stub->RequestStream(&ctx, &resp); - for (int i = 0; i < 10; i++) { - EXPECT_TRUE(writer->Write(req)); - expected_resp += "Hello"; - } - // The interceptor will reject the 11th message - writer->Write(req); - Status s = writer->Finish(); - EXPECT_EQ(s.ok(), false); - EXPECT_TRUE(ClientStreamingRpcHijackingInterceptor::GotFailedSend()); -} - -TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingHijackingTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back( - y_absl::make_unique<ServerStreamingRpcHijackingInterceptorFactory>()); - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeServerStreamingCall(channel); - EXPECT_TRUE(ServerStreamingRpcHijackingInterceptor::GotFailedMessage()); -} - -TEST_F(ClientInterceptorsStreamingEnd2endTest, - AsyncCQServerStreamingHijackingTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back( - y_absl::make_unique<ServerStreamingRpcHijackingInterceptorFactory>()); - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeAsyncCQServerStreamingCall(channel); - EXPECT_TRUE(ServerStreamingRpcHijackingInterceptor::GotFailedMessage()); -} - -TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingHijackingTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back( - y_absl::make_unique<BidiStreamingRpcHijackingInterceptorFactory>()); - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeBidiStreamingCall(channel); -} - -TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - creators.push_back(y_absl::make_unique<LoggingInterceptorFactory>()); - // Add 20 phony interceptors - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeBidiStreamingCall(channel); - LoggingInterceptor::VerifyBidiStreamingCall(); - // Make sure all 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); -} - -class ClientGlobalInterceptorEnd2endTest : public ::testing::Test { - protected: - ClientGlobalInterceptorEnd2endTest() { - int port = grpc_pick_unused_port_or_die(); - - ServerBuilder builder; - server_address_ = "localhost:" + ToString(port); - builder.AddListeningPort(server_address_, InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - ~ClientGlobalInterceptorEnd2endTest() override { server_->Shutdown(); } - - TString server_address_; - TestServiceImpl service_; - std::unique_ptr<Server> server_; -}; - -TEST_F(ClientGlobalInterceptorEnd2endTest, PhonyGlobalInterceptor) { - // We should ideally be registering a global interceptor only once per - // process, but for the purposes of testing, it should be fine to modify the - // registered global interceptor when there are no ongoing gRPC operations - PhonyInterceptorFactory global_factory; - experimental::RegisterGlobalClientInterceptorFactory(&global_factory); - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - // Add 20 phony interceptors - creators.reserve(20); - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeCall(channel); - // Make sure all 20 phony interceptors were run with the global interceptor - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 21); - experimental::TestOnlyResetGlobalClientInterceptorFactory(); -} - -TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { - // We should ideally be registering a global interceptor only once per - // process, but for the purposes of testing, it should be fine to modify the - // registered global interceptor when there are no ongoing gRPC operations - LoggingInterceptorFactory global_factory; - experimental::RegisterGlobalClientInterceptorFactory(&global_factory); - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - // Add 20 phony interceptors - creators.reserve(20); - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeCall(channel); - LoggingInterceptor::VerifyUnaryCall(); - // Make sure all 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); - experimental::TestOnlyResetGlobalClientInterceptorFactory(); -} - -TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { - // We should ideally be registering a global interceptor only once per - // process, but for the purposes of testing, it should be fine to modify the - // registered global interceptor when there are no ongoing gRPC operations - HijackingInterceptorFactory global_factory; - experimental::RegisterGlobalClientInterceptorFactory(&global_factory); - ChannelArguments args; - PhonyInterceptor::Reset(); - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - creators; - // Add 20 phony interceptors - creators.reserve(20); - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - auto channel = experimental::CreateCustomChannelWithInterceptors( - server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeCall(channel); - // Make sure all 20 phony interceptors were run - EXPECT_EQ(PhonyInterceptor::GetNumTimesRun(), 20); - experimental::TestOnlyResetGlobalClientInterceptorFactory(); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/client_lb_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/client_lb_end2end_test.cc deleted file mode 100644 index 31bac68e6d..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/client_lb_end2end_test.cc +++ /dev/null @@ -1,2023 +0,0 @@ -/* - * - * Copyright 2016 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 <algorithm> -#include <memory> -#include <mutex> -#include <random> -#include <set> -#include <util/generic/string.h> -#include <thread> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" -#include "y_absl/strings/str_cat.h" -#include "y_absl/strings/str_format.h" -#include "y_absl/strings/str_join.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/health_check_service_interface.h> -#include <grpcpp/impl/codegen/sync.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" -#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/service_config/service_config.h" -#include "src/core/lib/address_utils/parse_address.h" -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/gprpp/debug_location.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/iomgr/tcp_client.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/client/secure_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "src/proto/grpc/testing/xds/v3/orca_load_report.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/resolve_localhost_ip46.h" -#include "test/core/util/test_config.h" -#include "test/core/util/test_lb_policies.h" -#include "test/cpp/end2end/test_service_impl.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -// defined in tcp_client.cc -extern grpc_tcp_client_vtable* grpc_tcp_client_impl; - -static grpc_tcp_client_vtable* default_client_impl; - -namespace grpc { -namespace testing { -namespace { - -gpr_atm g_connection_delay_ms; - -void tcp_client_connect_with_delay(grpc_closure* closure, grpc_endpoint** ep, - grpc_pollset_set* interested_parties, - const grpc_channel_args* channel_args, - const grpc_resolved_address* addr, - grpc_millis deadline) { - const int delay_ms = gpr_atm_acq_load(&g_connection_delay_ms); - if (delay_ms > 0) { - gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(delay_ms)); - } - default_client_impl->connect(closure, ep, interested_parties, channel_args, - addr, deadline + delay_ms); -} - -grpc_tcp_client_vtable delayed_connect = {tcp_client_connect_with_delay}; - -// Subclass of TestServiceImpl that increments a request counter for -// every call to the Echo RPC. -class MyTestServiceImpl : public TestServiceImpl { - public: - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - const xds::data::orca::v3::OrcaLoadReport* load_report = nullptr; - { - grpc::internal::MutexLock lock(&mu_); - ++request_count_; - load_report = load_report_; - } - AddClient(context->peer().c_str()); - if (load_report != nullptr) { - // TODO(roth): Once we provide a more standard server-side API for - // populating this data, use that API here. - context->AddTrailingMetadata("x-endpoint-load-metrics-bin", - load_report->SerializeAsString()); - } - return TestServiceImpl::Echo(context, request, response); - } - - int request_count() { - grpc::internal::MutexLock lock(&mu_); - return request_count_; - } - - void ResetCounters() { - grpc::internal::MutexLock lock(&mu_); - request_count_ = 0; - } - - std::set<TString> clients() { - grpc::internal::MutexLock lock(&clients_mu_); - return clients_; - } - - void set_load_report(xds::data::orca::v3::OrcaLoadReport* load_report) { - grpc::internal::MutexLock lock(&mu_); - load_report_ = load_report; - } - - private: - void AddClient(const TString& client) { - grpc::internal::MutexLock lock(&clients_mu_); - clients_.insert(client); - } - - grpc::internal::Mutex mu_; - int request_count_ = 0; - const xds::data::orca::v3::OrcaLoadReport* load_report_ = nullptr; - grpc::internal::Mutex clients_mu_; - std::set<TString> clients_; -}; - -class FakeResolverResponseGeneratorWrapper { - public: - explicit FakeResolverResponseGeneratorWrapper(bool ipv6_only) - : ipv6_only_(ipv6_only), - response_generator_(grpc_core::MakeRefCounted< - grpc_core::FakeResolverResponseGenerator>()) {} - - FakeResolverResponseGeneratorWrapper( - FakeResolverResponseGeneratorWrapper&& other) noexcept { - ipv6_only_ = other.ipv6_only_; - response_generator_ = std::move(other.response_generator_); - } - - void SetNextResolution( - const std::vector<int>& ports, const char* service_config_json = nullptr, - const char* attribute_key = nullptr, - std::unique_ptr<grpc_core::ServerAddress::AttributeInterface> attribute = - nullptr) { - grpc_core::ExecCtx exec_ctx; - response_generator_->SetResponse( - BuildFakeResults(ipv6_only_, ports, service_config_json, attribute_key, - std::move(attribute))); - } - - void SetNextResolutionUponError(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; - response_generator_->SetReresolutionResponse( - BuildFakeResults(ipv6_only_, ports)); - } - - void SetFailureOnReresolution() { - grpc_core::ExecCtx exec_ctx; - response_generator_->SetFailureOnReresolution(); - } - - grpc_core::FakeResolverResponseGenerator* Get() const { - return response_generator_.get(); - } - - private: - static grpc_core::Resolver::Result BuildFakeResults( - bool ipv6_only, const std::vector<int>& ports, - const char* service_config_json = nullptr, - const char* attribute_key = nullptr, - std::unique_ptr<grpc_core::ServerAddress::AttributeInterface> attribute = - nullptr) { - grpc_core::Resolver::Result result; - for (const int& port : ports) { - y_absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse( - y_absl::StrCat(ipv6_only ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port)); - GPR_ASSERT(lb_uri.ok()); - grpc_resolved_address address; - GPR_ASSERT(grpc_parse_uri(*lb_uri, &address)); - std::map<const char*, - std::unique_ptr<grpc_core::ServerAddress::AttributeInterface>> - attributes; - if (attribute != nullptr) { - attributes[attribute_key] = attribute->Copy(); - } - result.addresses.emplace_back(address.addr, address.len, - nullptr /* args */, std::move(attributes)); - } - if (service_config_json != nullptr) { - result.service_config = grpc_core::ServiceConfig::Create( - nullptr, service_config_json, &result.service_config_error); - GPR_ASSERT(result.service_config != nullptr); - } - return result; - } - - bool ipv6_only_ = false; - grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> - response_generator_; -}; - -class ClientLbEnd2endTest : public ::testing::Test { - protected: - ClientLbEnd2endTest() - : server_host_("localhost"), - kRequestMessage_("Live long and prosper."), - creds_(new SecureChannelCredentials( - grpc_fake_transport_security_credentials_create())) {} - - static void SetUpTestCase() { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - } - - void SetUp() override { - grpc_init(); - bool localhost_resolves_to_ipv4 = false; - bool localhost_resolves_to_ipv6 = false; - grpc_core::LocalhostResolves(&localhost_resolves_to_ipv4, - &localhost_resolves_to_ipv6); - ipv6_only_ = !localhost_resolves_to_ipv4 && localhost_resolves_to_ipv6; - } - - void TearDown() override { - for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(); - } - servers_.clear(); - creds_.reset(); - grpc_shutdown(); - } - - void CreateServers(size_t num_servers, - std::vector<int> ports = std::vector<int>()) { - servers_.clear(); - for (size_t i = 0; i < num_servers; ++i) { - int port = 0; - if (ports.size() == num_servers) port = ports[i]; - servers_.emplace_back(new ServerData(port)); - } - } - - void StartServer(size_t index) { servers_[index]->Start(server_host_); } - - void StartServers(size_t num_servers, - std::vector<int> ports = std::vector<int>()) { - CreateServers(num_servers, std::move(ports)); - for (size_t i = 0; i < num_servers; ++i) { - StartServer(i); - } - } - - std::vector<int> GetServersPorts(size_t start_index = 0) { - std::vector<int> ports; - for (size_t i = start_index; i < servers_.size(); ++i) { - ports.push_back(servers_[i]->port_); - } - return ports; - } - - FakeResolverResponseGeneratorWrapper BuildResolverResponseGenerator() { - return FakeResolverResponseGeneratorWrapper(ipv6_only_); - } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( - const std::shared_ptr<Channel>& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr<Channel> BuildChannel( - const TString& lb_policy_name, - const FakeResolverResponseGeneratorWrapper& response_generator, - ChannelArguments args = ChannelArguments()) { - if (!lb_policy_name.empty()) { - args.SetLoadBalancingPolicyName(lb_policy_name); - } // else, default to pick first - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator.Get()); - return ::grpc::CreateCustomChannel("fake:///", creds_, args); - } - - bool SendRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - EchoResponse* response = nullptr, int timeout_ms = 1000, - Status* result = nullptr, bool wait_for_ready = false) { - const bool local_response = (response == nullptr); - if (local_response) response = new EchoResponse; - EchoRequest request; - request.set_message(kRequestMessage_); - request.mutable_param()->set_echo_metadata(true); - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); - if (wait_for_ready) context.set_wait_for_ready(true); - context.AddMetadata("foo", "1"); - context.AddMetadata("bar", "2"); - context.AddMetadata("baz", "3"); - Status status = stub->Echo(&context, request, response); - if (result != nullptr) *result = status; - if (local_response) delete response; - return status.ok(); - } - - void CheckRpcSendOk( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - const grpc_core::DebugLocation& location, bool wait_for_ready = false) { - EchoResponse response; - Status status; - const bool success = - SendRpc(stub, &response, 2000, &status, wait_for_ready); - ASSERT_TRUE(success) << "From " << location.file() << ":" << location.line() - << "\n" - << "Error: " << status.error_message() << " " - << status.error_details(); - ASSERT_EQ(response.message(), kRequestMessage_) - << "From " << location.file() << ":" << location.line(); - if (!success) abort(); - } - - void CheckRpcSendFailure( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub) { - const bool success = SendRpc(stub); - EXPECT_FALSE(success); - } - - struct ServerData { - const int port_; - std::unique_ptr<Server> server_; - MyTestServiceImpl service_; - std::unique_ptr<std::thread> thread_; - - grpc::internal::Mutex mu_; - grpc::internal::CondVar cond_; - bool server_ready_ Y_ABSL_GUARDED_BY(mu_) = false; - bool started_ Y_ABSL_GUARDED_BY(mu_) = false; - - explicit ServerData(int port = 0) - : port_(port > 0 ? port : 5100) {} - - void Start(const TString& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - grpc::internal::MutexLock lock(&mu_); - started_ = true; - thread_ = y_absl::make_unique<std::thread>( - std::bind(&ServerData::Serve, this, server_host)); - while (!server_ready_) { - cond_.Wait(&mu_); - } - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - - void Serve(const TString& server_host) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials( - grpc_fake_transport_security_server_credentials_create())); - builder.AddListeningPort(server_address.str(), std::move(creds)); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - grpc::internal::MutexLock lock(&mu_); - server_ready_ = true; - cond_.Signal(); - } - - void Shutdown() { - grpc::internal::MutexLock lock(&mu_); - if (!started_) return; - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - thread_->join(); - started_ = false; - } - - void SetServingStatus(const TString& service, bool serving) { - server_->GetHealthCheckService()->SetServingStatus(service, serving); - } - }; - - void ResetCounters() { - for (const auto& server : servers_) server->service_.ResetCounters(); - } - - void WaitForServer( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - size_t server_idx, const grpc_core::DebugLocation& location, - bool ignore_failure = false) { - do { - if (ignore_failure) { - SendRpc(stub); - } else { - CheckRpcSendOk(stub, location, true); - } - } while (servers_[server_idx]->service_.request_count() == 0); - ResetCounters(); - } - - bool WaitForChannelState( - Channel* channel, - const std::function<bool(grpc_connectivity_state)>& predicate, - bool try_to_connect = false, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - while (true) { - grpc_connectivity_state state = channel->GetState(try_to_connect); - if (predicate(state)) break; - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - auto predicate = [](grpc_connectivity_state state) { - return state != GRPC_CHANNEL_READY; - }; - return WaitForChannelState(channel, predicate, false, timeout_seconds); - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { - auto predicate = [](grpc_connectivity_state state) { - return state == GRPC_CHANNEL_READY; - }; - return WaitForChannelState(channel, predicate, true, timeout_seconds); - } - - bool SeenAllServers() { - for (const auto& server : servers_) { - if (server->service_.request_count() == 0) return false; - } - return true; - } - - // Updates \a connection_order by appending to it the index of the newly - // connected server. Must be called after every single RPC. - void UpdateConnectionOrder( - const std::vector<std::unique_ptr<ServerData>>& servers, - std::vector<int>* connection_order) { - for (size_t i = 0; i < servers.size(); ++i) { - if (servers[i]->service_.request_count() == 1) { - // Was the server index known? If not, update connection_order. - const auto it = - std::find(connection_order->begin(), connection_order->end(), i); - if (it == connection_order->end()) { - connection_order->push_back(i); - return; - } - } - } - } - - const TString server_host_; - std::vector<std::unique_ptr<ServerData>> servers_; - const TString kRequestMessage_; - std::shared_ptr<ChannelCredentials> creds_; - bool ipv6_only_ = false; -}; - -TEST_F(ClientLbEnd2endTest, ChannelStateConnectingWhenResolving) { - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("", response_generator); - auto stub = BuildStub(channel); - // Initial state should be IDLE. - EXPECT_EQ(channel->GetState(false /* try_to_connect */), GRPC_CHANNEL_IDLE); - // Tell the channel to try to connect. - // Note that this call also returns IDLE, since the state change has - // not yet occurred; it just gets triggered by this call. - EXPECT_EQ(channel->GetState(true /* try_to_connect */), GRPC_CHANNEL_IDLE); - // Now that the channel is trying to connect, we should be in state - // CONNECTING. - EXPECT_EQ(channel->GetState(false /* try_to_connect */), - GRPC_CHANNEL_CONNECTING); - // Return a resolver result, which allows the connection attempt to proceed. - response_generator.SetNextResolution(GetServersPorts()); - // We should eventually transition into state READY. - EXPECT_TRUE(WaitForChannelReady(channel.get())); -} - -TEST_F(ClientLbEnd2endTest, PickFirst) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel( - "", response_generator); // test that pick first is the default. - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - for (size_t i = 0; i < servers_.size(); ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - // All requests should have gone to a single server. - bool found = false; - for (size_t i = 0; i < servers_.size(); ++i) { - const int request_count = servers_[i]->service_.request_count(); - if (request_count == kNumServers) { - found = true; - } else { - EXPECT_EQ(0, request_count); - } - } - EXPECT_TRUE(found); - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, PickFirstProcessPending) { - StartServers(1); // Single server - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel( - "", response_generator); // test that pick first is the default. - auto stub = BuildStub(channel); - response_generator.SetNextResolution({servers_[0]->port_}); - WaitForServer(stub, 0, DEBUG_LOCATION); - // Create a new channel and its corresponding PF LB policy, which will pick - // the subchannels in READY state from the previous RPC against the same - // target (even if it happened over a different channel, because subchannels - // are globally reused). Progress should happen without any transition from - // this READY state. - auto second_response_generator = BuildResolverResponseGenerator(); - auto second_channel = BuildChannel("", second_response_generator); - auto second_stub = BuildStub(second_channel); - second_response_generator.SetNextResolution({servers_[0]->port_}); - CheckRpcSendOk(second_stub, DEBUG_LOCATION); -} - -TEST_F(ClientLbEnd2endTest, PickFirstSelectsReadyAtStartup) { - ChannelArguments args; - constexpr int kInitialBackOffMs = 5000; - args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); - // Create 2 servers, but start only the second one. - std::vector<int> ports = { 5101, // grpc_pick_unused_port_or_die(), - 5102}; // grpc_pick_unused_port_or_die()}; - CreateServers(2, ports); - StartServer(1); - auto response_generator1 = BuildResolverResponseGenerator(); - auto channel1 = BuildChannel("pick_first", response_generator1, args); - auto stub1 = BuildStub(channel1); - response_generator1.SetNextResolution(ports); - // Wait for second server to be ready. - WaitForServer(stub1, 1, DEBUG_LOCATION); - // Create a second channel with the same addresses. Its PF instance - // should immediately pick the second subchannel, since it's already - // in READY state. - auto response_generator2 = BuildResolverResponseGenerator(); - auto channel2 = BuildChannel("pick_first", response_generator2, args); - response_generator2.SetNextResolution(ports); - // Check that the channel reports READY without waiting for the - // initial backoff. - EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1 /* timeout_seconds */)); -} - -TEST_F(ClientLbEnd2endTest, PickFirstBackOffInitialReconnect) { - ChannelArguments args; - constexpr int kInitialBackOffMs = 100; - args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); - const std::vector<int> ports = {5103}; // {grpc_pick_unused_port_or_die()}; - const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator, args); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(ports); - // The channel won't become connected (there's no server). - ASSERT_FALSE(channel->WaitForConnected( - grpc_timeout_milliseconds_to_deadline(kInitialBackOffMs * 2))); - // Bring up a server on the chosen port. - StartServers(1, ports); - // Now it will. - ASSERT_TRUE(channel->WaitForConnected( - grpc_timeout_milliseconds_to_deadline(kInitialBackOffMs * 2))); - const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); - const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited_ms); - // We should have waited at least kInitialBackOffMs. We substract one to - // account for test and precision accuracy drift. - EXPECT_GE(waited_ms, kInitialBackOffMs - 1); - // But not much more. - EXPECT_GT( - gpr_time_cmp( - grpc_timeout_milliseconds_to_deadline(kInitialBackOffMs * 1.10), t1), - 0); -} - -TEST_F(ClientLbEnd2endTest, PickFirstBackOffMinReconnect) { - ChannelArguments args; - constexpr int kMinReconnectBackOffMs = 1000; - args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, kMinReconnectBackOffMs); - const std::vector<int> ports = {5104}; // {grpc_pick_unused_port_or_die()}; - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator, args); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(ports); - // Make connection delay a 10% longer than it's willing to in order to make - // sure we are hitting the codepath that waits for the min reconnect backoff. - gpr_atm_rel_store(&g_connection_delay_ms, kMinReconnectBackOffMs * 1.10); - default_client_impl = grpc_tcp_client_impl; - grpc_set_tcp_client_impl(&delayed_connect); - const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); - channel->WaitForConnected( - grpc_timeout_milliseconds_to_deadline(kMinReconnectBackOffMs * 2)); - const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); - const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " ms", waited_ms); - // We should have waited at least kMinReconnectBackOffMs. We substract one to - // account for test and precision accuracy drift. - EXPECT_GE(waited_ms, kMinReconnectBackOffMs - 1); - gpr_atm_rel_store(&g_connection_delay_ms, 0); -} - -TEST_F(ClientLbEnd2endTest, PickFirstResetConnectionBackoff) { - ChannelArguments args; - constexpr int kInitialBackOffMs = 1000; - args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); - const std::vector<int> ports = {5105}; // {grpc_pick_unused_port_or_die()}; - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator, args); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(ports); - // The channel won't become connected (there's no server). - EXPECT_FALSE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); - // Bring up a server on the chosen port. - StartServers(1, ports); - const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); - // Wait for connect, but not long enough. This proves that we're - // being throttled by initial backoff. - EXPECT_FALSE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); - // Reset connection backoff. - experimental::ChannelResetConnectionBackoff(channel.get()); - // Wait for connect. Should happen as soon as the client connects to - // the newly started server, which should be before the initial - // backoff timeout elapses. - EXPECT_TRUE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(20))); - const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); - const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited_ms); - // We should have waited less than kInitialBackOffMs. - EXPECT_LT(waited_ms, kInitialBackOffMs); -} - -TEST_F(ClientLbEnd2endTest, - PickFirstResetConnectionBackoffNextAttemptStartsImmediately) { - ChannelArguments args; - constexpr int kInitialBackOffMs = 1000; - args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); - const std::vector<int> ports = {5106}; // {grpc_pick_unused_port_or_die()}; - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator, args); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(ports); - // Wait for connect, which should fail ~immediately, because the server - // is not up. - gpr_log(GPR_INFO, "=== INITIAL CONNECTION ATTEMPT"); - EXPECT_FALSE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); - // Reset connection backoff. - // Note that the time at which the third attempt will be started is - // actually computed at this point, so we record the start time here. - gpr_log(GPR_INFO, "=== RESETTING BACKOFF"); - const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); - experimental::ChannelResetConnectionBackoff(channel.get()); - // Trigger a second connection attempt. This should also fail - // ~immediately, but the retry should be scheduled for - // kInitialBackOffMs instead of applying the multiplier. - gpr_log(GPR_INFO, "=== POLLING FOR SECOND CONNECTION ATTEMPT"); - EXPECT_FALSE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); - // Bring up a server on the chosen port. - gpr_log(GPR_INFO, "=== STARTING BACKEND"); - StartServers(1, ports); - // Wait for connect. Should happen within kInitialBackOffMs. - // Give an extra 100ms to account for the time spent in the second and - // third connection attempts themselves (since what we really want to - // measure is the time between the two). As long as this is less than - // the 1.6x increase we would see if the backoff state was not reset - // properly, the test is still proving that the backoff was reset. - constexpr int kWaitMs = kInitialBackOffMs + 100; - gpr_log(GPR_INFO, "=== POLLING FOR THIRD CONNECTION ATTEMPT"); - EXPECT_TRUE(channel->WaitForConnected( - grpc_timeout_milliseconds_to_deadline(kWaitMs))); - const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); - const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited_ms); - EXPECT_LT(waited_ms, kWaitMs); -} - -TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator); - auto stub = BuildStub(channel); - - std::vector<int> ports; - - // Perform one RPC against the first server. - ports.emplace_back(servers_[0]->port_); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [0] *******"); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(servers_[0]->service_.request_count(), 1); - - // An empty update will result in the channel going into TRANSIENT_FAILURE. - ports.clear(); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET none *******"); - grpc_connectivity_state channel_state; - do { - channel_state = channel->GetState(true /* try to connect */); - } while (channel_state == GRPC_CHANNEL_READY); - ASSERT_NE(channel_state, GRPC_CHANNEL_READY); - servers_[0]->service_.ResetCounters(); - - // Next update introduces servers_[1], making the channel recover. - ports.clear(); - ports.emplace_back(servers_[1]->port_); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [1] *******"); - WaitForServer(stub, 1, DEBUG_LOCATION); - EXPECT_EQ(servers_[0]->service_.request_count(), 0); - - // And again for servers_[2] - ports.clear(); - ports.emplace_back(servers_[2]->port_); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [2] *******"); - WaitForServer(stub, 2, DEBUG_LOCATION); - EXPECT_EQ(servers_[0]->service_.request_count(), 0); - EXPECT_EQ(servers_[1]->service_.request_count(), 0); - - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator); - auto stub = BuildStub(channel); - - std::vector<int> ports; - - // Perform one RPC against the first server. - ports.emplace_back(servers_[0]->port_); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [0] *******"); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(servers_[0]->service_.request_count(), 1); - servers_[0]->service_.ResetCounters(); - - // Send and superset update - ports.clear(); - ports.emplace_back(servers_[1]->port_); - ports.emplace_back(servers_[0]->port_); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET superset *******"); - CheckRpcSendOk(stub, DEBUG_LOCATION); - // We stick to the previously connected server. - WaitForServer(stub, 0, DEBUG_LOCATION); - EXPECT_EQ(0, servers_[1]->service_.request_count()); - - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, PickFirstGlobalSubchannelPool) { - // Start one server. - const int kNumServers = 1; - StartServers(kNumServers); - std::vector<int> ports = GetServersPorts(); - // Create two channels that (by default) use the global subchannel pool. - auto response_generator1 = BuildResolverResponseGenerator(); - auto channel1 = BuildChannel("pick_first", response_generator1); - auto stub1 = BuildStub(channel1); - response_generator1.SetNextResolution(ports); - auto response_generator2 = BuildResolverResponseGenerator(); - auto channel2 = BuildChannel("pick_first", response_generator2); - auto stub2 = BuildStub(channel2); - response_generator2.SetNextResolution(ports); - WaitForServer(stub1, 0, DEBUG_LOCATION); - // Send one RPC on each channel. - CheckRpcSendOk(stub1, DEBUG_LOCATION); - CheckRpcSendOk(stub2, DEBUG_LOCATION); - // The server receives two requests. - EXPECT_EQ(2, servers_[0]->service_.request_count()); - // The two requests are from the same client port, because the two channels - // share subchannels via the global subchannel pool. - EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); -} - -TEST_F(ClientLbEnd2endTest, PickFirstLocalSubchannelPool) { - // Start one server. - const int kNumServers = 1; - StartServers(kNumServers); - std::vector<int> ports = GetServersPorts(); - // Create two channels that use local subchannel pool. - ChannelArguments args; - args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); - auto response_generator1 = BuildResolverResponseGenerator(); - auto channel1 = BuildChannel("pick_first", response_generator1, args); - auto stub1 = BuildStub(channel1); - response_generator1.SetNextResolution(ports); - auto response_generator2 = BuildResolverResponseGenerator(); - auto channel2 = BuildChannel("pick_first", response_generator2, args); - auto stub2 = BuildStub(channel2); - response_generator2.SetNextResolution(ports); - WaitForServer(stub1, 0, DEBUG_LOCATION); - // Send one RPC on each channel. - CheckRpcSendOk(stub1, DEBUG_LOCATION); - CheckRpcSendOk(stub2, DEBUG_LOCATION); - // The server receives two requests. - EXPECT_EQ(2, servers_[0]->service_.request_count()); - // The two requests are from two client ports, because the two channels didn't - // share subchannels with each other. - EXPECT_EQ(2UL, servers_[0]->service_.clients().size()); -} - -TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { - const int kNumUpdates = 1000; - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator); - auto stub = BuildStub(channel); - std::vector<int> ports = GetServersPorts(); - for (size_t i = 0; i < kNumUpdates; ++i) { - std::shuffle(ports.begin(), ports.end(), - std::mt19937(std::random_device()())); - response_generator.SetNextResolution(ports); - // We should re-enter core at the end of the loop to give the resolution - // setting closure a chance to run. - if ((i + 1) % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION); - } - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { - // Prepare the ports for up servers and down servers. - const int kNumServers = 3; - const int kNumAliveServers = 1; - StartServers(kNumAliveServers); - std::vector<int> alive_ports, dead_ports; - for (size_t i = 0; i < kNumServers; ++i) { - if (i < kNumAliveServers) { - alive_ports.emplace_back(servers_[i]->port_); - } else { - dead_ports.emplace_back(5107 + i); - // dead_ports.emplace_back(grpc_pick_unused_port_or_die()); - } - } - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator); - auto stub = BuildStub(channel); - // The initial resolution only contains dead ports. There won't be any - // selected subchannel. Re-resolution will return the same result. - response_generator.SetNextResolution(dead_ports); - gpr_log(GPR_INFO, "****** INITIAL RESOLUTION SET *******"); - for (size_t i = 0; i < 10; ++i) CheckRpcSendFailure(stub); - // Set a re-resolution result that contains reachable ports, so that the - // pick_first LB policy can recover soon. - response_generator.SetNextResolutionUponError(alive_ports); - gpr_log(GPR_INFO, "****** RE-RESOLUTION SET *******"); - WaitForServer(stub, 0, DEBUG_LOCATION, true /* ignore_failure */); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(servers_[0]->service_.request_count(), 1); - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, PickFirstReconnectWithoutNewResolverResult) { - std::vector<int> ports = {5110}; // {grpc_pick_unused_port_or_die()}; - StartServers(1, ports); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); - WaitForServer(stub, 0, DEBUG_LOCATION); - gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); - servers_[0]->Shutdown(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - gpr_log(GPR_INFO, "****** RESTARTING SERVER ******"); - StartServers(1, ports); - WaitForServer(stub, 0, DEBUG_LOCATION); -} - -TEST_F(ClientLbEnd2endTest, - PickFirstReconnectWithoutNewResolverResultStartsFromTopOfList) { - std::vector<int> ports = {5111, // grpc_pick_unused_port_or_die(), - 5112}; // grpc_pick_unused_port_or_die()}; - CreateServers(2, ports); - StartServer(1); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("pick_first", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); - WaitForServer(stub, 1, DEBUG_LOCATION); - gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); - servers_[1]->Shutdown(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - gpr_log(GPR_INFO, "****** STARTING BOTH SERVERS ******"); - StartServers(2, ports); - WaitForServer(stub, 0, DEBUG_LOCATION); -} - -TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { - std::vector<int> ports = {5113}; // {grpc_pick_unused_port_or_die()}; - StartServers(1, ports); - auto response_generator = BuildResolverResponseGenerator(); - auto channel_1 = BuildChannel("pick_first", response_generator); - auto stub_1 = BuildStub(channel_1); - response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 1 *******"); - WaitForServer(stub_1, 0, DEBUG_LOCATION); - gpr_log(GPR_INFO, "****** CHANNEL 1 CONNECTED *******"); - servers_[0]->Shutdown(); - // Channel 1 will receive a re-resolution containing the same server. It will - // create a new subchannel and hold a ref to it. - StartServers(1, ports); - gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); - auto response_generator_2 = BuildResolverResponseGenerator(); - auto channel_2 = BuildChannel("pick_first", response_generator_2); - auto stub_2 = BuildStub(channel_2); - response_generator_2.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******"); - WaitForServer(stub_2, 0, DEBUG_LOCATION, true); - gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******"); - servers_[0]->Shutdown(); - // Wait until the disconnection has triggered the connectivity notification. - // Otherwise, the subchannel may be picked for next call but will fail soon. - EXPECT_TRUE(WaitForChannelNotReady(channel_2.get())); - // Channel 2 will also receive a re-resolution containing the same server. - // Both channels will ref the same subchannel that failed. - StartServers(1, ports); - gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******"); - gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******"); - // The first call after the server restart will succeed. - CheckRpcSendOk(stub_2, DEBUG_LOCATION); - gpr_log(GPR_INFO, "****** CHANNEL 2 FINISHED A CALL *******"); - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel_1->GetLoadBalancingPolicyName()); - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel_2->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, PickFirstIdleOnDisconnect) { - // Start server, send RPC, and make sure channel is READY. - const int kNumServers = 1; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = - BuildChannel("", response_generator); // pick_first is the default. - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - // Stop server. Channel should go into state IDLE. - response_generator.SetFailureOnReresolution(); - servers_[0]->Shutdown(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); - servers_.clear(); -} - -TEST_F(ClientLbEnd2endTest, PickFirstPendingUpdateAndSelectedSubchannelFails) { - auto response_generator = BuildResolverResponseGenerator(); - auto channel = - BuildChannel("", response_generator); // pick_first is the default. - auto stub = BuildStub(channel); - // Create a number of servers, but only start 1 of them. - CreateServers(10); - StartServer(0); - // Initially resolve to first server and make sure it connects. - gpr_log(GPR_INFO, "Phase 1: Connect to first server."); - response_generator.SetNextResolution({servers_[0]->port_}); - CheckRpcSendOk(stub, DEBUG_LOCATION, true /* wait_for_ready */); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - // Send a resolution update with the remaining servers, none of which are - // running yet, so the update will stay pending. Note that it's important - // to have multiple servers here, or else the test will be flaky; with only - // one server, the pending subchannel list has already gone into - // TRANSIENT_FAILURE due to hitting the end of the list by the time we - // check the state. - gpr_log(GPR_INFO, - "Phase 2: Resolver update pointing to remaining " - "(not started) servers."); - response_generator.SetNextResolution(GetServersPorts(1 /* start_index */)); - // RPCs will continue to be sent to the first server. - CheckRpcSendOk(stub, DEBUG_LOCATION); - // Now stop the first server, so that the current subchannel list - // fails. This should cause us to immediately swap over to the - // pending list, even though it's not yet connected. The state should - // be set to CONNECTING, since that's what the pending subchannel list - // was doing when we swapped over. - gpr_log(GPR_INFO, "Phase 3: Stopping first server."); - servers_[0]->Shutdown(); - WaitForChannelNotReady(channel.get()); - // TODO(roth): This should always return CONNECTING, but it's flaky - // between that and TRANSIENT_FAILURE. I suspect that this problem - // will go away once we move the backoff code out of the subchannel - // and into the LB policies. - EXPECT_THAT(channel->GetState(false), - ::testing::AnyOf(GRPC_CHANNEL_CONNECTING, - GRPC_CHANNEL_TRANSIENT_FAILURE)); - // Now start the second server. - gpr_log(GPR_INFO, "Phase 4: Starting second server."); - StartServer(1); - // The channel should go to READY state and RPCs should go to the - // second server. - WaitForChannelReady(channel.get()); - WaitForServer(stub, 1, DEBUG_LOCATION, true /* ignore_failure */); -} - -TEST_F(ClientLbEnd2endTest, PickFirstStaysIdleUponEmptyUpdate) { - // Start server, send RPC, and make sure channel is READY. - const int kNumServers = 1; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = - BuildChannel("", response_generator); // pick_first is the default. - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - // Stop server. Channel should go into state IDLE. - servers_[0]->Shutdown(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); - // Now send resolver update that includes no addresses. Channel - // should stay in state IDLE. - response_generator.SetNextResolution({}); - EXPECT_FALSE(channel->WaitForStateChange( - GRPC_CHANNEL_IDLE, grpc_timeout_seconds_to_deadline(3))); - // Now bring the backend back up and send a non-empty resolver update, - // and then try to send an RPC. Channel should go back into state READY. - StartServer(0); - response_generator.SetNextResolution(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); -} - -TEST_F(ClientLbEnd2endTest, RoundRobin) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - // Wait until all backends are ready. - do { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } while (!SeenAllServers()); - ResetCounters(); - // "Sync" to the end of the list. Next sequence of picks will start at the - // first server (index 0). - WaitForServer(stub, servers_.size() - 1, DEBUG_LOCATION); - std::vector<int> connection_order; - for (size_t i = 0; i < servers_.size(); ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - UpdateConnectionOrder(servers_, &connection_order); - } - // Backends should be iterated over in the order in which the addresses were - // given. - const auto expected = std::vector<int>{0, 1, 2}; - EXPECT_EQ(expected, connection_order); - // Check LB policy name for the channel. - EXPECT_EQ("round_robin", channel->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinProcessPending) { - StartServers(1); // Single server - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution({servers_[0]->port_}); - WaitForServer(stub, 0, DEBUG_LOCATION); - // Create a new channel and its corresponding RR LB policy, which will pick - // the subchannels in READY state from the previous RPC against the same - // target (even if it happened over a different channel, because subchannels - // are globally reused). Progress should happen without any transition from - // this READY state. - auto second_response_generator = BuildResolverResponseGenerator(); - auto second_channel = BuildChannel("round_robin", second_response_generator); - auto second_stub = BuildStub(second_channel); - second_response_generator.SetNextResolution({servers_[0]->port_}); - CheckRpcSendOk(second_stub, DEBUG_LOCATION); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - std::vector<int> ports; - // Start with a single server. - gpr_log(GPR_INFO, "*** FIRST BACKEND ***"); - ports.emplace_back(servers_[0]->port_); - response_generator.SetNextResolution(ports); - WaitForServer(stub, 0, DEBUG_LOCATION); - // Send RPCs. They should all go servers_[0] - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(10, servers_[0]->service_.request_count()); - EXPECT_EQ(0, servers_[1]->service_.request_count()); - EXPECT_EQ(0, servers_[2]->service_.request_count()); - servers_[0]->service_.ResetCounters(); - // And now for the second server. - gpr_log(GPR_INFO, "*** SECOND BACKEND ***"); - ports.clear(); - ports.emplace_back(servers_[1]->port_); - response_generator.SetNextResolution(ports); - // Wait until update has been processed, as signaled by the second backend - // receiving a request. - EXPECT_EQ(0, servers_[1]->service_.request_count()); - WaitForServer(stub, 1, DEBUG_LOCATION); - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(0, servers_[0]->service_.request_count()); - EXPECT_EQ(10, servers_[1]->service_.request_count()); - EXPECT_EQ(0, servers_[2]->service_.request_count()); - servers_[1]->service_.ResetCounters(); - // ... and for the last server. - gpr_log(GPR_INFO, "*** THIRD BACKEND ***"); - ports.clear(); - ports.emplace_back(servers_[2]->port_); - response_generator.SetNextResolution(ports); - WaitForServer(stub, 2, DEBUG_LOCATION); - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(0, servers_[0]->service_.request_count()); - EXPECT_EQ(0, servers_[1]->service_.request_count()); - EXPECT_EQ(10, servers_[2]->service_.request_count()); - servers_[2]->service_.ResetCounters(); - // Back to all servers. - gpr_log(GPR_INFO, "*** ALL BACKENDS ***"); - ports.clear(); - ports.emplace_back(servers_[0]->port_); - ports.emplace_back(servers_[1]->port_); - ports.emplace_back(servers_[2]->port_); - response_generator.SetNextResolution(ports); - WaitForServer(stub, 0, DEBUG_LOCATION); - WaitForServer(stub, 1, DEBUG_LOCATION); - WaitForServer(stub, 2, DEBUG_LOCATION); - // Send three RPCs, one per server. - for (size_t i = 0; i < 3; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(1, servers_[0]->service_.request_count()); - EXPECT_EQ(1, servers_[1]->service_.request_count()); - EXPECT_EQ(1, servers_[2]->service_.request_count()); - // An empty update will result in the channel going into TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "*** NO BACKENDS ***"); - ports.clear(); - response_generator.SetNextResolution(ports); - grpc_connectivity_state channel_state; - do { - channel_state = channel->GetState(true /* try to connect */); - } while (channel_state == GRPC_CHANNEL_READY); - ASSERT_NE(channel_state, GRPC_CHANNEL_READY); - servers_[0]->service_.ResetCounters(); - // Next update introduces servers_[1], making the channel recover. - gpr_log(GPR_INFO, "*** BACK TO SECOND BACKEND ***"); - ports.clear(); - ports.emplace_back(servers_[1]->port_); - response_generator.SetNextResolution(ports); - WaitForServer(stub, 1, DEBUG_LOCATION); - channel_state = channel->GetState(false /* try to connect */); - ASSERT_EQ(channel_state, GRPC_CHANNEL_READY); - // Check LB policy name for the channel. - EXPECT_EQ("round_robin", channel->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) { - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - std::vector<int> ports; - // Start with a single server. - ports.emplace_back(servers_[0]->port_); - response_generator.SetNextResolution(ports); - WaitForServer(stub, 0, DEBUG_LOCATION); - // Send RPCs. They should all go to servers_[0] - for (size_t i = 0; i < 10; ++i) SendRpc(stub); - EXPECT_EQ(10, servers_[0]->service_.request_count()); - EXPECT_EQ(0, servers_[1]->service_.request_count()); - EXPECT_EQ(0, servers_[2]->service_.request_count()); - servers_[0]->service_.ResetCounters(); - // Shutdown one of the servers to be sent in the update. - servers_[1]->Shutdown(); - ports.emplace_back(servers_[1]->port_); - ports.emplace_back(servers_[2]->port_); - response_generator.SetNextResolution(ports); - WaitForServer(stub, 0, DEBUG_LOCATION); - WaitForServer(stub, 2, DEBUG_LOCATION); - // Send three RPCs, one per server. - for (size_t i = 0; i < kNumServers; ++i) SendRpc(stub); - // The server in shutdown shouldn't receive any. - EXPECT_EQ(0, servers_[1]->service_.request_count()); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinManyUpdates) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - std::vector<int> ports = GetServersPorts(); - for (size_t i = 0; i < 1000; ++i) { - std::shuffle(ports.begin(), ports.end(), - std::mt19937(std::random_device()())); - response_generator.SetNextResolution(ports); - if (i % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION); - } - // Check LB policy name for the channel. - EXPECT_EQ("round_robin", channel->GetLoadBalancingPolicyName()); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinConcurrentUpdates) { - // TODO(dgq): replicate the way internal testing exercises the concurrent - // update provisions of RR. -} - -TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - std::vector<int> first_ports; - std::vector<int> second_ports; - first_ports.reserve(kNumServers); - for (int i = 0; i < kNumServers; ++i) { - // first_ports.push_back(grpc_pick_unused_port_or_die()); - first_ports.push_back(5114 + i); - } - second_ports.reserve(kNumServers); - for (int i = 0; i < kNumServers; ++i) { - // second_ports.push_back(grpc_pick_unused_port_or_die()); - second_ports.push_back(5117 + i); - } - StartServers(kNumServers, first_ports); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(first_ports); - // Send a number of RPCs, which succeed. - for (size_t i = 0; i < 100; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - // Kill all servers - gpr_log(GPR_INFO, "****** ABOUT TO KILL SERVERS *******"); - for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(); - } - gpr_log(GPR_INFO, "****** SERVERS KILLED *******"); - gpr_log(GPR_INFO, "****** SENDING DOOMED REQUESTS *******"); - // Client requests should fail. Send enough to tickle all subchannels. - for (size_t i = 0; i < servers_.size(); ++i) CheckRpcSendFailure(stub); - gpr_log(GPR_INFO, "****** DOOMED REQUESTS SENT *******"); - // Bring servers back up on a different set of ports. We need to do this to be - // sure that the eventual success is *not* due to subchannel reconnection - // attempts and that an actual re-resolution has happened as a result of the - // RR policy going into transient failure when all its subchannels become - // unavailable (in transient failure as well). - gpr_log(GPR_INFO, "****** RESTARTING SERVERS *******"); - StartServers(kNumServers, second_ports); - // Don't notify of the update. Wait for the LB policy's re-resolution to - // "pull" the new ports. - response_generator.SetNextResolutionUponError(second_ports); - gpr_log(GPR_INFO, "****** SERVERS RESTARTED *******"); - gpr_log(GPR_INFO, "****** SENDING REQUEST TO SUCCEED *******"); - // Client request should eventually (but still fairly soon) succeed. - const gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5); - gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); - while (gpr_time_cmp(deadline, now) > 0) { - if (SendRpc(stub)) break; - now = gpr_now(GPR_CLOCK_MONOTONIC); - } - ASSERT_GT(gpr_time_cmp(deadline, now), 0); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinTransientFailure) { - // Start servers and create channel. Channel should go to READY state. - const int kNumServers = 3; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - // Now kill the servers. The channel should transition to TRANSIENT_FAILURE. - // TODO(roth): This test should ideally check that even when the - // subchannels are in state CONNECTING for an extended period of time, - // we will still report TRANSIENT_FAILURE. Unfortunately, we don't - // currently have a good way to get a subchannel to report CONNECTING - // for a long period of time, since the servers in this test framework - // are on the loopback interface, which will immediately return a - // "Connection refused" error, so the subchannels will only be in - // CONNECTING state very briefly. When we have time, see if we can - // find a way to fix this. - for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(); - } - auto predicate = [](grpc_connectivity_state state) { - return state == GRPC_CHANNEL_TRANSIENT_FAILURE; - }; - EXPECT_TRUE(WaitForChannelState(channel.get(), predicate)); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinTransientFailureAtStartup) { - // Create channel and return servers that don't exist. Channel should - // quickly transition into TRANSIENT_FAILURE. - // TODO(roth): This test should ideally check that even when the - // subchannels are in state CONNECTING for an extended period of time, - // we will still report TRANSIENT_FAILURE. Unfortunately, we don't - // currently have a good way to get a subchannel to report CONNECTING - // for a long period of time, since the servers in this test framework - // are on the loopback interface, which will immediately return a - // "Connection refused" error, so the subchannels will only be in - // CONNECTING state very briefly. When we have time, see if we can - // find a way to fix this. - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution({ - grpc_pick_unused_port_or_die(), - grpc_pick_unused_port_or_die(), - grpc_pick_unused_port_or_die(), - }); - for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(); - } - auto predicate = [](grpc_connectivity_state state) { - return state == GRPC_CHANNEL_TRANSIENT_FAILURE; - }; - EXPECT_TRUE(WaitForChannelState(channel.get(), predicate, true)); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { - const int kNumServers = 3; - StartServers(kNumServers); - const auto ports = GetServersPorts(); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(ports); - for (size_t i = 0; i < kNumServers; ++i) { - WaitForServer(stub, i, DEBUG_LOCATION); - } - for (size_t i = 0; i < servers_.size(); ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(1, servers_[i]->service_.request_count()) << "for backend #" << i; - } - // One request should have gone to each server. - for (size_t i = 0; i < servers_.size(); ++i) { - EXPECT_EQ(1, servers_[i]->service_.request_count()); - } - const auto pre_death = servers_[0]->service_.request_count(); - // Kill the first server. - servers_[0]->Shutdown(); - // Client request still succeed. May need retrying if RR had returned a pick - // before noticing the change in the server's connectivity. - while (!SendRpc(stub)) { - } // Retry until success. - // Send a bunch of RPCs that should succeed. - for (int i = 0; i < 10 * kNumServers; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - const auto post_death = servers_[0]->service_.request_count(); - // No requests have gone to the deceased server. - EXPECT_EQ(pre_death, post_death); - // Bring the first server back up. - StartServer(0); - // Requests should start arriving at the first server either right away (if - // the server managed to start before the RR policy retried the subchannel) or - // after the subchannel retry delay otherwise (RR's subchannel retried before - // the server was fully back up). - WaitForServer(stub, 0, DEBUG_LOCATION); -} - -// If health checking is required by client but health checking service -// is not running on the server, the channel should be treated as healthy. -TEST_F(ClientLbEnd2endTest, - RoundRobinServersHealthCheckingUnimplementedTreatedAsHealthy) { - StartServers(1); // Single server - ChannelArguments args; - args.SetServiceConfigJSON( - "{\"healthCheckConfig\": " - "{\"serviceName\": \"health_check_service_name\"}}"); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator, args); - auto stub = BuildStub(channel); - response_generator.SetNextResolution({servers_[0]->port_}); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - CheckRpcSendOk(stub, DEBUG_LOCATION); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) { - EnableDefaultHealthCheckService(true); - // Start servers. - const int kNumServers = 3; - StartServers(kNumServers); - ChannelArguments args; - args.SetServiceConfigJSON( - "{\"healthCheckConfig\": " - "{\"serviceName\": \"health_check_service_name\"}}"); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator, args); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - // Channel should not become READY, because health checks should be failing. - gpr_log(GPR_INFO, - "*** initial state: unknown health check service name for " - "all servers"); - EXPECT_FALSE(WaitForChannelReady(channel.get(), 1)); - // Now set one of the servers to be healthy. - // The channel should become healthy and all requests should go to - // the healthy server. - gpr_log(GPR_INFO, "*** server 0 healthy"); - servers_[0]->SetServingStatus("health_check_service_name", true); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - for (int i = 0; i < 10; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - EXPECT_EQ(10, servers_[0]->service_.request_count()); - EXPECT_EQ(0, servers_[1]->service_.request_count()); - EXPECT_EQ(0, servers_[2]->service_.request_count()); - // Now set a second server to be healthy. - gpr_log(GPR_INFO, "*** server 2 healthy"); - servers_[2]->SetServingStatus("health_check_service_name", true); - WaitForServer(stub, 2, DEBUG_LOCATION); - for (int i = 0; i < 10; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - EXPECT_EQ(5, servers_[0]->service_.request_count()); - EXPECT_EQ(0, servers_[1]->service_.request_count()); - EXPECT_EQ(5, servers_[2]->service_.request_count()); - // Now set the remaining server to be healthy. - gpr_log(GPR_INFO, "*** server 1 healthy"); - servers_[1]->SetServingStatus("health_check_service_name", true); - WaitForServer(stub, 1, DEBUG_LOCATION); - for (int i = 0; i < 9; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - EXPECT_EQ(3, servers_[0]->service_.request_count()); - EXPECT_EQ(3, servers_[1]->service_.request_count()); - EXPECT_EQ(3, servers_[2]->service_.request_count()); - // Now set one server to be unhealthy again. Then wait until the - // unhealthiness has hit the client. We know that the client will see - // this when we send kNumServers requests and one of the remaining servers - // sees two of the requests. - gpr_log(GPR_INFO, "*** server 0 unhealthy"); - servers_[0]->SetServingStatus("health_check_service_name", false); - do { - ResetCounters(); - for (int i = 0; i < kNumServers; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - } while (servers_[1]->service_.request_count() != 2 && - servers_[2]->service_.request_count() != 2); - // Now set the remaining two servers to be unhealthy. Make sure the - // channel leaves READY state and that RPCs fail. - gpr_log(GPR_INFO, "*** all servers unhealthy"); - servers_[1]->SetServingStatus("health_check_service_name", false); - servers_[2]->SetServingStatus("health_check_service_name", false); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - CheckRpcSendFailure(stub); - // Clean up. - EnableDefaultHealthCheckService(false); -} - -TEST_F(ClientLbEnd2endTest, - RoundRobinWithHealthCheckingHandlesSubchannelFailure) { - EnableDefaultHealthCheckService(true); - // Start servers. - const int kNumServers = 3; - StartServers(kNumServers); - servers_[0]->SetServingStatus("health_check_service_name", true); - servers_[1]->SetServingStatus("health_check_service_name", true); - servers_[2]->SetServingStatus("health_check_service_name", true); - ChannelArguments args; - args.SetServiceConfigJSON( - "{\"healthCheckConfig\": " - "{\"serviceName\": \"health_check_service_name\"}}"); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator, args); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - WaitForServer(stub, 0, DEBUG_LOCATION); - // Stop server 0 and send a new resolver result to ensure that RR - // checks each subchannel's state. - servers_[0]->Shutdown(); - response_generator.SetNextResolution(GetServersPorts()); - // Send a bunch more RPCs. - for (size_t i = 0; i < 100; i++) { - SendRpc(stub); - } -} - -TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { - EnableDefaultHealthCheckService(true); - // Start server. - const int kNumServers = 1; - StartServers(kNumServers); - // Create a channel with health-checking enabled. - ChannelArguments args; - args.SetServiceConfigJSON( - "{\"healthCheckConfig\": " - "{\"serviceName\": \"health_check_service_name\"}}"); - auto response_generator1 = BuildResolverResponseGenerator(); - auto channel1 = BuildChannel("round_robin", response_generator1, args); - auto stub1 = BuildStub(channel1); - std::vector<int> ports = GetServersPorts(); - response_generator1.SetNextResolution(ports); - // Create a channel with health checking enabled but inhibited. - args.SetInt(GRPC_ARG_INHIBIT_HEALTH_CHECKING, 1); - auto response_generator2 = BuildResolverResponseGenerator(); - auto channel2 = BuildChannel("round_robin", response_generator2, args); - auto stub2 = BuildStub(channel2); - response_generator2.SetNextResolution(ports); - // First channel should not become READY, because health checks should be - // failing. - EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); - CheckRpcSendFailure(stub1); - // Second channel should be READY. - EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); - CheckRpcSendOk(stub2, DEBUG_LOCATION); - // Enable health checks on the backend and wait for channel 1 to succeed. - servers_[0]->SetServingStatus("health_check_service_name", true); - CheckRpcSendOk(stub1, DEBUG_LOCATION, true /* wait_for_ready */); - // Check that we created only one subchannel to the backend. - EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); - // Clean up. - EnableDefaultHealthCheckService(false); -} - -TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingServiceNamePerChannel) { - EnableDefaultHealthCheckService(true); - // Start server. - const int kNumServers = 1; - StartServers(kNumServers); - // Create a channel with health-checking enabled. - ChannelArguments args; - args.SetServiceConfigJSON( - "{\"healthCheckConfig\": " - "{\"serviceName\": \"health_check_service_name\"}}"); - auto response_generator1 = BuildResolverResponseGenerator(); - auto channel1 = BuildChannel("round_robin", response_generator1, args); - auto stub1 = BuildStub(channel1); - std::vector<int> ports = GetServersPorts(); - response_generator1.SetNextResolution(ports); - // Create a channel with health-checking enabled with a different - // service name. - ChannelArguments args2; - args2.SetServiceConfigJSON( - "{\"healthCheckConfig\": " - "{\"serviceName\": \"health_check_service_name2\"}}"); - auto response_generator2 = BuildResolverResponseGenerator(); - auto channel2 = BuildChannel("round_robin", response_generator2, args2); - auto stub2 = BuildStub(channel2); - response_generator2.SetNextResolution(ports); - // Allow health checks from channel 2 to succeed. - servers_[0]->SetServingStatus("health_check_service_name2", true); - // First channel should not become READY, because health checks should be - // failing. - EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); - CheckRpcSendFailure(stub1); - // Second channel should be READY. - EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); - CheckRpcSendOk(stub2, DEBUG_LOCATION); - // Enable health checks for channel 1 and wait for it to succeed. - servers_[0]->SetServingStatus("health_check_service_name", true); - CheckRpcSendOk(stub1, DEBUG_LOCATION, true /* wait_for_ready */); - // Check that we created only one subchannel to the backend. - EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); - // Clean up. - EnableDefaultHealthCheckService(false); -} - -TEST_F(ClientLbEnd2endTest, - RoundRobinWithHealthCheckingServiceNameChangesAfterSubchannelsCreated) { - EnableDefaultHealthCheckService(true); - // Start server. - const int kNumServers = 1; - StartServers(kNumServers); - // Create a channel with health-checking enabled. - const char* kServiceConfigJson = - "{\"healthCheckConfig\": " - "{\"serviceName\": \"health_check_service_name\"}}"; - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("round_robin", response_generator); - auto stub = BuildStub(channel); - std::vector<int> ports = GetServersPorts(); - response_generator.SetNextResolution(ports, kServiceConfigJson); - servers_[0]->SetServingStatus("health_check_service_name", true); - EXPECT_TRUE(WaitForChannelReady(channel.get(), 1 /* timeout_seconds */)); - // Send an update on the channel to change it to use a health checking - // service name that is not being reported as healthy. - const char* kServiceConfigJson2 = - "{\"healthCheckConfig\": " - "{\"serviceName\": \"health_check_service_name2\"}}"; - response_generator.SetNextResolution(ports, kServiceConfigJson2); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - // Clean up. - EnableDefaultHealthCheckService(false); -} - -TEST_F(ClientLbEnd2endTest, ChannelIdleness) { - // Start server. - const int kNumServers = 1; - StartServers(kNumServers); - // Set max idle time and build the channel. - ChannelArguments args; - args.SetInt(GRPC_ARG_CLIENT_IDLE_TIMEOUT_MS, 1000); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("", response_generator, args); - auto stub = BuildStub(channel); - // The initial channel state should be IDLE. - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); - // After sending RPC, channel state should be READY. - gpr_log(GPR_INFO, "*** SENDING RPC, CHANNEL SHOULD CONNECT ***"); - response_generator.SetNextResolution(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - // After a period time not using the channel, the channel state should switch - // to IDLE. - gpr_log(GPR_INFO, "*** WAITING FOR CHANNEL TO GO IDLE ***"); - gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(1200)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); - // Sending a new RPC should awake the IDLE channel. - gpr_log(GPR_INFO, "*** SENDING ANOTHER RPC, CHANNEL SHOULD RECONNECT ***"); - response_generator.SetNextResolution(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); -} - -class ClientLbPickArgsTest : public ClientLbEnd2endTest { - protected: - void SetUp() override { - ClientLbEnd2endTest::SetUp(); - current_test_instance_ = this; - } - - static void SetUpTestCase() { - grpc_init(); - grpc_core::RegisterTestPickArgsLoadBalancingPolicy(SavePickArgs); - } - - static void TearDownTestCase() { grpc_shutdown(); } - - std::vector<grpc_core::PickArgsSeen> args_seen_list() { - grpc::internal::MutexLock lock(&mu_); - return args_seen_list_; - } - - static TString ArgsSeenListString( - const std::vector<grpc_core::PickArgsSeen>& args_seen_list) { - std::vector<TString> entries; - for (const auto& args_seen : args_seen_list) { - std::vector<TString> metadata; - for (const auto& p : args_seen.metadata) { - metadata.push_back(y_absl::StrCat(p.first, "=", p.second)); - } - entries.push_back(y_absl::StrFormat("{path=\"%s\", metadata=[%s]}", - args_seen.path, - y_absl::StrJoin(metadata, ", "))); - } - return y_absl::StrCat("[", y_absl::StrJoin(entries, ", "), "]"); - } - - private: - static void SavePickArgs(const grpc_core::PickArgsSeen& args_seen) { - ClientLbPickArgsTest* self = current_test_instance_; - grpc::internal::MutexLock lock(&self->mu_); - self->args_seen_list_.emplace_back(args_seen); - } - - static ClientLbPickArgsTest* current_test_instance_; - grpc::internal::Mutex mu_; - std::vector<grpc_core::PickArgsSeen> args_seen_list_; -}; - -ClientLbPickArgsTest* ClientLbPickArgsTest::current_test_instance_ = nullptr; - -TEST_F(ClientLbPickArgsTest, Basic) { - const int kNumServers = 1; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("test_pick_args_lb", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - // Proactively connect the channel, so that the LB policy will always - // be connected before it sees the pick. Otherwise, the test would be - // flaky because sometimes the pick would be seen twice (once in - // CONNECTING and again in READY) and other times only once (in READY). - ASSERT_TRUE(channel->WaitForConnected(gpr_inf_future(GPR_CLOCK_MONOTONIC))); - // Check LB policy name for the channel. - EXPECT_EQ("test_pick_args_lb", channel->GetLoadBalancingPolicyName()); - // Now send an RPC and check that the picker sees the expected data. - CheckRpcSendOk(stub, DEBUG_LOCATION, /*wait_for_ready=*/true); - auto pick_args_seen_list = args_seen_list(); - EXPECT_THAT(pick_args_seen_list, - ::testing::ElementsAre(::testing::AllOf( - ::testing::Field(&grpc_core::PickArgsSeen::path, - "/grpc.testing.EchoTestService/Echo"), - ::testing::Field(&grpc_core::PickArgsSeen::metadata, - ::testing::UnorderedElementsAre( - ::testing::Pair("foo", "1"), - ::testing::Pair("bar", "2"), - ::testing::Pair("baz", "3")))))) - << ArgsSeenListString(pick_args_seen_list); -} - -class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { - protected: - void SetUp() override { - ClientLbEnd2endTest::SetUp(); - current_test_instance_ = this; - } - - static void SetUpTestCase() { - grpc_init(); - grpc_core::RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( - ReportTrailerIntercepted); - } - - static void TearDownTestCase() { grpc_shutdown(); } - - int trailers_intercepted() { - grpc::internal::MutexLock lock(&mu_); - return trailers_intercepted_; - } - - const grpc_core::MetadataVector& trailing_metadata() { - grpc::internal::MutexLock lock(&mu_); - return trailing_metadata_; - } - - const xds::data::orca::v3::OrcaLoadReport* backend_load_report() { - grpc::internal::MutexLock lock(&mu_); - return load_report_.get(); - } - - private: - static void ReportTrailerIntercepted( - const grpc_core::TrailingMetadataArgsSeen& args_seen) { - const auto* backend_metric_data = args_seen.backend_metric_data; - ClientLbInterceptTrailingMetadataTest* self = current_test_instance_; - grpc::internal::MutexLock lock(&self->mu_); - self->trailers_intercepted_++; - self->trailing_metadata_ = args_seen.metadata; - if (backend_metric_data != nullptr) { - self->load_report_ = - y_absl::make_unique<xds::data::orca::v3::OrcaLoadReport>(); - self->load_report_->set_cpu_utilization( - backend_metric_data->cpu_utilization); - self->load_report_->set_mem_utilization( - backend_metric_data->mem_utilization); - self->load_report_->set_rps(backend_metric_data->requests_per_second); - for (const auto& p : backend_metric_data->request_cost) { - TString name = TString(p.first); - (*self->load_report_->mutable_request_cost())[name] = p.second; - } - for (const auto& p : backend_metric_data->utilization) { - TString name = TString(p.first); - (*self->load_report_->mutable_utilization())[name] = p.second; - } - } - } - - static ClientLbInterceptTrailingMetadataTest* current_test_instance_; - grpc::internal::Mutex mu_; - int trailers_intercepted_ = 0; - grpc_core::MetadataVector trailing_metadata_; - std::unique_ptr<xds::data::orca::v3::OrcaLoadReport> load_report_; -}; - -ClientLbInterceptTrailingMetadataTest* - ClientLbInterceptTrailingMetadataTest::current_test_instance_ = nullptr; - -TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { - const int kNumServers = 1; - const int kNumRpcs = 10; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = - BuildChannel("intercept_trailing_metadata_lb", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - for (size_t i = 0; i < kNumRpcs; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - // Check LB policy name for the channel. - EXPECT_EQ("intercept_trailing_metadata_lb", - channel->GetLoadBalancingPolicyName()); - EXPECT_EQ(kNumRpcs, trailers_intercepted()); - EXPECT_THAT(trailing_metadata(), - ::testing::UnorderedElementsAre( - // TODO(roth): Should grpc-status be visible here? - ::testing::Pair("grpc-status", "0"), - ::testing::Pair("user-agent", ::testing::_), - ::testing::Pair("foo", "1"), ::testing::Pair("bar", "2"), - ::testing::Pair("baz", "3"))); - EXPECT_EQ(nullptr, backend_load_report()); -} - -TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) { - const int kNumServers = 1; - const int kNumRpcs = 10; - StartServers(kNumServers); - ChannelArguments args; - args.SetServiceConfigJSON( - "{\n" - " \"methodConfig\": [ {\n" - " \"name\": [\n" - " { \"service\": \"grpc.testing.EchoTestService\" }\n" - " ],\n" - " \"retryPolicy\": {\n" - " \"maxAttempts\": 3,\n" - " \"initialBackoff\": \"1s\",\n" - " \"maxBackoff\": \"120s\",\n" - " \"backoffMultiplier\": 1.6,\n" - " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" - " }\n" - " } ]\n" - "}"); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = - BuildChannel("intercept_trailing_metadata_lb", response_generator, args); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - for (size_t i = 0; i < kNumRpcs; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - } - // Check LB policy name for the channel. - EXPECT_EQ("intercept_trailing_metadata_lb", - channel->GetLoadBalancingPolicyName()); - EXPECT_EQ(kNumRpcs, trailers_intercepted()); - EXPECT_THAT(trailing_metadata(), - ::testing::UnorderedElementsAre( - // TODO(roth): Should grpc-status be visible here? - ::testing::Pair("grpc-status", "0"), - ::testing::Pair("user-agent", ::testing::_), - ::testing::Pair("foo", "1"), ::testing::Pair("bar", "2"), - ::testing::Pair("baz", "3"))); - EXPECT_EQ(nullptr, backend_load_report()); -} - -TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricData) { - const int kNumServers = 1; - const int kNumRpcs = 10; - StartServers(kNumServers); - xds::data::orca::v3::OrcaLoadReport load_report; - load_report.set_cpu_utilization(0.5); - load_report.set_mem_utilization(0.75); - load_report.set_rps(25); - auto* request_cost = load_report.mutable_request_cost(); - (*request_cost)["foo"] = 0.8; - (*request_cost)["bar"] = 1.4; - auto* utilization = load_report.mutable_utilization(); - (*utilization)["baz"] = 1.1; - (*utilization)["quux"] = 0.9; - for (const auto& server : servers_) { - server->service_.set_load_report(&load_report); - } - auto response_generator = BuildResolverResponseGenerator(); - auto channel = - BuildChannel("intercept_trailing_metadata_lb", response_generator); - auto stub = BuildStub(channel); - response_generator.SetNextResolution(GetServersPorts()); - for (size_t i = 0; i < kNumRpcs; ++i) { - CheckRpcSendOk(stub, DEBUG_LOCATION); - auto* actual = backend_load_report(); - ASSERT_NE(actual, nullptr); - // TODO(roth): Change this to use EqualsProto() once that becomes - // available in OSS. - EXPECT_EQ(actual->cpu_utilization(), load_report.cpu_utilization()); - EXPECT_EQ(actual->mem_utilization(), load_report.mem_utilization()); - EXPECT_EQ(actual->rps(), load_report.rps()); - EXPECT_EQ(actual->request_cost().size(), load_report.request_cost().size()); - for (const auto& p : actual->request_cost()) { - auto it = load_report.request_cost().find(p.first); - ASSERT_NE(it, load_report.request_cost().end()); - EXPECT_EQ(it->second, p.second); - } - EXPECT_EQ(actual->utilization().size(), load_report.utilization().size()); - for (const auto& p : actual->utilization()) { - auto it = load_report.utilization().find(p.first); - ASSERT_NE(it, load_report.utilization().end()); - EXPECT_EQ(it->second, p.second); - } - } - // Check LB policy name for the channel. - EXPECT_EQ("intercept_trailing_metadata_lb", - channel->GetLoadBalancingPolicyName()); - EXPECT_EQ(kNumRpcs, trailers_intercepted()); -} - -class ClientLbAddressTest : public ClientLbEnd2endTest { - protected: - static const char* kAttributeKey; - - class Attribute : public grpc_core::ServerAddress::AttributeInterface { - public: - explicit Attribute(const TString& str) : str_(str) {} - - std::unique_ptr<AttributeInterface> Copy() const override { - return y_absl::make_unique<Attribute>(str_); - } - - int Cmp(const AttributeInterface* other) const override { - return str_.compare(static_cast<const Attribute*>(other)->str_); - } - - TString ToString() const override { return str_; } - - private: - TString str_; - }; - - void SetUp() override { - ClientLbEnd2endTest::SetUp(); - current_test_instance_ = this; - } - - static void SetUpTestCase() { - grpc_init(); - grpc_core::RegisterAddressTestLoadBalancingPolicy(SaveAddress); - } - - static void TearDownTestCase() { grpc_shutdown(); } - - const std::vector<TString>& addresses_seen() { - grpc::internal::MutexLock lock(&mu_); - return addresses_seen_; - } - - private: - static void SaveAddress(const grpc_core::ServerAddress& address) { - ClientLbAddressTest* self = current_test_instance_; - grpc::internal::MutexLock lock(&self->mu_); - self->addresses_seen_.emplace_back(address.ToString()); - } - - static ClientLbAddressTest* current_test_instance_; - grpc::internal::Mutex mu_; - std::vector<TString> addresses_seen_; -}; - -const char* ClientLbAddressTest::kAttributeKey = "attribute_key"; - -ClientLbAddressTest* ClientLbAddressTest::current_test_instance_ = nullptr; - -TEST_F(ClientLbAddressTest, Basic) { - const int kNumServers = 1; - StartServers(kNumServers); - auto response_generator = BuildResolverResponseGenerator(); - auto channel = BuildChannel("address_test_lb", response_generator); - auto stub = BuildStub(channel); - // Addresses returned by the resolver will have attached attributes. - response_generator.SetNextResolution(GetServersPorts(), nullptr, - kAttributeKey, - y_absl::make_unique<Attribute>("foo")); - CheckRpcSendOk(stub, DEBUG_LOCATION); - // Check LB policy name for the channel. - EXPECT_EQ("address_test_lb", channel->GetLoadBalancingPolicyName()); - // Make sure that the attributes wind up on the subchannels. - std::vector<TString> expected; - for (const int port : GetServersPorts()) { - expected.emplace_back( - y_absl::StrCat(ipv6_only_ ? "[::1]:" : "127.0.0.1:", port, - " args={} attributes={", kAttributeKey, "=foo}")); - } - EXPECT_EQ(addresses_seen(), expected); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(argc, argv); - const auto result = RUN_ALL_TESTS(); - return result; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/context_allocator_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/context_allocator_end2end_test.cc deleted file mode 100644 index 0d9fa72f48..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/context_allocator_end2end_test.cc +++ /dev/null @@ -1,330 +0,0 @@ -/* - * - * 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. - * - */ - -#include <algorithm> -#include <atomic> -#include <condition_variable> -#include <functional> -#include <memory> -#include <mutex> -#include <sstream> -#include <thread> - -#include <gtest/gtest.h> - -#include <grpc/impl/codegen/log.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/client_callback.h> -#include <grpcpp/support/message_allocator.h> - -#include "src/core/lib/iomgr/iomgr.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_credentials_provider.h" - -namespace grpc { -namespace testing { -namespace { - -enum class Protocol { INPROC, TCP }; - -class TestScenario { - public: - TestScenario(Protocol protocol, const TString& creds_type) - : protocol(protocol), credentials_type(creds_type) {} - void Log() const; - Protocol protocol; - const TString credentials_type; -}; - -std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { - return out << "TestScenario{protocol=" - << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") - << "," << scenario.credentials_type << "}"; -} - -void TestScenario::Log() const { - std::ostringstream out; - out << *this; - gpr_log(GPR_INFO, "%s", out.str().c_str()); -} - -class ContextAllocatorEnd2endTestBase - : public ::testing::TestWithParam<TestScenario> { - protected: - static void SetUpTestCase() { grpc_init(); } - static void TearDownTestCase() { grpc_shutdown(); } - ContextAllocatorEnd2endTestBase() {} - - ~ContextAllocatorEnd2endTestBase() override = default; - - void SetUp() override { GetParam().Log(); } - - void CreateServer(std::unique_ptr<grpc::ContextAllocator> context_allocator) { - ServerBuilder builder; - - auto server_creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - if (GetParam().protocol == Protocol::TCP) { - picked_port_ = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << picked_port_; - builder.AddListeningPort(server_address_.str(), server_creds); - } - builder.SetContextAllocator(std::move(context_allocator)); - builder.RegisterService(&callback_service_); - - server_ = builder.BuildAndStart(); - } - - void DestroyServer() { - if (server_) { - server_->Shutdown(); - server_.reset(); - } - } - - void ResetStub() { - ChannelArguments args; - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - switch (GetParam().protocol) { - case Protocol::TCP: - channel_ = ::grpc::CreateCustomChannel(server_address_.str(), - channel_creds, args); - break; - case Protocol::INPROC: - channel_ = server_->InProcessChannel(args); - break; - default: - assert(false); - } - stub_ = EchoTestService::NewStub(channel_); - } - - void TearDown() override { - DestroyServer(); - if (picked_port_ > 0) { - grpc_recycle_unused_port(picked_port_); - } - } - - void SendRpcs(int num_rpcs) { - TString test_string(""); - for (int i = 0; i < num_rpcs; i++) { - EchoRequest request; - EchoResponse response; - ClientContext cli_ctx; - - test_string += TString(1024, 'x'); - request.set_message(test_string); - TString val; - cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); - - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub_->async()->Echo( - &cli_ctx, &request, &response, - [&request, &response, &done, &mu, &cv, val](Status s) { - GPR_ASSERT(s.ok()); - - EXPECT_EQ(request.message(), response.message()); - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } - } - } - - int picked_port_{0}; - std::shared_ptr<Channel> channel_; - std::unique_ptr<EchoTestService::Stub> stub_; - CallbackTestServiceImpl callback_service_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; -}; - -class DefaultContextAllocatorTest : public ContextAllocatorEnd2endTestBase {}; - -TEST_P(DefaultContextAllocatorTest, SimpleRpc) { - const int kRpcCount = 10; - CreateServer(nullptr); - ResetStub(); - SendRpcs(kRpcCount); -} - -class NullContextAllocatorTest : public ContextAllocatorEnd2endTestBase { - public: - class NullAllocator : public grpc::ContextAllocator { - public: - NullAllocator(std::atomic<int>* allocation_count, - std::atomic<int>* deallocation_count) - : allocation_count_(allocation_count), - deallocation_count_(deallocation_count) {} - grpc::CallbackServerContext* NewCallbackServerContext() override { - allocation_count_->fetch_add(1, std::memory_order_relaxed); - return nullptr; - } - - GenericCallbackServerContext* NewGenericCallbackServerContext() override { - allocation_count_->fetch_add(1, std::memory_order_relaxed); - return nullptr; - } - - void Release( - grpc::CallbackServerContext* /*callback_server_context*/) override { - deallocation_count_->fetch_add(1, std::memory_order_relaxed); - } - - void Release( - GenericCallbackServerContext* /*generic_callback_server_context*/) - override { - deallocation_count_->fetch_add(1, std::memory_order_relaxed); - } - - std::atomic<int>* allocation_count_; - std::atomic<int>* deallocation_count_; - }; -}; - -TEST_P(NullContextAllocatorTest, UnaryRpc) { - const int kRpcCount = 10; - std::atomic<int> allocation_count{0}; - std::atomic<int> deallocation_count{0}; - std::unique_ptr<NullAllocator> allocator( - new NullAllocator(&allocation_count, &deallocation_count)); - CreateServer(std::move(allocator)); - ResetStub(); - SendRpcs(kRpcCount); - // messages_deallocaton_count is updated in Release after server side - // OnDone. - DestroyServer(); - EXPECT_EQ(kRpcCount, allocation_count); - EXPECT_EQ(kRpcCount, deallocation_count); -} - -class SimpleContextAllocatorTest : public ContextAllocatorEnd2endTestBase { - public: - class SimpleAllocator : public grpc::ContextAllocator { - public: - SimpleAllocator(std::atomic<int>* allocation_count, - std::atomic<int>* deallocation_count) - : allocation_count_(allocation_count), - deallocation_count_(deallocation_count) {} - grpc::CallbackServerContext* NewCallbackServerContext() override { - allocation_count_->fetch_add(1, std::memory_order_relaxed); - return new grpc::CallbackServerContext(); - } - GenericCallbackServerContext* NewGenericCallbackServerContext() override { - allocation_count_->fetch_add(1, std::memory_order_relaxed); - return new GenericCallbackServerContext(); - } - - void Release( - grpc::CallbackServerContext* callback_server_context) override { - deallocation_count_->fetch_add(1, std::memory_order_relaxed); - delete callback_server_context; - } - - void Release(GenericCallbackServerContext* generic_callback_server_context) - override { - deallocation_count_->fetch_add(1, std::memory_order_relaxed); - delete generic_callback_server_context; - } - - std::atomic<int>* allocation_count_; - std::atomic<int>* deallocation_count_; - }; -}; - -TEST_P(SimpleContextAllocatorTest, UnaryRpc) { - const int kRpcCount = 10; - std::atomic<int> allocation_count{0}; - std::atomic<int> deallocation_count{0}; - std::unique_ptr<SimpleAllocator> allocator( - new SimpleAllocator(&allocation_count, &deallocation_count)); - CreateServer(std::move(allocator)); - ResetStub(); - SendRpcs(kRpcCount); - // messages_deallocaton_count is updated in Release after server side - // OnDone. - DestroyServer(); - EXPECT_EQ(kRpcCount, allocation_count); - EXPECT_EQ(kRpcCount, deallocation_count); -} - -std::vector<TestScenario> CreateTestScenarios(bool test_insecure) { - std::vector<TestScenario> scenarios; - std::vector<TString> credentials_types{ - GetCredentialsProvider()->GetSecureCredentialsTypeList()}; - auto insec_ok = [] { - // Only allow insecure credentials type when it is registered with the - // provider. User may create providers that do not have insecure. - return GetCredentialsProvider()->GetChannelCredentials( - kInsecureCredentialsType, nullptr) != nullptr; - }; - if (test_insecure && insec_ok()) { - credentials_types.push_back(kInsecureCredentialsType); - } - GPR_ASSERT(!credentials_types.empty()); - - Protocol parr[]{Protocol::INPROC, Protocol::TCP}; - for (Protocol p : parr) { - for (const auto& cred : credentials_types) { - if (p == Protocol::INPROC && - (cred != kInsecureCredentialsType || !insec_ok())) { - continue; - } - scenarios.emplace_back(p, cred); - } - } - return scenarios; -} - -// TODO(ddyihai): adding client streaming/server streaming/bidi streaming -// test. - -INSTANTIATE_TEST_SUITE_P(DefaultContextAllocatorTest, - DefaultContextAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); -INSTANTIATE_TEST_SUITE_P(NullContextAllocatorTest, NullContextAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); -INSTANTIATE_TEST_SUITE_P(SimpleContextAllocatorTest, SimpleContextAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/counted_service.h b/contrib/libs/grpc/test/cpp/end2end/counted_service.h deleted file mode 100644 index 8143521407..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/counted_service.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright 2017 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. -// - -#ifndef GRPC_TEST_CPP_END2END_COUNTED_SERVICE_H -#define GRPC_TEST_CPP_END2END_COUNTED_SERVICE_H - -#include "src/core/lib/gprpp/sync.h" - -namespace grpc { -namespace testing { - -// A wrapper around an RPC service implementation that provides request and -// response counting. -template <typename ServiceType> -class CountedService : public ServiceType { - public: - size_t request_count() { - grpc_core::MutexLock lock(&mu_); - return request_count_; - } - - size_t response_count() { - grpc_core::MutexLock lock(&mu_); - return response_count_; - } - - void IncreaseResponseCount() { - grpc_core::MutexLock lock(&mu_); - ++response_count_; - } - void IncreaseRequestCount() { - grpc_core::MutexLock lock(&mu_); - ++request_count_; - } - - void ResetCounters() { - grpc_core::MutexLock lock(&mu_); - request_count_ = 0; - response_count_ = 0; - } - - private: - grpc_core::Mutex mu_; - size_t request_count_ Y_ABSL_GUARDED_BY(mu_) = 0; - size_t response_count_ Y_ABSL_GUARDED_BY(mu_) = 0; -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_END2END_COUNTED_SERVICE_H diff --git a/contrib/libs/grpc/test/cpp/end2end/delegating_channel_test.cc b/contrib/libs/grpc/test/cpp/end2end/delegating_channel_test.cc deleted file mode 100644 index bdc0df0fb1..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/delegating_channel_test.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Copyright 2018 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 <memory> -#include <vector> - -#include <gtest/gtest.h> - -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/generic/generic_stub.h> -#include <grpcpp/impl/codegen/delegating_channel.h> -#include <grpcpp/impl/codegen/proto_utils.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/client_interceptor.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/byte_buffer_proto_helper.h" -#include "test/cpp/util/string_ref_helper.h" - -namespace grpc { -namespace testing { -namespace { - -class TestChannel : public experimental::DelegatingChannel { - public: - explicit TestChannel( - const std::shared_ptr<ChannelInterface>& delegate_channel) - : experimental::DelegatingChannel(delegate_channel) {} - // Always returns GRPC_CHANNEL_READY - grpc_connectivity_state GetState(bool /*try_to_connect*/) override { - return GRPC_CHANNEL_READY; - } -}; - -class DelegatingChannelTest : public ::testing::Test { - protected: - DelegatingChannelTest() { - int port = grpc_pick_unused_port_or_die(); - ServerBuilder builder; - server_address_ = "localhost:" + ToString(port); - builder.AddListeningPort(server_address_, InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - ~DelegatingChannelTest() override { server_->Shutdown(); } - - TString server_address_; - TestServiceImpl service_; - std::unique_ptr<Server> server_; -}; - -TEST_F(DelegatingChannelTest, SimpleTest) { - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); - std::shared_ptr<TestChannel> test_channel = - std::make_shared<TestChannel>(channel); - // gRPC channel should be in idle state at this point but our test channel - // will return ready. - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); - EXPECT_EQ(test_channel->GetState(false), GRPC_CHANNEL_READY); - auto stub = grpc::testing::EchoTestService::NewStub(test_channel); - ClientContext ctx; - EchoRequest req; - req.set_message("Hello"); - EchoResponse resp; - Status s = stub->Echo(&ctx, req, &resp); - EXPECT_EQ(s.ok(), true); - EXPECT_EQ(resp.message(), "Hello"); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/end2end_test.cc deleted file mode 100644 index 3649f3bbc0..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/end2end_test.cc +++ /dev/null @@ -1,2298 +0,0 @@ -/* - * - * Copyright 2015 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 <mutex> -#include <thread> - -#include "y_absl/memory/memory.h" -#include "y_absl/strings/match.h" -#include "y_absl/strings/str_format.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/resource_quota.h> -#include <grpcpp/security/auth_metadata_processor.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/string_ref.h> -#include <grpcpp/test/channel_test_peer.h> - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/security/credentials/credentials.h" -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/interceptors_util.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/string_ref_helper.h" -#include "test/cpp/util/test_credentials_provider.h" - -#ifdef GRPC_POSIX_SOCKET_EV -#include "src/core/lib/iomgr/ev_posix.h" -#endif // GRPC_POSIX_SOCKET_EV - -#include <gtest/gtest.h> - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using grpc::testing::kTlsCredentialsType; -using std::chrono::system_clock; - -namespace grpc { -namespace testing { -namespace { - -bool CheckIsLocalhost(const TString& addr) { - const TString kIpv6("ipv6:[::1]:"); - const TString kIpv4MappedIpv6("ipv6:[::ffff:127.0.0.1]:"); - const TString kIpv4("ipv4:127.0.0.1:"); - return addr.substr(0, kIpv4.size()) == kIpv4 || - addr.substr(0, kIpv4MappedIpv6.size()) == kIpv4MappedIpv6 || - addr.substr(0, kIpv6.size()) == kIpv6; -} - -const int kClientChannelBackupPollIntervalMs = 200; - -const char kTestCredsPluginErrorMsg[] = "Could not find plugin metadata."; - -const char kFakeToken[] = "fake_token"; -const char kFakeSelector[] = "fake_selector"; -const char kExpectedFakeCredsDebugString[] = - "SecureCallCredentials{GoogleIAMCredentials{Token:present," - "AuthoritySelector:fake_selector}}"; - -const char kWrongToken[] = "wrong_token"; -const char kWrongSelector[] = "wrong_selector"; -const char kExpectedWrongCredsDebugString[] = - "SecureCallCredentials{GoogleIAMCredentials{Token:present," - "AuthoritySelector:wrong_selector}}"; - -const char kFakeToken1[] = "fake_token1"; -const char kFakeSelector1[] = "fake_selector1"; -const char kExpectedFakeCreds1DebugString[] = - "SecureCallCredentials{GoogleIAMCredentials{Token:present," - "AuthoritySelector:fake_selector1}}"; - -const char kFakeToken2[] = "fake_token2"; -const char kFakeSelector2[] = "fake_selector2"; -const char kExpectedFakeCreds2DebugString[] = - "SecureCallCredentials{GoogleIAMCredentials{Token:present," - "AuthoritySelector:fake_selector2}}"; - -const char kExpectedAuthMetadataPluginKeyFailureCredsDebugString[] = - "SecureCallCredentials{TestMetadataCredentials{key:TestPluginMetadata," - "value:Does not matter, will fail the key is invalid.}}"; -const char kExpectedAuthMetadataPluginValueFailureCredsDebugString[] = - "SecureCallCredentials{TestMetadataCredentials{key:test-plugin-metadata," - "value:With illegal \n value.}}"; -const char kExpectedAuthMetadataPluginWithDeadlineCredsDebugString[] = - "SecureCallCredentials{TestMetadataCredentials{key:meta_key,value:Does not " - "matter}}"; -const char kExpectedNonBlockingAuthMetadataPluginFailureCredsDebugString[] = - "SecureCallCredentials{TestMetadataCredentials{key:test-plugin-metadata," - "value:Does not matter, will fail anyway (see 3rd param)}}"; -const char - kExpectedNonBlockingAuthMetadataPluginAndProcessorSuccessCredsDebugString - [] = "SecureCallCredentials{TestMetadataCredentials{key:test-plugin-" - "metadata,value:Dr Jekyll}}"; -const char - kExpectedNonBlockingAuthMetadataPluginAndProcessorFailureCredsDebugString - [] = "SecureCallCredentials{TestMetadataCredentials{key:test-plugin-" - "metadata,value:Mr Hyde}}"; -const char kExpectedBlockingAuthMetadataPluginFailureCredsDebugString[] = - "SecureCallCredentials{TestMetadataCredentials{key:test-plugin-metadata," - "value:Does not matter, will fail anyway (see 3rd param)}}"; -const char kExpectedCompositeCallCredsDebugString[] = - "SecureCallCredentials{CompositeCallCredentials{TestMetadataCredentials{" - "key:call-creds-key1,value:call-creds-val1},TestMetadataCredentials{key:" - "call-creds-key2,value:call-creds-val2}}}"; - -class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { - public: - static const char kGoodMetadataKey[]; - static const char kBadMetadataKey[]; - - TestMetadataCredentialsPlugin(const grpc::string_ref& metadata_key, - const grpc::string_ref& metadata_value, - bool is_blocking, bool is_successful, - int delay_ms) - : metadata_key_(metadata_key.data(), metadata_key.length()), - metadata_value_(metadata_value.data(), metadata_value.length()), - is_blocking_(is_blocking), - is_successful_(is_successful), - delay_ms_(delay_ms) {} - - bool IsBlocking() const override { return is_blocking_; } - - Status GetMetadata( - grpc::string_ref service_url, grpc::string_ref method_name, - const grpc::AuthContext& channel_auth_context, - std::multimap<TString, TString>* metadata) override { - if (delay_ms_ != 0) { - gpr_sleep_until( - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(delay_ms_, GPR_TIMESPAN))); - } - EXPECT_GT(service_url.length(), 0UL); - EXPECT_GT(method_name.length(), 0UL); - EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated()); - EXPECT_TRUE(metadata != nullptr); - if (is_successful_) { - metadata->insert(std::make_pair(metadata_key_, metadata_value_)); - return Status::OK; - } else { - return Status(StatusCode::NOT_FOUND, kTestCredsPluginErrorMsg); - } - } - - TString DebugString() override { - return y_absl::StrFormat("TestMetadataCredentials{key:%s,value:%s}", - metadata_key_.c_str(), metadata_value_.c_str()); - } - - private: - TString metadata_key_; - TString metadata_value_; - bool is_blocking_; - bool is_successful_; - int delay_ms_; -}; - -const char TestMetadataCredentialsPlugin::kBadMetadataKey[] = - "TestPluginMetadata"; -const char TestMetadataCredentialsPlugin::kGoodMetadataKey[] = - "test-plugin-metadata"; - -class TestAuthMetadataProcessor : public AuthMetadataProcessor { - public: - static const char kGoodGuy[]; - - explicit TestAuthMetadataProcessor(bool is_blocking) - : is_blocking_(is_blocking) {} - - std::shared_ptr<CallCredentials> GetCompatibleClientCreds() { - return grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin( - TestMetadataCredentialsPlugin::kGoodMetadataKey, kGoodGuy, - is_blocking_, true, 0))); - } - - std::shared_ptr<CallCredentials> GetIncompatibleClientCreds() { - return grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin( - TestMetadataCredentialsPlugin::kGoodMetadataKey, "Mr Hyde", - is_blocking_, true, 0))); - } - - // Interface implementation - bool IsBlocking() const override { return is_blocking_; } - - Status Process(const InputMetadata& auth_metadata, AuthContext* context, - OutputMetadata* consumed_auth_metadata, - OutputMetadata* response_metadata) override { - EXPECT_TRUE(consumed_auth_metadata != nullptr); - EXPECT_TRUE(context != nullptr); - EXPECT_TRUE(response_metadata != nullptr); - auto auth_md = - auth_metadata.find(TestMetadataCredentialsPlugin::kGoodMetadataKey); - EXPECT_NE(auth_md, auth_metadata.end()); - string_ref auth_md_value = auth_md->second; - if (auth_md_value == kGoodGuy) { - context->AddProperty(kIdentityPropName, kGoodGuy); - context->SetPeerIdentityPropertyName(kIdentityPropName); - consumed_auth_metadata->insert(std::make_pair( - string(auth_md->first.data(), auth_md->first.length()), - string(auth_md->second.data(), auth_md->second.length()))); - return Status::OK; - } else { - return Status(StatusCode::UNAUTHENTICATED, - string("Invalid principal: ") + - string(auth_md_value.data(), auth_md_value.length())); - } - } - - private: - static const char kIdentityPropName[]; - bool is_blocking_; -}; - -const char TestAuthMetadataProcessor::kGoodGuy[] = "Dr Jekyll"; -const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity"; - -class Proxy : public ::grpc::testing::EchoTestService::Service { - public: - explicit Proxy(const std::shared_ptr<Channel>& channel) - : stub_(grpc::testing::EchoTestService::NewStub(channel)) {} - - Status Echo(ServerContext* server_context, const EchoRequest* request, - EchoResponse* response) override { - std::unique_ptr<ClientContext> client_context = - ClientContext::FromServerContext(*server_context); - return stub_->Echo(client_context.get(), *request, response); - } - - private: - std::unique_ptr<::grpc::testing::EchoTestService::Stub> stub_; -}; - -class TestServiceImplDupPkg - : public ::grpc::testing::duplicate::EchoTestService::Service { - public: - Status Echo(ServerContext* /*context*/, const EchoRequest* /*request*/, - EchoResponse* response) override { - response->set_message("no package"); - return Status::OK; - } -}; - -class TestScenario { - public: - TestScenario(bool interceptors, bool proxy, bool inproc_stub, - const TString& creds_type, bool use_callback_server) - : use_interceptors(interceptors), - use_proxy(proxy), - inproc(inproc_stub), - credentials_type(creds_type), - callback_server(use_callback_server) {} - void Log() const; - bool use_interceptors; - bool use_proxy; - bool inproc; - const TString credentials_type; - bool callback_server; -}; - -std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { - return out << "TestScenario{use_interceptors=" - << (scenario.use_interceptors ? "true" : "false") - << ", use_proxy=" << (scenario.use_proxy ? "true" : "false") - << ", inproc=" << (scenario.inproc ? "true" : "false") - << ", server_type=" - << (scenario.callback_server ? "callback" : "sync") - << ", credentials='" << scenario.credentials_type << "'}"; -} - -void TestScenario::Log() const { - std::ostringstream out; - out << *this; - gpr_log(GPR_DEBUG, "%s", out.str().c_str()); -} - -class End2endTest : public ::testing::TestWithParam<TestScenario> { - protected: - static void SetUpTestCase() { grpc_init(); } - static void TearDownTestCase() { grpc_shutdown(); } - End2endTest() - : is_server_started_(false), - kMaxMessageSize_(8192), - special_service_("special"), - first_picked_port_(0) { - GetParam().Log(); - } - - void TearDown() override { - if (is_server_started_) { - server_->Shutdown(); - if (proxy_server_) proxy_server_->Shutdown(); - } - if (first_picked_port_ > 0) { - grpc_recycle_unused_port(first_picked_port_); - } - } - - void StartServer(const std::shared_ptr<AuthMetadataProcessor>& processor) { - int port = grpc_pick_unused_port_or_die(); - first_picked_port_ = port; - server_address_ << "localhost:" << port; - // Setup server - BuildAndStartServer(processor); - } - - void RestartServer(const std::shared_ptr<AuthMetadataProcessor>& processor) { - if (is_server_started_) { - server_->Shutdown(); - BuildAndStartServer(processor); - } - } - - void BuildAndStartServer( - const std::shared_ptr<AuthMetadataProcessor>& processor) { - ServerBuilder builder; - ConfigureServerBuilder(&builder); - auto server_creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - if (GetParam().credentials_type != kInsecureCredentialsType) { - server_creds->SetAuthMetadataProcessor(processor); - } - if (GetParam().use_interceptors) { - std::vector< - std::unique_ptr<experimental::ServerInterceptorFactoryInterface>> - creators; - // Add 20 phony server interceptors - creators.reserve(20); - for (auto i = 0; i < 20; i++) { - creators.push_back(y_absl::make_unique<PhonyInterceptorFactory>()); - } - builder.experimental().SetInterceptorCreators(std::move(creators)); - } - builder.AddListeningPort(server_address_.str(), server_creds); - if (!GetParam().callback_server) { - builder.RegisterService(&service_); - } else { - builder.RegisterService(&callback_service_); - } - builder.RegisterService("foo.test.youtube.com", &special_service_); - builder.RegisterService(&dup_pkg_service_); - - builder.SetSyncServerOption(ServerBuilder::SyncServerOption::NUM_CQS, 4); - builder.SetSyncServerOption( - ServerBuilder::SyncServerOption::CQ_TIMEOUT_MSEC, 10); - - server_ = builder.BuildAndStart(); - is_server_started_ = true; - } - - virtual void ConfigureServerBuilder(ServerBuilder* builder) { - builder->SetMaxMessageSize( - kMaxMessageSize_); // For testing max message size. - } - - void ResetChannel( - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators = {}) { - if (!is_server_started_) { - StartServer(std::shared_ptr<AuthMetadataProcessor>()); - } - EXPECT_TRUE(is_server_started_); - ChannelArguments args; - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - if (!user_agent_prefix_.empty()) { - args.SetUserAgentPrefix(user_agent_prefix_); - } - args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test"); - - if (!GetParam().inproc) { - if (!GetParam().use_interceptors) { - channel_ = ::grpc::CreateCustomChannel(server_address_.str(), - channel_creds, args); - } else { - channel_ = CreateCustomChannelWithInterceptors( - server_address_.str(), channel_creds, args, - interceptor_creators.empty() ? CreatePhonyClientInterceptors() - : std::move(interceptor_creators)); - } - } else { - if (!GetParam().use_interceptors) { - channel_ = server_->InProcessChannel(args); - } else { - channel_ = server_->experimental().InProcessChannelWithInterceptors( - args, interceptor_creators.empty() - ? CreatePhonyClientInterceptors() - : std::move(interceptor_creators)); - } - } - } - - void ResetStub( - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators = {}) { - ResetChannel(std::move(interceptor_creators)); - if (GetParam().use_proxy) { - proxy_service_ = y_absl::make_unique<Proxy>(channel_); - int port = grpc_pick_unused_port_or_die(); - std::ostringstream proxyaddr; - proxyaddr << "localhost:" << port; - ServerBuilder builder; - builder.AddListeningPort(proxyaddr.str(), InsecureServerCredentials()); - builder.RegisterService(proxy_service_.get()); - - builder.SetSyncServerOption(ServerBuilder::SyncServerOption::NUM_CQS, 4); - builder.SetSyncServerOption( - ServerBuilder::SyncServerOption::CQ_TIMEOUT_MSEC, 10); - - proxy_server_ = builder.BuildAndStart(); - - channel_ = - grpc::CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); - } - - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - PhonyInterceptor::Reset(); - } - - bool is_server_started_; - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::unique_ptr<Server> proxy_server_; - std::unique_ptr<Proxy> proxy_service_; - std::ostringstream server_address_; - const int kMaxMessageSize_; - TestServiceImpl service_; - CallbackTestServiceImpl callback_service_; - TestServiceImpl special_service_; - TestServiceImplDupPkg dup_pkg_service_; - TString user_agent_prefix_; - int first_picked_port_; -}; - -void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs, - bool with_binary_metadata) { - EchoRequest request; - EchoResponse response; - request.set_message("Hello hello hello hello"); - - for (int i = 0; i < num_rpcs; ++i) { - ClientContext context; - if (with_binary_metadata) { - char bytes[8] = {'\0', '\1', '\2', '\3', - '\4', '\5', '\6', static_cast<char>(i)}; - context.AddMetadata("custom-bin", TString(bytes, 8)); - } - context.set_compression_algorithm(GRPC_COMPRESS_GZIP); - Status s = stub->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - } -} - -// This class is for testing scenarios where RPCs are cancelled on the server -// by calling ServerContext::TryCancel() -class End2endServerTryCancelTest : public End2endTest { - protected: - // Helper for testing client-streaming RPCs which are cancelled on the server. - // Depending on the value of server_try_cancel parameter, this will test one - // of the following three scenarios: - // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading - // any messages from the client - // - // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading - // messages from the client - // - // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading all - // the messages from the client - // - // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. - void TestRequestStreamServerCancel( - ServerTryCancelRequestPhase server_try_cancel, int num_msgs_to_send) { - RestartServer(std::shared_ptr<AuthMetadataProcessor>()); - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - // Send server_try_cancel value in the client metadata - context.AddMetadata(kServerTryCancelRequest, - ToString(server_try_cancel)); - - auto stream = stub_->RequestStream(&context, &response); - - int num_msgs_sent = 0; - while (num_msgs_sent < num_msgs_to_send) { - request.set_message("hello"); - if (!stream->Write(request)) { - break; - } - num_msgs_sent++; - } - gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent); - - stream->WritesDone(); - Status s = stream->Finish(); - - // At this point, we know for sure that RPC was cancelled by the server - // since we passed server_try_cancel value in the metadata. Depending on the - // value of server_try_cancel, the RPC might have been cancelled by the - // server at different stages. The following validates our expectations of - // number of messages sent in various cancellation scenarios: - - switch (server_try_cancel) { - case CANCEL_BEFORE_PROCESSING: - case CANCEL_DURING_PROCESSING: - // If the RPC is cancelled by server before / during messages from the - // client, it means that the client most likely did not get a chance to - // send all the messages it wanted to send. i.e num_msgs_sent <= - // num_msgs_to_send - EXPECT_LE(num_msgs_sent, num_msgs_to_send); - break; - - case CANCEL_AFTER_PROCESSING: - // If the RPC was cancelled after all messages were read by the server, - // the client did get a chance to send all its messages - EXPECT_EQ(num_msgs_sent, num_msgs_to_send); - break; - - default: - gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d", - server_try_cancel); - EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL && - server_try_cancel <= CANCEL_AFTER_PROCESSING); - break; - } - - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } - } - - // Helper for testing server-streaming RPCs which are cancelled on the server. - // Depending on the value of server_try_cancel parameter, this will test one - // of the following three scenarios: - // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before writing - // any messages to the client - // - // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while writing - // messages to the client - // - // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after writing all - // the messages to the client - // - // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. - void TestResponseStreamServerCancel( - ServerTryCancelRequestPhase server_try_cancel) { - RestartServer(std::shared_ptr<AuthMetadataProcessor>()); - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - // Send server_try_cancel in the client metadata - context.AddMetadata(kServerTryCancelRequest, - ToString(server_try_cancel)); - - request.set_message("hello"); - auto stream = stub_->ResponseStream(&context, request); - - int num_msgs_read = 0; - while (num_msgs_read < kServerDefaultResponseStreamsToSend) { - if (!stream->Read(&response)) { - break; - } - EXPECT_EQ(response.message(), - request.message() + ToString(num_msgs_read)); - num_msgs_read++; - } - gpr_log(GPR_INFO, "Read %d messages", num_msgs_read); - - Status s = stream->Finish(); - - // Depending on the value of server_try_cancel, the RPC might have been - // cancelled by the server at different stages. The following validates our - // expectations of number of messages read in various cancellation - // scenarios: - switch (server_try_cancel) { - case CANCEL_BEFORE_PROCESSING: - // Server cancelled before sending any messages. Which means the client - // wouldn't have read any - EXPECT_EQ(num_msgs_read, 0); - break; - - case CANCEL_DURING_PROCESSING: - // Server cancelled while writing messages. Client must have read less - // than or equal to the expected number of messages - EXPECT_LE(num_msgs_read, kServerDefaultResponseStreamsToSend); - break; - - case CANCEL_AFTER_PROCESSING: - // Even though the Server cancelled after writing all messages, the RPC - // may be cancelled before the Client got a chance to read all the - // messages. - EXPECT_LE(num_msgs_read, kServerDefaultResponseStreamsToSend); - break; - - default: { - gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d", - server_try_cancel); - EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL && - server_try_cancel <= CANCEL_AFTER_PROCESSING); - break; - } - } - - EXPECT_FALSE(s.ok()); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } - } - - // Helper for testing bidirectional-streaming RPCs which are cancelled on the - // server. Depending on the value of server_try_cancel parameter, this will - // test one of the following three scenarios: - // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading/ - // writing any messages from/to the client - // - // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading/ - // writing messages from/to the client - // - // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading/writing - // all the messages from/to the client - // - // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. - void TestBidiStreamServerCancel(ServerTryCancelRequestPhase server_try_cancel, - int num_messages) { - RestartServer(std::shared_ptr<AuthMetadataProcessor>()); - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - // Send server_try_cancel in the client metadata - context.AddMetadata(kServerTryCancelRequest, - ToString(server_try_cancel)); - - auto stream = stub_->BidiStream(&context); - - int num_msgs_read = 0; - int num_msgs_sent = 0; - while (num_msgs_sent < num_messages) { - request.set_message("hello " + ToString(num_msgs_sent)); - if (!stream->Write(request)) { - break; - } - num_msgs_sent++; - - if (!stream->Read(&response)) { - break; - } - num_msgs_read++; - - EXPECT_EQ(response.message(), request.message()); - } - gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent); - gpr_log(GPR_INFO, "Read %d messages", num_msgs_read); - - stream->WritesDone(); - Status s = stream->Finish(); - - // Depending on the value of server_try_cancel, the RPC might have been - // cancelled by the server at different stages. The following validates our - // expectations of number of messages read in various cancellation - // scenarios: - switch (server_try_cancel) { - case CANCEL_BEFORE_PROCESSING: - EXPECT_EQ(num_msgs_read, 0); - break; - - case CANCEL_DURING_PROCESSING: - EXPECT_LE(num_msgs_sent, num_messages); - EXPECT_LE(num_msgs_read, num_msgs_sent); - break; - - case CANCEL_AFTER_PROCESSING: - EXPECT_EQ(num_msgs_sent, num_messages); - - // The Server cancelled after reading the last message and after writing - // the message to the client. However, the RPC cancellation might have - // taken effect before the client actually read the response. - EXPECT_LE(num_msgs_read, num_msgs_sent); - break; - - default: - gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d", - server_try_cancel); - EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL && - server_try_cancel <= CANCEL_AFTER_PROCESSING); - break; - } - - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - // Make sure that the server interceptors were notified - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } - } -}; - -TEST_P(End2endServerTryCancelTest, RequestEchoServerCancel) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - context.AddMetadata(kServerTryCancelRequest, - ToString(CANCEL_BEFORE_PROCESSING)); - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); -} - -// Server to cancel before doing reading the request -TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelBeforeReads) { - TestRequestStreamServerCancel(CANCEL_BEFORE_PROCESSING, 1); -} - -// Server to cancel while reading a request from the stream in parallel -TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelDuringRead) { - TestRequestStreamServerCancel(CANCEL_DURING_PROCESSING, 10); -} - -// Server to cancel after reading all the requests but before returning to the -// client -TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelAfterReads) { - TestRequestStreamServerCancel(CANCEL_AFTER_PROCESSING, 4); -} - -// Server to cancel before sending any response messages -TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelBefore) { - TestResponseStreamServerCancel(CANCEL_BEFORE_PROCESSING); -} - -// Server to cancel while writing a response to the stream in parallel -TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelDuring) { - TestResponseStreamServerCancel(CANCEL_DURING_PROCESSING); -} - -// Server to cancel after writing all the respones to the stream but before -// returning to the client -TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelAfter) { - TestResponseStreamServerCancel(CANCEL_AFTER_PROCESSING); -} - -// Server to cancel before reading/writing any requests/responses on the stream -TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelBefore) { - TestBidiStreamServerCancel(CANCEL_BEFORE_PROCESSING, 2); -} - -// Server to cancel while reading/writing requests/responses on the stream in -// parallel -TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelDuring) { - TestBidiStreamServerCancel(CANCEL_DURING_PROCESSING, 10); -} - -// Server to cancel after reading/writing all requests/responses on the stream -// but before returning to the client -TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelAfter) { - TestBidiStreamServerCancel(CANCEL_AFTER_PROCESSING, 5); -} - -TEST_P(End2endTest, SimpleRpcWithCustomUserAgentPrefix) { - // User-Agent is an HTTP header for HTTP transports only - if (GetParam().inproc) { - return; - } - user_agent_prefix_ = "custom_prefix"; - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello hello hello hello"); - request.mutable_param()->set_echo_metadata(true); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - const auto& trailing_metadata = context.GetServerTrailingMetadata(); - auto iter = trailing_metadata.find("user-agent"); - EXPECT_TRUE(iter != trailing_metadata.end()); - TString expected_prefix = user_agent_prefix_ + " grpc-c++/"; - EXPECT_TRUE(iter->second.starts_with(expected_prefix)) << iter->second; -} - -TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { - ResetStub(); - std::vector<std::thread> threads; - threads.reserve(10); - for (int i = 0; i < 10; ++i) { - threads.emplace_back(SendRpc, stub_.get(), 10, true); - } - for (int i = 0; i < 10; ++i) { - threads[i].join(); - } -} - -TEST_P(End2endTest, MultipleRpcs) { - ResetStub(); - std::vector<std::thread> threads; - threads.reserve(10); - for (int i = 0; i < 10; ++i) { - threads.emplace_back(SendRpc, stub_.get(), 10, false); - } - for (int i = 0; i < 10; ++i) { - threads[i].join(); - } -} - -TEST_P(End2endTest, ManyStubs) { - ResetStub(); - ChannelTestPeer peer(channel_.get()); - int registered_calls_pre = peer.registered_calls(); - int registration_attempts_pre = peer.registration_attempts(); - for (int i = 0; i < 1000; ++i) { - grpc::testing::EchoTestService::NewStub(channel_); - } - EXPECT_EQ(peer.registered_calls(), registered_calls_pre); - EXPECT_GT(peer.registration_attempts(), registration_attempts_pre); -} - -TEST_P(End2endTest, EmptyBinaryMetadata) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello hello hello hello"); - ClientContext context; - context.AddMetadata("custom-bin", ""); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, ReconnectChannel) { - if (GetParam().inproc) { - return; - } - int poller_slowdown_factor = 1; - // It needs 2 pollset_works to reconnect the channel with polling engine - // "poll" -#ifdef GRPC_POSIX_SOCKET_EV - grpc_core::UniquePtr<char> poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); - if (0 == strcmp(poller.get(), "poll")) { - poller_slowdown_factor = 2; - } -#endif // GRPC_POSIX_SOCKET_EV - ResetStub(); - SendRpc(stub_.get(), 1, false); - RestartServer(std::shared_ptr<AuthMetadataProcessor>()); - // It needs more than GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS time to - // reconnect the channel. Make it a factor of 5x - gpr_sleep_until( - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(kClientChannelBackupPollIntervalMs * 5 * - poller_slowdown_factor * - grpc_test_slowdown_factor(), - GPR_TIMESPAN))); - SendRpc(stub_.get(), 1, false); -} - -TEST_P(End2endTest, RequestStreamOneRequest) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - auto stream = stub_->RequestStream(&context, &response); - request.set_message("hello"); - EXPECT_TRUE(stream->Write(request)); - stream->WritesDone(); - Status s = stream->Finish(); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - EXPECT_TRUE(context.debug_error_string().empty()); -} - -TEST_P(End2endTest, RequestStreamOneRequestWithCoalescingApi) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - context.set_initial_metadata_corked(true); - auto stream = stub_->RequestStream(&context, &response); - request.set_message("hello"); - stream->WriteLast(request, WriteOptions()); - Status s = stream->Finish(); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, RequestStreamTwoRequests) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - auto stream = stub_->RequestStream(&context, &response); - request.set_message("hello"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Write(request)); - stream->WritesDone(); - Status s = stream->Finish(); - EXPECT_EQ(response.message(), "hellohello"); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, RequestStreamTwoRequestsWithWriteThrough) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - auto stream = stub_->RequestStream(&context, &response); - request.set_message("hello"); - EXPECT_TRUE(stream->Write(request, WriteOptions().set_write_through())); - EXPECT_TRUE(stream->Write(request, WriteOptions().set_write_through())); - stream->WritesDone(); - Status s = stream->Finish(); - EXPECT_EQ(response.message(), "hellohello"); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, RequestStreamTwoRequestsWithCoalescingApi) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - context.set_initial_metadata_corked(true); - auto stream = stub_->RequestStream(&context, &response); - request.set_message("hello"); - EXPECT_TRUE(stream->Write(request)); - stream->WriteLast(request, WriteOptions()); - Status s = stream->Finish(); - EXPECT_EQ(response.message(), "hellohello"); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, ResponseStream) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - - auto stream = stub_->ResponseStream(&context, request); - for (int i = 0; i < kServerDefaultResponseStreamsToSend; ++i) { - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + ToString(i)); - } - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, ResponseStreamWithCoalescingApi) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - context.AddMetadata(kServerUseCoalescingApi, "1"); - - auto stream = stub_->ResponseStream(&context, request); - for (int i = 0; i < kServerDefaultResponseStreamsToSend; ++i) { - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + ToString(i)); - } - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); -} - -// This was added to prevent regression from issue: -// https://github.com/grpc/grpc/issues/11546 -TEST_P(End2endTest, ResponseStreamWithEverythingCoalesced) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - context.AddMetadata(kServerUseCoalescingApi, "1"); - // We will only send one message, forcing everything (init metadata, message, - // trailing) to be coalesced together. - context.AddMetadata(kServerResponseStreamsToSend, "1"); - - auto stream = stub_->ResponseStream(&context, request); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "0"); - - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, BidiStream) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - TString msg("hello"); - - auto stream = stub_->BidiStream(&context); - - for (int i = 0; i < kServerDefaultResponseStreamsToSend; ++i) { - request.set_message(msg + ToString(i)); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - } - - stream->WritesDone(); - EXPECT_FALSE(stream->Read(&response)); - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, BidiStreamWithCoalescingApi) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.AddMetadata(kServerFinishAfterNReads, "3"); - context.set_initial_metadata_corked(true); - TString msg("hello"); - - auto stream = stub_->BidiStream(&context); - - request.set_message(msg + "0"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - request.set_message(msg + "1"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - request.set_message(msg + "2"); - stream->WriteLast(request, WriteOptions()); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - EXPECT_FALSE(stream->Read(&response)); - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); -} - -// This was added to prevent regression from issue: -// https://github.com/grpc/grpc/issues/11546 -TEST_P(End2endTest, BidiStreamWithEverythingCoalesced) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.AddMetadata(kServerFinishAfterNReads, "1"); - context.set_initial_metadata_corked(true); - TString msg("hello"); - - auto stream = stub_->BidiStream(&context); - - request.set_message(msg + "0"); - stream->WriteLast(request, WriteOptions()); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - EXPECT_FALSE(stream->Read(&response)); - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); -} - -// Talk to the two services with the same name but different package names. -// The two stubs are created on the same channel. -TEST_P(End2endTest, DiffPackageServices) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - - std::unique_ptr<grpc::testing::duplicate::EchoTestService::Stub> dup_pkg_stub( - grpc::testing::duplicate::EchoTestService::NewStub(channel_)); - ClientContext context2; - s = dup_pkg_stub->Echo(&context2, request, &response); - EXPECT_EQ("no package", response.message()); - EXPECT_TRUE(s.ok()); -} - -template <class ServiceType> -void CancelRpc(ClientContext* context, int delay_us, ServiceType* service) { - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(delay_us, GPR_TIMESPAN))); - while (!service->signal_client()) { - } - context->TryCancel(); -} - -TEST_P(End2endTest, CancelRpcBeforeStart) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - context.TryCancel(); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ("", response.message()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(End2endTest, CancelRpcAfterStart) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - request.mutable_param()->set_server_notify_client_when_started(true); - request.mutable_param()->set_skip_cancelled_check(true); - Status s; - std::thread echo_thread([this, &s, &context, &request, &response] { - s = stub_->Echo(&context, request, &response); - EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); - }); - if (!GetParam().callback_server) { - service_.ClientWaitUntilRpcStarted(); - } else { - callback_service_.ClientWaitUntilRpcStarted(); - } - - context.TryCancel(); - - if (!GetParam().callback_server) { - service_.SignalServerToContinue(); - } else { - callback_service_.SignalServerToContinue(); - } - - echo_thread.join(); - EXPECT_EQ("", response.message()); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Client cancels request stream after sending two messages -TEST_P(End2endTest, ClientCancelsRequestStream) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - - auto stream = stub_->RequestStream(&context, &response); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Write(request)); - - context.TryCancel(); - - Status s = stream->Finish(); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - - EXPECT_EQ(response.message(), ""); - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Client cancels server stream after sending some messages -TEST_P(End2endTest, ClientCancelsResponseStream) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("hello"); - - auto stream = stub_->ResponseStream(&context, request); - - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "0"); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "1"); - - context.TryCancel(); - - // The cancellation races with responses, so there might be zero or - // one responses pending, read till failure - - if (stream->Read(&response)) { - EXPECT_EQ(response.message(), request.message() + "2"); - // Since we have cancelled, we expect the next attempt to read to fail - EXPECT_FALSE(stream->Read(&response)); - } - - Status s = stream->Finish(); - // The final status could be either of CANCELLED or OK depending on - // who won the race. - EXPECT_GE(grpc::StatusCode::CANCELLED, s.error_code()); - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -// Client cancels bidi stream after sending some messages -TEST_P(End2endTest, ClientCancelsBidi) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - TString msg("hello"); - - // Send server_try_cancel value in the client metadata - context.AddMetadata(kClientTryCancelRequest, ToString(1)); - - auto stream = stub_->BidiStream(&context); - - request.set_message(msg + "0"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - request.set_message(msg + "1"); - EXPECT_TRUE(stream->Write(request)); - - context.TryCancel(); - - // The cancellation races with responses, so there might be zero or - // one responses pending, read till failure - - if (stream->Read(&response)) { - EXPECT_EQ(response.message(), request.message()); - // Since we have cancelled, we expect the next attempt to read to fail - EXPECT_FALSE(stream->Read(&response)); - } - - Status s = stream->Finish(); - EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); - if (GetParam().use_interceptors) { - EXPECT_EQ(20, PhonyInterceptor::GetNumTimesCancel()); - } -} - -TEST_P(End2endTest, RpcMaxMessageSize) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message(string(kMaxMessageSize_ * 2, 'a')); - request.mutable_param()->set_server_die(true); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); -} - -void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream, - gpr_event* ev) { - EchoResponse resp; - gpr_event_set(ev, reinterpret_cast<void*>(1)); - while (stream->Read(&resp)) { - gpr_log(GPR_INFO, "Read message"); - } -} - -// Run a Read and a WritesDone simultaneously. -TEST_P(End2endTest, SimultaneousReadWritesDone) { - ResetStub(); - ClientContext context; - gpr_event ev; - gpr_event_init(&ev); - auto stream = stub_->BidiStream(&context); - std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev); - gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME)); - stream->WritesDone(); - reader_thread.join(); - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); -} - -TEST_P(End2endTest, ChannelState) { - if (GetParam().inproc) { - return; - } - - ResetStub(); - // Start IDLE - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false)); - - // Did not ask to connect, no state change. - CompletionQueue cq; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::milliseconds(10); - channel_->NotifyOnStateChange(GRPC_CHANNEL_IDLE, deadline, &cq, nullptr); - void* tag; - bool ok = true; - cq.Next(&tag, &ok); - EXPECT_FALSE(ok); - - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true)); - EXPECT_TRUE(channel_->WaitForStateChange(GRPC_CHANNEL_IDLE, - gpr_inf_future(GPR_CLOCK_REALTIME))); - auto state = channel_->GetState(false); - EXPECT_TRUE(state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_READY); -} - -// Takes 10s. -TEST_P(End2endTest, ChannelStateTimeout) { - if ((GetParam().credentials_type != kInsecureCredentialsType) || - GetParam().inproc) { - return; - } - int port = grpc_pick_unused_port_or_die(); - std::ostringstream server_address; - server_address << "localhost:" << port; - // Channel to non-existing server - auto channel = - grpc::CreateChannel(server_address.str(), InsecureChannelCredentials()); - // Start IDLE - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true)); - - auto state = GRPC_CHANNEL_IDLE; - for (int i = 0; i < 10; i++) { - channel->WaitForStateChange( - state, std::chrono::system_clock::now() + std::chrono::seconds(1)); - state = channel->GetState(false); - } -} - -TEST_P(End2endTest, ChannelStateOnLameChannel) { - if ((GetParam().credentials_type != kInsecureCredentialsType) || - GetParam().inproc) { - return; - } - // Channel using invalid target URI. This creates a lame channel. - auto channel = grpc::CreateChannel("dns:///", InsecureChannelCredentials()); - // Channel should immediately report TRANSIENT_FAILURE. - EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel->GetState(true)); - // And state will never change. - auto state = GRPC_CHANNEL_TRANSIENT_FAILURE; - for (int i = 0; i < 10; ++i) { - channel->WaitForStateChange( - state, std::chrono::system_clock::now() + std::chrono::seconds(1)); - state = channel->GetState(false); - } -} - -// Talking to a non-existing service. -TEST_P(End2endTest, NonExistingService) { - ResetChannel(); - std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub; - stub = grpc::testing::UnimplementedEchoService::NewStub(channel_); - - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - Status s = stub->Unimplemented(&context, request, &response); - EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code()); - EXPECT_EQ("", s.error_message()); -} - -// Ask the server to send back a serialized proto in trailer. -// This is an example of setting error details. -TEST_P(End2endTest, BinaryTrailerTest) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - request.mutable_param()->set_echo_metadata(true); - DebugInfo* info = request.mutable_param()->mutable_debug_info(); - info->add_stack_entries("stack_entry_1"); - info->add_stack_entries("stack_entry_2"); - info->add_stack_entries("stack_entry_3"); - info->set_detail("detailed debug info"); - TString expected_string = info->SerializeAsString(); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - auto trailers = context.GetServerTrailingMetadata(); - EXPECT_EQ(1u, trailers.count(kDebugInfoTrailerKey)); - auto iter = trailers.find(kDebugInfoTrailerKey); - EXPECT_EQ(expected_string, iter->second); - // Parse the returned trailer into a DebugInfo proto. - DebugInfo returned_info; - EXPECT_TRUE(returned_info.ParseFromString(ToString(iter->second))); -} - -TEST_P(End2endTest, ExpectErrorTest) { - ResetStub(); - - std::vector<ErrorStatus> expected_status; - expected_status.emplace_back(); - expected_status.back().set_code(13); // INTERNAL - // No Error message or details - - expected_status.emplace_back(); - expected_status.back().set_code(13); // INTERNAL - expected_status.back().set_error_message("text error message"); - expected_status.back().set_binary_error_details("text error details"); - - expected_status.emplace_back(); - expected_status.back().set_code(13); // INTERNAL - expected_status.back().set_error_message("text error message"); - expected_status.back().set_binary_error_details( - "\x0\x1\x2\x3\x4\x5\x6\x8\x9\xA\xB"); - - for (auto iter = expected_status.begin(); iter != expected_status.end(); - ++iter) { - EchoRequest request; - EchoResponse response; - ClientContext context; - request.set_message("Hello"); - auto* error = request.mutable_param()->mutable_expected_error(); - error->set_code(iter->code()); - error->set_error_message(iter->error_message()); - error->set_binary_error_details(iter->binary_error_details()); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(iter->code(), s.error_code()); - EXPECT_EQ(iter->error_message(), s.error_message()); - EXPECT_EQ(iter->binary_error_details(), s.error_details()); - EXPECT_TRUE(y_absl::StrContains(context.debug_error_string(), "created")); -#ifndef NDEBUG - // GRPC_ERROR_INT_FILE_LINE is for debug only - EXPECT_TRUE(y_absl::StrContains(context.debug_error_string(), "file")); - EXPECT_TRUE(y_absl::StrContains(context.debug_error_string(), "line")); -#endif - EXPECT_TRUE(y_absl::StrContains(context.debug_error_string(), "status")); - EXPECT_TRUE(y_absl::StrContains(context.debug_error_string(), "13")); - } -} - -////////////////////////////////////////////////////////////////////////// -// Test with and without a proxy. -class ProxyEnd2endTest : public End2endTest { - protected: -}; - -TEST_P(ProxyEnd2endTest, SimpleRpc) { - ResetStub(); - SendRpc(stub_.get(), 1, false); -} - -TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) { - ResetStub(); - EchoRequest request; - EchoResponse response; - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_TRUE(s.ok()); -} - -TEST_P(ProxyEnd2endTest, MultipleRpcs) { - ResetStub(); - std::vector<std::thread> threads; - threads.reserve(10); - for (int i = 0; i < 10; ++i) { - threads.emplace_back(SendRpc, stub_.get(), 10, false); - } - for (int i = 0; i < 10; ++i) { - threads[i].join(); - } -} - -// Set a 10us deadline and make sure proper error is returned. -TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - request.mutable_param()->set_skip_cancelled_check(true); - // Let server sleep for 40 ms first to guarantee expiry. - // 40 ms might seem a bit extreme but the timer manager would have been just - // initialized (when ResetStub() was called) and there are some warmup costs - // i.e the timer thread many not have even started. There might also be other - // delays in the timer manager thread (in acquiring locks, timer data - // structure manipulations, starting backup timer threads) that add to the - // delays. 40ms is still not enough in some cases but this significantly - // reduces the test flakes - request.mutable_param()->set_server_sleep_us(40 * 1000); - - ClientContext context; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::milliseconds(1); - context.set_deadline(deadline); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code()); -} - -// Set a long but finite deadline. -TEST_P(ProxyEnd2endTest, RpcLongDeadline) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::hours(1); - context.set_deadline(deadline); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); -} - -// Ask server to echo back the deadline it sees. -TEST_P(ProxyEnd2endTest, EchoDeadline) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - request.mutable_param()->set_echo_deadline(true); - - ClientContext context; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::seconds(100); - context.set_deadline(deadline); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - gpr_timespec sent_deadline; - Timepoint2Timespec(deadline, &sent_deadline); - // We want to allow some reasonable error given: - // - request_deadline() only has 1sec resolution so the best we can do is +-1 - // - if sent_deadline.tv_nsec is very close to the next second's boundary we - // can end up being off by 2 in one direction. - EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 2); - EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1); -} - -// Ask server to echo back the deadline it sees. The rpc has no deadline. -TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - request.mutable_param()->set_echo_deadline(true); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(response.param().request_deadline(), - gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec); -} - -TEST_P(ProxyEnd2endTest, UnimplementedRpc) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - Status s = stub_->Unimplemented(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED); - EXPECT_EQ(s.error_message(), ""); - EXPECT_EQ(response.message(), ""); -} - -// Client cancels rpc after 10ms -TEST_P(ProxyEnd2endTest, ClientCancelsRpc) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - const int kCancelDelayUs = 10 * 1000; - request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs); - - ClientContext context; - std::thread cancel_thread; - if (!GetParam().callback_server) { - cancel_thread = std::thread( - [&context, this](int delay) { CancelRpc(&context, delay, &service_); }, - kCancelDelayUs); - // Note: the unusual pattern above (and below) is caused by a conflict - // between two sets of compiler expectations. clang allows const to be - // captured without mention, so there is no need to capture kCancelDelayUs - // (and indeed clang-tidy complains if you do so). OTOH, a Windows compiler - // in our tests requires an explicit capture even for const. We square this - // circle by passing the const value in as an argument to the lambda. - } else { - cancel_thread = std::thread( - [&context, this](int delay) { - CancelRpc(&context, delay, &callback_service_); - }, - kCancelDelayUs); - } - Status s = stub_->Echo(&context, request, &response); - cancel_thread.join(); - EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); - EXPECT_EQ(s.error_message(), "CANCELLED"); -} - -// Server cancels rpc after 1ms -TEST_P(ProxyEnd2endTest, ServerCancelsRpc) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - request.mutable_param()->set_server_cancel_after_us(1000); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); - EXPECT_TRUE(s.error_message().empty()); -} - -// Make the response larger than the flow control window. -TEST_P(ProxyEnd2endTest, HugeResponse) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("huge response"); - const size_t kResponseSize = 1024 * (1024 + 10); - request.mutable_param()->set_response_message_length(kResponseSize); - - ClientContext context; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::seconds(20); - context.set_deadline(deadline); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(kResponseSize, response.message().size()); - EXPECT_TRUE(s.ok()); -} - -TEST_P(ProxyEnd2endTest, Peer) { - // Peer is not meaningful for inproc - if (GetParam().inproc) { - return; - } - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("hello"); - request.mutable_param()->set_echo_peer(true); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - EXPECT_TRUE(CheckIsLocalhost(response.param().peer())); - EXPECT_TRUE(CheckIsLocalhost(context.peer())); -} - -////////////////////////////////////////////////////////////////////////// -class SecureEnd2endTest : public End2endTest { - protected: - SecureEnd2endTest() { - GPR_ASSERT(!GetParam().use_proxy); - GPR_ASSERT(GetParam().credentials_type != kInsecureCredentialsType); - } -}; - -TEST_P(SecureEnd2endTest, SimpleRpcWithHost) { - ResetStub(); - - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - context.set_authority("foo.test.youtube.com"); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(response.has_param()); - EXPECT_EQ("special", response.param().host()); - EXPECT_TRUE(s.ok()); -} - -bool MetadataContains( - const std::multimap<grpc::string_ref, grpc::string_ref>& metadata, - const TString& key, const TString& value) { - int count = 0; - - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter = - metadata.begin(); - iter != metadata.end(); ++iter) { - if (ToString(iter->first) == key && ToString(iter->second) == value) { - count++; - } - } - return count == 1; -} - -TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) { - auto* processor = new TestAuthMetadataProcessor(true); - StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(processor->GetCompatibleClientCreds()); - request.set_message("Hello"); - request.mutable_param()->set_echo_metadata(true); - request.mutable_param()->set_expected_client_identity( - TestAuthMetadataProcessor::kGoodGuy); - request.mutable_param()->set_expected_transport_security_type( - GetParam().credentials_type); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(request.message(), response.message()); - EXPECT_TRUE(s.ok()); - - // Metadata should have been consumed by the processor. - EXPECT_FALSE(MetadataContains( - context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY, - TString("Bearer ") + TestAuthMetadataProcessor::kGoodGuy)); -} - -TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) { - auto* processor = new TestAuthMetadataProcessor(true); - StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(processor->GetIncompatibleClientCreds()); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); -} - -TEST_P(SecureEnd2endTest, SetPerCallCredentials) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - std::shared_ptr<CallCredentials> creds = - GoogleIAMCredentials(kFakeToken, kFakeSelector); - context.set_credentials(creds); - request.set_message("Hello"); - request.mutable_param()->set_echo_metadata(true); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(request.message(), response.message()); - EXPECT_TRUE(s.ok()); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, - kFakeToken)); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, - kFakeSelector)); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedFakeCredsDebugString); -} - -class CredentialsInterceptor : public experimental::Interceptor { - public: - explicit CredentialsInterceptor(experimental::ClientRpcInfo* info) - : info_(info) {} - - void Intercept(experimental::InterceptorBatchMethods* methods) override { - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { - std::shared_ptr<CallCredentials> creds = - GoogleIAMCredentials(kFakeToken, kFakeSelector); - info_->client_context()->set_credentials(creds); - } - methods->Proceed(); - } - - private: - experimental::ClientRpcInfo* info_ = nullptr; -}; - -class CredentialsInterceptorFactory - : public experimental::ClientInterceptorFactoryInterface { - CredentialsInterceptor* CreateClientInterceptor( - experimental::ClientRpcInfo* info) override { - return new CredentialsInterceptor(info); - } -}; - -TEST_P(SecureEnd2endTest, CallCredentialsInterception) { - if (!GetParam().use_interceptors) { - return; - } - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators; - interceptor_creators.push_back( - y_absl::make_unique<CredentialsInterceptorFactory>()); - ResetStub(std::move(interceptor_creators)); - EchoRequest request; - EchoResponse response; - ClientContext context; - - request.set_message("Hello"); - request.mutable_param()->set_echo_metadata(true); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(request.message(), response.message()); - EXPECT_TRUE(s.ok()); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, - kFakeToken)); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, - kFakeSelector)); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedFakeCredsDebugString); -} - -TEST_P(SecureEnd2endTest, CallCredentialsInterceptionWithSetCredentials) { - if (!GetParam().use_interceptors) { - return; - } - std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators; - interceptor_creators.push_back( - y_absl::make_unique<CredentialsInterceptorFactory>()); - ResetStub(std::move(interceptor_creators)); - EchoRequest request; - EchoResponse response; - ClientContext context; - std::shared_ptr<CallCredentials> creds1 = - GoogleIAMCredentials(kWrongToken, kWrongSelector); - context.set_credentials(creds1); - EXPECT_EQ(context.credentials(), creds1); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedWrongCredsDebugString); - request.set_message("Hello"); - request.mutable_param()->set_echo_metadata(true); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(request.message(), response.message()); - EXPECT_TRUE(s.ok()); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, - kFakeToken)); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, - kFakeSelector)); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedFakeCredsDebugString); -} - -TEST_P(SecureEnd2endTest, OverridePerCallCredentials) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - std::shared_ptr<CallCredentials> creds1 = - GoogleIAMCredentials(kFakeToken1, kFakeSelector1); - context.set_credentials(creds1); - EXPECT_EQ(context.credentials(), creds1); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedFakeCreds1DebugString); - std::shared_ptr<CallCredentials> creds2 = - GoogleIAMCredentials(kFakeToken2, kFakeSelector2); - context.set_credentials(creds2); - EXPECT_EQ(context.credentials(), creds2); - request.set_message("Hello"); - request.mutable_param()->set_echo_metadata(true); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, - kFakeToken2)); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, - kFakeSelector2)); - EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, - kFakeToken1)); - EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(), - GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, - kFakeSelector1)); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedFakeCreds2DebugString); - EXPECT_EQ(request.message(), response.message()); - EXPECT_TRUE(s.ok()); -} - -TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin( - TestMetadataCredentialsPlugin::kBadMetadataKey, - "Does not matter, will fail the key is invalid.", false, true, - 0)))); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedAuthMetadataPluginKeyFailureCredsDebugString); -} - -TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin( - TestMetadataCredentialsPlugin::kGoodMetadataKey, - "With illegal \n value.", false, true, 0)))); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedAuthMetadataPluginValueFailureCredsDebugString); -} - -TEST_P(SecureEnd2endTest, AuthMetadataPluginWithDeadline) { - ResetStub(); - EchoRequest request; - request.mutable_param()->set_skip_cancelled_check(true); - EchoResponse response; - ClientContext context; - const int delay = 100; - std::chrono::system_clock::time_point deadline = - std::chrono::system_clock::now() + std::chrono::milliseconds(delay); - context.set_deadline(deadline); - context.set_credentials(grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin("meta_key", "Does not matter", true, - true, delay)))); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - if (!s.ok()) { - EXPECT_TRUE(s.error_code() == StatusCode::DEADLINE_EXCEEDED || - s.error_code() == StatusCode::UNAVAILABLE); - } - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedAuthMetadataPluginWithDeadlineCredsDebugString); -} - -TEST_P(SecureEnd2endTest, AuthMetadataPluginWithCancel) { - ResetStub(); - EchoRequest request; - request.mutable_param()->set_skip_cancelled_check(true); - EchoResponse response; - ClientContext context; - const int delay = 100; - context.set_credentials(grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin("meta_key", "Does not matter", true, - true, delay)))); - request.set_message("Hello"); - - std::thread cancel_thread([&] { - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(delay, GPR_TIMESPAN))); - context.TryCancel(); - }); - Status s = stub_->Echo(&context, request, &response); - if (!s.ok()) { - EXPECT_TRUE(s.error_code() == StatusCode::CANCELLED || - s.error_code() == StatusCode::UNAVAILABLE); - } - cancel_thread.join(); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedAuthMetadataPluginWithDeadlineCredsDebugString); -} - -TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin( - TestMetadataCredentialsPlugin::kGoodMetadataKey, - "Does not matter, will fail anyway (see 3rd param)", false, false, - 0)))); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); - EXPECT_EQ(s.error_message(), - TString("Getting metadata from plugin failed with error: ") + - kTestCredsPluginErrorMsg); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedNonBlockingAuthMetadataPluginFailureCredsDebugString); -} - -TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) { - auto* processor = new TestAuthMetadataProcessor(false); - StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(processor->GetCompatibleClientCreds()); - request.set_message("Hello"); - request.mutable_param()->set_echo_metadata(true); - request.mutable_param()->set_expected_client_identity( - TestAuthMetadataProcessor::kGoodGuy); - request.mutable_param()->set_expected_transport_security_type( - GetParam().credentials_type); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(request.message(), response.message()); - EXPECT_TRUE(s.ok()); - - // Metadata should have been consumed by the processor. - EXPECT_FALSE(MetadataContains( - context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY, - TString("Bearer ") + TestAuthMetadataProcessor::kGoodGuy)); - EXPECT_EQ( - context.credentials()->DebugString(), - kExpectedNonBlockingAuthMetadataPluginAndProcessorSuccessCredsDebugString); -} - -TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) { - auto* processor = new TestAuthMetadataProcessor(false); - StartServer(std::shared_ptr<AuthMetadataProcessor>(processor)); - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(processor->GetIncompatibleClientCreds()); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); - EXPECT_EQ( - context.credentials()->DebugString(), - kExpectedNonBlockingAuthMetadataPluginAndProcessorFailureCredsDebugString); -} - -TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_credentials(grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin( - TestMetadataCredentialsPlugin::kGoodMetadataKey, - "Does not matter, will fail anyway (see 3rd param)", true, false, - 0)))); - request.set_message("Hello"); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); - EXPECT_EQ(s.error_message(), - TString("Getting metadata from plugin failed with error: ") + - kTestCredsPluginErrorMsg); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedBlockingAuthMetadataPluginFailureCredsDebugString); -} - -TEST_P(SecureEnd2endTest, CompositeCallCreds) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - const char kMetadataKey1[] = "call-creds-key1"; - const char kMetadataKey2[] = "call-creds-key2"; - const char kMetadataVal1[] = "call-creds-val1"; - const char kMetadataVal2[] = "call-creds-val2"; - - context.set_credentials(grpc::CompositeCallCredentials( - grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, - true, true, 0))), - grpc::MetadataCredentialsFromPlugin( - std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, - true, true, 0))))); - request.set_message("Hello"); - request.mutable_param()->set_echo_metadata(true); - - Status s = stub_->Echo(&context, request, &response); - EXPECT_TRUE(s.ok()); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - kMetadataKey1, kMetadataVal1)); - EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), - kMetadataKey2, kMetadataVal2)); - EXPECT_EQ(context.credentials()->DebugString(), - kExpectedCompositeCallCredsDebugString); -} - -TEST_P(SecureEnd2endTest, ClientAuthContext) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - request.mutable_param()->set_check_auth_context(GetParam().credentials_type == - kTlsCredentialsType); - request.mutable_param()->set_expected_transport_security_type( - GetParam().credentials_type); - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - - std::shared_ptr<const AuthContext> auth_ctx = context.auth_context(); - std::vector<grpc::string_ref> tst = - auth_ctx->FindPropertyValues("transport_security_type"); - ASSERT_EQ(1u, tst.size()); - EXPECT_EQ(GetParam().credentials_type, ToString(tst[0])); - if (GetParam().credentials_type == kTlsCredentialsType) { - EXPECT_EQ("x509_subject_alternative_name", - auth_ctx->GetPeerIdentityPropertyName()); - EXPECT_EQ(4u, auth_ctx->GetPeerIdentity().size()); - EXPECT_EQ("*.test.google.fr", ToString(auth_ctx->GetPeerIdentity()[0])); - EXPECT_EQ("waterzooi.test.google.be", - ToString(auth_ctx->GetPeerIdentity()[1])); - EXPECT_EQ("*.test.youtube.com", ToString(auth_ctx->GetPeerIdentity()[2])); - EXPECT_EQ("192.168.1.3", ToString(auth_ctx->GetPeerIdentity()[3])); - } -} - -class ResourceQuotaEnd2endTest : public End2endTest { - public: - ResourceQuotaEnd2endTest() - : server_resource_quota_("server_resource_quota") {} - - void ConfigureServerBuilder(ServerBuilder* builder) override { - builder->SetResourceQuota(server_resource_quota_); - } - - private: - ResourceQuota server_resource_quota_; -}; - -TEST_P(ResourceQuotaEnd2endTest, SimpleRequest) { - ResetStub(); - - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); -} - -// TODO(vjpai): refactor arguments into a struct if it makes sense -std::vector<TestScenario> CreateTestScenarios(bool use_proxy, - bool test_insecure, - bool test_secure, - bool test_inproc, - bool test_callback_server) { - std::vector<TestScenario> scenarios; - std::vector<TString> credentials_types; - - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, - kClientChannelBackupPollIntervalMs); -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - - if (test_secure) { - credentials_types = - GetCredentialsProvider()->GetSecureCredentialsTypeList(); - } - auto insec_ok = [] { - // Only allow insecure credentials type when it is registered with the - // provider. User may create providers that do not have insecure. - return GetCredentialsProvider()->GetChannelCredentials( - kInsecureCredentialsType, nullptr) != nullptr; - }; - if (test_insecure && insec_ok()) { - credentials_types.push_back(kInsecureCredentialsType); - } - - // Test callback with inproc or if the event-engine allows it - GPR_ASSERT(!credentials_types.empty()); - for (const auto& cred : credentials_types) { - scenarios.emplace_back(false, false, false, cred, false); - scenarios.emplace_back(true, false, false, cred, false); - if (test_callback_server) { - // Note that these scenarios will be dynamically disabled if the event - // engine doesn't run in the background - scenarios.emplace_back(false, false, false, cred, true); - scenarios.emplace_back(true, false, false, cred, true); - } - if (use_proxy) { - scenarios.emplace_back(false, true, false, cred, false); - scenarios.emplace_back(true, true, false, cred, false); - } - } - if (test_inproc && insec_ok()) { - scenarios.emplace_back(false, false, true, kInsecureCredentialsType, false); - scenarios.emplace_back(true, false, true, kInsecureCredentialsType, false); - if (test_callback_server) { - scenarios.emplace_back(false, false, true, kInsecureCredentialsType, - true); - scenarios.emplace_back(true, false, true, kInsecureCredentialsType, true); - } - } - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P( - End2end, End2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); - -INSTANTIATE_TEST_SUITE_P( - End2endServerTryCancel, End2endServerTryCancelTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); - -INSTANTIATE_TEST_SUITE_P( - ProxyEnd2end, ProxyEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(true, true, true, true, true))); - -INSTANTIATE_TEST_SUITE_P( - SecureEnd2end, SecureEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, false, true, false, true))); - -INSTANTIATE_TEST_SUITE_P( - ResourceQuotaEnd2end, ResourceQuotaEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/exception_test.cc b/contrib/libs/grpc/test/cpp/end2end/exception_test.cc deleted file mode 100644 index 1a4c418bed..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/exception_test.cc +++ /dev/null @@ -1,124 +0,0 @@ -/* - * - * Copyright 2017 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 <grpc/impl/codegen/port_platform.h> - -#include <exception> -#include <memory> - -#include <gtest/gtest.h> - -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/test_config.h" - -namespace grpc { -namespace testing { - -const char* kErrorMessage = "This service caused an exception"; - -#if GRPC_ALLOW_EXCEPTIONS -class ExceptingServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - Status Echo(ServerContext* /*server_context*/, const EchoRequest* /*request*/, - EchoResponse* /*response*/) override { - throw -1; - } - Status RequestStream(ServerContext* /*context*/, - ServerReader<EchoRequest>* /*reader*/, - EchoResponse* /*response*/) override { - throw ServiceException(); - } - - private: - class ServiceException final : public std::exception { - public: - ServiceException() {} - - private: - const char* what() const noexcept override { return kErrorMessage; } - }; -}; - -class ExceptionTest : public ::testing::Test { - protected: - ExceptionTest() {} - - void SetUp() override { - ServerBuilder builder; - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - void TearDown() override { server_->Shutdown(); } - - void ResetStub() { - channel_ = server_->InProcessChannel(ChannelArguments()); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - ExceptingServiceImpl service_; -}; - -TEST_F(ExceptionTest, Unary) { - ResetStub(); - EchoRequest request; - EchoResponse response; - request.set_message("test"); - - for (int i = 0; i < 10; i++) { - ClientContext context; - Status s = stub_->Echo(&context, request, &response); - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNKNOWN); - } -} - -TEST_F(ExceptionTest, RequestStream) { - ResetStub(); - EchoResponse response; - - for (int i = 0; i < 10; i++) { - ClientContext context; - auto stream = stub_->RequestStream(&context, &response); - stream->WritesDone(); - Status s = stream->Finish(); - - EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNKNOWN); - } -} - -#endif // GRPC_ALLOW_EXCEPTIONS - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/filter_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/filter_end2end_test.cc deleted file mode 100644 index 839d6d17d0..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/filter_end2end_test.cc +++ /dev/null @@ -1,347 +0,0 @@ -/* - * - * Copyright 2016 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 <memory> -#include <mutex> -#include <thread> - -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/generic/async_generic_service.h> -#include <grpcpp/generic/generic_stub.h> -#include <grpcpp/impl/codegen/proto_utils.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/config.h> -#include <grpcpp/support/slice.h> - -#include "src/cpp/common/channel_filter.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/byte_buffer_proto_helper.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { -namespace { - -void* tag(int i) { return reinterpret_cast<void*>(i); } - -void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { - bool ok; - void* got_tag; - EXPECT_TRUE(cq->Next(&got_tag, &ok)); - EXPECT_EQ(expect_ok, ok); - EXPECT_EQ(tag(i), got_tag); -} - -namespace { - -int global_num_connections = 0; -int global_num_calls = 0; -std::mutex global_mu; - -void IncrementConnectionCounter() { - std::unique_lock<std::mutex> lock(global_mu); - ++global_num_connections; -} - -void ResetConnectionCounter() { - std::unique_lock<std::mutex> lock(global_mu); - global_num_connections = 0; -} - -int GetConnectionCounterValue() { - std::unique_lock<std::mutex> lock(global_mu); - return global_num_connections; -} - -void IncrementCallCounter() { - std::unique_lock<std::mutex> lock(global_mu); - ++global_num_calls; -} - -void ResetCallCounter() { - std::unique_lock<std::mutex> lock(global_mu); - global_num_calls = 0; -} - -int GetCallCounterValue() { - std::unique_lock<std::mutex> lock(global_mu); - return global_num_calls; -} - -} // namespace - -class ChannelDataImpl : public ChannelData { - public: - grpc_error_handle Init(grpc_channel_element* /*elem*/, - grpc_channel_element_args* /*args*/) override { - IncrementConnectionCounter(); - return GRPC_ERROR_NONE; - } -}; - -class CallDataImpl : public CallData { - public: - void StartTransportStreamOpBatch(grpc_call_element* elem, - TransportStreamOpBatch* op) override { - // Incrementing the counter could be done from Init(), but we want - // to test that the individual methods are actually called correctly. - if (op->recv_initial_metadata() != nullptr) IncrementCallCounter(); - grpc_call_next_op(elem, op->op()); - } -}; - -class FilterEnd2endTest : public ::testing::Test { - protected: - FilterEnd2endTest() : server_host_("localhost") {} - - static void SetUpTestCase() { - // Workaround for - // https://github.com/google/google-toolbox-for-mac/issues/242 - static bool setup_done = false; - if (!setup_done) { - setup_done = true; - grpc::RegisterChannelFilter<ChannelDataImpl, CallDataImpl>( - "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); - } - } - - void SetUp() override { - int port = grpc_pick_unused_port_or_die(); - server_address_ << server_host_ << ":" << port; - // Setup server - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - InsecureServerCredentials()); - builder.RegisterAsyncGenericService(&generic_service_); - srv_cq_ = builder.AddCompletionQueue(); - server_ = builder.BuildAndStart(); - } - - void TearDown() override { - server_->Shutdown(); - void* ignored_tag; - bool ignored_ok; - cli_cq_.Shutdown(); - srv_cq_->Shutdown(); - while (cli_cq_.Next(&ignored_tag, &ignored_ok)) { - } - while (srv_cq_->Next(&ignored_tag, &ignored_ok)) { - } - } - - void ResetStub() { - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), InsecureChannelCredentials()); - generic_stub_ = y_absl::make_unique<GenericStub>(channel); - ResetConnectionCounter(); - ResetCallCounter(); - } - - void server_ok(int i) { verify_ok(srv_cq_.get(), i, true); } - void client_ok(int i) { verify_ok(&cli_cq_, i, true); } - void server_fail(int i) { verify_ok(srv_cq_.get(), i, false); } - void client_fail(int i) { verify_ok(&cli_cq_, i, false); } - - void SendRpc(int num_rpcs) { - const TString kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); - for (int i = 0; i < num_rpcs; i++) { - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - GenericServerContext srv_ctx; - GenericServerAsyncReaderWriter stream(&srv_ctx); - - // The string needs to be long enough to test heap-based slice. - send_request.set_message("Hello world. Hello world. Hello world."); - std::thread request_call([this]() { server_ok(4); }); - std::unique_ptr<GenericClientAsyncReaderWriter> call = - generic_stub_->PrepareCall(&cli_ctx, kMethodName, &cli_cq_); - call->StartCall(tag(1)); - client_ok(1); - std::unique_ptr<ByteBuffer> send_buffer = - SerializeToByteBuffer(&send_request); - call->Write(*send_buffer, tag(2)); - // Send ByteBuffer can be destroyed after calling Write. - send_buffer.reset(); - client_ok(2); - call->WritesDone(tag(3)); - client_ok(3); - - generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), - srv_cq_.get(), tag(4)); - - request_call.join(); - EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); - EXPECT_EQ(kMethodName, srv_ctx.method()); - ByteBuffer recv_buffer; - stream.Read(&recv_buffer, tag(5)); - server_ok(5); - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - send_buffer = SerializeToByteBuffer(&send_response); - stream.Write(*send_buffer, tag(6)); - send_buffer.reset(); - server_ok(6); - - stream.Finish(Status::OK, tag(7)); - server_ok(7); - - recv_buffer.Clear(); - call->Read(&recv_buffer, tag(8)); - client_ok(8); - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); - - call->Finish(&recv_status, tag(9)); - client_ok(9); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } - } - - CompletionQueue cli_cq_; - std::unique_ptr<ServerCompletionQueue> srv_cq_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<grpc::GenericStub> generic_stub_; - std::unique_ptr<Server> server_; - AsyncGenericService generic_service_; - const TString server_host_; - std::ostringstream server_address_; -}; - -TEST_F(FilterEnd2endTest, SimpleRpc) { - ResetStub(); - EXPECT_EQ(0, GetConnectionCounterValue()); - EXPECT_EQ(0, GetCallCounterValue()); - SendRpc(1); - EXPECT_EQ(1, GetConnectionCounterValue()); - EXPECT_EQ(1, GetCallCounterValue()); -} - -TEST_F(FilterEnd2endTest, SequentialRpcs) { - ResetStub(); - EXPECT_EQ(0, GetConnectionCounterValue()); - EXPECT_EQ(0, GetCallCounterValue()); - SendRpc(10); - EXPECT_EQ(1, GetConnectionCounterValue()); - EXPECT_EQ(10, GetCallCounterValue()); -} - -// One ping, one pong. -TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { - ResetStub(); - EXPECT_EQ(0, GetConnectionCounterValue()); - EXPECT_EQ(0, GetCallCounterValue()); - - const TString kMethodName( - "/grpc.cpp.test.util.EchoTestService/BidiStream"); - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - GenericServerContext srv_ctx; - GenericServerAsyncReaderWriter srv_stream(&srv_ctx); - - cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); - send_request.set_message("Hello"); - std::thread request_call([this]() { server_ok(2); }); - std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream = - generic_stub_->PrepareCall(&cli_ctx, kMethodName, &cli_cq_); - cli_stream->StartCall(tag(1)); - client_ok(1); - - generic_service_.RequestCall(&srv_ctx, &srv_stream, srv_cq_.get(), - srv_cq_.get(), tag(2)); - - request_call.join(); - EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); - EXPECT_EQ(kMethodName, srv_ctx.method()); - - std::unique_ptr<ByteBuffer> send_buffer = - SerializeToByteBuffer(&send_request); - cli_stream->Write(*send_buffer, tag(3)); - send_buffer.reset(); - client_ok(3); - - ByteBuffer recv_buffer; - srv_stream.Read(&recv_buffer, tag(4)); - server_ok(4); - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - send_buffer = SerializeToByteBuffer(&send_response); - srv_stream.Write(*send_buffer, tag(5)); - send_buffer.reset(); - server_ok(5); - - cli_stream->Read(&recv_buffer, tag(6)); - client_ok(6); - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); - EXPECT_EQ(send_response.message(), recv_response.message()); - - cli_stream->WritesDone(tag(7)); - client_ok(7); - - srv_stream.Read(&recv_buffer, tag(8)); - server_fail(8); - - srv_stream.Finish(Status::OK, tag(9)); - server_ok(9); - - cli_stream->Finish(&recv_status, tag(10)); - client_ok(10); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - - EXPECT_EQ(1, GetCallCounterValue()); - EXPECT_EQ(1, GetConnectionCounterValue()); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/flaky_network_test.cc b/contrib/libs/grpc/test/cpp/end2end/flaky_network_test.cc deleted file mode 100644 index 70d5b8f0a8..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/flaky_network_test.cc +++ /dev/null @@ -1,552 +0,0 @@ -/* - * - * Copyright 2019 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 <grpc/support/port_platform.h> - -#include <algorithm> -#include <condition_variable> -#include <memory> -#include <mutex> -#include <random> -#include <thread> - -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/health_check_service_interface.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> - -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/gpr/env.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_credentials_provider.h" - -#ifdef GPR_LINUX -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { -namespace { - -struct TestScenario { - TestScenario(const TString& creds_type, const TString& content) - : credentials_type(creds_type), message_content(content) {} - const TString credentials_type; - const TString message_content; -}; - -class FlakyNetworkTest : public ::testing::TestWithParam<TestScenario> { - protected: - FlakyNetworkTest() - : server_host_("grpctest"), - interface_("lo:1"), - ipv4_address_("10.0.0.1"), - netmask_("/32") {} - - void InterfaceUp() { - std::ostringstream cmd; - // create interface_ with address ipv4_address_ - cmd << "ip addr add " << ipv4_address_ << netmask_ << " dev " << interface_; - std::system(cmd.str().c_str()); - } - - void InterfaceDown() { - std::ostringstream cmd; - // remove interface_ - cmd << "ip addr del " << ipv4_address_ << netmask_ << " dev " << interface_; - std::system(cmd.str().c_str()); - } - - void DNSUp() { - std::ostringstream cmd; - // Add DNS entry for server_host_ in /etc/hosts - cmd << "echo '" << ipv4_address_ << " " << server_host_ - << "' >> /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DNSDown() { - std::ostringstream cmd; - // Remove DNS entry for server_host_ from /etc/hosts - // NOTE: we can't do this in one step with sed -i because when we are - // running under docker, the file is mounted by docker so we can't change - // its inode from within the container (sed -i creates a new file and - // replaces the old file, which changes the inode) - cmd << "sed '/" << server_host_ << "/d' /etc/hosts > /etc/hosts.orig"; - std::system(cmd.str().c_str()); - - // clear the stream - cmd.str(""); - - cmd << "cat /etc/hosts.orig > /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DropPackets() { - std::ostringstream cmd; - // drop packets with src IP = ipv4_address_ - cmd << "iptables -A INPUT -s " << ipv4_address_ << " -j DROP"; - - std::system(cmd.str().c_str()); - // clear the stream - cmd.str(""); - - // drop packets with dst IP = ipv4_address_ - cmd << "iptables -A INPUT -d " << ipv4_address_ << " -j DROP"; - } - - void RestoreNetwork() { - std::ostringstream cmd; - // remove iptables rule to drop packets with src IP = ipv4_address_ - cmd << "iptables -D INPUT -s " << ipv4_address_ << " -j DROP"; - std::system(cmd.str().c_str()); - // clear the stream - cmd.str(""); - // remove iptables rule to drop packets with dest IP = ipv4_address_ - cmd << "iptables -D INPUT -d " << ipv4_address_ << " -j DROP"; - } - - void FlakeNetwork() { - std::ostringstream cmd; - // Emulate a flaky network connection over interface_. Add a delay of 100ms - // +/- 20ms, 0.1% packet loss, 1% duplicates and 0.01% corrupt packets. - cmd << "tc qdisc replace dev " << interface_ - << " root netem delay 100ms 20ms distribution normal loss 0.1% " - "duplicate " - "0.1% corrupt 0.01% "; - std::system(cmd.str().c_str()); - } - - void UnflakeNetwork() { - // Remove simulated network flake on interface_ - std::ostringstream cmd; - cmd << "tc qdisc del dev " << interface_ << " root netem"; - std::system(cmd.str().c_str()); - } - - void NetworkUp() { - InterfaceUp(); - DNSUp(); - } - - void NetworkDown() { - InterfaceDown(); - DNSDown(); - } - - void SetUp() override { - NetworkUp(); - grpc_init(); - StartServer(); - } - - void TearDown() override { - NetworkDown(); - StopServer(); - grpc_shutdown(); - } - - void StartServer() { - // TODO (pjaikumar): Ideally, we should allocate the port dynamically using - // grpc_pick_unused_port_or_die(). That doesn't work inside some docker - // containers because port_server listens on localhost which maps to - // ip6-looopback, but ipv6 support is not enabled by default in docker. - port_ = SERVER_PORT; - - server_ = y_absl::make_unique<ServerData>(port_, GetParam().credentials_type); - server_->Start(server_host_); - } - void StopServer() { server_->Shutdown(); } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( - const std::shared_ptr<Channel>& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr<Channel> BuildChannel( - const TString& lb_policy_name, - ChannelArguments args = ChannelArguments()) { - if (!lb_policy_name.empty()) { - args.SetLoadBalancingPolicyName(lb_policy_name); - } // else, default to pick first - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - std::ostringstream server_address; - server_address << server_host_ << ":" << port_; - return CreateCustomChannel(server_address.str(), channel_creds, args); - } - - bool SendRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - int timeout_ms = 0, bool wait_for_ready = false) { - auto response = y_absl::make_unique<EchoResponse>(); - EchoRequest request; - auto& msg = GetParam().message_content; - request.set_message(msg); - ClientContext context; - if (timeout_ms > 0) { - context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); - // Allow an RPC to be canceled (for deadline exceeded) after it has - // reached the server. - request.mutable_param()->set_skip_cancelled_check(true); - } - // See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md for - // details of wait-for-ready semantics - if (wait_for_ready) { - context.set_wait_for_ready(true); - } - Status status = stub->Echo(&context, request, response.get()); - auto ok = status.ok(); - if (ok) { - gpr_log(GPR_DEBUG, "RPC succeeded"); - } else { - gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); - } - return ok; - } - - struct ServerData { - int port_; - const TString creds_; - std::unique_ptr<Server> server_; - TestServiceImpl service_; - std::unique_ptr<std::thread> thread_; - bool server_ready_ = false; - - ServerData(int port, const TString& creds) - : port_(port), creds_(creds) {} - - void Start(const TString& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - std::mutex mu; - std::unique_lock<std::mutex> lock(mu); - std::condition_variable cond; - thread_ = y_absl::make_unique<std::thread>( - std::bind(&ServerData::Serve, this, server_host, &mu, &cond)); - cond.wait(lock, [this] { return server_ready_; }); - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - - void Serve(const TString& server_host, std::mutex* mu, - std::condition_variable* cond) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - auto server_creds = - GetCredentialsProvider()->GetServerCredentials(creds_); - builder.AddListeningPort(server_address.str(), server_creds); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - std::lock_guard<std::mutex> lock(*mu); - server_ready_ = true; - cond->notify_one(); - } - - void Shutdown() { - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - thread_->join(); - } - }; - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(false /* try_to_connect */)) == - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(true /* try_to_connect */)) != - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - private: - const TString server_host_; - const TString interface_; - const TString ipv4_address_; - const TString netmask_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<ServerData> server_; - const int SERVER_PORT = 32750; - int port_; -}; - -std::vector<TestScenario> CreateTestScenarios() { - std::vector<TestScenario> scenarios; - std::vector<TString> credentials_types; - std::vector<TString> messages; - - credentials_types.push_back(kInsecureCredentialsType); - auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); - for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { - credentials_types.push_back(*sec); - } - - messages.push_back("🖖"); - for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { - TString big_msg; - for (size_t i = 0; i < k * 1024; ++i) { - char c = 'a' + (i % 26); - big_msg += c; - } - messages.push_back(big_msg); - } - for (auto cred = credentials_types.begin(); cred != credentials_types.end(); - ++cred) { - for (auto msg = messages.begin(); msg != messages.end(); msg++) { - scenarios.emplace_back(*cred, *msg); - } - } - - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P(FlakyNetworkTest, FlakyNetworkTest, - ::testing::ValuesIn(CreateTestScenarios())); - -// Network interface connected to server flaps -TEST_P(FlakyNetworkTest, NetworkTransition) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // bring down network - NetworkDown(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - // bring network interface back up - InterfaceUp(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - // Restore DNS entry for server - DNSUp(); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); -} - -// Traffic to server server is blackholed temporarily with keepalives enabled -TEST_P(FlakyNetworkTest, ServerUnreachableWithKeepalive) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - const int kReconnectBackoffMs = 1000; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - // max time for a connection attempt - args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); - // max time between reconnect attempts - args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); - - gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive start"); - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // break network connectivity - gpr_log(GPR_DEBUG, "Adding iptables rule to drop packets"); - DropPackets(); - std::this_thread::sleep_for(std::chrono::milliseconds(10000)); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - // bring network interface back up - RestoreNetwork(); - gpr_log(GPR_DEBUG, "Removed iptables rule to drop packets"); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); - gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive end"); -} - -// -// Traffic to server server is blackholed temporarily with keepalives disabled -TEST_P(FlakyNetworkTest, ServerUnreachableNoKeepalive) { - auto channel = BuildChannel("pick_first", ChannelArguments()); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // break network connectivity - DropPackets(); - - std::thread sender = std::thread([this, &stub]() { - // RPC with deadline should timeout - EXPECT_FALSE(SendRpc(stub, /*timeout_ms=*/500, /*wait_for_ready=*/true)); - // RPC without deadline forever until call finishes - EXPECT_TRUE(SendRpc(stub, /*timeout_ms=*/0, /*wait_for_ready=*/true)); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - // bring network interface back up - RestoreNetwork(); - - // wait for RPC to finish - sender.join(); -} - -// Send RPCs over a flaky network connection -TEST_P(FlakyNetworkTest, FlakyNetwork) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - const int kMessageCount = 100; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // simulate flaky network (packet loss, corruption and delays) - FlakeNetwork(); - for (int i = 0; i < kMessageCount; ++i) { - SendRpc(stub); - } - // remove network flakiness - UnflakeNetwork(); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); -} - -// Server is shutdown gracefully and restarted. Client keepalives are enabled -TEST_P(FlakyNetworkTest, ServerRestartKeepaliveEnabled) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // server goes down, client should detect server going down and calls should - // fail - StopServer(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - EXPECT_FALSE(SendRpc(stub)); - - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - // server restarts, calls succeed - StartServer(); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - // EXPECT_TRUE(SendRpc(stub)); -} - -// Server is shutdown gracefully and restarted. Client keepalives are enabled -TEST_P(FlakyNetworkTest, ServerRestartKeepaliveDisabled) { - auto channel = BuildChannel("pick_first", ChannelArguments()); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // server sends GOAWAY when it's shutdown, so client attempts to reconnect - StopServer(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - // server restarts, calls succeed - StartServer(); - EXPECT_TRUE(WaitForChannelReady(channel.get())); -} - -} // namespace -} // namespace testing -} // namespace grpc -#endif // GPR_LINUX - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(argc, argv); - auto result = RUN_ALL_TESTS(); - return result; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/generic_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/generic_end2end_test.cc deleted file mode 100644 index dae816531e..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/generic_end2end_test.cc +++ /dev/null @@ -1,431 +0,0 @@ -/* - * - * Copyright 2015 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 <memory> -#include <thread> - -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/generic/async_generic_service.h> -#include <grpcpp/generic/generic_stub.h> -#include <grpcpp/impl/codegen/proto_utils.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/slice.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/byte_buffer_proto_helper.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { -namespace { - -void* tag(int i) { return reinterpret_cast<void*>(i); } - -void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { - bool ok; - void* got_tag; - EXPECT_TRUE(cq->Next(&got_tag, &ok)); - EXPECT_EQ(expect_ok, ok); - EXPECT_EQ(tag(i), got_tag); -} - -class GenericEnd2endTest : public ::testing::Test { - protected: - GenericEnd2endTest() : server_host_("localhost") {} - - void SetUp() override { - shut_down_ = false; - int port = grpc_pick_unused_port_or_die(); - server_address_ << server_host_ << ":" << port; - // Setup server - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - InsecureServerCredentials()); - builder.RegisterAsyncGenericService(&generic_service_); - // Include a second call to RegisterAsyncGenericService to make sure that - // we get an error in the log, since it is not allowed to have 2 async - // generic services - builder.RegisterAsyncGenericService(&generic_service_); - srv_cq_ = builder.AddCompletionQueue(); - server_ = builder.BuildAndStart(); - } - - void ShutDownServerAndCQs() { - if (!shut_down_) { - server_->Shutdown(); - void* ignored_tag; - bool ignored_ok; - cli_cq_.Shutdown(); - srv_cq_->Shutdown(); - while (cli_cq_.Next(&ignored_tag, &ignored_ok)) { - } - while (srv_cq_->Next(&ignored_tag, &ignored_ok)) { - } - shut_down_ = true; - } - } - void TearDown() override { ShutDownServerAndCQs(); } - - void ResetStub() { - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel); - generic_stub_ = y_absl::make_unique<GenericStub>(channel); - } - - void server_ok(int i) { verify_ok(srv_cq_.get(), i, true); } - void client_ok(int i) { verify_ok(&cli_cq_, i, true); } - void server_fail(int i) { verify_ok(srv_cq_.get(), i, false); } - void client_fail(int i) { verify_ok(&cli_cq_, i, false); } - - void SendRpc(int num_rpcs) { - SendRpc(num_rpcs, false, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - - void SendRpc(int num_rpcs, bool check_deadline, gpr_timespec deadline) { - const TString kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); - for (int i = 0; i < num_rpcs; i++) { - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - GenericServerContext srv_ctx; - GenericServerAsyncReaderWriter stream(&srv_ctx); - - // The string needs to be long enough to test heap-based slice. - send_request.set_message("Hello world. Hello world. Hello world."); - - if (check_deadline) { - cli_ctx.set_deadline(deadline); - } - - // Rather than using the original kMethodName, make a short-lived - // copy to also confirm that we don't refer to this object beyond - // the initial call preparation - const TString* method_name = new TString(kMethodName); - - std::unique_ptr<GenericClientAsyncReaderWriter> call = - generic_stub_->PrepareCall(&cli_ctx, *method_name, &cli_cq_); - - delete method_name; // Make sure that this is not needed after invocation - - std::thread request_call([this]() { server_ok(4); }); - call->StartCall(tag(1)); - client_ok(1); - std::unique_ptr<ByteBuffer> send_buffer = - SerializeToByteBuffer(&send_request); - call->Write(*send_buffer, tag(2)); - // Send ByteBuffer can be destroyed after calling Write. - send_buffer.reset(); - client_ok(2); - call->WritesDone(tag(3)); - client_ok(3); - - generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), - srv_cq_.get(), tag(4)); - - request_call.join(); - EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); - EXPECT_EQ(kMethodName, srv_ctx.method()); - - if (check_deadline) { - EXPECT_TRUE(gpr_time_similar(deadline, srv_ctx.raw_deadline(), - gpr_time_from_millis(1000, GPR_TIMESPAN))); - } - - ByteBuffer recv_buffer; - stream.Read(&recv_buffer, tag(5)); - server_ok(5); - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - send_buffer = SerializeToByteBuffer(&send_response); - stream.Write(*send_buffer, tag(6)); - send_buffer.reset(); - server_ok(6); - - stream.Finish(Status::OK, tag(7)); - server_ok(7); - - recv_buffer.Clear(); - call->Read(&recv_buffer, tag(8)); - client_ok(8); - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); - - call->Finish(&recv_status, tag(9)); - client_ok(9); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } - } - - // Return errors to up to one call that comes in on the supplied completion - // queue, until the CQ is being shut down (and therefore we can no longer - // enqueue further events). - void DriveCompletionQueue() { - enum class Event : uintptr_t { - kCallReceived, - kResponseSent, - }; - // Request the call, but only if the main thread hasn't beaten us to - // shutting down the CQ. - grpc::GenericServerContext server_context; - grpc::GenericServerAsyncReaderWriter reader_writer(&server_context); - - { - std::lock_guard<std::mutex> lock(shutting_down_mu_); - if (!shutting_down_) { - generic_service_.RequestCall( - &server_context, &reader_writer, srv_cq_.get(), srv_cq_.get(), - reinterpret_cast<void*>(Event::kCallReceived)); - } - } - // Process events. - { - Event event; - bool ok; - while (srv_cq_->Next(reinterpret_cast<void**>(&event), &ok)) { - std::lock_guard<std::mutex> lock(shutting_down_mu_); - if (shutting_down_) { - // The main thread has started shutting down. Simply continue to drain - // events. - continue; - } - - switch (event) { - case Event::kCallReceived: - reader_writer.Finish( - ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "go away"), - reinterpret_cast<void*>(Event::kResponseSent)); - break; - - case Event::kResponseSent: - // We are done. - break; - } - } - } - } - - CompletionQueue cli_cq_; - std::unique_ptr<ServerCompletionQueue> srv_cq_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<grpc::GenericStub> generic_stub_; - std::unique_ptr<Server> server_; - AsyncGenericService generic_service_; - const TString server_host_; - std::ostringstream server_address_; - bool shutting_down_; - bool shut_down_; - std::mutex shutting_down_mu_; -}; - -TEST_F(GenericEnd2endTest, SimpleRpc) { - ResetStub(); - SendRpc(1); -} - -TEST_F(GenericEnd2endTest, SequentialRpcs) { - ResetStub(); - SendRpc(10); -} - -TEST_F(GenericEnd2endTest, SequentialUnaryRpcs) { - ResetStub(); - const int num_rpcs = 10; - const TString kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); - for (int i = 0; i < num_rpcs; i++) { - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - GenericServerContext srv_ctx; - GenericServerAsyncReaderWriter stream(&srv_ctx); - - // The string needs to be long enough to test heap-based slice. - send_request.set_message("Hello world. Hello world. Hello world."); - - std::unique_ptr<ByteBuffer> cli_send_buffer = - SerializeToByteBuffer(&send_request); - std::thread request_call([this]() { server_ok(4); }); - std::unique_ptr<GenericClientAsyncResponseReader> call = - generic_stub_->PrepareUnaryCall(&cli_ctx, kMethodName, *cli_send_buffer, - &cli_cq_); - call->StartCall(); - ByteBuffer cli_recv_buffer; - call->Finish(&cli_recv_buffer, &recv_status, tag(1)); - std::thread client_check([this] { client_ok(1); }); - - generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), - srv_cq_.get(), tag(4)); - request_call.join(); - EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); - EXPECT_EQ(kMethodName, srv_ctx.method()); - - ByteBuffer srv_recv_buffer; - stream.Read(&srv_recv_buffer, tag(5)); - server_ok(5); - EXPECT_TRUE(ParseFromByteBuffer(&srv_recv_buffer, &recv_request)); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - std::unique_ptr<ByteBuffer> srv_send_buffer = - SerializeToByteBuffer(&send_response); - stream.Write(*srv_send_buffer, tag(6)); - server_ok(6); - - stream.Finish(Status::OK, tag(7)); - server_ok(7); - - client_check.join(); - EXPECT_TRUE(ParseFromByteBuffer(&cli_recv_buffer, &recv_response)); - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } -} - -// One ping, one pong. -TEST_F(GenericEnd2endTest, SimpleBidiStreaming) { - ResetStub(); - - const TString kMethodName( - "/grpc.cpp.test.util.EchoTestService/BidiStream"); - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - ClientContext cli_ctx; - GenericServerContext srv_ctx; - GenericServerAsyncReaderWriter srv_stream(&srv_ctx); - - cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); - send_request.set_message("Hello"); - std::thread request_call([this]() { server_ok(2); }); - std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream = - generic_stub_->PrepareCall(&cli_ctx, kMethodName, &cli_cq_); - cli_stream->StartCall(tag(1)); - client_ok(1); - - generic_service_.RequestCall(&srv_ctx, &srv_stream, srv_cq_.get(), - srv_cq_.get(), tag(2)); - request_call.join(); - - EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); - EXPECT_EQ(kMethodName, srv_ctx.method()); - - std::unique_ptr<ByteBuffer> send_buffer = - SerializeToByteBuffer(&send_request); - cli_stream->Write(*send_buffer, tag(3)); - send_buffer.reset(); - client_ok(3); - - ByteBuffer recv_buffer; - srv_stream.Read(&recv_buffer, tag(4)); - server_ok(4); - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - send_buffer = SerializeToByteBuffer(&send_response); - srv_stream.Write(*send_buffer, tag(5)); - send_buffer.reset(); - server_ok(5); - - cli_stream->Read(&recv_buffer, tag(6)); - client_ok(6); - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); - EXPECT_EQ(send_response.message(), recv_response.message()); - - cli_stream->WritesDone(tag(7)); - client_ok(7); - - srv_stream.Read(&recv_buffer, tag(8)); - server_fail(8); - - srv_stream.Finish(Status::OK, tag(9)); - server_ok(9); - - cli_stream->Finish(&recv_status, tag(10)); - client_ok(10); - - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); -} - -TEST_F(GenericEnd2endTest, Deadline) { - ResetStub(); - SendRpc(1, true, - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(10, GPR_TIMESPAN))); -} - -TEST_F(GenericEnd2endTest, ShortDeadline) { - ResetStub(); - - ClientContext cli_ctx; - EchoRequest request; - EchoResponse response; - - shutting_down_ = false; - std::thread driver([this] { DriveCompletionQueue(); }); - - request.set_message(""); - cli_ctx.set_deadline(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_micros(500, GPR_TIMESPAN))); - Status s = stub_->Echo(&cli_ctx, request, &response); - EXPECT_FALSE(s.ok()); - { - std::lock_guard<std::mutex> lock(shutting_down_mu_); - shutting_down_ = true; - } - ShutDownServerAndCQs(); - driver.join(); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/grpclb_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/grpclb_end2end_test.cc deleted file mode 100644 index 1f71145b66..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/grpclb_end2end_test.cc +++ /dev/null @@ -1,2038 +0,0 @@ -// -// Copyright 2017 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 <deque> -#include <memory> -#include <mutex> -#include <set> -#include <sstream> -#include <util/generic/string.h> -#include <thread> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" -#include "y_absl/strings/str_cat.h" -#include "y_absl/strings/str_format.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/impl/codegen/sync.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" -#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" -#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/service_config/service_config.h" -#include "src/core/lib/address_utils/parse_address.h" -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/client/secure_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" -#include "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/resolve_localhost_ip46.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/counted_service.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_config.h" - -// TODO(dgq): Other scenarios in need of testing: -// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc). -// - Test reception of invalid serverlist -// - Test against a non-LB server. -// - Random LB server closing the stream unexpectedly. -// -// Findings from end to end testing to be covered here: -// - Handling of LB servers restart, including reconnection after backing-off -// retries. -// - Destruction of load balanced channel (and therefore of grpclb instance) -// while: -// 1) the internal LB call is still active. This should work by virtue -// of the weak reference the LB call holds. The call should be terminated as -// part of the grpclb shutdown process. -// 2) the retry timer is active. Again, the weak reference it holds should -// prevent a premature call to \a glb_destroy. - -using std::chrono::system_clock; - -using grpc::lb::v1::LoadBalancer; -using grpc::lb::v1::LoadBalanceRequest; -using grpc::lb::v1::LoadBalanceResponse; - -namespace grpc { -namespace testing { -namespace { - -constexpr char kDefaultServiceConfig[] = - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{} }\n" - " ]\n" - "}"; - -using BackendService = CountedService<TestServiceImpl>; -using BalancerService = CountedService<LoadBalancer::Service>; - -const char g_kCallCredsMdKey[] = "Balancer should not ..."; -const char g_kCallCredsMdValue[] = "... receive me"; - -class BackendServiceImpl : public BackendService { - public: - BackendServiceImpl() {} - - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - // Backend should receive the call credentials metadata. - auto call_credentials_entry = - context->client_metadata().find(g_kCallCredsMdKey); - EXPECT_NE(call_credentials_entry, context->client_metadata().end()); - if (call_credentials_entry != context->client_metadata().end()) { - EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); - } - IncreaseRequestCount(); - const auto status = TestServiceImpl::Echo(context, request, response); - IncreaseResponseCount(); - AddClient(context->peer().c_str()); - return status; - } - - void Start() {} - - void Shutdown() {} - - std::set<TString> clients() { - grpc::internal::MutexLock lock(&clients_mu_); - return clients_; - } - - private: - void AddClient(const TString& client) { - grpc::internal::MutexLock lock(&clients_mu_); - clients_.insert(client); - } - - grpc::internal::Mutex clients_mu_; - std::set<TString> clients_ Y_ABSL_GUARDED_BY(&clients_mu_); -}; - -TString Ip4ToPackedString(const char* ip_str) { - struct in_addr ip4; - GPR_ASSERT(inet_pton(AF_INET, ip_str, &ip4) == 1); - return TString(reinterpret_cast<const char*>(&ip4), sizeof(ip4)); -} - -TString Ip6ToPackedString(const char* ip_str) { - struct in6_addr ip6; - GPR_ASSERT(inet_pton(AF_INET6, ip_str, &ip6) == 1); - return TString(reinterpret_cast<const char*>(&ip6), sizeof(ip6)); -} - -struct ClientStats { - size_t num_calls_started = 0; - size_t num_calls_finished = 0; - size_t num_calls_finished_with_client_failed_to_send = 0; - size_t num_calls_finished_known_received = 0; - std::map<TString, size_t> drop_token_counts; - - ClientStats& operator+=(const ClientStats& other) { - num_calls_started += other.num_calls_started; - num_calls_finished += other.num_calls_finished; - num_calls_finished_with_client_failed_to_send += - other.num_calls_finished_with_client_failed_to_send; - num_calls_finished_known_received += - other.num_calls_finished_known_received; - for (const auto& p : other.drop_token_counts) { - drop_token_counts[p.first] += p.second; - } - return *this; - } - - void Reset() { - num_calls_started = 0; - num_calls_finished = 0; - num_calls_finished_with_client_failed_to_send = 0; - num_calls_finished_known_received = 0; - drop_token_counts.clear(); - } -}; - -class BalancerServiceImpl : public BalancerService { - public: - using Stream = ServerReaderWriter<LoadBalanceResponse, LoadBalanceRequest>; - using ResponseDelayPair = std::pair<LoadBalanceResponse, int>; - - explicit BalancerServiceImpl(int client_load_reporting_interval_seconds) - : client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds) {} - - Status BalanceLoad(ServerContext* context, Stream* stream) override { - gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); - { - grpc::internal::MutexLock lock(&mu_); - if (serverlist_done_) goto done; - } - { - // Balancer shouldn't receive the call credentials metadata. - EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), - context->client_metadata().end()); - LoadBalanceRequest request; - std::vector<ResponseDelayPair> responses_and_delays; - - if (!stream->Read(&request)) { - goto done; - } else { - if (request.has_initial_request()) { - grpc::internal::MutexLock lock(&mu_); - service_names_.push_back(request.initial_request().name()); - } - } - IncreaseRequestCount(); - gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this, - request.DebugString().c_str()); - - // TODO(juanlishen): Initial response should always be the first response. - if (client_load_reporting_interval_seconds_ > 0) { - LoadBalanceResponse initial_response; - initial_response.mutable_initial_response() - ->mutable_client_stats_report_interval() - ->set_seconds(client_load_reporting_interval_seconds_); - stream->Write(initial_response); - } - - { - grpc::internal::MutexLock lock(&mu_); - responses_and_delays = responses_and_delays_; - } - for (const auto& response_and_delay : responses_and_delays) { - SendResponse(stream, response_and_delay.first, - response_and_delay.second); - } - { - grpc::internal::MutexLock lock(&mu_); - while (!serverlist_done_) { - serverlist_cond_.Wait(&mu_); - } - } - - if (client_load_reporting_interval_seconds_ > 0) { - request.Clear(); - while (stream->Read(&request)) { - gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'", - this, request.DebugString().c_str()); - GPR_ASSERT(request.has_client_stats()); - ClientStats load_report; - load_report.num_calls_started = - request.client_stats().num_calls_started(); - load_report.num_calls_finished = - request.client_stats().num_calls_finished(); - load_report.num_calls_finished_with_client_failed_to_send = - request.client_stats() - .num_calls_finished_with_client_failed_to_send(); - load_report.num_calls_finished_known_received = - request.client_stats().num_calls_finished_known_received(); - for (const auto& drop_token_count : - request.client_stats().calls_finished_with_drop()) { - load_report - .drop_token_counts[drop_token_count.load_balance_token()] = - drop_token_count.num_calls(); - } - // We need to acquire the lock here in order to prevent the notify_one - // below from firing before its corresponding wait is executed. - grpc::internal::MutexLock lock(&mu_); - load_report_queue_.emplace_back(std::move(load_report)); - load_report_cond_.Signal(); - } - } - } - done: - gpr_log(GPR_INFO, "LB[%p]: done", this); - return Status::OK; - } - - void add_response(const LoadBalanceResponse& response, int send_after_ms) { - grpc::internal::MutexLock lock(&mu_); - responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); - } - - void Start() { - grpc::internal::MutexLock lock(&mu_); - serverlist_done_ = false; - responses_and_delays_.clear(); - load_report_queue_.clear(); - } - - void Shutdown() { - NotifyDoneWithServerlists(); - gpr_log(GPR_INFO, "LB[%p]: shut down", this); - } - - ClientStats WaitForLoadReport() { - grpc::internal::MutexLock lock(&mu_); - if (load_report_queue_.empty()) { - while (load_report_queue_.empty()) { - load_report_cond_.Wait(&mu_); - } - } - ClientStats load_report = std::move(load_report_queue_.front()); - load_report_queue_.pop_front(); - return load_report; - } - - void NotifyDoneWithServerlists() { - grpc::internal::MutexLock lock(&mu_); - if (!serverlist_done_) { - serverlist_done_ = true; - serverlist_cond_.SignalAll(); - } - } - - std::vector<TString> service_names() { - grpc::internal::MutexLock lock(&mu_); - return service_names_; - } - - private: - void SendResponse(Stream* stream, const LoadBalanceResponse& response, - int delay_ms) { - gpr_log(GPR_INFO, "LB[%p]: sleeping for %d ms...", this, delay_ms); - if (delay_ms > 0) { - gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(delay_ms)); - } - gpr_log(GPR_INFO, "LB[%p]: Woke up! Sending response '%s'", this, - response.DebugString().c_str()); - IncreaseResponseCount(); - stream->Write(response); - } - - const int client_load_reporting_interval_seconds_; - std::vector<ResponseDelayPair> responses_and_delays_; - std::vector<TString> service_names_; - - grpc::internal::Mutex mu_; - grpc::internal::CondVar serverlist_cond_; - bool serverlist_done_ Y_ABSL_GUARDED_BY(mu_) = false; - grpc::internal::CondVar load_report_cond_; - std::deque<ClientStats> load_report_queue_ Y_ABSL_GUARDED_BY(mu_); -}; - -class GrpclbEnd2endTest : public ::testing::Test { - protected: - GrpclbEnd2endTest(size_t num_backends, size_t num_balancers, - int client_load_reporting_interval_seconds) - : server_host_("localhost"), - num_backends_(num_backends), - num_balancers_(num_balancers), - client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds) {} - - static void SetUpTestCase() { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - grpc_init(); - } - - static void TearDownTestCase() { grpc_shutdown(); } - - void SetUp() override { - bool localhost_resolves_to_ipv4 = false; - bool localhost_resolves_to_ipv6 = false; - grpc_core::LocalhostResolves(&localhost_resolves_to_ipv4, - &localhost_resolves_to_ipv6); - ipv6_only_ = !localhost_resolves_to_ipv4 && localhost_resolves_to_ipv6; - response_generator_ = - grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); - // Start the backends. - for (size_t i = 0; i < num_backends_; ++i) { - backends_.emplace_back(new ServerThread<BackendServiceImpl>("backend")); - backends_.back()->Start(server_host_); - } - // Start the load balancers. - for (size_t i = 0; i < num_balancers_; ++i) { - balancers_.emplace_back(new ServerThread<BalancerServiceImpl>( - "balancer", client_load_reporting_interval_seconds_)); - balancers_.back()->Start(server_host_); - } - ResetStub(); - } - - void TearDown() override { - ShutdownAllBackends(); - for (auto& balancer : balancers_) balancer->Shutdown(); - } - - void StartAllBackends() { - for (auto& backend : backends_) backend->Start(server_host_); - } - - void StartBackend(size_t index) { backends_[index]->Start(server_host_); } - - void ShutdownAllBackends() { - for (auto& backend : backends_) backend->Shutdown(); - } - - void ShutdownBackend(size_t index) { backends_[index]->Shutdown(); } - - void ResetStub(int fallback_timeout = 0, - const TString& expected_targets = "", - int subchannel_cache_delay_ms = 0) { - ChannelArguments args; - if (fallback_timeout > 0) args.SetGrpclbFallbackTimeout(fallback_timeout); - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_.get()); - if (!expected_targets.empty()) { - args.SetString(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets); - } - if (subchannel_cache_delay_ms > 0) { - args.SetInt(GRPC_ARG_GRPCLB_SUBCHANNEL_CACHE_INTERVAL_MS, - subchannel_cache_delay_ms); - } - std::ostringstream uri; - uri << "fake:///" << kApplicationTargetName_; - // TODO(dgq): templatize tests to run everything using both secure and - // insecure channel credentials. - grpc_channel_credentials* channel_creds = - grpc_fake_transport_security_credentials_create(); - grpc_call_credentials* call_creds = grpc_md_only_test_credentials_create( - g_kCallCredsMdKey, g_kCallCredsMdValue, false); - std::shared_ptr<ChannelCredentials> creds( - new SecureChannelCredentials(grpc_composite_channel_credentials_create( - channel_creds, call_creds, nullptr))); - call_creds->Unref(); - channel_creds->Unref(); - channel_ = ::grpc::CreateCustomChannel(uri.str(), creds, args); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - void ResetBackendCounters() { - for (auto& backend : backends_) backend->service_.ResetCounters(); - } - - ClientStats WaitForLoadReports() { - ClientStats client_stats; - for (auto& balancer : balancers_) { - client_stats += balancer->service_.WaitForLoadReport(); - } - return client_stats; - } - - bool SeenAllBackends(size_t start_index = 0, size_t stop_index = 0) { - if (stop_index == 0) stop_index = backends_.size(); - for (size_t i = start_index; i < stop_index; ++i) { - if (backends_[i]->service_.request_count() == 0) return false; - } - return true; - } - - void SendRpcAndCount(int* num_total, int* num_ok, int* num_failure, - int* num_drops) { - const Status status = SendRpc(); - if (status.ok()) { - ++*num_ok; - } else { - if (status.error_message() == "drop directed by grpclb balancer") { - ++*num_drops; - } else { - ++*num_failure; - } - } - ++*num_total; - } - - std::tuple<int, int, int> WaitForAllBackends(int num_requests_multiple_of = 1, - size_t start_index = 0, - size_t stop_index = 0) { - int num_ok = 0; - int num_failure = 0; - int num_drops = 0; - int num_total = 0; - while (!SeenAllBackends(start_index, stop_index)) { - SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); - } - while (num_total % num_requests_multiple_of != 0) { - SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); - } - ResetBackendCounters(); - gpr_log(GPR_INFO, - "Performed %d warm up requests (a multiple of %d) against the " - "backends. %d succeeded, %d failed, %d dropped.", - num_total, num_requests_multiple_of, num_ok, num_failure, - num_drops); - return std::make_tuple(num_ok, num_failure, num_drops); - } - - void WaitForBackend(size_t backend_idx) { - do { - (void)SendRpc(); - } while (backends_[backend_idx]->service_.request_count() == 0); - ResetBackendCounters(); - } - - struct AddressData { - int port; - TString balancer_name; - }; - - grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( - const std::vector<AddressData>& address_data) { - grpc_core::ServerAddressList addresses; - for (const auto& addr : address_data) { - y_absl::StatusOr<grpc_core::URI> lb_uri = - grpc_core::URI::Parse(y_absl::StrCat( - ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", addr.port)); - GPR_ASSERT(lb_uri.ok()); - grpc_resolved_address address; - GPR_ASSERT(grpc_parse_uri(*lb_uri, &address)); - grpc_arg arg = grpc_channel_arg_string_create( - const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), - const_cast<char*>(addr.balancer_name.c_str())); - grpc_channel_args* args = - grpc_channel_args_copy_and_add(nullptr, &arg, 1); - addresses.emplace_back(address.addr, address.len, args); - } - return addresses; - } - - grpc_core::Resolver::Result MakeResolverResult( - const std::vector<AddressData>& balancer_address_data, - const std::vector<AddressData>& backend_address_data = {}, - const char* service_config_json = kDefaultServiceConfig) { - grpc_core::Resolver::Result result; - result.addresses = - CreateLbAddressesFromAddressDataList(backend_address_data); - grpc_error_handle error = GRPC_ERROR_NONE; - result.service_config = - grpc_core::ServiceConfig::Create(nullptr, service_config_json, &error); - GPR_ASSERT(error == GRPC_ERROR_NONE); - grpc_core::ServerAddressList balancer_addresses = - CreateLbAddressesFromAddressDataList(balancer_address_data); - grpc_arg arg = CreateGrpclbBalancerAddressesArg(&balancer_addresses); - result.args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); - return result; - } - - void SetNextResolutionAllBalancers( - const char* service_config_json = kDefaultServiceConfig) { - std::vector<AddressData> addresses; - for (size_t i = 0; i < balancers_.size(); ++i) { - addresses.emplace_back(AddressData{balancers_[i]->port_, ""}); - } - SetNextResolution(addresses, {}, service_config_json); - } - - void SetNextResolution( - const std::vector<AddressData>& balancer_address_data, - const std::vector<AddressData>& backend_address_data = {}, - const char* service_config_json = kDefaultServiceConfig) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = MakeResolverResult( - balancer_address_data, backend_address_data, service_config_json); - response_generator_->SetResponse(std::move(result)); - } - - void SetNextReresolutionResponse( - const std::vector<AddressData>& balancer_address_data, - const std::vector<AddressData>& backend_address_data = {}, - const char* service_config_json = kDefaultServiceConfig) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = MakeResolverResult( - balancer_address_data, backend_address_data, service_config_json); - response_generator_->SetReresolutionResponse(std::move(result)); - } - - std::vector<int> GetBackendPorts(size_t start_index = 0, - size_t stop_index = 0) const { - if (stop_index == 0) stop_index = backends_.size(); - std::vector<int> backend_ports; - for (size_t i = start_index; i < stop_index; ++i) { - backend_ports.push_back(backends_[i]->port_); - } - return backend_ports; - } - - void ScheduleResponseForBalancer(size_t i, - const LoadBalanceResponse& response, - int delay_ms) { - balancers_[i]->service_.add_response(response, delay_ms); - } - - LoadBalanceResponse BuildResponseForBackends( - const std::vector<int>& backend_ports, - const std::map<TString, size_t>& drop_token_counts) { - LoadBalanceResponse response; - for (const auto& drop_token_count : drop_token_counts) { - for (size_t i = 0; i < drop_token_count.second; ++i) { - auto* server = response.mutable_server_list()->add_servers(); - server->set_drop(true); - server->set_load_balance_token(drop_token_count.first); - } - } - for (const int& backend_port : backend_ports) { - auto* server = response.mutable_server_list()->add_servers(); - server->set_ip_address(ipv6_only_ ? Ip6ToPackedString("::1") - : Ip4ToPackedString("127.0.0.1")); - server->set_port(backend_port); - static int token_count = 0; - server->set_load_balance_token( - y_absl::StrFormat("token%03d", ++token_count)); - } - return response; - } - - Status SendRpc(EchoResponse* response = nullptr, int timeout_ms = 1000, - bool wait_for_ready = false, - const Status& expected_status = Status::OK) { - const bool local_response = (response == nullptr); - if (local_response) response = new EchoResponse; - EchoRequest request; - request.set_message(kRequestMessage_); - if (!expected_status.ok()) { - auto* error = request.mutable_param()->mutable_expected_error(); - error->set_code(expected_status.error_code()); - error->set_error_message(expected_status.error_message()); - } - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); - if (wait_for_ready) context.set_wait_for_ready(true); - Status status = stub_->Echo(&context, request, response); - if (local_response) delete response; - return status; - } - - void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000, - bool wait_for_ready = false) { - for (size_t i = 0; i < times; ++i) { - EchoResponse response; - const Status status = SendRpc(&response, timeout_ms, wait_for_ready); - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); - EXPECT_EQ(response.message(), kRequestMessage_); - } - } - - void CheckRpcSendFailure() { - const Status status = SendRpc(); - EXPECT_FALSE(status.ok()); - } - - template <typename T> - struct ServerThread { - template <typename... Args> - explicit ServerThread(const TString& type, Args&&... args) - : port_(grpc_pick_unused_port_or_die()), - type_(type), - service_(std::forward<Args>(args)...) {} - - void Start(const TString& server_host) { - gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); - GPR_ASSERT(!running_); - running_ = true; - service_.Start(); - grpc::internal::Mutex mu; - // We need to acquire the lock here in order to prevent the notify_one - // by ServerThread::Serve from firing before the wait below is hit. - grpc::internal::MutexLock lock(&mu); - grpc::internal::CondVar cond; - thread_ = y_absl::make_unique<std::thread>( - std::bind(&ServerThread::Serve, this, server_host, &mu, &cond)); - cond.Wait(&mu); - gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); - } - - void Serve(const TString& server_host, grpc::internal::Mutex* mu, - grpc::internal::CondVar* cond) { - // We need to acquire the lock here in order to prevent the notify_one - // below from firing before its corresponding wait is executed. - grpc::internal::MutexLock lock(mu); - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials( - grpc_fake_transport_security_server_credentials_create())); - builder.AddListeningPort(server_address.str(), creds); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - cond->Signal(); - } - - void Shutdown() { - if (!running_) return; - gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); - service_.Shutdown(); - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - thread_->join(); - gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); - running_ = false; - } - - const int port_; - TString type_; - T service_; - std::unique_ptr<Server> server_; - std::unique_ptr<std::thread> thread_; - bool running_ = false; - }; - - const TString server_host_; - const size_t num_backends_; - const size_t num_balancers_; - const int client_load_reporting_interval_seconds_; - bool ipv6_only_ = false; - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::vector<std::unique_ptr<ServerThread<BackendServiceImpl>>> backends_; - std::vector<std::unique_ptr<ServerThread<BalancerServiceImpl>>> balancers_; - grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> - response_generator_; - const TString kRequestMessage_ = "Live long and prosper."; - const TString kApplicationTargetName_ = "application_target_name"; -}; - -class SingleBalancerTest : public GrpclbEnd2endTest { - public: - SingleBalancerTest() : GrpclbEnd2endTest(4, 1, 0) {} -}; - -TEST_F(SingleBalancerTest, Vanilla) { - SetNextResolutionAllBalancers(); - const size_t kNumRpcsPerAddress = 100; - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - // Make sure that trying to connect works without a call. - channel_->GetState(true /* try_to_connect */); - // We need to wait for all backends to come online. - WaitForAllBackends(); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - - // Each backend should have gotten 100 requests. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); - } - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(SingleBalancerTest, SubchannelCaching) { - ResetStub(/*fallback_timeout=*/0, /*expected_targets=*/"", - /*subchannel_cache_delay_ms=*/1500); - SetNextResolutionAllBalancers(); - // Initially send all backends. - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - // Then remove backends 0 and 1. - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(2), {}), 1000); - // Now re-add backend 1. - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(1), {}), 1000); - // Wait for all backends to come online. - WaitForAllBackends(); - // Send RPCs for long enough to get all responses. - gpr_timespec deadline = grpc_timeout_milliseconds_to_deadline(3000); - do { - CheckRpcSendOk(); - } while (gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), deadline) < 0); - // Backend 0 should have received less traffic than the others. - // Backend 1 would have received less traffic than 2 and 3. - gpr_log(GPR_INFO, "BACKEND 0: %" PRIuPTR " requests", - backends_[0]->service_.request_count()); - EXPECT_GT(backends_[0]->service_.request_count(), 0); - for (size_t i = 1; i < backends_.size(); ++i) { - gpr_log(GPR_INFO, "BACKEND %" PRIuPTR ": %" PRIuPTR " requests", i, - backends_[i]->service_.request_count()); - EXPECT_GT(backends_[i]->service_.request_count(), - backends_[0]->service_.request_count()) - << "backend " << i; - if (i >= 2) { - EXPECT_GT(backends_[i]->service_.request_count(), - backends_[1]->service_.request_count()) - << "backend " << i; - } - } - // Backend 1 should never have lost its connection from the client. - EXPECT_EQ(1UL, backends_[1]->service_.clients().size()); - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // And sent 3 responses. - EXPECT_EQ(3U, balancers_[0]->service_.response_count()); -} - -TEST_F(SingleBalancerTest, ReturnServerStatus) { - SetNextResolutionAllBalancers(); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - // We need to wait for all backends to come online. - WaitForAllBackends(); - // Send a request that the backend will fail, and make sure we get - // back the right status. - Status expected(StatusCode::INVALID_ARGUMENT, "He's dead, Jim!"); - Status actual = SendRpc(/*response=*/nullptr, /*timeout_ms=*/1000, - /*wait_for_ready=*/false, expected); - EXPECT_EQ(actual.error_code(), expected.error_code()); - EXPECT_EQ(actual.error_message(), expected.error_message()); -} - -TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { - SetNextResolutionAllBalancers( - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"does_not_exist\":{} },\n" - " { \"grpclb\":{} }\n" - " ]\n" - "}"); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - CheckRpcSendOk(1, 1000 /* timeout_ms */, true /* wait_for_ready */); - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(SingleBalancerTest, - SelectGrpclbWithMigrationServiceConfigAndNoAddresses) { - const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); - ResetStub(kFallbackTimeoutMs); - SetNextResolution({}, {}, - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"does_not_exist\":{} },\n" - " { \"grpclb\":{} }\n" - " ]\n" - "}"); - // Try to connect. - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true)); - // Should go into state TRANSIENT_FAILURE when we enter fallback mode. - const gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); - grpc_connectivity_state state; - while ((state = channel_->GetState(false)) != - GRPC_CHANNEL_TRANSIENT_FAILURE) { - ASSERT_TRUE(channel_->WaitForStateChange(state, deadline)); - } - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(SingleBalancerTest, UsePickFirstChildPolicy) { - SetNextResolutionAllBalancers( - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{\n" - " \"childPolicy\":[\n" - " { \"pick_first\":{} }\n" - " ]\n" - " } }\n" - " ]\n" - "}"); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - const size_t kNumRpcs = num_backends_ * 2; - CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); - balancers_[0]->service_.NotifyDoneWithServerlists(); - // Check that all requests went to the first backend. This verifies - // that we used pick_first instead of round_robin as the child policy. - EXPECT_EQ(backends_[0]->service_.request_count(), kNumRpcs); - for (size_t i = 1; i < backends_.size(); ++i) { - EXPECT_EQ(backends_[i]->service_.request_count(), 0UL); - } - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(SingleBalancerTest, SwapChildPolicy) { - SetNextResolutionAllBalancers( - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{\n" - " \"childPolicy\":[\n" - " { \"pick_first\":{} }\n" - " ]\n" - " } }\n" - " ]\n" - "}"); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - const size_t kNumRpcs = num_backends_ * 2; - CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); - // Check that all requests went to the first backend. This verifies - // that we used pick_first instead of round_robin as the child policy. - EXPECT_EQ(backends_[0]->service_.request_count(), kNumRpcs); - for (size_t i = 1; i < backends_.size(); ++i) { - EXPECT_EQ(backends_[i]->service_.request_count(), 0UL); - } - // Send new resolution that removes child policy from service config. - SetNextResolutionAllBalancers(); - WaitForAllBackends(); - CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); - // Check that every backend saw the same number of requests. This verifies - // that we used round_robin. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(backends_[i]->service_.request_count(), 2UL); - } - // Done. - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { - SetNextResolutionAllBalancers(); - // Same backend listed twice. - std::vector<int> ports; - ports.push_back(backends_[0]->port_); - ports.push_back(backends_[0]->port_); - const size_t kNumRpcsPerAddress = 10; - ScheduleResponseForBalancer(0, BuildResponseForBackends(ports, {}), 0); - // We need to wait for the backend to come online. - WaitForBackend(0); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); - // Backend should have gotten 20 requests. - EXPECT_EQ(kNumRpcsPerAddress * 2, backends_[0]->service_.request_count()); - // And they should have come from a single client port, because of - // subchannel sharing. - EXPECT_EQ(1UL, backends_[0]->service_.clients().size()); - balancers_[0]->service_.NotifyDoneWithServerlists(); -} - -TEST_F(SingleBalancerTest, SecureNaming) { - ResetStub(0, kApplicationTargetName_ + ";lb"); - SetNextResolution({AddressData{balancers_[0]->port_, "lb"}}); - const size_t kNumRpcsPerAddress = 100; - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - // Make sure that trying to connect works without a call. - channel_->GetState(true /* try_to_connect */); - // We need to wait for all backends to come online. - WaitForAllBackends(); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - - // Each backend should have gotten 100 requests. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); - } - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(SingleBalancerTest, SecureNamingDeathTest) { - GRPC_GTEST_FLAG_SET_DEATH_TEST_STYLE("threadsafe"); - // Make sure that we blow up (via abort() from the security connector) when - // the name from the balancer doesn't match expectations. - ASSERT_DEATH_IF_SUPPORTED( - { - ResetStub(0, kApplicationTargetName_ + ";lb"); - SetNextResolution({AddressData{balancers_[0]->port_, "woops"}}); - channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1)); - }, - ""); -} - -TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { - SetNextResolutionAllBalancers(); - const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); - const int kCallDeadlineMs = kServerlistDelayMs * 2; - // First response is an empty serverlist, sent right away. - ScheduleResponseForBalancer(0, LoadBalanceResponse(), 0); - // Send non-empty serverlist only after kServerlistDelayMs - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), kServerlistDelayMs); - const auto t0 = system_clock::now(); - // Client will block: LB will initially send empty serverlist. - CheckRpcSendOk(1, kCallDeadlineMs, true /* wait_for_ready */); - const auto ellapsed_ms = - std::chrono::duration_cast<std::chrono::milliseconds>( - system_clock::now() - t0); - // but eventually, the LB sends a serverlist update that allows the call to - // proceed. The call delay must be larger than the delay in sending the - // populated serverlist but under the call's deadline (which is enforced by - // the call's deadline). - EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent two responses. - EXPECT_EQ(2U, balancers_[0]->service_.response_count()); -} - -TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { - SetNextResolutionAllBalancers(); - const size_t kNumUnreachableServers = 5; - std::vector<int> ports; - for (size_t i = 0; i < kNumUnreachableServers; ++i) { - ports.push_back(grpc_pick_unused_port_or_die()); - } - ScheduleResponseForBalancer(0, BuildResponseForBackends(ports, {}), 0); - const Status status = SendRpc(); - // The error shouldn't be DEADLINE_EXCEEDED. - EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); -} - -TEST_F(SingleBalancerTest, Fallback) { - SetNextResolutionAllBalancers(); - const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); - const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); - const size_t kNumBackendsInResolution = backends_.size() / 2; - - ResetStub(kFallbackTimeoutMs); - std::vector<AddressData> balancer_addresses; - balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - std::vector<AddressData> backend_addresses; - for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); - } - SetNextResolution(balancer_addresses, backend_addresses); - - // Send non-empty serverlist only after kServerlistDelayMs. - ScheduleResponseForBalancer( - 0, - BuildResponseForBackends( - GetBackendPorts(kNumBackendsInResolution /* start_index */), {}), - kServerlistDelayMs); - - // Wait until all the fallback backends are reachable. - for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - WaitForBackend(i); - } - - // The first request. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(kNumBackendsInResolution); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - - // Fallback is used: each backend returned by the resolver should have - // gotten one request. - for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - EXPECT_EQ(1U, backends_[i]->service_.request_count()); - } - for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(0U, backends_[i]->service_.request_count()); - } - - // Wait until the serverlist reception has been processed and all backends - // in the serverlist are reachable. - for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { - WaitForBackend(i); - } - - // Send out the second request. - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(backends_.size() - kNumBackendsInResolution); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - - // Serverlist is used: each backend returned by the balancer should - // have gotten one request. - for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - EXPECT_EQ(0U, backends_[i]->service_.request_count()); - } - for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(1U, backends_[i]->service_.request_count()); - } - - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); -} - -TEST_F(SingleBalancerTest, FallbackUpdate) { - SetNextResolutionAllBalancers(); - const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); - const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); - const size_t kNumBackendsInResolution = backends_.size() / 3; - const size_t kNumBackendsInResolutionUpdate = backends_.size() / 3; - - ResetStub(kFallbackTimeoutMs); - std::vector<AddressData> balancer_addresses; - balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - std::vector<AddressData> backend_addresses; - for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); - } - SetNextResolution(balancer_addresses, backend_addresses); - - // Send non-empty serverlist only after kServerlistDelayMs. - ScheduleResponseForBalancer( - 0, - BuildResponseForBackends( - GetBackendPorts(kNumBackendsInResolution + - kNumBackendsInResolutionUpdate /* start_index */), - {}), - kServerlistDelayMs); - - // Wait until all the fallback backends are reachable. - for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - WaitForBackend(i); - } - - // The first request. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(kNumBackendsInResolution); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - - // Fallback is used: each backend returned by the resolver should have - // gotten one request. - for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - EXPECT_EQ(1U, backends_[i]->service_.request_count()); - } - for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(0U, backends_[i]->service_.request_count()); - } - - balancer_addresses.clear(); - balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - backend_addresses.clear(); - for (size_t i = kNumBackendsInResolution; - i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { - backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); - } - SetNextResolution(balancer_addresses, backend_addresses); - - // Wait until the resolution update has been processed and all the new - // fallback backends are reachable. - for (size_t i = kNumBackendsInResolution; - i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { - WaitForBackend(i); - } - - // Send out the second request. - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(kNumBackendsInResolutionUpdate); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - - // The resolution update is used: each backend in the resolution update should - // have gotten one request. - for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - EXPECT_EQ(0U, backends_[i]->service_.request_count()); - } - for (size_t i = kNumBackendsInResolution; - i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { - EXPECT_EQ(1U, backends_[i]->service_.request_count()); - } - for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; - i < backends_.size(); ++i) { - EXPECT_EQ(0U, backends_[i]->service_.request_count()); - } - - // Wait until the serverlist reception has been processed and all backends - // in the serverlist are reachable. - for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; - i < backends_.size(); ++i) { - WaitForBackend(i); - } - - // Send out the third request. - gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); - CheckRpcSendOk(backends_.size() - kNumBackendsInResolution - - kNumBackendsInResolutionUpdate); - gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); - - // Serverlist is used: each backend returned by the balancer should - // have gotten one request. - for (size_t i = 0; - i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { - EXPECT_EQ(0U, backends_[i]->service_.request_count()); - } - for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; - i < backends_.size(); ++i) { - EXPECT_EQ(1U, backends_[i]->service_.request_count()); - } - - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); -} - -TEST_F(SingleBalancerTest, - FallbackAfterStartup_LoseContactWithBalancerThenBackends) { - // First two backends are fallback, last two are pointed to by balancer. - const size_t kNumFallbackBackends = 2; - const size_t kNumBalancerBackends = backends_.size() - kNumFallbackBackends; - std::vector<AddressData> backend_addresses; - for (size_t i = 0; i < kNumFallbackBackends; ++i) { - backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); - } - std::vector<AddressData> balancer_addresses; - for (size_t i = 0; i < balancers_.size(); ++i) { - balancer_addresses.emplace_back(AddressData{balancers_[i]->port_, ""}); - } - SetNextResolution(balancer_addresses, backend_addresses); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(kNumFallbackBackends), {}), - 0); - // Try to connect. - channel_->GetState(true /* try_to_connect */); - WaitForAllBackends(1 /* num_requests_multiple_of */, - kNumFallbackBackends /* start_index */); - // Stop balancer. RPCs should continue going to backends from balancer. - balancers_[0]->Shutdown(); - CheckRpcSendOk(100 * kNumBalancerBackends); - for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { - EXPECT_EQ(100UL, backends_[i]->service_.request_count()); - } - // Stop backends from balancer. This should put us in fallback mode. - for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { - ShutdownBackend(i); - } - WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, - kNumFallbackBackends /* stop_index */); - // Restart the backends from the balancer. We should *not* start - // sending traffic back to them at this point (although the behavior - // in xds may be different). - for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { - StartBackend(i); - } - CheckRpcSendOk(100 * kNumBalancerBackends); - for (size_t i = 0; i < kNumFallbackBackends; ++i) { - EXPECT_EQ(100UL, backends_[i]->service_.request_count()); - } - // Now start the balancer again. This should cause us to exit - // fallback mode. - balancers_[0]->Start(server_host_); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(kNumFallbackBackends), {}), - 0); - WaitForAllBackends(1 /* num_requests_multiple_of */, - kNumFallbackBackends /* start_index */); -} - -TEST_F(SingleBalancerTest, - FallbackAfterStartup_LoseContactWithBackendsThenBalancer) { - // First two backends are fallback, last two are pointed to by balancer. - const size_t kNumFallbackBackends = 2; - const size_t kNumBalancerBackends = backends_.size() - kNumFallbackBackends; - std::vector<AddressData> backend_addresses; - for (size_t i = 0; i < kNumFallbackBackends; ++i) { - backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); - } - std::vector<AddressData> balancer_addresses; - for (size_t i = 0; i < balancers_.size(); ++i) { - balancer_addresses.emplace_back(AddressData{balancers_[i]->port_, ""}); - } - SetNextResolution(balancer_addresses, backend_addresses); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(kNumFallbackBackends), {}), - 0); - // Try to connect. - channel_->GetState(true /* try_to_connect */); - WaitForAllBackends(1 /* num_requests_multiple_of */, - kNumFallbackBackends /* start_index */); - // Stop backends from balancer. Since we are still in contact with - // the balancer at this point, RPCs should be failing. - for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { - ShutdownBackend(i); - } - CheckRpcSendFailure(); - // Stop balancer. This should put us in fallback mode. - balancers_[0]->Shutdown(); - WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, - kNumFallbackBackends /* stop_index */); - // Restart the backends from the balancer. We should *not* start - // sending traffic back to them at this point (although the behavior - // in xds may be different). - for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { - StartBackend(i); - } - CheckRpcSendOk(100 * kNumBalancerBackends); - for (size_t i = 0; i < kNumFallbackBackends; ++i) { - EXPECT_EQ(100UL, backends_[i]->service_.request_count()); - } - // Now start the balancer again. This should cause us to exit - // fallback mode. - balancers_[0]->Start(server_host_); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(kNumFallbackBackends), {}), - 0); - WaitForAllBackends(1 /* num_requests_multiple_of */, - kNumFallbackBackends /* start_index */); -} - -TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { - const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); - ResetStub(kFallbackTimeoutMs); - // Return an unreachable balancer and one fallback backend. - std::vector<AddressData> balancer_addresses; - balancer_addresses.emplace_back( - AddressData{grpc_pick_unused_port_or_die(), ""}); - std::vector<AddressData> backend_addresses; - backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); - SetNextResolution(balancer_addresses, backend_addresses); - // Send RPC with deadline less than the fallback timeout and make sure it - // succeeds. - CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, - /* wait_for_ready */ false); -} - -TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerCallFails) { - const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); - ResetStub(kFallbackTimeoutMs); - // Return one balancer and one fallback backend. - std::vector<AddressData> balancer_addresses; - balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - std::vector<AddressData> backend_addresses; - backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); - SetNextResolution(balancer_addresses, backend_addresses); - // Balancer drops call without sending a serverlist. - balancers_[0]->service_.NotifyDoneWithServerlists(); - // Send RPC with deadline less than the fallback timeout and make sure it - // succeeds. - CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, - /* wait_for_ready */ false); -} - -TEST_F(SingleBalancerTest, FallbackControlledByBalancer_BeforeFirstServerlist) { - const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); - ResetStub(kFallbackTimeoutMs); - // Return one balancer and one fallback backend. - std::vector<AddressData> balancer_addresses; - balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - std::vector<AddressData> backend_addresses; - backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); - SetNextResolution(balancer_addresses, backend_addresses); - // Balancer explicitly tells client to fallback. - LoadBalanceResponse resp; - resp.mutable_fallback_response(); - ScheduleResponseForBalancer(0, resp, 0); - // Send RPC with deadline less than the fallback timeout and make sure it - // succeeds. - CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, - /* wait_for_ready */ false); -} - -TEST_F(SingleBalancerTest, FallbackControlledByBalancer_AfterFirstServerlist) { - // Return one balancer and one fallback backend (backend 0). - std::vector<AddressData> balancer_addresses; - balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - std::vector<AddressData> backend_addresses; - backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); - SetNextResolution(balancer_addresses, backend_addresses); - // Balancer initially sends serverlist, then tells client to fall back, - // then sends the serverlist again. - // The serverlist points to backend 1. - LoadBalanceResponse serverlist_resp = - BuildResponseForBackends({backends_[1]->port_}, {}); - LoadBalanceResponse fallback_resp; - fallback_resp.mutable_fallback_response(); - ScheduleResponseForBalancer(0, serverlist_resp, 0); - ScheduleResponseForBalancer(0, fallback_resp, 100); - ScheduleResponseForBalancer(0, serverlist_resp, 100); - // Requests initially go to backend 1, then go to backend 0 in - // fallback mode, then go back to backend 1 when we exit fallback. - WaitForBackend(1); - WaitForBackend(0); - WaitForBackend(1); -} - -TEST_F(SingleBalancerTest, BackendsRestart) { - SetNextResolutionAllBalancers(); - const size_t kNumRpcsPerAddress = 100; - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - // Make sure that trying to connect works without a call. - channel_->GetState(true /* try_to_connect */); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - // Stop backends. RPCs should fail. - ShutdownAllBackends(); - CheckRpcSendFailure(); - // Restart backends. RPCs should start succeeding again. - StartAllBackends(); - CheckRpcSendOk(1 /* times */, 2000 /* timeout_ms */, - true /* wait_for_ready */); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); -} - -TEST_F(SingleBalancerTest, ServiceNameFromLbPolicyConfig) { - constexpr char kServiceConfigWithTarget[] = - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{\n" - " \"serviceName\":\"test_service\"\n" - " }}\n" - " ]\n" - "}"; - - SetNextResolutionAllBalancers(kServiceConfigWithTarget); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - // Make sure that trying to connect works without a call. - channel_->GetState(true /* try_to_connect */); - // We need to wait for all backends to come online. - WaitForAllBackends(); - EXPECT_EQ(balancers_[0]->service_.service_names().back(), "test_service"); -} - -class UpdatesTest : public GrpclbEnd2endTest { - public: - UpdatesTest() : GrpclbEnd2endTest(4, 3, 0) {} -}; - -TEST_F(UpdatesTest, UpdateBalancersButKeepUsingOriginalBalancer) { - SetNextResolutionAllBalancers(); - const std::vector<int> first_backend{GetBackendPorts()[0]}; - const std::vector<int> second_backend{GetBackendPorts()[1]}; - ScheduleResponseForBalancer(0, BuildResponseForBackends(first_backend, {}), - 0); - ScheduleResponseForBalancer(1, BuildResponseForBackends(second_backend, {}), - 0); - - // Wait until the first backend is ready. - WaitForBackend(0); - - // Send 10 requests. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - - // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backends_[0]->service_.request_count()); - - // Balancer 0 got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - EXPECT_EQ(0U, balancers_[1]->service_.request_count()); - EXPECT_EQ(0U, balancers_[1]->service_.response_count()); - EXPECT_EQ(0U, balancers_[2]->service_.request_count()); - EXPECT_EQ(0U, balancers_[2]->service_.response_count()); - - std::vector<AddressData> addresses; - addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); - SetNextResolution(addresses); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - - EXPECT_EQ(0U, backends_[1]->service_.request_count()); - gpr_timespec deadline = gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); - // Send 10 seconds worth of RPCs - do { - CheckRpcSendOk(); - } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); - // The current LB call is still working, so grpclb continued using it to the - // first balancer, which doesn't assign the second backend. - EXPECT_EQ(0U, backends_[1]->service_.request_count()); - - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - EXPECT_EQ(0U, balancers_[1]->service_.request_count()); - EXPECT_EQ(0U, balancers_[1]->service_.response_count()); - EXPECT_EQ(0U, balancers_[2]->service_.request_count()); - EXPECT_EQ(0U, balancers_[2]->service_.response_count()); -} - -// Send an update with the same set of LBs as the one in SetUp() in order to -// verify that the LB channel inside grpclb keeps the initial connection (which -// by definition is also present in the update). -TEST_F(UpdatesTest, UpdateBalancersRepeated) { - SetNextResolutionAllBalancers(); - const std::vector<int> first_backend{GetBackendPorts()[0]}; - const std::vector<int> second_backend{GetBackendPorts()[0]}; - - ScheduleResponseForBalancer(0, BuildResponseForBackends(first_backend, {}), - 0); - ScheduleResponseForBalancer(1, BuildResponseForBackends(second_backend, {}), - 0); - - // Wait until the first backend is ready. - WaitForBackend(0); - - // Send 10 requests. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - - // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backends_[0]->service_.request_count()); - - balancers_[0]->service_.NotifyDoneWithServerlists(); - // Balancer 0 got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - EXPECT_EQ(0U, balancers_[1]->service_.request_count()); - EXPECT_EQ(0U, balancers_[1]->service_.response_count()); - EXPECT_EQ(0U, balancers_[2]->service_.request_count()); - EXPECT_EQ(0U, balancers_[2]->service_.response_count()); - - std::vector<AddressData> addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); - addresses.emplace_back(AddressData{balancers_[2]->port_, ""}); - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); - SetNextResolution(addresses); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - - EXPECT_EQ(0U, backends_[1]->service_.request_count()); - gpr_timespec deadline = gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); - // Send 10 seconds worth of RPCs - do { - CheckRpcSendOk(); - } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); - // grpclb continued using the original LB call to the first balancer, which - // doesn't assign the second backend. - EXPECT_EQ(0U, backends_[1]->service_.request_count()); - balancers_[0]->service_.NotifyDoneWithServerlists(); - - addresses.clear(); - addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); - SetNextResolution(addresses); - gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); - - EXPECT_EQ(0U, backends_[1]->service_.request_count()); - deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(10000, GPR_TIMESPAN)); - // Send 10 seconds worth of RPCs - do { - CheckRpcSendOk(); - } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); - // grpclb continued using the original LB call to the first balancer, which - // doesn't assign the second backend. - EXPECT_EQ(0U, backends_[1]->service_.request_count()); - balancers_[0]->service_.NotifyDoneWithServerlists(); -} - -TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { - std::vector<AddressData> addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - SetNextResolution(addresses); - const std::vector<int> first_backend{GetBackendPorts()[0]}; - const std::vector<int> second_backend{GetBackendPorts()[1]}; - - ScheduleResponseForBalancer(0, BuildResponseForBackends(first_backend, {}), - 0); - ScheduleResponseForBalancer(1, BuildResponseForBackends(second_backend, {}), - 0); - - // Start servers and send 10 RPCs per server. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backends_[0]->service_.request_count()); - - // Kill balancer 0 - gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); - balancers_[0]->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); - - // This is serviced by the existing RR policy - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - // All 10 requests should again have gone to the first backend. - EXPECT_EQ(20U, backends_[0]->service_.request_count()); - EXPECT_EQ(0U, backends_[1]->service_.request_count()); - - // Balancer 0 got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - EXPECT_EQ(0U, balancers_[1]->service_.request_count()); - EXPECT_EQ(0U, balancers_[1]->service_.response_count()); - EXPECT_EQ(0U, balancers_[2]->service_.request_count()); - EXPECT_EQ(0U, balancers_[2]->service_.response_count()); - - addresses.clear(); - addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); - SetNextResolution(addresses); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - - // Wait until update has been processed, as signaled by the second backend - // receiving a request. In the meantime, the client continues to be serviced - // (by the first backend) without interruption. - EXPECT_EQ(0U, backends_[1]->service_.request_count()); - WaitForBackend(1); - - // This is serviced by the updated RR policy - backends_[1]->service_.ResetCounters(); - gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); - // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backends_[1]->service_.request_count()); - - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - // The second balancer, published as part of the first update, may end up - // getting two requests (that is, 1 <= #req <= 2) if the LB call retry timer - // firing races with the arrival of the update containing the second - // balancer. - EXPECT_GE(balancers_[1]->service_.request_count(), 1U); - EXPECT_GE(balancers_[1]->service_.response_count(), 1U); - EXPECT_LE(balancers_[1]->service_.request_count(), 2U); - EXPECT_LE(balancers_[1]->service_.response_count(), 2U); - EXPECT_EQ(0U, balancers_[2]->service_.request_count()); - EXPECT_EQ(0U, balancers_[2]->service_.response_count()); -} - -TEST_F(UpdatesTest, ReresolveDeadBackend) { - ResetStub(500); - // The first resolution contains the addresses of a balancer that never - // responds, and a fallback backend. - std::vector<AddressData> balancer_addresses; - balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - std::vector<AddressData> backend_addresses; - backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); - SetNextResolution(balancer_addresses, backend_addresses); - // Ask channel to connect to trigger resolver creation. - channel_->GetState(true); - // The re-resolution result will contain the addresses of the same balancer - // and a new fallback backend. - balancer_addresses.clear(); - balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - backend_addresses.clear(); - backend_addresses.emplace_back(AddressData{backends_[1]->port_, ""}); - SetNextReresolutionResponse(balancer_addresses, backend_addresses); - - // Start servers and send 10 RPCs per server. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - // All 10 requests should have gone to the fallback backend. - EXPECT_EQ(10U, backends_[0]->service_.request_count()); - - // Kill backend 0. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); - backends_[0]->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); - - // Wait until re-resolution has finished, as signaled by the second backend - // receiving a request. - WaitForBackend(1); - - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backends_[1]->service_.request_count()); - - balancers_[0]->service_.NotifyDoneWithServerlists(); - balancers_[1]->service_.NotifyDoneWithServerlists(); - balancers_[2]->service_.NotifyDoneWithServerlists(); - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - EXPECT_EQ(0U, balancers_[0]->service_.response_count()); - EXPECT_EQ(0U, balancers_[1]->service_.request_count()); - EXPECT_EQ(0U, balancers_[1]->service_.response_count()); - EXPECT_EQ(0U, balancers_[2]->service_.request_count()); - EXPECT_EQ(0U, balancers_[2]->service_.response_count()); -} - -// TODO(juanlishen): Should be removed when the first response is always the -// initial response. Currently, if client load reporting is not enabled, the -// balancer doesn't send initial response. When the backend shuts down, an -// unexpected re-resolution will happen. This test configuration is a workaround -// for test ReresolveDeadBalancer. -class UpdatesWithClientLoadReportingTest : public GrpclbEnd2endTest { - public: - UpdatesWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 3, 2) {} -}; - -TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { - const std::vector<int> first_backend{GetBackendPorts()[0]}; - const std::vector<int> second_backend{GetBackendPorts()[1]}; - ScheduleResponseForBalancer(0, BuildResponseForBackends(first_backend, {}), - 0); - ScheduleResponseForBalancer(1, BuildResponseForBackends(second_backend, {}), - 0); - - // Ask channel to connect to trigger resolver creation. - channel_->GetState(true); - std::vector<AddressData> addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); - SetNextResolution(addresses); - addresses.clear(); - addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); - SetNextReresolutionResponse(addresses); - - // Start servers and send 10 RPCs per server. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backends_[0]->service_.request_count()); - - // Kill backend 0. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); - backends_[0]->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); - - CheckRpcSendFailure(); - - // Balancer 0 got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - EXPECT_EQ(0U, balancers_[1]->service_.request_count()); - EXPECT_EQ(0U, balancers_[1]->service_.response_count()); - EXPECT_EQ(0U, balancers_[2]->service_.request_count()); - EXPECT_EQ(0U, balancers_[2]->service_.response_count()); - - // Kill balancer 0. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); - balancers_[0]->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); - - // Wait until re-resolution has finished, as signaled by the second backend - // receiving a request. - WaitForBackend(1); - - // This is serviced by the new serverlist. - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backends_[1]->service_.request_count()); - - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - // After balancer 0 is killed, we restart an LB call immediately (because we - // disconnect to a previously connected balancer). Although we will cancel - // this call when the re-resolution update is done and another LB call restart - // is needed, this old call may still succeed reaching the LB server if - // re-resolution is slow. So balancer 1 may have received 2 requests and sent - // 2 responses. - EXPECT_GE(balancers_[1]->service_.request_count(), 1U); - EXPECT_GE(balancers_[1]->service_.response_count(), 1U); - EXPECT_LE(balancers_[1]->service_.request_count(), 2U); - EXPECT_LE(balancers_[1]->service_.response_count(), 2U); - EXPECT_EQ(0U, balancers_[2]->service_.request_count()); - EXPECT_EQ(0U, balancers_[2]->service_.response_count()); -} - -TEST_F(SingleBalancerTest, Drop) { - SetNextResolutionAllBalancers(); - const size_t kNumRpcsPerAddress = 100; - const int num_of_drop_by_rate_limiting_addresses = 1; - const int num_of_drop_by_load_balancing_addresses = 2; - const int num_of_drop_addresses = num_of_drop_by_rate_limiting_addresses + - num_of_drop_by_load_balancing_addresses; - const int num_total_addresses = num_backends_ + num_of_drop_addresses; - ScheduleResponseForBalancer( - 0, - BuildResponseForBackends( - GetBackendPorts(), - {{"rate_limiting", num_of_drop_by_rate_limiting_addresses}, - {"load_balancing", num_of_drop_by_load_balancing_addresses}}), - 0); - // Wait until all backends are ready. - WaitForAllBackends(); - // Send kNumRpcsPerAddress RPCs for each server and drop address. - size_t num_drops = 0; - for (size_t i = 0; i < kNumRpcsPerAddress * num_total_addresses; ++i) { - EchoResponse response; - const Status status = SendRpc(&response); - if (!status.ok() && - status.error_message() == "drop directed by grpclb balancer") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); - EXPECT_EQ(response.message(), kRequestMessage_); - } - } - EXPECT_EQ(kNumRpcsPerAddress * num_of_drop_addresses, num_drops); - // Each backend should have gotten 100 requests. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); - } - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); -} - -TEST_F(SingleBalancerTest, DropAllFirst) { - SetNextResolutionAllBalancers(); - // All registered addresses are marked as "drop". - const int num_of_drop_by_rate_limiting_addresses = 1; - const int num_of_drop_by_load_balancing_addresses = 1; - ScheduleResponseForBalancer( - 0, - BuildResponseForBackends( - {}, {{"rate_limiting", num_of_drop_by_rate_limiting_addresses}, - {"load_balancing", num_of_drop_by_load_balancing_addresses}}), - 0); - const Status status = SendRpc(nullptr, 1000, true); - EXPECT_FALSE(status.ok()); - EXPECT_EQ(status.error_message(), "drop directed by grpclb balancer"); -} - -TEST_F(SingleBalancerTest, DropAll) { - SetNextResolutionAllBalancers(); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - const int num_of_drop_by_rate_limiting_addresses = 1; - const int num_of_drop_by_load_balancing_addresses = 1; - ScheduleResponseForBalancer( - 0, - BuildResponseForBackends( - {}, {{"rate_limiting", num_of_drop_by_rate_limiting_addresses}, - {"load_balancing", num_of_drop_by_load_balancing_addresses}}), - 1000); - - // First call succeeds. - CheckRpcSendOk(); - // But eventually, the update with only dropped servers is processed and calls - // fail. - Status status; - do { - status = SendRpc(nullptr, 1000, true); - } while (status.ok()); - EXPECT_FALSE(status.ok()); - EXPECT_EQ(status.error_message(), "drop directed by grpclb balancer"); -} - -class SingleBalancerWithClientLoadReportingTest : public GrpclbEnd2endTest { - public: - SingleBalancerWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 1, 3) {} -}; - -TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) { - SetNextResolutionAllBalancers(); - const size_t kNumRpcsPerAddress = 100; - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(), {}), 0); - // Wait until all backends are ready. - int num_ok = 0; - int num_failure = 0; - int num_drops = 0; - std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - // Each backend should have gotten 100 requests. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); - } - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - - ClientStats client_stats; - do { - client_stats += WaitForLoadReports(); - } while (client_stats.num_calls_finished != - kNumRpcsPerAddress * num_backends_ + num_ok); - EXPECT_EQ(kNumRpcsPerAddress * num_backends_ + num_ok, - client_stats.num_calls_started); - EXPECT_EQ(kNumRpcsPerAddress * num_backends_ + num_ok, - client_stats.num_calls_finished); - EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send); - EXPECT_EQ(kNumRpcsPerAddress * num_backends_ + (num_ok + num_drops), - client_stats.num_calls_finished_known_received); - EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); -} - -TEST_F(SingleBalancerWithClientLoadReportingTest, BalancerRestart) { - SetNextResolutionAllBalancers(); - const size_t kNumBackendsFirstPass = 2; - const size_t kNumBackendsSecondPass = - backends_.size() - kNumBackendsFirstPass; - // Balancer returns backends starting at index 1. - ScheduleResponseForBalancer( - 0, - BuildResponseForBackends(GetBackendPorts(0, kNumBackendsFirstPass), {}), - 0); - // Wait until all backends returned by the balancer are ready. - int num_ok = 0; - int num_failure = 0; - int num_drops = 0; - std::tie(num_ok, num_failure, num_drops) = - WaitForAllBackends(/* num_requests_multiple_of */ 1, /* start_index */ 0, - /* stop_index */ kNumBackendsFirstPass); - balancers_[0]->service_.NotifyDoneWithServerlists(); - ClientStats client_stats = WaitForLoadReports(); - EXPECT_EQ(static_cast<size_t>(num_ok), client_stats.num_calls_started); - EXPECT_EQ(static_cast<size_t>(num_ok), client_stats.num_calls_finished); - EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send); - EXPECT_EQ(static_cast<size_t>(num_ok), - client_stats.num_calls_finished_known_received); - EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); - // Shut down the balancer. - balancers_[0]->Shutdown(); - // Send 10 more requests per backend. This will continue using the - // last serverlist we received from the balancer before it was shut down. - ResetBackendCounters(); - CheckRpcSendOk(kNumBackendsFirstPass); - // Each backend should have gotten 1 request. - for (size_t i = 0; i < kNumBackendsFirstPass; ++i) { - EXPECT_EQ(1UL, backends_[i]->service_.request_count()); - } - // Now restart the balancer, this time pointing to all backends. - balancers_[0]->Start(server_host_); - ScheduleResponseForBalancer( - 0, BuildResponseForBackends(GetBackendPorts(kNumBackendsFirstPass), {}), - 0); - // Wait for queries to start going to one of the new backends. - // This tells us that we're now using the new serverlist. - do { - CheckRpcSendOk(); - } while (backends_[2]->service_.request_count() == 0 && - backends_[3]->service_.request_count() == 0); - // Send one RPC per backend. - CheckRpcSendOk(kNumBackendsSecondPass); - balancers_[0]->service_.NotifyDoneWithServerlists(); - // Check client stats. - client_stats = WaitForLoadReports(); - EXPECT_EQ(kNumBackendsSecondPass + 1, client_stats.num_calls_started); - EXPECT_EQ(kNumBackendsSecondPass + 1, client_stats.num_calls_finished); - EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send); - EXPECT_EQ(kNumBackendsSecondPass + 1, - client_stats.num_calls_finished_known_received); - EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); -} - -TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { - SetNextResolutionAllBalancers(); - const size_t kNumRpcsPerAddress = 3; - const int num_of_drop_by_rate_limiting_addresses = 2; - const int num_of_drop_by_load_balancing_addresses = 1; - const int num_of_drop_addresses = num_of_drop_by_rate_limiting_addresses + - num_of_drop_by_load_balancing_addresses; - const int num_total_addresses = num_backends_ + num_of_drop_addresses; - ScheduleResponseForBalancer( - 0, - BuildResponseForBackends( - GetBackendPorts(), - {{"rate_limiting", num_of_drop_by_rate_limiting_addresses}, - {"load_balancing", num_of_drop_by_load_balancing_addresses}}), - 0); - // Wait until all backends are ready. - int num_warmup_ok = 0; - int num_warmup_failure = 0; - int num_warmup_drops = 0; - std::tie(num_warmup_ok, num_warmup_failure, num_warmup_drops) = - WaitForAllBackends(num_total_addresses /* num_requests_multiple_of */); - const int num_total_warmup_requests = - num_warmup_ok + num_warmup_failure + num_warmup_drops; - size_t num_drops = 0; - for (size_t i = 0; i < kNumRpcsPerAddress * num_total_addresses; ++i) { - EchoResponse response; - const Status status = SendRpc(&response); - if (!status.ok() && - status.error_message() == "drop directed by grpclb balancer") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); - EXPECT_EQ(response.message(), kRequestMessage_); - } - } - EXPECT_EQ(kNumRpcsPerAddress * num_of_drop_addresses, num_drops); - // Each backend should have gotten 100 requests. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); - } - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); - - const ClientStats client_stats = WaitForLoadReports(); - EXPECT_EQ( - kNumRpcsPerAddress * num_total_addresses + num_total_warmup_requests, - client_stats.num_calls_started); - EXPECT_EQ( - kNumRpcsPerAddress * num_total_addresses + num_total_warmup_requests, - client_stats.num_calls_finished); - EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send); - EXPECT_EQ(kNumRpcsPerAddress * num_backends_ + num_warmup_ok, - client_stats.num_calls_finished_known_received); - // The number of warmup request is a multiple of the number of addresses. - // Therefore, all addresses in the scheduled balancer response are hit the - // same number of times. - const int num_times_drop_addresses_hit = - num_warmup_drops / num_of_drop_addresses; - EXPECT_THAT( - client_stats.drop_token_counts, - ::testing::ElementsAre( - ::testing::Pair("load_balancing", - (kNumRpcsPerAddress + num_times_drop_addresses_hit)), - ::testing::Pair( - "rate_limiting", - (kNumRpcsPerAddress + num_times_drop_addresses_hit) * 2))); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - const auto result = RUN_ALL_TESTS(); - return result; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/hybrid_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/hybrid_end2end_test.cc deleted file mode 100644 index 72b3213bac..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/hybrid_end2end_test.cc +++ /dev/null @@ -1,976 +0,0 @@ -/* - * - * Copyright 2016 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 <memory> -#include <thread> - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/generic/async_generic_service.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/iomgr.h" -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/byte_buffer_proto_helper.h" - -namespace grpc { -namespace testing { -namespace { - -void* tag(int i) { return reinterpret_cast<void*>(i); } - -bool VerifyReturnSuccess(CompletionQueue* cq, int i) { - void* got_tag; - bool ok; - EXPECT_TRUE(cq->Next(&got_tag, &ok)); - EXPECT_EQ(tag(i), got_tag); - return ok; -} - -void Verify(CompletionQueue* cq, int i, bool expect_ok) { - EXPECT_EQ(expect_ok, VerifyReturnSuccess(cq, i)); -} - -// Handlers to handle async request at a server. To be run in a separate thread. -template <class Service> -void HandleEcho(Service* service, ServerCompletionQueue* cq, bool dup_service) { - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - EchoRequest recv_request; - EchoResponse send_response; - service->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq, cq, - tag(1)); - Verify(cq, 1, true); - send_response.set_message(recv_request.message()); - if (dup_service) { - send_response.mutable_message()->append("_dup"); - } - response_writer.Finish(send_response, Status::OK, tag(2)); - Verify(cq, 2, true); -} - -// Handlers to handle raw request at a server. To be run in a -// separate thread. Note that this is the same as the async version, except -// that the req/resp are ByteBuffers -template <class Service> -void HandleRawEcho(Service* service, ServerCompletionQueue* cq, - bool /*dup_service*/) { - ServerContext srv_ctx; - GenericServerAsyncResponseWriter response_writer(&srv_ctx); - ByteBuffer recv_buffer; - service->RequestEcho(&srv_ctx, &recv_buffer, &response_writer, cq, cq, - tag(1)); - Verify(cq, 1, true); - EchoRequest recv_request; - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); - EchoResponse send_response; - send_response.set_message(recv_request.message()); - auto send_buffer = SerializeToByteBuffer(&send_response); - response_writer.Finish(*send_buffer, Status::OK, tag(2)); - Verify(cq, 2, true); -} - -template <class Service> -void HandleClientStreaming(Service* service, ServerCompletionQueue* cq) { - ServerContext srv_ctx; - EchoRequest recv_request; - EchoResponse send_response; - ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx); - service->RequestRequestStream(&srv_ctx, &srv_stream, cq, cq, tag(1)); - Verify(cq, 1, true); - int i = 1; - do { - i++; - send_response.mutable_message()->append(recv_request.message()); - srv_stream.Read(&recv_request, tag(i)); - } while (VerifyReturnSuccess(cq, i)); - srv_stream.Finish(send_response, Status::OK, tag(100)); - Verify(cq, 100, true); -} - -template <class Service> -void HandleRawClientStreaming(Service* service, ServerCompletionQueue* cq) { - ServerContext srv_ctx; - ByteBuffer recv_buffer; - EchoRequest recv_request; - EchoResponse send_response; - GenericServerAsyncReader srv_stream(&srv_ctx); - service->RequestRequestStream(&srv_ctx, &srv_stream, cq, cq, tag(1)); - Verify(cq, 1, true); - int i = 1; - while (true) { - i++; - srv_stream.Read(&recv_buffer, tag(i)); - if (!VerifyReturnSuccess(cq, i)) { - break; - } - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); - send_response.mutable_message()->append(recv_request.message()); - } - auto send_buffer = SerializeToByteBuffer(&send_response); - srv_stream.Finish(*send_buffer, Status::OK, tag(100)); - Verify(cq, 100, true); -} - -template <class Service> -void HandleServerStreaming(Service* service, ServerCompletionQueue* cq) { - ServerContext srv_ctx; - EchoRequest recv_request; - EchoResponse send_response; - ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx); - service->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, cq, cq, - tag(1)); - Verify(cq, 1, true); - send_response.set_message(recv_request.message() + "0"); - srv_stream.Write(send_response, tag(2)); - Verify(cq, 2, true); - send_response.set_message(recv_request.message() + "1"); - srv_stream.Write(send_response, tag(3)); - Verify(cq, 3, true); - send_response.set_message(recv_request.message() + "2"); - srv_stream.Write(send_response, tag(4)); - Verify(cq, 4, true); - srv_stream.Finish(Status::OK, tag(5)); - Verify(cq, 5, true); -} - -void HandleGenericEcho(GenericServerAsyncReaderWriter* stream, - CompletionQueue* cq) { - ByteBuffer recv_buffer; - stream->Read(&recv_buffer, tag(2)); - Verify(cq, 2, true); - EchoRequest recv_request; - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); - EchoResponse send_response; - send_response.set_message(recv_request.message()); - auto send_buffer = SerializeToByteBuffer(&send_response); - stream->Write(*send_buffer, tag(3)); - Verify(cq, 3, true); - stream->Finish(Status::OK, tag(4)); - Verify(cq, 4, true); -} - -void HandleGenericRequestStream(GenericServerAsyncReaderWriter* stream, - CompletionQueue* cq) { - ByteBuffer recv_buffer; - EchoRequest recv_request; - EchoResponse send_response; - int i = 1; - while (true) { - i++; - stream->Read(&recv_buffer, tag(i)); - if (!VerifyReturnSuccess(cq, i)) { - break; - } - EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); - send_response.mutable_message()->append(recv_request.message()); - } - auto send_buffer = SerializeToByteBuffer(&send_response); - stream->Write(*send_buffer, tag(99)); - Verify(cq, 99, true); - stream->Finish(Status::OK, tag(100)); - Verify(cq, 100, true); -} - -// Request and handle one generic call. -void HandleGenericCall(AsyncGenericService* service, - ServerCompletionQueue* cq) { - GenericServerContext srv_ctx; - GenericServerAsyncReaderWriter stream(&srv_ctx); - service->RequestCall(&srv_ctx, &stream, cq, cq, tag(1)); - Verify(cq, 1, true); - if (srv_ctx.method() == "/grpc.testing.EchoTestService/Echo") { - HandleGenericEcho(&stream, cq); - } else if (srv_ctx.method() == - "/grpc.testing.EchoTestService/RequestStream") { - HandleGenericRequestStream(&stream, cq); - } else { // other methods not handled yet. - gpr_log(GPR_ERROR, "method: %s", srv_ctx.method().c_str()); - GPR_ASSERT(0); - } -} - -class TestServiceImplDupPkg - : public ::grpc::testing::duplicate::EchoTestService::Service { - public: - Status Echo(ServerContext* /*context*/, const EchoRequest* request, - EchoResponse* response) override { - response->set_message(request->message() + "_dup"); - return Status::OK; - } -}; - -class HybridEnd2endTest : public ::testing::TestWithParam<bool> { - protected: - HybridEnd2endTest() {} - - static void SetUpTestCase() { -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - } - - void SetUp() override { - inproc_ = (::testing::UnitTest::GetInstance() - ->current_test_info() - ->value_param() != nullptr) - ? GetParam() - : false; - } - - bool SetUpServer(::grpc::Service* service1, ::grpc::Service* service2, - AsyncGenericService* generic_service, - CallbackGenericService* callback_generic_service, - int max_message_size = 0) { - int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; - - // Setup server - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - grpc::InsecureServerCredentials()); - // Always add a sync unimplemented service: we rely on having at least one - // synchronous method to get a listening cq - builder.RegisterService(&unimplemented_service_); - builder.RegisterService(service1); - if (service2) { - builder.RegisterService(service2); - } - if (generic_service) { - builder.RegisterAsyncGenericService(generic_service); - } - if (callback_generic_service) { - builder.RegisterCallbackGenericService(callback_generic_service); - } - - if (max_message_size != 0) { - builder.SetMaxMessageSize(max_message_size); - } - - // Create a separate cq for each potential handler. - for (int i = 0; i < 5; i++) { - cqs_.push_back(builder.AddCompletionQueue(false)); - } - server_ = builder.BuildAndStart(); - - // If there is a generic callback service, this setup is only successful if - // we have an iomgr that can run in the background or are inprocess - return !callback_generic_service || grpc_iomgr_run_in_background() || - inproc_; - } - - void TearDown() override { - if (server_) { - server_->Shutdown(); - } - void* ignored_tag; - bool ignored_ok; - for (auto it = cqs_.begin(); it != cqs_.end(); ++it) { - (*it)->Shutdown(); - while ((*it)->Next(&ignored_tag, &ignored_ok)) { - } - } - } - - void ResetStub() { - std::shared_ptr<Channel> channel = - inproc_ ? server_->InProcessChannel(ChannelArguments()) - : grpc::CreateChannel(server_address_.str(), - InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - - // Test all rpc methods. - void TestAllMethods() { - SendEcho(); - SendSimpleClientStreaming(); - SendSimpleServerStreaming(); - SendBidiStreaming(); - } - - void SendEcho() { - EchoRequest send_request; - EchoResponse recv_response; - ClientContext cli_ctx; - cli_ctx.set_wait_for_ready(true); - send_request.set_message("Hello"); - Status recv_status = stub_->Echo(&cli_ctx, send_request, &recv_response); - EXPECT_EQ(send_request.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } - - void SendEchoToDupService() { - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), InsecureChannelCredentials()); - auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); - EchoRequest send_request; - EchoResponse recv_response; - ClientContext cli_ctx; - cli_ctx.set_wait_for_ready(true); - send_request.set_message("Hello"); - Status recv_status = stub->Echo(&cli_ctx, send_request, &recv_response); - EXPECT_EQ(send_request.message() + "_dup", recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } - - void SendSimpleClientStreaming() { - EchoRequest send_request; - EchoResponse recv_response; - TString expected_message; - ClientContext cli_ctx; - cli_ctx.set_wait_for_ready(true); - send_request.set_message("Hello"); - auto stream = stub_->RequestStream(&cli_ctx, &recv_response); - for (int i = 0; i < 5; i++) { - EXPECT_TRUE(stream->Write(send_request)); - expected_message.append(send_request.message()); - } - stream->WritesDone(); - Status recv_status = stream->Finish(); - EXPECT_EQ(expected_message, recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } - - void SendSimpleServerStreaming() { - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_wait_for_ready(true); - request.set_message("hello"); - - auto stream = stub_->ResponseStream(&context, request); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "0"); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "1"); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "2"); - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); - } - - void SendSimpleServerStreamingToDupService() { - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), InsecureChannelCredentials()); - auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_wait_for_ready(true); - request.set_message("hello"); - - auto stream = stub->ResponseStream(&context, request); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "0_dup"); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "1_dup"); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message() + "2_dup"); - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); - } - - void SendBidiStreaming() { - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_wait_for_ready(true); - TString msg("hello"); - - auto stream = stub_->BidiStream(&context); - - request.set_message(msg + "0"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - request.set_message(msg + "1"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - request.set_message(msg + "2"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - stream->WritesDone(); - EXPECT_FALSE(stream->Read(&response)); - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); - } - - grpc::testing::UnimplementedEchoService::Service unimplemented_service_; - std::vector<std::unique_ptr<ServerCompletionQueue>> cqs_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - bool inproc_; -}; - -TEST_F(HybridEnd2endTest, AsyncEcho) { - typedef EchoTestService::WithAsyncMethod_Echo<TestServiceImpl> SType; - SType service; - SetUpServer(&service, nullptr, nullptr, nullptr); - ResetStub(); - std::thread echo_handler_thread(HandleEcho<SType>, &service, cqs_[0].get(), - false); - TestAllMethods(); - echo_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, RawEcho) { - typedef EchoTestService::WithRawMethod_Echo<TestServiceImpl> SType; - SType service; - SetUpServer(&service, nullptr, nullptr, nullptr); - ResetStub(); - std::thread echo_handler_thread(HandleRawEcho<SType>, &service, cqs_[0].get(), - false); - TestAllMethods(); - echo_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, RawRequestStream) { - typedef EchoTestService::WithRawMethod_RequestStream<TestServiceImpl> SType; - SType service; - SetUpServer(&service, nullptr, nullptr, nullptr); - ResetStub(); - std::thread request_stream_handler_thread(HandleRawClientStreaming<SType>, - &service, cqs_[0].get()); - TestAllMethods(); - request_stream_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, AsyncEchoRawRequestStream) { - typedef EchoTestService::WithRawMethod_RequestStream< - EchoTestService::WithAsyncMethod_Echo<TestServiceImpl>> - SType; - SType service; - SetUpServer(&service, nullptr, nullptr, nullptr); - ResetStub(); - std::thread echo_handler_thread(HandleEcho<SType>, &service, cqs_[0].get(), - false); - std::thread request_stream_handler_thread(HandleRawClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - request_stream_handler_thread.join(); - echo_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, GenericEchoRawRequestStream) { - typedef EchoTestService::WithRawMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo<TestServiceImpl>> - SType; - SType service; - AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service, nullptr); - ResetStub(); - std::thread generic_handler_thread(HandleGenericCall, &generic_service, - cqs_[0].get()); - std::thread request_stream_handler_thread(HandleRawClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - generic_handler_thread.join(); - request_stream_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, AsyncEchoRequestStream) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_Echo<TestServiceImpl>> - SType; - SType service; - SetUpServer(&service, nullptr, nullptr, nullptr); - ResetStub(); - std::thread echo_handler_thread(HandleEcho<SType>, &service, cqs_[0].get(), - false); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - echo_handler_thread.join(); - request_stream_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> - SType; - SType service; - SetUpServer(&service, nullptr, nullptr, nullptr); - ResetStub(); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - response_stream_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service with one sync method. -TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> - SType; - SType service; - TestServiceImplDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, nullptr); - ResetStub(); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - SendEchoToDupService(); - response_stream_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service with one sync streamed unary method. -class StreamedUnaryDupPkg - : public duplicate::EchoTestService::WithStreamedUnaryMethod_Echo< - TestServiceImplDupPkg> { - public: - Status StreamedEcho( - ServerContext* /*context*/, - ServerUnaryStreamer<EchoRequest, EchoResponse>* stream) override { - EchoRequest req; - EchoResponse resp; - uint32_t next_msg_sz; - stream->NextMessageSize(&next_msg_sz); - gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz); - GPR_ASSERT(stream->Read(&req)); - resp.set_message(req.message() + "_dup"); - GPR_ASSERT(stream->Write(resp)); - return Status::OK; - } -}; - -TEST_F(HybridEnd2endTest, - AsyncRequestStreamResponseStream_SyncStreamedUnaryDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> - SType; - SType service; - StreamedUnaryDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); - ResetStub(); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - SendEchoToDupService(); - response_stream_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service that is fully Streamed Unary -class FullyStreamedUnaryDupPkg - : public duplicate::EchoTestService::StreamedUnaryService { - public: - Status StreamedEcho( - ServerContext* /*context*/, - ServerUnaryStreamer<EchoRequest, EchoResponse>* stream) override { - EchoRequest req; - EchoResponse resp; - uint32_t next_msg_sz; - stream->NextMessageSize(&next_msg_sz); - gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz); - GPR_ASSERT(stream->Read(&req)); - resp.set_message(req.message() + "_dup"); - GPR_ASSERT(stream->Write(resp)); - return Status::OK; - } -}; - -TEST_F(HybridEnd2endTest, - AsyncRequestStreamResponseStream_SyncFullyStreamedUnaryDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> - SType; - SType service; - FullyStreamedUnaryDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); - ResetStub(); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - SendEchoToDupService(); - response_stream_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service with one sync split server streaming method. -class SplitResponseStreamDupPkg - : public duplicate::EchoTestService:: - WithSplitStreamingMethod_ResponseStream<TestServiceImplDupPkg> { - public: - Status StreamedResponseStream( - ServerContext* /*context*/, - ServerSplitStreamer<EchoRequest, EchoResponse>* stream) override { - EchoRequest req; - EchoResponse resp; - uint32_t next_msg_sz; - stream->NextMessageSize(&next_msg_sz); - gpr_log(GPR_INFO, "Split Streamed Next Message Size is %u", next_msg_sz); - GPR_ASSERT(stream->Read(&req)); - for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { - resp.set_message(req.message() + ToString(i) + "_dup"); - GPR_ASSERT(stream->Write(resp)); - } - return Status::OK; - } -}; - -TEST_F(HybridEnd2endTest, - AsyncRequestStreamResponseStream_SyncSplitStreamedDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> - SType; - SType service; - SplitResponseStreamDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); - ResetStub(); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - SendSimpleServerStreamingToDupService(); - response_stream_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service that is fully split server streamed -class FullySplitStreamedDupPkg - : public duplicate::EchoTestService::SplitStreamedService { - public: - Status StreamedResponseStream( - ServerContext* /*context*/, - ServerSplitStreamer<EchoRequest, EchoResponse>* stream) override { - EchoRequest req; - EchoResponse resp; - uint32_t next_msg_sz; - stream->NextMessageSize(&next_msg_sz); - gpr_log(GPR_INFO, "Split Streamed Next Message Size is %u", next_msg_sz); - GPR_ASSERT(stream->Read(&req)); - for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { - resp.set_message(req.message() + ToString(i) + "_dup"); - GPR_ASSERT(stream->Write(resp)); - } - return Status::OK; - } -}; - -TEST_F(HybridEnd2endTest, - AsyncRequestStreamResponseStream_FullySplitStreamedDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> - SType; - SType service; - FullySplitStreamedDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); - ResetStub(); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - SendSimpleServerStreamingToDupService(); - response_stream_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service that is fully server streamed -class FullyStreamedDupPkg : public duplicate::EchoTestService::StreamedService { - public: - Status StreamedEcho( - ServerContext* /*context*/, - ServerUnaryStreamer<EchoRequest, EchoResponse>* stream) override { - EchoRequest req; - EchoResponse resp; - uint32_t next_msg_sz; - stream->NextMessageSize(&next_msg_sz); - gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz); - GPR_ASSERT(stream->Read(&req)); - resp.set_message(req.message() + "_dup"); - GPR_ASSERT(stream->Write(resp)); - return Status::OK; - } - Status StreamedResponseStream( - ServerContext* /*context*/, - ServerSplitStreamer<EchoRequest, EchoResponse>* stream) override { - EchoRequest req; - EchoResponse resp; - uint32_t next_msg_sz; - stream->NextMessageSize(&next_msg_sz); - gpr_log(GPR_INFO, "Split Streamed Next Message Size is %u", next_msg_sz); - GPR_ASSERT(stream->Read(&req)); - for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { - resp.set_message(req.message() + ToString(i) + "_dup"); - GPR_ASSERT(stream->Write(resp)); - } - return Status::OK; - } -}; - -TEST_F(HybridEnd2endTest, - AsyncRequestStreamResponseStream_FullyStreamedDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> - SType; - SType service; - FullyStreamedDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); - ResetStub(); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - SendEchoToDupService(); - SendSimpleServerStreamingToDupService(); - response_stream_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service with one async method. -TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> - SType; - SType service; - duplicate::EchoTestService::AsyncService dup_service; - SetUpServer(&service, &dup_service, nullptr, nullptr); - ResetStub(); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - std::thread echo_handler_thread( - HandleEcho<duplicate::EchoTestService::AsyncService>, &dup_service, - cqs_[2].get(), true); - TestAllMethods(); - SendEchoToDupService(); - response_stream_handler_thread.join(); - request_stream_handler_thread.join(); - echo_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, GenericEcho) { - EchoTestService::WithGenericMethod_Echo<TestServiceImpl> service; - AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service, nullptr); - ResetStub(); - std::thread generic_handler_thread(HandleGenericCall, &generic_service, - cqs_[0].get()); - TestAllMethods(); - generic_handler_thread.join(); -} - -TEST_P(HybridEnd2endTest, CallbackGenericEcho) { - EchoTestService::WithGenericMethod_Echo<TestServiceImpl> service; - class GenericEchoService : public CallbackGenericService { - private: - ServerGenericBidiReactor* CreateReactor( - GenericCallbackServerContext* context) override { - EXPECT_EQ(context->method(), "/grpc.testing.EchoTestService/Echo"); - gpr_log(GPR_DEBUG, "Constructor of generic service %d", - static_cast<int>(context->deadline().time_since_epoch().count())); - - class Reactor : public ServerGenericBidiReactor { - public: - Reactor() { StartRead(&request_); } - - private: - void OnDone() override { delete this; } - void OnReadDone(bool ok) override { - if (!ok) { - EXPECT_EQ(reads_complete_, 1); - } else { - EXPECT_EQ(reads_complete_++, 0); - response_ = request_; - StartWrite(&response_); - StartRead(&request_); - } - } - void OnWriteDone(bool ok) override { - Finish(ok ? Status::OK - : Status(StatusCode::UNKNOWN, "Unexpected failure")); - } - ByteBuffer request_; - ByteBuffer response_; - std::atomic_int reads_complete_{0}; - }; - return new Reactor; - } - } generic_service; - - if (!SetUpServer(&service, nullptr, nullptr, &generic_service)) { - return; - } - ResetStub(); - TestAllMethods(); -} - -TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo<TestServiceImpl>> - SType; - SType service; - AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service, nullptr); - ResetStub(); - std::thread generic_handler_thread(HandleGenericCall, &generic_service, - cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - generic_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service with one sync method. -TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_SyncDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo<TestServiceImpl>> - SType; - SType service; - AsyncGenericService generic_service; - TestServiceImplDupPkg dup_service; - SetUpServer(&service, &dup_service, &generic_service, nullptr); - ResetStub(); - std::thread generic_handler_thread(HandleGenericCall, &generic_service, - cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - TestAllMethods(); - SendEchoToDupService(); - generic_handler_thread.join(); - request_stream_handler_thread.join(); -} - -// Add a second service with one async method. -TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_AsyncDupService) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo<TestServiceImpl>> - SType; - SType service; - AsyncGenericService generic_service; - duplicate::EchoTestService::AsyncService dup_service; - SetUpServer(&service, &dup_service, &generic_service, nullptr); - ResetStub(); - std::thread generic_handler_thread(HandleGenericCall, &generic_service, - cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - std::thread echo_handler_thread( - HandleEcho<duplicate::EchoTestService::AsyncService>, &dup_service, - cqs_[2].get(), true); - TestAllMethods(); - SendEchoToDupService(); - generic_handler_thread.join(); - request_stream_handler_thread.join(); - echo_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStreamResponseStream) { - typedef EchoTestService::WithAsyncMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>>> - SType; - SType service; - AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service, nullptr); - ResetStub(); - std::thread generic_handler_thread(HandleGenericCall, &generic_service, - cqs_[0].get()); - std::thread request_stream_handler_thread(HandleClientStreaming<SType>, - &service, cqs_[1].get()); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[2].get()); - TestAllMethods(); - generic_handler_thread.join(); - request_stream_handler_thread.join(); - response_stream_handler_thread.join(); -} - -TEST_F(HybridEnd2endTest, GenericEchoRequestStreamAsyncResponseStream) { - typedef EchoTestService::WithGenericMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>>> - SType; - SType service; - AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service, nullptr); - ResetStub(); - std::thread generic_handler_thread(HandleGenericCall, &generic_service, - cqs_[0].get()); - std::thread generic_handler_thread2(HandleGenericCall, &generic_service, - cqs_[1].get()); - std::thread response_stream_handler_thread(HandleServerStreaming<SType>, - &service, cqs_[2].get()); - TestAllMethods(); - generic_handler_thread.join(); - generic_handler_thread2.join(); - response_stream_handler_thread.join(); -} - -// If WithGenericMethod is called and no generic service is registered, the -// server will fail to build. -TEST_F(HybridEnd2endTest, GenericMethodWithoutGenericService) { - EchoTestService::WithGenericMethod_RequestStream< - EchoTestService::WithGenericMethod_Echo< - EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>>> - service; - SetUpServer(&service, nullptr, nullptr, nullptr); - EXPECT_EQ(nullptr, server_.get()); -} - -INSTANTIATE_TEST_SUITE_P(HybridEnd2endTest, HybridEnd2endTest, - ::testing::Bool()); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/message_allocator_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/message_allocator_end2end_test.cc deleted file mode 100644 index 04b8be75b8..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/message_allocator_end2end_test.cc +++ /dev/null @@ -1,400 +0,0 @@ -/* - * - * Copyright 2019 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 <algorithm> -#include <atomic> -#include <condition_variable> -#include <functional> -#include <memory> -#include <mutex> -#include <sstream> -#include <thread> - -#include <google/protobuf/arena.h> -#include <gtest/gtest.h> - -#include <grpc/impl/codegen/log.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/client_callback.h> -#include <grpcpp/support/message_allocator.h> - -#include "src/core/lib/iomgr/iomgr.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/test_credentials_provider.h" - -namespace grpc { -namespace testing { -namespace { - -class CallbackTestServiceImpl : public EchoTestService::CallbackService { - public: - explicit CallbackTestServiceImpl() {} - - void SetAllocatorMutator( - std::function<void(RpcAllocatorState* allocator_state, - const EchoRequest* req, EchoResponse* resp)> - mutator) { - allocator_mutator_ = std::move(mutator); - } - - ServerUnaryReactor* Echo(CallbackServerContext* context, - const EchoRequest* request, - EchoResponse* response) override { - response->set_message(request->message()); - if (allocator_mutator_) { - allocator_mutator_(context->GetRpcAllocatorState(), request, response); - } - auto* reactor = context->DefaultReactor(); - reactor->Finish(Status::OK); - return reactor; - } - - private: - std::function<void(RpcAllocatorState* allocator_state, const EchoRequest* req, - EchoResponse* resp)> - allocator_mutator_; -}; - -enum class Protocol { INPROC, TCP }; - -class TestScenario { - public: - TestScenario(Protocol protocol, const TString& creds_type) - : protocol(protocol), credentials_type(creds_type) {} - void Log() const; - Protocol protocol; - const TString credentials_type; -}; - -std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { - return out << "TestScenario{protocol=" - << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") - << "," << scenario.credentials_type << "}"; -} - -void TestScenario::Log() const { - std::ostringstream out; - out << *this; - gpr_log(GPR_INFO, "%s", out.str().c_str()); -} - -class MessageAllocatorEnd2endTestBase - : public ::testing::TestWithParam<TestScenario> { - protected: - MessageAllocatorEnd2endTestBase() { GetParam().Log(); } - - ~MessageAllocatorEnd2endTestBase() override = default; - - void CreateServer(MessageAllocator<EchoRequest, EchoResponse>* allocator) { - ServerBuilder builder; - - auto server_creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - if (GetParam().protocol == Protocol::TCP) { - picked_port_ = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << picked_port_; - builder.AddListeningPort(server_address_.str(), server_creds); - } - callback_service_.SetMessageAllocatorFor_Echo(allocator); - builder.RegisterService(&callback_service_); - - server_ = builder.BuildAndStart(); - } - - void DestroyServer() { - if (server_) { - server_->Shutdown(); - server_.reset(); - } - } - - void ResetStub() { - ChannelArguments args; - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - switch (GetParam().protocol) { - case Protocol::TCP: - channel_ = ::grpc::CreateCustomChannel(server_address_.str(), - channel_creds, args); - break; - case Protocol::INPROC: - channel_ = server_->InProcessChannel(args); - break; - default: - assert(false); - } - stub_ = EchoTestService::NewStub(channel_); - } - - void TearDown() override { - DestroyServer(); - if (picked_port_ > 0) { - grpc_recycle_unused_port(picked_port_); - } - } - - void SendRpcs(int num_rpcs) { - TString test_string(""); - for (int i = 0; i < num_rpcs; i++) { - EchoRequest request; - EchoResponse response; - ClientContext cli_ctx; - - test_string += TString(1024, 'x'); - request.set_message(test_string); - TString val; - cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); - - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub_->async()->Echo( - &cli_ctx, &request, &response, - [&request, &response, &done, &mu, &cv, val](Status s) { - GPR_ASSERT(s.ok()); - - EXPECT_EQ(request.message(), response.message()); - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } - } - } - - int picked_port_{0}; - std::shared_ptr<Channel> channel_; - std::unique_ptr<EchoTestService::Stub> stub_; - CallbackTestServiceImpl callback_service_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; -}; - -class NullAllocatorTest : public MessageAllocatorEnd2endTestBase {}; - -TEST_P(NullAllocatorTest, SimpleRpc) { - CreateServer(nullptr); - ResetStub(); - SendRpcs(1); -} - -class SimpleAllocatorTest : public MessageAllocatorEnd2endTestBase { - public: - class SimpleAllocator : public MessageAllocator<EchoRequest, EchoResponse> { - public: - class MessageHolderImpl : public MessageHolder<EchoRequest, EchoResponse> { - public: - MessageHolderImpl(std::atomic_int* request_deallocation_count, - std::atomic_int* messages_deallocation_count) - : request_deallocation_count_(request_deallocation_count), - messages_deallocation_count_(messages_deallocation_count) { - set_request(new EchoRequest); - set_response(new EchoResponse); - } - void Release() override { - (*messages_deallocation_count_)++; - delete request(); - delete response(); - delete this; - } - void FreeRequest() override { - (*request_deallocation_count_)++; - delete request(); - set_request(nullptr); - } - - EchoRequest* ReleaseRequest() { - auto* ret = request(); - set_request(nullptr); - return ret; - } - - private: - std::atomic_int* const request_deallocation_count_; - std::atomic_int* const messages_deallocation_count_; - }; - MessageHolder<EchoRequest, EchoResponse>* AllocateMessages() override { - allocation_count++; - return new MessageHolderImpl(&request_deallocation_count, - &messages_deallocation_count); - } - int allocation_count = 0; - std::atomic_int request_deallocation_count{0}; - std::atomic_int messages_deallocation_count{0}; - }; -}; - -TEST_P(SimpleAllocatorTest, SimpleRpc) { - const int kRpcCount = 10; - std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); - CreateServer(allocator.get()); - ResetStub(); - SendRpcs(kRpcCount); - // messages_deallocaton_count is updated in Release after server side OnDone. - // Destroy server to make sure it has been updated. - DestroyServer(); - EXPECT_EQ(kRpcCount, allocator->allocation_count); - EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); - EXPECT_EQ(0, allocator->request_deallocation_count); -} - -TEST_P(SimpleAllocatorTest, RpcWithEarlyFreeRequest) { - const int kRpcCount = 10; - std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); - auto mutator = [](RpcAllocatorState* allocator_state, const EchoRequest* req, - EchoResponse* resp) { - auto* info = - static_cast<SimpleAllocator::MessageHolderImpl*>(allocator_state); - EXPECT_EQ(req, info->request()); - EXPECT_EQ(resp, info->response()); - allocator_state->FreeRequest(); - EXPECT_EQ(nullptr, info->request()); - }; - callback_service_.SetAllocatorMutator(mutator); - CreateServer(allocator.get()); - ResetStub(); - SendRpcs(kRpcCount); - // messages_deallocaton_count is updated in Release after server side OnDone. - // Destroy server to make sure it has been updated. - DestroyServer(); - EXPECT_EQ(kRpcCount, allocator->allocation_count); - EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); - EXPECT_EQ(kRpcCount, allocator->request_deallocation_count); -} - -TEST_P(SimpleAllocatorTest, RpcWithReleaseRequest) { - const int kRpcCount = 10; - std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); - std::vector<EchoRequest*> released_requests; - auto mutator = [&released_requests](RpcAllocatorState* allocator_state, - const EchoRequest* req, - EchoResponse* resp) { - auto* info = - static_cast<SimpleAllocator::MessageHolderImpl*>(allocator_state); - EXPECT_EQ(req, info->request()); - EXPECT_EQ(resp, info->response()); - released_requests.push_back(info->ReleaseRequest()); - EXPECT_EQ(nullptr, info->request()); - }; - callback_service_.SetAllocatorMutator(mutator); - CreateServer(allocator.get()); - ResetStub(); - SendRpcs(kRpcCount); - // messages_deallocaton_count is updated in Release after server side OnDone. - // Destroy server to make sure it has been updated. - DestroyServer(); - EXPECT_EQ(kRpcCount, allocator->allocation_count); - EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); - EXPECT_EQ(0, allocator->request_deallocation_count); - EXPECT_EQ(static_cast<unsigned>(kRpcCount), released_requests.size()); - for (auto* req : released_requests) { - delete req; - } -} - -class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { - public: - class ArenaAllocator : public MessageAllocator<EchoRequest, EchoResponse> { - public: - class MessageHolderImpl : public MessageHolder<EchoRequest, EchoResponse> { - public: - MessageHolderImpl() { - set_request( - google::protobuf::Arena::CreateMessage<EchoRequest>(&arena_)); - set_response( - google::protobuf::Arena::CreateMessage<EchoResponse>(&arena_)); - } - void Release() override { delete this; } - void FreeRequest() override { GPR_ASSERT(0); } - - private: - google::protobuf::Arena arena_; - }; - MessageHolder<EchoRequest, EchoResponse>* AllocateMessages() override { - allocation_count++; - return new MessageHolderImpl; - } - int allocation_count = 0; - }; -}; - -TEST_P(ArenaAllocatorTest, SimpleRpc) { - const int kRpcCount = 10; - std::unique_ptr<ArenaAllocator> allocator(new ArenaAllocator); - CreateServer(allocator.get()); - ResetStub(); - SendRpcs(kRpcCount); - EXPECT_EQ(kRpcCount, allocator->allocation_count); -} - -std::vector<TestScenario> CreateTestScenarios(bool test_insecure) { - std::vector<TestScenario> scenarios; - std::vector<TString> credentials_types{ - GetCredentialsProvider()->GetSecureCredentialsTypeList()}; - auto insec_ok = [] { - // Only allow insecure credentials type when it is registered with the - // provider. User may create providers that do not have insecure. - return GetCredentialsProvider()->GetChannelCredentials( - kInsecureCredentialsType, nullptr) != nullptr; - }; - if (test_insecure && insec_ok()) { - credentials_types.push_back(kInsecureCredentialsType); - } - GPR_ASSERT(!credentials_types.empty()); - - Protocol parr[]{Protocol::INPROC, Protocol::TCP}; - for (Protocol p : parr) { - for (const auto& cred : credentials_types) { - // TODO(vjpai): Test inproc with secure credentials when feasible - if (p == Protocol::INPROC && - (cred != kInsecureCredentialsType || !insec_ok())) { - continue; - } - scenarios.emplace_back(p, cred); - } - } - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P(NullAllocatorTest, NullAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); -INSTANTIATE_TEST_SUITE_P(SimpleAllocatorTest, SimpleAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); -INSTANTIATE_TEST_SUITE_P(ArenaAllocatorTest, ArenaAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/mock_test.cc b/contrib/libs/grpc/test/cpp/end2end/mock_test.cc deleted file mode 100644 index dc4b34e21d..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/mock_test.cc +++ /dev/null @@ -1,433 +0,0 @@ -/* - * - * Copyright 2015 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 <climits> -#include <iostream> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include "y_absl/types/optional.h" - -#include <grpc/grpc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/test/default_reactor_test_peer.h> -#include <grpcpp/test/mock_stream.h> - -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "src/proto/grpc/testing/echo_mock.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -using grpc::testing::DefaultReactorTestPeer; -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using grpc::testing::EchoTestService; -using grpc::testing::MockClientReaderWriter; -using std::vector; -using ::testing::_; -using ::testing::AtLeast; -using ::testing::DoAll; -using ::testing::Return; -using ::testing::SaveArg; -using ::testing::SetArgPointee; -using ::testing::WithArg; - -namespace grpc { -namespace testing { - -namespace { -class FakeClient { - public: - explicit FakeClient(EchoTestService::StubInterface* stub) : stub_(stub) {} - - void DoEcho() { - ClientContext context; - EchoRequest request; - EchoResponse response; - request.set_message("hello world"); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(request.message(), response.message()); - EXPECT_TRUE(s.ok()); - } - - void DoRequestStream() { - EchoRequest request; - EchoResponse response; - - ClientContext context; - TString msg("hello"); - TString exp(msg); - - std::unique_ptr<ClientWriterInterface<EchoRequest>> cstream = - stub_->RequestStream(&context, &response); - - request.set_message(msg); - EXPECT_TRUE(cstream->Write(request)); - - msg = ", world"; - request.set_message(msg); - exp.append(msg); - EXPECT_TRUE(cstream->Write(request)); - - cstream->WritesDone(); - Status s = cstream->Finish(); - - EXPECT_EQ(exp, response.message()); - EXPECT_TRUE(s.ok()); - } - - void DoResponseStream() { - EchoRequest request; - EchoResponse response; - request.set_message("hello world"); - - ClientContext context; - std::unique_ptr<ClientReaderInterface<EchoResponse>> cstream = - stub_->ResponseStream(&context, request); - - TString exp = ""; - EXPECT_TRUE(cstream->Read(&response)); - exp.append(response.message() + " "); - - EXPECT_TRUE(cstream->Read(&response)); - exp.append(response.message()); - - EXPECT_FALSE(cstream->Read(&response)); - EXPECT_EQ(request.message(), exp); - - Status s = cstream->Finish(); - EXPECT_TRUE(s.ok()); - } - - void DoBidiStream() { - EchoRequest request; - EchoResponse response; - ClientContext context; - TString msg("hello"); - - std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>> - stream = stub_->BidiStream(&context); - - request.set_message(msg + "0"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - request.set_message(msg + "1"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - request.set_message(msg + "2"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(response.message(), request.message()); - - stream->WritesDone(); - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - EXPECT_TRUE(s.ok()); - } - - void ResetStub(EchoTestService::StubInterface* stub) { stub_ = stub; } - - private: - EchoTestService::StubInterface* stub_; -}; - -class CallbackTestServiceImpl : public EchoTestService::CallbackService { - public: - ServerUnaryReactor* Echo(CallbackServerContext* context, - const EchoRequest* request, - EchoResponse* response) override { - // Make the mock service explicitly treat empty input messages as invalid - // arguments so that we can test various results of status. In general, a - // mocked service should just use the original service methods, but we are - // adding this variance in Status return value just to improve coverage in - // this test. - auto* reactor = context->DefaultReactor(); - if (request->message().length() > 0) { - response->set_message(request->message()); - reactor->Finish(Status::OK); - } else { - reactor->Finish(Status(StatusCode::INVALID_ARGUMENT, "Invalid request")); - } - return reactor; - } -}; - -class MockCallbackTest : public ::testing::Test { - protected: - CallbackTestServiceImpl service_; - ServerContext context_; -}; - -TEST_F(MockCallbackTest, MockedCallSucceedsWithWait) { - CallbackServerContext ctx; - EchoRequest req; - EchoResponse resp; - struct { - grpc::internal::Mutex mu; - grpc::internal::CondVar cv; - y_absl::optional<grpc::Status> Y_ABSL_GUARDED_BY(mu) status; - } status; - DefaultReactorTestPeer peer(&ctx, [&](::grpc::Status s) { - grpc::internal::MutexLock l(&status.mu); - status.status = std::move(s); - status.cv.Signal(); - }); - - req.set_message("mock 1"); - auto* reactor = service_.Echo(&ctx, &req, &resp); - - grpc::internal::MutexLock l(&status.mu); - while (!status.status.has_value()) { - status.cv.Wait(&status.mu); - } - - EXPECT_EQ(reactor, peer.reactor()); - EXPECT_TRUE(peer.test_status_set()); - EXPECT_TRUE(peer.test_status().ok()); - EXPECT_TRUE(status.status.has_value()); - EXPECT_TRUE(status.status.value().ok()); - EXPECT_EQ(req.message(), resp.message()); -} - -TEST_F(MockCallbackTest, MockedCallSucceeds) { - CallbackServerContext ctx; - EchoRequest req; - EchoResponse resp; - DefaultReactorTestPeer peer(&ctx); - - req.set_message("ha ha, consider yourself mocked."); - auto* reactor = service_.Echo(&ctx, &req, &resp); - EXPECT_EQ(reactor, peer.reactor()); - EXPECT_TRUE(peer.test_status_set()); - EXPECT_TRUE(peer.test_status().ok()); -} - -TEST_F(MockCallbackTest, MockedCallFails) { - CallbackServerContext ctx; - EchoRequest req; - EchoResponse resp; - DefaultReactorTestPeer peer(&ctx); - - auto* reactor = service_.Echo(&ctx, &req, &resp); - EXPECT_EQ(reactor, peer.reactor()); - EXPECT_TRUE(peer.test_status_set()); - EXPECT_EQ(peer.test_status().error_code(), StatusCode::INVALID_ARGUMENT); -} - -class TestServiceImpl : public EchoTestService::Service { - public: - Status Echo(ServerContext* /*context*/, const EchoRequest* request, - EchoResponse* response) override { - response->set_message(request->message()); - return Status::OK; - } - - Status RequestStream(ServerContext* /*context*/, - ServerReader<EchoRequest>* reader, - EchoResponse* response) override { - EchoRequest request; - TString resp(""); - while (reader->Read(&request)) { - gpr_log(GPR_INFO, "recv msg %s", request.message().c_str()); - resp.append(request.message()); - } - response->set_message(resp); - return Status::OK; - } - - Status ResponseStream(ServerContext* /*context*/, const EchoRequest* request, - ServerWriter<EchoResponse>* writer) override { - EchoResponse response; - vector<TString> tokens = split(request->message()); - for (const TString& token : tokens) { - response.set_message(token); - writer->Write(response); - } - return Status::OK; - } - - Status BidiStream( - ServerContext* /*context*/, - ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { - EchoRequest request; - EchoResponse response; - while (stream->Read(&request)) { - gpr_log(GPR_INFO, "recv msg %s", request.message().c_str()); - response.set_message(request.message()); - stream->Write(response); - } - return Status::OK; - } - - private: - vector<TString> split(const TString& input) { - TString buff(""); - vector<TString> result; - - for (auto n : input) { - if (n != ' ') { - buff += n; - continue; - } - if (buff.empty()) continue; - result.push_back(buff); - buff = ""; - } - if (!buff.empty()) result.push_back(buff); - - return result; - } -}; - -class MockTest : public ::testing::Test { - protected: - MockTest() {} - - void SetUp() override { - int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; - // Setup server - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - void TearDown() override { server_->Shutdown(); } - - void ResetStub() { - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - TestServiceImpl service_; -}; - -// Do one real rpc and one mocked one -TEST_F(MockTest, SimpleRpc) { - ResetStub(); - FakeClient client(stub_.get()); - client.DoEcho(); - MockEchoTestServiceStub stub; - EchoResponse resp; - resp.set_message("hello world"); - EXPECT_CALL(stub, Echo(_, _, _)) - .Times(AtLeast(1)) - .WillOnce(DoAll(SetArgPointee<2>(resp), Return(Status::OK))); - client.ResetStub(&stub); - client.DoEcho(); -} - -TEST_F(MockTest, ClientStream) { - ResetStub(); - FakeClient client(stub_.get()); - client.DoRequestStream(); - - MockEchoTestServiceStub stub; - auto w = new MockClientWriter<EchoRequest>(); - EchoResponse resp; - resp.set_message("hello, world"); - - EXPECT_CALL(*w, Write(_, _)).Times(2).WillRepeatedly(Return(true)); - EXPECT_CALL(*w, WritesDone()); - EXPECT_CALL(*w, Finish()).WillOnce(Return(Status::OK)); - - EXPECT_CALL(stub, RequestStreamRaw(_, _)) - .WillOnce(DoAll(SetArgPointee<1>(resp), Return(w))); - client.ResetStub(&stub); - client.DoRequestStream(); -} - -TEST_F(MockTest, ServerStream) { - ResetStub(); - FakeClient client(stub_.get()); - client.DoResponseStream(); - - MockEchoTestServiceStub stub; - auto r = new MockClientReader<EchoResponse>(); - EchoResponse resp1; - resp1.set_message("hello"); - EchoResponse resp2; - resp2.set_message("world"); - - EXPECT_CALL(*r, Read(_)) - .WillOnce(DoAll(SetArgPointee<0>(resp1), Return(true))) - .WillOnce(DoAll(SetArgPointee<0>(resp2), Return(true))) - .WillOnce(Return(false)); - EXPECT_CALL(*r, Finish()).WillOnce(Return(Status::OK)); - - EXPECT_CALL(stub, ResponseStreamRaw(_, _)).WillOnce(Return(r)); - - client.ResetStub(&stub); - client.DoResponseStream(); -} - -ACTION_P(copy, msg) { arg0->set_message(msg->message()); } - -TEST_F(MockTest, BidiStream) { - ResetStub(); - FakeClient client(stub_.get()); - client.DoBidiStream(); - MockEchoTestServiceStub stub; - auto rw = new MockClientReaderWriter<EchoRequest, EchoResponse>(); - EchoRequest msg; - - EXPECT_CALL(*rw, Write(_, _)) - .Times(3) - .WillRepeatedly(DoAll(SaveArg<0>(&msg), Return(true))); - EXPECT_CALL(*rw, Read(_)) - .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true))) - .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true))) - .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true))) - .WillOnce(Return(false)); - EXPECT_CALL(*rw, WritesDone()); - EXPECT_CALL(*rw, Finish()).WillOnce(Return(Status::OK)); - - EXPECT_CALL(stub, BidiStreamRaw(_)).WillOnce(Return(rw)); - client.ResetStub(&stub); - client.DoBidiStream(); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/nonblocking_test.cc b/contrib/libs/grpc/test/cpp/end2end/nonblocking_test.cc deleted file mode 100644 index 392e7de21e..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/nonblocking_test.cc +++ /dev/null @@ -1,218 +0,0 @@ -/* - * - * Copyright 2018 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 <memory> - -#include "y_absl/memory/memory.h" - -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/tls.h" -#include "src/core/lib/iomgr/port.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -#ifdef GRPC_POSIX_SOCKET -#include "src/core/lib/iomgr/ev_posix.h" -#endif // GRPC_POSIX_SOCKET - -#include <gtest/gtest.h> - -#ifdef GRPC_POSIX_SOCKET -// Thread-local variable to so that only polls from this test assert -// non-blocking (not polls from resolver, timer thread, etc), and only when the -// thread is waiting on polls caused by CompletionQueue::AsyncNext (not for -// picking a port or other reasons). -static GPR_THREAD_LOCAL(bool) g_is_nonblocking_poll; - -namespace { - -int maybe_assert_non_blocking_poll(struct pollfd* pfds, nfds_t nfds, - int timeout) { - // Only assert that this poll should have zero timeout if we're in the - // middle of a zero-timeout CQ Next. - if (g_is_nonblocking_poll) { - GPR_ASSERT(timeout == 0); - } - return poll(pfds, nfds, timeout); -} - -} // namespace - -namespace grpc { -namespace testing { -namespace { - -void* tag(int i) { return reinterpret_cast<void*>(static_cast<intptr_t>(i)); } -int detag(void* p) { return static_cast<int>(reinterpret_cast<intptr_t>(p)); } - -class NonblockingTest : public ::testing::Test { - protected: - NonblockingTest() {} - - void SetUp() override { - port_ = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port_; - - // Setup server - BuildAndStartServer(); - } - - bool LoopForTag(void** tag, bool* ok) { - // Temporarily set the thread-local nonblocking poll flag so that the polls - // caused by this loop are indeed sent by the library with zero timeout. - bool orig_val = g_is_nonblocking_poll; - g_is_nonblocking_poll = true; - for (;;) { - auto r = cq_->AsyncNext(tag, ok, gpr_time_0(GPR_CLOCK_REALTIME)); - if (r == CompletionQueue::SHUTDOWN) { - g_is_nonblocking_poll = orig_val; - return false; - } else if (r == CompletionQueue::GOT_EVENT) { - g_is_nonblocking_poll = orig_val; - return true; - } - } - } - - void TearDown() override { - server_->Shutdown(); - void* ignored_tag; - bool ignored_ok; - cq_->Shutdown(); - while (LoopForTag(&ignored_tag, &ignored_ok)) { - } - stub_.reset(); - grpc_recycle_unused_port(port_); - } - - void BuildAndStartServer() { - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - grpc::InsecureServerCredentials()); - service_ = - y_absl::make_unique<grpc::testing::EchoTestService::AsyncService>(); - builder.RegisterService(service_.get()); - cq_ = builder.AddCompletionQueue(); - server_ = builder.BuildAndStart(); - } - - void ResetStub() { - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), grpc::InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - - void SendRpc(int num_rpcs) { - for (int i = 0; i < num_rpcs; i++) { - EchoRequest send_request; - EchoRequest recv_request; - EchoResponse send_response; - EchoResponse recv_response; - Status recv_status; - - ClientContext cli_ctx; - ServerContext srv_ctx; - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx); - - send_request.set_message("hello non-blocking world"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->PrepareAsyncEcho(&cli_ctx, send_request, cq_.get())); - - response_reader->StartCall(); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - - service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, - cq_.get(), cq_.get(), tag(2)); - - void* got_tag; - bool ok; - EXPECT_TRUE(LoopForTag(&got_tag, &ok)); - EXPECT_TRUE(ok); - EXPECT_EQ(detag(got_tag), 2); - EXPECT_EQ(send_request.message(), recv_request.message()); - - send_response.set_message(recv_request.message()); - response_writer.Finish(send_response, Status::OK, tag(3)); - - int tagsum = 0; - int tagprod = 1; - EXPECT_TRUE(LoopForTag(&got_tag, &ok)); - EXPECT_TRUE(ok); - tagsum += detag(got_tag); - tagprod *= detag(got_tag); - - EXPECT_TRUE(LoopForTag(&got_tag, &ok)); - EXPECT_TRUE(ok); - tagsum += detag(got_tag); - tagprod *= detag(got_tag); - - EXPECT_EQ(tagsum, 7); - EXPECT_EQ(tagprod, 12); - EXPECT_EQ(send_response.message(), recv_response.message()); - EXPECT_TRUE(recv_status.ok()); - } - } - - std::unique_ptr<ServerCompletionQueue> cq_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::unique_ptr<grpc::testing::EchoTestService::AsyncService> service_; - std::ostringstream server_address_; - int port_; -}; - -TEST_F(NonblockingTest, SimpleRpc) { - ResetStub(); - SendRpc(10); -} - -} // namespace -} // namespace testing -} // namespace grpc - -#endif // GRPC_POSIX_SOCKET - -int main(int argc, char** argv) { -#ifdef GRPC_POSIX_SOCKET - // Override the poll function before anything else can happen - grpc_poll_function = maybe_assert_non_blocking_poll; - - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - - // Start the nonblocking poll thread-local variable as false because the - // thread that issues RPCs starts by picking a port (which has non-zero - // timeout). - g_is_nonblocking_poll = false; - - int ret = RUN_ALL_TESTS(); - - return ret; -#else // GRPC_POSIX_SOCKET - (void)argc; - (void)argv; - return 0; -#endif // GRPC_POSIX_SOCKET -} diff --git a/contrib/libs/grpc/test/cpp/end2end/port_sharing_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/port_sharing_end2end_test.cc deleted file mode 100644 index 96ecc4cc76..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/port_sharing_end2end_test.cc +++ /dev/null @@ -1,374 +0,0 @@ -/* - * - * Copyright 2019 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 <mutex> -#include <thread> - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/endpoint.h" -#include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/iomgr/pollset.h" -#include "src/core/lib/iomgr/port.h" -#include "src/core/lib/iomgr/tcp_server.h" -#include "src/core/lib/security/credentials/credentials.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/core/util/test_tcp_server.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_credentials_provider.h" - -#ifdef GRPC_POSIX_SOCKET_TCP_SERVER - -#include "src/core/lib/iomgr/tcp_posix.h" - -namespace grpc { -namespace testing { -namespace { - -class TestScenario { - public: - TestScenario(bool server_port, bool pending_data, - const TString& creds_type) - : server_has_port(server_port), - queue_pending_data(pending_data), - credentials_type(creds_type) {} - void Log() const; - // server has its own port or not - bool server_has_port; - // whether tcp server should read some data before handoff - bool queue_pending_data; - const TString credentials_type; -}; - -std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { - return out << "TestScenario{server_has_port=" - << (scenario.server_has_port ? "true" : "false") - << ", queue_pending_data=" - << (scenario.queue_pending_data ? "true" : "false") - << ", credentials='" << scenario.credentials_type << "'}"; -} - -void TestScenario::Log() const { - std::ostringstream out; - out << *this; - gpr_log(GPR_ERROR, "%s", out.str().c_str()); -} - -// Set up a test tcp server which is in charge of accepting connections and -// handing off the connections as fds. -class TestTcpServer { - public: - TestTcpServer() - : shutdown_(false), - queue_data_(false), - port_(grpc_pick_unused_port_or_die()) { - std::ostringstream server_address; - server_address << "localhost:" << port_; - address_ = server_address.str(); - test_tcp_server_init(&tcp_server_, &TestTcpServer::OnConnect, this); - GRPC_CLOSURE_INIT(&on_fd_released_, &TestTcpServer::OnFdReleased, this, - grpc_schedule_on_exec_ctx); - } - - ~TestTcpServer() { - running_thread_.join(); - test_tcp_server_destroy(&tcp_server_); - grpc_recycle_unused_port(port_); - } - - // Read some data before handing off the connection. - void SetQueueData() { queue_data_ = true; } - - void Start() { - test_tcp_server_start(&tcp_server_, port_); - gpr_log(GPR_INFO, "Test TCP server started at %s", address_.c_str()); - } - - const TString& address() { return address_; } - - void SetAcceptor( - std::unique_ptr<experimental::ExternalConnectionAcceptor> acceptor) { - connection_acceptor_ = std::move(acceptor); - } - - void Run() { - running_thread_ = std::thread([this]() { - while (true) { - { - std::lock_guard<std::mutex> lock(mu_); - if (shutdown_) { - return; - } - } - test_tcp_server_poll(&tcp_server_, 1); - } - }); - } - - void Shutdown() { - std::lock_guard<std::mutex> lock(mu_); - shutdown_ = true; - } - - static void OnConnect(void* arg, grpc_endpoint* tcp, - grpc_pollset* accepting_pollset, - grpc_tcp_server_acceptor* acceptor) { - auto* self = static_cast<TestTcpServer*>(arg); - self->OnConnect(tcp, accepting_pollset, acceptor); - } - - static void OnFdReleased(void* arg, grpc_error_handle err) { - auto* self = static_cast<TestTcpServer*>(arg); - self->OnFdReleased(err); - } - - private: - void OnConnect(grpc_endpoint* tcp, grpc_pollset* /*accepting_pollset*/, - grpc_tcp_server_acceptor* acceptor) { - TString peer(grpc_endpoint_get_peer(tcp)); - gpr_log(GPR_INFO, "Got incoming connection! from %s", peer.c_str()); - EXPECT_FALSE(acceptor->external_connection); - listener_fd_ = grpc_tcp_server_port_fd( - acceptor->from_server, acceptor->port_index, acceptor->fd_index); - gpr_free(acceptor); - grpc_tcp_destroy_and_release_fd(tcp, &fd_, &on_fd_released_); - } - - void OnFdReleased(grpc_error_handle err) { - EXPECT_EQ(GRPC_ERROR_NONE, err); - experimental::ExternalConnectionAcceptor::NewConnectionParameters p; - p.listener_fd = listener_fd_; - p.fd = fd_; - if (queue_data_) { - char buf[1024]; - ssize_t read_bytes = 0; - while (read_bytes <= 0) { - read_bytes = read(fd_, buf, 1024); - } - Slice data(buf, read_bytes); - p.read_buffer = ByteBuffer(&data, 1); - } - gpr_log(GPR_INFO, "Handing off fd %d with data size %d from listener fd %d", - fd_, static_cast<int>(p.read_buffer.Length()), listener_fd_); - connection_acceptor_->HandleNewConnection(&p); - } - - std::mutex mu_; - bool shutdown_; - - int listener_fd_ = -1; - int fd_ = -1; - bool queue_data_ = false; - - grpc_closure on_fd_released_; - std::thread running_thread_; - int port_ = -1; - TString address_; - std::unique_ptr<experimental::ExternalConnectionAcceptor> - connection_acceptor_; - test_tcp_server tcp_server_; -}; - -class PortSharingEnd2endTest : public ::testing::TestWithParam<TestScenario> { - protected: - PortSharingEnd2endTest() : is_server_started_(false), first_picked_port_(0) { - GetParam().Log(); - } - - void SetUp() override { - if (GetParam().queue_pending_data) { - tcp_server1_.SetQueueData(); - tcp_server2_.SetQueueData(); - } - tcp_server1_.Start(); - tcp_server2_.Start(); - ServerBuilder builder; - if (GetParam().server_has_port) { - int port = grpc_pick_unused_port_or_die(); - first_picked_port_ = port; - server_address_ << "localhost:" << port; - auto creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - builder.AddListeningPort(server_address_.str(), creds); - gpr_log(GPR_INFO, "gRPC server listening on %s", - server_address_.str().c_str()); - } - auto server_creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - auto acceptor1 = builder.experimental().AddExternalConnectionAcceptor( - ServerBuilder::experimental_type::ExternalConnectionType::FROM_FD, - server_creds); - tcp_server1_.SetAcceptor(std::move(acceptor1)); - auto acceptor2 = builder.experimental().AddExternalConnectionAcceptor( - ServerBuilder::experimental_type::ExternalConnectionType::FROM_FD, - server_creds); - tcp_server2_.SetAcceptor(std::move(acceptor2)); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - is_server_started_ = true; - - tcp_server1_.Run(); - tcp_server2_.Run(); - } - - void TearDown() override { - tcp_server1_.Shutdown(); - tcp_server2_.Shutdown(); - if (is_server_started_) { - server_->Shutdown(); - } - if (first_picked_port_ > 0) { - grpc_recycle_unused_port(first_picked_port_); - } - } - - void ResetStubs() { - EXPECT_TRUE(is_server_started_); - ChannelArguments args; - args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - channel_handoff1_ = - CreateCustomChannel(tcp_server1_.address(), channel_creds, args); - stub_handoff1_ = EchoTestService::NewStub(channel_handoff1_); - channel_handoff2_ = - CreateCustomChannel(tcp_server2_.address(), channel_creds, args); - stub_handoff2_ = EchoTestService::NewStub(channel_handoff2_); - if (GetParam().server_has_port) { - ChannelArguments direct_args; - direct_args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); - auto direct_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &direct_args); - channel_direct_ = - CreateCustomChannel(server_address_.str(), direct_creds, direct_args); - stub_direct_ = EchoTestService::NewStub(channel_direct_); - } - } - - bool is_server_started_; - // channel/stub to the test tcp server, the connection will be handed to the - // grpc server. - std::shared_ptr<Channel> channel_handoff1_; - std::unique_ptr<EchoTestService::Stub> stub_handoff1_; - std::shared_ptr<Channel> channel_handoff2_; - std::unique_ptr<EchoTestService::Stub> stub_handoff2_; - // channel/stub to talk to the grpc server directly, if applicable. - std::shared_ptr<Channel> channel_direct_; - std::unique_ptr<EchoTestService::Stub> stub_direct_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - TestServiceImpl service_; - TestTcpServer tcp_server1_; - TestTcpServer tcp_server2_; - int first_picked_port_; -}; - -void SendRpc(EchoTestService::Stub* stub, int num_rpcs) { - EchoRequest request; - EchoResponse response; - request.set_message("Hello hello hello hello"); - - for (int i = 0; i < num_rpcs; ++i) { - ClientContext context; - Status s = stub->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - } -} - -std::vector<TestScenario> CreateTestScenarios() { - std::vector<TestScenario> scenarios; - std::vector<TString> credentials_types; - -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - - credentials_types = GetCredentialsProvider()->GetSecureCredentialsTypeList(); - // Only allow insecure credentials type when it is registered with the - // provider. User may create providers that do not have insecure. - if (GetCredentialsProvider()->GetChannelCredentials(kInsecureCredentialsType, - nullptr) != nullptr) { - credentials_types.push_back(kInsecureCredentialsType); - } - - GPR_ASSERT(!credentials_types.empty()); - for (const auto& cred : credentials_types) { - for (auto server_has_port : {true, false}) { - for (auto queue_pending_data : {true, false}) { - scenarios.emplace_back(server_has_port, queue_pending_data, cred); - } - } - } - return scenarios; -} - -TEST_P(PortSharingEnd2endTest, HandoffAndDirectCalls) { - ResetStubs(); - SendRpc(stub_handoff1_.get(), 5); - if (GetParam().server_has_port) { - SendRpc(stub_direct_.get(), 5); - } -} - -TEST_P(PortSharingEnd2endTest, MultipleHandoff) { - for (int i = 0; i < 3; i++) { - ResetStubs(); - SendRpc(stub_handoff2_.get(), 1); - } -} - -TEST_P(PortSharingEnd2endTest, TwoHandoffPorts) { - for (int i = 0; i < 3; i++) { - ResetStubs(); - SendRpc(stub_handoff1_.get(), 5); - SendRpc(stub_handoff2_.get(), 5); - } -} - -INSTANTIATE_TEST_SUITE_P(PortSharingEnd2end, PortSharingEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios())); - -} // namespace -} // namespace testing -} // namespace grpc - -#endif // GRPC_POSIX_SOCKET_TCP_SERVER - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/proto_server_reflection_test.cc b/contrib/libs/grpc/test/cpp/end2end/proto_server_reflection_test.cc deleted file mode 100644 index b9a0c6e8b9..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/proto_server_reflection_test.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* - * - * Copyright 2016 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 <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/ext/proto_server_reflection_plugin.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/proto_reflection_descriptor_database.h" - -namespace grpc { -namespace testing { - -class ProtoServerReflectionTest : public ::testing::Test { - public: - ProtoServerReflectionTest() {} - - void SetUp() override { - port_ = grpc_pick_unused_port_or_die(); - ref_desc_pool_ = protobuf::DescriptorPool::generated_pool(); - - ServerBuilder builder; - TString server_address = "localhost:" + to_string(port_); - builder.AddListeningPort(server_address, InsecureServerCredentials()); - server_ = builder.BuildAndStart(); - } - - void ResetStub() { - string target = "dns:localhost:" + to_string(port_); - std::shared_ptr<Channel> channel = - grpc::CreateChannel(target, InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel); - desc_db_ = y_absl::make_unique<ProtoReflectionDescriptorDatabase>(channel); - desc_pool_ = y_absl::make_unique<protobuf::DescriptorPool>(desc_db_.get()); - } - - string to_string(const int number) { - std::stringstream strs; - strs << number; - return strs.str(); - } - - void CompareService(const TString& service) { - const protobuf::ServiceDescriptor* service_desc = - desc_pool_->FindServiceByName(service); - const protobuf::ServiceDescriptor* ref_service_desc = - ref_desc_pool_->FindServiceByName(service); - EXPECT_TRUE(service_desc != nullptr); - EXPECT_TRUE(ref_service_desc != nullptr); - EXPECT_EQ(service_desc->DebugString(), ref_service_desc->DebugString()); - - const protobuf::FileDescriptor* file_desc = service_desc->file(); - if (known_files_.find(file_desc->package() + "/" + file_desc->name()) != - known_files_.end()) { - EXPECT_EQ(file_desc->DebugString(), - ref_service_desc->file()->DebugString()); - known_files_.insert(file_desc->package() + "/" + file_desc->name()); - } - - for (int i = 0; i < service_desc->method_count(); ++i) { - CompareMethod(service_desc->method(i)->full_name()); - } - } - - void CompareMethod(const TString& method) { - const protobuf::MethodDescriptor* method_desc = - desc_pool_->FindMethodByName(method); - const protobuf::MethodDescriptor* ref_method_desc = - ref_desc_pool_->FindMethodByName(method); - EXPECT_TRUE(method_desc != nullptr); - EXPECT_TRUE(ref_method_desc != nullptr); - EXPECT_EQ(method_desc->DebugString(), ref_method_desc->DebugString()); - - CompareType(method_desc->input_type()->full_name()); - CompareType(method_desc->output_type()->full_name()); - } - - void CompareType(const TString& type) { - if (known_types_.find(type) != known_types_.end()) { - return; - } - - const protobuf::Descriptor* desc = desc_pool_->FindMessageTypeByName(type); - const protobuf::Descriptor* ref_desc = - ref_desc_pool_->FindMessageTypeByName(type); - EXPECT_TRUE(desc != nullptr); - EXPECT_TRUE(ref_desc != nullptr); - EXPECT_EQ(desc->DebugString(), ref_desc->DebugString()); - } - - protected: - std::unique_ptr<Server> server_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<ProtoReflectionDescriptorDatabase> desc_db_; - std::unique_ptr<protobuf::DescriptorPool> desc_pool_; - std::unordered_set<string> known_files_; - std::unordered_set<string> known_types_; - const protobuf::DescriptorPool* ref_desc_pool_; - int port_; - reflection::ProtoServerReflectionPlugin plugin_; -}; - -TEST_F(ProtoServerReflectionTest, CheckResponseWithLocalDescriptorPool) { - ResetStub(); - - std::vector<TString> services; - desc_db_->GetServices(&services); - // The service list has at least one service (reflection servcie). - EXPECT_TRUE(!services.empty()); - - for (auto it = services.begin(); it != services.end(); ++it) { - CompareService(*it); - } -} - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/raw_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/raw_end2end_test.cc deleted file mode 100644 index e0c29cd61b..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/raw_end2end_test.cc +++ /dev/null @@ -1,370 +0,0 @@ -/* - * - * Copyright 2015 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 <cinttypes> -#include <memory> -#include <thread> - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/port.h" -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/byte_buffer_proto_helper.h" -#include "test/cpp/util/string_ref_helper.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { - -namespace { - -void* tag(int i) { return reinterpret_cast<void*>(i); } -int detag(void* p) { return static_cast<int>(reinterpret_cast<intptr_t>(p)); } - -class Verifier { - public: - Verifier() {} - - // Expect sets the expected ok value for a specific tag - Verifier& Expect(int i, bool expect_ok) { - expectations_[tag(i)] = expect_ok; - return *this; - } - - // Next waits for 1 async tag to complete, checks its - // expectations, and returns the tag - int Next(CompletionQueue* cq, bool ignore_ok) { - bool ok; - void* got_tag; - EXPECT_TRUE(cq->Next(&got_tag, &ok)); - GotTag(got_tag, ok, ignore_ok); - return detag(got_tag); - } - - // Verify keeps calling Next until all currently set - // expected tags are complete - void Verify(CompletionQueue* cq) { - GPR_ASSERT(!expectations_.empty()); - while (!expectations_.empty()) { - Next(cq, false); - } - } - - private: - void GotTag(void* got_tag, bool ok, bool ignore_ok) { - auto it = expectations_.find(got_tag); - if (it != expectations_.end()) { - if (!ignore_ok) { - EXPECT_EQ(it->second, ok); - } - expectations_.erase(it); - } - } - - std::map<void*, bool> expectations_; -}; - -class RawEnd2EndTest : public ::testing::Test { - protected: - RawEnd2EndTest() {} - - void SetUp() override { - port_ = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port_; - } - - void TearDown() override { - server_->Shutdown(); - void* ignored_tag; - bool ignored_ok; - cq_->Shutdown(); - while (cq_->Next(&ignored_tag, &ignored_ok)) { - } - stub_.reset(); - grpc_recycle_unused_port(port_); - } - - template <typename ServerType> - std::unique_ptr<ServerType> BuildAndStartServer() { - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - grpc::InsecureServerCredentials()); - std::unique_ptr<ServerType> service(new ServerType()); - builder.RegisterService(service.get()); - cq_ = builder.AddCompletionQueue(); - server_ = builder.BuildAndStart(); - return service; - } - - void ResetStub() { - ChannelArguments args; - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), grpc::InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - - std::unique_ptr<ServerCompletionQueue> cq_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - int port_; - - // For the client application to populate and send to server. - EchoRequest send_request_; - ::grpc::ByteBuffer send_request_buffer_; - - // For the server to give to gRPC to be populated by incoming request - // from client. - EchoRequest recv_request_; - ::grpc::ByteBuffer recv_request_buffer_; - - // For the server application to populate and send back to client. - EchoResponse send_response_; - ::grpc::ByteBuffer send_response_buffer_; - - // For the client to give to gRPC to be populated by incoming response - // from server. - EchoResponse recv_response_; - ::grpc::ByteBuffer recv_response_buffer_; - Status recv_status_; - - // Both sides need contexts - ClientContext cli_ctx_; - ServerContext srv_ctx_; -}; - -// Regular Async, both peers use proto -TEST_F(RawEnd2EndTest, PureAsyncService) { - typedef grpc::testing::EchoTestService::AsyncService SType; - ResetStub(); - auto service = BuildAndStartServer<SType>(); - grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx_); - - send_request_.set_message("hello"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx_, send_request_, cq_.get())); - service->RequestEcho(&srv_ctx_, &recv_request_, &response_writer, cq_.get(), - cq_.get(), tag(2)); - response_reader->Finish(&recv_response_, &recv_status_, tag(4)); - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_EQ(send_request_.message(), recv_request_.message()); - send_response_.set_message(recv_request_.message()); - response_writer.Finish(send_response_, Status::OK, tag(3)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(send_response_.message(), recv_response_.message()); - EXPECT_TRUE(recv_status_.ok()); -} - -// Client uses proto, server uses generic codegen, unary -TEST_F(RawEnd2EndTest, RawServerUnary) { - typedef grpc::testing::EchoTestService::WithRawMethod_Echo< - grpc::testing::EchoTestService::Service> - SType; - ResetStub(); - auto service = BuildAndStartServer<SType>(); - grpc::GenericServerAsyncResponseWriter response_writer(&srv_ctx_); - - send_request_.set_message("hello unary"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( - stub_->AsyncEcho(&cli_ctx_, send_request_, cq_.get())); - service->RequestEcho(&srv_ctx_, &recv_request_buffer_, &response_writer, - cq_.get(), cq_.get(), tag(2)); - response_reader->Finish(&recv_response_, &recv_status_, tag(4)); - Verifier().Expect(2, true).Verify(cq_.get()); - EXPECT_TRUE(ParseFromByteBuffer(&recv_request_buffer_, &recv_request_)); - EXPECT_EQ(send_request_.message(), recv_request_.message()); - send_response_.set_message(recv_request_.message()); - EXPECT_TRUE( - SerializeToByteBufferInPlace(&send_response_, &send_response_buffer_)); - response_writer.Finish(send_response_buffer_, Status::OK, tag(3)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - - EXPECT_EQ(send_response_.message(), recv_response_.message()); - EXPECT_TRUE(recv_status_.ok()); -} - -// Client uses proto, server uses generic codegen, client streaming -TEST_F(RawEnd2EndTest, RawServerClientStreaming) { - typedef grpc::testing::EchoTestService::WithRawMethod_RequestStream< - grpc::testing::EchoTestService::Service> - SType; - ResetStub(); - auto service = BuildAndStartServer<SType>(); - - grpc::GenericServerAsyncReader srv_stream(&srv_ctx_); - - send_request_.set_message("hello client streaming"); - std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream( - stub_->AsyncRequestStream(&cli_ctx_, &recv_response_, cq_.get(), tag(1))); - - service->RequestRequestStream(&srv_ctx_, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - Verifier().Expect(2, true).Expect(1, true).Verify(cq_.get()); - - cli_stream->Write(send_request_, tag(3)); - srv_stream.Read(&recv_request_buffer_, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - ParseFromByteBuffer(&recv_request_buffer_, &recv_request_); - EXPECT_EQ(send_request_.message(), recv_request_.message()); - - cli_stream->Write(send_request_, tag(5)); - srv_stream.Read(&recv_request_buffer_, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - - ParseFromByteBuffer(&recv_request_buffer_, &recv_request_); - EXPECT_EQ(send_request_.message(), recv_request_.message()); - cli_stream->WritesDone(tag(7)); - srv_stream.Read(&recv_request_buffer_, tag(8)); - Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); - - ParseFromByteBuffer(&recv_request_buffer_, &recv_request_); - send_response_.set_message(recv_request_.message()); - SerializeToByteBufferInPlace(&send_response_, &send_response_buffer_); - srv_stream.Finish(send_response_buffer_, Status::OK, tag(9)); - cli_stream->Finish(&recv_status_, tag(10)); - Verifier().Expect(9, true).Expect(10, true).Verify(cq_.get()); - - EXPECT_EQ(send_response_.message(), recv_response_.message()); - EXPECT_TRUE(recv_status_.ok()); -} - -// Client uses proto, server uses generic codegen, server streaming -TEST_F(RawEnd2EndTest, RawServerServerStreaming) { - typedef grpc::testing::EchoTestService::WithRawMethod_ResponseStream< - grpc::testing::EchoTestService::Service> - SType; - ResetStub(); - auto service = BuildAndStartServer<SType>(); - grpc::GenericServerAsyncWriter srv_stream(&srv_ctx_); - - send_request_.set_message("hello server streaming"); - std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream( - stub_->AsyncResponseStream(&cli_ctx_, send_request_, cq_.get(), tag(1))); - - service->RequestResponseStream(&srv_ctx_, &recv_request_buffer_, &srv_stream, - cq_.get(), cq_.get(), tag(2)); - - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - ParseFromByteBuffer(&recv_request_buffer_, &recv_request_); - EXPECT_EQ(send_request_.message(), recv_request_.message()); - - send_response_.set_message(recv_request_.message()); - SerializeToByteBufferInPlace(&send_response_, &send_response_buffer_); - srv_stream.Write(send_response_buffer_, tag(3)); - cli_stream->Read(&recv_response_, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(send_response_.message(), recv_response_.message()); - - srv_stream.Write(send_response_buffer_, tag(5)); - cli_stream->Read(&recv_response_, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_response_.message(), recv_response_.message()); - - srv_stream.Finish(Status::OK, tag(7)); - cli_stream->Read(&recv_response_, tag(8)); - Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); - - cli_stream->Finish(&recv_status_, tag(9)); - Verifier().Expect(9, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status_.ok()); -} - -// Client uses proto, server uses generic codegen, bidi streaming -TEST_F(RawEnd2EndTest, RawServerBidiStreaming) { - typedef grpc::testing::EchoTestService::WithRawMethod_BidiStream< - grpc::testing::EchoTestService::Service> - SType; - ResetStub(); - auto service = BuildAndStartServer<SType>(); - - grpc::GenericServerAsyncReaderWriter srv_stream(&srv_ctx_); - - send_request_.set_message("hello bidi streaming"); - std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>> - cli_stream(stub_->AsyncBidiStream(&cli_ctx_, cq_.get(), tag(1))); - - service->RequestBidiStream(&srv_ctx_, &srv_stream, cq_.get(), cq_.get(), - tag(2)); - - Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - - cli_stream->Write(send_request_, tag(3)); - srv_stream.Read(&recv_request_buffer_, tag(4)); - Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); - ParseFromByteBuffer(&recv_request_buffer_, &recv_request_); - EXPECT_EQ(send_request_.message(), recv_request_.message()); - - send_response_.set_message(recv_request_.message()); - SerializeToByteBufferInPlace(&send_response_, &send_response_buffer_); - srv_stream.Write(send_response_buffer_, tag(5)); - cli_stream->Read(&recv_response_, tag(6)); - Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); - EXPECT_EQ(send_response_.message(), recv_response_.message()); - - cli_stream->WritesDone(tag(7)); - srv_stream.Read(&recv_request_buffer_, tag(8)); - Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); - - srv_stream.Finish(Status::OK, tag(9)); - cli_stream->Finish(&recv_status_, tag(10)); - Verifier().Expect(9, true).Expect(10, true).Verify(cq_.get()); - - EXPECT_TRUE(recv_status_.ok()); -} - -// Testing that this pattern compiles -TEST_F(RawEnd2EndTest, CompileTest) { - typedef grpc::testing::EchoTestService::WithRawMethod_Echo< - grpc::testing::EchoTestService::AsyncService> - SType; - ResetStub(); - auto service = BuildAndStartServer<SType>(); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - // Change the backup poll interval from 5s to 100ms to speed up the - // ReconnectChannel test - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/rls_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/rls_end2end_test.cc deleted file mode 100644 index d383761a29..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/rls_end2end_test.cc +++ /dev/null @@ -1,1458 +0,0 @@ -// -// 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. -// - -// FIXME: add tests: -// - cache eviction via cleanup timer (based on age) -// - RLS channel is down; wait_for_ready request is sent and RLS request fails -// and goes into backoff; RLS channel comes back up before backoff timer -// fires; request is processed at that point - -#include <deque> -#include <map> -#include <thread> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include "y_absl/strings/str_format.h" -#include "y_absl/strings/str_join.h" -#include "y_absl/types/optional.h" - -#include <grpcpp/channel.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/support/channel_arguments.h> - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/lib/address_utils/parse_address.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/core/lib/uri/uri_parser.h" -#include "src/cpp/client/secure_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" -#include "src/proto/grpc/lookup/v1/rls.grpc.pb.h" -#include "src/proto/grpc/lookup/v1/rls.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/resolve_localhost_ip46.h" -#include "test/core/util/test_config.h" -#include "test/core/util/test_lb_policies.h" -#include "test/cpp/end2end/counted_service.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_config.h" - -using ::grpc::lookup::v1::RouteLookupRequest; -using ::grpc::lookup::v1::RouteLookupResponse; - -namespace grpc { -namespace testing { -namespace { - -const char* kServerName = "test.google.fr"; -const char* kRequestMessage = "Live long and prosper."; - -const char* kCallCredsMdKey = "call_cred_name"; -const char* kCallCredsMdValue = "call_cred_value"; - -const char* kTestKey = "test_key"; -const char* kTestValue = "test_value"; -const char* kHostKey = "host_key"; -const char* kServiceKey = "service_key"; -const char* kServiceValue = "grpc.testing.EchoTestService"; -const char* kMethodKey = "method_key"; -const char* kMethodValue = "Echo"; -const char* kConstantKey = "constant_key"; -const char* kConstantValue = "constant_value"; - -using BackendService = CountedService<TestServiceImpl>; -using RlsService = - CountedService<grpc::lookup::v1::RouteLookupService::Service>; - -class RlsServiceImpl : public RlsService { - public: - ::grpc::Status RouteLookup(::grpc::ServerContext* context, - const RouteLookupRequest* request, - RouteLookupResponse* response) override { - gpr_log(GPR_INFO, "RLS: Received request: %s", - request->DebugString().c_str()); - // RLS server should see call creds. - EXPECT_THAT(context->client_metadata(), - ::testing::Contains( - ::testing::Pair(kCallCredsMdKey, kCallCredsMdValue))); - IncreaseRequestCount(); - EXPECT_EQ(request->target_type(), "grpc"); - // See if we have a configured response for this request. - ResponseData res; - { - grpc::internal::MutexLock lock(&mu_); - auto it = responses_.find(*request); - if (it == responses_.end()) { - gpr_log(GPR_INFO, "RLS: no matching request, returning INTERNAL"); - unmatched_requests_.push_back(*request); - return Status(StatusCode::INTERNAL, "no response entry"); - } - res = it->second; - } - // Configured response found, so use it. - if (res.response_delay > 0) { - gpr_sleep_until( - grpc_timeout_milliseconds_to_deadline(res.response_delay)); - } - IncreaseResponseCount(); - *response = res.response; - gpr_log(GPR_INFO, "RLS: returning configured response: %s", - response->DebugString().c_str()); - return Status::OK; - } - - void Start() {} - - void Shutdown() {} - - void SetResponse(RouteLookupRequest request, RouteLookupResponse response, - grpc_millis response_delay = 0) { - grpc::internal::MutexLock lock(&mu_); - responses_[std::move(request)] = {std::move(response), response_delay}; - } - - void RemoveResponse(const RouteLookupRequest& request) { - grpc::internal::MutexLock lock(&mu_); - responses_.erase(request); - } - - std::vector<RouteLookupRequest> GetUnmatchedRequests() { - grpc::internal::MutexLock lock(&mu_); - return std::move(unmatched_requests_); - } - - private: - // Sorting thunk for RouteLookupRequest. - struct RlsRequestLessThan { - bool operator()(const RouteLookupRequest& req1, - const RouteLookupRequest& req2) const { - std::map<y_absl::string_view, y_absl::string_view> key_map1( - req1.key_map().begin(), req1.key_map().end()); - std::map<y_absl::string_view, y_absl::string_view> key_map2( - req2.key_map().begin(), req2.key_map().end()); - if (key_map1 < key_map2) return true; - if (req1.reason() < req2.reason()) return true; - if (req1.stale_header_data() < req2.stale_header_data()) return true; - return false; - } - }; - - struct ResponseData { - RouteLookupResponse response; - grpc_millis response_delay; - }; - - grpc::internal::Mutex mu_; - std::map<RouteLookupRequest, ResponseData, RlsRequestLessThan> responses_ - Y_ABSL_GUARDED_BY(&mu_); - std::vector<RouteLookupRequest> unmatched_requests_ Y_ABSL_GUARDED_BY(&mu_); -}; - -// Subclass of TestServiceImpl that increments a request counter for -// every call to the Echo Rpc. -class MyTestServiceImpl : public BackendService { - public: - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - // Backend should see call creds. - EXPECT_THAT(context->client_metadata(), - ::testing::Contains( - ::testing::Pair(kCallCredsMdKey, kCallCredsMdValue))); - IncreaseRequestCount(); - auto client_metadata = context->client_metadata(); - auto range = client_metadata.equal_range("X-Google-RLS-Data"); - { - grpc::internal::MutexLock lock(&mu_); - for (auto it = range.first; it != range.second; ++it) { - rls_header_data_.insert( - TString(it->second.begin(), it->second.length())); - } - } - IncreaseResponseCount(); - return TestServiceImpl::Echo(context, request, response); - } - - std::set<TString> rls_data() { - grpc::internal::MutexLock lock(&mu_); - return std::move(rls_header_data_); - } - - void Start() {} - - void Shutdown() {} - - private: - grpc::internal::Mutex mu_; - std::set<TString> rls_header_data_ Y_ABSL_GUARDED_BY(&mu_); -}; - -class FakeResolverResponseGeneratorWrapper { - public: - FakeResolverResponseGeneratorWrapper() - : response_generator_(grpc_core::MakeRefCounted< - grpc_core::FakeResolverResponseGenerator>()) {} - - void SetNextResolution(y_absl::string_view service_config_json) { - grpc_core::ExecCtx exec_ctx; - response_generator_->SetResponse(BuildFakeResults(service_config_json)); - } - - grpc_core::FakeResolverResponseGenerator* Get() const { - return response_generator_.get(); - } - - private: - static grpc_core::Resolver::Result BuildFakeResults( - y_absl::string_view service_config_json) { - grpc_core::Resolver::Result result; - result.service_config_error = GRPC_ERROR_NONE; - result.service_config = grpc_core::ServiceConfig::Create( - result.args, service_config_json, &result.service_config_error); - EXPECT_EQ(result.service_config_error, GRPC_ERROR_NONE) - << "JSON: " << service_config_json - << "Error: " << grpc_error_std_string(result.service_config_error); - EXPECT_NE(result.service_config, nullptr); - return result; - } - - grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> - response_generator_; -}; - -class RlsEnd2endTest : public ::testing::Test { - protected: - static void SetUpTestSuite() { - gpr_setenv("GRPC_EXPERIMENTAL_ENABLE_RLS_LB_POLICY", "true"); - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - grpc_init(); - grpc_core::RegisterFixedAddressLoadBalancingPolicy(); - } - - static void TearDownTestSuite() { - grpc_shutdown_blocking(); - gpr_unsetenv("GRPC_EXPERIMENTAL_ENABLE_RLS_LB_POLICY"); - } - - void SetUp() override { - bool localhost_resolves_to_ipv4 = false; - bool localhost_resolves_to_ipv6 = false; - grpc_core::LocalhostResolves(&localhost_resolves_to_ipv4, - &localhost_resolves_to_ipv6); - ipv6_only_ = !localhost_resolves_to_ipv4 && localhost_resolves_to_ipv6; - rls_server_ = y_absl::make_unique<ServerThread<RlsServiceImpl>>("rls"); - rls_server_->Start(); - resolver_response_generator_ = - y_absl::make_unique<FakeResolverResponseGeneratorWrapper>(); - ResetStub(); - } - - void TearDown() override { - ShutdownBackends(); - rls_server_->Shutdown(); - } - - void ResetStub(const char* expected_authority = kServerName) { - ChannelArguments args; - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - resolver_response_generator_->Get()); - args.SetString(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_authority); - grpc_channel_credentials* channel_creds = - grpc_fake_transport_security_credentials_create(); - grpc_call_credentials* call_creds = grpc_md_only_test_credentials_create( - kCallCredsMdKey, kCallCredsMdValue, false); - auto creds = std::make_shared<SecureChannelCredentials>( - grpc_composite_channel_credentials_create(channel_creds, call_creds, - nullptr)); - call_creds->Unref(); - channel_creds->Unref(); - channel_ = ::grpc::CreateCustomChannel( - y_absl::StrCat("fake:///", kServerName).c_str(), std::move(creds), args); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - void ShutdownBackends() { - for (auto& server : backends_) { - server->Shutdown(); - } - } - - void StartBackends(size_t num_servers) { - backends_.clear(); - for (size_t i = 0; i < num_servers; ++i) { - backends_.push_back( - y_absl::make_unique<ServerThread<MyTestServiceImpl>>("backend")); - backends_.back()->Start(); - } - } - - TString TargetStringForPort(int port) { - if (ipv6_only_) return y_absl::StrCat("ipv6:[::1]:", port); - return y_absl::StrCat("ipv4:127.0.0.1:", port); - } - - static RouteLookupRequest BuildRlsRequest( - std::map<TString, TString> key, - RouteLookupRequest::Reason reason = RouteLookupRequest::REASON_MISS, - const char* stale_header_data = "") { - RouteLookupRequest request; - request.set_target_type("grpc"); - request.mutable_key_map()->insert(key.begin(), key.end()); - request.set_reason(reason); - request.set_stale_header_data(stale_header_data); - return request; - } - - static RouteLookupResponse BuildRlsResponse(std::vector<TString> targets, - const char* header_data = "") { - RouteLookupResponse response; - response.mutable_targets()->Add(targets.begin(), targets.end()); - response.set_header_data(header_data); - return response; - } - - struct RpcOptions { - int timeout_ms = 1000; - bool wait_for_ready = false; - std::vector<std::pair<TString, TString>> metadata; - - RpcOptions() {} - - RpcOptions& set_timeout_ms(int rpc_timeout_ms) { - timeout_ms = rpc_timeout_ms; - return *this; - } - - RpcOptions& set_wait_for_ready(bool rpc_wait_for_ready) { - wait_for_ready = rpc_wait_for_ready; - return *this; - } - - RpcOptions& set_metadata( - std::vector<std::pair<TString, TString>> rpc_metadata) { - metadata = std::move(rpc_metadata); - return *this; - } - - // Populates context. - void SetupRpc(ClientContext* context) const { - for (const auto& item : metadata) { - context->AddMetadata(item.first, item.second); - } - if (timeout_ms != 0) { - context->set_deadline( - grpc_timeout_milliseconds_to_deadline(timeout_ms)); - } - if (wait_for_ready) context->set_wait_for_ready(true); - } - }; - - Status SendRpc(const RpcOptions& rpc_options = RpcOptions(), - EchoResponse* response = nullptr) { - EchoResponse local_response; - if (response == nullptr) response = &local_response; - ClientContext context; - rpc_options.SetupRpc(&context); - EchoRequest request; - request.set_message(kRequestMessage); - return stub_->Echo(&context, request, response); - } - - void CheckRpcSendOk(const grpc_core::DebugLocation& location, - const RpcOptions& rpc_options = RpcOptions()) { - EchoResponse response; - Status status = SendRpc(rpc_options, &response); - ASSERT_TRUE(status.ok()) << location.file() << ":" << location.line() - << ": RPC failed: " << status.error_code() << ": " - << status.error_message(); - EXPECT_EQ(response.message(), kRequestMessage) - << location.file() << ":" << location.line(); - } - - void CheckRpcSendFailure(const grpc_core::DebugLocation& location, - const RpcOptions& rpc_options = RpcOptions()) { - Status status = SendRpc(rpc_options); - ASSERT_FALSE(status.ok()) << location.file() << ":" << location.line(); - } - - class ServiceConfigBuilder { - public: - explicit ServiceConfigBuilder(int rls_server_port) - : rls_server_port_(rls_server_port) {} - - ServiceConfigBuilder& set_lookup_service_timeout(grpc_millis timeout) { - lookup_service_timeout_ = timeout * grpc_test_slowdown_factor(); - return *this; - } - - ServiceConfigBuilder& set_default_target(TString default_target) { - default_target_ = std::move(default_target); - return *this; - } - - ServiceConfigBuilder& set_max_age(grpc_millis max_age) { - max_age_ = max_age * grpc_test_slowdown_factor(); - return *this; - } - - ServiceConfigBuilder& set_stale_age(grpc_millis stale_age) { - stale_age_ = stale_age * grpc_test_slowdown_factor(); - return *this; - } - - ServiceConfigBuilder& set_cache_size_bytes(int64_t size) { - cache_size_bytes_ = size; - return *this; - } - - ServiceConfigBuilder& AddKeyBuilder(y_absl::string_view key_builder) { - key_builders_.push_back(y_absl::StrCat("{", key_builder, "}")); - return *this; - } - - TString Build() { - // First build parts of routeLookupConfig. - std::vector<TString> route_lookup_config_parts; - route_lookup_config_parts.push_back(y_absl::StrFormat( - " \"lookupService\":\"localhost:%d\"", rls_server_port_)); - if (lookup_service_timeout_ > 0) { - route_lookup_config_parts.push_back(y_absl::StrFormat( - " \"lookupServiceTimeout\":\"%d.%09ds\"", - lookup_service_timeout_ / 1000, lookup_service_timeout_ % 1000)); - } - if (!default_target_.empty()) { - route_lookup_config_parts.push_back(y_absl::StrFormat( - " \"defaultTarget\":\"%s\"", default_target_)); - } - route_lookup_config_parts.push_back(y_absl::StrFormat( - " \"cacheSizeBytes\":%" PRId64, cache_size_bytes_)); - if (max_age_ > 0) { - route_lookup_config_parts.push_back( - y_absl::StrFormat(" \"maxAge\":\"%d.%09ds\"", max_age_ / 1000, - max_age_ % 1000)); - } - if (stale_age_ > 0) { - route_lookup_config_parts.push_back( - y_absl::StrFormat(" \"staleAge\":\"%d.%09ds\"", - stale_age_ / 1000, stale_age_ % 1000)); - } - if (!key_builders_.empty()) { - route_lookup_config_parts.push_back( - y_absl::StrFormat(" \"grpcKeybuilders\":[%s]", - y_absl::StrJoin(key_builders_, ","))); - } - // Now build parts of RLS LB policy config. - std::vector<TString> rls_config_parts; - if (!route_lookup_config_parts.empty()) { - rls_config_parts.push_back(y_absl::StrCat( - " \"routeLookupConfig\":{", - y_absl::StrJoin(route_lookup_config_parts, ","), " }")); - } - rls_config_parts.push_back( - " \"childPolicy\":[{" - " \"fixed_address_lb\":{}\n" - " }],\n" - " \"childPolicyConfigTargetFieldName\":\"address\"\n"); - // Put it all together. - return y_absl::StrCat( - "{" - " \"loadBalancingConfig\":[{" - " \"rls\":{", - y_absl::StrJoin(rls_config_parts, ","), - " }" - " }]" - "}"); - } - - private: - int rls_server_port_; - grpc_millis lookup_service_timeout_ = 0; - TString default_target_; - grpc_millis max_age_ = 0; - grpc_millis stale_age_ = 0; - int64_t cache_size_bytes_ = 10485760; - std::vector<TString> key_builders_; - }; - - ServiceConfigBuilder MakeServiceConfigBuilder() { - return ServiceConfigBuilder(rls_server_->port_); - } - - void SetNextResolution(y_absl::string_view service_config_json) { - resolver_response_generator_->SetNextResolution(service_config_json); - } - - template <typename T> - struct ServerThread { - template <typename... Args> - explicit ServerThread(const grpc::string& type, Args&&... args) - : port_(grpc_pick_unused_port_or_die()), - type_(type), - service_(std::forward<Args>(args)...) {} - - void Start() { - gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); - GPR_ASSERT(!running_); - running_ = true; - service_.Start(); - grpc::internal::Mutex mu; - // We need to acquire the lock here in order to prevent the notify_one - // by ServerThread::Serve from firing before the wait below is hit. - grpc::internal::MutexLock lock(&mu); - grpc::internal::CondVar cond; - thread_ = y_absl::make_unique<std::thread>( - std::bind(&ServerThread::Serve, this, &mu, &cond)); - cond.Wait(&mu); - gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); - } - - void Serve(grpc::internal::Mutex* mu, grpc::internal::CondVar* cond) { - // We need to acquire the lock here in order to prevent the notify_one - // below from firing before its corresponding wait is executed. - grpc::internal::MutexLock lock(mu); - ServerBuilder builder; - auto creds = std::make_shared<SecureServerCredentials>( - grpc_fake_transport_security_server_credentials_create()); - builder.AddListeningPort(y_absl::StrCat("localhost:", port_), - std::move(creds)); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - cond->Signal(); - } - - void Shutdown() { - if (!running_) return; - gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); - service_.Shutdown(); - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - thread_->join(); - gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); - running_ = false; - } - - const int port_; - grpc::string type_; - T service_; - std::unique_ptr<Server> server_; - std::unique_ptr<std::thread> thread_; - bool running_ = false; - }; - - bool ipv6_only_; - std::vector<std::unique_ptr<ServerThread<MyTestServiceImpl>>> backends_; - std::unique_ptr<ServerThread<RlsServiceImpl>> rls_server_; - std::unique_ptr<FakeResolverResponseGeneratorWrapper> - resolver_response_generator_; - std::shared_ptr<grpc::Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; -}; - -TEST_F(RlsEnd2endTest, Basic) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - // No RLS header seen by the backend, since the RLS response didn't set any. - EXPECT_THAT(backends_[0]->service_.rls_data(), ::testing::ElementsAre()); -} - -TEST_F(RlsEnd2endTest, DuplicateHeadersAreMerged) { - const char* kTestValue2 = "test_value_2"; - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, y_absl::StrCat(kTestValue, ",", kTestValue2)}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - // Same header present twice in the request. Values should be merged. - CheckRpcSendOk( - DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}, {"key1", kTestValue2}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, SecondHeaderUsed) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\", \"key2\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key2", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, MultipleHeaderKeys) { - const char* kTestKey2 = "test_key_2"; - const char* kTestValue2 = "test_value_2"; - StartBackends(1); - SetNextResolution(MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat( - "\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }," - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key2\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey, kTestKey2)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({ - {kTestKey, kTestValue}, - {kTestKey2, kTestValue2}, - }), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk( - DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}, {"key2", kTestValue2}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - // No RLS header seen by the backend, since the RLS response didn't set any. - EXPECT_THAT(backends_[0]->service_.rls_data(), ::testing::ElementsAre()); -} - -TEST_F(RlsEnd2endTest, NoHeaderMatch) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - // Request does not have header "key1", so kTestKey will not be added. - CheckRpcSendOk(DEBUG_LOCATION); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, WildcardMethod) { - StartBackends(1); - SetNextResolution(MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, NoKeyBuilderForMethod) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"some_other_method\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk(DEBUG_LOCATION); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, HeaderData) { - const char* kHeaderData = "header_data"; - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)}, - kHeaderData)); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - EXPECT_THAT(backends_[0]->service_.rls_data(), - ::testing::ElementsAre(kHeaderData)); -} - -TEST_F(RlsEnd2endTest, ExtraKeysAndConstantKeys) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\",\"key2\",\"key3\"" - " ]" - " }" - "]," - "\"extraKeys\":{" - " \"host\":\"%s\"," - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}," - "\"constantKeys\":{" - " \"%s\":\"%s\"" - "}", - kServiceValue, kMethodValue, kTestKey, - kHostKey, kServiceKey, kMethodKey, - kConstantKey, kConstantValue)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({ - {kTestKey, kTestValue}, - {kHostKey, kServerName}, - {kServiceKey, kServiceValue}, - {kMethodKey, kMethodValue}, - {kConstantKey, kConstantValue}, - }), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, TwoCacheEntriesWithSameTarget) { - const char* kTestValue2 = "test_value2"; - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue2}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue2}})); - EXPECT_EQ(rls_server_->service_.request_count(), 2); - EXPECT_EQ(rls_server_->service_.response_count(), 2); - EXPECT_EQ(backends_[0]->service_.request_count(), 2); -} - -TEST_F(RlsEnd2endTest, FailedRlsRequestWithoutDefaultTarget) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - // Send an RPC before we give the RLS server a response. - // The RLS request will fail, and thus so will the data plane RPC. - CheckRpcSendFailure(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_THAT( - rls_server_->service_.GetUnmatchedRequests(), - ::testing::ElementsAre( - // TODO(roth): Change this to use ::testing::ProtoEquals() - // once that becomes available in OSS. - ::testing::Property( - &RouteLookupRequest::DebugString, - BuildRlsRequest({{kTestKey, kTestValue}}).DebugString()))); - // Now give the RLS server the right response. - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - // Sleep long enough for backoff to elapse, then try another RPC. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(3)); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 2); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, FailedRlsRequestWithDefaultTarget) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .set_default_target(TargetStringForPort(backends_[0]->port_)) - .Build()); - // Don't give the RLS server a response, so the RLS request will fail. - // The data plane RPC should be sent to the default target. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_THAT( - rls_server_->service_.GetUnmatchedRequests(), - ::testing::ElementsAre( - // TODO(roth): Change this to use ::testing::ProtoEquals() - // once that becomes available in OSS. - ::testing::Property( - &RouteLookupRequest::DebugString, - BuildRlsRequest({{kTestKey, kTestValue}}).DebugString()))); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 0); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, RlsRequestTimeout) { - StartBackends(2); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .set_default_target(TargetStringForPort(backends_[1]->port_)) - .set_lookup_service_timeout(2000) - .Build()); - // RLS server will send a response, but it's longer than the timeout. - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)}), - /*response_delay=*/3000); - // The data plane RPC should be sent to the default target. - CheckRpcSendOk(DEBUG_LOCATION, RpcOptions().set_timeout_ms(4000).set_metadata( - {{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 0); - EXPECT_EQ(backends_[1]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, UpdateConfig) { - StartBackends(2); - auto service_config_builder = - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .set_default_target(TargetStringForPort(backends_[0]->port_)); - SetNextResolution(service_config_builder.Build()); - // Don't give the RLS server a response, so the RLS request will fail. - // The data plane RPC should be sent to the default target. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_THAT( - rls_server_->service_.GetUnmatchedRequests(), - ::testing::ElementsAre( - // TODO(roth): Change this to use ::testing::ProtoEquals() - // once that becomes available in OSS. - ::testing::Property( - &RouteLookupRequest::DebugString, - BuildRlsRequest({{kTestKey, kTestValue}}).DebugString()))); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 0); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - EXPECT_EQ(backends_[1]->service_.request_count(), 0); - // Now update the config to point to a new default target. - service_config_builder.set_default_target( - TargetStringForPort(backends_[1]->port_)); - SetNextResolution(service_config_builder.Build()); - // Send another RPC, which should go to the new default target. - // The RLS server will *not* see another request, because the cache - // entry is still in backoff. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 0); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - EXPECT_EQ(backends_[1]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, CachedResponse) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - // Send two RPCs. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - // The RLS server should have seen only one request. - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 2); -} - -TEST_F(RlsEnd2endTest, StaleCacheEntry) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .set_max_age(5000) - .set_stale_age(1000) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - // Send one RPC. RLS server gets a request, and RPC goes to backend. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - // Update RLS server to expect stale request. - rls_server_->service_.RemoveResponse( - BuildRlsRequest({{kTestKey, kTestValue}})); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}, - RouteLookupRequest::REASON_STALE), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - // Wait longer than stale age. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - // Send another RPC. This should use the stale value but should - // dispatch a second RLS request. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(backends_[0]->service_.request_count(), 2); - // Wait for RLS server to receive the second request. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - EXPECT_EQ(rls_server_->service_.request_count(), 2); - EXPECT_EQ(rls_server_->service_.response_count(), 2); -} - -TEST_F(RlsEnd2endTest, StaleCacheEntryWithHeaderData) { - const char* kHeaderData = "header_data"; - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .set_max_age(5000) - .set_stale_age(1000) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)}, - kHeaderData)); - // Send one RPC. RLS server gets a request, and RPC goes to backend. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - // Update RLS server to expect stale request. - rls_server_->service_.RemoveResponse( - BuildRlsRequest({{kTestKey, kTestValue}})); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}, - RouteLookupRequest::REASON_STALE, kHeaderData), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)}, - kHeaderData)); - // Wait longer than stale age. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - // Send another RPC. This should use the stale value but should - // dispatch a second RLS request. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(backends_[0]->service_.request_count(), 2); - // Wait for RLS server to receive the second request. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - EXPECT_EQ(rls_server_->service_.request_count(), 2); - EXPECT_EQ(rls_server_->service_.response_count(), 2); -} - -TEST_F(RlsEnd2endTest, ExpiredCacheEntry) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .set_max_age(1000) - .set_lookup_service_timeout(1000) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - // Send one RPC. RLS server gets a request, and RPC goes to backend. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - // Remove response from RLS server so that the next RLS request fails. - rls_server_->service_.RemoveResponse( - BuildRlsRequest({{kTestKey, kTestValue}})); - // Wait for cache to be expired. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - // Send another RPC. This should trigger a second RLS request, but - // that fails, so the RPC fails. - CheckRpcSendFailure(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 2); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, CacheSizeLimit) { - const char* kTestValue2 = "test_value_2"; - StartBackends(2); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, - kTestKey)) - .set_cache_size_bytes(1) // Not even big enough for one entry. - .Build()); - // Set RLS responses for both kTestValue and kTestValue2. - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({TargetStringForPort(backends_[0]->port_)})); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue2}}), - BuildRlsResponse({TargetStringForPort(backends_[1]->port_)})); - // Send an RPC for kTestValue. - // RLS server gets a request, and RPC goes to backend. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - EXPECT_EQ(backends_[1]->service_.request_count(), 0); - // A second RPC for kTestValue should not generate another RLS - // request, because the cache entry is held by min_eviction_time. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 2); - EXPECT_EQ(backends_[1]->service_.request_count(), 0); - // Wait for min_eviction_time to elapse. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(6)); - // Send a request for kTestValue2. - // RLS server gets a request, and RPC goes to backend. - // This causes the entry for kTestValue to be evicted. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue2}})); - EXPECT_EQ(rls_server_->service_.request_count(), 2); - EXPECT_EQ(rls_server_->service_.response_count(), 2); - EXPECT_EQ(backends_[0]->service_.request_count(), 2); - EXPECT_EQ(backends_[1]->service_.request_count(), 1); - // Send another RPC for kTestValue. - // This should now trigger a new RLS request. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 3); - EXPECT_EQ(rls_server_->service_.response_count(), 3); - EXPECT_EQ(backends_[0]->service_.request_count(), 3); - EXPECT_EQ(backends_[1]->service_.request_count(), 1); - // Another RPC for kTestValue2 should still work due to min_eviction_time. - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue2}})); - EXPECT_EQ(rls_server_->service_.request_count(), 3); - EXPECT_EQ(rls_server_->service_.response_count(), 3); - EXPECT_EQ(backends_[0]->service_.request_count(), 3); - EXPECT_EQ(backends_[1]->service_.request_count(), 2); -} - -TEST_F(RlsEnd2endTest, MultipleTargets) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse( - // First target will report TRANSIENT_FAILURE.. - {"invalid_target", TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); -} - -TEST_F(RlsEnd2endTest, ConnectivityStateReady) { - StartBackends(1); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(/*try_to_connect=*/false)); - rls_server_->service_.SetResponse( - BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse( - // One target in TRANSIENT_FAILURE, the other in READY. - {"invalid_target", TargetStringForPort(backends_[0]->port_)})); - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(backends_[0]->service_.request_count(), 1); - EXPECT_EQ(GRPC_CHANNEL_READY, channel_->GetState(/*try_to_connect=*/false)); -} - -TEST_F(RlsEnd2endTest, ConnectivityStateIdle) { - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(/*try_to_connect=*/false)); - // RLS server not given any responses, so the request will fail. - CheckRpcSendFailure(DEBUG_LOCATION); - // No child policies, so should be IDLE. - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(/*try_to_connect=*/false)); -} - -TEST_F(RlsEnd2endTest, ConnectivityStateTransientFailure) { - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(/*try_to_connect=*/false)); - rls_server_->service_.SetResponse(BuildRlsRequest({{kTestKey, kTestValue}}), - BuildRlsResponse({"invalid_target"})); - CheckRpcSendFailure(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - EXPECT_EQ(rls_server_->service_.request_count(), 1); - EXPECT_EQ(rls_server_->service_.response_count(), 1); - EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, - channel_->GetState(/*try_to_connect=*/false)); -} - -TEST_F(RlsEnd2endTest, RlsAuthorityDeathTest) { - GRPC_GTEST_FLAG_SET_DEATH_TEST_STYLE("threadsafe"); - ResetStub("incorrect_authority"); - SetNextResolution( - MakeServiceConfigBuilder() - .AddKeyBuilder(y_absl::StrFormat("\"names\":[{" - " \"service\":\"%s\"," - " \"method\":\"%s\"" - "}]," - "\"headers\":[" - " {" - " \"key\":\"%s\"," - " \"names\":[" - " \"key1\"" - " ]" - " }" - "]", - kServiceValue, kMethodValue, kTestKey)) - .Build()); - // Make sure that we blow up (via abort() from the security connector) when - // the authority for the RLS channel doesn't match expectations. - ASSERT_DEATH_IF_SUPPORTED( - { - CheckRpcSendOk(DEBUG_LOCATION, - RpcOptions().set_metadata({{"key1", kTestValue}})); - }, - ""); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/sdk_authz_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/sdk_authz_end2end_test.cc deleted file mode 100644 index e3e676a32a..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/sdk_authz_end2end_test.cc +++ /dev/null @@ -1,763 +0,0 @@ -// 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 <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/security/authorization_policy_provider.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> - -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/client/secure_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/core/util/tls_utils.h" -#include "test/cpp/end2end/test_service_impl.h" - -namespace grpc { -namespace testing { -namespace { - -constexpr char kMessage[] = "Hello"; - -class SdkAuthzEnd2EndTest : public ::testing::Test { - protected: - SdkAuthzEnd2EndTest() - : server_address_( - y_absl::StrCat("localhost:", grpc_pick_unused_port_or_die())), - server_creds_( - std::shared_ptr<ServerCredentials>(new SecureServerCredentials( - grpc_fake_transport_security_server_credentials_create()))), - channel_creds_( - std::shared_ptr<ChannelCredentials>(new SecureChannelCredentials( - grpc_fake_transport_security_credentials_create()))) {} - - ~SdkAuthzEnd2EndTest() override { server_->Shutdown(); } - - // Replaces existing credentials with insecure credentials. - void UseInsecureCredentials() { - server_creds_ = InsecureServerCredentials(); - channel_creds_ = InsecureChannelCredentials(); - } - - // Creates server with sdk authorization enabled when provider is not null. - void InitServer( - std::shared_ptr<experimental::AuthorizationPolicyProviderInterface> - provider) { - ServerBuilder builder; - builder.AddListeningPort(server_address_, std::move(server_creds_)); - builder.experimental().SetAuthorizationPolicyProvider(std::move(provider)); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - std::shared_ptr<experimental::AuthorizationPolicyProviderInterface> - CreateStaticAuthzPolicyProvider(const TString& policy) { - grpc::Status status; - auto provider = experimental::StaticDataAuthorizationPolicyProvider::Create( - policy, &status); - EXPECT_TRUE(status.ok()); - return provider; - } - - std::shared_ptr<experimental::AuthorizationPolicyProviderInterface> - CreateFileWatcherAuthzPolicyProvider(const TString& policy_path, - unsigned int refresh_interval_sec) { - grpc::Status status; - auto provider = - experimental::FileWatcherAuthorizationPolicyProvider::Create( - policy_path, refresh_interval_sec, &status); - EXPECT_TRUE(status.ok()); - return provider; - } - - std::shared_ptr<Channel> BuildChannel() { - ChannelArguments args; - return ::grpc::CreateCustomChannel(server_address_, channel_creds_, args); - } - - grpc::Status SendRpc(const std::shared_ptr<Channel>& channel, - ClientContext* context, - grpc::testing::EchoResponse* response = nullptr) { - auto stub = grpc::testing::EchoTestService::NewStub(channel); - grpc::testing::EchoRequest request; - request.set_message(kMessage); - return stub->Echo(context, request, response); - } - - TString server_address_; - TestServiceImpl service_; - std::unique_ptr<Server> server_; - std::shared_ptr<ServerCredentials> server_creds_; - std::shared_ptr<ChannelCredentials> channel_creds_; -}; - -TEST_F(SdkAuthzEnd2EndTest, - StaticInitAllowsRpcRequestNoMatchInDenyMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]," - " \"headers\": [" - " {" - " \"key\": \"key-foo\"," - " \"values\": [\"foo1\", \"foo2\"]" - " }," - " {" - " \"key\": \"key-bar\"," - " \"values\": [\"bar1\"]" - " }" - " ]" - " }" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_clientstreamingecho\"," - " \"request\": {" - " \"paths\": [" - " \"*/ClientStreamingEcho\"" - " ]" - " }" - " }" - " ]" - "}"; - InitServer(CreateStaticAuthzPolicyProvider(policy)); - auto channel = BuildChannel(); - ClientContext context; - context.AddMetadata("key-foo", "foo2"); - context.AddMetadata("key-bar", "bar1"); - context.AddMetadata("key-baz", "baz1"); - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp.message(), kMessage); -} - -TEST_F(SdkAuthzEnd2EndTest, StaticInitDeniesRpcRequestNoMatchInAllowAndDeny) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_foo\"," - " \"request\": {" - " \"paths\": [" - " \"*/foo\"" - " ]" - " }" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_bar\"," - " \"source\": {" - " \"principals\": [" - " \"bar\"" - " ]" - " }" - " }" - " ]" - "}"; - InitServer(CreateStaticAuthzPolicyProvider(policy)); - auto channel = BuildChannel(); - ClientContext context; - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, StaticInitDeniesRpcRequestMatchInDenyMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_all\"" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - InitServer(CreateStaticAuthzPolicyProvider(policy)); - auto channel = BuildChannel(); - ClientContext context; - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, - StaticInitDeniesRpcRequestMatchInDenyNoMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_clientstreamingecho\"," - " \"request\": {" - " \"paths\": [" - " \"*/ClientStreamingEcho\"" - " ]" - " }" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - InitServer(CreateStaticAuthzPolicyProvider(policy)); - auto channel = BuildChannel(); - ClientContext context; - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, StaticInitAllowsRpcRequestEmptyDenyMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]," - " \"headers\": [" - " {" - " \"key\": \"key-foo\"," - " \"values\": [\"foo1\", \"foo2\"]" - " }," - " {" - " \"key\": \"key-bar\"," - " \"values\": [\"bar1\"]" - " }" - " ]" - " }" - " }" - " ]" - "}"; - InitServer(CreateStaticAuthzPolicyProvider(policy)); - auto channel = BuildChannel(); - ClientContext context; - context.AddMetadata("key-foo", "foo2"); - context.AddMetadata("key-bar", "bar1"); - context.AddMetadata("key-baz", "baz1"); - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp.message(), kMessage); -} - -TEST_F(SdkAuthzEnd2EndTest, StaticInitDeniesRpcRequestEmptyDenyNoMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]," - " \"headers\": [" - " {" - " \"key\": \"key-foo\"," - " \"values\": [\"foo1\"]" - " }" - " ]" - " }" - " }" - " ]" - "}"; - InitServer(CreateStaticAuthzPolicyProvider(policy)); - auto channel = BuildChannel(); - ClientContext context; - context.AddMetadata("key-bar", "bar1"); - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F( - SdkAuthzEnd2EndTest, - StaticInitDeniesRpcRequestWithPrincipalsFieldOnUnauthenticatedConnection) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"source\": {" - " \"principals\": [" - " \"foo\"" - " ]" - " }," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - UseInsecureCredentials(); - InitServer(CreateStaticAuthzPolicyProvider(policy)); - auto channel = BuildChannel(); - ClientContext context; - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, - FileWatcherInitAllowsRpcRequestNoMatchInDenyMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]," - " \"headers\": [" - " {" - " \"key\": \"key-foo\"," - " \"values\": [\"foo1\", \"foo2\"]" - " }," - " {" - " \"key\": \"key-bar\"," - " \"values\": [\"bar1\"]" - " }" - " ]" - " }" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_clientstreamingecho\"," - " \"request\": {" - " \"paths\": [" - " \"*/ClientStreamingEcho\"" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5)); - auto channel = BuildChannel(); - ClientContext context; - context.AddMetadata("key-foo", "foo2"); - context.AddMetadata("key-bar", "bar1"); - context.AddMetadata("key-baz", "baz1"); - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp.message(), kMessage); -} - -TEST_F(SdkAuthzEnd2EndTest, - FileWatcherInitDeniesRpcRequestNoMatchInAllowAndDeny) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_foo\"," - " \"request\": {" - " \"paths\": [" - " \"*/foo\"" - " ]" - " }" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_bar\"," - " \"source\": {" - " \"principals\": [" - " \"bar\"" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5)); - auto channel = BuildChannel(); - ClientContext context; - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, - FileWatcherInitDeniesRpcRequestMatchInDenyMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_all\"" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5)); - auto channel = BuildChannel(); - ClientContext context; - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, - FileWatcherInitDeniesRpcRequestMatchInDenyNoMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_clientstreamingecho\"," - " \"request\": {" - " \"paths\": [" - " \"*/ClientStreamingEcho\"" - " ]" - " }" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5)); - auto channel = BuildChannel(); - ClientContext context; - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, - FileWatcherInitAllowsRpcRequestEmptyDenyMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]," - " \"headers\": [" - " {" - " \"key\": \"key-foo\"," - " \"values\": [\"foo1\", \"foo2\"]" - " }," - " {" - " \"key\": \"key-bar\"," - " \"values\": [\"bar1\"]" - " }" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5)); - auto channel = BuildChannel(); - ClientContext context; - context.AddMetadata("key-foo", "foo2"); - context.AddMetadata("key-bar", "bar1"); - context.AddMetadata("key-baz", "baz1"); - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp.message(), kMessage); -} - -TEST_F(SdkAuthzEnd2EndTest, - FileWatcherInitDeniesRpcRequestEmptyDenyNoMatchInAllow) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]," - " \"headers\": [" - " {" - " \"key\": \"key-foo\"," - " \"values\": [\"foo1\"]" - " }" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 5)); - auto channel = BuildChannel(); - ClientContext context; - context.AddMetadata("key-bar", "bar1"); - grpc::testing::EchoResponse resp; - grpc::Status status = SendRpc(channel, &context, &resp); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, FileWatcherValidPolicyRefresh) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 1)); - auto channel = BuildChannel(); - ClientContext context1; - grpc::testing::EchoResponse resp1; - grpc::Status status = SendRpc(channel, &context1, &resp1); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp1.message(), kMessage); - // Replace the existing policy with a new authorization policy. - policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_foo\"," - " \"request\": {" - " \"paths\": [" - " \"*/foo\"" - " ]" - " }" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - tmp_policy.RewriteFile(policy); - // Wait 2 seconds for the provider's refresh thread to read the updated files. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - ClientContext context2; - grpc::testing::EchoResponse resp2; - status = SendRpc(channel, &context2, &resp2); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp2.message().empty()); -} - -TEST_F(SdkAuthzEnd2EndTest, FileWatcherInvalidPolicyRefreshSkipsReload) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 1)); - auto channel = BuildChannel(); - ClientContext context1; - grpc::testing::EchoResponse resp1; - grpc::Status status = SendRpc(channel, &context1, &resp1); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp1.message(), kMessage); - // Replaces existing policy with an invalid authorization policy. - policy = "{}"; - tmp_policy.RewriteFile(policy); - // Wait 2 seconds for the provider's refresh thread to read the updated files. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - ClientContext context2; - grpc::testing::EchoResponse resp2; - status = SendRpc(channel, &context2, &resp2); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp2.message(), kMessage); -} - -TEST_F(SdkAuthzEnd2EndTest, FileWatcherRecoversFromFailure) { - TString policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - grpc_core::testing::TmpFile tmp_policy(policy); - InitServer(CreateFileWatcherAuthzPolicyProvider(tmp_policy.name(), 1)); - auto channel = BuildChannel(); - ClientContext context1; - grpc::testing::EchoResponse resp1; - grpc::Status status = SendRpc(channel, &context1, &resp1); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp1.message(), kMessage); - // Replaces existing policy with an invalid authorization policy. - policy = "{}"; - tmp_policy.RewriteFile(policy); - // Wait 2 seconds for the provider's refresh thread to read the updated files. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - ClientContext context2; - grpc::testing::EchoResponse resp2; - status = SendRpc(channel, &context2, &resp2); - EXPECT_TRUE(status.ok()); - EXPECT_EQ(resp2.message(), kMessage); - // Replace the existing invalid policy with a valid authorization policy. - policy = - "{" - " \"name\": \"authz\"," - " \"allow_rules\": [" - " {" - " \"name\": \"allow_foo\"," - " \"request\": {" - " \"paths\": [" - " \"*/foo\"" - " ]" - " }" - " }" - " ]," - " \"deny_rules\": [" - " {" - " \"name\": \"deny_echo\"," - " \"request\": {" - " \"paths\": [" - " \"*/Echo\"" - " ]" - " }" - " }" - " ]" - "}"; - tmp_policy.RewriteFile(policy); - // Wait 2 seconds for the provider's refresh thread to read the updated files. - gpr_sleep_until(grpc_timeout_seconds_to_deadline(2)); - ClientContext context3; - grpc::testing::EchoResponse resp3; - status = SendRpc(channel, &context3, &resp3); - EXPECT_EQ(status.error_code(), grpc::StatusCode::PERMISSION_DENIED); - EXPECT_EQ(status.error_message(), "Unauthorized RPC request rejected."); - EXPECT_TRUE(resp3.message().empty()); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(argc, argv); - const auto result = RUN_ALL_TESTS(); - return result; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/server_builder_plugin_test.cc b/contrib/libs/grpc/test/cpp/end2end/server_builder_plugin_test.cc deleted file mode 100644 index 56c32b65da..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/server_builder_plugin_test.cc +++ /dev/null @@ -1,267 +0,0 @@ -/* - * - * Copyright 2016 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 <thread> - -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/impl/server_builder_option.h> -#include <grpcpp/impl/server_builder_plugin.h> -#include <grpcpp/impl/server_initializer.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" - -#define PLUGIN_NAME "TestServerBuilderPlugin" - -namespace grpc { -namespace testing { - -class TestServerBuilderPlugin : public ServerBuilderPlugin { - public: - TestServerBuilderPlugin() : service_(new TestServiceImpl()) { - init_server_is_called_ = false; - finish_is_called_ = false; - change_arguments_is_called_ = false; - register_service_ = false; - } - - TString name() override { return PLUGIN_NAME; } - - void InitServer(ServerInitializer* si) override { - init_server_is_called_ = true; - if (register_service_) { - si->RegisterService(service_); - } - } - - void Finish(ServerInitializer* /*si*/) override { finish_is_called_ = true; } - - void ChangeArguments(const TString& /*name*/, void* /*value*/) override { - change_arguments_is_called_ = true; - } - - bool has_async_methods() const override { - if (register_service_) { - return service_->has_async_methods(); - } - return false; - } - - bool has_sync_methods() const override { - if (register_service_) { - return service_->has_synchronous_methods(); - } - return false; - } - - void SetRegisterService() { register_service_ = true; } - - bool init_server_is_called() { return init_server_is_called_; } - bool finish_is_called() { return finish_is_called_; } - bool change_arguments_is_called() { return change_arguments_is_called_; } - - private: - bool init_server_is_called_; - bool finish_is_called_; - bool change_arguments_is_called_; - bool register_service_; - std::shared_ptr<TestServiceImpl> service_; -}; - -class InsertPluginServerBuilderOption : public ServerBuilderOption { - public: - InsertPluginServerBuilderOption() { register_service_ = false; } - - void UpdateArguments(ChannelArguments* /*arg*/) override {} - - void UpdatePlugins( - std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) override { - plugins->clear(); - - std::unique_ptr<TestServerBuilderPlugin> plugin( - new TestServerBuilderPlugin()); - if (register_service_) plugin->SetRegisterService(); - plugins->emplace_back(std::move(plugin)); - } - - void SetRegisterService() { register_service_ = true; } - - private: - bool register_service_; -}; - -std::unique_ptr<ServerBuilderPlugin> CreateTestServerBuilderPlugin() { - return std::unique_ptr<ServerBuilderPlugin>(new TestServerBuilderPlugin()); -} - -// Force AddServerBuilderPlugin() to be called at static initialization time. -struct StaticTestPluginInitializer { - StaticTestPluginInitializer() { - ::grpc::ServerBuilder::InternalAddPluginFactory( - &CreateTestServerBuilderPlugin); - } -} static_plugin_initializer_test_; - -// When the param boolean is true, the ServerBuilder plugin will be added at the -// time of static initialization. When it's false, the ServerBuilder plugin will -// be added using ServerBuilder::SetOption(). -class ServerBuilderPluginTest : public ::testing::TestWithParam<bool> { - public: - ServerBuilderPluginTest() {} - - void SetUp() override { - port_ = grpc_pick_unused_port_or_die(); - builder_ = y_absl::make_unique<ServerBuilder>(); - } - - void InsertPlugin() { - if (GetParam()) { - // Add ServerBuilder plugin in static initialization - CheckPresent(); - } else { - // Add ServerBuilder plugin using ServerBuilder::SetOption() - builder_->SetOption(std::unique_ptr<ServerBuilderOption>( - new InsertPluginServerBuilderOption())); - } - } - - void InsertPluginWithTestService() { - if (GetParam()) { - // Add ServerBuilder plugin in static initialization - auto plugin = CheckPresent(); - EXPECT_TRUE(plugin); - plugin->SetRegisterService(); - } else { - // Add ServerBuilder plugin using ServerBuilder::SetOption() - std::unique_ptr<InsertPluginServerBuilderOption> option( - new InsertPluginServerBuilderOption()); - option->SetRegisterService(); - builder_->SetOption(std::move(option)); - } - } - - void StartServer() { - TString server_address = "localhost:" + to_string(port_); - builder_->AddListeningPort(server_address, InsecureServerCredentials()); - // we run some tests without a service, and for those we need to supply a - // frequently polled completion queue - cq_ = builder_->AddCompletionQueue(); - cq_thread_ = new std::thread(&ServerBuilderPluginTest::RunCQ, this); - server_ = builder_->BuildAndStart(); - EXPECT_TRUE(CheckPresent()); - } - - void ResetStub() { - string target = "dns:localhost:" + to_string(port_); - channel_ = grpc::CreateChannel(target, InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - void TearDown() override { - auto plugin = CheckPresent(); - EXPECT_TRUE(plugin); - EXPECT_TRUE(plugin->init_server_is_called()); - EXPECT_TRUE(plugin->finish_is_called()); - server_->Shutdown(); - cq_->Shutdown(); - cq_thread_->join(); - delete cq_thread_; - } - - string to_string(const int number) { - std::stringstream strs; - strs << number; - return strs.str(); - } - - protected: - std::shared_ptr<Channel> channel_; - std::unique_ptr<ServerBuilder> builder_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<ServerCompletionQueue> cq_; - std::unique_ptr<Server> server_; - std::thread* cq_thread_; - TestServiceImpl service_; - int port_; - - private: - TestServerBuilderPlugin* CheckPresent() { - auto it = builder_->plugins_.begin(); - for (; it != builder_->plugins_.end(); it++) { - if ((*it)->name() == PLUGIN_NAME) break; - } - if (it != builder_->plugins_.end()) { - return static_cast<TestServerBuilderPlugin*>(it->get()); - } else { - return nullptr; - } - } - - void RunCQ() { - void* tag; - bool ok; - while (cq_->Next(&tag, &ok)) { - } - } -}; - -TEST_P(ServerBuilderPluginTest, PluginWithoutServiceTest) { - InsertPlugin(); - StartServer(); -} - -TEST_P(ServerBuilderPluginTest, PluginWithServiceTest) { - InsertPluginWithTestService(); - StartServer(); - ResetStub(); - - EchoRequest request; - EchoResponse response; - request.set_message("Hello hello hello hello"); - ClientContext context; - context.set_compression_algorithm(GRPC_COMPRESS_GZIP); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); -} - -INSTANTIATE_TEST_SUITE_P(ServerBuilderPluginTest, ServerBuilderPluginTest, - ::testing::Values(false, true)); - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/server_crash_test.cc b/contrib/libs/grpc/test/cpp/end2end/server_crash_test.cc deleted file mode 100644 index 9ac41f9b63..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/server_crash_test.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* - * - * Copyright 2015 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 <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/subprocess.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -static TString g_root; - -namespace grpc { -namespace testing { - -namespace { - -class ServiceImpl final : public ::grpc::testing::EchoTestService::Service { - public: - ServiceImpl() : bidi_stream_count_(0), response_stream_count_(0) {} - - Status BidiStream( - ServerContext* /*context*/, - ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { - bidi_stream_count_++; - EchoRequest request; - EchoResponse response; - while (stream->Read(&request)) { - gpr_log(GPR_INFO, "recv msg %s", request.message().c_str()); - response.set_message(request.message()); - stream->Write(response); - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(1, GPR_TIMESPAN))); - } - return Status::OK; - } - - Status ResponseStream(ServerContext* /*context*/, - const EchoRequest* /*request*/, - ServerWriter<EchoResponse>* writer) override { - EchoResponse response; - response_stream_count_++; - for (int i = 0;; i++) { - std::ostringstream msg; - msg << "Hello " << i; - response.set_message(msg.str()); - if (!writer->Write(response)) break; - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(1, GPR_TIMESPAN))); - } - return Status::OK; - } - - int bidi_stream_count() { return bidi_stream_count_; } - - int response_stream_count() { return response_stream_count_; } - - private: - int bidi_stream_count_; - int response_stream_count_; -}; - -class CrashTest : public ::testing::Test { - protected: - CrashTest() {} - - std::unique_ptr<Server> CreateServerAndClient(const TString& mode) { - auto port = grpc_pick_unused_port_or_die(); - std::ostringstream addr_stream; - addr_stream << "localhost:" << port; - auto addr = addr_stream.str(); - client_ = y_absl::make_unique<SubProcess>( - std::vector<TString>({g_root + "/server_crash_test_client", - "--address=" + addr, "--mode=" + mode})); - GPR_ASSERT(client_); - - ServerBuilder builder; - builder.AddListeningPort(addr, grpc::InsecureServerCredentials()); - builder.RegisterService(&service_); - return builder.BuildAndStart(); - } - - void KillClient() { client_.reset(); } - - bool HadOneBidiStream() { return service_.bidi_stream_count() == 1; } - - bool HadOneResponseStream() { return service_.response_stream_count() == 1; } - - private: - std::unique_ptr<SubProcess> client_; - ServiceImpl service_; -}; - -TEST_F(CrashTest, ResponseStream) { - auto server = CreateServerAndClient("response"); - - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(60, GPR_TIMESPAN))); - KillClient(); - server->Shutdown(); - GPR_ASSERT(HadOneResponseStream()); -} - -TEST_F(CrashTest, BidiStream) { - auto server = CreateServerAndClient("bidi"); - - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(60, GPR_TIMESPAN))); - KillClient(); - server->Shutdown(); - GPR_ASSERT(HadOneBidiStream()); -} - -} // namespace - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - TString me = argv[0]; - auto lslash = me.rfind('/'); - if (lslash != TString::npos) { - g_root = me.substr(0, lslash); - } else { - g_root = "."; - } - - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/server_crash_test_client.cc b/contrib/libs/grpc/test/cpp/end2end/server_crash_test_client.cc deleted file mode 100644 index 8ecdaf56bb..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/server_crash_test_client.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Copyright 2015 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 <iostream> -#include <memory> -#include <sstream> -#include <util/generic/string.h> - -#include "y_absl/flags/flag.h" - -#include <grpc/support/log.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/cpp/util/test_config.h" - -Y_ABSL_FLAG(TString, address, "", "Address to connect to"); -Y_ABSL_FLAG(TString, mode, "", "Test mode to use"); - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); - auto stub = grpc::testing::EchoTestService::NewStub(grpc::CreateChannel( - y_absl::GetFlag(FLAGS_address), grpc::InsecureChannelCredentials())); - - EchoRequest request; - EchoResponse response; - grpc::ClientContext context; - context.set_wait_for_ready(true); - - if (y_absl::GetFlag(FLAGS_mode) == "bidi") { - auto stream = stub->BidiStream(&context); - for (int i = 0;; i++) { - std::ostringstream msg; - msg << "Hello " << i; - request.set_message(msg.str()); - GPR_ASSERT(stream->Write(request)); - GPR_ASSERT(stream->Read(&response)); - GPR_ASSERT(response.message() == request.message()); - } - } else if (y_absl::GetFlag(FLAGS_mode) == "response") { - EchoRequest request; - request.set_message("Hello"); - auto stream = stub->ResponseStream(&context, request); - for (;;) { - GPR_ASSERT(stream->Read(&response)); - } - } else { - gpr_log(GPR_ERROR, "invalid test mode '%s'", - y_absl::GetFlag(FLAGS_mode).c_str()); - return 1; - } -} diff --git a/contrib/libs/grpc/test/cpp/end2end/server_early_return_test.cc b/contrib/libs/grpc/test/cpp/end2end/server_early_return_test.cc deleted file mode 100644 index b33c708295..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/server_early_return_test.cc +++ /dev/null @@ -1,232 +0,0 @@ -/* - * - * Copyright 2018 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 <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/string_ref_helper.h" - -namespace grpc { -namespace testing { -namespace { - -const char kServerReturnStatusCode[] = "server_return_status_code"; -const char kServerDelayBeforeReturnUs[] = "server_delay_before_return_us"; -const char kServerReturnAfterNReads[] = "server_return_after_n_reads"; - -class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - // Unused methods are not implemented. - - Status RequestStream(ServerContext* context, - ServerReader<EchoRequest>* reader, - EchoResponse* response) override { - int server_return_status_code = - GetIntValueFromMetadata(context, kServerReturnStatusCode, 0); - int server_delay_before_return_us = - GetIntValueFromMetadata(context, kServerDelayBeforeReturnUs, 0); - int server_return_after_n_reads = - GetIntValueFromMetadata(context, kServerReturnAfterNReads, 0); - - EchoRequest request; - while (server_return_after_n_reads--) { - EXPECT_TRUE(reader->Read(&request)); - } - - response->set_message("response msg"); - - gpr_sleep_until(gpr_time_add( - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_micros(server_delay_before_return_us, GPR_TIMESPAN))); - - return Status(static_cast<StatusCode>(server_return_status_code), ""); - } - - Status BidiStream( - ServerContext* context, - ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { - int server_return_status_code = - GetIntValueFromMetadata(context, kServerReturnStatusCode, 0); - int server_delay_before_return_us = - GetIntValueFromMetadata(context, kServerDelayBeforeReturnUs, 0); - int server_return_after_n_reads = - GetIntValueFromMetadata(context, kServerReturnAfterNReads, 0); - - EchoRequest request; - EchoResponse response; - while (server_return_after_n_reads--) { - EXPECT_TRUE(stream->Read(&request)); - response.set_message(request.message()); - EXPECT_TRUE(stream->Write(response)); - } - - gpr_sleep_until(gpr_time_add( - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_micros(server_delay_before_return_us, GPR_TIMESPAN))); - - return Status(static_cast<StatusCode>(server_return_status_code), ""); - } - - int GetIntValueFromMetadata(ServerContext* context, const char* key, - int default_value) { - auto metadata = context->client_metadata(); - if (metadata.find(key) != metadata.end()) { - std::istringstream iss(ToString(metadata.find(key)->second)); - iss >> default_value; - } - return default_value; - } -}; - -class ServerEarlyReturnTest : public ::testing::Test { - protected: - ServerEarlyReturnTest() : picked_port_(0) {} - - void SetUp() override { - int port = grpc_pick_unused_port_or_die(); - picked_port_ = port; - server_address_ << "localhost:" << port; - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - - channel_ = grpc::CreateChannel(server_address_.str(), - InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - void TearDown() override { - server_->Shutdown(); - if (picked_port_ > 0) { - grpc_recycle_unused_port(picked_port_); - } - } - - // Client sends 20 requests and the server returns after reading 10 requests. - // If return_cancel is true, server returns CANCELLED status. Otherwise it - // returns OK. - void DoBidiStream(bool return_cancelled) { - EchoRequest request; - EchoResponse response; - ClientContext context; - - context.AddMetadata(kServerReturnAfterNReads, "10"); - if (return_cancelled) { - // "1" means CANCELLED - context.AddMetadata(kServerReturnStatusCode, "1"); - } - context.AddMetadata(kServerDelayBeforeReturnUs, "10000"); - - auto stream = stub_->BidiStream(&context); - - for (int i = 0; i < 20; i++) { - request.set_message(TString("hello") + ToString(i)); - bool write_ok = stream->Write(request); - bool read_ok = stream->Read(&response); - if (i < 10) { - EXPECT_TRUE(write_ok); - EXPECT_TRUE(read_ok); - EXPECT_EQ(response.message(), request.message()); - } else { - EXPECT_FALSE(read_ok); - } - } - - stream->WritesDone(); - EXPECT_FALSE(stream->Read(&response)); - - Status s = stream->Finish(); - if (return_cancelled) { - EXPECT_EQ(s.error_code(), StatusCode::CANCELLED); - } else { - EXPECT_TRUE(s.ok()); - } - } - - void DoRequestStream(bool return_cancelled) { - EchoRequest request; - EchoResponse response; - ClientContext context; - - context.AddMetadata(kServerReturnAfterNReads, "10"); - if (return_cancelled) { - // "1" means CANCELLED - context.AddMetadata(kServerReturnStatusCode, "1"); - } - context.AddMetadata(kServerDelayBeforeReturnUs, "10000"); - - auto stream = stub_->RequestStream(&context, &response); - for (int i = 0; i < 20; i++) { - request.set_message(TString("hello") + ToString(i)); - bool written = stream->Write(request); - if (i < 10) { - EXPECT_TRUE(written); - } - } - stream->WritesDone(); - Status s = stream->Finish(); - if (return_cancelled) { - EXPECT_EQ(s.error_code(), StatusCode::CANCELLED); - } else { - EXPECT_TRUE(s.ok()); - } - } - - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - TestServiceImpl service_; - int picked_port_; -}; - -TEST_F(ServerEarlyReturnTest, BidiStreamEarlyOk) { DoBidiStream(false); } - -TEST_F(ServerEarlyReturnTest, BidiStreamEarlyCancel) { DoBidiStream(true); } - -TEST_F(ServerEarlyReturnTest, RequestStreamEarlyOK) { DoRequestStream(false); } -TEST_F(ServerEarlyReturnTest, RequestStreamEarlyCancel) { - DoRequestStream(true); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/server_load_reporting_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/server_load_reporting_end2end_test.cc deleted file mode 100644 index e97b51f21e..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/server_load_reporting_end2end_test.cc +++ /dev/null @@ -1,192 +0,0 @@ -/* - * - * Copyright 2018 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 <grpc/support/port_platform.h> - -#include <thread> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include <grpc++/grpc++.h> -#include <grpc/grpc.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpcpp/ext/server_load_reporting.h> -#include <grpcpp/server_builder.h> - -#include "src/proto/grpc/lb/v1/load_reporter.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -namespace grpc { -namespace testing { -namespace { - -constexpr double kMetricValue = 3.1415; -constexpr char kMetricName[] = "METRIC_PI"; - -// Different messages result in different response statuses. For simplicity in -// computing request bytes, the message sizes should be the same. -const char kOkMessage[] = "hello"; -const char kServerErrorMessage[] = "sverr"; -const char kClientErrorMessage[] = "clerr"; - -class EchoTestServiceImpl : public EchoTestService::Service { - public: - ~EchoTestServiceImpl() override {} - - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - if (request->message() == kServerErrorMessage) { - return Status(StatusCode::UNKNOWN, "Server error requested"); - } - if (request->message() == kClientErrorMessage) { - return Status(StatusCode::FAILED_PRECONDITION, "Client error requested"); - } - response->set_message(request->message()); - ::grpc::load_reporter::experimental::AddLoadReportingCost( - context, kMetricName, kMetricValue); - return Status::OK; - } -}; - -class ServerLoadReportingEnd2endTest : public ::testing::Test { - protected: - void SetUp() override { - server_address_ = - "localhost:" + ToString(grpc_pick_unused_port_or_die()); - server_ = - ServerBuilder() - .AddListeningPort(server_address_, InsecureServerCredentials()) - .RegisterService(&echo_service_) - .SetOption(std::unique_ptr<::grpc::ServerBuilderOption>( - new ::grpc::load_reporter::experimental:: - LoadReportingServiceServerBuilderOption())) - .BuildAndStart(); - server_thread_ = - std::thread(&ServerLoadReportingEnd2endTest::RunServerLoop, this); - } - - void RunServerLoop() { server_->Wait(); } - - void TearDown() override { - server_->Shutdown(); - server_thread_.join(); - } - - void ClientMakeEchoCalls(const TString& lb_id, const TString& lb_tag, - const TString& message, size_t num_requests) { - auto stub = EchoTestService::NewStub( - grpc::CreateChannel(server_address_, InsecureChannelCredentials())); - TString lb_token = lb_id + lb_tag; - for (size_t i = 0; i < num_requests; ++i) { - ClientContext ctx; - if (!lb_token.empty()) ctx.AddMetadata(GRPC_LB_TOKEN_MD_KEY, lb_token); - EchoRequest request; - EchoResponse response; - request.set_message(message); - Status status = stub->Echo(&ctx, request, &response); - if (message == kOkMessage) { - ASSERT_EQ(status.error_code(), StatusCode::OK); - ASSERT_EQ(request.message(), response.message()); - } else if (message == kServerErrorMessage) { - ASSERT_EQ(status.error_code(), StatusCode::UNKNOWN); - } else if (message == kClientErrorMessage) { - ASSERT_EQ(status.error_code(), StatusCode::FAILED_PRECONDITION); - } - } - } - - TString server_address_; - std::unique_ptr<Server> server_; - std::thread server_thread_; - EchoTestServiceImpl echo_service_; -}; - -TEST_F(ServerLoadReportingEnd2endTest, NoCall) {} - -TEST_F(ServerLoadReportingEnd2endTest, BasicReport) { - auto channel = - grpc::CreateChannel(server_address_, InsecureChannelCredentials()); - auto stub = ::grpc::lb::v1::LoadReporter::NewStub(channel); - ClientContext ctx; - auto stream = stub->ReportLoad(&ctx); - ::grpc::lb::v1::LoadReportRequest request; - request.mutable_initial_request()->set_load_balanced_hostname( - server_address_); - request.mutable_initial_request()->set_load_key("LOAD_KEY"); - request.mutable_initial_request() - ->mutable_load_report_interval() - ->set_seconds(5); - stream->Write(request); - gpr_log(GPR_INFO, "Initial request sent."); - ::grpc::lb::v1::LoadReportResponse response; - stream->Read(&response); - const TString& lb_id = response.initial_response().load_balancer_id(); - gpr_log(GPR_INFO, "Initial response received (lb_id: %s).", lb_id.c_str()); - ClientMakeEchoCalls(lb_id, "LB_TAG", kOkMessage, 1); - while (true) { - stream->Read(&response); - if (!response.load().empty()) { - ASSERT_EQ(response.load().size(), 3); - for (const auto& load : response.load()) { - if (load.in_progress_report_case()) { - // The special load record that reports the number of in-progress - // calls. - ASSERT_EQ(load.num_calls_in_progress(), 1); - } else if (load.orphaned_load_case()) { - // The call from the balancer doesn't have any valid LB token. - ASSERT_EQ(load.orphaned_load_case(), load.kLoadKeyUnknown); - ASSERT_EQ(load.num_calls_started(), 1); - ASSERT_EQ(load.num_calls_finished_without_error(), 0); - ASSERT_EQ(load.num_calls_finished_with_error(), 0); - } else { - // This corresponds to the calls from the client. - ASSERT_EQ(load.num_calls_started(), 1); - ASSERT_EQ(load.num_calls_finished_without_error(), 1); - ASSERT_EQ(load.num_calls_finished_with_error(), 0); - ASSERT_GE(load.total_bytes_received(), sizeof(kOkMessage)); - ASSERT_GE(load.total_bytes_sent(), sizeof(kOkMessage)); - ASSERT_EQ(load.metric_data().size(), 1); - ASSERT_EQ(load.metric_data().Get(0).metric_name(), kMetricName); - ASSERT_EQ(load.metric_data().Get(0).num_calls_finished_with_metric(), - 1); - ASSERT_EQ(load.metric_data().Get(0).total_metric_value(), - kMetricValue); - } - } - break; - } - } - stream->WritesDone(); - ASSERT_EQ(stream->Finish().error_code(), StatusCode::CANCELLED); -} - -// TODO(juanlishen): Add more tests. - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/service_config_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/service_config_end2end_test.cc deleted file mode 100644 index b974befd49..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/service_config_end2end_test.cc +++ /dev/null @@ -1,621 +0,0 @@ -/* - * - * Copyright 2016 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 <algorithm> -#include <memory> -#include <mutex> -#include <random> -#include <set> -#include <util/generic/string.h> -#include <thread> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" -#include "y_absl/strings/str_cat.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/health_check_service_interface.h> -#include <grpcpp/impl/codegen/sync.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/support/validate_service_config.h> - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" -#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/address_utils/parse_address.h" -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/debug_location.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/iomgr/tcp_client.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/client/secure_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/resolve_localhost_ip46.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { -namespace { - -// Subclass of TestServiceImpl that increments a request counter for -// every call to the Echo RPC. -class MyTestServiceImpl : public TestServiceImpl { - public: - MyTestServiceImpl() : request_count_(0) {} - - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - { - grpc::internal::MutexLock lock(&mu_); - ++request_count_; - } - AddClient(context->peer()); - return TestServiceImpl::Echo(context, request, response); - } - - int request_count() { - grpc::internal::MutexLock lock(&mu_); - return request_count_; - } - - void ResetCounters() { - grpc::internal::MutexLock lock(&mu_); - request_count_ = 0; - } - - std::set<TString> clients() { - grpc::internal::MutexLock lock(&clients_mu_); - return clients_; - } - - private: - void AddClient(const TString& client) { - grpc::internal::MutexLock lock(&clients_mu_); - clients_.insert(client); - } - - grpc::internal::Mutex mu_; - int request_count_; - grpc::internal::Mutex clients_mu_; - std::set<TString> clients_; -}; - -class ServiceConfigEnd2endTest : public ::testing::Test { - protected: - ServiceConfigEnd2endTest() - : server_host_("localhost"), - kRequestMessage_("Live long and prosper."), - creds_(new SecureChannelCredentials( - grpc_fake_transport_security_credentials_create())) {} - - static void SetUpTestCase() { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - } - - void SetUp() override { - grpc_init(); - response_generator_ = - grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); - bool localhost_resolves_to_ipv4 = false; - bool localhost_resolves_to_ipv6 = false; - grpc_core::LocalhostResolves(&localhost_resolves_to_ipv4, - &localhost_resolves_to_ipv6); - ipv6_only_ = !localhost_resolves_to_ipv4 && localhost_resolves_to_ipv6; - } - - void TearDown() override { - for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(); - } - // Explicitly destroy all the members so that we can make sure grpc_shutdown - // has finished by the end of this function, and thus all the registered - // LB policy factories are removed. - stub_.reset(); - servers_.clear(); - creds_.reset(); - grpc_shutdown(); - } - - void CreateServers(size_t num_servers, - std::vector<int> ports = std::vector<int>()) { - servers_.clear(); - for (size_t i = 0; i < num_servers; ++i) { - int port = 0; - if (ports.size() == num_servers) port = ports[i]; - servers_.emplace_back(new ServerData(port)); - } - } - - void StartServer(size_t index) { servers_[index]->Start(server_host_); } - - void StartServers(size_t num_servers, - std::vector<int> ports = std::vector<int>()) { - CreateServers(num_servers, std::move(ports)); - for (size_t i = 0; i < num_servers; ++i) { - StartServer(i); - } - } - - grpc_core::Resolver::Result BuildFakeResults(const std::vector<int>& ports) { - grpc_core::Resolver::Result result; - for (const int& port : ports) { - TString lb_uri_str = - y_absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port); - y_absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse(lb_uri_str); - GPR_ASSERT(lb_uri.ok()); - grpc_resolved_address address; - GPR_ASSERT(grpc_parse_uri(*lb_uri, &address)); - result.addresses.emplace_back(address.addr, address.len, - nullptr /* args */); - } - return result; - } - - void SetNextResolutionNoServiceConfig(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = BuildFakeResults(ports); - response_generator_->SetResponse(result); - } - - void SetNextResolutionValidServiceConfig(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = BuildFakeResults(ports); - result.service_config = grpc_core::ServiceConfig::Create( - nullptr, "{}", &result.service_config_error); - response_generator_->SetResponse(result); - } - - void SetNextResolutionInvalidServiceConfig(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = BuildFakeResults(ports); - result.service_config = grpc_core::ServiceConfig::Create( - nullptr, "{", &result.service_config_error); - response_generator_->SetResponse(result); - } - - void SetNextResolutionWithServiceConfig(const std::vector<int>& ports, - const char* svc_cfg) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = BuildFakeResults(ports); - result.service_config = grpc_core::ServiceConfig::Create( - nullptr, svc_cfg, &result.service_config_error); - response_generator_->SetResponse(result); - } - - std::vector<int> GetServersPorts(size_t start_index = 0) { - std::vector<int> ports; - for (size_t i = start_index; i < servers_.size(); ++i) { - ports.push_back(servers_[i]->port_); - } - return ports; - } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( - const std::shared_ptr<Channel>& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr<Channel> BuildChannel() { - ChannelArguments args; - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_.get()); - return ::grpc::CreateCustomChannel("fake:///", creds_, args); - } - - std::shared_ptr<Channel> BuildChannelWithDefaultServiceConfig() { - ChannelArguments args; - EXPECT_THAT(grpc::experimental::ValidateServiceConfigJSON( - ValidDefaultServiceConfig()), - ::testing::StrEq("")); - args.SetServiceConfigJSON(ValidDefaultServiceConfig()); - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_.get()); - return ::grpc::CreateCustomChannel("fake:///", creds_, args); - } - - std::shared_ptr<Channel> BuildChannelWithInvalidDefaultServiceConfig() { - ChannelArguments args; - EXPECT_THAT(grpc::experimental::ValidateServiceConfigJSON( - InvalidDefaultServiceConfig()), - ::testing::HasSubstr("JSON parse error")); - args.SetServiceConfigJSON(InvalidDefaultServiceConfig()); - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_.get()); - return ::grpc::CreateCustomChannel("fake:///", creds_, args); - } - - bool SendRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - EchoResponse* response = nullptr, int timeout_ms = 1000, - Status* result = nullptr, bool wait_for_ready = false) { - const bool local_response = (response == nullptr); - if (local_response) response = new EchoResponse; - EchoRequest request; - request.set_message(kRequestMessage_); - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); - if (wait_for_ready) context.set_wait_for_ready(true); - Status status = stub->Echo(&context, request, response); - if (result != nullptr) *result = status; - if (local_response) delete response; - return status.ok(); - } - - void CheckRpcSendOk( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - const grpc_core::DebugLocation& location, bool wait_for_ready = false) { - EchoResponse response; - Status status; - const bool success = - SendRpc(stub, &response, 2000, &status, wait_for_ready); - ASSERT_TRUE(success) << "From " << location.file() << ":" << location.line() - << "\n" - << "Error: " << status.error_message() << " " - << status.error_details(); - ASSERT_EQ(response.message(), kRequestMessage_) - << "From " << location.file() << ":" << location.line(); - if (!success) abort(); - } - - void CheckRpcSendFailure( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub) { - const bool success = SendRpc(stub); - EXPECT_FALSE(success); - } - - struct ServerData { - const int port_; - std::unique_ptr<Server> server_; - MyTestServiceImpl service_; - std::unique_ptr<std::thread> thread_; - - grpc::internal::Mutex mu_; - grpc::internal::CondVar cond_; - bool server_ready_ Y_ABSL_GUARDED_BY(mu_) = false; - bool started_ Y_ABSL_GUARDED_BY(mu_) = false; - - explicit ServerData(int port = 0) - : port_(port > 0 ? port : grpc_pick_unused_port_or_die()) {} - - void Start(const TString& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - grpc::internal::MutexLock lock(&mu_); - started_ = true; - thread_ = y_absl::make_unique<std::thread>( - std::bind(&ServerData::Serve, this, server_host)); - while (!server_ready_) { - cond_.Wait(&mu_); - } - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - - void Serve(const TString& server_host) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials( - grpc_fake_transport_security_server_credentials_create())); - builder.AddListeningPort(server_address.str(), std::move(creds)); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - grpc::internal::MutexLock lock(&mu_); - server_ready_ = true; - cond_.Signal(); - } - - void Shutdown() { - grpc::internal::MutexLock lock(&mu_); - if (!started_) return; - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - thread_->join(); - started_ = false; - } - - void SetServingStatus(const TString& service, bool serving) { - server_->GetHealthCheckService()->SetServingStatus(service, serving); - } - }; - - void ResetCounters() { - for (const auto& server : servers_) server->service_.ResetCounters(); - } - - void WaitForServer( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - size_t server_idx, const grpc_core::DebugLocation& location, - bool ignore_failure = false) { - do { - if (ignore_failure) { - SendRpc(stub); - } else { - CheckRpcSendOk(stub, location, true); - } - } while (servers_[server_idx]->service_.request_count() == 0); - ResetCounters(); - } - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(false /* try_to_connect */)) == - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(true /* try_to_connect */)) != - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool SeenAllServers() { - for (const auto& server : servers_) { - if (server->service_.request_count() == 0) return false; - } - return true; - } - - // Updates \a connection_order by appending to it the index of the newly - // connected server. Must be called after every single RPC. - void UpdateConnectionOrder( - const std::vector<std::unique_ptr<ServerData>>& servers, - std::vector<int>* connection_order) { - for (size_t i = 0; i < servers.size(); ++i) { - if (servers[i]->service_.request_count() == 1) { - // Was the server index known? If not, update connection_order. - const auto it = - std::find(connection_order->begin(), connection_order->end(), i); - if (it == connection_order->end()) { - connection_order->push_back(i); - return; - } - } - } - } - - const char* ValidServiceConfigV1() { return "{\"version\": \"1\"}"; } - - const char* ValidServiceConfigV2() { return "{\"version\": \"2\"}"; } - - const char* ValidDefaultServiceConfig() { - return "{\"version\": \"valid_default\"}"; - } - - const char* InvalidDefaultServiceConfig() { - return "{\"version\": \"invalid_default\""; - } - - bool ipv6_only_ = false; - const TString server_host_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::vector<std::unique_ptr<ServerData>> servers_; - grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> - response_generator_; - const TString kRequestMessage_; - std::shared_ptr<ChannelCredentials> creds_; -}; - -TEST_F(ServiceConfigEnd2endTest, NoServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, NoServiceConfigWithDefaultConfigTest) { - StartServers(1); - auto channel = BuildChannelWithDefaultServiceConfig(); - auto stub = BuildStub(channel); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidDefaultServiceConfig(), - channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, ValidServiceConfigUpdatesTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV2()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV2(), channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - NoServiceConfigUpdateAfterValidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - NoServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { - StartServers(1); - auto channel = BuildChannelWithDefaultServiceConfig(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidDefaultServiceConfig(), - channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidServiceConfigUpdateAfterValidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { - StartServers(1); - auto channel = BuildChannelWithDefaultServiceConfig(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - ValidServiceConfigAfterInvalidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); - SetNextResolutionValidServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); -} - -TEST_F(ServiceConfigEnd2endTest, NoServiceConfigAfterInvalidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - AnotherInvalidServiceConfigAfterInvalidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, InvalidDefaultServiceConfigTest) { - StartServers(1); - auto channel = BuildChannelWithInvalidDefaultServiceConfig(); - auto stub = BuildStub(channel); - // An invalid default service config results in a lame channel which fails all - // RPCs - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidDefaultServiceConfigTestWithValidServiceConfig) { - StartServers(1); - auto channel = BuildChannelWithInvalidDefaultServiceConfig(); - auto stub = BuildStub(channel); - CheckRpcSendFailure(stub); - // An invalid default service config results in a lame channel which fails all - // RPCs - SetNextResolutionValidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidDefaultServiceConfigTestWithInvalidServiceConfig) { - StartServers(1); - auto channel = BuildChannelWithInvalidDefaultServiceConfig(); - auto stub = BuildStub(channel); - CheckRpcSendFailure(stub); - // An invalid default service config results in a lame channel which fails all - // RPCs - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidDefaultServiceConfigTestWithNoServiceConfig) { - StartServers(1); - auto channel = BuildChannelWithInvalidDefaultServiceConfig(); - auto stub = BuildStub(channel); - CheckRpcSendFailure(stub); - // An invalid default service config results in a lame channel which fails all - // RPCs - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(argc, argv); - const auto result = RUN_ALL_TESTS(); - return result; -} diff --git a/contrib/libs/grpc/test/cpp/end2end/shutdown_test.cc b/contrib/libs/grpc/test/cpp/end2end/shutdown_test.cc deleted file mode 100644 index 01d32fc3bf..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/shutdown_test.cc +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * Copyright 2015 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 <thread> - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/support/log.h> -#include <grpc/support/sync.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/env.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/test_credentials_provider.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { - -class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - explicit TestServiceImpl(gpr_event* ev) : ev_(ev) {} - - Status Echo(ServerContext* context, const EchoRequest* /*request*/, - EchoResponse* /*response*/) override { - gpr_event_set(ev_, reinterpret_cast<void*>(1)); - while (!context->IsCancelled()) { - } - return Status::OK; - } - - private: - gpr_event* ev_; -}; - -class ShutdownTest : public ::testing::TestWithParam<string> { - public: - ShutdownTest() : shutdown_(false), service_(&ev_) { gpr_event_init(&ev_); } - - void SetUp() override { - port_ = grpc_pick_unused_port_or_die(); - server_ = SetUpServer(port_); - } - - std::unique_ptr<Server> SetUpServer(const int port) { - TString server_address = "localhost:" + to_string(port); - - ServerBuilder builder; - auto server_creds = - GetCredentialsProvider()->GetServerCredentials(GetParam()); - builder.AddListeningPort(server_address, server_creds); - builder.RegisterService(&service_); - std::unique_ptr<Server> server = builder.BuildAndStart(); - return server; - } - - void TearDown() override { GPR_ASSERT(shutdown_); } - - void ResetStub() { - string target = "dns:localhost:" + to_string(port_); - ChannelArguments args; - auto channel_creds = - GetCredentialsProvider()->GetChannelCredentials(GetParam(), &args); - channel_ = ::grpc::CreateCustomChannel(target, channel_creds, args); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - string to_string(const int number) { - std::stringstream strs; - strs << number; - return strs.str(); - } - - void SendRequest() { - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - ClientContext context; - GPR_ASSERT(!shutdown_); - Status s = stub_->Echo(&context, request, &response); - GPR_ASSERT(shutdown_); - } - - protected: - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - bool shutdown_; - int port_; - gpr_event ev_; - TestServiceImpl service_; -}; - -std::vector<string> GetAllCredentialsTypeList() { - std::vector<TString> credentials_types; - if (GetCredentialsProvider()->GetChannelCredentials(kInsecureCredentialsType, - nullptr) != nullptr) { - credentials_types.push_back(kInsecureCredentialsType); - } - auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); - for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { - credentials_types.push_back(*sec); - } - GPR_ASSERT(!credentials_types.empty()); - - TString credentials_type_list("credentials types:"); - for (const string& type : credentials_types) { - credentials_type_list.append(" " + type); - } - gpr_log(GPR_INFO, "%s", credentials_type_list.c_str()); - return credentials_types; -} - -INSTANTIATE_TEST_SUITE_P(End2EndShutdown, ShutdownTest, - ::testing::ValuesIn(GetAllCredentialsTypeList())); - -// TODO(ctiller): leaked objects in this test -TEST_P(ShutdownTest, ShutdownTest) { - ResetStub(); - - // send the request in a background thread - std::thread thr(std::bind(&ShutdownTest::SendRequest, this)); - - // wait for the server to get the event - gpr_event_wait(&ev_, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - - shutdown_ = true; - - // shutdown should trigger cancellation causing everything to shutdown - auto deadline = - std::chrono::system_clock::now() + std::chrono::microseconds(100); - server_->Shutdown(deadline); - EXPECT_GE(std::chrono::system_clock::now(), deadline); - - thr.join(); -} - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/streaming_throughput_test.cc b/contrib/libs/grpc/test/cpp/end2end/streaming_throughput_test.cc deleted file mode 100644 index 41721957e5..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/streaming_throughput_test.cc +++ /dev/null @@ -1,193 +0,0 @@ -/* - * - * Copyright 2015 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 <time.h> - -#include <mutex> -#include <thread> - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -const char* kLargeString = - "(" - "To be, or not to be- that is the question:" - "Whether 'tis nobler in the mind to suffer" - "The slings and arrows of outrageous fortune" - "Or to take arms against a sea of troubles," - "And by opposing end them. To die- to sleep-" - "No more; and by a sleep to say we end" - "The heartache, and the thousand natural shock" - "That flesh is heir to. 'Tis a consummation" - "Devoutly to be wish'd. To die- to sleep." - "To sleep- perchance to dream: ay, there's the rub!" - "For in that sleep of death what dreams may come" - "When we have shuffled off this mortal coil," - "Must give us pause. There's the respect" - "That makes calamity of so long life." - "For who would bear the whips and scorns of time," - "Th' oppressor's wrong, the proud man's contumely," - "The pangs of despis'd love, the law's delay," - "The insolence of office, and the spurns" - "That patient merit of th' unworthy takes," - "When he himself might his quietus make" - "With a bare bodkin? Who would these fardels bear," - "To grunt and sweat under a weary life," - "But that the dread of something after death-" - "The undiscover'd country, from whose bourn" - "No traveller returns- puzzles the will," - "And makes us rather bear those ills we have" - "Than fly to others that we know not of?" - "Thus conscience does make cowards of us all," - "And thus the native hue of resolution" - "Is sicklied o'er with the pale cast of thought," - "And enterprises of great pith and moment" - "With this regard their currents turn awry" - "And lose the name of action.- Soft you now!" - "The fair Ophelia!- Nymph, in thy orisons" - "Be all my sins rememb'red."; - -namespace grpc { -namespace testing { - -class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - static void BidiStream_Sender( - ServerReaderWriter<EchoResponse, EchoRequest>* stream, - gpr_atm* should_exit) { - EchoResponse response; - response.set_message(kLargeString); - while (gpr_atm_acq_load(should_exit) == static_cast<gpr_atm>(0)) { - struct timespec tv = {0, 1000000}; // 1 ms - struct timespec rem; - // TODO (vpai): Mark this blocking - while (nanosleep(&tv, &rem) != 0) { - tv = rem; - }; - - stream->Write(response); - } - } - - // Only implement the one method we will be calling for brevity. - Status BidiStream( - ServerContext* /*context*/, - ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { - EchoRequest request; - gpr_atm should_exit; - gpr_atm_rel_store(&should_exit, static_cast<gpr_atm>(0)); - - std::thread sender( - std::bind(&TestServiceImpl::BidiStream_Sender, stream, &should_exit)); - - while (stream->Read(&request)) { - struct timespec tv = {0, 3000000}; // 3 ms - struct timespec rem; - // TODO (vpai): Mark this blocking - while (nanosleep(&tv, &rem) != 0) { - tv = rem; - }; - } - gpr_atm_rel_store(&should_exit, static_cast<gpr_atm>(1)); - sender.join(); - return Status::OK; - } -}; - -class End2endTest : public ::testing::Test { - protected: - void SetUp() override { - int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; - // Setup server - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - void TearDown() override { server_->Shutdown(); } - - void ResetStub() { - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - TestServiceImpl service_; -}; - -static void Drainer(ClientReaderWriter<EchoRequest, EchoResponse>* reader) { - EchoResponse response; - while (reader->Read(&response)) { - // Just drain out the responses as fast as possible. - } -} - -TEST_F(End2endTest, StreamingThroughput) { - ResetStub(); - grpc::ClientContext context; - auto stream = stub_->BidiStream(&context); - - auto reader = stream.get(); - std::thread receiver(std::bind(Drainer, reader)); - - for (int i = 0; i < 10000; i++) { - EchoRequest request; - request.set_message(kLargeString); - ASSERT_TRUE(stream->Write(request)); - if (i % 1000 == 0) { - gpr_log(GPR_INFO, "Send count = %d", i); - } - } - stream->WritesDone(); - receiver.join(); -} - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/thread/ya.make_ b/contrib/libs/grpc/test/cpp/end2end/thread/ya.make_ deleted file mode 100644 index afabda1c8f..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/thread/ya.make_ +++ /dev/null @@ -1,31 +0,0 @@ -GTEST_UGLY() - -OWNER( - dvshkurko - g:ymake -) - -ADDINCL( - ${ARCADIA_ROOT}/contrib/libs/grpc -) - -PEERDIR( - contrib/libs/grpc/src/proto/grpc/core - contrib/libs/grpc/src/proto/grpc/testing - contrib/libs/grpc/src/proto/grpc/testing/duplicate - contrib/libs/grpc/test/core/util - contrib/libs/grpc/test/cpp/end2end - contrib/libs/grpc/test/cpp/util -) - -NO_COMPILER_WARNINGS() - -SRCDIR( - contrib/libs/grpc/test/cpp/end2end -) - -SRCS( - thread_stress_test.cc -) - -END() diff --git a/contrib/libs/grpc/test/cpp/end2end/thread_stress_test.cc b/contrib/libs/grpc/test/cpp/end2end/thread_stress_test.cc deleted file mode 100644 index 15740cc2ce..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/thread_stress_test.cc +++ /dev/null @@ -1,440 +0,0 @@ -/* - * - * Copyright 2015 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 <cinttypes> -#include <mutex> -#include <thread> - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/impl/codegen/sync.h> -#include <grpcpp/resource_quota.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/surface/api_trace.h" -#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -const int kNumThreads = 100; // Number of threads -const int kNumAsyncSendThreads = 2; -const int kNumAsyncReceiveThreads = 50; -const int kNumAsyncServerThreads = 50; -const int kNumRpcs = 1000; // Number of RPCs per thread - -namespace grpc { -namespace testing { - -class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - TestServiceImpl() {} - - Status Echo(ServerContext* /*context*/, const EchoRequest* request, - EchoResponse* response) override { - response->set_message(request->message()); - return Status::OK; - } -}; - -template <class Service> -class CommonStressTest { - public: - CommonStressTest() : kMaxMessageSize_(8192) { -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - } - virtual ~CommonStressTest() {} - virtual void SetUp() = 0; - virtual void TearDown() = 0; - virtual void ResetStub() = 0; - virtual bool AllowExhaustion() = 0; - grpc::testing::EchoTestService::Stub* GetStub() { return stub_.get(); } - - protected: - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - - virtual void SetUpStart(ServerBuilder* builder, Service* service) = 0; - void SetUpStartCommon(ServerBuilder* builder, Service* service) { - builder->RegisterService(service); - builder->SetMaxMessageSize( - kMaxMessageSize_); // For testing max message size. - } - void SetUpEnd(ServerBuilder* builder) { server_ = builder->BuildAndStart(); } - void TearDownStart() { server_->Shutdown(); } - void TearDownEnd() {} - - private: - const int kMaxMessageSize_; -}; - -template <class Service> -class CommonStressTestInsecure : public CommonStressTest<Service> { - public: - void ResetStub() override { - std::shared_ptr<Channel> channel = grpc::CreateChannel( - server_address_.str(), InsecureChannelCredentials()); - this->stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - bool AllowExhaustion() override { return false; } - - protected: - void SetUpStart(ServerBuilder* builder, Service* service) override { - int port = 5003; // grpc_pick_unused_port_or_die(); - this->server_address_ << "localhost:" << port; - // Setup server - builder->AddListeningPort(server_address_.str(), - InsecureServerCredentials()); - this->SetUpStartCommon(builder, service); - } - - private: - std::ostringstream server_address_; -}; - -template <class Service, bool allow_resource_exhaustion> -class CommonStressTestInproc : public CommonStressTest<Service> { - public: - void ResetStub() override { - ChannelArguments args; - std::shared_ptr<Channel> channel = this->server_->InProcessChannel(args); - this->stub_ = grpc::testing::EchoTestService::NewStub(channel); - } - bool AllowExhaustion() override { return allow_resource_exhaustion; } - - protected: - void SetUpStart(ServerBuilder* builder, Service* service) override { - this->SetUpStartCommon(builder, service); - } -}; - -template <class BaseClass> -class CommonStressTestSyncServer : public BaseClass { - public: - void SetUp() override { - ServerBuilder builder; - this->SetUpStart(&builder, &service_); - this->SetUpEnd(&builder); - } - void TearDown() override { - this->TearDownStart(); - this->TearDownEnd(); - } - - private: - TestServiceImpl service_; -}; - -template <class BaseClass> -class CommonStressTestSyncServerLowThreadCount : public BaseClass { - public: - void SetUp() override { - ServerBuilder builder; - ResourceQuota quota; - this->SetUpStart(&builder, &service_); - quota.SetMaxThreads(4); - builder.SetResourceQuota(quota); - this->SetUpEnd(&builder); - } - void TearDown() override { - this->TearDownStart(); - this->TearDownEnd(); - } - - private: - TestServiceImpl service_; -}; - -template <class BaseClass> -class CommonStressTestAsyncServer : public BaseClass { - public: - CommonStressTestAsyncServer() : contexts_(kNumAsyncServerThreads * 100) {} - void SetUp() override { - shutting_down_ = false; - ServerBuilder builder; - this->SetUpStart(&builder, &service_); - cq_ = builder.AddCompletionQueue(); - this->SetUpEnd(&builder); - for (int i = 0; i < kNumAsyncServerThreads * 100; i++) { - RefreshContext(i); - } - for (int i = 0; i < kNumAsyncServerThreads; i++) { - server_threads_.emplace_back(&CommonStressTestAsyncServer::ProcessRpcs, - this); - } - } - void TearDown() override { - { - grpc::internal::MutexLock l(&mu_); - this->TearDownStart(); - shutting_down_ = true; - cq_->Shutdown(); - } - - for (int i = 0; i < kNumAsyncServerThreads; i++) { - server_threads_[i].join(); - } - - void* ignored_tag; - bool ignored_ok; - while (cq_->Next(&ignored_tag, &ignored_ok)) { - } - this->TearDownEnd(); - } - - private: - void ProcessRpcs() { - void* tag; - bool ok; - while (cq_->Next(&tag, &ok)) { - if (ok) { - int i = static_cast<int>(reinterpret_cast<intptr_t>(tag)); - switch (contexts_[i].state) { - case Context::READY: { - contexts_[i].state = Context::DONE; - EchoResponse send_response; - send_response.set_message(contexts_[i].recv_request.message()); - contexts_[i].response_writer->Finish(send_response, Status::OK, - tag); - break; - } - case Context::DONE: - RefreshContext(i); - break; - } - } - } - } - void RefreshContext(int i) { - grpc::internal::MutexLock l(&mu_); - if (!shutting_down_) { - contexts_[i].state = Context::READY; - contexts_[i].srv_ctx.reset(new ServerContext); - contexts_[i].response_writer.reset( - new grpc::ServerAsyncResponseWriter<EchoResponse>( - contexts_[i].srv_ctx.get())); - service_.RequestEcho(contexts_[i].srv_ctx.get(), - &contexts_[i].recv_request, - contexts_[i].response_writer.get(), cq_.get(), - cq_.get(), reinterpret_cast<void*>(i)); - } - } - struct Context { - std::unique_ptr<ServerContext> srv_ctx; - std::unique_ptr<grpc::ServerAsyncResponseWriter<EchoResponse>> - response_writer; - EchoRequest recv_request; - enum { READY, DONE } state; - }; - std::vector<Context> contexts_; - ::grpc::testing::EchoTestService::AsyncService service_; - std::unique_ptr<ServerCompletionQueue> cq_; - bool shutting_down_; - grpc::internal::Mutex mu_; - std::vector<std::thread> server_threads_; -}; - -template <class Common> -class End2endTest : public ::testing::Test { - protected: - End2endTest() {} - void SetUp() override { common_.SetUp(); } - void TearDown() override { common_.TearDown(); } - void ResetStub() { common_.ResetStub(); } - - Common common_; -}; - -static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs, - bool allow_exhaustion, gpr_atm* errors) { - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - for (int i = 0; i < num_rpcs; ++i) { - ClientContext context; - Status s = stub->Echo(&context, request, &response); - EXPECT_TRUE(s.ok() || (allow_exhaustion && - s.error_code() == StatusCode::RESOURCE_EXHAUSTED)); - if (!s.ok()) { - if (!(allow_exhaustion && - s.error_code() == StatusCode::RESOURCE_EXHAUSTED)) { - gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), - s.error_message().c_str()); - } - gpr_atm_no_barrier_fetch_add(errors, static_cast<gpr_atm>(1)); - } else { - EXPECT_EQ(response.message(), request.message()); - } - } -} - -typedef ::testing::Types< - CommonStressTestSyncServer<CommonStressTestInsecure<TestServiceImpl>>, - CommonStressTestSyncServer<CommonStressTestInproc<TestServiceImpl, false>>, - CommonStressTestSyncServerLowThreadCount< - CommonStressTestInproc<TestServiceImpl, true>>, - CommonStressTestAsyncServer< - CommonStressTestInsecure<grpc::testing::EchoTestService::AsyncService>>, - CommonStressTestAsyncServer<CommonStressTestInproc< - grpc::testing::EchoTestService::AsyncService, false>>> - CommonTypes; -TYPED_TEST_SUITE(End2endTest, CommonTypes); -TYPED_TEST(End2endTest, ThreadStress) { - this->common_.ResetStub(); - std::vector<std::thread> threads; - gpr_atm errors; - gpr_atm_rel_store(&errors, static_cast<gpr_atm>(0)); - threads.reserve(kNumThreads); - for (int i = 0; i < kNumThreads; ++i) { - threads.emplace_back(SendRpc, this->common_.GetStub(), kNumRpcs, - this->common_.AllowExhaustion(), &errors); - } - for (int i = 0; i < kNumThreads; ++i) { - threads[i].join(); - } - uint64_t error_cnt = static_cast<uint64_t>(gpr_atm_no_barrier_load(&errors)); - if (error_cnt != 0) { - gpr_log(GPR_INFO, "RPC error count: %" PRIu64, error_cnt); - } - // If this test allows resource exhaustion, expect that it actually sees some - if (this->common_.AllowExhaustion()) { - EXPECT_GT(error_cnt, static_cast<uint64_t>(0)); - } -} - -template <class Common> -class AsyncClientEnd2endTest : public ::testing::Test { - protected: - AsyncClientEnd2endTest() : rpcs_outstanding_(0) {} - - void SetUp() override { common_.SetUp(); } - void TearDown() override { - void* ignored_tag; - bool ignored_ok; - while (cq_.Next(&ignored_tag, &ignored_ok)) { - } - common_.TearDown(); - } - - void Wait() { - grpc::internal::MutexLock l(&mu_); - while (rpcs_outstanding_ != 0) { - cv_.Wait(&mu_); - } - - cq_.Shutdown(); - } - - struct AsyncClientCall { - EchoResponse response; - ClientContext context; - Status status; - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader; - }; - - void AsyncSendRpc(int num_rpcs) { - for (int i = 0; i < num_rpcs; ++i) { - AsyncClientCall* call = new AsyncClientCall; - EchoRequest request; - request.set_message(TString("Hello: " + grpc::to_string(i)).c_str()); - call->response_reader = - common_.GetStub()->AsyncEcho(&call->context, request, &cq_); - call->response_reader->Finish(&call->response, &call->status, call); - - grpc::internal::MutexLock l(&mu_); - rpcs_outstanding_++; - } - } - - void AsyncCompleteRpc() { - while (true) { - void* got_tag; - bool ok = false; - if (!cq_.Next(&got_tag, &ok)) break; - AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag); - if (!ok) { - gpr_log(GPR_DEBUG, "Error: %d", call->status.error_code()); - } - delete call; - - bool notify; - { - grpc::internal::MutexLock l(&mu_); - rpcs_outstanding_--; - notify = (rpcs_outstanding_ == 0); - } - if (notify) { - cv_.Signal(); - } - } - } - - Common common_; - CompletionQueue cq_; - grpc::internal::Mutex mu_; - grpc::internal::CondVar cv_; - int rpcs_outstanding_; -}; - -TYPED_TEST_SUITE(AsyncClientEnd2endTest, CommonTypes); -TYPED_TEST(AsyncClientEnd2endTest, ThreadStress) { - this->common_.ResetStub(); - std::vector<std::thread> send_threads, completion_threads; - for (int i = 0; i < kNumAsyncReceiveThreads; ++i) { - completion_threads.emplace_back( - &AsyncClientEnd2endTest_ThreadStress_Test<TypeParam>::AsyncCompleteRpc, - this); - } - for (int i = 0; i < kNumAsyncSendThreads; ++i) { - send_threads.emplace_back( - &AsyncClientEnd2endTest_ThreadStress_Test<TypeParam>::AsyncSendRpc, - this, kNumRpcs); - } - for (int i = 0; i < kNumAsyncSendThreads; ++i) { - send_threads[i].join(); - } - - this->Wait(); - for (int i = 0; i < kNumAsyncReceiveThreads; ++i) { - completion_threads[i].join(); - } -} - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/end2end/time_change_test.cc b/contrib/libs/grpc/test/cpp/end2end/time_change_test.cc deleted file mode 100644 index c058b62d61..0000000000 --- a/contrib/libs/grpc/test/cpp/end2end/time_change_test.cc +++ /dev/null @@ -1,371 +0,0 @@ -/* - * - * Copyright 2019 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 <sys/time.h> - -#include <thread> - -#include <gtest/gtest.h> - -#include "y_absl/memory/memory.h" - -#include <grpc/grpc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/iomgr/timer.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/subprocess.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -static TString g_root; - -static gpr_mu g_mu; -extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); -gpr_timespec (*gpr_now_impl_orig)(gpr_clock_type clock_type) = gpr_now_impl; -static int g_time_shift_sec = 0; -static int g_time_shift_nsec = 0; -static gpr_timespec now_impl(gpr_clock_type clock) { - auto ts = gpr_now_impl_orig(clock); - // We only manipulate the realtime clock to simulate changes in wall-clock - // time - if (clock != GPR_CLOCK_REALTIME) { - return ts; - } - GPR_ASSERT(ts.tv_nsec >= 0); - GPR_ASSERT(ts.tv_nsec < GPR_NS_PER_SEC); - gpr_mu_lock(&g_mu); - ts.tv_sec += g_time_shift_sec; - ts.tv_nsec += g_time_shift_nsec; - gpr_mu_unlock(&g_mu); - if (ts.tv_nsec >= GPR_NS_PER_SEC) { - ts.tv_nsec -= GPR_NS_PER_SEC; - ++ts.tv_sec; - } else if (ts.tv_nsec < 0) { - --ts.tv_sec; - ts.tv_nsec = GPR_NS_PER_SEC + ts.tv_nsec; - } - return ts; -} - -// offset the value returned by gpr_now(GPR_CLOCK_REALTIME) by msecs -// milliseconds -static void set_now_offset(int msecs) { - gpr_mu_lock(&g_mu); - g_time_shift_sec = msecs / 1000; - g_time_shift_nsec = (msecs % 1000) * 1e6; - gpr_mu_unlock(&g_mu); -} - -// restore the original implementation of gpr_now() -static void reset_now_offset() { - gpr_mu_lock(&g_mu); - g_time_shift_sec = 0; - g_time_shift_nsec = 0; - gpr_mu_unlock(&g_mu); -} - -namespace grpc { -namespace testing { - -namespace { - -// gpr_now() is called with invalid clock_type -TEST(TimespecTest, GprNowInvalidClockType) { - // initialize to some junk value - gpr_clock_type invalid_clock_type = static_cast<gpr_clock_type>(32641); - EXPECT_DEATH(gpr_now(invalid_clock_type), ".*"); -} - -// Add timespan with negative nanoseconds -TEST(TimespecTest, GprTimeAddNegativeNs) { - gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); - gpr_timespec bad_ts = {1, -1000, GPR_TIMESPAN}; - EXPECT_DEATH(gpr_time_add(now, bad_ts), ".*"); -} - -// Subtract timespan with negative nanoseconds -TEST(TimespecTest, GprTimeSubNegativeNs) { - // Nanoseconds must always be positive. Negative timestamps are represented by - // (negative seconds, positive nanoseconds) - gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); - gpr_timespec bad_ts = {1, -1000, GPR_TIMESPAN}; - EXPECT_DEATH(gpr_time_sub(now, bad_ts), ".*"); -} - -// Add negative milliseconds to gpr_timespec -TEST(TimespecTest, GrpcNegativeMillisToTimespec) { - // -1500 milliseconds converts to timespec (-2 secs, 5 * 10^8 nsec) - gpr_timespec ts = grpc_millis_to_timespec(-1500, GPR_CLOCK_MONOTONIC); - GPR_ASSERT(ts.tv_sec = -2); - GPR_ASSERT(ts.tv_nsec = 5e8); - GPR_ASSERT(ts.clock_type == GPR_CLOCK_MONOTONIC); -} - -class TimeChangeTest : public ::testing::Test { - protected: - TimeChangeTest() {} - - static void SetUpTestCase() { - auto port = grpc_pick_unused_port_or_die(); - std::ostringstream addr_stream; - addr_stream << "localhost:" << port; - server_address_ = addr_stream.str(); - server_ = y_absl::make_unique<SubProcess>(std::vector<TString>({ - g_root + "/client_crash_test_server", - "--address=" + server_address_, - })); - GPR_ASSERT(server_); - // connect to server and make sure it's reachable. - auto channel = - grpc::CreateChannel(server_address_, InsecureChannelCredentials()); - GPR_ASSERT(channel); - EXPECT_TRUE(channel->WaitForConnected( - grpc_timeout_milliseconds_to_deadline(30000))); - } - - static void TearDownTestCase() { server_.reset(); } - - void SetUp() override { - channel_ = - grpc::CreateChannel(server_address_, InsecureChannelCredentials()); - GPR_ASSERT(channel_); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - void TearDown() override { reset_now_offset(); } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> CreateStub() { - return grpc::testing::EchoTestService::NewStub(channel_); - } - - std::shared_ptr<Channel> GetChannel() { return channel_; } - // time jump offsets in milliseconds - const int TIME_OFFSET1 = 20123; - const int TIME_OFFSET2 = 5678; - - private: - static TString server_address_; - static std::unique_ptr<SubProcess> server_; - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; -}; -TString TimeChangeTest::server_address_; -std::unique_ptr<SubProcess> TimeChangeTest::server_; - -// Wall-clock time jumps forward on client before bidi stream is created -TEST_F(TimeChangeTest, TimeJumpForwardBeforeStreamCreated) { - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); - context.AddMetadata(kServerResponseStreamsToSend, "1"); - - auto channel = GetChannel(); - GPR_ASSERT(channel); - EXPECT_TRUE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); - auto stub = CreateStub(); - - // time jumps forward by TIME_OFFSET1 milliseconds - set_now_offset(TIME_OFFSET1); - auto stream = stub->BidiStream(&context); - request.set_message("Hello"); - EXPECT_TRUE(stream->Write(request)); - - EXPECT_TRUE(stream->WritesDone()); - EXPECT_TRUE(stream->Read(&response)); - - auto status = stream->Finish(); - EXPECT_TRUE(status.ok()); -} - -// Wall-clock time jumps back on client before bidi stream is created -TEST_F(TimeChangeTest, TimeJumpBackBeforeStreamCreated) { - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); - context.AddMetadata(kServerResponseStreamsToSend, "1"); - - auto channel = GetChannel(); - GPR_ASSERT(channel); - EXPECT_TRUE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); - auto stub = CreateStub(); - - // time jumps back by TIME_OFFSET1 milliseconds - set_now_offset(-TIME_OFFSET1); - auto stream = stub->BidiStream(&context); - request.set_message("Hello"); - EXPECT_TRUE(stream->Write(request)); - - EXPECT_TRUE(stream->WritesDone()); - EXPECT_TRUE(stream->Read(&response)); - EXPECT_EQ(request.message(), response.message()); - - auto status = stream->Finish(); - EXPECT_TRUE(status.ok()); -} - -// Wall-clock time jumps forward on client while call is in progress -TEST_F(TimeChangeTest, TimeJumpForwardAfterStreamCreated) { - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); - context.AddMetadata(kServerResponseStreamsToSend, "2"); - - auto channel = GetChannel(); - GPR_ASSERT(channel); - EXPECT_TRUE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); - auto stub = CreateStub(); - - auto stream = stub->BidiStream(&context); - - request.set_message("Hello"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - - // time jumps forward by TIME_OFFSET1 milliseconds. - set_now_offset(TIME_OFFSET1); - - request.set_message("World"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->WritesDone()); - EXPECT_TRUE(stream->Read(&response)); - - auto status = stream->Finish(); - EXPECT_TRUE(status.ok()); -} - -// Wall-clock time jumps back on client while call is in progress -TEST_F(TimeChangeTest, TimeJumpBackAfterStreamCreated) { - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); - context.AddMetadata(kServerResponseStreamsToSend, "2"); - - auto channel = GetChannel(); - GPR_ASSERT(channel); - EXPECT_TRUE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); - auto stub = CreateStub(); - - auto stream = stub->BidiStream(&context); - - request.set_message("Hello"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->Read(&response)); - - // time jumps back TIME_OFFSET1 milliseconds. - set_now_offset(-TIME_OFFSET1); - - request.set_message("World"); - EXPECT_TRUE(stream->Write(request)); - EXPECT_TRUE(stream->WritesDone()); - EXPECT_TRUE(stream->Read(&response)); - - auto status = stream->Finish(); - EXPECT_TRUE(status.ok()); -} - -// Wall-clock time jumps forward and backwards during call -TEST_F(TimeChangeTest, TimeJumpForwardAndBackDuringCall) { - EchoRequest request; - EchoResponse response; - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); - context.AddMetadata(kServerResponseStreamsToSend, "2"); - - auto channel = GetChannel(); - GPR_ASSERT(channel); - - EXPECT_TRUE( - channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); - auto stub = CreateStub(); - auto stream = stub->BidiStream(&context); - - request.set_message("Hello"); - EXPECT_TRUE(stream->Write(request)); - - // time jumps back by TIME_OFFSET2 milliseconds - set_now_offset(-TIME_OFFSET2); - - EXPECT_TRUE(stream->Read(&response)); - request.set_message("World"); - - // time jumps forward by TIME_OFFSET milliseconds - set_now_offset(TIME_OFFSET1); - - EXPECT_TRUE(stream->Write(request)); - - // time jumps back by TIME_OFFSET2 milliseconds - set_now_offset(-TIME_OFFSET2); - - EXPECT_TRUE(stream->WritesDone()); - - // time jumps back by TIME_OFFSET2 milliseconds - set_now_offset(-TIME_OFFSET2); - - EXPECT_TRUE(stream->Read(&response)); - - // time jumps back by TIME_OFFSET2 milliseconds - set_now_offset(-TIME_OFFSET2); - - auto status = stream->Finish(); - EXPECT_TRUE(status.ok()); -} - -} // namespace - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - TString me = argv[0]; - // get index of last slash in path to test binary - auto lslash = me.rfind('/'); - // set g_root = path to directory containing test binary - if (lslash != TString::npos) { - g_root = me.substr(0, lslash); - } else { - g_root = "."; - } - - gpr_mu_init(&g_mu); - gpr_now_impl = now_impl; - - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - auto ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/util/.yandex_meta/licenses.list.txt b/contrib/libs/grpc/test/cpp/util/.yandex_meta/licenses.list.txt deleted file mode 100644 index c498b515e1..0000000000 --- a/contrib/libs/grpc/test/cpp/util/.yandex_meta/licenses.list.txt +++ /dev/null @@ -1,50 +0,0 @@ -====================Apache-2.0==================== - * 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. - - -====================Apache-2.0==================== -// 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. - - -====================COPYRIGHT==================== - * Copyright 2015 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2015-2016 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2016 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2017 gRPC authors. - - -====================COPYRIGHT==================== - * Copyright 2018 gRPC authors. - - -====================COPYRIGHT==================== -// Copyright 2021 gRPC authors. diff --git a/contrib/libs/grpc/test/cpp/util/byte_buffer_test.cc b/contrib/libs/grpc/test/cpp/util/byte_buffer_test.cc deleted file mode 100644 index ab18b5ecc6..0000000000 --- a/contrib/libs/grpc/test/cpp/util/byte_buffer_test.cc +++ /dev/null @@ -1,163 +0,0 @@ -/* - * - * Copyright 2015 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 <cstring> -#include <vector> - -#include <gtest/gtest.h> - -#include <grpc++/support/byte_buffer.h> -#include <grpc/grpc.h> -#include <grpc/slice.h> -#include <grpcpp/impl/grpc_library.h> -#include <grpcpp/support/slice.h> - -#include "test/core/util/test_config.h" - -namespace grpc { - -static internal::GrpcLibraryInitializer g_gli_initializer; - -namespace { - -const char* kContent1 = "hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char* kContent2 = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy world"; - -class ByteBufferTest : public ::testing::Test { - protected: - static void SetUpTestCase() { grpc_init(); } - - static void TearDownTestCase() { grpc_shutdown(); } -}; - -TEST_F(ByteBufferTest, CopyCtor) { - ByteBuffer buffer1; - EXPECT_FALSE(buffer1.Valid()); - const ByteBuffer& buffer2 = buffer1; - EXPECT_FALSE(buffer2.Valid()); -} - -TEST_F(ByteBufferTest, CreateFromSingleSlice) { - Slice s(kContent1); - ByteBuffer buffer(&s, 1); - EXPECT_EQ(strlen(kContent1), buffer.Length()); -} - -TEST_F(ByteBufferTest, CreateFromVector) { - std::vector<Slice> slices; - slices.emplace_back(kContent1); - slices.emplace_back(kContent2); - ByteBuffer buffer(&slices[0], 2); - EXPECT_EQ(strlen(kContent1) + strlen(kContent2), buffer.Length()); -} - -TEST_F(ByteBufferTest, Clear) { - Slice s(kContent1); - ByteBuffer buffer(&s, 1); - buffer.Clear(); - EXPECT_EQ(static_cast<size_t>(0), buffer.Length()); -} - -TEST_F(ByteBufferTest, Length) { - std::vector<Slice> slices; - slices.emplace_back(kContent1); - slices.emplace_back(kContent2); - ByteBuffer buffer(&slices[0], 2); - EXPECT_EQ(strlen(kContent1) + strlen(kContent2), buffer.Length()); -} - -bool SliceEqual(const Slice& a, grpc_slice b) { - if (a.size() != GRPC_SLICE_LENGTH(b)) { - return false; - } - for (size_t i = 0; i < a.size(); i++) { - if (a.begin()[i] != GRPC_SLICE_START_PTR(b)[i]) { - return false; - } - } - return true; -} - -TEST_F(ByteBufferTest, Dump) { - grpc_slice hello = grpc_slice_from_copied_string(kContent1); - grpc_slice world = grpc_slice_from_copied_string(kContent2); - std::vector<Slice> slices; - slices.push_back(Slice(hello, Slice::STEAL_REF)); - slices.push_back(Slice(world, Slice::STEAL_REF)); - ByteBuffer buffer(&slices[0], 2); - slices.clear(); - (void)buffer.Dump(&slices); - EXPECT_TRUE(SliceEqual(slices[0], hello)); - EXPECT_TRUE(SliceEqual(slices[1], world)); -} - -TEST_F(ByteBufferTest, SerializationMakesCopy) { - grpc_slice hello = grpc_slice_from_copied_string(kContent1); - grpc_slice world = grpc_slice_from_copied_string(kContent2); - std::vector<Slice> slices; - slices.push_back(Slice(hello, Slice::STEAL_REF)); - slices.push_back(Slice(world, Slice::STEAL_REF)); - ByteBuffer send_buffer; - bool owned = false; - ByteBuffer buffer(&slices[0], 2); - slices.clear(); - auto status = SerializationTraits<ByteBuffer, void>::Serialize( - buffer, &send_buffer, &owned); - EXPECT_TRUE(status.ok()); - EXPECT_TRUE(owned); - EXPECT_TRUE(send_buffer.Valid()); -} - -TEST_F(ByteBufferTest, TrySingleSliceWithSingleSlice) { - std::vector<Slice> slices; - slices.emplace_back(kContent1); - ByteBuffer buffer(&slices[0], 1); - Slice slice; - EXPECT_TRUE(buffer.TrySingleSlice(&slice).ok()); - EXPECT_EQ(slice.size(), slices[0].size()); - EXPECT_EQ(memcmp(slice.begin(), slices[0].begin(), slice.size()), 0); -} - -TEST_F(ByteBufferTest, TrySingleSliceWithMultipleSlices) { - std::vector<Slice> slices; - slices.emplace_back(kContent1); - slices.emplace_back(kContent2); - ByteBuffer buffer(&slices[0], 2); - Slice slice; - EXPECT_FALSE(buffer.TrySingleSlice(&slice).ok()); -} - -TEST_F(ByteBufferTest, DumpToSingleSlice) { - std::vector<Slice> slices; - slices.emplace_back(kContent1); - slices.emplace_back(kContent2); - ByteBuffer buffer(&slices[0], 2); - Slice slice; - EXPECT_TRUE(buffer.DumpToSingleSlice(&slice).ok()); - EXPECT_EQ(strlen(kContent1) + strlen(kContent2), slice.size()); -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.cc b/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.cc deleted file mode 100644 index 672e5c6544..0000000000 --- a/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright 2018 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 <grpc/support/port_platform.h> - -#include "test/cpp/util/channel_trace_proto_helper.h" - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/support/log.h> -#include <grpcpp/impl/codegen/config.h> -#include <grpcpp/impl/codegen/config_protobuf.h> - -#include "src/core/lib/iomgr/error.h" -#include "src/core/lib/json/json.h" -#include "src/proto/grpc/channelz/channelz.pb.h" - -namespace grpc { - -namespace { - -// Generic helper that takes in a json string, converts it to a proto, and -// then back to json. This ensures that the json string was correctly formatted -// according to https://developers.google.com/protocol-buffers/docs/proto3#json -template <typename Message> -void VaidateProtoJsonTranslation(const TString& json_str) { - Message msg; - grpc::protobuf::json::JsonParseOptions parse_options; - // If the following line is failing, then uncomment the last line of the - // comment, and uncomment the lines that print the two strings. You can - // then compare the output, and determine what fields are missing. - // - // parse_options.ignore_unknown_fields = true; - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, &msg, parse_options); - EXPECT_TRUE(s.ok()); - TString proto_json_str; - grpc::protobuf::json::JsonPrintOptions print_options; - // We usually do not want this to be true, however it can be helpful to - // uncomment and see the output produced then all fields are printed. - // print_options.always_print_primitive_fields = true; - s = grpc::protobuf::json::MessageToJsonString(msg, &proto_json_str); - EXPECT_TRUE(s.ok()); - // Parse JSON and re-dump to string, to make sure formatting is the - // same as what would be generated by our JSON library. - grpc_error_handle error = GRPC_ERROR_NONE; - grpc_core::Json parsed_json = - grpc_core::Json::Parse(proto_json_str.c_str(), &error); - ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error); - ASSERT_EQ(parsed_json.type(), grpc_core::Json::Type::OBJECT); - proto_json_str = parsed_json.Dump(); - // uncomment these to compare the json strings. - // gpr_log(GPR_ERROR, "tracer json: %s", json_str.c_str()); - // gpr_log(GPR_ERROR, "proto json: %s", proto_json_str.c_str()); - EXPECT_EQ(json_str, proto_json_str); -} - -} // namespace - -namespace testing { - -void ValidateChannelTraceProtoJsonTranslation(const char* json_c_str) { - VaidateProtoJsonTranslation<grpc::channelz::v1::ChannelTrace>(json_c_str); -} - -void ValidateChannelProtoJsonTranslation(const char* json_c_str) { - VaidateProtoJsonTranslation<grpc::channelz::v1::Channel>(json_c_str); -} - -void ValidateGetTopChannelsResponseProtoJsonTranslation( - const char* json_c_str) { - VaidateProtoJsonTranslation<grpc::channelz::v1::GetTopChannelsResponse>( - json_c_str); -} - -void ValidateGetChannelResponseProtoJsonTranslation(const char* json_c_str) { - VaidateProtoJsonTranslation<grpc::channelz::v1::GetChannelResponse>( - json_c_str); -} - -void ValidateGetServerResponseProtoJsonTranslation(const char* json_c_str) { - VaidateProtoJsonTranslation<grpc::channelz::v1::GetServerResponse>( - json_c_str); -} - -void ValidateSubchannelProtoJsonTranslation(const char* json_c_str) { - VaidateProtoJsonTranslation<grpc::channelz::v1::Subchannel>(json_c_str); -} - -void ValidateServerProtoJsonTranslation(const char* json_c_str) { - VaidateProtoJsonTranslation<grpc::channelz::v1::Server>(json_c_str); -} - -void ValidateGetServersResponseProtoJsonTranslation(const char* json_c_str) { - VaidateProtoJsonTranslation<grpc::channelz::v1::GetServersResponse>( - json_c_str); -} - -} // namespace testing -} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.h b/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.h deleted file mode 100644 index 664e899deb..0000000000 --- a/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * Copyright 2018 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H -#define GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H - -namespace grpc { -namespace testing { - -void ValidateChannelTraceProtoJsonTranslation(const char* json_c_str); -void ValidateChannelProtoJsonTranslation(const char* json_c_str); -void ValidateGetTopChannelsResponseProtoJsonTranslation(const char* json_c_str); -void ValidateGetChannelResponseProtoJsonTranslation(const char* json_c_str); -void ValidateGetServerResponseProtoJsonTranslation(const char* json_c_str); -void ValidateSubchannelProtoJsonTranslation(const char* json_c_str); -void ValidateServerProtoJsonTranslation(const char* json_c_str); -void ValidateGetServersResponseProtoJsonTranslation(const char* json_c_str); - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H diff --git a/contrib/libs/grpc/test/cpp/util/channelz_sampler.cc b/contrib/libs/grpc/test/cpp/util/channelz_sampler.cc deleted file mode 100644 index 65d6a18a07..0000000000 --- a/contrib/libs/grpc/test/cpp/util/channelz_sampler.cc +++ /dev/null @@ -1,593 +0,0 @@ -/* - * - * Copyright 2015 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 <grpc/support/port_platform.h> - -#include <unistd.h> - -#include <cstdlib> -#include <fstream> -#include <iostream> -#include <memory> -#include <ostream> -#include <queue> -#include <util/generic/string.h> - -#include "y_absl/flags/flag.h" -#include "y_absl/strings/str_format.h" -#include "y_absl/strings/str_join.h" -#include "google/protobuf/text_format.h" - -#include <grpc/grpc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/ext/channelz_service_plugin.h> -#include <grpcpp/grpcpp.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/json/json.h" -#include "src/cpp/server/channelz/channelz_service.h" -#include "src/proto/grpc/channelz/channelz.pb.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/test_config.h" -#include "test/cpp/util/test_credentials_provider.h" - -Y_ABSL_FLAG(TString, server_address, "", "channelz server address"); -Y_ABSL_FLAG(TString, custom_credentials_type, "", "custom credentials type"); -Y_ABSL_FLAG(int64_t, sampling_times, 1, "number of sampling"); -// TODO(Capstan): Consider using y_absl::Duration -Y_ABSL_FLAG(int64_t, sampling_interval_seconds, 0, - "sampling interval in seconds"); -Y_ABSL_FLAG(TString, output_json, "", "output filename in json format"); - -namespace { -using grpc::ClientContext; -using grpc::Status; -using grpc::StatusCode; -using grpc::channelz::v1::GetChannelRequest; -using grpc::channelz::v1::GetChannelResponse; -using grpc::channelz::v1::GetServersRequest; -using grpc::channelz::v1::GetServersResponse; -using grpc::channelz::v1::GetSocketRequest; -using grpc::channelz::v1::GetSocketResponse; -using grpc::channelz::v1::GetSubchannelRequest; -using grpc::channelz::v1::GetSubchannelResponse; -using grpc::channelz::v1::GetTopChannelsRequest; -using grpc::channelz::v1::GetTopChannelsResponse; -} // namespace - -class ChannelzSampler final { - public: - // Get server_id of a server - int64_t GetServerID(const grpc::channelz::v1::Server& server) { - return server.ref().server_id(); - } - - // Get channel_id of a channel - inline int64_t GetChannelID(const grpc::channelz::v1::Channel& channel) { - return channel.ref().channel_id(); - } - - // Get subchannel_id of a subchannel - inline int64_t GetSubchannelID( - const grpc::channelz::v1::Subchannel& subchannel) { - return subchannel.ref().subchannel_id(); - } - - // Get socket_id of a socket - inline int64_t GetSocketID(const grpc::channelz::v1::Socket& socket) { - return socket.ref().socket_id(); - } - - // Get name of a server - inline TString GetServerName(const grpc::channelz::v1::Server& server) { - return server.ref().name(); - } - - // Get name of a channel - inline TString GetChannelName( - const grpc::channelz::v1::Channel& channel) { - return channel.ref().name(); - } - - // Get name of a subchannel - inline TString GetSubchannelName( - const grpc::channelz::v1::Subchannel& subchannel) { - return subchannel.ref().name(); - } - - // Get name of a socket - inline TString GetSocketName(const grpc::channelz::v1::Socket& socket) { - return socket.ref().name(); - } - - // Get a channel based on channel_id - grpc::channelz::v1::Channel GetChannelRPC(int64_t channel_id) { - GetChannelRequest get_channel_request; - get_channel_request.set_channel_id(channel_id); - GetChannelResponse get_channel_response; - ClientContext get_channel_context; - get_channel_context.set_deadline( - grpc_timeout_seconds_to_deadline(rpc_timeout_seconds_)); - Status status = channelz_stub_->GetChannel( - &get_channel_context, get_channel_request, &get_channel_response); - if (!status.ok()) { - gpr_log(GPR_ERROR, "GetChannelRPC failed: %s", - get_channel_context.debug_error_string().c_str()); - GPR_ASSERT(0); - } - return get_channel_response.channel(); - } - - // Get a subchannel based on subchannel_id - grpc::channelz::v1::Subchannel GetSubchannelRPC(int64_t subchannel_id) { - GetSubchannelRequest get_subchannel_request; - get_subchannel_request.set_subchannel_id(subchannel_id); - GetSubchannelResponse get_subchannel_response; - ClientContext get_subchannel_context; - get_subchannel_context.set_deadline( - grpc_timeout_seconds_to_deadline(rpc_timeout_seconds_)); - Status status = channelz_stub_->GetSubchannel(&get_subchannel_context, - get_subchannel_request, - &get_subchannel_response); - if (!status.ok()) { - gpr_log(GPR_ERROR, "GetSubchannelRPC failed: %s", - get_subchannel_context.debug_error_string().c_str()); - GPR_ASSERT(0); - } - return get_subchannel_response.subchannel(); - } - - // get a socket based on socket_id - grpc::channelz::v1::Socket GetSocketRPC(int64_t socket_id) { - GetSocketRequest get_socket_request; - get_socket_request.set_socket_id(socket_id); - GetSocketResponse get_socket_response; - ClientContext get_socket_context; - get_socket_context.set_deadline( - grpc_timeout_seconds_to_deadline(rpc_timeout_seconds_)); - Status status = channelz_stub_->GetSocket( - &get_socket_context, get_socket_request, &get_socket_response); - if (!status.ok()) { - gpr_log(GPR_ERROR, "GetSocketRPC failed: %s", - get_socket_context.debug_error_string().c_str()); - GPR_ASSERT(0); - } - return get_socket_response.socket(); - } - - // get the descedent channels/subchannels/sockets of a channel - // push descedent channels/subchannels to queue for layer traverse - // store descedent channels/subchannels/sockets for dumping data - void GetChannelDescedence( - const grpc::channelz::v1::Channel& channel, - std::queue<grpc::channelz::v1::Channel>& channel_queue, - std::queue<grpc::channelz::v1::Subchannel>& subchannel_queue) { - std::cout << " Channel ID" << GetChannelID(channel) << "_" - << GetChannelName(channel) << " descendence - "; - if (channel.channel_ref_size() > 0 || channel.subchannel_ref_size() > 0) { - if (channel.channel_ref_size() > 0) { - std::cout << "channel: "; - for (const auto& _channelref : channel.channel_ref()) { - int64_t ch_id = _channelref.channel_id(); - std::cout << "ID" << ch_id << "_" << _channelref.name() << " "; - grpc::channelz::v1::Channel ch = GetChannelRPC(ch_id); - channel_queue.push(ch); - if (CheckID(ch_id)) { - all_channels_.push_back(ch); - StoreChannelInJson(ch); - } - } - if (channel.subchannel_ref_size() > 0) { - std::cout << ", "; - } - } - if (channel.subchannel_ref_size() > 0) { - std::cout << "subchannel: "; - for (const auto& _subchannelref : channel.subchannel_ref()) { - int64_t subch_id = _subchannelref.subchannel_id(); - std::cout << "ID" << subch_id << "_" << _subchannelref.name() << " "; - grpc::channelz::v1::Subchannel subch = GetSubchannelRPC(subch_id); - subchannel_queue.push(subch); - if (CheckID(subch_id)) { - all_subchannels_.push_back(subch); - StoreSubchannelInJson(subch); - } - } - } - } else if (channel.socket_ref_size() > 0) { - std::cout << "socket: "; - for (const auto& _socketref : channel.socket_ref()) { - int64_t so_id = _socketref.socket_id(); - std::cout << "ID" << so_id << "_" << _socketref.name() << " "; - grpc::channelz::v1::Socket so = GetSocketRPC(so_id); - if (CheckID(so_id)) { - all_sockets_.push_back(so); - StoreSocketInJson(so); - } - } - } - std::cout << std::endl; - } - - // get the descedent channels/subchannels/sockets of a subchannel - // push descedent channels/subchannels to queue for layer traverse - // store descedent channels/subchannels/sockets for dumping data - void GetSubchannelDescedence( - grpc::channelz::v1::Subchannel& subchannel, - std::queue<grpc::channelz::v1::Channel>& channel_queue, - std::queue<grpc::channelz::v1::Subchannel>& subchannel_queue) { - std::cout << " Subchannel ID" << GetSubchannelID(subchannel) << "_" - << GetSubchannelName(subchannel) << " descendence - "; - if (subchannel.channel_ref_size() > 0 || - subchannel.subchannel_ref_size() > 0) { - if (subchannel.channel_ref_size() > 0) { - std::cout << "channel: "; - for (const auto& _channelref : subchannel.channel_ref()) { - int64_t ch_id = _channelref.channel_id(); - std::cout << "ID" << ch_id << "_" << _channelref.name() << " "; - grpc::channelz::v1::Channel ch = GetChannelRPC(ch_id); - channel_queue.push(ch); - if (CheckID(ch_id)) { - all_channels_.push_back(ch); - StoreChannelInJson(ch); - } - } - if (subchannel.subchannel_ref_size() > 0) { - std::cout << ", "; - } - } - if (subchannel.subchannel_ref_size() > 0) { - std::cout << "subchannel: "; - for (const auto& _subchannelref : subchannel.subchannel_ref()) { - int64_t subch_id = _subchannelref.subchannel_id(); - std::cout << "ID" << subch_id << "_" << _subchannelref.name() << " "; - grpc::channelz::v1::Subchannel subch = GetSubchannelRPC(subch_id); - subchannel_queue.push(subch); - if (CheckID(subch_id)) { - all_subchannels_.push_back(subch); - StoreSubchannelInJson(subch); - } - } - } - } else if (subchannel.socket_ref_size() > 0) { - std::cout << "socket: "; - for (const auto& _socketref : subchannel.socket_ref()) { - int64_t so_id = _socketref.socket_id(); - std::cout << "ID" << so_id << "_" << _socketref.name() << " "; - grpc::channelz::v1::Socket so = GetSocketRPC(so_id); - if (CheckID(so_id)) { - all_sockets_.push_back(so); - StoreSocketInJson(so); - } - } - } - std::cout << std::endl; - } - - // Set up the channelz sampler client - // Initialize json as an array - void Setup(const TString& custom_credentials_type, - const TString& server_address) { - json_ = grpc_core::Json::Array(); - rpc_timeout_seconds_ = 20; - grpc::ChannelArguments channel_args; - std::shared_ptr<grpc::ChannelCredentials> channel_creds = - grpc::testing::GetCredentialsProvider()->GetChannelCredentials( - custom_credentials_type, &channel_args); - if (!channel_creds) { - gpr_log(GPR_ERROR, - "Wrong user credential type: %s. Allowed credential types: " - "INSECURE_CREDENTIALS, ssl, alts, google_default_credentials.", - custom_credentials_type.c_str()); - GPR_ASSERT(0); - } - std::shared_ptr<grpc::Channel> channel = - CreateChannel(server_address, channel_creds); - channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel); - } - - // Get all servers, keep querying until getting all - // Store servers for dumping data - // Need to check id repeating for servers - void GetServersRPC() { - int64_t server_start_id = 0; - while (true) { - GetServersRequest get_servers_request; - GetServersResponse get_servers_response; - ClientContext get_servers_context; - get_servers_context.set_deadline( - grpc_timeout_seconds_to_deadline(rpc_timeout_seconds_)); - get_servers_request.set_start_server_id(server_start_id); - Status status = channelz_stub_->GetServers( - &get_servers_context, get_servers_request, &get_servers_response); - if (!status.ok()) { - if (status.error_code() == StatusCode::UNIMPLEMENTED) { - gpr_log(GPR_ERROR, - "Error status UNIMPLEMENTED. Please check and make sure " - "channelz has been registered on the server being queried."); - } else { - gpr_log(GPR_ERROR, - "GetServers RPC with GetServersRequest.server_start_id=%d, " - "failed: %s", - int(server_start_id), - get_servers_context.debug_error_string().c_str()); - } - GPR_ASSERT(0); - } - for (const auto& _server : get_servers_response.server()) { - all_servers_.push_back(_server); - StoreServerInJson(_server); - } - if (!get_servers_response.end()) { - server_start_id = GetServerID(all_servers_.back()) + 1; - } else { - break; - } - } - std::cout << "Number of servers = " << all_servers_.size() << std::endl; - } - - // Get sockets that belongs to servers - // Store sockets for dumping data - void GetSocketsOfServers() { - for (const auto& _server : all_servers_) { - std::cout << "Server ID" << GetServerID(_server) << "_" - << GetServerName(_server) << " listen_socket - "; - for (const auto& _socket : _server.listen_socket()) { - int64_t so_id = _socket.socket_id(); - std::cout << "ID" << so_id << "_" << _socket.name() << " "; - if (CheckID(so_id)) { - grpc::channelz::v1::Socket so = GetSocketRPC(so_id); - all_sockets_.push_back(so); - StoreSocketInJson(so); - } - } - std::cout << std::endl; - } - } - - // Get all top channels, keep querying until getting all - // Store channels for dumping data - // No need to check id repeating for top channels - void GetTopChannelsRPC() { - int64_t channel_start_id = 0; - while (true) { - GetTopChannelsRequest get_top_channels_request; - GetTopChannelsResponse get_top_channels_response; - ClientContext get_top_channels_context; - get_top_channels_context.set_deadline( - grpc_timeout_seconds_to_deadline(rpc_timeout_seconds_)); - get_top_channels_request.set_start_channel_id(channel_start_id); - Status status = channelz_stub_->GetTopChannels( - &get_top_channels_context, get_top_channels_request, - &get_top_channels_response); - if (!status.ok()) { - gpr_log(GPR_ERROR, - "GetTopChannels RPC with " - "GetTopChannelsRequest.channel_start_id=%d failed: %s", - int(channel_start_id), - get_top_channels_context.debug_error_string().c_str()); - GPR_ASSERT(0); - } - for (const auto& _topchannel : get_top_channels_response.channel()) { - top_channels_.push_back(_topchannel); - all_channels_.push_back(_topchannel); - StoreChannelInJson(_topchannel); - } - if (!get_top_channels_response.end()) { - channel_start_id = GetChannelID(top_channels_.back()) + 1; - } else { - break; - } - } - std::cout << std::endl - << "Number of top channels = " << top_channels_.size() - << std::endl; - } - - // layer traverse for each top channel - void TraverseTopChannels() { - for (const auto& _topchannel : top_channels_) { - int tree_depth = 0; - std::queue<grpc::channelz::v1::Channel> channel_queue; - std::queue<grpc::channelz::v1::Subchannel> subchannel_queue; - std::cout << "Tree depth = " << tree_depth << std::endl; - GetChannelDescedence(_topchannel, channel_queue, subchannel_queue); - while (!channel_queue.empty() || !subchannel_queue.empty()) { - ++tree_depth; - std::cout << "Tree depth = " << tree_depth << std::endl; - int ch_q_size = channel_queue.size(); - int subch_q_size = subchannel_queue.size(); - for (int i = 0; i < ch_q_size; ++i) { - grpc::channelz::v1::Channel ch = channel_queue.front(); - channel_queue.pop(); - GetChannelDescedence(ch, channel_queue, subchannel_queue); - } - for (int i = 0; i < subch_q_size; ++i) { - grpc::channelz::v1::Subchannel subch = subchannel_queue.front(); - subchannel_queue.pop(); - GetSubchannelDescedence(subch, channel_queue, subchannel_queue); - } - } - std::cout << std::endl; - } - } - - // dump data of all entities to stdout - void DumpStdout() { - TString data_str; - for (const auto& _channel : all_channels_) { - std::cout << "channel ID" << GetChannelID(_channel) << "_" - << GetChannelName(_channel) << " data:" << std::endl; - // TODO(mohanli): TextFormat::PrintToString records time as seconds and - // nanos. Need a more human readable way. - ::google::protobuf::TextFormat::PrintToString(_channel.data(), &data_str); - printf("%s\n", data_str.c_str()); - } - for (const auto& _subchannel : all_subchannels_) { - std::cout << "subchannel ID" << GetSubchannelID(_subchannel) << "_" - << GetSubchannelName(_subchannel) << " data:" << std::endl; - ::google::protobuf::TextFormat::PrintToString(_subchannel.data(), - &data_str); - printf("%s\n", data_str.c_str()); - } - for (const auto& _server : all_servers_) { - std::cout << "server ID" << GetServerID(_server) << "_" - << GetServerName(_server) << " data:" << std::endl; - ::google::protobuf::TextFormat::PrintToString(_server.data(), &data_str); - printf("%s\n", data_str.c_str()); - } - for (const auto& _socket : all_sockets_) { - std::cout << "socket ID" << GetSocketID(_socket) << "_" - << GetSocketName(_socket) << " data:" << std::endl; - ::google::protobuf::TextFormat::PrintToString(_socket.data(), &data_str); - printf("%s\n", data_str.c_str()); - } - } - - // Store a channel in Json - void StoreChannelInJson(const grpc::channelz::v1::Channel& channel) { - TString id = grpc::to_string(GetChannelID(channel)); - TString type = "Channel"; - TString description; - ::google::protobuf::TextFormat::PrintToString(channel.data(), &description); - grpc_core::Json description_json = grpc_core::Json(description); - StoreEntityInJson(id, type, description_json); - } - - // Store a subchannel in Json - void StoreSubchannelInJson(const grpc::channelz::v1::Subchannel& subchannel) { - TString id = grpc::to_string(GetSubchannelID(subchannel)); - TString type = "Subchannel"; - TString description; - ::google::protobuf::TextFormat::PrintToString(subchannel.data(), - &description); - grpc_core::Json description_json = grpc_core::Json(description); - StoreEntityInJson(id, type, description_json); - } - - // Store a server in Json - void StoreServerInJson(const grpc::channelz::v1::Server& server) { - TString id = grpc::to_string(GetServerID(server)); - TString type = "Server"; - TString description; - ::google::protobuf::TextFormat::PrintToString(server.data(), &description); - grpc_core::Json description_json = grpc_core::Json(description); - StoreEntityInJson(id, type, description_json); - } - - // Store a socket in Json - void StoreSocketInJson(const grpc::channelz::v1::Socket& socket) { - TString id = grpc::to_string(GetSocketID(socket)); - TString type = "Socket"; - TString description; - ::google::protobuf::TextFormat::PrintToString(socket.data(), &description); - grpc_core::Json description_json = grpc_core::Json(description); - StoreEntityInJson(id, type, description_json); - } - - // Store an entity in Json - void StoreEntityInJson(TString& id, TString& type, - const grpc_core::Json& description) { - TString start, finish; - gpr_timespec ago = gpr_time_sub( - now_, - gpr_time_from_seconds(y_absl::GetFlag(FLAGS_sampling_interval_seconds), - GPR_TIMESPAN)); - std::stringstream ss; - const time_t time_now = now_.tv_sec; - ss << std::put_time(std::localtime(&time_now), "%F %T"); - finish = ss.str(); // example: "2019-02-01 12:12:18" - ss.str(""); - const time_t time_ago = ago.tv_sec; - ss << std::put_time(std::localtime(&time_ago), "%F %T"); - start = ss.str(); - grpc_core::Json obj = - grpc_core::Json::Object{{"Task", y_absl::StrFormat("%s_ID%s", type, id)}, - {"Start", start}, - {"Finish", finish}, - {"ID", id}, - {"Type", type}, - {"Description", description}}; - json_.mutable_array()->push_back(obj); - } - - // Dump data in json - TString DumpJson() { return json_.Dump(); } - - // Check if one entity has been recorded - bool CheckID(int64_t id) { - if (id_set_.count(id) == 0) { - id_set_.insert(id); - return true; - } else { - return false; - } - } - - // Record current time - void RecordNow() { now_ = gpr_now(GPR_CLOCK_REALTIME); } - - private: - std::unique_ptr<grpc::channelz::v1::Channelz::Stub> channelz_stub_; - std::vector<grpc::channelz::v1::Channel> top_channels_; - std::vector<grpc::channelz::v1::Server> all_servers_; - std::vector<grpc::channelz::v1::Channel> all_channels_; - std::vector<grpc::channelz::v1::Subchannel> all_subchannels_; - std::vector<grpc::channelz::v1::Socket> all_sockets_; - std::unordered_set<int64_t> id_set_; - grpc_core::Json json_; - int64_t rpc_timeout_seconds_; - gpr_timespec now_; -}; - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - grpc::testing::InitTest(&argc, &argv, true); - std::ofstream output_file(y_absl::GetFlag(FLAGS_output_json)); - for (int i = 0; i < y_absl::GetFlag(FLAGS_sampling_times); ++i) { - ChannelzSampler channelz_sampler; - channelz_sampler.Setup(y_absl::GetFlag(FLAGS_custom_credentials_type), - y_absl::GetFlag(FLAGS_server_address)); - std::cout << "Wait for sampling interval " - << y_absl::GetFlag(FLAGS_sampling_interval_seconds) << "s..." - << std::endl; - const gpr_timespec kDelay = gpr_time_add( - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(y_absl::GetFlag(FLAGS_sampling_interval_seconds), - GPR_TIMESPAN)); - gpr_sleep_until(kDelay); - std::cout << "##### " << i << "th sampling #####" << std::endl; - channelz_sampler.RecordNow(); - channelz_sampler.GetServersRPC(); - channelz_sampler.GetSocketsOfServers(); - channelz_sampler.GetTopChannelsRPC(); - channelz_sampler.TraverseTopChannels(); - channelz_sampler.DumpStdout(); - if (!y_absl::GetFlag(FLAGS_output_json).empty()) { - output_file << channelz_sampler.DumpJson() << "\n" << std::flush; - } - } - output_file.close(); - return 0; -} diff --git a/contrib/libs/grpc/test/cpp/util/channelz_sampler_test.cc b/contrib/libs/grpc/test/cpp/util/channelz_sampler_test.cc deleted file mode 100644 index 6d9f05e95c..0000000000 --- a/contrib/libs/grpc/test/cpp/util/channelz_sampler_test.cc +++ /dev/null @@ -1,179 +0,0 @@ -/* - * - * Copyright 2016 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 <grpc/support/port_platform.h> - -#include <stdlib.h> -#include <unistd.h> - -#include <cstdlib> -#include <iostream> -#include <memory> -#include <util/generic/string.h> -#include <thread> - -#include "gtest/gtest.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/ext/channelz_service_plugin.h> -#include <grpcpp/grpcpp.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/env.h" -#include "src/cpp/server/channelz/channelz_service.h" -#include "src/proto/grpc/testing/test.grpc.pb.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/subprocess.h" -#include "test/cpp/util/test_credentials_provider.h" - -static TString g_root; - -namespace { -using grpc::ClientContext; -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::Status; -} // namespace - -// Test variables -TString server_address("0.0.0.0:10000"); -TString custom_credentials_type("INSECURE_CREDENTIALS"); -TString sampling_times = "2"; -TString sampling_interval_seconds = "3"; -TString output_json("output.json"); - -// Creata an echo server -class EchoServerImpl final : public grpc::testing::TestService::Service { - Status EmptyCall(::grpc::ServerContext* /*context*/, - const grpc::testing::Empty* /*request*/, - grpc::testing::Empty* /*response*/) override { - return Status::OK; - } -}; - -// Run client in a thread -void RunClient(const TString& client_id, gpr_event* done_ev) { - grpc::ChannelArguments channel_args; - std::shared_ptr<grpc::ChannelCredentials> channel_creds = - grpc::testing::GetCredentialsProvider()->GetChannelCredentials( - custom_credentials_type, &channel_args); - std::unique_ptr<grpc::testing::TestService::Stub> stub = - grpc::testing::TestService::NewStub( - grpc::CreateChannel(server_address, channel_creds)); - gpr_log(GPR_INFO, "Client %s is echoing!", client_id.c_str()); - while (true) { - if (gpr_event_wait(done_ev, grpc_timeout_seconds_to_deadline(1)) != - nullptr) { - return; - } - grpc::testing::Empty request; - grpc::testing::Empty response; - ClientContext context; - Status status = stub->EmptyCall(&context, request, &response); - if (!status.ok()) { - gpr_log(GPR_ERROR, "Client echo failed."); - GPR_ASSERT(0); - } - } -} - -// Create the channelz to test the connection to the server -bool WaitForConnection(int wait_server_seconds) { - grpc::ChannelArguments channel_args; - std::shared_ptr<grpc::ChannelCredentials> channel_creds = - grpc::testing::GetCredentialsProvider()->GetChannelCredentials( - custom_credentials_type, &channel_args); - auto channel = grpc::CreateChannel(server_address, channel_creds); - return channel->WaitForConnected( - grpc_timeout_seconds_to_deadline(wait_server_seconds)); -} - -// Test the channelz sampler -TEST(ChannelzSamplerTest, SimpleTest) { - // start server - ::grpc::channelz::experimental::InitChannelzService(); - EchoServerImpl service; - grpc::ServerBuilder builder; - auto server_creds = - grpc::testing::GetCredentialsProvider()->GetServerCredentials( - custom_credentials_type); - builder.AddListeningPort(server_address, server_creds); - builder.RegisterService(&service); - std::unique_ptr<Server> server(builder.BuildAndStart()); - gpr_log(GPR_INFO, "Server listening on %s", server_address.c_str()); - const int kWaitForServerSeconds = 10; - ASSERT_TRUE(WaitForConnection(kWaitForServerSeconds)); - // client threads - gpr_event done_ev1, done_ev2; - gpr_event_init(&done_ev1); - gpr_event_init(&done_ev2); - std::thread client_thread_1(RunClient, "1", &done_ev1); - std::thread client_thread_2(RunClient, "2", &done_ev2); - // Run the channelz sampler - grpc::SubProcess* test_driver = new grpc::SubProcess( - {g_root + "/channelz_sampler", "--server_address=" + server_address, - "--custom_credentials_type=" + custom_credentials_type, - "--sampling_times=" + sampling_times, - "--sampling_interval_seconds=" + sampling_interval_seconds, - "--output_json=" + output_json}); - int status = test_driver->Join(); - if (WIFEXITED(status)) { - if (WEXITSTATUS(status)) { - gpr_log(GPR_ERROR, - "Channelz sampler test test-runner exited with code %d", - WEXITSTATUS(status)); - GPR_ASSERT(0); // log the line number of the assertion failure - } - } else if (WIFSIGNALED(status)) { - gpr_log(GPR_ERROR, "Channelz sampler test test-runner ended from signal %d", - WTERMSIG(status)); - GPR_ASSERT(0); - } else { - gpr_log(GPR_ERROR, - "Channelz sampler test test-runner ended with unknown status %d", - status); - GPR_ASSERT(0); - } - delete test_driver; - gpr_event_set(&done_ev1, reinterpret_cast<void*>(1)); - gpr_event_set(&done_ev2, reinterpret_cast<void*>(1)); - client_thread_1.join(); - client_thread_2.join(); -} - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - TString me = argv[0]; - auto lslash = me.rfind('/'); - if (lslash != TString::npos) { - g_root = me.substr(0, lslash); - } else { - g_root = "."; - } - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/util/cli_call_test.cc b/contrib/libs/grpc/test/cpp/util/cli_call_test.cc deleted file mode 100644 index 4064899e0c..0000000000 --- a/contrib/libs/grpc/test/cpp/util/cli_call_test.cc +++ /dev/null @@ -1,129 +0,0 @@ -/* - * - * Copyright 2015 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 "test/cpp/util/cli_call.h" - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/string_ref_helper.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { - -class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - response->set_message(request->message()); - return Status::OK; - } -}; - -class CliCallTest : public ::testing::Test { - protected: - CliCallTest() {} - - void SetUp() override { - int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; - // Setup server - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - void TearDown() override { server_->Shutdown(); } - - void ResetStub() { - channel_ = grpc::CreateChannel(server_address_.str(), - InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - TestServiceImpl service_; -}; - -// Send a rpc with a normal stub and then a CliCall. Verify they match. -TEST_F(CliCallTest, SimpleRpc) { - ResetStub(); - // Normal stub. - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - context.AddMetadata("key1", "val1"); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - - const TString kMethod("/grpc.testing.EchoTestService/Echo"); - TString request_bin, response_bin, expected_response_bin; - EXPECT_TRUE(request.SerializeToString(&request_bin)); - EXPECT_TRUE(response.SerializeToString(&expected_response_bin)); - std::multimap<TString, TString> client_metadata; - std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata, - server_trailing_metadata; - client_metadata.insert(std::pair<TString, TString>("key1", "val1")); - CliCall call(channel_, kMethod, client_metadata); - Status s2 = call.Call(request_bin, &response_bin, &server_initial_metadata, - &server_trailing_metadata); - EXPECT_TRUE(s2.ok()); - - EXPECT_EQ(expected_response_bin, response_bin); - EXPECT_EQ(context.GetServerInitialMetadata(), server_initial_metadata); - EXPECT_EQ(context.GetServerTrailingMetadata(), server_trailing_metadata); -} - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/util/create_test_channel.cc b/contrib/libs/grpc/test/cpp/util/create_test_channel.cc deleted file mode 100644 index be13bb4e55..0000000000 --- a/contrib/libs/grpc/test/cpp/util/create_test_channel.cc +++ /dev/null @@ -1,252 +0,0 @@ -/* - * - * Copyright 2015-2016 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 "test/cpp/util/create_test_channel.h" - -#include "y_absl/flags/flag.h" - -#include <grpc/support/log.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/security/credentials.h> - -#include "test/cpp/util/test_credentials_provider.h" - -Y_ABSL_FLAG(TString, grpc_test_use_grpclb_with_child_policy, "", - "If non-empty, set a static service config on channels created by " - "grpc::CreateTestChannel, that configures the grpclb LB policy " - "with a child policy being the value of this flag (e.g. round_robin " - "or pick_first)."); - -namespace grpc { - -namespace { - -const char kProdTlsCredentialsType[] = "prod_ssl"; - -class SslCredentialProvider : public testing::CredentialTypeProvider { - public: - std::shared_ptr<ChannelCredentials> GetChannelCredentials( - grpc::ChannelArguments* /*args*/) override { - return grpc::SslCredentials(SslCredentialsOptions()); - } - std::shared_ptr<ServerCredentials> GetServerCredentials() override { - return nullptr; - } -}; - -gpr_once g_once_init_add_prod_ssl_provider = GPR_ONCE_INIT; -// Register ssl with non-test roots type to the credentials provider. -void AddProdSslType() { - testing::GetCredentialsProvider()->AddSecureType( - kProdTlsCredentialsType, std::unique_ptr<testing::CredentialTypeProvider>( - new SslCredentialProvider)); -} - -void MaybeSetCustomChannelArgs(grpc::ChannelArguments* args) { - if (!y_absl::GetFlag(FLAGS_grpc_test_use_grpclb_with_child_policy).empty()) { - args->SetString( - "grpc.service_config", - "{\"loadBalancingConfig\":[{\"grpclb\":{\"childPolicy\":[{" - "\"" + - y_absl::GetFlag(FLAGS_grpc_test_use_grpclb_with_child_policy) + - "\":{}}]}}]}"); - } -} - -} // namespace - -// When cred_type is 'ssl', if server is empty, override_hostname is used to -// create channel. Otherwise, connect to server and override hostname if -// override_hostname is provided. -// When cred_type is not 'ssl', override_hostname is ignored. -// Set use_prod_root to true to use the SSL root for connecting to google. -// In this case, path to the roots pem file must be set via environment variable -// GRPC_DEFAULT_SSL_ROOTS_FILE_PATH. -// Otherwise, root for test SSL cert will be used. -// creds will be used to create a channel when cred_type is 'ssl'. -// Use examples: -// CreateTestChannel( -// "1.1.1.1:12345", "ssl", "override.hostname.com", false, creds); -// CreateTestChannel("test.google.com:443", "ssl", "", true, creds); -// same as above -// CreateTestChannel("", "ssl", "test.google.com:443", true, creds); -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& cred_type, - const TString& override_hostname, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - const ChannelArguments& args) { - return CreateTestChannel(server, cred_type, override_hostname, use_prod_roots, - creds, args, - /*interceptor_creators=*/{}); -} - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - const ChannelArguments& args) { - return CreateTestChannel(server, override_hostname, security_type, - use_prod_roots, creds, args, - /*interceptor_creators=*/{}); -} - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds) { - return CreateTestChannel(server, override_hostname, security_type, - use_prod_roots, creds, ChannelArguments()); -} - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots) { - return CreateTestChannel(server, override_hostname, security_type, - use_prod_roots, std::shared_ptr<CallCredentials>()); -} - -// Shortcut for end2end and interop tests. -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, testing::transport_security security_type) { - return CreateTestChannel(server, "foo.test.google.fr", security_type, false); -} - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& credential_type, - const std::shared_ptr<CallCredentials>& creds) { - ChannelArguments channel_args; - MaybeSetCustomChannelArgs(&channel_args); - std::shared_ptr<ChannelCredentials> channel_creds = - testing::GetCredentialsProvider()->GetChannelCredentials(credential_type, - &channel_args); - GPR_ASSERT(channel_creds != nullptr); - if (creds.get()) { - channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); - } - return ::grpc::CreateCustomChannel(server, channel_creds, channel_args); -} - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& cred_type, - const TString& override_hostname, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, const ChannelArguments& args, - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators) { - ChannelArguments channel_args(args); - MaybeSetCustomChannelArgs(&channel_args); - std::shared_ptr<ChannelCredentials> channel_creds; - if (cred_type.empty()) { - if (interceptor_creators.empty()) { - return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), - channel_args); - } else { - return experimental::CreateCustomChannelWithInterceptors( - server, InsecureChannelCredentials(), channel_args, - std::move(interceptor_creators)); - } - } else if (cred_type == testing::kTlsCredentialsType) { // cred_type == "ssl" - if (use_prod_roots) { - gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType); - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - kProdTlsCredentialsType, &channel_args); - if (!server.empty() && !override_hostname.empty()) { - channel_args.SetSslTargetNameOverride(override_hostname); - } - } else { - // override_hostname is discarded as the provider handles it. - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - testing::kTlsCredentialsType, &channel_args); - } - GPR_ASSERT(channel_creds != nullptr); - - const TString& connect_to = server.empty() ? override_hostname : server; - if (creds.get()) { - channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); - } - if (interceptor_creators.empty()) { - return ::grpc::CreateCustomChannel(connect_to, channel_creds, - channel_args); - } else { - return experimental::CreateCustomChannelWithInterceptors( - connect_to, channel_creds, channel_args, - std::move(interceptor_creators)); - } - } else { - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - cred_type, &channel_args); - GPR_ASSERT(channel_creds != nullptr); - - if (interceptor_creators.empty()) { - return ::grpc::CreateCustomChannel(server, channel_creds, channel_args); - } else { - return experimental::CreateCustomChannelWithInterceptors( - server, channel_creds, channel_args, std::move(interceptor_creators)); - } - } -} - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, const ChannelArguments& args, - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators) { - TString credential_type = - security_type == testing::ALTS - ? testing::kAltsCredentialsType - : (security_type == testing::TLS ? testing::kTlsCredentialsType - : testing::kInsecureCredentialsType); - return CreateTestChannel(server, credential_type, override_hostname, - use_prod_roots, creds, args, - std::move(interceptor_creators)); -} - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators) { - return CreateTestChannel(server, override_hostname, security_type, - use_prod_roots, creds, ChannelArguments(), - std::move(interceptor_creators)); -} - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& credential_type, - const std::shared_ptr<CallCredentials>& creds, - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators) { - ChannelArguments channel_args; - MaybeSetCustomChannelArgs(&channel_args); - std::shared_ptr<ChannelCredentials> channel_creds = - testing::GetCredentialsProvider()->GetChannelCredentials(credential_type, - &channel_args); - GPR_ASSERT(channel_creds != nullptr); - if (creds.get()) { - channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); - } - return experimental::CreateCustomChannelWithInterceptors( - server, channel_creds, channel_args, std::move(interceptor_creators)); -} - -} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/create_test_channel.h b/contrib/libs/grpc/test/cpp/util/create_test_channel.h deleted file mode 100644 index ed4ce6c11b..0000000000 --- a/contrib/libs/grpc/test/cpp/util/create_test_channel.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * Copyright 2015-2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H -#define GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H - -#include <memory> - -#include <grpcpp/channel.h> -#include <grpcpp/impl/codegen/client_interceptor.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/support/channel_arguments.h> - -namespace grpc { -class Channel; - -namespace testing { - -typedef enum { INSECURE = 0, TLS, ALTS } transport_security; - -} // namespace testing - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, testing::transport_security security_type); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - const ChannelArguments& args); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& cred_type, - const TString& override_hostname, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - const ChannelArguments& args); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& credential_type, - const std::shared_ptr<CallCredentials>& creds); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, const ChannelArguments& args, - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& cred_type, - const TString& override_hostname, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, const ChannelArguments& args, - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators); - -std::shared_ptr<Channel> CreateTestChannel( - const TString& server, const TString& credential_type, - const std::shared_ptr<CallCredentials>& creds, - std::vector< - std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> - interceptor_creators); - -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H diff --git a/contrib/libs/grpc/test/cpp/util/error_details_test.cc b/contrib/libs/grpc/test/cpp/util/error_details_test.cc deleted file mode 100644 index 9ce827038d..0000000000 --- a/contrib/libs/grpc/test/cpp/util/error_details_test.cc +++ /dev/null @@ -1,126 +0,0 @@ -/* - * - * Copyright 2017 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 <gtest/gtest.h> - -#include <grpcpp/support/error_details.h> - -#include "src/proto/grpc/status/status.pb.h" -#include "src/proto/grpc/testing/echo_messages.pb.h" -#include "test/core/util/test_config.h" - -namespace grpc { -namespace { - -TEST(ExtractTest, Success) { - google::rpc::Status expected; - expected.set_code(13); // INTERNAL - expected.set_message("I am an error message"); - testing::EchoRequest expected_details; - expected_details.set_message(TString(100, '\0')); - expected.add_details()->PackFrom(expected_details); - - google::rpc::Status to; - TString error_details = expected.SerializeAsString(); - Status from(static_cast<StatusCode>(expected.code()), expected.message(), - error_details); - EXPECT_TRUE(ExtractErrorDetails(from, &to).ok()); - EXPECT_EQ(expected.code(), to.code()); - EXPECT_EQ(expected.message(), to.message()); - EXPECT_EQ(1, to.details_size()); - testing::EchoRequest details; - to.details(0).UnpackTo(&details); - EXPECT_EQ(expected_details.message(), details.message()); -} - -TEST(ExtractTest, NullInput) { - EXPECT_EQ(StatusCode::FAILED_PRECONDITION, - ExtractErrorDetails(Status(), nullptr).error_code()); -} - -TEST(ExtractTest, Unparsable) { - TString error_details("I am not a status object"); - Status from(StatusCode::INTERNAL, "", error_details); - google::rpc::Status to; - EXPECT_EQ(StatusCode::INVALID_ARGUMENT, - ExtractErrorDetails(from, &to).error_code()); -} - -TEST(SetTest, Success) { - google::rpc::Status expected; - expected.set_code(13); // INTERNAL - expected.set_message("I am an error message"); - testing::EchoRequest expected_details; - expected_details.set_message(TString(100, '\0')); - expected.add_details()->PackFrom(expected_details); - - Status to; - Status s = SetErrorDetails(expected, &to); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(expected.code(), to.error_code()); - EXPECT_EQ(expected.message(), to.error_message()); - EXPECT_EQ(expected.SerializeAsString(), to.error_details()); -} - -TEST(SetTest, NullInput) { - EXPECT_EQ(StatusCode::FAILED_PRECONDITION, - SetErrorDetails(google::rpc::Status(), nullptr).error_code()); -} - -TEST(SetTest, OutOfScopeErrorCode) { - google::rpc::Status expected; - expected.set_code(17); // Out of scope (UNAUTHENTICATED is 16). - expected.set_message("I am an error message"); - testing::EchoRequest expected_details; - expected_details.set_message(TString(100, '\0')); - expected.add_details()->PackFrom(expected_details); - - Status to; - Status s = SetErrorDetails(expected, &to); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(StatusCode::UNKNOWN, to.error_code()); - EXPECT_EQ(expected.message(), to.error_message()); - EXPECT_EQ(expected.SerializeAsString(), to.error_details()); -} - -TEST(SetTest, ValidScopeErrorCode) { - for (int c = StatusCode::OK; c <= StatusCode::UNAUTHENTICATED; c++) { - google::rpc::Status expected; - expected.set_code(c); - expected.set_message("I am an error message"); - testing::EchoRequest expected_details; - expected_details.set_message(TString(100, '\0')); - expected.add_details()->PackFrom(expected_details); - - Status to; - Status s = SetErrorDetails(expected, &to); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(c, to.error_code()); - EXPECT_EQ(expected.message(), to.error_message()); - EXPECT_EQ(expected.SerializeAsString(), to.error_details()); - } -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/util/grpc_cli.cc b/contrib/libs/grpc/test/cpp/util/grpc_cli.cc deleted file mode 100644 index 9b587901bc..0000000000 --- a/contrib/libs/grpc/test/cpp/util/grpc_cli.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - - * Copyright 2015 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. - * - */ - -/* - A command line tool to talk to a grpc server. - Run `grpc_cli help` command to see its usage information. - - Example of talking to grpc interop server: - grpc_cli call localhost:50051 UnaryCall "response_size:10" \ - --protofiles=src/proto/grpc/testing/test.proto \ - --channel_creds_type=insecure - - Options: - 1. --protofiles, use this flag to provide proto files if the server does - does not have the reflection service. - 2. --proto_path, if your proto file is not under current working directory, - use this flag to provide a search root. It should work similar to the - counterpart in protoc. This option is valid only when protofiles is - provided. - 3. --metadata specifies metadata to be sent to the server, such as: - --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2" - 4. --channel_creds_type, whether to use tls, insecure or platform-specific - options. - 5. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call - 6. --infile, input filename (defaults to stdin) - 7. --outfile, output filename (defaults to stdout) - 8. --binary_input, use the serialized request as input. The serialized - request can be generated by calling something like: - protoc --proto_path=src/proto/grpc/testing/ \ - --encode=grpc.testing.SimpleRequest \ - src/proto/grpc/testing/messages.proto \ - < input.txt > input.bin - If this is used and no proto file is provided in the argument list, the - method string has to be exact in the form of /package.service/method. - 9. --binary_output, use binary format response as output, it can - be later decoded using protoc: - protoc --proto_path=src/proto/grpc/testing/ \ - --decode=grpc.testing.SimpleResponse \ - src/proto/grpc/testing/messages.proto \ - < output.bin > output.txt - 10. --default_service_config, optional default service config to use - on the channel. Note that this may be ignored if the name resolver - returns a service config. - 11. --display_peer_address, on CallMethod commands, log the peer socket - address of the connection that each RPC is made on to stderr. -*/ - -#include <fstream> -#include <functional> -#include <iostream> - -#include "y_absl/flags/flag.h" - -#include <grpcpp/support/config.h> - -#include "test/cpp/util/cli_credentials.h" -#include "test/cpp/util/grpc_tool.h" -#include "test/cpp/util/test_config.h" - -Y_ABSL_FLAG(TString, outfile, "", "Output file (default is stdout)"); - -static bool SimplePrint(const TString& outfile, const TString& output) { - if (outfile.empty()) { - std::cout << output << std::flush; - } else { - std::ofstream output_file(outfile, std::ios::app | std::ios::binary); - output_file << output << std::flush; - output_file.close(); - } - return true; -} - -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); - - return grpc::testing::GrpcToolMainLib( - argc, const_cast<const char**>(argv), grpc::testing::CliCredentials(), - std::bind(SimplePrint, y_absl::GetFlag(FLAGS_outfile), - std::placeholders::_1)); -} diff --git a/contrib/libs/grpc/test/cpp/util/grpc_tool_test.cc b/contrib/libs/grpc/test/cpp/util/grpc_tool_test.cc deleted file mode 100644 index e2798b8a2b..0000000000 --- a/contrib/libs/grpc/test/cpp/util/grpc_tool_test.cc +++ /dev/null @@ -1,1354 +0,0 @@ -/* - * - * Copyright 2016 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 "test/cpp/util/grpc_tool.h" - -#include <chrono> -#include <sstream> - -#include <gtest/gtest.h> - -#include "y_absl/flags/declare.h" -#include "y_absl/flags/flag.h" - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/ext/proto_server_reflection_plugin.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/load_file.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "src/proto/grpc/testing/echo.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/cli_credentials.h" -#include "test/cpp/util/string_ref_helper.h" -#include "test/cpp/util/test_config.h" - -#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem" -#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem" -#define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -#define USAGE_REGEX "( grpc_cli .+\n){2,10}" - -#define ECHO_TEST_SERVICE_SUMMARY \ - "Echo\n" \ - "Echo1\n" \ - "Echo2\n" \ - "CheckDeadlineUpperBound\n" \ - "CheckDeadlineSet\n" \ - "CheckClientInitialMetadata\n" \ - "RequestStream\n" \ - "ResponseStream\n" \ - "BidiStream\n" \ - "Unimplemented\n" \ - "UnimplementedBidi\n" - -#define ECHO_TEST_SERVICE_DESCRIPTION \ - "filename: src/proto/grpc/testing/echo.proto\n" \ - "package: grpc.testing;\n" \ - "service EchoTestService {\n" \ - " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ - "{}\n" \ - " rpc Echo1(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ - "{}\n" \ - " rpc Echo2(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ - "{}\n" \ - " rpc CheckDeadlineUpperBound(grpc.testing.SimpleRequest) returns " \ - "(grpc.testing.StringValue) {}\n" \ - " rpc CheckDeadlineSet(grpc.testing.SimpleRequest) returns " \ - "(grpc.testing.StringValue) {}\n" \ - " rpc CheckClientInitialMetadata(grpc.testing.SimpleRequest) returns " \ - "(grpc.testing.SimpleResponse) {}\n" \ - " rpc RequestStream(stream grpc.testing.EchoRequest) returns " \ - "(grpc.testing.EchoResponse) {}\n" \ - " rpc ResponseStream(grpc.testing.EchoRequest) returns (stream " \ - "grpc.testing.EchoResponse) {}\n" \ - " rpc BidiStream(stream grpc.testing.EchoRequest) returns (stream " \ - "grpc.testing.EchoResponse) {}\n" \ - " rpc Unimplemented(grpc.testing.EchoRequest) returns " \ - "(grpc.testing.EchoResponse) {}\n" \ - " rpc UnimplementedBidi(stream grpc.testing.EchoRequest) returns (stream " \ - "grpc.testing.EchoResponse) {}\n" \ - "}\n" \ - "\n" - -#define ECHO_METHOD_DESCRIPTION \ - " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ - "{}\n" - -#define ECHO_RESPONSE_MESSAGE_TEXT_FORMAT \ - "message: \"echo\"\n" \ - "param {\n" \ - " host: \"localhost\"\n" \ - " peer: \"peer\"\n" \ - "}\n\n" - -#define ECHO_RESPONSE_MESSAGE_JSON_FORMAT \ - "{\n" \ - " \"message\": \"echo\",\n" \ - " \"param\": {\n" \ - " \"host\": \"localhost\",\n" \ - " \"peer\": \"peer\"\n" \ - " }\n" \ - "}\n\n" - -Y_ABSL_DECLARE_FLAG(TString, channel_creds_type); -Y_ABSL_DECLARE_FLAG(TString, ssl_target); -Y_ABSL_DECLARE_FLAG(bool, binary_input); -Y_ABSL_DECLARE_FLAG(bool, binary_output); -Y_ABSL_DECLARE_FLAG(bool, json_input); -Y_ABSL_DECLARE_FLAG(bool, json_output); -Y_ABSL_DECLARE_FLAG(bool, l); -Y_ABSL_DECLARE_FLAG(bool, batch); -Y_ABSL_DECLARE_FLAG(TString, metadata); -Y_ABSL_DECLARE_FLAG(TString, protofiles); -Y_ABSL_DECLARE_FLAG(TString, proto_path); -Y_ABSL_DECLARE_FLAG(TString, default_service_config); -Y_ABSL_DECLARE_FLAG(double, timeout); - -namespace grpc { -namespace testing { -namespace { - -const int kServerDefaultResponseStreamsToSend = 3; - -class TestCliCredentials final : public grpc::testing::CliCredentials { - public: - explicit TestCliCredentials(bool secure = false) : secure_(secure) {} - std::shared_ptr<grpc::ChannelCredentials> GetChannelCredentials() - const override { - if (!secure_) { - return InsecureChannelCredentials(); - } - grpc_slice ca_slice; - GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(CA_CERT_PATH, 1, &ca_slice))); - const char* test_root_cert = - reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice); - SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; - std::shared_ptr<grpc::ChannelCredentials> credential_ptr = - grpc::SslCredentials(grpc::SslCredentialsOptions(ssl_opts)); - grpc_slice_unref(ca_slice); - return credential_ptr; - } - TString GetCredentialUsage() const override { return ""; } - - private: - const bool secure_; -}; - -bool PrintStream(std::stringstream* ss, const TString& output) { - (*ss) << output; - return true; -} - -template <typename T> -size_t ArraySize(T& a) { - return ((sizeof(a) / sizeof(*(a))) / - static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); -} - -class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - response->set_message(request->message()); - return Status::OK; - } - - Status CheckDeadlineSet(ServerContext* context, - const SimpleRequest* /*request*/, - StringValue* response) override { - response->set_message(context->deadline() != - std::chrono::system_clock::time_point::max() - ? "true" - : "false"); - return Status::OK; - } - - // Check if deadline - current time <= timeout - // If deadline set, timeout + current time should be an upper bound for it - Status CheckDeadlineUpperBound(ServerContext* context, - const SimpleRequest* /*request*/, - StringValue* response) override { - auto seconds = std::chrono::duration_cast<std::chrono::seconds>( - context->deadline() - std::chrono::system_clock::now()); - - // Returning string instead of bool to avoid using embedded messages in - // proto3 - response->set_message( - seconds.count() <= y_absl::GetFlag(FLAGS_timeout) ? "true" : "false"); - return Status::OK; - } - - Status RequestStream(ServerContext* context, - ServerReader<EchoRequest>* reader, - EchoResponse* response) override { - EchoRequest request; - response->set_message(""); - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - while (reader->Read(&request)) { - response->mutable_message()->append(request.message()); - } - - return Status::OK; - } - - Status ResponseStream(ServerContext* context, const EchoRequest* request, - ServerWriter<EchoResponse>* writer) override { - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - - EchoResponse response; - for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { - response.set_message(request->message() + ToString(i)); - writer->Write(response); - } - - return Status::OK; - } - - Status BidiStream( - ServerContext* context, - ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { - EchoRequest request; - EchoResponse response; - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - - while (stream->Read(&request)) { - response.set_message(request.message()); - stream->Write(response); - } - - return Status::OK; - } -}; - -} // namespace - -class GrpcToolTest : public ::testing::Test { - protected: - GrpcToolTest() {} - - // SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die() - // uses atexit() to free chosen ports, and it will spawn a new thread in - // resolve_address_posix.c:192 at exit time. - TString SetUpServer(bool secure = false) { - std::ostringstream server_address; - int port = grpc_pick_unused_port_or_die(); - server_address << "localhost:" << port; - // Setup server - ServerBuilder builder; - std::shared_ptr<grpc::ServerCredentials> creds; - grpc_slice cert_slice, key_slice; - GPR_ASSERT(GRPC_LOG_IF_ERROR( - "load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice))); - GPR_ASSERT(GRPC_LOG_IF_ERROR( - "load_file", grpc_load_file(SERVER_KEY_PATH, 1, &key_slice))); - const char* server_cert = - reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); - const char* server_key = - reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice); - SslServerCredentialsOptions::PemKeyCertPair pkcp = {server_key, - server_cert}; - if (secure) { - SslServerCredentialsOptions ssl_opts; - ssl_opts.pem_root_certs = ""; - ssl_opts.pem_key_cert_pairs.push_back(pkcp); - creds = SslServerCredentials(ssl_opts); - } else { - creds = InsecureServerCredentials(); - } - builder.AddListeningPort(server_address.str(), creds); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - grpc_slice_unref(cert_slice); - grpc_slice_unref(key_slice); - return server_address.str(); - } - - void ShutdownServer() { server_->Shutdown(); } - - std::unique_ptr<Server> server_; - TestServiceImpl service_; - reflection::ProtoServerReflectionPlugin plugin_; -}; - -TEST_F(GrpcToolTest, NoCommand) { - // Test input "grpc_cli" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli"}; - // Exit with 1, print usage instruction in stderr - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), "No command specified\n" USAGE_REGEX); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, InvalidCommand) { - // Test input "grpc_cli" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "abc"}; - // Exit with 1, print usage instruction in stderr - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), "Invalid command 'abc'\n" USAGE_REGEX); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, HelpCommand) { - // Test input "grpc_cli help" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "help"}; - // Exit with 1, print usage instruction in stderr - EXPECT_EXIT(GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1)), - ::testing::ExitedWithCode(1), USAGE_REGEX); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, ListCommand) { - // Test input "grpc_cli list localhost:<port>" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "ls", server_address.c_str()}; - - y_absl::SetFlag(&FLAGS_l, false); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - "grpc.testing.EchoTestService\n" - "grpc.reflection.v1alpha.ServerReflection\n")); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, ListOneService) { - // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), - "grpc.testing.EchoTestService"}; - // without -l flag - y_absl::SetFlag(&FLAGS_l, false); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: ECHO_TEST_SERVICE_SUMMARY - EXPECT_TRUE(0 == - strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_SUMMARY)); - - // with -l flag - output_stream.str(TString()); - output_stream.clear(); - y_absl::SetFlag(&FLAGS_l, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: ECHO_TEST_SERVICE_DESCRIPTION - EXPECT_TRUE( - 0 == strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_DESCRIPTION)); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, TypeCommand) { - // Test input "grpc_cli type localhost:<port> grpc.testing.EchoRequest" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "type", server_address.c_str(), - "grpc.testing.EchoRequest"}; - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - const grpc::protobuf::Descriptor* desc = - grpc::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName( - "grpc.testing.EchoRequest"); - // Expected output: the DebugString of grpc.testing.EchoRequest - EXPECT_TRUE(0 == - strcmp(output_stream.str().c_str(), desc->DebugString().c_str())); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, ListOneMethod) { - // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), - "grpc.testing.EchoTestService.Echo"}; - // without -l flag - y_absl::SetFlag(&FLAGS_l, false); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "Echo" - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), "Echo\n")); - - // with -l flag - output_stream.str(TString()); - output_stream.clear(); - y_absl::SetFlag(&FLAGS_l, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: ECHO_METHOD_DESCRIPTION - EXPECT_TRUE(0 == - strcmp(output_stream.str().c_str(), ECHO_METHOD_DESCRIPTION)); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, TypeNotFound) { - // Test input "grpc_cli type localhost:<port> grpc.testing.PhonyRequest" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "type", server_address.c_str(), - "grpc.testing.PhonyRequest"}; - - EXPECT_TRUE(1 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommand) { - // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "message: 'Hello'"}; - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); - - // with json_output - output_stream.str(TString()); - output_stream.clear(); - - // TODO(Capstan): Consider using y_absl::FlagSaver - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - - // Expected output: - // { - // "message": "Hello" - // } - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "{\n \"message\": \"Hello\"\n}")); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandJsonInput) { - // Test input "grpc_cli call localhost:<port> Echo "{ \"message\": \"Hello\"}" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "{ \"message\": \"Hello\"}"}; - - y_absl::SetFlag(&FLAGS_json_input, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); - - // with json_output - output_stream.str(TString()); - output_stream.clear(); - - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - y_absl::SetFlag(&FLAGS_json_input, false); - - // Expected output: - // { - // "message": "Hello" - // } - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "{\n \"message\": \"Hello\"\n}")); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandBatch) { - // Test input "grpc_cli call Echo" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "message: 'Hello0'"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_batch, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_batch, false); - - // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: - // "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: " - "\"Hello1\"\nmessage: \"Hello2\"\n")); - // with json_output - output_stream.str(TString()); - output_stream.clear(); - ss.clear(); - ss.seekg(0); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_batch, true); - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - y_absl::SetFlag(&FLAGS_batch, false); - - // Expected output: - // { - // "message": "Hello0" - // } - // { - // "message": "Hello1" - // } - // { - // "message": "Hello2" - // } - // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: - // "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "{\n \"message\": \"Hello0\"\n}\n" - "{\n \"message\": \"Hello1\"\n}\n" - "{\n \"message\": \"Hello2\"\n}\n")); - - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandBatchJsonInput) { - // Test input "grpc_cli call Echo" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "{\"message\": \"Hello0\"}"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss( - "{\"message\": \"Hello1\"}\n\n{\"message\": \"Hello2\" }\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_json_input, true); - y_absl::SetFlag(&FLAGS_batch, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_batch, false); - - // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: - // "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: " - "\"Hello1\"\nmessage: \"Hello2\"\n")); - // with json_output - output_stream.str(TString()); - output_stream.clear(); - ss.clear(); - ss.seekg(0); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_batch, true); - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - y_absl::SetFlag(&FLAGS_batch, false); - y_absl::SetFlag(&FLAGS_json_input, false); - - // Expected output: - // { - // "message": "Hello0" - // } - // { - // "message": "Hello1" - // } - // { - // "message": "Hello2" - // } - // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: - // "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "{\n \"message\": \"Hello0\"\n}\n" - "{\n \"message\": \"Hello1\"\n}\n" - "{\n \"message\": \"Hello2\"\n}\n")); - - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) { - // Test input "grpc_cli call Echo" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "message: 'Hello0'"}; - - // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 1\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_batch, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_batch, false); - - // Expected output: "message: "Hello0"\nmessage: "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: \"Hello2\"\n")); - - // with json_output - output_stream.str(TString()); - output_stream.clear(); - ss.clear(); - ss.seekg(0); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_batch, true); - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - y_absl::SetFlag(&FLAGS_batch, false); - - // Expected output: - // { - // "message": "Hello0" - // } - // { - // "message": "Hello2" - // } - // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: - // "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "{\n \"message\": \"Hello0\"\n}\n" - "{\n \"message\": \"Hello2\"\n}\n")); - - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandBatchJsonInputWithBadRequest) { - // Test input "grpc_cli call Echo" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "{ \"message\": \"Hello0\"}"}; - - // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss( - "{ \"message\": 1 }\n\n { \"message\": \"Hello2\" }\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_batch, true); - y_absl::SetFlag(&FLAGS_json_input, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_input, false); - y_absl::SetFlag(&FLAGS_batch, false); - - // Expected output: "message: "Hello0"\nmessage: "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: \"Hello2\"\n")); - - // with json_output - output_stream.str(TString()); - output_stream.clear(); - ss.clear(); - ss.seekg(0); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_batch, true); - y_absl::SetFlag(&FLAGS_json_input, true); - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - y_absl::SetFlag(&FLAGS_json_input, false); - y_absl::SetFlag(&FLAGS_batch, false); - - // Expected output: - // { - // "message": "Hello0" - // } - // { - // "message": "Hello2" - // } - // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: - // "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "{\n \"message\": \"Hello0\"\n}\n" - "{\n \"message\": \"Hello2\"\n}\n")); - - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandRequestStream) { - // Test input: grpc_cli call localhost:<port> RequestStream "message: - // 'Hello0'" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "RequestStream", "message: 'Hello0'"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello0Hello1Hello2\"" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0Hello1Hello2\"")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandRequestStreamJsonInput) { - // Test input: grpc_cli call localhost:<port> RequestStream "{ \"message\": - // \"Hello0\"}" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "RequestStream", "{ \"message\": \"Hello0\" }"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss( - "{ \"message\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_json_input, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_input, false); - - // Expected output: "message: \"Hello0Hello1Hello2\"" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0Hello1Hello2\"")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) { - // Test input: grpc_cli call localhost:<port> RequestStream "message: - // 'Hello0'" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "RequestStream", "message: 'Hello0'"}; - - // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("bad_field: 'Hello1'\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello0Hello2\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\"")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequestJsonInput) { - // Test input: grpc_cli call localhost:<port> RequestStream "message: - // 'Hello0'" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "RequestStream", "{ \"message\": \"Hello0\" }"}; - - // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss( - "{ \"bad_field\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - y_absl::SetFlag(&FLAGS_json_input, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_input, false); - - // Expected output: "message: \"Hello0Hello2\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\"")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandWithTimeoutDeadlineSet) { - // Test input "grpc_cli call CheckDeadlineSet --timeout=5000.25" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "CheckDeadlineSet"}; - - // Set timeout to 5000.25 seconds - y_absl::SetFlag(&FLAGS_timeout, 5000.25); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: "true"", deadline set - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"true\"")); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandWithTimeoutDeadlineUpperBound) { - // Test input "grpc_cli call CheckDeadlineUpperBound --timeout=900" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "CheckDeadlineUpperBound"}; - - // Set timeout to 900 seconds - y_absl::SetFlag(&FLAGS_timeout, 900); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - TString output = output_stream.str(); - - // Expected output: "message: "true"" - // deadline not greater than timeout + current time - EXPECT_TRUE(nullptr != strstr(output.c_str(), "message: \"true\"")) << output; - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandWithNegativeTimeoutValue) { - // Test input "grpc_cli call CheckDeadlineSet --timeout=-5" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "CheckDeadlineSet"}; - - // Set timeout to -5 (deadline not set) - y_absl::SetFlag(&FLAGS_timeout, -5); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: "false"", deadline not set - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"false\"")); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandWithDefaultTimeoutValue) { - // Test input "grpc_cli call CheckDeadlineSet --timeout=-1" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "CheckDeadlineSet"}; - - // Set timeout to -1 (default value, deadline not set) - y_absl::SetFlag(&FLAGS_timeout, -1); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: "false"", deadline not set - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"false\"")); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandResponseStream) { - // Test input: grpc_cli call localhost:<port> ResponseStream "message: - // 'Hello'" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "ResponseStream", "message: 'Hello'"}; - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello{n}\"" - for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { - TString expected_response_text = - "message: \"Hello" + ToString(i) + "\"\n"; - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - expected_response_text.c_str())); - } - - // with json_output - output_stream.str(TString()); - output_stream.clear(); - - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - - // Expected output: "{\n \"message\": \"Hello{n}\"\n}\n" - for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { - TString expected_response_text = - "{\n \"message\": \"Hello" + ToString(i) + "\"\n}\n"; - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - expected_response_text.c_str())); - } - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandBidiStream) { - // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "BidiStream", "message: 'Hello0'"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage: - // \"Hello2\"\n\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: " - "\"Hello1\"\nmessage: \"Hello2\"\n")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandBidiStreamWithBadRequest) { - // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'" - std::stringstream output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "BidiStream", "message: 'Hello0'"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 1.0\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage: - // \"Hello2\"\n\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: \"Hello2\"\n")); - std::cin.rdbuf(orig); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, ParseCommand) { - // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse - // ECHO_RESPONSE_MESSAGE" - std::stringstream output_stream; - std::stringstream binary_output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "parse", server_address.c_str(), - "grpc.testing.EchoResponse", - ECHO_RESPONSE_MESSAGE_TEXT_FORMAT}; - - y_absl::SetFlag(&FLAGS_binary_input, false); - y_absl::SetFlag(&FLAGS_binary_output, false); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - ECHO_RESPONSE_MESSAGE_TEXT_FORMAT)); - - // with json_output - output_stream.str(TString()); - output_stream.clear(); - - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - - // Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - ECHO_RESPONSE_MESSAGE_JSON_FORMAT)); - - // Parse text message to binary message and then parse it back to text message - output_stream.str(TString()); - output_stream.clear(); - y_absl::SetFlag(&FLAGS_binary_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - TString binary_data = output_stream.str(); - output_stream.str(TString()); - output_stream.clear(); - argv[4] = binary_data.c_str(); - y_absl::SetFlag(&FLAGS_binary_input, true); - y_absl::SetFlag(&FLAGS_binary_output, false); - EXPECT_TRUE(0 == GrpcToolMainLib(5, argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: ECHO_RESPONSE_MESSAGE - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - ECHO_RESPONSE_MESSAGE_TEXT_FORMAT)); - - y_absl::SetFlag(&FLAGS_binary_input, false); - y_absl::SetFlag(&FLAGS_binary_output, false); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, ParseCommandJsonFormat) { - // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse - // ECHO_RESPONSE_MESSAGE_JSON_FORMAT" - std::stringstream output_stream; - std::stringstream binary_output_stream; - - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "parse", server_address.c_str(), - "grpc.testing.EchoResponse", - ECHO_RESPONSE_MESSAGE_JSON_FORMAT}; - - y_absl::SetFlag(&FLAGS_json_input, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - ECHO_RESPONSE_MESSAGE_TEXT_FORMAT)); - - // with json_output - output_stream.str(TString()); - output_stream.clear(); - - y_absl::SetFlag(&FLAGS_json_output, true); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_json_output, false); - y_absl::SetFlag(&FLAGS_json_input, false); - - // Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - ECHO_RESPONSE_MESSAGE_JSON_FORMAT)); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, TooFewArguments) { - // Test input "grpc_cli call Echo" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "call", "Echo"}; - - // Exit with 1 - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, TooManyArguments) { - // Test input "grpc_cli call localhost:<port> Echo Echo "message: 'Hello'" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "call", "localhost:10000", - "Echo", "Echo", "message: 'Hello'"}; - - // Exit with 1 - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, CallCommandWithMetadata) { - // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "message: 'Hello'"}; - - { - std::stringstream output_stream; - y_absl::SetFlag(&FLAGS_metadata, "key0:val0:key1:valq:key2:val2"); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, - TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); - } - - { - std::stringstream output_stream; - y_absl::SetFlag(&FLAGS_metadata, "key:val\\:val"); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, - TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); - } - - { - std::stringstream output_stream; - y_absl::SetFlag(&FLAGS_metadata, "key:val\\\\val"); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, - TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); - } - - y_absl::SetFlag(&FLAGS_metadata, ""); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandWithBadMetadata) { - // Test input "grpc_cli call localhost:10000 Echo "message: 'Hello'" - const char* argv[] = {"grpc_cli", "call", "localhost:10000", - "grpc.testing.EchoTestService.Echo", - "message: 'Hello'"}; - y_absl::SetFlag(&FLAGS_protofiles, "src/proto/grpc/testing/echo.proto"); - char* test_srcdir = gpr_getenv("TEST_SRCDIR"); - if (test_srcdir != nullptr) { - y_absl::SetFlag(&FLAGS_proto_path, - test_srcdir + TString("/com_github_grpc_grpc")); - } - - { - std::stringstream output_stream; - y_absl::SetFlag(&FLAGS_metadata, "key0:val0:key1"); - // Exit with 1 - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*"); - } - - { - std::stringstream output_stream; - y_absl::SetFlag(&FLAGS_metadata, "key:val\\val"); - // Exit with 1 - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*"); - } - - y_absl::SetFlag(&FLAGS_metadata, ""); - y_absl::SetFlag(&FLAGS_protofiles, ""); - - gpr_free(test_srcdir); -} - -TEST_F(GrpcToolTest, ListCommand_OverrideSslHostName) { - const TString server_address = SetUpServer(true); - - // Test input "grpc_cli ls localhost:<port> --channel_creds_type=ssl - // --ssl_target=z.test.google.fr" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "ls", server_address.c_str()}; - y_absl::SetFlag(&FLAGS_l, false); - y_absl::SetFlag(&FLAGS_channel_creds_type, "ssl"); - y_absl::SetFlag(&FLAGS_ssl_target, "z.test.google.fr"); - EXPECT_TRUE( - 0 == GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(true), - std::bind(PrintStream, &output_stream, std::placeholders::_1))); - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - "grpc.testing.EchoTestService\n" - "grpc.reflection.v1alpha.ServerReflection\n")); - - y_absl::SetFlag(&FLAGS_channel_creds_type, ""); - y_absl::SetFlag(&FLAGS_ssl_target, ""); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, ConfiguringDefaultServiceConfig) { - // Test input "grpc_cli list localhost:<port> - // --default_service_config={\"loadBalancingConfig\":[{\"pick_first\":{}}]}" - std::stringstream output_stream; - const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "ls", server_address.c_str()}; - // Just check that the tool is still operational when --default_service_config - // is configured. This particular service config is in reality redundant with - // the channel's default configuration. - y_absl::SetFlag(&FLAGS_l, false); - y_absl::SetFlag(&FLAGS_default_service_config, - "{\"loadBalancingConfig\":[{\"pick_first\":{}}]}"); - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - y_absl::SetFlag(&FLAGS_default_service_config, ""); - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - "grpc.testing.EchoTestService\n" - "grpc.reflection.v1alpha.ServerReflection\n")); - ShutdownServer(); -} - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - GRPC_GTEST_FLAG_SET_DEATH_TEST_STYLE("threadsafe"); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/util/metrics_server.cc b/contrib/libs/grpc/test/cpp/util/metrics_server.cc deleted file mode 100644 index 0493da053e..0000000000 --- a/contrib/libs/grpc/test/cpp/util/metrics_server.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* - * - * Copyright 2015 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. - *is % allowed in string - */ - -#include "test/cpp/util/metrics_server.h" - -#include <grpc/support/log.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> - -#include "src/proto/grpc/testing/metrics.grpc.pb.h" -#include "src/proto/grpc/testing/metrics.pb.h" - -namespace grpc { -namespace testing { - -QpsGauge::QpsGauge() - : start_time_(gpr_now(GPR_CLOCK_REALTIME)), num_queries_(0) {} - -void QpsGauge::Reset() { - std::lock_guard<std::mutex> lock(num_queries_mu_); - num_queries_ = 0; - start_time_ = gpr_now(GPR_CLOCK_REALTIME); -} - -void QpsGauge::Incr() { - std::lock_guard<std::mutex> lock(num_queries_mu_); - num_queries_++; -} - -long QpsGauge::Get() { - std::lock_guard<std::mutex> lock(num_queries_mu_); - gpr_timespec time_diff = - gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start_time_); - long duration_secs = time_diff.tv_sec > 0 ? time_diff.tv_sec : 1; - return num_queries_ / duration_secs; -} - -grpc::Status MetricsServiceImpl::GetAllGauges( - ServerContext* /*context*/, const EmptyMessage* /*request*/, - ServerWriter<GaugeResponse>* writer) { - gpr_log(GPR_DEBUG, "GetAllGauges called"); - - std::lock_guard<std::mutex> lock(mu_); - for (auto it = qps_gauges_.begin(); it != qps_gauges_.end(); it++) { - GaugeResponse resp; - resp.set_name(it->first); // Gauge name - resp.set_long_value(it->second->Get()); // Gauge value - writer->Write(resp); - } - - return Status::OK; -} - -grpc::Status MetricsServiceImpl::GetGauge(ServerContext* /*context*/, - const GaugeRequest* request, - GaugeResponse* response) { - std::lock_guard<std::mutex> lock(mu_); - - const auto it = qps_gauges_.find(request->name()); - if (it != qps_gauges_.end()) { - response->set_name(it->first); - response->set_long_value(it->second->Get()); - } - - return Status::OK; -} - -std::shared_ptr<QpsGauge> MetricsServiceImpl::CreateQpsGauge( - const TString& name, bool* already_present) { - std::lock_guard<std::mutex> lock(mu_); - - std::shared_ptr<QpsGauge> qps_gauge(new QpsGauge()); - const auto p = qps_gauges_.insert(std::make_pair(name, qps_gauge)); - - // p.first is an iterator pointing to <name, shared_ptr<QpsGauge>> pair. - // p.second is a boolean which is set to 'true' if the QpsGauge is - // successfully inserted in the guages_ map and 'false' if it is already - // present in the map - *already_present = !p.second; - return p.first->second; -} - -// Starts the metrics server and returns the grpc::Server instance. Call Wait() -// on the returned server instance. -std::unique_ptr<grpc::Server> MetricsServiceImpl::StartServer(int port) { - gpr_log(GPR_INFO, "Building metrics server.."); - - const TString address = "0.0.0.0:" + ToString(port); - - ServerBuilder builder; - builder.AddListeningPort(address, grpc::InsecureServerCredentials()); - builder.RegisterService(this); - - std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); - gpr_log(GPR_INFO, "Metrics server %s started. Ready to receive requests..", - address.c_str()); - - return server; -} - -} // namespace testing -} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/metrics_server.h b/contrib/libs/grpc/test/cpp/util/metrics_server.h deleted file mode 100644 index 10ffa7b4dd..0000000000 --- a/contrib/libs/grpc/test/cpp/util/metrics_server.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * Copyright 2015 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. - *is % allowed in string - */ -#ifndef GRPC_TEST_CPP_METRICS_SERVER_H -#define GRPC_TEST_CPP_METRICS_SERVER_H - -#include <map> -#include <mutex> - -#include <grpcpp/server.h> - -#include "src/proto/grpc/testing/metrics.grpc.pb.h" -#include "src/proto/grpc/testing/metrics.pb.h" - -/* - * This implements a Metrics server defined in - * src/proto/grpc/testing/metrics.proto. Any - * test service can use this to export Metrics (TODO (sreek): Only Gauges for - * now). - * - * Example: - * MetricsServiceImpl metricsImpl; - * .. - * // Create QpsGauge(s). Note: QpsGauges can be created even after calling - * // 'StartServer'. - * QpsGauge qps_gauge1 = metricsImpl.CreateQpsGauge("foo", is_present); - * // qps_gauge1 can now be used anywhere in the program by first making a - * // one-time call qps_gauge1.Reset() and then calling qps_gauge1.Incr() - * // every time to increment a query counter - * - * ... - * // Create the metrics server - * std::unique_ptr<grpc::Server> server = metricsImpl.StartServer(port); - * server->Wait(); // Note: This is blocking. - */ -namespace grpc { -namespace testing { - -class QpsGauge { - public: - QpsGauge(); - - // Initialize the internal timer and reset the query count to 0 - void Reset(); - - // Increment the query count by 1 - void Incr(); - - // Return the current qps (i.e query count divided by the time since this - // QpsGauge object created (or Reset() was called)) - long Get(); - - private: - gpr_timespec start_time_; - long num_queries_; - std::mutex num_queries_mu_; -}; - -class MetricsServiceImpl final : public MetricsService::Service { - public: - grpc::Status GetAllGauges(ServerContext* context, const EmptyMessage* request, - ServerWriter<GaugeResponse>* writer) override; - - grpc::Status GetGauge(ServerContext* context, const GaugeRequest* request, - GaugeResponse* response) override; - - // Create a QpsGauge with name 'name'. is_present is set to true if the Gauge - // is already present in the map. - // NOTE: CreateQpsGauge can be called anytime (i.e before or after calling - // StartServer). - std::shared_ptr<QpsGauge> CreateQpsGauge(const TString& name, - bool* already_present); - - std::unique_ptr<grpc::Server> StartServer(int port); - - private: - std::map<string, std::shared_ptr<QpsGauge>> qps_gauges_; - std::mutex mu_; -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_METRICS_SERVER_H diff --git a/contrib/libs/grpc/test/cpp/util/slice_test.cc b/contrib/libs/grpc/test/cpp/util/slice_test.cc deleted file mode 100644 index c10319c5a2..0000000000 --- a/contrib/libs/grpc/test/cpp/util/slice_test.cc +++ /dev/null @@ -1,151 +0,0 @@ -/* - * - * Copyright 2015 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 <gtest/gtest.h> - -#include <grpc++/support/slice.h> -#include <grpc/grpc.h> -#include <grpc/slice.h> -#include <grpcpp/impl/grpc_library.h> - -#include "test/core/util/test_config.h" - -namespace grpc { - -static internal::GrpcLibraryInitializer g_gli_initializer; - -namespace { - -const char* kContent = "hello xxxxxxxxxxxxxxxxxxxx world"; - -class SliceTest : public ::testing::Test { - protected: - static void SetUpTestCase() { grpc_init(); } - - static void TearDownTestCase() { grpc_shutdown(); } - - void CheckSliceSize(const Slice& s, const TString& content) { - EXPECT_EQ(content.size(), s.size()); - } - void CheckSlice(const Slice& s, const TString& content) { - EXPECT_EQ(content.size(), s.size()); - EXPECT_EQ(content, - TString(reinterpret_cast<const char*>(s.begin()), s.size())); - } -}; - -TEST_F(SliceTest, Empty) { - Slice empty_slice; - CheckSlice(empty_slice, ""); -} - -TEST_F(SliceTest, Sized) { - Slice sized_slice(strlen(kContent)); - CheckSliceSize(sized_slice, kContent); -} - -TEST_F(SliceTest, String) { - Slice spp(kContent); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, Buf) { - Slice spp(kContent, strlen(kContent)); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, StaticBuf) { - Slice spp(kContent, strlen(kContent), Slice::STATIC_SLICE); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, SliceNew) { - char* x = new char[strlen(kContent) + 1]; - strcpy(x, kContent); - Slice spp(x, strlen(x), [](void* p) { delete[] static_cast<char*>(p); }); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, SliceNewDoNothing) { - Slice spp(const_cast<char*>(kContent), strlen(kContent), [](void* /*p*/) {}); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, SliceNewWithUserData) { - struct stest { - char* x; - int y; - }; - auto* t = new stest; - t->x = new char[strlen(kContent) + 1]; - strcpy(t->x, kContent); - Slice spp( - t->x, strlen(t->x), - [](void* p) { - auto* t = static_cast<stest*>(p); - delete[] t->x; - delete t; - }, - t); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, SliceNewLen) { - Slice spp(const_cast<char*>(kContent), strlen(kContent), - [](void* /*p*/, size_t l) { EXPECT_EQ(l, strlen(kContent)); }); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, Steal) { - grpc_slice s = grpc_slice_from_copied_string(kContent); - Slice spp(s, Slice::STEAL_REF); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, Add) { - grpc_slice s = grpc_slice_from_copied_string(kContent); - Slice spp(s, Slice::ADD_REF); - grpc_slice_unref(s); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, Sub) { - Slice spp("0123456789"); - Slice sub = spp.sub(1, 9); - CheckSlice(sub, "12345678"); -} - -TEST_F(SliceTest, Cslice) { - grpc_slice s = grpc_slice_from_copied_string(kContent); - Slice spp(s, Slice::STEAL_REF); - CheckSlice(spp, kContent); - grpc_slice c_slice = spp.c_slice(); - EXPECT_EQ(GRPC_SLICE_START_PTR(s), GRPC_SLICE_START_PTR(c_slice)); - EXPECT_EQ(GRPC_SLICE_END_PTR(s), GRPC_SLICE_END_PTR(c_slice)); - grpc_slice_unref(c_slice); -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/contrib/libs/grpc/test/cpp/util/string_ref_test.cc b/contrib/libs/grpc/test/cpp/util/string_ref_test.cc deleted file mode 100644 index 1537e187e2..0000000000 --- a/contrib/libs/grpc/test/cpp/util/string_ref_test.cc +++ /dev/null @@ -1,205 +0,0 @@ -/* - * - * Copyright 2015 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 <string.h> - -#include <gtest/gtest.h> - -#include <grpcpp/support/string_ref.h> - -#include "test/core/util/test_config.h" - -namespace grpc { -namespace { - -const char kTestString[] = "blah"; -const char kTestStringWithEmbeddedNull[] = "blah\0foo"; -const size_t kTestStringWithEmbeddedNullLength = 8; -const char kTestUnrelatedString[] = "foo"; - -class StringRefTest : public ::testing::Test {}; - -TEST_F(StringRefTest, Empty) { - string_ref s; - EXPECT_EQ(0U, s.length()); - EXPECT_EQ(nullptr, s.data()); -} - -TEST_F(StringRefTest, FromCString) { - string_ref s(kTestString); - EXPECT_EQ(strlen(kTestString), s.length()); - EXPECT_EQ(kTestString, s.data()); -} - -TEST_F(StringRefTest, FromCStringWithLength) { - string_ref s(kTestString, 2); - EXPECT_EQ(2U, s.length()); - EXPECT_EQ(kTestString, s.data()); -} - -TEST_F(StringRefTest, FromString) { - string copy(kTestString); - string_ref s(copy); - EXPECT_EQ(copy.data(), s.data()); - EXPECT_EQ(copy.length(), s.length()); -} - -TEST_F(StringRefTest, CopyConstructor) { - string_ref s1(kTestString); - ; - const string_ref& s2(s1); - EXPECT_EQ(s1.length(), s2.length()); - EXPECT_EQ(s1.data(), s2.data()); -} - -TEST_F(StringRefTest, FromStringWithEmbeddedNull) { - string copy(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - string_ref s(copy); - EXPECT_EQ(copy.data(), s.data()); - EXPECT_EQ(copy.length(), s.length()); - EXPECT_EQ(kTestStringWithEmbeddedNullLength, s.length()); -} - -TEST_F(StringRefTest, Assignment) { - string_ref s1(kTestString); - ; - string_ref s2; - EXPECT_EQ(nullptr, s2.data()); - s2 = s1; - EXPECT_EQ(s1.length(), s2.length()); - EXPECT_EQ(s1.data(), s2.data()); -} - -TEST_F(StringRefTest, Iterator) { - string_ref s(kTestString); - size_t i = 0; - for (auto it = s.cbegin(); it != s.cend(); ++it) { - auto val = kTestString[i++]; - EXPECT_EQ(val, *it); - } - EXPECT_EQ(strlen(kTestString), i); -} - -TEST_F(StringRefTest, ReverseIterator) { - string_ref s(kTestString); - size_t i = strlen(kTestString); - for (auto rit = s.crbegin(); rit != s.crend(); ++rit) { - auto val = kTestString[--i]; - EXPECT_EQ(val, *rit); - } - EXPECT_EQ(0U, i); -} - -TEST_F(StringRefTest, Capacity) { - string_ref empty; - EXPECT_EQ(0U, empty.length()); - EXPECT_EQ(0U, empty.size()); - EXPECT_EQ(0U, empty.max_size()); - EXPECT_TRUE(empty.empty()); - - string_ref s(kTestString); - EXPECT_EQ(strlen(kTestString), s.length()); - EXPECT_EQ(s.length(), s.size()); - EXPECT_EQ(s.max_size(), s.length()); - EXPECT_FALSE(s.empty()); -} - -TEST_F(StringRefTest, Compare) { - string_ref s1(kTestString); - string s1_copy(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_EQ(0, s1.compare(s1_copy)); - EXPECT_NE(0, s1.compare(s2)); - EXPECT_NE(0, s1.compare(s3)); -} - -TEST_F(StringRefTest, StartsWith) { - string_ref s1(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_TRUE(s1.starts_with(s1)); - EXPECT_FALSE(s1.starts_with(s2)); - EXPECT_FALSE(s2.starts_with(s1)); - EXPECT_FALSE(s1.starts_with(s3)); - EXPECT_TRUE(s3.starts_with(s1)); -} - -TEST_F(StringRefTest, Endswith) { - string_ref s1(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_TRUE(s1.ends_with(s1)); - EXPECT_FALSE(s1.ends_with(s2)); - EXPECT_FALSE(s2.ends_with(s1)); - EXPECT_FALSE(s2.ends_with(s3)); - EXPECT_TRUE(s3.ends_with(s2)); -} - -TEST_F(StringRefTest, Find) { - string_ref s1(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_EQ(0U, s1.find(s1)); - EXPECT_EQ(0U, s2.find(s2)); - EXPECT_EQ(0U, s3.find(s3)); - EXPECT_EQ(string_ref::npos, s1.find(s2)); - EXPECT_EQ(string_ref::npos, s2.find(s1)); - EXPECT_EQ(string_ref::npos, s1.find(s3)); - EXPECT_EQ(0U, s3.find(s1)); - EXPECT_EQ(5U, s3.find(s2)); - EXPECT_EQ(string_ref::npos, s1.find('z')); - EXPECT_EQ(1U, s2.find('o')); -} - -TEST_F(StringRefTest, SubString) { - string_ref s(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - string_ref sub1 = s.substr(0, 4); - EXPECT_EQ(string_ref(kTestString), sub1); - string_ref sub2 = s.substr(5); - EXPECT_EQ(string_ref(kTestUnrelatedString), sub2); -} - -TEST_F(StringRefTest, ComparisonOperators) { - string_ref s1(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_EQ(s1, s1); - EXPECT_EQ(s2, s2); - EXPECT_EQ(s3, s3); - EXPECT_GE(s1, s1); - EXPECT_GE(s2, s2); - EXPECT_GE(s3, s3); - EXPECT_LE(s1, s1); - EXPECT_LE(s2, s2); - EXPECT_LE(s3, s3); - EXPECT_NE(s1, s2); - EXPECT_NE(s1, s3); - EXPECT_NE(s2, s3); - EXPECT_GT(s3, s1); - EXPECT_LT(s1, s3); -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/util/subprocess.cc b/contrib/libs/grpc/test/cpp/util/subprocess.cc deleted file mode 100644 index 648bd50274..0000000000 --- a/contrib/libs/grpc/test/cpp/util/subprocess.cc +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Copyright 2015 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 "test/cpp/util/subprocess.h" - -#include <vector> - -#include "test/core/util/subprocess.h" - -namespace grpc { - -static gpr_subprocess* MakeProcess(const std::vector<TString>& args) { - std::vector<const char*> vargs; - for (auto it = args.begin(); it != args.end(); ++it) { - vargs.push_back(it->c_str()); - } - return gpr_subprocess_create(vargs.size(), &vargs[0]); -} - -SubProcess::SubProcess(const std::vector<TString>& args) - : subprocess_(MakeProcess(args)) {} - -SubProcess::~SubProcess() { gpr_subprocess_destroy(subprocess_); } - -int SubProcess::Join() { return gpr_subprocess_join(subprocess_); } - -void SubProcess::Interrupt() { gpr_subprocess_interrupt(subprocess_); } - -} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/subprocess.h b/contrib/libs/grpc/test/cpp/util/subprocess.h deleted file mode 100644 index c01a15f0d7..0000000000 --- a/contrib/libs/grpc/test/cpp/util/subprocess.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2015 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_SUBPROCESS_H -#define GRPC_TEST_CPP_UTIL_SUBPROCESS_H - -#include <initializer_list> -#include <util/generic/string.h> -#include <vector> - -struct gpr_subprocess; - -namespace grpc { - -class SubProcess { - public: - explicit SubProcess(const std::vector<TString>& args); - ~SubProcess(); - - int Join(); - void Interrupt(); - - private: - SubProcess(const SubProcess& other); - SubProcess& operator=(const SubProcess& other); - - gpr_subprocess* const subprocess_; -}; - -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_SUBPROCESS_H diff --git a/contrib/libs/grpc/test/cpp/util/test_credentials_provider.cc b/contrib/libs/grpc/test/cpp/util/test_credentials_provider.cc deleted file mode 100644 index 6f339dd3f5..0000000000 --- a/contrib/libs/grpc/test/cpp/util/test_credentials_provider.cc +++ /dev/null @@ -1,183 +0,0 @@ - -/* - * - * Copyright 2016 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 "test/cpp/util/test_credentials_provider.h" - -#include <cstdio> -#include <fstream> -#include <iostream> -#include <mutex> -#include <unordered_map> - -#include "y_absl/flags/flag.h" - -#include <grpc/support/log.h> -#include <grpc/support/sync.h> -#include <grpcpp/security/server_credentials.h> - -#include "test/core/end2end/data/ssl_test_data.h" - -Y_ABSL_FLAG(TString, tls_cert_file, "", - "The TLS cert file used when --use_tls=true"); -Y_ABSL_FLAG(TString, tls_key_file, "", - "The TLS key file used when --use_tls=true"); - -namespace grpc { -namespace testing { -namespace { - -TString ReadFile(const TString& src_path) { - std::ifstream src; - src.open(src_path, std::ifstream::in | std::ifstream::binary); - - TString contents; - src.seekg(0, std::ios::end); - contents.reserve(src.tellg()); - src.seekg(0, std::ios::beg); - contents.assign((std::istreambuf_iterator<char>(src)), - (std::istreambuf_iterator<char>())); - return contents; -} - -class DefaultCredentialsProvider : public CredentialsProvider { - public: - DefaultCredentialsProvider() { - if (!y_absl::GetFlag(FLAGS_tls_key_file).empty()) { - custom_server_key_ = ReadFile(y_absl::GetFlag(FLAGS_tls_key_file)); - } - if (!y_absl::GetFlag(FLAGS_tls_cert_file).empty()) { - custom_server_cert_ = ReadFile(y_absl::GetFlag(FLAGS_tls_cert_file)); - } - } - ~DefaultCredentialsProvider() override {} - - void AddSecureType( - const TString& type, - std::unique_ptr<CredentialTypeProvider> type_provider) override { - // This clobbers any existing entry for type, except the defaults, which - // can't be clobbered. - std::unique_lock<std::mutex> lock(mu_); - auto it = std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type); - if (it == added_secure_type_names_.end()) { - added_secure_type_names_.push_back(type); - added_secure_type_providers_.push_back(std::move(type_provider)); - } else { - added_secure_type_providers_[it - added_secure_type_names_.begin()] = - std::move(type_provider); - } - } - - std::shared_ptr<ChannelCredentials> GetChannelCredentials( - const TString& type, ChannelArguments* args) override { - if (type == grpc::testing::kInsecureCredentialsType) { - return InsecureChannelCredentials(); - } else if (type == grpc::testing::kAltsCredentialsType) { - grpc::experimental::AltsCredentialsOptions alts_opts; - return grpc::experimental::AltsCredentials(alts_opts); - } else if (type == grpc::testing::kTlsCredentialsType) { - SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; - args->SetSslTargetNameOverride("foo.test.google.fr"); - return grpc::SslCredentials(ssl_opts); - } else if (type == grpc::testing::kGoogleDefaultCredentialsType) { - return grpc::GoogleDefaultCredentials(); - } else { - std::unique_lock<std::mutex> lock(mu_); - auto it(std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type)); - if (it == added_secure_type_names_.end()) { - gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); - return nullptr; - } - return added_secure_type_providers_[it - added_secure_type_names_.begin()] - ->GetChannelCredentials(args); - } - } - - std::shared_ptr<ServerCredentials> GetServerCredentials( - const TString& type) override { - if (type == grpc::testing::kInsecureCredentialsType) { - return InsecureServerCredentials(); - } else if (type == grpc::testing::kAltsCredentialsType) { - grpc::experimental::AltsServerCredentialsOptions alts_opts; - return grpc::experimental::AltsServerCredentials(alts_opts); - } else if (type == grpc::testing::kTlsCredentialsType) { - SslServerCredentialsOptions ssl_opts; - ssl_opts.pem_root_certs = ""; - if (!custom_server_key_.empty() && !custom_server_cert_.empty()) { - SslServerCredentialsOptions::PemKeyCertPair pkcp = { - custom_server_key_, custom_server_cert_}; - ssl_opts.pem_key_cert_pairs.push_back(pkcp); - } else { - SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, - test_server1_cert}; - ssl_opts.pem_key_cert_pairs.push_back(pkcp); - } - return SslServerCredentials(ssl_opts); - } else { - std::unique_lock<std::mutex> lock(mu_); - auto it(std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type)); - if (it == added_secure_type_names_.end()) { - gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); - return nullptr; - } - return added_secure_type_providers_[it - added_secure_type_names_.begin()] - ->GetServerCredentials(); - } - } - std::vector<TString> GetSecureCredentialsTypeList() override { - std::vector<TString> types; - types.push_back(grpc::testing::kTlsCredentialsType); - std::unique_lock<std::mutex> lock(mu_); - for (auto it = added_secure_type_names_.begin(); - it != added_secure_type_names_.end(); it++) { - types.push_back(*it); - } - return types; - } - - private: - std::mutex mu_; - std::vector<TString> added_secure_type_names_; - std::vector<std::unique_ptr<CredentialTypeProvider>> - added_secure_type_providers_; - TString custom_server_key_; - TString custom_server_cert_; -}; - -CredentialsProvider* g_provider = nullptr; - -} // namespace - -CredentialsProvider* GetCredentialsProvider() { - if (g_provider == nullptr) { - g_provider = new DefaultCredentialsProvider; - } - return g_provider; -} - -void SetCredentialsProvider(CredentialsProvider* provider) { - // For now, forbids overriding provider. - GPR_ASSERT(g_provider == nullptr); - g_provider = provider; -} - -} // namespace testing -} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/test_credentials_provider.h b/contrib/libs/grpc/test/cpp/util/test_credentials_provider.h deleted file mode 100644 index acba277ada..0000000000 --- a/contrib/libs/grpc/test/cpp/util/test_credentials_provider.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H -#define GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H - -#include <memory> - -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/support/channel_arguments.h> - -namespace grpc { -namespace testing { - -const char kInsecureCredentialsType[] = "INSECURE_CREDENTIALS"; -// For real credentials, like tls/ssl, this name should match the AuthContext -// property "transport_security_type". -const char kTlsCredentialsType[] = "ssl"; -const char kAltsCredentialsType[] = "alts"; -const char kGoogleDefaultCredentialsType[] = "google_default_credentials"; - -// Provide test credentials of a particular type. -class CredentialTypeProvider { - public: - virtual ~CredentialTypeProvider() {} - - virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials( - ChannelArguments* args) = 0; - virtual std::shared_ptr<ServerCredentials> GetServerCredentials() = 0; -}; - -// Provide test credentials. Thread-safe. -class CredentialsProvider { - public: - virtual ~CredentialsProvider() {} - - // Add a secure type in addition to the defaults. The default provider has - // (kInsecureCredentialsType, kTlsCredentialsType). - virtual void AddSecureType( - const TString& type, - std::unique_ptr<CredentialTypeProvider> type_provider) = 0; - - // Provide channel credentials according to the given type. Alter the channel - // arguments if needed. Return nullptr if type is not registered. - virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials( - const TString& type, ChannelArguments* args) = 0; - - // Provide server credentials according to the given type. - // Return nullptr if type is not registered. - virtual std::shared_ptr<ServerCredentials> GetServerCredentials( - const TString& type) = 0; - - // Provide a list of secure credentials type. - virtual std::vector<TString> GetSecureCredentialsTypeList() = 0; -}; - -// Get the current provider. Create a default one if not set. -// Not thread-safe. -CredentialsProvider* GetCredentialsProvider(); - -// Set the global provider. Takes ownership. The previous set provider will be -// destroyed. -// Not thread-safe. -void SetCredentialsProvider(CredentialsProvider* provider); - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H diff --git a/contrib/libs/grpc/test/cpp/util/time_test.cc b/contrib/libs/grpc/test/cpp/util/time_test.cc deleted file mode 100644 index 4970f4b56b..0000000000 --- a/contrib/libs/grpc/test/cpp/util/time_test.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Copyright 2015 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 <gtest/gtest.h> - -#include <grpc/support/time.h> -#include <grpcpp/support/time.h> - -#include "test/core/util/test_config.h" - -using std::chrono::microseconds; -using std::chrono::system_clock; - -namespace grpc { -namespace { - -class TimeTest : public ::testing::Test {}; - -TEST_F(TimeTest, AbsolutePointTest) { - int64_t us = 10000000L; - gpr_timespec ts = gpr_time_from_micros(us, GPR_TIMESPAN); - ts.clock_type = GPR_CLOCK_REALTIME; - system_clock::time_point tp{microseconds(us)}; - system_clock::time_point tp_converted = Timespec2Timepoint(ts); - gpr_timespec ts_converted; - Timepoint2Timespec(tp_converted, &ts_converted); - EXPECT_TRUE(ts.tv_sec == ts_converted.tv_sec); - EXPECT_TRUE(ts.tv_nsec == ts_converted.tv_nsec); - system_clock::time_point tp_converted_2 = Timespec2Timepoint(ts_converted); - EXPECT_TRUE(tp == tp_converted); - EXPECT_TRUE(tp == tp_converted_2); -} - -// gpr_inf_future is treated specially and mapped to/from time_point::max() -TEST_F(TimeTest, InfFuture) { - EXPECT_EQ(system_clock::time_point::max(), - Timespec2Timepoint(gpr_inf_future(GPR_CLOCK_REALTIME))); - gpr_timespec from_time_point_max; - Timepoint2Timespec(system_clock::time_point::max(), &from_time_point_max); - EXPECT_EQ( - 0, gpr_time_cmp(gpr_inf_future(GPR_CLOCK_REALTIME), from_time_point_max)); - // This will cause an overflow - Timepoint2Timespec( - std::chrono::time_point<system_clock, std::chrono::seconds>::max(), - &from_time_point_max); - EXPECT_EQ( - 0, gpr_time_cmp(gpr_inf_future(GPR_CLOCK_REALTIME), from_time_point_max)); -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/contrib/libs/grpc/test/cpp/util/tls_test_utils.cc b/contrib/libs/grpc/test/cpp/util/tls_test_utils.cc deleted file mode 100644 index 6bf727c8cb..0000000000 --- a/contrib/libs/grpc/test/cpp/util/tls_test_utils.cc +++ /dev/null @@ -1,99 +0,0 @@ -// -// 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 "test/cpp/util/tls_test_utils.h" - -#include <memory> - -#include "src/core/lib/gprpp/thd.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -using ::grpc::experimental::ExternalCertificateVerifier; -using ::grpc::experimental::TlsCustomVerificationCheckRequest; - -namespace grpc { -namespace testing { - -bool SyncCertificateVerifier::Verify(TlsCustomVerificationCheckRequest*, - std::function<void(grpc::Status)>, - grpc::Status* sync_status) { - if (!success_) { - *sync_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED, - "SyncCertificateVerifier failed"); - } else { - *sync_status = grpc::Status(grpc::StatusCode::OK, ""); - } - return true; -} - -AsyncCertificateVerifier::AsyncCertificateVerifier(bool success) - : success_(success), - thread_("AsyncCertificateVerifierWorkerThread", WorkerThread, this) { - thread_.Start(); -} - -AsyncCertificateVerifier::~AsyncCertificateVerifier() { - // Tell the thread to shut down. - { - internal::MutexLock lock(&mu_); - queue_.push_back(Request{nullptr, nullptr, true}); - } - // Wait for thread to exit. - thread_.Join(); -} - -bool AsyncCertificateVerifier::Verify( - TlsCustomVerificationCheckRequest* request, - std::function<void(grpc::Status)> callback, grpc::Status*) { - internal::MutexLock lock(&mu_); - queue_.push_back(Request{request, std::move(callback), false}); - return false; // Asynchronous call -} - -void AsyncCertificateVerifier::WorkerThread(void* arg) { - auto* self = static_cast<AsyncCertificateVerifier*>(arg); - while (true) { - // Check queue for work. - bool got_request = false; - Request request; - { - internal::MutexLock lock(&self->mu_); - if (!self->queue_.empty()) { - got_request = true; - request = self->queue_.front(); - self->queue_.pop_front(); - } - } - // If nothing found in the queue, sleep for a bit and try again. - if (!got_request) { - gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100)); - continue; - } - // If we're being told to shut down, return. - if (request.shutdown) return; - auto return_status = grpc::Status(grpc::StatusCode::OK, ""); - // Process the request. - if (!self->success_) { - return_status = grpc::Status(grpc::StatusCode::UNAUTHENTICATED, - "AsyncCertificateVerifier failed"); - } - request.callback(return_status); - } -} - -} // namespace testing -} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/tls_test_utils.h b/contrib/libs/grpc/test/cpp/util/tls_test_utils.h deleted file mode 100644 index 3f8d3d5a5d..0000000000 --- a/contrib/libs/grpc/test/cpp/util/tls_test_utils.h +++ /dev/null @@ -1,82 +0,0 @@ -// -// 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. -// - -#ifndef GRPC_TEST_CPP_UTIL_TLS_TEST_UTILS_H -#define GRPC_TEST_CPP_UTIL_TLS_TEST_UTILS_H - -#include <deque> - -#include <grpc/grpc.h> -#include <grpc/grpc_security.h> -#include <grpcpp/security/server_credentials.h> - -#include "src/core/lib/gprpp/thd.h" - -namespace grpc { -namespace testing { - -class SyncCertificateVerifier - : public ::grpc::experimental::ExternalCertificateVerifier { - public: - explicit SyncCertificateVerifier(bool success) : success_(success) {} - - ~SyncCertificateVerifier() override {} - - bool Verify(::grpc::experimental::TlsCustomVerificationCheckRequest* request, - std::function<void(grpc::Status)> callback, - grpc::Status* sync_status) override; - - void Cancel( - ::grpc::experimental::TlsCustomVerificationCheckRequest*) override {} - - private: - bool success_ = false; -}; - -class AsyncCertificateVerifier - : public ::grpc::experimental::ExternalCertificateVerifier { - public: - explicit AsyncCertificateVerifier(bool success); - - ~AsyncCertificateVerifier() override; - - bool Verify(::grpc::experimental::TlsCustomVerificationCheckRequest* request, - std::function<void(grpc::Status)> callback, - grpc::Status* sync_status) override; - - void Cancel( - ::grpc::experimental::TlsCustomVerificationCheckRequest*) override {} - - private: - // A request to pass to the worker thread. - struct Request { - ::grpc::experimental::TlsCustomVerificationCheckRequest* request; - std::function<void(grpc::Status)> callback; - bool shutdown; // If true, thread will exit. - }; - - static void WorkerThread(void* arg); - - bool success_ = false; - grpc_core::Thread thread_; - grpc::internal::Mutex mu_; - std::deque<Request> queue_ Y_ABSL_GUARDED_BY(mu_); -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_TLS_TEST_UTILS_H |