diff options
Diffstat (limited to 'test')
762 files changed, 33793 insertions, 11927 deletions
diff --git a/test/build/openssl-npn.c b/test/build/openssl-npn.c deleted file mode 100644 index 9c71382720..0000000000 --- a/test/build/openssl-npn.c +++ /dev/null @@ -1,30 +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. - * - */ - -/* This is just a compilation test, to see if we have a version of OpenSSL with - NPN support installed. It's not meant to be run, and all of the values and - function calls there are non-sensical. The code is only meant to test the - presence of symbols, and we're expecting a compilation failure otherwise. */ - -#include <stdlib.h> -#include <openssl/ssl.h> - -int main() { - SSL_get0_next_proto_negotiated(NULL, NULL, NULL); - return OPENSSL_NPN_UNSUPPORTED; -} diff --git a/test/core/avl/BUILD b/test/core/avl/BUILD new file mode 100644 index 0000000000..48f5baeb1a --- /dev/null +++ b/test/core/avl/BUILD @@ -0,0 +1,30 @@ +# 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. + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package") + +licenses(["notice"]) # Apache v2 + +grpc_package(name = "test/core/avl") + +grpc_cc_test( + name = "avl_test", + srcs = ["avl_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + ], +) diff --git a/test/core/avl/avl_test.cc b/test/core/avl/avl_test.cc new file mode 100644 index 0000000000..ecebe833b3 --- /dev/null +++ b/test/core/avl/avl_test.cc @@ -0,0 +1,3661 @@ +/* + * + * 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/avl/avl.h" + +#include <stdio.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" + +static int* box(int x) { + int* b = static_cast<int*>(gpr_malloc(sizeof(*b))); + *b = x; + return b; +} + +static long int_compare(void* int1, void* int2, void* unused) { + return (*static_cast<int*>(int1)) - (*static_cast<int*>(int2)); +} +static void* int_copy(void* p, void* unused) { + return box(*static_cast<int*>(p)); +} + +static void destroy(void* p, void* unused) { gpr_free(p); } + +static const grpc_avl_vtable int_int_vtable = {destroy, int_copy, int_compare, + destroy, int_copy}; + +static void check_get(grpc_avl avl, int key, int value) { + int* k = box(key); + GPR_ASSERT(*(int*)grpc_avl_get(avl, k, nullptr) == value); + gpr_free(k); +} + +static void check_negget(grpc_avl avl, int key) { + int* k = box(key); + GPR_ASSERT(grpc_avl_get(avl, k, nullptr) == nullptr); + gpr_free(k); +} + +static grpc_avl remove_int(grpc_avl avl, int key) { + int* k = box(key); + avl = grpc_avl_remove(avl, k, nullptr); + gpr_free(k); + return avl; +} + +static void test_get(void) { + grpc_avl avl; + gpr_log(GPR_DEBUG, "test_get"); + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(1), box(11), nullptr); + avl = grpc_avl_add(avl, box(2), box(22), nullptr); + avl = grpc_avl_add(avl, box(3), box(33), nullptr); + check_get(avl, 1, 11); + check_get(avl, 2, 22); + check_get(avl, 3, 33); + check_negget(avl, 4); + grpc_avl_unref(avl, nullptr); +} + +static void test_ll(void) { + grpc_avl avl; + gpr_log(GPR_DEBUG, "test_ll"); + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(5), box(1), nullptr); + avl = grpc_avl_add(avl, box(4), box(2), nullptr); + avl = grpc_avl_add(avl, box(3), box(3), nullptr); + GPR_ASSERT(*(int*)avl.root->key == 4); + GPR_ASSERT(*(int*)avl.root->left->key == 3); + GPR_ASSERT(*(int*)avl.root->right->key == 5); + grpc_avl_unref(avl, nullptr); +} + +static void test_lr(void) { + grpc_avl avl; + gpr_log(GPR_DEBUG, "test_lr"); + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(5), box(1), nullptr); + avl = grpc_avl_add(avl, box(3), box(2), nullptr); + avl = grpc_avl_add(avl, box(4), box(3), nullptr); + GPR_ASSERT(*(int*)avl.root->key == 4); + GPR_ASSERT(*(int*)avl.root->left->key == 3); + GPR_ASSERT(*(int*)avl.root->right->key == 5); + grpc_avl_unref(avl, nullptr); +} + +static void test_rr(void) { + grpc_avl avl; + gpr_log(GPR_DEBUG, "test_rr"); + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(3), box(1), nullptr); + avl = grpc_avl_add(avl, box(4), box(2), nullptr); + avl = grpc_avl_add(avl, box(5), box(3), nullptr); + GPR_ASSERT(*(int*)avl.root->key == 4); + GPR_ASSERT(*(int*)avl.root->left->key == 3); + GPR_ASSERT(*(int*)avl.root->right->key == 5); + grpc_avl_unref(avl, nullptr); +} + +static void test_rl(void) { + grpc_avl avl; + gpr_log(GPR_DEBUG, "test_rl"); + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(3), box(1), nullptr); + avl = grpc_avl_add(avl, box(5), box(2), nullptr); + avl = grpc_avl_add(avl, box(4), box(3), nullptr); + GPR_ASSERT(*(int*)avl.root->key == 4); + GPR_ASSERT(*(int*)avl.root->left->key == 3); + GPR_ASSERT(*(int*)avl.root->right->key == 5); + grpc_avl_unref(avl, nullptr); +} + +static void test_unbalanced(void) { + grpc_avl avl; + gpr_log(GPR_DEBUG, "test_unbalanced"); + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(5), box(1), nullptr); + avl = grpc_avl_add(avl, box(4), box(2), nullptr); + avl = grpc_avl_add(avl, box(3), box(3), nullptr); + avl = grpc_avl_add(avl, box(2), box(4), nullptr); + avl = grpc_avl_add(avl, box(1), box(5), nullptr); + GPR_ASSERT(*(int*)avl.root->key == 4); + GPR_ASSERT(*(int*)avl.root->left->key == 2); + GPR_ASSERT(*(int*)avl.root->left->left->key == 1); + GPR_ASSERT(*(int*)avl.root->left->right->key == 3); + GPR_ASSERT(*(int*)avl.root->right->key == 5); + grpc_avl_unref(avl, nullptr); +} + +static void test_replace(void) { + grpc_avl avl; + gpr_log(GPR_DEBUG, "test_replace"); + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(1), box(1), nullptr); + avl = grpc_avl_add(avl, box(1), box(2), nullptr); + check_get(avl, 1, 2); + check_negget(avl, 2); + grpc_avl_unref(avl, nullptr); +} + +static void test_remove(void) { + grpc_avl avl; + grpc_avl avl3, avl4, avl5, avln; + gpr_log(GPR_DEBUG, "test_remove"); + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(3), box(1), nullptr); + avl = grpc_avl_add(avl, box(4), box(2), nullptr); + avl = grpc_avl_add(avl, box(5), box(3), nullptr); + + avl3 = remove_int(grpc_avl_ref(avl, nullptr), 3); + avl4 = remove_int(grpc_avl_ref(avl, nullptr), 4); + avl5 = remove_int(grpc_avl_ref(avl, nullptr), 5); + avln = remove_int(grpc_avl_ref(avl, nullptr), 1); + + grpc_avl_unref(avl, nullptr); + + check_negget(avl3, 3); + check_get(avl3, 4, 2); + check_get(avl3, 5, 3); + grpc_avl_unref(avl3, nullptr); + + check_get(avl4, 3, 1); + check_negget(avl4, 4); + check_get(avl4, 5, 3); + grpc_avl_unref(avl4, nullptr); + + check_get(avl5, 3, 1); + check_get(avl5, 4, 2); + check_negget(avl5, 5); + grpc_avl_unref(avl5, nullptr); + + check_get(avln, 3, 1); + check_get(avln, 4, 2); + check_get(avln, 5, 3); + grpc_avl_unref(avln, nullptr); +} + +static void test_badcase1(void) { + grpc_avl avl; + + gpr_log(GPR_DEBUG, "test_badcase1"); + + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(88), box(1), nullptr); + avl = remove_int(avl, 643); + avl = remove_int(avl, 983); + avl = grpc_avl_add(avl, box(985), box(4), nullptr); + avl = grpc_avl_add(avl, box(640), box(5), nullptr); + avl = grpc_avl_add(avl, box(41), box(6), nullptr); + avl = grpc_avl_add(avl, box(112), box(7), nullptr); + avl = grpc_avl_add(avl, box(342), box(8), nullptr); + avl = remove_int(avl, 1013); + avl = grpc_avl_add(avl, box(434), box(10), nullptr); + avl = grpc_avl_add(avl, box(520), box(11), nullptr); + avl = grpc_avl_add(avl, box(231), box(12), nullptr); + avl = grpc_avl_add(avl, box(852), box(13), nullptr); + avl = remove_int(avl, 461); + avl = grpc_avl_add(avl, box(108), box(15), nullptr); + avl = grpc_avl_add(avl, box(806), box(16), nullptr); + avl = grpc_avl_add(avl, box(827), box(17), nullptr); + avl = remove_int(avl, 796); + avl = grpc_avl_add(avl, box(340), box(19), nullptr); + avl = grpc_avl_add(avl, box(498), box(20), nullptr); + avl = grpc_avl_add(avl, box(203), box(21), nullptr); + avl = grpc_avl_add(avl, box(751), box(22), nullptr); + avl = grpc_avl_add(avl, box(150), box(23), nullptr); + avl = remove_int(avl, 237); + avl = grpc_avl_add(avl, box(830), box(25), nullptr); + avl = remove_int(avl, 1007); + avl = remove_int(avl, 394); + avl = grpc_avl_add(avl, box(65), box(28), nullptr); + avl = remove_int(avl, 904); + avl = remove_int(avl, 123); + avl = grpc_avl_add(avl, box(238), box(31), nullptr); + avl = grpc_avl_add(avl, box(184), box(32), nullptr); + avl = remove_int(avl, 331); + avl = grpc_avl_add(avl, box(827), box(34), nullptr); + + check_get(avl, 830, 25); + + grpc_avl_unref(avl, nullptr); +} + +static void test_badcase2(void) { + grpc_avl avl; + + gpr_log(GPR_DEBUG, "test_badcase2"); + + avl = grpc_avl_create(&int_int_vtable); + avl = grpc_avl_add(avl, box(288), box(1), nullptr); + avl = remove_int(avl, 415); + avl = grpc_avl_add(avl, box(953), box(3), nullptr); + avl = grpc_avl_add(avl, box(101), box(4), nullptr); + avl = grpc_avl_add(avl, box(516), box(5), nullptr); + avl = grpc_avl_add(avl, box(547), box(6), nullptr); + avl = grpc_avl_add(avl, box(467), box(7), nullptr); + avl = grpc_avl_add(avl, box(793), box(8), nullptr); + avl = remove_int(avl, 190); + avl = grpc_avl_add(avl, box(687), box(10), nullptr); + avl = grpc_avl_add(avl, box(242), box(11), nullptr); + avl = grpc_avl_add(avl, box(142), box(12), nullptr); + avl = remove_int(avl, 705); + avl = remove_int(avl, 578); + avl = remove_int(avl, 767); + avl = remove_int(avl, 183); + avl = grpc_avl_add(avl, box(950), box(17), nullptr); + avl = grpc_avl_add(avl, box(622), box(18), nullptr); + avl = remove_int(avl, 513); + avl = remove_int(avl, 429); + avl = grpc_avl_add(avl, box(205), box(21), nullptr); + avl = remove_int(avl, 663); + avl = remove_int(avl, 953); + avl = remove_int(avl, 892); + avl = grpc_avl_add(avl, box(236), box(25), nullptr); + avl = remove_int(avl, 982); + avl = remove_int(avl, 201); + avl = remove_int(avl, 684); + avl = grpc_avl_add(avl, box(572), box(29), nullptr); + avl = remove_int(avl, 817); + avl = grpc_avl_add(avl, box(970), box(31), nullptr); + avl = remove_int(avl, 347); + avl = remove_int(avl, 574); + avl = grpc_avl_add(avl, box(752), box(34), nullptr); + avl = grpc_avl_add(avl, box(670), box(35), nullptr); + avl = grpc_avl_add(avl, box(69), box(36), nullptr); + avl = remove_int(avl, 111); + avl = remove_int(avl, 523); + avl = grpc_avl_add(avl, box(141), box(39), nullptr); + avl = remove_int(avl, 159); + avl = grpc_avl_add(avl, box(947), box(41), nullptr); + avl = grpc_avl_add(avl, box(855), box(42), nullptr); + avl = remove_int(avl, 218); + avl = remove_int(avl, 6); + avl = grpc_avl_add(avl, box(753), box(45), nullptr); + avl = remove_int(avl, 82); + avl = remove_int(avl, 799); + avl = grpc_avl_add(avl, box(572), box(48), nullptr); + avl = remove_int(avl, 376); + avl = remove_int(avl, 413); + avl = grpc_avl_add(avl, box(458), box(51), nullptr); + avl = remove_int(avl, 897); + avl = grpc_avl_add(avl, box(191), box(53), nullptr); + avl = grpc_avl_add(avl, box(609), box(54), nullptr); + avl = remove_int(avl, 787); + avl = remove_int(avl, 710); + avl = remove_int(avl, 886); + avl = remove_int(avl, 835); + avl = remove_int(avl, 33); + avl = grpc_avl_add(avl, box(871), box(60), nullptr); + avl = remove_int(avl, 641); + avl = grpc_avl_add(avl, box(462), box(62), nullptr); + avl = remove_int(avl, 359); + avl = remove_int(avl, 767); + avl = grpc_avl_add(avl, box(310), box(65), nullptr); + avl = remove_int(avl, 757); + avl = remove_int(avl, 639); + avl = remove_int(avl, 314); + avl = grpc_avl_add(avl, box(2), box(69), nullptr); + avl = remove_int(avl, 138); + avl = grpc_avl_add(avl, box(669), box(71), nullptr); + avl = remove_int(avl, 477); + avl = grpc_avl_add(avl, box(366), box(73), nullptr); + avl = grpc_avl_add(avl, box(612), box(74), nullptr); + avl = grpc_avl_add(avl, box(106), box(75), nullptr); + avl = remove_int(avl, 161); + avl = grpc_avl_add(avl, box(388), box(77), nullptr); + avl = grpc_avl_add(avl, box(141), box(78), nullptr); + avl = remove_int(avl, 633); + avl = remove_int(avl, 459); + avl = grpc_avl_add(avl, box(40), box(81), nullptr); + avl = remove_int(avl, 689); + avl = grpc_avl_add(avl, box(823), box(83), nullptr); + avl = remove_int(avl, 485); + avl = grpc_avl_add(avl, box(903), box(85), nullptr); + avl = grpc_avl_add(avl, box(592), box(86), nullptr); + avl = remove_int(avl, 448); + avl = grpc_avl_add(avl, box(56), box(88), nullptr); + avl = remove_int(avl, 333); + avl = grpc_avl_add(avl, box(189), box(90), nullptr); + avl = grpc_avl_add(avl, box(103), box(91), nullptr); + avl = remove_int(avl, 164); + avl = remove_int(avl, 974); + avl = grpc_avl_add(avl, box(215), box(94), nullptr); + avl = remove_int(avl, 189); + avl = remove_int(avl, 504); + avl = grpc_avl_add(avl, box(868), box(97), nullptr); + avl = remove_int(avl, 909); + avl = remove_int(avl, 148); + avl = remove_int(avl, 469); + avl = grpc_avl_add(avl, box(994), box(101), nullptr); + avl = grpc_avl_add(avl, box(576), box(102), nullptr); + avl = remove_int(avl, 82); + avl = remove_int(avl, 209); + avl = grpc_avl_add(avl, box(276), box(105), nullptr); + avl = remove_int(avl, 856); + avl = grpc_avl_add(avl, box(750), box(107), nullptr); + avl = remove_int(avl, 871); + avl = grpc_avl_add(avl, box(301), box(109), nullptr); + avl = remove_int(avl, 260); + avl = remove_int(avl, 737); + avl = remove_int(avl, 719); + avl = grpc_avl_add(avl, box(933), box(113), nullptr); + avl = grpc_avl_add(avl, box(225), box(114), nullptr); + avl = grpc_avl_add(avl, box(975), box(115), nullptr); + avl = grpc_avl_add(avl, box(86), box(116), nullptr); + avl = remove_int(avl, 732); + avl = grpc_avl_add(avl, box(340), box(118), nullptr); + avl = grpc_avl_add(avl, box(271), box(119), nullptr); + avl = remove_int(avl, 206); + avl = grpc_avl_add(avl, box(949), box(121), nullptr); + avl = grpc_avl_add(avl, box(927), box(122), nullptr); + avl = grpc_avl_add(avl, box(34), box(123), nullptr); + avl = grpc_avl_add(avl, box(351), box(124), nullptr); + avl = remove_int(avl, 836); + avl = grpc_avl_add(avl, box(825), box(126), nullptr); + avl = grpc_avl_add(avl, box(352), box(127), nullptr); + avl = remove_int(avl, 107); + avl = remove_int(avl, 101); + avl = grpc_avl_add(avl, box(320), box(130), nullptr); + avl = grpc_avl_add(avl, box(3), box(131), nullptr); + avl = remove_int(avl, 998); + avl = remove_int(avl, 44); + avl = grpc_avl_add(avl, box(525), box(134), nullptr); + avl = grpc_avl_add(avl, box(864), box(135), nullptr); + avl = grpc_avl_add(avl, box(863), box(136), nullptr); + avl = remove_int(avl, 770); + avl = grpc_avl_add(avl, box(440), box(138), nullptr); + avl = remove_int(avl, 516); + avl = grpc_avl_add(avl, box(116), box(140), nullptr); + avl = remove_int(avl, 380); + avl = grpc_avl_add(avl, box(878), box(142), nullptr); + avl = remove_int(avl, 439); + avl = grpc_avl_add(avl, box(994), box(144), nullptr); + avl = remove_int(avl, 294); + avl = remove_int(avl, 593); + avl = grpc_avl_add(avl, box(696), box(147), nullptr); + avl = remove_int(avl, 8); + avl = grpc_avl_add(avl, box(881), box(149), nullptr); + avl = remove_int(avl, 32); + avl = remove_int(avl, 242); + avl = grpc_avl_add(avl, box(487), box(152), nullptr); + avl = grpc_avl_add(avl, box(637), box(153), nullptr); + avl = grpc_avl_add(avl, box(793), box(154), nullptr); + avl = grpc_avl_add(avl, box(696), box(155), nullptr); + avl = remove_int(avl, 458); + avl = grpc_avl_add(avl, box(828), box(157), nullptr); + avl = remove_int(avl, 784); + avl = remove_int(avl, 274); + avl = grpc_avl_add(avl, box(783), box(160), nullptr); + avl = remove_int(avl, 21); + avl = grpc_avl_add(avl, box(866), box(162), nullptr); + avl = remove_int(avl, 919); + avl = grpc_avl_add(avl, box(435), box(164), nullptr); + avl = remove_int(avl, 385); + avl = grpc_avl_add(avl, box(475), box(166), nullptr); + avl = remove_int(avl, 339); + avl = grpc_avl_add(avl, box(615), box(168), nullptr); + avl = remove_int(avl, 866); + avl = remove_int(avl, 82); + avl = remove_int(avl, 271); + avl = grpc_avl_add(avl, box(590), box(172), nullptr); + avl = grpc_avl_add(avl, box(852), box(173), nullptr); + avl = remove_int(avl, 318); + avl = remove_int(avl, 82); + avl = grpc_avl_add(avl, box(672), box(176), nullptr); + avl = remove_int(avl, 430); + avl = grpc_avl_add(avl, box(821), box(178), nullptr); + avl = grpc_avl_add(avl, box(365), box(179), nullptr); + avl = remove_int(avl, 78); + avl = grpc_avl_add(avl, box(700), box(181), nullptr); + avl = grpc_avl_add(avl, box(353), box(182), nullptr); + avl = remove_int(avl, 492); + avl = grpc_avl_add(avl, box(991), box(184), nullptr); + avl = remove_int(avl, 330); + avl = grpc_avl_add(avl, box(873), box(186), nullptr); + avl = remove_int(avl, 589); + avl = grpc_avl_add(avl, box(676), box(188), nullptr); + avl = grpc_avl_add(avl, box(790), box(189), nullptr); + avl = remove_int(avl, 521); + avl = remove_int(avl, 47); + avl = grpc_avl_add(avl, box(976), box(192), nullptr); + avl = grpc_avl_add(avl, box(683), box(193), nullptr); + avl = remove_int(avl, 803); + avl = remove_int(avl, 1006); + avl = grpc_avl_add(avl, box(775), box(196), nullptr); + avl = grpc_avl_add(avl, box(411), box(197), nullptr); + avl = grpc_avl_add(avl, box(697), box(198), nullptr); + avl = remove_int(avl, 50); + avl = grpc_avl_add(avl, box(213), box(200), nullptr); + avl = remove_int(avl, 714); + avl = grpc_avl_add(avl, box(981), box(202), nullptr); + avl = grpc_avl_add(avl, box(502), box(203), nullptr); + avl = grpc_avl_add(avl, box(697), box(204), nullptr); + avl = grpc_avl_add(avl, box(603), box(205), nullptr); + avl = grpc_avl_add(avl, box(117), box(206), nullptr); + avl = remove_int(avl, 363); + avl = grpc_avl_add(avl, box(104), box(208), nullptr); + avl = remove_int(avl, 842); + avl = grpc_avl_add(avl, box(48), box(210), nullptr); + avl = remove_int(avl, 764); + avl = grpc_avl_add(avl, box(482), box(212), nullptr); + avl = grpc_avl_add(avl, box(928), box(213), nullptr); + avl = grpc_avl_add(avl, box(30), box(214), nullptr); + avl = grpc_avl_add(avl, box(820), box(215), nullptr); + avl = grpc_avl_add(avl, box(334), box(216), nullptr); + avl = remove_int(avl, 306); + avl = grpc_avl_add(avl, box(789), box(218), nullptr); + avl = remove_int(avl, 924); + avl = grpc_avl_add(avl, box(53), box(220), nullptr); + avl = remove_int(avl, 657); + avl = grpc_avl_add(avl, box(130), box(222), nullptr); + avl = grpc_avl_add(avl, box(239), box(223), nullptr); + avl = remove_int(avl, 20); + avl = grpc_avl_add(avl, box(117), box(225), nullptr); + avl = remove_int(avl, 882); + avl = remove_int(avl, 891); + avl = grpc_avl_add(avl, box(9), box(228), nullptr); + avl = grpc_avl_add(avl, box(496), box(229), nullptr); + avl = grpc_avl_add(avl, box(750), box(230), nullptr); + avl = grpc_avl_add(avl, box(283), box(231), nullptr); + avl = grpc_avl_add(avl, box(802), box(232), nullptr); + avl = remove_int(avl, 352); + avl = grpc_avl_add(avl, box(374), box(234), nullptr); + avl = grpc_avl_add(avl, box(6), box(235), nullptr); + avl = grpc_avl_add(avl, box(756), box(236), nullptr); + avl = grpc_avl_add(avl, box(597), box(237), nullptr); + avl = grpc_avl_add(avl, box(661), box(238), nullptr); + avl = remove_int(avl, 96); + avl = grpc_avl_add(avl, box(894), box(240), nullptr); + avl = remove_int(avl, 749); + avl = grpc_avl_add(avl, box(71), box(242), nullptr); + avl = remove_int(avl, 68); + avl = grpc_avl_add(avl, box(388), box(244), nullptr); + avl = remove_int(avl, 119); + avl = remove_int(avl, 856); + avl = grpc_avl_add(avl, box(176), box(247), nullptr); + avl = grpc_avl_add(avl, box(993), box(248), nullptr); + avl = remove_int(avl, 178); + avl = remove_int(avl, 781); + avl = remove_int(avl, 771); + avl = remove_int(avl, 848); + avl = remove_int(avl, 376); + avl = remove_int(avl, 157); + avl = remove_int(avl, 142); + avl = remove_int(avl, 686); + avl = grpc_avl_add(avl, box(779), box(257), nullptr); + avl = grpc_avl_add(avl, box(484), box(258), nullptr); + avl = remove_int(avl, 837); + avl = grpc_avl_add(avl, box(388), box(260), nullptr); + avl = remove_int(avl, 987); + avl = grpc_avl_add(avl, box(336), box(262), nullptr); + avl = remove_int(avl, 855); + avl = grpc_avl_add(avl, box(668), box(264), nullptr); + avl = remove_int(avl, 648); + avl = grpc_avl_add(avl, box(193), box(266), nullptr); + avl = remove_int(avl, 939); + avl = grpc_avl_add(avl, box(740), box(268), nullptr); + avl = grpc_avl_add(avl, box(503), box(269), nullptr); + avl = grpc_avl_add(avl, box(765), box(270), nullptr); + avl = remove_int(avl, 924); + avl = remove_int(avl, 513); + avl = grpc_avl_add(avl, box(161), box(273), nullptr); + avl = grpc_avl_add(avl, box(502), box(274), nullptr); + avl = grpc_avl_add(avl, box(846), box(275), nullptr); + avl = remove_int(avl, 931); + avl = grpc_avl_add(avl, box(87), box(277), nullptr); + avl = grpc_avl_add(avl, box(949), box(278), nullptr); + avl = grpc_avl_add(avl, box(548), box(279), nullptr); + avl = grpc_avl_add(avl, box(951), box(280), nullptr); + avl = remove_int(avl, 1018); + avl = remove_int(avl, 568); + avl = grpc_avl_add(avl, box(138), box(283), nullptr); + avl = grpc_avl_add(avl, box(202), box(284), nullptr); + avl = grpc_avl_add(avl, box(157), box(285), nullptr); + avl = grpc_avl_add(avl, box(264), box(286), nullptr); + avl = grpc_avl_add(avl, box(370), box(287), nullptr); + avl = remove_int(avl, 736); + avl = remove_int(avl, 751); + avl = remove_int(avl, 506); + avl = remove_int(avl, 81); + avl = remove_int(avl, 358); + avl = remove_int(avl, 657); + avl = remove_int(avl, 86); + avl = grpc_avl_add(avl, box(876), box(295), nullptr); + avl = remove_int(avl, 354); + avl = grpc_avl_add(avl, box(134), box(297), nullptr); + avl = remove_int(avl, 781); + avl = remove_int(avl, 183); + avl = grpc_avl_add(avl, box(914), box(300), nullptr); + avl = remove_int(avl, 926); + avl = remove_int(avl, 398); + avl = remove_int(avl, 932); + avl = remove_int(avl, 804); + avl = remove_int(avl, 326); + avl = grpc_avl_add(avl, box(208), box(306), nullptr); + avl = grpc_avl_add(avl, box(699), box(307), nullptr); + avl = remove_int(avl, 576); + avl = remove_int(avl, 850); + avl = remove_int(avl, 514); + avl = remove_int(avl, 676); + avl = remove_int(avl, 549); + avl = remove_int(avl, 767); + avl = grpc_avl_add(avl, box(58), box(314), nullptr); + avl = grpc_avl_add(avl, box(265), box(315), nullptr); + avl = grpc_avl_add(avl, box(268), box(316), nullptr); + avl = grpc_avl_add(avl, box(103), box(317), nullptr); + avl = grpc_avl_add(avl, box(440), box(318), nullptr); + avl = remove_int(avl, 777); + avl = grpc_avl_add(avl, box(670), box(320), nullptr); + avl = remove_int(avl, 506); + avl = remove_int(avl, 487); + avl = grpc_avl_add(avl, box(421), box(323), nullptr); + avl = remove_int(avl, 514); + avl = grpc_avl_add(avl, box(701), box(325), nullptr); + avl = remove_int(avl, 949); + avl = remove_int(avl, 872); + avl = remove_int(avl, 139); + avl = grpc_avl_add(avl, box(781), box(329), nullptr); + avl = grpc_avl_add(avl, box(543), box(330), nullptr); + avl = grpc_avl_add(avl, box(147), box(331), nullptr); + avl = remove_int(avl, 190); + avl = grpc_avl_add(avl, box(453), box(333), nullptr); + avl = remove_int(avl, 262); + avl = remove_int(avl, 850); + avl = remove_int(avl, 286); + avl = remove_int(avl, 787); + avl = grpc_avl_add(avl, box(514), box(338), nullptr); + avl = remove_int(avl, 812); + avl = grpc_avl_add(avl, box(431), box(340), nullptr); + avl = grpc_avl_add(avl, box(8), box(341), nullptr); + avl = remove_int(avl, 843); + avl = grpc_avl_add(avl, box(831), box(343), nullptr); + avl = remove_int(avl, 472); + avl = remove_int(avl, 157); + avl = grpc_avl_add(avl, box(612), box(346), nullptr); + avl = grpc_avl_add(avl, box(802), box(347), nullptr); + avl = remove_int(avl, 554); + avl = grpc_avl_add(avl, box(409), box(349), nullptr); + avl = grpc_avl_add(avl, box(439), box(350), nullptr); + avl = grpc_avl_add(avl, box(725), box(351), nullptr); + avl = grpc_avl_add(avl, box(568), box(352), nullptr); + avl = remove_int(avl, 475); + avl = remove_int(avl, 672); + avl = remove_int(avl, 62); + avl = remove_int(avl, 753); + avl = grpc_avl_add(avl, box(435), box(357), nullptr); + avl = grpc_avl_add(avl, box(950), box(358), nullptr); + avl = grpc_avl_add(avl, box(532), box(359), nullptr); + avl = grpc_avl_add(avl, box(832), box(360), nullptr); + avl = remove_int(avl, 390); + avl = grpc_avl_add(avl, box(993), box(362), nullptr); + avl = remove_int(avl, 198); + avl = remove_int(avl, 401); + avl = grpc_avl_add(avl, box(316), box(365), nullptr); + avl = remove_int(avl, 843); + avl = grpc_avl_add(avl, box(541), box(367), nullptr); + avl = grpc_avl_add(avl, box(505), box(368), nullptr); + avl = remove_int(avl, 445); + avl = remove_int(avl, 256); + avl = grpc_avl_add(avl, box(232), box(371), nullptr); + avl = remove_int(avl, 577); + avl = remove_int(avl, 558); + avl = grpc_avl_add(avl, box(910), box(374), nullptr); + avl = remove_int(avl, 902); + avl = remove_int(avl, 755); + avl = remove_int(avl, 114); + avl = remove_int(avl, 438); + avl = remove_int(avl, 224); + avl = grpc_avl_add(avl, box(920), box(380), nullptr); + avl = grpc_avl_add(avl, box(655), box(381), nullptr); + avl = remove_int(avl, 557); + avl = remove_int(avl, 102); + avl = remove_int(avl, 165); + avl = grpc_avl_add(avl, box(191), box(385), nullptr); + avl = remove_int(avl, 30); + avl = grpc_avl_add(avl, box(406), box(387), nullptr); + avl = grpc_avl_add(avl, box(66), box(388), nullptr); + avl = grpc_avl_add(avl, box(87), box(389), nullptr); + avl = remove_int(avl, 7); + avl = remove_int(avl, 671); + avl = grpc_avl_add(avl, box(234), box(392), nullptr); + avl = remove_int(avl, 463); + avl = grpc_avl_add(avl, box(75), box(394), nullptr); + avl = grpc_avl_add(avl, box(487), box(395), nullptr); + avl = remove_int(avl, 203); + avl = grpc_avl_add(avl, box(711), box(397), nullptr); + avl = remove_int(avl, 291); + avl = remove_int(avl, 798); + avl = remove_int(avl, 337); + avl = grpc_avl_add(avl, box(877), box(401), nullptr); + avl = grpc_avl_add(avl, box(388), box(402), nullptr); + avl = remove_int(avl, 975); + avl = grpc_avl_add(avl, box(200), box(404), nullptr); + avl = grpc_avl_add(avl, box(408), box(405), nullptr); + avl = grpc_avl_add(avl, box(3), box(406), nullptr); + avl = grpc_avl_add(avl, box(971), box(407), nullptr); + avl = remove_int(avl, 841); + avl = remove_int(avl, 910); + avl = remove_int(avl, 74); + avl = remove_int(avl, 888); + avl = grpc_avl_add(avl, box(492), box(412), nullptr); + avl = remove_int(avl, 14); + avl = remove_int(avl, 364); + avl = grpc_avl_add(avl, box(215), box(415), nullptr); + avl = remove_int(avl, 778); + avl = remove_int(avl, 45); + avl = grpc_avl_add(avl, box(328), box(418), nullptr); + avl = grpc_avl_add(avl, box(597), box(419), nullptr); + avl = remove_int(avl, 34); + avl = grpc_avl_add(avl, box(736), box(421), nullptr); + avl = remove_int(avl, 37); + avl = grpc_avl_add(avl, box(275), box(423), nullptr); + avl = grpc_avl_add(avl, box(70), box(424), nullptr); + avl = grpc_avl_add(avl, box(771), box(425), nullptr); + avl = remove_int(avl, 536); + avl = remove_int(avl, 421); + avl = grpc_avl_add(avl, box(186), box(428), nullptr); + avl = grpc_avl_add(avl, box(788), box(429), nullptr); + avl = grpc_avl_add(avl, box(224), box(430), nullptr); + avl = remove_int(avl, 228); + avl = grpc_avl_add(avl, box(48), box(432), nullptr); + avl = grpc_avl_add(avl, box(120), box(433), nullptr); + avl = grpc_avl_add(avl, box(269), box(434), nullptr); + avl = grpc_avl_add(avl, box(904), box(435), nullptr); + avl = remove_int(avl, 699); + avl = grpc_avl_add(avl, box(340), box(437), nullptr); + avl = remove_int(avl, 276); + avl = grpc_avl_add(avl, box(591), box(439), nullptr); + avl = grpc_avl_add(avl, box(778), box(440), nullptr); + avl = remove_int(avl, 490); + avl = remove_int(avl, 973); + avl = grpc_avl_add(avl, box(294), box(443), nullptr); + avl = grpc_avl_add(avl, box(323), box(444), nullptr); + avl = remove_int(avl, 685); + avl = grpc_avl_add(avl, box(38), box(446), nullptr); + avl = grpc_avl_add(avl, box(525), box(447), nullptr); + avl = remove_int(avl, 162); + avl = grpc_avl_add(avl, box(462), box(449), nullptr); + avl = grpc_avl_add(avl, box(340), box(450), nullptr); + avl = remove_int(avl, 734); + avl = remove_int(avl, 959); + avl = grpc_avl_add(avl, box(752), box(453), nullptr); + avl = grpc_avl_add(avl, box(667), box(454), nullptr); + avl = remove_int(avl, 558); + avl = remove_int(avl, 657); + avl = grpc_avl_add(avl, box(711), box(457), nullptr); + avl = remove_int(avl, 937); + avl = grpc_avl_add(avl, box(741), box(459), nullptr); + avl = grpc_avl_add(avl, box(40), box(460), nullptr); + avl = remove_int(avl, 784); + avl = grpc_avl_add(avl, box(292), box(462), nullptr); + avl = remove_int(avl, 164); + avl = remove_int(avl, 931); + avl = remove_int(avl, 886); + avl = grpc_avl_add(avl, box(968), box(466), nullptr); + avl = remove_int(avl, 263); + avl = grpc_avl_add(avl, box(647), box(468), nullptr); + avl = grpc_avl_add(avl, box(92), box(469), nullptr); + avl = remove_int(avl, 310); + avl = grpc_avl_add(avl, box(711), box(471), nullptr); + avl = grpc_avl_add(avl, box(675), box(472), nullptr); + avl = remove_int(avl, 549); + avl = grpc_avl_add(avl, box(380), box(474), nullptr); + avl = remove_int(avl, 825); + avl = grpc_avl_add(avl, box(668), box(476), nullptr); + avl = remove_int(avl, 498); + avl = grpc_avl_add(avl, box(870), box(478), nullptr); + avl = grpc_avl_add(avl, box(391), box(479), nullptr); + avl = grpc_avl_add(avl, box(264), box(480), nullptr); + avl = remove_int(avl, 1); + avl = remove_int(avl, 849); + avl = remove_int(avl, 88); + avl = remove_int(avl, 255); + avl = remove_int(avl, 763); + avl = remove_int(avl, 831); + avl = grpc_avl_add(avl, box(508), box(487), nullptr); + avl = remove_int(avl, 849); + avl = remove_int(avl, 47); + avl = grpc_avl_add(avl, box(299), box(490), nullptr); + avl = remove_int(avl, 625); + avl = remove_int(avl, 433); + avl = remove_int(avl, 904); + avl = remove_int(avl, 761); + avl = grpc_avl_add(avl, box(33), box(495), nullptr); + avl = grpc_avl_add(avl, box(524), box(496), nullptr); + avl = remove_int(avl, 210); + avl = remove_int(avl, 299); + avl = grpc_avl_add(avl, box(823), box(499), nullptr); + avl = remove_int(avl, 479); + avl = remove_int(avl, 96); + avl = remove_int(avl, 1013); + avl = grpc_avl_add(avl, box(768), box(503), nullptr); + avl = remove_int(avl, 638); + avl = remove_int(avl, 20); + avl = grpc_avl_add(avl, box(663), box(506), nullptr); + avl = remove_int(avl, 882); + avl = grpc_avl_add(avl, box(745), box(508), nullptr); + avl = remove_int(avl, 352); + avl = grpc_avl_add(avl, box(10), box(510), nullptr); + avl = remove_int(avl, 484); + avl = grpc_avl_add(avl, box(420), box(512), nullptr); + avl = grpc_avl_add(avl, box(884), box(513), nullptr); + avl = grpc_avl_add(avl, box(993), box(514), nullptr); + avl = grpc_avl_add(avl, box(251), box(515), nullptr); + avl = remove_int(avl, 222); + avl = grpc_avl_add(avl, box(734), box(517), nullptr); + avl = grpc_avl_add(avl, box(952), box(518), nullptr); + avl = remove_int(avl, 26); + avl = remove_int(avl, 270); + avl = remove_int(avl, 481); + avl = remove_int(avl, 693); + avl = remove_int(avl, 1006); + avl = grpc_avl_add(avl, box(77), box(524), nullptr); + avl = remove_int(avl, 897); + avl = grpc_avl_add(avl, box(719), box(526), nullptr); + avl = grpc_avl_add(avl, box(622), box(527), nullptr); + avl = remove_int(avl, 28); + avl = remove_int(avl, 836); + avl = remove_int(avl, 142); + avl = grpc_avl_add(avl, box(445), box(531), nullptr); + avl = grpc_avl_add(avl, box(410), box(532), nullptr); + avl = remove_int(avl, 575); + avl = grpc_avl_add(avl, box(634), box(534), nullptr); + avl = grpc_avl_add(avl, box(906), box(535), nullptr); + avl = remove_int(avl, 649); + avl = grpc_avl_add(avl, box(813), box(537), nullptr); + avl = remove_int(avl, 702); + avl = remove_int(avl, 732); + avl = grpc_avl_add(avl, box(105), box(540), nullptr); + avl = grpc_avl_add(avl, box(867), box(541), nullptr); + avl = remove_int(avl, 964); + avl = remove_int(avl, 941); + avl = grpc_avl_add(avl, box(947), box(544), nullptr); + avl = remove_int(avl, 990); + avl = grpc_avl_add(avl, box(816), box(546), nullptr); + avl = remove_int(avl, 429); + avl = remove_int(avl, 567); + avl = remove_int(avl, 541); + avl = remove_int(avl, 583); + avl = grpc_avl_add(avl, box(57), box(551), nullptr); + avl = grpc_avl_add(avl, box(786), box(552), nullptr); + avl = grpc_avl_add(avl, box(526), box(553), nullptr); + avl = remove_int(avl, 642); + avl = remove_int(avl, 220); + avl = remove_int(avl, 840); + avl = remove_int(avl, 548); + avl = grpc_avl_add(avl, box(528), box(558), nullptr); + avl = grpc_avl_add(avl, box(749), box(559), nullptr); + avl = grpc_avl_add(avl, box(194), box(560), nullptr); + avl = remove_int(avl, 517); + avl = grpc_avl_add(avl, box(102), box(562), nullptr); + avl = remove_int(avl, 189); + avl = grpc_avl_add(avl, box(927), box(564), nullptr); + avl = remove_int(avl, 846); + avl = remove_int(avl, 130); + avl = grpc_avl_add(avl, box(694), box(567), nullptr); + avl = remove_int(avl, 750); + avl = grpc_avl_add(avl, box(357), box(569), nullptr); + avl = remove_int(avl, 431); + avl = remove_int(avl, 91); + avl = grpc_avl_add(avl, box(640), box(572), nullptr); + avl = remove_int(avl, 4); + avl = grpc_avl_add(avl, box(81), box(574), nullptr); + avl = grpc_avl_add(avl, box(595), box(575), nullptr); + avl = remove_int(avl, 444); + avl = remove_int(avl, 262); + avl = remove_int(avl, 11); + avl = grpc_avl_add(avl, box(192), box(579), nullptr); + avl = grpc_avl_add(avl, box(158), box(580), nullptr); + avl = remove_int(avl, 401); + avl = remove_int(avl, 918); + avl = grpc_avl_add(avl, box(180), box(583), nullptr); + avl = remove_int(avl, 268); + avl = grpc_avl_add(avl, box(1012), box(585), nullptr); + avl = grpc_avl_add(avl, box(90), box(586), nullptr); + avl = grpc_avl_add(avl, box(946), box(587), nullptr); + avl = remove_int(avl, 719); + avl = grpc_avl_add(avl, box(874), box(589), nullptr); + avl = grpc_avl_add(avl, box(679), box(590), nullptr); + avl = remove_int(avl, 53); + avl = remove_int(avl, 534); + avl = grpc_avl_add(avl, box(646), box(593), nullptr); + avl = grpc_avl_add(avl, box(767), box(594), nullptr); + avl = grpc_avl_add(avl, box(460), box(595), nullptr); + avl = grpc_avl_add(avl, box(852), box(596), nullptr); + avl = grpc_avl_add(avl, box(189), box(597), nullptr); + avl = remove_int(avl, 932); + avl = remove_int(avl, 366); + avl = remove_int(avl, 907); + avl = grpc_avl_add(avl, box(875), box(601), nullptr); + avl = grpc_avl_add(avl, box(434), box(602), nullptr); + avl = grpc_avl_add(avl, box(704), box(603), nullptr); + avl = grpc_avl_add(avl, box(724), box(604), nullptr); + avl = grpc_avl_add(avl, box(930), box(605), nullptr); + avl = grpc_avl_add(avl, box(1000), box(606), nullptr); + avl = remove_int(avl, 479); + avl = grpc_avl_add(avl, box(275), box(608), nullptr); + avl = remove_int(avl, 32); + avl = grpc_avl_add(avl, box(939), box(610), nullptr); + avl = remove_int(avl, 943); + avl = remove_int(avl, 329); + avl = grpc_avl_add(avl, box(490), box(613), nullptr); + avl = remove_int(avl, 477); + avl = remove_int(avl, 414); + avl = remove_int(avl, 187); + avl = remove_int(avl, 334); + avl = grpc_avl_add(avl, box(40), box(618), nullptr); + avl = remove_int(avl, 751); + avl = grpc_avl_add(avl, box(568), box(620), nullptr); + avl = grpc_avl_add(avl, box(120), box(621), nullptr); + avl = grpc_avl_add(avl, box(617), box(622), nullptr); + avl = grpc_avl_add(avl, box(32), box(623), nullptr); + avl = remove_int(avl, 701); + avl = grpc_avl_add(avl, box(910), box(625), nullptr); + avl = remove_int(avl, 557); + avl = remove_int(avl, 361); + avl = remove_int(avl, 937); + avl = remove_int(avl, 100); + avl = remove_int(avl, 684); + avl = grpc_avl_add(avl, box(751), box(631), nullptr); + avl = remove_int(avl, 781); + avl = remove_int(avl, 469); + avl = remove_int(avl, 75); + avl = remove_int(avl, 561); + avl = grpc_avl_add(avl, box(854), box(636), nullptr); + avl = remove_int(avl, 164); + avl = remove_int(avl, 258); + avl = remove_int(avl, 315); + avl = remove_int(avl, 261); + avl = grpc_avl_add(avl, box(552), box(641), nullptr); + avl = grpc_avl_add(avl, box(6), box(642), nullptr); + avl = grpc_avl_add(avl, box(680), box(643), nullptr); + avl = remove_int(avl, 741); + avl = remove_int(avl, 309); + avl = remove_int(avl, 272); + avl = grpc_avl_add(avl, box(249), box(647), nullptr); + avl = remove_int(avl, 97); + avl = remove_int(avl, 850); + avl = grpc_avl_add(avl, box(915), box(650), nullptr); + avl = grpc_avl_add(avl, box(816), box(651), nullptr); + avl = grpc_avl_add(avl, box(45), box(652), nullptr); + avl = grpc_avl_add(avl, box(168), box(653), nullptr); + avl = remove_int(avl, 153); + avl = remove_int(avl, 239); + avl = grpc_avl_add(avl, box(684), box(656), nullptr); + avl = grpc_avl_add(avl, box(208), box(657), nullptr); + avl = grpc_avl_add(avl, box(681), box(658), nullptr); + avl = grpc_avl_add(avl, box(609), box(659), nullptr); + avl = grpc_avl_add(avl, box(645), box(660), nullptr); + avl = remove_int(avl, 799); + avl = grpc_avl_add(avl, box(955), box(662), nullptr); + avl = grpc_avl_add(avl, box(946), box(663), nullptr); + avl = grpc_avl_add(avl, box(744), box(664), nullptr); + avl = grpc_avl_add(avl, box(201), box(665), nullptr); + avl = grpc_avl_add(avl, box(136), box(666), nullptr); + avl = remove_int(avl, 357); + avl = grpc_avl_add(avl, box(974), box(668), nullptr); + avl = remove_int(avl, 485); + avl = grpc_avl_add(avl, box(1009), box(670), nullptr); + avl = grpc_avl_add(avl, box(517), box(671), nullptr); + avl = remove_int(avl, 491); + avl = grpc_avl_add(avl, box(336), box(673), nullptr); + avl = grpc_avl_add(avl, box(589), box(674), nullptr); + avl = remove_int(avl, 546); + avl = remove_int(avl, 840); + avl = remove_int(avl, 104); + avl = remove_int(avl, 347); + avl = grpc_avl_add(avl, box(801), box(679), nullptr); + avl = remove_int(avl, 799); + avl = remove_int(avl, 702); + avl = remove_int(avl, 996); + avl = remove_int(avl, 93); + avl = grpc_avl_add(avl, box(561), box(684), nullptr); + avl = grpc_avl_add(avl, box(25), box(685), nullptr); + avl = remove_int(avl, 278); + avl = grpc_avl_add(avl, box(191), box(687), nullptr); + avl = remove_int(avl, 243); + avl = remove_int(avl, 918); + avl = remove_int(avl, 449); + avl = grpc_avl_add(avl, box(19), box(691), nullptr); + avl = grpc_avl_add(avl, box(762), box(692), nullptr); + avl = grpc_avl_add(avl, box(13), box(693), nullptr); + avl = grpc_avl_add(avl, box(151), box(694), nullptr); + avl = grpc_avl_add(avl, box(152), box(695), nullptr); + avl = grpc_avl_add(avl, box(793), box(696), nullptr); + avl = remove_int(avl, 862); + avl = remove_int(avl, 890); + avl = grpc_avl_add(avl, box(687), box(699), nullptr); + avl = grpc_avl_add(avl, box(509), box(700), nullptr); + avl = grpc_avl_add(avl, box(973), box(701), nullptr); + avl = remove_int(avl, 230); + avl = grpc_avl_add(avl, box(532), box(703), nullptr); + avl = remove_int(avl, 668); + avl = grpc_avl_add(avl, box(281), box(705), nullptr); + avl = grpc_avl_add(avl, box(867), box(706), nullptr); + avl = grpc_avl_add(avl, box(359), box(707), nullptr); + avl = remove_int(avl, 425); + avl = grpc_avl_add(avl, box(691), box(709), nullptr); + avl = grpc_avl_add(avl, box(163), box(710), nullptr); + avl = grpc_avl_add(avl, box(502), box(711), nullptr); + avl = remove_int(avl, 674); + avl = grpc_avl_add(avl, box(697), box(713), nullptr); + avl = remove_int(avl, 271); + avl = grpc_avl_add(avl, box(968), box(715), nullptr); + avl = grpc_avl_add(avl, box(48), box(716), nullptr); + avl = remove_int(avl, 543); + avl = grpc_avl_add(avl, box(35), box(718), nullptr); + avl = grpc_avl_add(avl, box(751), box(719), nullptr); + avl = grpc_avl_add(avl, box(478), box(720), nullptr); + avl = remove_int(avl, 797); + avl = remove_int(avl, 309); + avl = grpc_avl_add(avl, box(927), box(723), nullptr); + avl = remove_int(avl, 504); + avl = grpc_avl_add(avl, box(286), box(725), nullptr); + avl = grpc_avl_add(avl, box(413), box(726), nullptr); + avl = grpc_avl_add(avl, box(599), box(727), nullptr); + avl = remove_int(avl, 105); + avl = remove_int(avl, 605); + avl = grpc_avl_add(avl, box(632), box(730), nullptr); + avl = grpc_avl_add(avl, box(133), box(731), nullptr); + avl = remove_int(avl, 443); + avl = grpc_avl_add(avl, box(958), box(733), nullptr); + avl = grpc_avl_add(avl, box(729), box(734), nullptr); + avl = remove_int(avl, 158); + avl = grpc_avl_add(avl, box(694), box(736), nullptr); + avl = grpc_avl_add(avl, box(505), box(737), nullptr); + avl = remove_int(avl, 63); + avl = remove_int(avl, 714); + avl = grpc_avl_add(avl, box(1002), box(740), nullptr); + avl = remove_int(avl, 211); + avl = grpc_avl_add(avl, box(765), box(742), nullptr); + avl = grpc_avl_add(avl, box(455), box(743), nullptr); + avl = remove_int(avl, 59); + avl = remove_int(avl, 224); + avl = grpc_avl_add(avl, box(586), box(746), nullptr); + avl = grpc_avl_add(avl, box(348), box(747), nullptr); + avl = remove_int(avl, 10); + avl = remove_int(avl, 484); + avl = grpc_avl_add(avl, box(968), box(750), nullptr); + avl = grpc_avl_add(avl, box(923), box(751), nullptr); + avl = remove_int(avl, 573); + avl = remove_int(avl, 617); + avl = grpc_avl_add(avl, box(812), box(754), nullptr); + avl = grpc_avl_add(avl, box(179), box(755), nullptr); + avl = remove_int(avl, 284); + avl = remove_int(avl, 157); + avl = remove_int(avl, 177); + avl = remove_int(avl, 896); + avl = grpc_avl_add(avl, box(649), box(760), nullptr); + avl = grpc_avl_add(avl, box(927), box(761), nullptr); + avl = grpc_avl_add(avl, box(454), box(762), nullptr); + avl = grpc_avl_add(avl, box(217), box(763), nullptr); + avl = remove_int(avl, 534); + avl = grpc_avl_add(avl, box(180), box(765), nullptr); + avl = grpc_avl_add(avl, box(319), box(766), nullptr); + avl = remove_int(avl, 92); + avl = grpc_avl_add(avl, box(483), box(768), nullptr); + avl = remove_int(avl, 504); + avl = remove_int(avl, 1017); + avl = remove_int(avl, 37); + avl = remove_int(avl, 50); + avl = grpc_avl_add(avl, box(302), box(773), nullptr); + avl = remove_int(avl, 807); + avl = grpc_avl_add(avl, box(463), box(775), nullptr); + avl = grpc_avl_add(avl, box(271), box(776), nullptr); + avl = grpc_avl_add(avl, box(644), box(777), nullptr); + avl = remove_int(avl, 618); + avl = grpc_avl_add(avl, box(166), box(779), nullptr); + avl = grpc_avl_add(avl, box(538), box(780), nullptr); + avl = remove_int(avl, 606); + avl = grpc_avl_add(avl, box(425), box(782), nullptr); + avl = remove_int(avl, 725); + avl = remove_int(avl, 383); + avl = grpc_avl_add(avl, box(155), box(785), nullptr); + avl = remove_int(avl, 889); + avl = grpc_avl_add(avl, box(653), box(787), nullptr); + avl = remove_int(avl, 386); + avl = grpc_avl_add(avl, box(142), box(789), nullptr); + avl = remove_int(avl, 107); + avl = remove_int(avl, 603); + avl = remove_int(avl, 971); + avl = grpc_avl_add(avl, box(80), box(793), nullptr); + avl = grpc_avl_add(avl, box(61), box(794), nullptr); + avl = grpc_avl_add(avl, box(693), box(795), nullptr); + avl = grpc_avl_add(avl, box(592), box(796), nullptr); + avl = grpc_avl_add(avl, box(433), box(797), nullptr); + avl = grpc_avl_add(avl, box(973), box(798), nullptr); + avl = remove_int(avl, 901); + avl = remove_int(avl, 340); + avl = remove_int(avl, 709); + avl = grpc_avl_add(avl, box(224), box(802), nullptr); + avl = remove_int(avl, 120); + avl = remove_int(avl, 271); + avl = grpc_avl_add(avl, box(780), box(805), nullptr); + avl = grpc_avl_add(avl, box(867), box(806), nullptr); + avl = grpc_avl_add(avl, box(756), box(807), nullptr); + avl = grpc_avl_add(avl, box(583), box(808), nullptr); + avl = grpc_avl_add(avl, box(356), box(809), nullptr); + avl = grpc_avl_add(avl, box(58), box(810), nullptr); + avl = remove_int(avl, 219); + avl = grpc_avl_add(avl, box(301), box(812), nullptr); + avl = remove_int(avl, 643); + avl = remove_int(avl, 787); + avl = remove_int(avl, 583); + avl = remove_int(avl, 552); + avl = remove_int(avl, 308); + avl = remove_int(avl, 608); + avl = remove_int(avl, 363); + avl = remove_int(avl, 690); + avl = grpc_avl_add(avl, box(233), box(821), nullptr); + avl = grpc_avl_add(avl, box(479), box(822), nullptr); + avl = grpc_avl_add(avl, box(323), box(823), nullptr); + avl = grpc_avl_add(avl, box(802), box(824), nullptr); + avl = remove_int(avl, 682); + avl = remove_int(avl, 705); + avl = remove_int(avl, 487); + avl = grpc_avl_add(avl, box(530), box(828), nullptr); + avl = grpc_avl_add(avl, box(232), box(829), nullptr); + avl = remove_int(avl, 627); + avl = grpc_avl_add(avl, box(396), box(831), nullptr); + avl = grpc_avl_add(avl, box(61), box(832), nullptr); + avl = grpc_avl_add(avl, box(932), box(833), nullptr); + avl = grpc_avl_add(avl, box(108), box(834), nullptr); + avl = grpc_avl_add(avl, box(524), box(835), nullptr); + avl = remove_int(avl, 390); + avl = remove_int(avl, 307); + avl = grpc_avl_add(avl, box(722), box(838), nullptr); + avl = grpc_avl_add(avl, box(907), box(839), nullptr); + avl = remove_int(avl, 286); + avl = remove_int(avl, 337); + avl = remove_int(avl, 443); + avl = grpc_avl_add(avl, box(973), box(843), nullptr); + avl = remove_int(avl, 930); + avl = remove_int(avl, 242); + avl = grpc_avl_add(avl, box(997), box(846), nullptr); + avl = grpc_avl_add(avl, box(689), box(847), nullptr); + avl = remove_int(avl, 318); + avl = grpc_avl_add(avl, box(703), box(849), nullptr); + avl = grpc_avl_add(avl, box(868), box(850), nullptr); + avl = grpc_avl_add(avl, box(200), box(851), nullptr); + avl = grpc_avl_add(avl, box(960), box(852), nullptr); + avl = grpc_avl_add(avl, box(80), box(853), nullptr); + avl = remove_int(avl, 113); + avl = grpc_avl_add(avl, box(135), box(855), nullptr); + avl = remove_int(avl, 529); + avl = grpc_avl_add(avl, box(366), box(857), nullptr); + avl = remove_int(avl, 272); + avl = grpc_avl_add(avl, box(921), box(859), nullptr); + avl = remove_int(avl, 497); + avl = grpc_avl_add(avl, box(712), box(861), nullptr); + avl = remove_int(avl, 777); + avl = remove_int(avl, 505); + avl = remove_int(avl, 974); + avl = remove_int(avl, 497); + avl = grpc_avl_add(avl, box(388), box(866), nullptr); + avl = grpc_avl_add(avl, box(29), box(867), nullptr); + avl = grpc_avl_add(avl, box(180), box(868), nullptr); + avl = grpc_avl_add(avl, box(983), box(869), nullptr); + avl = grpc_avl_add(avl, box(72), box(870), nullptr); + avl = grpc_avl_add(avl, box(693), box(871), nullptr); + avl = grpc_avl_add(avl, box(567), box(872), nullptr); + avl = remove_int(avl, 549); + avl = remove_int(avl, 351); + avl = grpc_avl_add(avl, box(1019), box(875), nullptr); + avl = remove_int(avl, 585); + avl = remove_int(avl, 294); + avl = remove_int(avl, 61); + avl = grpc_avl_add(avl, box(409), box(879), nullptr); + avl = grpc_avl_add(avl, box(984), box(880), nullptr); + avl = grpc_avl_add(avl, box(830), box(881), nullptr); + avl = remove_int(avl, 579); + avl = grpc_avl_add(avl, box(672), box(883), nullptr); + avl = remove_int(avl, 968); + + grpc_avl_unref(avl, nullptr); +} + +static void test_badcase3(void) { + grpc_avl avl; + + gpr_log(GPR_DEBUG, "test_badcase3"); + + avl = grpc_avl_create(&int_int_vtable); + avl = remove_int(avl, 624); + avl = grpc_avl_add(avl, box(59), box(2), nullptr); + avl = grpc_avl_add(avl, box(494), box(3), nullptr); + avl = grpc_avl_add(avl, box(226), box(4), nullptr); + avl = remove_int(avl, 524); + avl = grpc_avl_add(avl, box(540), box(6), nullptr); + avl = remove_int(avl, 1008); + avl = grpc_avl_add(avl, box(502), box(8), nullptr); + avl = remove_int(avl, 267); + avl = remove_int(avl, 764); + avl = remove_int(avl, 443); + avl = grpc_avl_add(avl, box(8), box(12), nullptr); + avl = remove_int(avl, 291); + avl = remove_int(avl, 796); + avl = remove_int(avl, 1002); + avl = grpc_avl_add(avl, box(778), box(16), nullptr); + avl = remove_int(avl, 621); + avl = remove_int(avl, 891); + avl = remove_int(avl, 880); + avl = grpc_avl_add(avl, box(197), box(20), nullptr); + avl = grpc_avl_add(avl, box(441), box(21), nullptr); + avl = grpc_avl_add(avl, box(719), box(22), nullptr); + avl = remove_int(avl, 109); + avl = grpc_avl_add(avl, box(458), box(24), nullptr); + avl = remove_int(avl, 86); + avl = grpc_avl_add(avl, box(897), box(26), nullptr); + avl = grpc_avl_add(avl, box(997), box(27), nullptr); + avl = remove_int(avl, 235); + avl = remove_int(avl, 425); + avl = remove_int(avl, 186); + avl = grpc_avl_add(avl, box(887), box(31), nullptr); + avl = grpc_avl_add(avl, box(1005), box(32), nullptr); + avl = grpc_avl_add(avl, box(778), box(33), nullptr); + avl = grpc_avl_add(avl, box(575), box(34), nullptr); + avl = remove_int(avl, 966); + avl = remove_int(avl, 1015); + avl = grpc_avl_add(avl, box(486), box(37), nullptr); + avl = grpc_avl_add(avl, box(809), box(38), nullptr); + avl = grpc_avl_add(avl, box(907), box(39), nullptr); + avl = grpc_avl_add(avl, box(971), box(40), nullptr); + avl = remove_int(avl, 441); + avl = remove_int(avl, 498); + avl = grpc_avl_add(avl, box(727), box(43), nullptr); + avl = remove_int(avl, 679); + avl = remove_int(avl, 740); + avl = remove_int(avl, 532); + avl = grpc_avl_add(avl, box(805), box(47), nullptr); + avl = remove_int(avl, 64); + avl = grpc_avl_add(avl, box(362), box(49), nullptr); + avl = grpc_avl_add(avl, box(170), box(50), nullptr); + avl = grpc_avl_add(avl, box(389), box(51), nullptr); + avl = grpc_avl_add(avl, box(689), box(52), nullptr); + avl = remove_int(avl, 871); + avl = grpc_avl_add(avl, box(447), box(54), nullptr); + avl = remove_int(avl, 718); + avl = grpc_avl_add(avl, box(724), box(56), nullptr); + avl = remove_int(avl, 215); + avl = grpc_avl_add(avl, box(550), box(58), nullptr); + avl = remove_int(avl, 932); + avl = grpc_avl_add(avl, box(47), box(60), nullptr); + avl = remove_int(avl, 46); + avl = remove_int(avl, 229); + avl = grpc_avl_add(avl, box(68), box(63), nullptr); + avl = grpc_avl_add(avl, box(387), box(64), nullptr); + avl = remove_int(avl, 933); + avl = remove_int(avl, 736); + avl = remove_int(avl, 719); + avl = grpc_avl_add(avl, box(150), box(68), nullptr); + avl = remove_int(avl, 875); + avl = remove_int(avl, 298); + avl = grpc_avl_add(avl, box(991), box(71), nullptr); + avl = remove_int(avl, 705); + avl = grpc_avl_add(avl, box(197), box(73), nullptr); + avl = grpc_avl_add(avl, box(101), box(74), nullptr); + avl = remove_int(avl, 436); + avl = grpc_avl_add(avl, box(755), box(76), nullptr); + avl = grpc_avl_add(avl, box(727), box(77), nullptr); + avl = remove_int(avl, 309); + avl = remove_int(avl, 253); + avl = grpc_avl_add(avl, box(203), box(80), nullptr); + avl = remove_int(avl, 231); + avl = grpc_avl_add(avl, box(461), box(82), nullptr); + avl = remove_int(avl, 316); + avl = remove_int(avl, 493); + avl = grpc_avl_add(avl, box(184), box(85), nullptr); + avl = remove_int(avl, 737); + avl = grpc_avl_add(avl, box(790), box(87), nullptr); + avl = grpc_avl_add(avl, box(335), box(88), nullptr); + avl = remove_int(avl, 649); + avl = grpc_avl_add(avl, box(69), box(90), nullptr); + avl = remove_int(avl, 585); + avl = remove_int(avl, 543); + avl = grpc_avl_add(avl, box(784), box(93), nullptr); + avl = grpc_avl_add(avl, box(60), box(94), nullptr); + avl = grpc_avl_add(avl, box(525), box(95), nullptr); + avl = grpc_avl_add(avl, box(177), box(96), nullptr); + avl = grpc_avl_add(avl, box(178), box(97), nullptr); + avl = grpc_avl_add(avl, box(683), box(98), nullptr); + avl = grpc_avl_add(avl, box(226), box(99), nullptr); + avl = grpc_avl_add(avl, box(662), box(100), nullptr); + avl = remove_int(avl, 944); + avl = grpc_avl_add(avl, box(562), box(102), nullptr); + avl = grpc_avl_add(avl, box(793), box(103), nullptr); + avl = remove_int(avl, 673); + avl = grpc_avl_add(avl, box(310), box(105), nullptr); + avl = remove_int(avl, 479); + avl = remove_int(avl, 543); + avl = remove_int(avl, 159); + avl = remove_int(avl, 850); + avl = grpc_avl_add(avl, box(318), box(110), nullptr); + avl = grpc_avl_add(avl, box(483), box(111), nullptr); + avl = grpc_avl_add(avl, box(84), box(112), nullptr); + avl = remove_int(avl, 109); + avl = grpc_avl_add(avl, box(132), box(114), nullptr); + avl = grpc_avl_add(avl, box(920), box(115), nullptr); + avl = remove_int(avl, 746); + avl = grpc_avl_add(avl, box(145), box(117), nullptr); + avl = grpc_avl_add(avl, box(526), box(118), nullptr); + avl = remove_int(avl, 158); + avl = grpc_avl_add(avl, box(332), box(120), nullptr); + avl = grpc_avl_add(avl, box(918), box(121), nullptr); + avl = remove_int(avl, 339); + avl = grpc_avl_add(avl, box(809), box(123), nullptr); + avl = grpc_avl_add(avl, box(742), box(124), nullptr); + avl = grpc_avl_add(avl, box(718), box(125), nullptr); + avl = remove_int(avl, 988); + avl = remove_int(avl, 531); + avl = remove_int(avl, 840); + avl = grpc_avl_add(avl, box(816), box(129), nullptr); + avl = grpc_avl_add(avl, box(976), box(130), nullptr); + avl = remove_int(avl, 743); + avl = remove_int(avl, 528); + avl = remove_int(avl, 982); + avl = grpc_avl_add(avl, box(803), box(134), nullptr); + avl = grpc_avl_add(avl, box(205), box(135), nullptr); + avl = grpc_avl_add(avl, box(584), box(136), nullptr); + avl = remove_int(avl, 923); + avl = remove_int(avl, 538); + avl = remove_int(avl, 398); + avl = remove_int(avl, 320); + avl = remove_int(avl, 292); + avl = grpc_avl_add(avl, box(270), box(142), nullptr); + avl = grpc_avl_add(avl, box(333), box(143), nullptr); + avl = remove_int(avl, 439); + avl = grpc_avl_add(avl, box(35), box(145), nullptr); + avl = grpc_avl_add(avl, box(837), box(146), nullptr); + avl = remove_int(avl, 65); + avl = remove_int(avl, 642); + avl = remove_int(avl, 371); + avl = remove_int(avl, 140); + avl = remove_int(avl, 533); + avl = remove_int(avl, 676); + avl = grpc_avl_add(avl, box(624), box(153), nullptr); + avl = grpc_avl_add(avl, box(116), box(154), nullptr); + avl = grpc_avl_add(avl, box(446), box(155), nullptr); + avl = remove_int(avl, 91); + avl = remove_int(avl, 721); + avl = remove_int(avl, 537); + avl = grpc_avl_add(avl, box(448), box(159), nullptr); + avl = remove_int(avl, 155); + avl = remove_int(avl, 344); + avl = remove_int(avl, 237); + avl = grpc_avl_add(avl, box(309), box(163), nullptr); + avl = grpc_avl_add(avl, box(434), box(164), nullptr); + avl = grpc_avl_add(avl, box(277), box(165), nullptr); + avl = remove_int(avl, 233); + avl = grpc_avl_add(avl, box(275), box(167), nullptr); + avl = grpc_avl_add(avl, box(218), box(168), nullptr); + avl = grpc_avl_add(avl, box(76), box(169), nullptr); + avl = grpc_avl_add(avl, box(898), box(170), nullptr); + avl = remove_int(avl, 771); + avl = grpc_avl_add(avl, box(237), box(172), nullptr); + avl = remove_int(avl, 327); + avl = grpc_avl_add(avl, box(499), box(174), nullptr); + avl = remove_int(avl, 727); + avl = remove_int(avl, 234); + avl = remove_int(avl, 623); + avl = remove_int(avl, 458); + avl = remove_int(avl, 326); + avl = remove_int(avl, 589); + avl = grpc_avl_add(avl, box(442), box(181), nullptr); + avl = remove_int(avl, 389); + avl = grpc_avl_add(avl, box(708), box(183), nullptr); + avl = grpc_avl_add(avl, box(594), box(184), nullptr); + avl = grpc_avl_add(avl, box(942), box(185), nullptr); + avl = grpc_avl_add(avl, box(282), box(186), nullptr); + avl = remove_int(avl, 434); + avl = remove_int(avl, 134); + avl = remove_int(avl, 270); + avl = remove_int(avl, 512); + avl = remove_int(avl, 265); + avl = remove_int(avl, 21); + avl = remove_int(avl, 193); + avl = remove_int(avl, 797); + avl = remove_int(avl, 347); + avl = grpc_avl_add(avl, box(99), box(196), nullptr); + avl = grpc_avl_add(avl, box(161), box(197), nullptr); + avl = remove_int(avl, 484); + avl = grpc_avl_add(avl, box(72), box(199), nullptr); + avl = remove_int(avl, 629); + avl = grpc_avl_add(avl, box(522), box(201), nullptr); + avl = remove_int(avl, 679); + avl = grpc_avl_add(avl, box(407), box(203), nullptr); + avl = remove_int(avl, 693); + avl = grpc_avl_add(avl, box(424), box(205), nullptr); + avl = grpc_avl_add(avl, box(651), box(206), nullptr); + avl = grpc_avl_add(avl, box(927), box(207), nullptr); + avl = remove_int(avl, 553); + avl = grpc_avl_add(avl, box(128), box(209), nullptr); + avl = grpc_avl_add(avl, box(616), box(210), nullptr); + avl = grpc_avl_add(avl, box(690), box(211), nullptr); + avl = remove_int(avl, 241); + avl = remove_int(avl, 179); + avl = grpc_avl_add(avl, box(697), box(214), nullptr); + avl = remove_int(avl, 779); + avl = grpc_avl_add(avl, box(241), box(216), nullptr); + avl = remove_int(avl, 190); + avl = remove_int(avl, 210); + avl = grpc_avl_add(avl, box(711), box(219), nullptr); + avl = remove_int(avl, 251); + avl = remove_int(avl, 61); + avl = grpc_avl_add(avl, box(800), box(222), nullptr); + avl = remove_int(avl, 551); + avl = grpc_avl_add(avl, box(61), box(224), nullptr); + avl = grpc_avl_add(avl, box(656), box(225), nullptr); + avl = remove_int(avl, 130); + avl = remove_int(avl, 368); + avl = remove_int(avl, 150); + avl = remove_int(avl, 73); + avl = grpc_avl_add(avl, box(799), box(230), nullptr); + avl = grpc_avl_add(avl, box(125), box(231), nullptr); + avl = remove_int(avl, 107); + avl = grpc_avl_add(avl, box(938), box(233), nullptr); + avl = grpc_avl_add(avl, box(914), box(234), nullptr); + avl = grpc_avl_add(avl, box(197), box(235), nullptr); + avl = remove_int(avl, 736); + avl = grpc_avl_add(avl, box(20), box(237), nullptr); + avl = remove_int(avl, 224); + avl = remove_int(avl, 841); + avl = grpc_avl_add(avl, box(226), box(240), nullptr); + avl = remove_int(avl, 963); + avl = remove_int(avl, 796); + avl = remove_int(avl, 728); + avl = grpc_avl_add(avl, box(855), box(244), nullptr); + avl = grpc_avl_add(avl, box(769), box(245), nullptr); + avl = grpc_avl_add(avl, box(631), box(246), nullptr); + avl = remove_int(avl, 648); + avl = grpc_avl_add(avl, box(187), box(248), nullptr); + avl = grpc_avl_add(avl, box(31), box(249), nullptr); + avl = remove_int(avl, 163); + avl = grpc_avl_add(avl, box(218), box(251), nullptr); + avl = grpc_avl_add(avl, box(488), box(252), nullptr); + avl = grpc_avl_add(avl, box(387), box(253), nullptr); + avl = grpc_avl_add(avl, box(809), box(254), nullptr); + avl = grpc_avl_add(avl, box(997), box(255), nullptr); + avl = remove_int(avl, 678); + avl = grpc_avl_add(avl, box(368), box(257), nullptr); + avl = grpc_avl_add(avl, box(220), box(258), nullptr); + avl = grpc_avl_add(avl, box(373), box(259), nullptr); + avl = remove_int(avl, 874); + avl = remove_int(avl, 682); + avl = remove_int(avl, 1014); + avl = remove_int(avl, 195); + avl = grpc_avl_add(avl, box(868), box(264), nullptr); + avl = remove_int(avl, 254); + avl = remove_int(avl, 456); + avl = grpc_avl_add(avl, box(906), box(267), nullptr); + avl = remove_int(avl, 711); + avl = grpc_avl_add(avl, box(632), box(269), nullptr); + avl = remove_int(avl, 474); + avl = grpc_avl_add(avl, box(508), box(271), nullptr); + avl = grpc_avl_add(avl, box(518), box(272), nullptr); + avl = remove_int(avl, 579); + avl = remove_int(avl, 948); + avl = grpc_avl_add(avl, box(789), box(275), nullptr); + avl = grpc_avl_add(avl, box(48), box(276), nullptr); + avl = grpc_avl_add(avl, box(256), box(277), nullptr); + avl = grpc_avl_add(avl, box(754), box(278), nullptr); + avl = remove_int(avl, 215); + avl = grpc_avl_add(avl, box(679), box(280), nullptr); + avl = grpc_avl_add(avl, box(606), box(281), nullptr); + avl = remove_int(avl, 941); + avl = remove_int(avl, 31); + avl = grpc_avl_add(avl, box(758), box(284), nullptr); + avl = remove_int(avl, 101); + avl = grpc_avl_add(avl, box(244), box(286), nullptr); + avl = grpc_avl_add(avl, box(337), box(287), nullptr); + avl = grpc_avl_add(avl, box(461), box(288), nullptr); + avl = remove_int(avl, 476); + avl = grpc_avl_add(avl, box(845), box(290), nullptr); + avl = remove_int(avl, 160); + avl = grpc_avl_add(avl, box(690), box(292), nullptr); + avl = remove_int(avl, 931); + avl = grpc_avl_add(avl, box(869), box(294), nullptr); + avl = grpc_avl_add(avl, box(1019), box(295), nullptr); + avl = remove_int(avl, 591); + avl = remove_int(avl, 635); + avl = remove_int(avl, 67); + avl = grpc_avl_add(avl, box(113), box(299), nullptr); + avl = remove_int(avl, 305); + avl = grpc_avl_add(avl, box(10), box(301), nullptr); + avl = remove_int(avl, 823); + avl = remove_int(avl, 288); + avl = remove_int(avl, 239); + avl = grpc_avl_add(avl, box(646), box(305), nullptr); + avl = grpc_avl_add(avl, box(1006), box(306), nullptr); + avl = grpc_avl_add(avl, box(954), box(307), nullptr); + avl = grpc_avl_add(avl, box(199), box(308), nullptr); + avl = grpc_avl_add(avl, box(69), box(309), nullptr); + avl = grpc_avl_add(avl, box(984), box(310), nullptr); + avl = remove_int(avl, 568); + avl = remove_int(avl, 666); + avl = remove_int(avl, 37); + avl = grpc_avl_add(avl, box(845), box(314), nullptr); + avl = remove_int(avl, 535); + avl = remove_int(avl, 365); + avl = remove_int(avl, 676); + avl = remove_int(avl, 892); + avl = remove_int(avl, 425); + avl = remove_int(avl, 704); + avl = remove_int(avl, 168); + avl = grpc_avl_add(avl, box(853), box(322), nullptr); + avl = grpc_avl_add(avl, box(335), box(323), nullptr); + avl = grpc_avl_add(avl, box(961), box(324), nullptr); + avl = grpc_avl_add(avl, box(73), box(325), nullptr); + avl = remove_int(avl, 469); + avl = grpc_avl_add(avl, box(449), box(327), nullptr); + avl = remove_int(avl, 821); + avl = grpc_avl_add(avl, box(845), box(329), nullptr); + avl = remove_int(avl, 637); + avl = grpc_avl_add(avl, box(769), box(331), nullptr); + avl = grpc_avl_add(avl, box(901), box(332), nullptr); + avl = remove_int(avl, 142); + avl = remove_int(avl, 361); + avl = remove_int(avl, 876); + avl = grpc_avl_add(avl, box(614), box(336), nullptr); + avl = grpc_avl_add(avl, box(729), box(337), nullptr); + avl = remove_int(avl, 120); + avl = remove_int(avl, 473); + avl = remove_int(avl, 445); + avl = grpc_avl_add(avl, box(978), box(341), nullptr); + avl = grpc_avl_add(avl, box(164), box(342), nullptr); + avl = grpc_avl_add(avl, box(1), box(343), nullptr); + avl = remove_int(avl, 890); + avl = grpc_avl_add(avl, box(605), box(345), nullptr); + avl = grpc_avl_add(avl, box(178), box(346), nullptr); + avl = grpc_avl_add(avl, box(481), box(347), nullptr); + avl = grpc_avl_add(avl, box(772), box(348), nullptr); + avl = remove_int(avl, 824); + avl = remove_int(avl, 167); + avl = remove_int(avl, 151); + avl = grpc_avl_add(avl, box(698), box(352), nullptr); + avl = grpc_avl_add(avl, box(202), box(353), nullptr); + avl = grpc_avl_add(avl, box(921), box(354), nullptr); + avl = grpc_avl_add(avl, box(875), box(355), nullptr); + avl = remove_int(avl, 197); + avl = remove_int(avl, 232); + avl = grpc_avl_add(avl, box(209), box(358), nullptr); + avl = remove_int(avl, 324); + avl = remove_int(avl, 56); + avl = remove_int(avl, 579); + avl = remove_int(avl, 255); + avl = remove_int(avl, 290); + avl = grpc_avl_add(avl, box(661), box(364), nullptr); + avl = grpc_avl_add(avl, box(113), box(365), nullptr); + avl = remove_int(avl, 767); + avl = grpc_avl_add(avl, box(586), box(367), nullptr); + avl = grpc_avl_add(avl, box(121), box(368), nullptr); + avl = remove_int(avl, 235); + avl = remove_int(avl, 439); + avl = remove_int(avl, 360); + avl = grpc_avl_add(avl, box(916), box(372), nullptr); + avl = remove_int(avl, 999); + avl = grpc_avl_add(avl, box(825), box(374), nullptr); + avl = grpc_avl_add(avl, box(177), box(375), nullptr); + avl = remove_int(avl, 204); + avl = remove_int(avl, 92); + avl = grpc_avl_add(avl, box(794), box(378), nullptr); + avl = grpc_avl_add(avl, box(463), box(379), nullptr); + avl = grpc_avl_add(avl, box(472), box(380), nullptr); + avl = remove_int(avl, 235); + avl = grpc_avl_add(avl, box(840), box(382), nullptr); + avl = remove_int(avl, 657); + avl = grpc_avl_add(avl, box(586), box(384), nullptr); + avl = grpc_avl_add(avl, box(979), box(385), nullptr); + avl = remove_int(avl, 979); + avl = grpc_avl_add(avl, box(639), box(387), nullptr); + avl = remove_int(avl, 907); + avl = remove_int(avl, 973); + avl = grpc_avl_add(avl, box(913), box(390), nullptr); + avl = grpc_avl_add(avl, box(566), box(391), nullptr); + avl = grpc_avl_add(avl, box(883), box(392), nullptr); + avl = grpc_avl_add(avl, box(552), box(393), nullptr); + avl = grpc_avl_add(avl, box(16), box(394), nullptr); + avl = remove_int(avl, 60); + avl = grpc_avl_add(avl, box(567), box(396), nullptr); + avl = grpc_avl_add(avl, box(705), box(397), nullptr); + avl = grpc_avl_add(avl, box(94), box(398), nullptr); + avl = remove_int(avl, 321); + avl = grpc_avl_add(avl, box(207), box(400), nullptr); + avl = grpc_avl_add(avl, box(682), box(401), nullptr); + avl = grpc_avl_add(avl, box(592), box(402), nullptr); + avl = grpc_avl_add(avl, box(10), box(403), nullptr); + avl = remove_int(avl, 911); + avl = remove_int(avl, 161); + avl = grpc_avl_add(avl, box(86), box(406), nullptr); + avl = remove_int(avl, 893); + avl = remove_int(avl, 362); + avl = grpc_avl_add(avl, box(599), box(409), nullptr); + avl = remove_int(avl, 413); + avl = grpc_avl_add(avl, box(867), box(411), nullptr); + avl = remove_int(avl, 955); + avl = grpc_avl_add(avl, box(341), box(413), nullptr); + avl = grpc_avl_add(avl, box(887), box(414), nullptr); + avl = remove_int(avl, 706); + avl = grpc_avl_add(avl, box(939), box(416), nullptr); + avl = remove_int(avl, 233); + avl = remove_int(avl, 662); + avl = remove_int(avl, 984); + avl = remove_int(avl, 203); + avl = grpc_avl_add(avl, box(326), box(421), nullptr); + avl = remove_int(avl, 848); + avl = grpc_avl_add(avl, box(235), box(423), nullptr); + avl = remove_int(avl, 617); + avl = grpc_avl_add(avl, box(565), box(425), nullptr); + avl = remove_int(avl, 469); + avl = grpc_avl_add(avl, box(988), box(427), nullptr); + avl = remove_int(avl, 957); + avl = grpc_avl_add(avl, box(426), box(429), nullptr); + avl = remove_int(avl, 967); + avl = grpc_avl_add(avl, box(890), box(431), nullptr); + avl = grpc_avl_add(avl, box(473), box(432), nullptr); + avl = remove_int(avl, 367); + avl = remove_int(avl, 344); + avl = remove_int(avl, 660); + avl = remove_int(avl, 448); + avl = remove_int(avl, 837); + avl = remove_int(avl, 158); + avl = grpc_avl_add(avl, box(459), box(439), nullptr); + avl = remove_int(avl, 882); + avl = remove_int(avl, 782); + avl = grpc_avl_add(avl, box(408), box(442), nullptr); + avl = grpc_avl_add(avl, box(728), box(443), nullptr); + avl = remove_int(avl, 27); + avl = grpc_avl_add(avl, box(137), box(445), nullptr); + avl = grpc_avl_add(avl, box(239), box(446), nullptr); + avl = remove_int(avl, 854); + avl = grpc_avl_add(avl, box(104), box(448), nullptr); + avl = grpc_avl_add(avl, box(823), box(449), nullptr); + avl = grpc_avl_add(avl, box(524), box(450), nullptr); + avl = grpc_avl_add(avl, box(995), box(451), nullptr); + avl = remove_int(avl, 422); + avl = remove_int(avl, 220); + avl = grpc_avl_add(avl, box(856), box(454), nullptr); + avl = remove_int(avl, 332); + avl = grpc_avl_add(avl, box(679), box(456), nullptr); + avl = remove_int(avl, 18); + avl = grpc_avl_add(avl, box(837), box(458), nullptr); + avl = remove_int(avl, 405); + avl = remove_int(avl, 877); + avl = remove_int(avl, 835); + avl = grpc_avl_add(avl, box(547), box(462), nullptr); + avl = remove_int(avl, 805); + avl = remove_int(avl, 862); + avl = grpc_avl_add(avl, box(75), box(465), nullptr); + avl = remove_int(avl, 41); + avl = grpc_avl_add(avl, box(310), box(467), nullptr); + avl = remove_int(avl, 855); + avl = grpc_avl_add(avl, box(20), box(469), nullptr); + avl = remove_int(avl, 186); + avl = remove_int(avl, 378); + avl = remove_int(avl, 442); + avl = remove_int(avl, 930); + avl = grpc_avl_add(avl, box(118), box(474), nullptr); + avl = grpc_avl_add(avl, box(96), box(475), nullptr); + avl = remove_int(avl, 854); + avl = grpc_avl_add(avl, box(65), box(477), nullptr); + avl = grpc_avl_add(avl, box(573), box(478), nullptr); + avl = grpc_avl_add(avl, box(4), box(479), nullptr); + avl = grpc_avl_add(avl, box(451), box(480), nullptr); + avl = grpc_avl_add(avl, box(774), box(481), nullptr); + avl = grpc_avl_add(avl, box(126), box(482), nullptr); + avl = remove_int(avl, 956); + avl = remove_int(avl, 591); + avl = remove_int(avl, 644); + avl = grpc_avl_add(avl, box(304), box(486), nullptr); + avl = remove_int(avl, 620); + avl = remove_int(avl, 394); + avl = grpc_avl_add(avl, box(1002), box(489), nullptr); + avl = grpc_avl_add(avl, box(837), box(490), nullptr); + avl = remove_int(avl, 485); + avl = grpc_avl_add(avl, box(1005), box(492), nullptr); + avl = remove_int(avl, 21); + avl = grpc_avl_add(avl, box(396), box(494), nullptr); + avl = remove_int(avl, 966); + avl = grpc_avl_add(avl, box(105), box(496), nullptr); + avl = grpc_avl_add(avl, box(316), box(497), nullptr); + avl = remove_int(avl, 776); + avl = grpc_avl_add(avl, box(188), box(499), nullptr); + avl = remove_int(avl, 200); + avl = grpc_avl_add(avl, box(98), box(501), nullptr); + avl = grpc_avl_add(avl, box(831), box(502), nullptr); + avl = grpc_avl_add(avl, box(227), box(503), nullptr); + avl = grpc_avl_add(avl, box(220), box(504), nullptr); + avl = remove_int(avl, 715); + avl = remove_int(avl, 279); + avl = grpc_avl_add(avl, box(701), box(507), nullptr); + avl = grpc_avl_add(avl, box(726), box(508), nullptr); + avl = grpc_avl_add(avl, box(815), box(509), nullptr); + avl = grpc_avl_add(avl, box(749), box(510), nullptr); + avl = remove_int(avl, 946); + avl = remove_int(avl, 449); + avl = remove_int(avl, 62); + avl = remove_int(avl, 487); + avl = grpc_avl_add(avl, box(545), box(515), nullptr); + avl = remove_int(avl, 59); + avl = grpc_avl_add(avl, box(168), box(517), nullptr); + avl = remove_int(avl, 337); + avl = grpc_avl_add(avl, box(69), box(519), nullptr); + avl = remove_int(avl, 600); + avl = grpc_avl_add(avl, box(591), box(521), nullptr); + avl = grpc_avl_add(avl, box(960), box(522), nullptr); + avl = grpc_avl_add(avl, box(116), box(523), nullptr); + avl = remove_int(avl, 991); + avl = grpc_avl_add(avl, box(760), box(525), nullptr); + avl = grpc_avl_add(avl, box(664), box(526), nullptr); + avl = grpc_avl_add(avl, box(547), box(527), nullptr); + avl = remove_int(avl, 922); + avl = grpc_avl_add(avl, box(290), box(529), nullptr); + avl = grpc_avl_add(avl, box(859), box(530), nullptr); + avl = grpc_avl_add(avl, box(49), box(531), nullptr); + avl = remove_int(avl, 455); + avl = remove_int(avl, 786); + avl = grpc_avl_add(avl, box(613), box(534), nullptr); + avl = grpc_avl_add(avl, box(326), box(535), nullptr); + avl = remove_int(avl, 615); + avl = grpc_avl_add(avl, box(45), box(537), nullptr); + avl = grpc_avl_add(avl, box(162), box(538), nullptr); + avl = grpc_avl_add(avl, box(189), box(539), nullptr); + avl = remove_int(avl, 68); + avl = remove_int(avl, 846); + avl = grpc_avl_add(avl, box(608), box(542), nullptr); + avl = remove_int(avl, 821); + avl = grpc_avl_add(avl, box(978), box(544), nullptr); + avl = grpc_avl_add(avl, box(892), box(545), nullptr); + avl = remove_int(avl, 924); + avl = grpc_avl_add(avl, box(708), box(547), nullptr); + avl = remove_int(avl, 135); + avl = remove_int(avl, 124); + avl = grpc_avl_add(avl, box(301), box(550), nullptr); + avl = grpc_avl_add(avl, box(939), box(551), nullptr); + avl = grpc_avl_add(avl, box(344), box(552), nullptr); + avl = remove_int(avl, 443); + avl = remove_int(avl, 122); + avl = grpc_avl_add(avl, box(636), box(555), nullptr); + avl = remove_int(avl, 558); + avl = grpc_avl_add(avl, box(923), box(557), nullptr); + avl = remove_int(avl, 827); + avl = grpc_avl_add(avl, box(649), box(559), nullptr); + avl = grpc_avl_add(avl, box(808), box(560), nullptr); + avl = remove_int(avl, 570); + avl = remove_int(avl, 434); + avl = grpc_avl_add(avl, box(40), box(563), nullptr); + avl = grpc_avl_add(avl, box(725), box(564), nullptr); + avl = remove_int(avl, 295); + avl = remove_int(avl, 615); + avl = remove_int(avl, 919); + avl = remove_int(avl, 170); + avl = remove_int(avl, 442); + avl = remove_int(avl, 971); + avl = grpc_avl_add(avl, box(483), box(571), nullptr); + avl = grpc_avl_add(avl, box(512), box(572), nullptr); + avl = remove_int(avl, 648); + avl = remove_int(avl, 78); + avl = remove_int(avl, 72); + avl = remove_int(avl, 790); + avl = remove_int(avl, 571); + avl = grpc_avl_add(avl, box(898), box(578), nullptr); + avl = remove_int(avl, 770); + avl = remove_int(avl, 776); + avl = grpc_avl_add(avl, box(602), box(581), nullptr); + avl = remove_int(avl, 251); + avl = grpc_avl_add(avl, box(303), box(583), nullptr); + avl = remove_int(avl, 837); + avl = grpc_avl_add(avl, box(714), box(585), nullptr); + avl = remove_int(avl, 800); + avl = grpc_avl_add(avl, box(266), box(587), nullptr); + avl = grpc_avl_add(avl, box(555), box(588), nullptr); + avl = remove_int(avl, 604); + avl = remove_int(avl, 163); + avl = remove_int(avl, 497); + avl = grpc_avl_add(avl, box(296), box(592), nullptr); + avl = remove_int(avl, 129); + avl = grpc_avl_add(avl, box(656), box(594), nullptr); + avl = remove_int(avl, 769); + avl = remove_int(avl, 941); + avl = grpc_avl_add(avl, box(775), box(597), nullptr); + avl = grpc_avl_add(avl, box(846), box(598), nullptr); + avl = remove_int(avl, 591); + avl = remove_int(avl, 801); + avl = remove_int(avl, 419); + avl = remove_int(avl, 455); + avl = grpc_avl_add(avl, box(866), box(603), nullptr); + avl = grpc_avl_add(avl, box(575), box(604), nullptr); + avl = grpc_avl_add(avl, box(620), box(605), nullptr); + avl = remove_int(avl, 100); + avl = remove_int(avl, 667); + avl = grpc_avl_add(avl, box(138), box(608), nullptr); + avl = grpc_avl_add(avl, box(566), box(609), nullptr); + avl = grpc_avl_add(avl, box(673), box(610), nullptr); + avl = grpc_avl_add(avl, box(178), box(611), nullptr); + avl = remove_int(avl, 659); + avl = grpc_avl_add(avl, box(759), box(613), nullptr); + avl = grpc_avl_add(avl, box(1008), box(614), nullptr); + avl = remove_int(avl, 116); + avl = grpc_avl_add(avl, box(608), box(616), nullptr); + avl = grpc_avl_add(avl, box(339), box(617), nullptr); + avl = grpc_avl_add(avl, box(197), box(618), nullptr); + avl = remove_int(avl, 25); + avl = remove_int(avl, 628); + avl = grpc_avl_add(avl, box(487), box(621), nullptr); + avl = remove_int(avl, 739); + avl = remove_int(avl, 100); + avl = remove_int(avl, 928); + avl = grpc_avl_add(avl, box(647), box(625), nullptr); + avl = remove_int(avl, 978); + avl = remove_int(avl, 143); + avl = remove_int(avl, 755); + avl = grpc_avl_add(avl, box(71), box(629), nullptr); + avl = remove_int(avl, 205); + avl = grpc_avl_add(avl, box(501), box(631), nullptr); + avl = remove_int(avl, 723); + avl = remove_int(avl, 852); + avl = remove_int(avl, 1021); + avl = remove_int(avl, 670); + avl = remove_int(avl, 500); + avl = grpc_avl_add(avl, box(330), box(637), nullptr); + avl = remove_int(avl, 264); + avl = grpc_avl_add(avl, box(69), box(639), nullptr); + avl = remove_int(avl, 73); + avl = grpc_avl_add(avl, box(745), box(641), nullptr); + avl = remove_int(avl, 518); + avl = remove_int(avl, 641); + avl = remove_int(avl, 768); + avl = grpc_avl_add(avl, box(988), box(645), nullptr); + avl = grpc_avl_add(avl, box(899), box(646), nullptr); + avl = remove_int(avl, 763); + avl = remove_int(avl, 281); + avl = remove_int(avl, 496); + avl = grpc_avl_add(avl, box(445), box(650), nullptr); + avl = remove_int(avl, 905); + avl = grpc_avl_add(avl, box(275), box(652), nullptr); + avl = grpc_avl_add(avl, box(137), box(653), nullptr); + avl = remove_int(avl, 642); + avl = grpc_avl_add(avl, box(708), box(655), nullptr); + avl = remove_int(avl, 922); + avl = grpc_avl_add(avl, box(743), box(657), nullptr); + avl = remove_int(avl, 295); + avl = remove_int(avl, 665); + avl = remove_int(avl, 48); + avl = grpc_avl_add(avl, box(1012), box(661), nullptr); + avl = remove_int(avl, 71); + avl = remove_int(avl, 523); + avl = grpc_avl_add(avl, box(319), box(664), nullptr); + avl = remove_int(avl, 632); + avl = grpc_avl_add(avl, box(137), box(666), nullptr); + avl = grpc_avl_add(avl, box(686), box(667), nullptr); + avl = grpc_avl_add(avl, box(724), box(668), nullptr); + avl = grpc_avl_add(avl, box(952), box(669), nullptr); + avl = grpc_avl_add(avl, box(5), box(670), nullptr); + avl = remove_int(avl, 35); + avl = grpc_avl_add(avl, box(43), box(672), nullptr); + avl = grpc_avl_add(avl, box(320), box(673), nullptr); + avl = grpc_avl_add(avl, box(115), box(674), nullptr); + avl = remove_int(avl, 377); + avl = remove_int(avl, 591); + avl = remove_int(avl, 87); + avl = remove_int(avl, 93); + avl = grpc_avl_add(avl, box(1016), box(679), nullptr); + avl = grpc_avl_add(avl, box(605), box(680), nullptr); + avl = grpc_avl_add(avl, box(152), box(681), nullptr); + avl = grpc_avl_add(avl, box(113), box(682), nullptr); + avl = remove_int(avl, 131); + avl = remove_int(avl, 637); + avl = grpc_avl_add(avl, box(156), box(685), nullptr); + avl = remove_int(avl, 696); + avl = grpc_avl_add(avl, box(546), box(687), nullptr); + avl = remove_int(avl, 970); + avl = remove_int(avl, 53); + avl = remove_int(avl, 827); + avl = remove_int(avl, 224); + avl = remove_int(avl, 796); + avl = remove_int(avl, 34); + avl = remove_int(avl, 922); + avl = remove_int(avl, 277); + avl = remove_int(avl, 650); + avl = remove_int(avl, 222); + avl = remove_int(avl, 244); + avl = remove_int(avl, 576); + avl = remove_int(avl, 413); + avl = grpc_avl_add(avl, box(500), box(701), nullptr); + avl = remove_int(avl, 924); + avl = grpc_avl_add(avl, box(825), box(703), nullptr); + avl = remove_int(avl, 888); + avl = remove_int(avl, 931); + avl = grpc_avl_add(avl, box(285), box(706), nullptr); + avl = remove_int(avl, 62); + avl = remove_int(avl, 444); + avl = remove_int(avl, 946); + avl = grpc_avl_add(avl, box(122), box(710), nullptr); + avl = grpc_avl_add(avl, box(846), box(711), nullptr); + avl = remove_int(avl, 628); + avl = grpc_avl_add(avl, box(511), box(713), nullptr); + avl = grpc_avl_add(avl, box(398), box(714), nullptr); + avl = remove_int(avl, 730); + avl = grpc_avl_add(avl, box(797), box(716), nullptr); + avl = remove_int(avl, 897); + avl = remove_int(avl, 228); + avl = remove_int(avl, 544); + avl = remove_int(avl, 552); + avl = remove_int(avl, 783); + avl = remove_int(avl, 583); + avl = remove_int(avl, 894); + avl = remove_int(avl, 942); + avl = grpc_avl_add(avl, box(346), box(725), nullptr); + avl = grpc_avl_add(avl, box(1015), box(726), nullptr); + avl = remove_int(avl, 813); + avl = grpc_avl_add(avl, box(213), box(728), nullptr); + avl = remove_int(avl, 468); + avl = remove_int(avl, 365); + avl = remove_int(avl, 399); + avl = grpc_avl_add(avl, box(380), box(732), nullptr); + avl = remove_int(avl, 835); + avl = remove_int(avl, 970); + avl = grpc_avl_add(avl, box(700), box(735), nullptr); + avl = grpc_avl_add(avl, box(807), box(736), nullptr); + avl = remove_int(avl, 312); + avl = remove_int(avl, 282); + avl = remove_int(avl, 370); + avl = remove_int(avl, 999); + avl = remove_int(avl, 241); + avl = remove_int(avl, 884); + avl = grpc_avl_add(avl, box(587), box(743), nullptr); + avl = grpc_avl_add(avl, box(332), box(744), nullptr); + avl = remove_int(avl, 686); + avl = remove_int(avl, 206); + avl = remove_int(avl, 835); + avl = grpc_avl_add(avl, box(334), box(748), nullptr); + avl = remove_int(avl, 171); + avl = grpc_avl_add(avl, box(1002), box(750), nullptr); + avl = grpc_avl_add(avl, box(779), box(751), nullptr); + avl = grpc_avl_add(avl, box(307), box(752), nullptr); + avl = grpc_avl_add(avl, box(127), box(753), nullptr); + avl = grpc_avl_add(avl, box(251), box(754), nullptr); + avl = remove_int(avl, 790); + avl = remove_int(avl, 189); + avl = remove_int(avl, 193); + avl = remove_int(avl, 38); + avl = remove_int(avl, 124); + avl = grpc_avl_add(avl, box(812), box(760), nullptr); + avl = remove_int(avl, 43); + avl = grpc_avl_add(avl, box(871), box(762), nullptr); + avl = grpc_avl_add(avl, box(580), box(763), nullptr); + avl = remove_int(avl, 501); + avl = remove_int(avl, 462); + avl = remove_int(avl, 599); + avl = grpc_avl_add(avl, box(240), box(767), nullptr); + avl = grpc_avl_add(avl, box(285), box(768), nullptr); + avl = grpc_avl_add(avl, box(472), box(769), nullptr); + avl = remove_int(avl, 865); + avl = remove_int(avl, 763); + avl = remove_int(avl, 245); + avl = remove_int(avl, 80); + avl = remove_int(avl, 713); + avl = remove_int(avl, 654); + avl = remove_int(avl, 1014); + avl = grpc_avl_add(avl, box(495), box(777), nullptr); + avl = grpc_avl_add(avl, box(552), box(778), nullptr); + avl = remove_int(avl, 19); + avl = remove_int(avl, 803); + avl = grpc_avl_add(avl, box(508), box(781), nullptr); + avl = remove_int(avl, 699); + avl = remove_int(avl, 260); + avl = remove_int(avl, 92); + avl = remove_int(avl, 497); + avl = grpc_avl_add(avl, box(970), box(786), nullptr); + avl = remove_int(avl, 987); + avl = remove_int(avl, 168); + avl = remove_int(avl, 476); + avl = remove_int(avl, 248); + avl = grpc_avl_add(avl, box(358), box(791), nullptr); + avl = remove_int(avl, 804); + avl = remove_int(avl, 77); + avl = remove_int(avl, 905); + avl = remove_int(avl, 362); + avl = grpc_avl_add(avl, box(578), box(796), nullptr); + avl = remove_int(avl, 38); + avl = remove_int(avl, 595); + avl = grpc_avl_add(avl, box(213), box(799), nullptr); + avl = remove_int(avl, 7); + avl = remove_int(avl, 620); + avl = grpc_avl_add(avl, box(946), box(802), nullptr); + avl = remove_int(avl, 145); + avl = grpc_avl_add(avl, box(628), box(804), nullptr); + avl = remove_int(avl, 972); + avl = grpc_avl_add(avl, box(728), box(806), nullptr); + avl = remove_int(avl, 91); + avl = grpc_avl_add(avl, box(136), box(808), nullptr); + avl = grpc_avl_add(avl, box(841), box(809), nullptr); + avl = grpc_avl_add(avl, box(265), box(810), nullptr); + avl = grpc_avl_add(avl, box(701), box(811), nullptr); + avl = grpc_avl_add(avl, box(27), box(812), nullptr); + avl = remove_int(avl, 72); + avl = remove_int(avl, 14); + avl = grpc_avl_add(avl, box(286), box(815), nullptr); + avl = remove_int(avl, 996); + avl = remove_int(avl, 998); + avl = grpc_avl_add(avl, box(466), box(818), nullptr); + avl = remove_int(avl, 1009); + avl = remove_int(avl, 741); + avl = remove_int(avl, 947); + avl = remove_int(avl, 241); + avl = remove_int(avl, 954); + avl = remove_int(avl, 183); + avl = remove_int(avl, 395); + avl = remove_int(avl, 951); + avl = grpc_avl_add(avl, box(267), box(827), nullptr); + avl = remove_int(avl, 812); + avl = grpc_avl_add(avl, box(577), box(829), nullptr); + avl = remove_int(avl, 624); + avl = remove_int(avl, 847); + avl = remove_int(avl, 745); + avl = grpc_avl_add(avl, box(491), box(833), nullptr); + avl = grpc_avl_add(avl, box(941), box(834), nullptr); + avl = remove_int(avl, 258); + avl = grpc_avl_add(avl, box(410), box(836), nullptr); + avl = grpc_avl_add(avl, box(80), box(837), nullptr); + avl = grpc_avl_add(avl, box(196), box(838), nullptr); + avl = grpc_avl_add(avl, box(5), box(839), nullptr); + avl = remove_int(avl, 782); + avl = grpc_avl_add(avl, box(827), box(841), nullptr); + avl = remove_int(avl, 472); + avl = remove_int(avl, 664); + avl = grpc_avl_add(avl, box(409), box(844), nullptr); + avl = grpc_avl_add(avl, box(62), box(845), nullptr); + avl = remove_int(avl, 56); + avl = remove_int(avl, 606); + avl = remove_int(avl, 707); + avl = remove_int(avl, 989); + avl = remove_int(avl, 549); + avl = remove_int(avl, 259); + avl = grpc_avl_add(avl, box(405), box(852), nullptr); + avl = remove_int(avl, 587); + avl = remove_int(avl, 350); + avl = grpc_avl_add(avl, box(980), box(855), nullptr); + avl = grpc_avl_add(avl, box(992), box(856), nullptr); + avl = grpc_avl_add(avl, box(818), box(857), nullptr); + avl = remove_int(avl, 853); + avl = remove_int(avl, 701); + avl = grpc_avl_add(avl, box(675), box(860), nullptr); + avl = remove_int(avl, 248); + avl = remove_int(avl, 649); + avl = grpc_avl_add(avl, box(508), box(863), nullptr); + avl = remove_int(avl, 927); + avl = grpc_avl_add(avl, box(957), box(865), nullptr); + avl = grpc_avl_add(avl, box(698), box(866), nullptr); + avl = grpc_avl_add(avl, box(388), box(867), nullptr); + avl = grpc_avl_add(avl, box(532), box(868), nullptr); + avl = grpc_avl_add(avl, box(681), box(869), nullptr); + avl = remove_int(avl, 544); + avl = remove_int(avl, 991); + avl = remove_int(avl, 397); + avl = grpc_avl_add(avl, box(954), box(873), nullptr); + avl = grpc_avl_add(avl, box(219), box(874), nullptr); + avl = grpc_avl_add(avl, box(465), box(875), nullptr); + avl = remove_int(avl, 371); + avl = grpc_avl_add(avl, box(601), box(877), nullptr); + avl = grpc_avl_add(avl, box(543), box(878), nullptr); + avl = remove_int(avl, 329); + avl = grpc_avl_add(avl, box(560), box(880), nullptr); + avl = remove_int(avl, 898); + avl = grpc_avl_add(avl, box(455), box(882), nullptr); + avl = remove_int(avl, 313); + avl = grpc_avl_add(avl, box(215), box(884), nullptr); + avl = remove_int(avl, 846); + avl = grpc_avl_add(avl, box(608), box(886), nullptr); + avl = remove_int(avl, 248); + avl = grpc_avl_add(avl, box(575), box(888), nullptr); + avl = remove_int(avl, 207); + avl = remove_int(avl, 810); + avl = remove_int(avl, 665); + avl = remove_int(avl, 361); + avl = grpc_avl_add(avl, box(154), box(893), nullptr); + avl = grpc_avl_add(avl, box(329), box(894), nullptr); + avl = grpc_avl_add(avl, box(326), box(895), nullptr); + avl = remove_int(avl, 746); + avl = remove_int(avl, 99); + avl = grpc_avl_add(avl, box(464), box(898), nullptr); + avl = grpc_avl_add(avl, box(141), box(899), nullptr); + avl = remove_int(avl, 383); + avl = grpc_avl_add(avl, box(414), box(901), nullptr); + avl = grpc_avl_add(avl, box(777), box(902), nullptr); + avl = remove_int(avl, 972); + avl = remove_int(avl, 841); + avl = remove_int(avl, 100); + avl = grpc_avl_add(avl, box(828), box(906), nullptr); + avl = remove_int(avl, 785); + avl = grpc_avl_add(avl, box(1008), box(908), nullptr); + avl = grpc_avl_add(avl, box(46), box(909), nullptr); + avl = remove_int(avl, 399); + avl = grpc_avl_add(avl, box(178), box(911), nullptr); + avl = grpc_avl_add(avl, box(573), box(912), nullptr); + avl = remove_int(avl, 299); + avl = grpc_avl_add(avl, box(690), box(914), nullptr); + avl = grpc_avl_add(avl, box(692), box(915), nullptr); + avl = remove_int(avl, 404); + avl = remove_int(avl, 16); + avl = remove_int(avl, 746); + avl = remove_int(avl, 486); + avl = remove_int(avl, 119); + avl = grpc_avl_add(avl, box(167), box(921), nullptr); + avl = remove_int(avl, 328); + avl = grpc_avl_add(avl, box(89), box(923), nullptr); + avl = remove_int(avl, 867); + avl = remove_int(avl, 626); + avl = remove_int(avl, 507); + avl = grpc_avl_add(avl, box(365), box(927), nullptr); + avl = grpc_avl_add(avl, box(58), box(928), nullptr); + avl = grpc_avl_add(avl, box(70), box(929), nullptr); + avl = remove_int(avl, 81); + avl = remove_int(avl, 797); + avl = grpc_avl_add(avl, box(846), box(932), nullptr); + avl = remove_int(avl, 642); + avl = grpc_avl_add(avl, box(777), box(934), nullptr); + avl = remove_int(avl, 107); + avl = grpc_avl_add(avl, box(691), box(936), nullptr); + avl = grpc_avl_add(avl, box(820), box(937), nullptr); + avl = grpc_avl_add(avl, box(202), box(938), nullptr); + avl = grpc_avl_add(avl, box(308), box(939), nullptr); + avl = grpc_avl_add(avl, box(20), box(940), nullptr); + avl = remove_int(avl, 289); + avl = grpc_avl_add(avl, box(714), box(942), nullptr); + avl = grpc_avl_add(avl, box(584), box(943), nullptr); + avl = remove_int(avl, 294); + avl = grpc_avl_add(avl, box(496), box(945), nullptr); + avl = grpc_avl_add(avl, box(394), box(946), nullptr); + avl = grpc_avl_add(avl, box(860), box(947), nullptr); + avl = grpc_avl_add(avl, box(58), box(948), nullptr); + avl = remove_int(avl, 784); + avl = remove_int(avl, 584); + avl = remove_int(avl, 708); + avl = grpc_avl_add(avl, box(142), box(952), nullptr); + avl = grpc_avl_add(avl, box(247), box(953), nullptr); + avl = grpc_avl_add(avl, box(389), box(954), nullptr); + avl = remove_int(avl, 390); + avl = grpc_avl_add(avl, box(465), box(956), nullptr); + avl = grpc_avl_add(avl, box(936), box(957), nullptr); + avl = grpc_avl_add(avl, box(309), box(958), nullptr); + avl = remove_int(avl, 928); + avl = remove_int(avl, 128); + avl = remove_int(avl, 979); + avl = remove_int(avl, 670); + avl = remove_int(avl, 738); + avl = remove_int(avl, 271); + avl = remove_int(avl, 540); + avl = grpc_avl_add(avl, box(365), box(966), nullptr); + avl = remove_int(avl, 82); + avl = grpc_avl_add(avl, box(728), box(968), nullptr); + avl = remove_int(avl, 852); + avl = grpc_avl_add(avl, box(884), box(970), nullptr); + avl = grpc_avl_add(avl, box(502), box(971), nullptr); + avl = remove_int(avl, 898); + avl = remove_int(avl, 481); + avl = grpc_avl_add(avl, box(911), box(974), nullptr); + avl = remove_int(avl, 787); + avl = remove_int(avl, 785); + avl = remove_int(avl, 537); + avl = remove_int(avl, 535); + avl = remove_int(avl, 136); + avl = remove_int(avl, 749); + avl = remove_int(avl, 637); + avl = remove_int(avl, 900); + avl = grpc_avl_add(avl, box(598), box(983), nullptr); + avl = remove_int(avl, 25); + avl = remove_int(avl, 697); + avl = grpc_avl_add(avl, box(645), box(986), nullptr); + avl = grpc_avl_add(avl, box(211), box(987), nullptr); + avl = grpc_avl_add(avl, box(589), box(988), nullptr); + avl = remove_int(avl, 702); + avl = grpc_avl_add(avl, box(53), box(990), nullptr); + avl = remove_int(avl, 492); + avl = remove_int(avl, 185); + avl = remove_int(avl, 246); + avl = remove_int(avl, 257); + avl = remove_int(avl, 502); + avl = remove_int(avl, 34); + avl = grpc_avl_add(avl, box(74), box(997), nullptr); + avl = grpc_avl_add(avl, box(834), box(998), nullptr); + avl = grpc_avl_add(avl, box(514), box(999), nullptr); + avl = grpc_avl_add(avl, box(75), box(1000), nullptr); + avl = remove_int(avl, 745); + avl = grpc_avl_add(avl, box(362), box(1002), nullptr); + avl = remove_int(avl, 215); + avl = grpc_avl_add(avl, box(624), box(1004), nullptr); + avl = remove_int(avl, 404); + avl = remove_int(avl, 359); + avl = remove_int(avl, 491); + avl = grpc_avl_add(avl, box(903), box(1008), nullptr); + avl = grpc_avl_add(avl, box(240), box(1009), nullptr); + avl = remove_int(avl, 95); + avl = grpc_avl_add(avl, box(119), box(1011), nullptr); + avl = grpc_avl_add(avl, box(857), box(1012), nullptr); + avl = remove_int(avl, 39); + avl = remove_int(avl, 866); + avl = grpc_avl_add(avl, box(503), box(1015), nullptr); + avl = grpc_avl_add(avl, box(740), box(1016), nullptr); + avl = remove_int(avl, 637); + avl = remove_int(avl, 156); + avl = remove_int(avl, 6); + avl = remove_int(avl, 745); + avl = remove_int(avl, 433); + avl = remove_int(avl, 283); + avl = grpc_avl_add(avl, box(625), box(1023), nullptr); + avl = remove_int(avl, 638); + avl = grpc_avl_add(avl, box(299), box(1025), nullptr); + avl = grpc_avl_add(avl, box(584), box(1026), nullptr); + avl = remove_int(avl, 863); + avl = grpc_avl_add(avl, box(612), box(1028), nullptr); + avl = grpc_avl_add(avl, box(62), box(1029), nullptr); + avl = grpc_avl_add(avl, box(432), box(1030), nullptr); + avl = remove_int(avl, 371); + avl = remove_int(avl, 790); + avl = remove_int(avl, 227); + avl = remove_int(avl, 836); + avl = grpc_avl_add(avl, box(703), box(1035), nullptr); + avl = grpc_avl_add(avl, box(644), box(1036), nullptr); + avl = remove_int(avl, 638); + avl = grpc_avl_add(avl, box(13), box(1038), nullptr); + avl = remove_int(avl, 66); + avl = remove_int(avl, 82); + avl = grpc_avl_add(avl, box(362), box(1041), nullptr); + avl = grpc_avl_add(avl, box(783), box(1042), nullptr); + avl = remove_int(avl, 60); + avl = grpc_avl_add(avl, box(80), box(1044), nullptr); + avl = grpc_avl_add(avl, box(825), box(1045), nullptr); + avl = grpc_avl_add(avl, box(688), box(1046), nullptr); + avl = grpc_avl_add(avl, box(662), box(1047), nullptr); + avl = remove_int(avl, 156); + avl = remove_int(avl, 376); + avl = remove_int(avl, 99); + avl = grpc_avl_add(avl, box(526), box(1051), nullptr); + avl = grpc_avl_add(avl, box(168), box(1052), nullptr); + avl = remove_int(avl, 646); + avl = remove_int(avl, 380); + avl = remove_int(avl, 833); + avl = grpc_avl_add(avl, box(53), box(1056), nullptr); + avl = remove_int(avl, 105); + avl = grpc_avl_add(avl, box(373), box(1058), nullptr); + avl = grpc_avl_add(avl, box(184), box(1059), nullptr); + avl = remove_int(avl, 288); + avl = grpc_avl_add(avl, box(966), box(1061), nullptr); + avl = remove_int(avl, 158); + avl = grpc_avl_add(avl, box(406), box(1063), nullptr); + avl = remove_int(avl, 470); + avl = grpc_avl_add(avl, box(283), box(1065), nullptr); + avl = grpc_avl_add(avl, box(838), box(1066), nullptr); + avl = grpc_avl_add(avl, box(288), box(1067), nullptr); + avl = grpc_avl_add(avl, box(950), box(1068), nullptr); + avl = grpc_avl_add(avl, box(163), box(1069), nullptr); + avl = remove_int(avl, 623); + avl = remove_int(avl, 769); + avl = grpc_avl_add(avl, box(144), box(1072), nullptr); + avl = grpc_avl_add(avl, box(489), box(1073), nullptr); + avl = remove_int(avl, 15); + avl = grpc_avl_add(avl, box(971), box(1075), nullptr); + avl = remove_int(avl, 660); + avl = grpc_avl_add(avl, box(255), box(1077), nullptr); + avl = remove_int(avl, 494); + avl = grpc_avl_add(avl, box(109), box(1079), nullptr); + avl = grpc_avl_add(avl, box(420), box(1080), nullptr); + avl = grpc_avl_add(avl, box(509), box(1081), nullptr); + avl = remove_int(avl, 178); + avl = grpc_avl_add(avl, box(216), box(1083), nullptr); + avl = grpc_avl_add(avl, box(707), box(1084), nullptr); + avl = grpc_avl_add(avl, box(411), box(1085), nullptr); + avl = grpc_avl_add(avl, box(352), box(1086), nullptr); + avl = remove_int(avl, 983); + avl = grpc_avl_add(avl, box(6), box(1088), nullptr); + avl = grpc_avl_add(avl, box(1014), box(1089), nullptr); + avl = remove_int(avl, 98); + avl = remove_int(avl, 325); + avl = grpc_avl_add(avl, box(851), box(1092), nullptr); + avl = remove_int(avl, 553); + avl = grpc_avl_add(avl, box(218), box(1094), nullptr); + avl = grpc_avl_add(avl, box(261), box(1095), nullptr); + avl = remove_int(avl, 31); + avl = grpc_avl_add(avl, box(872), box(1097), nullptr); + avl = remove_int(avl, 543); + avl = remove_int(avl, 314); + avl = remove_int(avl, 443); + avl = grpc_avl_add(avl, box(533), box(1101), nullptr); + avl = remove_int(avl, 881); + avl = remove_int(avl, 269); + avl = remove_int(avl, 940); + avl = remove_int(avl, 909); + avl = remove_int(avl, 197); + avl = remove_int(avl, 773); + avl = remove_int(avl, 790); + avl = remove_int(avl, 345); + avl = grpc_avl_add(avl, box(965), box(1110), nullptr); + avl = remove_int(avl, 622); + avl = grpc_avl_add(avl, box(352), box(1112), nullptr); + avl = remove_int(avl, 182); + avl = grpc_avl_add(avl, box(534), box(1114), nullptr); + avl = grpc_avl_add(avl, box(97), box(1115), nullptr); + avl = grpc_avl_add(avl, box(198), box(1116), nullptr); + avl = remove_int(avl, 750); + avl = grpc_avl_add(avl, box(98), box(1118), nullptr); + avl = remove_int(avl, 943); + avl = grpc_avl_add(avl, box(254), box(1120), nullptr); + avl = grpc_avl_add(avl, box(30), box(1121), nullptr); + avl = remove_int(avl, 14); + avl = remove_int(avl, 475); + avl = remove_int(avl, 82); + avl = grpc_avl_add(avl, box(789), box(1125), nullptr); + avl = grpc_avl_add(avl, box(402), box(1126), nullptr); + avl = remove_int(avl, 1019); + avl = grpc_avl_add(avl, box(858), box(1128), nullptr); + avl = grpc_avl_add(avl, box(625), box(1129), nullptr); + avl = remove_int(avl, 675); + avl = remove_int(avl, 323); + avl = grpc_avl_add(avl, box(329), box(1132), nullptr); + avl = remove_int(avl, 929); + avl = remove_int(avl, 44); + avl = grpc_avl_add(avl, box(443), box(1135), nullptr); + avl = grpc_avl_add(avl, box(653), box(1136), nullptr); + avl = grpc_avl_add(avl, box(750), box(1137), nullptr); + avl = grpc_avl_add(avl, box(252), box(1138), nullptr); + avl = grpc_avl_add(avl, box(449), box(1139), nullptr); + avl = remove_int(avl, 1022); + avl = remove_int(avl, 357); + avl = remove_int(avl, 602); + avl = remove_int(avl, 131); + avl = grpc_avl_add(avl, box(531), box(1144), nullptr); + avl = remove_int(avl, 806); + avl = grpc_avl_add(avl, box(455), box(1146), nullptr); + avl = remove_int(avl, 31); + avl = grpc_avl_add(avl, box(154), box(1148), nullptr); + avl = grpc_avl_add(avl, box(189), box(1149), nullptr); + avl = remove_int(avl, 786); + avl = grpc_avl_add(avl, box(496), box(1151), nullptr); + avl = grpc_avl_add(avl, box(81), box(1152), nullptr); + avl = grpc_avl_add(avl, box(59), box(1153), nullptr); + avl = remove_int(avl, 424); + avl = remove_int(avl, 668); + avl = grpc_avl_add(avl, box(723), box(1156), nullptr); + avl = grpc_avl_add(avl, box(822), box(1157), nullptr); + avl = grpc_avl_add(avl, box(354), box(1158), nullptr); + avl = remove_int(avl, 738); + avl = grpc_avl_add(avl, box(686), box(1160), nullptr); + avl = grpc_avl_add(avl, box(43), box(1161), nullptr); + avl = grpc_avl_add(avl, box(625), box(1162), nullptr); + avl = grpc_avl_add(avl, box(902), box(1163), nullptr); + avl = grpc_avl_add(avl, box(12), box(1164), nullptr); + avl = grpc_avl_add(avl, box(977), box(1165), nullptr); + avl = grpc_avl_add(avl, box(699), box(1166), nullptr); + avl = grpc_avl_add(avl, box(189), box(1167), nullptr); + avl = remove_int(avl, 672); + avl = remove_int(avl, 90); + avl = remove_int(avl, 757); + avl = remove_int(avl, 494); + avl = grpc_avl_add(avl, box(759), box(1172), nullptr); + avl = remove_int(avl, 758); + avl = remove_int(avl, 222); + avl = grpc_avl_add(avl, box(975), box(1175), nullptr); + avl = remove_int(avl, 993); + avl = grpc_avl_add(avl, box(2), box(1177), nullptr); + avl = grpc_avl_add(avl, box(70), box(1178), nullptr); + avl = remove_int(avl, 350); + avl = remove_int(avl, 972); + avl = remove_int(avl, 880); + avl = grpc_avl_add(avl, box(753), box(1182), nullptr); + avl = remove_int(avl, 404); + avl = grpc_avl_add(avl, box(294), box(1184), nullptr); + avl = remove_int(avl, 474); + avl = grpc_avl_add(avl, box(228), box(1186), nullptr); + avl = grpc_avl_add(avl, box(484), box(1187), nullptr); + avl = remove_int(avl, 238); + avl = remove_int(avl, 53); + avl = remove_int(avl, 691); + avl = grpc_avl_add(avl, box(345), box(1191), nullptr); + avl = remove_int(avl, 0); + avl = grpc_avl_add(avl, box(230), box(1193), nullptr); + avl = remove_int(avl, 227); + avl = remove_int(avl, 152); + avl = grpc_avl_add(avl, box(884), box(1196), nullptr); + avl = remove_int(avl, 823); + avl = remove_int(avl, 53); + avl = grpc_avl_add(avl, box(1015), box(1199), nullptr); + avl = grpc_avl_add(avl, box(697), box(1200), nullptr); + avl = grpc_avl_add(avl, box(376), box(1201), nullptr); + avl = remove_int(avl, 411); + avl = grpc_avl_add(avl, box(888), box(1203), nullptr); + avl = remove_int(avl, 55); + avl = grpc_avl_add(avl, box(85), box(1205), nullptr); + avl = remove_int(avl, 947); + avl = remove_int(avl, 382); + avl = remove_int(avl, 777); + avl = grpc_avl_add(avl, box(1017), box(1209), nullptr); + avl = grpc_avl_add(avl, box(169), box(1210), nullptr); + avl = grpc_avl_add(avl, box(156), box(1211), nullptr); + avl = remove_int(avl, 153); + avl = remove_int(avl, 642); + avl = remove_int(avl, 158); + avl = grpc_avl_add(avl, box(554), box(1215), nullptr); + avl = grpc_avl_add(avl, box(76), box(1216), nullptr); + avl = grpc_avl_add(avl, box(756), box(1217), nullptr); + avl = remove_int(avl, 767); + avl = remove_int(avl, 112); + avl = remove_int(avl, 539); + avl = remove_int(avl, 544); + avl = remove_int(avl, 628); + avl = remove_int(avl, 385); + avl = remove_int(avl, 514); + avl = remove_int(avl, 362); + avl = grpc_avl_add(avl, box(523), box(1226), nullptr); + avl = grpc_avl_add(avl, box(712), box(1227), nullptr); + avl = grpc_avl_add(avl, box(474), box(1228), nullptr); + avl = grpc_avl_add(avl, box(882), box(1229), nullptr); + avl = grpc_avl_add(avl, box(965), box(1230), nullptr); + avl = remove_int(avl, 464); + avl = grpc_avl_add(avl, box(319), box(1232), nullptr); + avl = grpc_avl_add(avl, box(504), box(1233), nullptr); + avl = remove_int(avl, 818); + avl = grpc_avl_add(avl, box(884), box(1235), nullptr); + avl = grpc_avl_add(avl, box(813), box(1236), nullptr); + avl = grpc_avl_add(avl, box(795), box(1237), nullptr); + avl = remove_int(avl, 306); + avl = grpc_avl_add(avl, box(799), box(1239), nullptr); + avl = remove_int(avl, 534); + avl = grpc_avl_add(avl, box(480), box(1241), nullptr); + avl = grpc_avl_add(avl, box(656), box(1242), nullptr); + avl = grpc_avl_add(avl, box(709), box(1243), nullptr); + avl = grpc_avl_add(avl, box(500), box(1244), nullptr); + avl = remove_int(avl, 740); + avl = grpc_avl_add(avl, box(980), box(1246), nullptr); + avl = grpc_avl_add(avl, box(458), box(1247), nullptr); + avl = remove_int(avl, 377); + avl = remove_int(avl, 338); + avl = grpc_avl_add(avl, box(554), box(1250), nullptr); + avl = grpc_avl_add(avl, box(504), box(1251), nullptr); + avl = grpc_avl_add(avl, box(603), box(1252), nullptr); + avl = grpc_avl_add(avl, box(761), box(1253), nullptr); + avl = remove_int(avl, 431); + avl = grpc_avl_add(avl, box(707), box(1255), nullptr); + avl = grpc_avl_add(avl, box(673), box(1256), nullptr); + avl = remove_int(avl, 998); + avl = remove_int(avl, 332); + avl = remove_int(avl, 413); + avl = remove_int(avl, 227); + avl = remove_int(avl, 249); + avl = remove_int(avl, 309); + avl = remove_int(avl, 459); + avl = grpc_avl_add(avl, box(645), box(1264), nullptr); + avl = remove_int(avl, 858); + avl = remove_int(avl, 997); + avl = grpc_avl_add(avl, box(519), box(1267), nullptr); + avl = remove_int(avl, 614); + avl = remove_int(avl, 462); + avl = remove_int(avl, 792); + avl = grpc_avl_add(avl, box(987), box(1271), nullptr); + avl = grpc_avl_add(avl, box(309), box(1272), nullptr); + avl = remove_int(avl, 747); + avl = grpc_avl_add(avl, box(621), box(1274), nullptr); + avl = grpc_avl_add(avl, box(450), box(1275), nullptr); + avl = remove_int(avl, 265); + avl = remove_int(avl, 8); + avl = remove_int(avl, 383); + avl = grpc_avl_add(avl, box(238), box(1279), nullptr); + avl = remove_int(avl, 241); + avl = grpc_avl_add(avl, box(180), box(1281), nullptr); + avl = grpc_avl_add(avl, box(411), box(1282), nullptr); + avl = grpc_avl_add(avl, box(791), box(1283), nullptr); + avl = grpc_avl_add(avl, box(955), box(1284), nullptr); + avl = remove_int(avl, 24); + avl = remove_int(avl, 375); + avl = grpc_avl_add(avl, box(140), box(1287), nullptr); + avl = remove_int(avl, 949); + avl = grpc_avl_add(avl, box(301), box(1289), nullptr); + avl = grpc_avl_add(avl, box(0), box(1290), nullptr); + avl = remove_int(avl, 371); + avl = remove_int(avl, 427); + avl = remove_int(avl, 841); + avl = remove_int(avl, 847); + avl = grpc_avl_add(avl, box(814), box(1295), nullptr); + avl = grpc_avl_add(avl, box(127), box(1296), nullptr); + avl = grpc_avl_add(avl, box(279), box(1297), nullptr); + avl = remove_int(avl, 669); + avl = remove_int(avl, 541); + avl = remove_int(avl, 275); + avl = remove_int(avl, 299); + avl = remove_int(avl, 552); + avl = grpc_avl_add(avl, box(310), box(1303), nullptr); + avl = grpc_avl_add(avl, box(304), box(1304), nullptr); + avl = grpc_avl_add(avl, box(1), box(1305), nullptr); + avl = grpc_avl_add(avl, box(339), box(1306), nullptr); + avl = remove_int(avl, 570); + avl = remove_int(avl, 752); + avl = remove_int(avl, 552); + avl = remove_int(avl, 442); + avl = remove_int(avl, 639); + avl = grpc_avl_add(avl, box(313), box(1312), nullptr); + avl = remove_int(avl, 85); + avl = grpc_avl_add(avl, box(964), box(1314), nullptr); + avl = grpc_avl_add(avl, box(559), box(1315), nullptr); + avl = remove_int(avl, 167); + avl = grpc_avl_add(avl, box(866), box(1317), nullptr); + avl = remove_int(avl, 275); + avl = grpc_avl_add(avl, box(173), box(1319), nullptr); + avl = grpc_avl_add(avl, box(765), box(1320), nullptr); + avl = remove_int(avl, 883); + avl = grpc_avl_add(avl, box(547), box(1322), nullptr); + avl = grpc_avl_add(avl, box(847), box(1323), nullptr); + avl = remove_int(avl, 817); + avl = remove_int(avl, 850); + avl = remove_int(avl, 718); + avl = grpc_avl_add(avl, box(806), box(1327), nullptr); + avl = grpc_avl_add(avl, box(360), box(1328), nullptr); + avl = remove_int(avl, 991); + avl = grpc_avl_add(avl, box(493), box(1330), nullptr); + avl = remove_int(avl, 516); + avl = grpc_avl_add(avl, box(361), box(1332), nullptr); + avl = remove_int(avl, 355); + avl = grpc_avl_add(avl, box(512), box(1334), nullptr); + avl = grpc_avl_add(avl, box(191), box(1335), nullptr); + avl = remove_int(avl, 703); + avl = grpc_avl_add(avl, box(333), box(1337), nullptr); + avl = remove_int(avl, 481); + avl = grpc_avl_add(avl, box(501), box(1339), nullptr); + avl = remove_int(avl, 532); + avl = remove_int(avl, 510); + avl = grpc_avl_add(avl, box(793), box(1342), nullptr); + avl = grpc_avl_add(avl, box(234), box(1343), nullptr); + avl = remove_int(avl, 159); + avl = remove_int(avl, 429); + avl = remove_int(avl, 728); + avl = remove_int(avl, 288); + avl = grpc_avl_add(avl, box(281), box(1348), nullptr); + avl = grpc_avl_add(avl, box(702), box(1349), nullptr); + avl = grpc_avl_add(avl, box(149), box(1350), nullptr); + avl = remove_int(avl, 22); + avl = remove_int(avl, 944); + avl = remove_int(avl, 55); + avl = remove_int(avl, 512); + avl = remove_int(avl, 676); + avl = remove_int(avl, 884); + avl = grpc_avl_add(avl, box(246), box(1357), nullptr); + avl = grpc_avl_add(avl, box(455), box(1358), nullptr); + avl = remove_int(avl, 782); + avl = remove_int(avl, 682); + avl = grpc_avl_add(avl, box(243), box(1361), nullptr); + avl = grpc_avl_add(avl, box(109), box(1362), nullptr); + avl = grpc_avl_add(avl, box(452), box(1363), nullptr); + avl = remove_int(avl, 151); + avl = grpc_avl_add(avl, box(159), box(1365), nullptr); + avl = remove_int(avl, 1023); + avl = grpc_avl_add(avl, box(129), box(1367), nullptr); + avl = grpc_avl_add(avl, box(537), box(1368), nullptr); + avl = remove_int(avl, 321); + avl = grpc_avl_add(avl, box(740), box(1370), nullptr); + avl = remove_int(avl, 45); + avl = remove_int(avl, 136); + avl = grpc_avl_add(avl, box(229), box(1373), nullptr); + avl = remove_int(avl, 772); + avl = grpc_avl_add(avl, box(181), box(1375), nullptr); + avl = remove_int(avl, 175); + avl = grpc_avl_add(avl, box(817), box(1377), nullptr); + avl = remove_int(avl, 956); + avl = grpc_avl_add(avl, box(675), box(1379), nullptr); + avl = grpc_avl_add(avl, box(375), box(1380), nullptr); + avl = remove_int(avl, 384); + avl = grpc_avl_add(avl, box(1016), box(1382), nullptr); + avl = remove_int(avl, 295); + avl = remove_int(avl, 697); + avl = remove_int(avl, 554); + avl = remove_int(avl, 590); + avl = remove_int(avl, 1014); + avl = grpc_avl_add(avl, box(890), box(1388), nullptr); + avl = grpc_avl_add(avl, box(293), box(1389), nullptr); + avl = remove_int(avl, 207); + avl = remove_int(avl, 46); + avl = grpc_avl_add(avl, box(899), box(1392), nullptr); + avl = grpc_avl_add(avl, box(666), box(1393), nullptr); + avl = grpc_avl_add(avl, box(85), box(1394), nullptr); + avl = grpc_avl_add(avl, box(914), box(1395), nullptr); + avl = grpc_avl_add(avl, box(128), box(1396), nullptr); + avl = grpc_avl_add(avl, box(835), box(1397), nullptr); + avl = grpc_avl_add(avl, box(787), box(1398), nullptr); + avl = grpc_avl_add(avl, box(649), box(1399), nullptr); + avl = grpc_avl_add(avl, box(723), box(1400), nullptr); + avl = remove_int(avl, 874); + avl = grpc_avl_add(avl, box(778), box(1402), nullptr); + avl = grpc_avl_add(avl, box(1015), box(1403), nullptr); + avl = grpc_avl_add(avl, box(59), box(1404), nullptr); + avl = grpc_avl_add(avl, box(259), box(1405), nullptr); + avl = grpc_avl_add(avl, box(758), box(1406), nullptr); + avl = remove_int(avl, 648); + avl = grpc_avl_add(avl, box(145), box(1408), nullptr); + avl = grpc_avl_add(avl, box(440), box(1409), nullptr); + avl = remove_int(avl, 608); + avl = remove_int(avl, 690); + avl = grpc_avl_add(avl, box(605), box(1412), nullptr); + avl = remove_int(avl, 856); + avl = remove_int(avl, 608); + avl = grpc_avl_add(avl, box(829), box(1415), nullptr); + avl = grpc_avl_add(avl, box(660), box(1416), nullptr); + avl = remove_int(avl, 596); + avl = grpc_avl_add(avl, box(519), box(1418), nullptr); + avl = grpc_avl_add(avl, box(35), box(1419), nullptr); + avl = grpc_avl_add(avl, box(871), box(1420), nullptr); + avl = remove_int(avl, 845); + avl = grpc_avl_add(avl, box(600), box(1422), nullptr); + avl = grpc_avl_add(avl, box(215), box(1423), nullptr); + avl = remove_int(avl, 761); + avl = grpc_avl_add(avl, box(975), box(1425), nullptr); + avl = remove_int(avl, 987); + avl = grpc_avl_add(avl, box(58), box(1427), nullptr); + avl = remove_int(avl, 119); + avl = grpc_avl_add(avl, box(937), box(1429), nullptr); + avl = grpc_avl_add(avl, box(372), box(1430), nullptr); + avl = grpc_avl_add(avl, box(11), box(1431), nullptr); + avl = grpc_avl_add(avl, box(398), box(1432), nullptr); + avl = grpc_avl_add(avl, box(423), box(1433), nullptr); + avl = remove_int(avl, 171); + avl = grpc_avl_add(avl, box(473), box(1435), nullptr); + avl = remove_int(avl, 752); + avl = remove_int(avl, 625); + avl = remove_int(avl, 764); + avl = remove_int(avl, 49); + avl = grpc_avl_add(avl, box(472), box(1440), nullptr); + avl = remove_int(avl, 847); + avl = remove_int(avl, 642); + avl = remove_int(avl, 1004); + avl = remove_int(avl, 795); + avl = remove_int(avl, 465); + avl = grpc_avl_add(avl, box(636), box(1446), nullptr); + avl = remove_int(avl, 152); + avl = grpc_avl_add(avl, box(61), box(1448), nullptr); + avl = remove_int(avl, 929); + avl = remove_int(avl, 9); + avl = grpc_avl_add(avl, box(251), box(1451), nullptr); + avl = grpc_avl_add(avl, box(672), box(1452), nullptr); + avl = grpc_avl_add(avl, box(66), box(1453), nullptr); + avl = remove_int(avl, 693); + avl = remove_int(avl, 914); + avl = remove_int(avl, 116); + avl = remove_int(avl, 577); + avl = grpc_avl_add(avl, box(618), box(1458), nullptr); + avl = grpc_avl_add(avl, box(495), box(1459), nullptr); + avl = remove_int(avl, 450); + avl = grpc_avl_add(avl, box(533), box(1461), nullptr); + avl = grpc_avl_add(avl, box(414), box(1462), nullptr); + avl = remove_int(avl, 74); + avl = remove_int(avl, 236); + avl = grpc_avl_add(avl, box(707), box(1465), nullptr); + avl = grpc_avl_add(avl, box(357), box(1466), nullptr); + avl = grpc_avl_add(avl, box(1007), box(1467), nullptr); + avl = grpc_avl_add(avl, box(811), box(1468), nullptr); + avl = grpc_avl_add(avl, box(418), box(1469), nullptr); + avl = grpc_avl_add(avl, box(164), box(1470), nullptr); + avl = grpc_avl_add(avl, box(622), box(1471), nullptr); + avl = remove_int(avl, 22); + avl = remove_int(avl, 14); + avl = remove_int(avl, 732); + avl = remove_int(avl, 7); + avl = remove_int(avl, 447); + avl = grpc_avl_add(avl, box(221), box(1477), nullptr); + avl = grpc_avl_add(avl, box(202), box(1478), nullptr); + avl = grpc_avl_add(avl, box(312), box(1479), nullptr); + avl = remove_int(avl, 274); + avl = grpc_avl_add(avl, box(684), box(1481), nullptr); + avl = grpc_avl_add(avl, box(954), box(1482), nullptr); + avl = grpc_avl_add(avl, box(637), box(1483), nullptr); + avl = remove_int(avl, 716); + avl = grpc_avl_add(avl, box(198), box(1485), nullptr); + avl = remove_int(avl, 340); + avl = remove_int(avl, 137); + avl = remove_int(avl, 995); + avl = remove_int(avl, 1004); + avl = grpc_avl_add(avl, box(661), box(1490), nullptr); + avl = grpc_avl_add(avl, box(862), box(1491), nullptr); + avl = remove_int(avl, 527); + avl = grpc_avl_add(avl, box(945), box(1493), nullptr); + avl = remove_int(avl, 355); + avl = remove_int(avl, 144); + avl = grpc_avl_add(avl, box(229), box(1496), nullptr); + avl = grpc_avl_add(avl, box(237), box(1497), nullptr); + avl = remove_int(avl, 471); + avl = remove_int(avl, 901); + avl = grpc_avl_add(avl, box(905), box(1500), nullptr); + avl = remove_int(avl, 19); + avl = remove_int(avl, 896); + avl = remove_int(avl, 585); + avl = remove_int(avl, 308); + avl = grpc_avl_add(avl, box(547), box(1505), nullptr); + avl = grpc_avl_add(avl, box(552), box(1506), nullptr); + avl = grpc_avl_add(avl, box(30), box(1507), nullptr); + avl = grpc_avl_add(avl, box(445), box(1508), nullptr); + avl = remove_int(avl, 785); + avl = remove_int(avl, 185); + avl = grpc_avl_add(avl, box(405), box(1511), nullptr); + avl = grpc_avl_add(avl, box(733), box(1512), nullptr); + avl = grpc_avl_add(avl, box(573), box(1513), nullptr); + avl = grpc_avl_add(avl, box(492), box(1514), nullptr); + avl = grpc_avl_add(avl, box(343), box(1515), nullptr); + avl = grpc_avl_add(avl, box(527), box(1516), nullptr); + avl = grpc_avl_add(avl, box(596), box(1517), nullptr); + avl = grpc_avl_add(avl, box(519), box(1518), nullptr); + avl = remove_int(avl, 243); + avl = remove_int(avl, 722); + avl = grpc_avl_add(avl, box(772), box(1521), nullptr); + avl = remove_int(avl, 152); + avl = remove_int(avl, 305); + avl = grpc_avl_add(avl, box(754), box(1524), nullptr); + avl = grpc_avl_add(avl, box(373), box(1525), nullptr); + avl = remove_int(avl, 995); + avl = grpc_avl_add(avl, box(329), box(1527), nullptr); + avl = remove_int(avl, 397); + avl = grpc_avl_add(avl, box(884), box(1529), nullptr); + avl = remove_int(avl, 329); + avl = remove_int(avl, 240); + avl = grpc_avl_add(avl, box(566), box(1532), nullptr); + avl = grpc_avl_add(avl, box(232), box(1533), nullptr); + avl = remove_int(avl, 993); + avl = grpc_avl_add(avl, box(888), box(1535), nullptr); + avl = remove_int(avl, 242); + avl = grpc_avl_add(avl, box(941), box(1537), nullptr); + avl = remove_int(avl, 415); + avl = grpc_avl_add(avl, box(992), box(1539), nullptr); + avl = remove_int(avl, 289); + avl = grpc_avl_add(avl, box(60), box(1541), nullptr); + avl = grpc_avl_add(avl, box(97), box(1542), nullptr); + avl = remove_int(avl, 965); + avl = remove_int(avl, 267); + avl = remove_int(avl, 360); + avl = grpc_avl_add(avl, box(5), box(1546), nullptr); + avl = remove_int(avl, 429); + avl = grpc_avl_add(avl, box(412), box(1548), nullptr); + avl = remove_int(avl, 632); + avl = remove_int(avl, 113); + avl = grpc_avl_add(avl, box(48), box(1551), nullptr); + avl = grpc_avl_add(avl, box(108), box(1552), nullptr); + avl = grpc_avl_add(avl, box(750), box(1553), nullptr); + avl = remove_int(avl, 188); + avl = grpc_avl_add(avl, box(668), box(1555), nullptr); + avl = remove_int(avl, 37); + avl = remove_int(avl, 737); + avl = grpc_avl_add(avl, box(93), box(1558), nullptr); + avl = grpc_avl_add(avl, box(628), box(1559), nullptr); + avl = grpc_avl_add(avl, box(480), box(1560), nullptr); + avl = remove_int(avl, 958); + avl = remove_int(avl, 565); + avl = remove_int(avl, 32); + avl = remove_int(avl, 1); + avl = remove_int(avl, 335); + avl = grpc_avl_add(avl, box(136), box(1566), nullptr); + avl = grpc_avl_add(avl, box(469), box(1567), nullptr); + avl = remove_int(avl, 349); + avl = grpc_avl_add(avl, box(768), box(1569), nullptr); + avl = grpc_avl_add(avl, box(915), box(1570), nullptr); + avl = remove_int(avl, 1014); + avl = grpc_avl_add(avl, box(117), box(1572), nullptr); + avl = remove_int(avl, 62); + avl = grpc_avl_add(avl, box(382), box(1574), nullptr); + avl = remove_int(avl, 571); + avl = grpc_avl_add(avl, box(655), box(1576), nullptr); + avl = grpc_avl_add(avl, box(323), box(1577), nullptr); + avl = remove_int(avl, 869); + avl = remove_int(avl, 151); + avl = grpc_avl_add(avl, box(1019), box(1580), nullptr); + avl = grpc_avl_add(avl, box(984), box(1581), nullptr); + avl = grpc_avl_add(avl, box(870), box(1582), nullptr); + avl = grpc_avl_add(avl, box(376), box(1583), nullptr); + avl = remove_int(avl, 625); + avl = grpc_avl_add(avl, box(733), box(1585), nullptr); + avl = remove_int(avl, 532); + avl = remove_int(avl, 444); + avl = grpc_avl_add(avl, box(428), box(1588), nullptr); + avl = grpc_avl_add(avl, box(860), box(1589), nullptr); + avl = grpc_avl_add(avl, box(173), box(1590), nullptr); + avl = remove_int(avl, 649); + avl = remove_int(avl, 913); + avl = remove_int(avl, 1); + avl = remove_int(avl, 304); + avl = grpc_avl_add(avl, box(604), box(1595), nullptr); + avl = grpc_avl_add(avl, box(639), box(1596), nullptr); + avl = remove_int(avl, 431); + avl = grpc_avl_add(avl, box(993), box(1598), nullptr); + avl = remove_int(avl, 681); + avl = remove_int(avl, 927); + avl = grpc_avl_add(avl, box(87), box(1601), nullptr); + avl = grpc_avl_add(avl, box(91), box(1602), nullptr); + avl = remove_int(avl, 61); + avl = remove_int(avl, 14); + avl = remove_int(avl, 305); + avl = remove_int(avl, 304); + avl = remove_int(avl, 1016); + avl = grpc_avl_add(avl, box(903), box(1608), nullptr); + avl = grpc_avl_add(avl, box(951), box(1609), nullptr); + avl = grpc_avl_add(avl, box(146), box(1610), nullptr); + avl = grpc_avl_add(avl, box(482), box(1611), nullptr); + avl = grpc_avl_add(avl, box(71), box(1612), nullptr); + avl = remove_int(avl, 246); + avl = remove_int(avl, 696); + avl = grpc_avl_add(avl, box(636), box(1615), nullptr); + avl = grpc_avl_add(avl, box(295), box(1616), nullptr); + avl = remove_int(avl, 11); + avl = remove_int(avl, 231); + avl = grpc_avl_add(avl, box(905), box(1619), nullptr); + avl = grpc_avl_add(avl, box(993), box(1620), nullptr); + avl = grpc_avl_add(avl, box(433), box(1621), nullptr); + avl = grpc_avl_add(avl, box(117), box(1622), nullptr); + avl = grpc_avl_add(avl, box(467), box(1623), nullptr); + avl = remove_int(avl, 419); + avl = grpc_avl_add(avl, box(179), box(1625), nullptr); + avl = remove_int(avl, 926); + avl = remove_int(avl, 326); + avl = grpc_avl_add(avl, box(551), box(1628), nullptr); + avl = remove_int(avl, 14); + avl = remove_int(avl, 476); + avl = remove_int(avl, 823); + avl = grpc_avl_add(avl, box(350), box(1632), nullptr); + avl = grpc_avl_add(avl, box(133), box(1633), nullptr); + avl = remove_int(avl, 906); + avl = grpc_avl_add(avl, box(827), box(1635), nullptr); + avl = grpc_avl_add(avl, box(201), box(1636), nullptr); + avl = remove_int(avl, 124); + avl = remove_int(avl, 662); + avl = grpc_avl_add(avl, box(314), box(1639), nullptr); + avl = grpc_avl_add(avl, box(986), box(1640), nullptr); + avl = grpc_avl_add(avl, box(622), box(1641), nullptr); + avl = remove_int(avl, 130); + avl = grpc_avl_add(avl, box(861), box(1643), nullptr); + avl = remove_int(avl, 497); + avl = remove_int(avl, 905); + avl = grpc_avl_add(avl, box(502), box(1646), nullptr); + avl = remove_int(avl, 721); + avl = grpc_avl_add(avl, box(514), box(1648), nullptr); + avl = grpc_avl_add(avl, box(410), box(1649), nullptr); + avl = remove_int(avl, 869); + avl = remove_int(avl, 247); + avl = grpc_avl_add(avl, box(450), box(1652), nullptr); + avl = remove_int(avl, 364); + avl = grpc_avl_add(avl, box(963), box(1654), nullptr); + avl = grpc_avl_add(avl, box(146), box(1655), nullptr); + avl = remove_int(avl, 147); + avl = remove_int(avl, 789); + avl = grpc_avl_add(avl, box(693), box(1658), nullptr); + avl = grpc_avl_add(avl, box(959), box(1659), nullptr); + avl = remove_int(avl, 478); + avl = grpc_avl_add(avl, box(116), box(1661), nullptr); + avl = grpc_avl_add(avl, box(520), box(1662), nullptr); + avl = grpc_avl_add(avl, box(809), box(1663), nullptr); + avl = grpc_avl_add(avl, box(667), box(1664), nullptr); + avl = grpc_avl_add(avl, box(406), box(1665), nullptr); + avl = remove_int(avl, 409); + avl = grpc_avl_add(avl, box(558), box(1667), nullptr); + avl = grpc_avl_add(avl, box(0), box(1668), nullptr); + avl = grpc_avl_add(avl, box(948), box(1669), nullptr); + avl = grpc_avl_add(avl, box(576), box(1670), nullptr); + avl = remove_int(avl, 864); + avl = remove_int(avl, 840); + avl = remove_int(avl, 1001); + avl = grpc_avl_add(avl, box(232), box(1674), nullptr); + avl = remove_int(avl, 676); + avl = remove_int(avl, 752); + avl = remove_int(avl, 667); + avl = remove_int(avl, 605); + avl = grpc_avl_add(avl, box(258), box(1679), nullptr); + avl = grpc_avl_add(avl, box(648), box(1680), nullptr); + avl = grpc_avl_add(avl, box(761), box(1681), nullptr); + avl = remove_int(avl, 293); + avl = remove_int(avl, 893); + avl = grpc_avl_add(avl, box(194), box(1684), nullptr); + avl = remove_int(avl, 233); + avl = grpc_avl_add(avl, box(888), box(1686), nullptr); + avl = remove_int(avl, 470); + avl = remove_int(avl, 703); + avl = remove_int(avl, 190); + avl = remove_int(avl, 359); + avl = grpc_avl_add(avl, box(621), box(1691), nullptr); + avl = remove_int(avl, 634); + avl = remove_int(avl, 335); + avl = grpc_avl_add(avl, box(718), box(1694), nullptr); + avl = grpc_avl_add(avl, box(463), box(1695), nullptr); + avl = grpc_avl_add(avl, box(233), box(1696), nullptr); + avl = remove_int(avl, 376); + avl = remove_int(avl, 496); + avl = remove_int(avl, 819); + avl = remove_int(avl, 38); + avl = remove_int(avl, 436); + avl = remove_int(avl, 102); + avl = grpc_avl_add(avl, box(607), box(1703), nullptr); + avl = remove_int(avl, 329); + avl = grpc_avl_add(avl, box(716), box(1705), nullptr); + avl = remove_int(avl, 639); + avl = remove_int(avl, 775); + avl = remove_int(avl, 578); + avl = remove_int(avl, 464); + avl = remove_int(avl, 679); + avl = remove_int(avl, 615); + avl = remove_int(avl, 104); + avl = grpc_avl_add(avl, box(414), box(1713), nullptr); + avl = grpc_avl_add(avl, box(212), box(1714), nullptr); + avl = grpc_avl_add(avl, box(266), box(1715), nullptr); + avl = grpc_avl_add(avl, box(238), box(1716), nullptr); + avl = remove_int(avl, 153); + avl = grpc_avl_add(avl, box(585), box(1718), nullptr); + avl = remove_int(avl, 121); + avl = grpc_avl_add(avl, box(534), box(1720), nullptr); + avl = remove_int(avl, 579); + avl = grpc_avl_add(avl, box(127), box(1722), nullptr); + avl = grpc_avl_add(avl, box(399), box(1723), nullptr); + avl = remove_int(avl, 417); + avl = grpc_avl_add(avl, box(978), box(1725), nullptr); + avl = grpc_avl_add(avl, box(768), box(1726), nullptr); + avl = remove_int(avl, 985); + avl = grpc_avl_add(avl, box(536), box(1728), nullptr); + avl = grpc_avl_add(avl, box(449), box(1729), nullptr); + avl = grpc_avl_add(avl, box(586), box(1730), nullptr); + avl = remove_int(avl, 998); + avl = remove_int(avl, 394); + avl = remove_int(avl, 141); + avl = grpc_avl_add(avl, box(889), box(1734), nullptr); + avl = grpc_avl_add(avl, box(871), box(1735), nullptr); + avl = grpc_avl_add(avl, box(76), box(1736), nullptr); + avl = grpc_avl_add(avl, box(549), box(1737), nullptr); + avl = grpc_avl_add(avl, box(757), box(1738), nullptr); + avl = remove_int(avl, 908); + avl = grpc_avl_add(avl, box(789), box(1740), nullptr); + avl = remove_int(avl, 224); + avl = grpc_avl_add(avl, box(407), box(1742), nullptr); + avl = grpc_avl_add(avl, box(381), box(1743), nullptr); + avl = grpc_avl_add(avl, box(561), box(1744), nullptr); + avl = grpc_avl_add(avl, box(667), box(1745), nullptr); + avl = grpc_avl_add(avl, box(522), box(1746), nullptr); + avl = grpc_avl_add(avl, box(948), box(1747), nullptr); + avl = remove_int(avl, 770); + avl = grpc_avl_add(avl, box(872), box(1749), nullptr); + avl = grpc_avl_add(avl, box(327), box(1750), nullptr); + avl = remove_int(avl, 10); + avl = grpc_avl_add(avl, box(122), box(1752), nullptr); + avl = remove_int(avl, 606); + avl = grpc_avl_add(avl, box(485), box(1754), nullptr); + avl = remove_int(avl, 6); + avl = grpc_avl_add(avl, box(329), box(1756), nullptr); + avl = grpc_avl_add(avl, box(783), box(1757), nullptr); + avl = remove_int(avl, 416); + avl = grpc_avl_add(avl, box(656), box(1759), nullptr); + avl = grpc_avl_add(avl, box(971), box(1760), nullptr); + avl = grpc_avl_add(avl, box(77), box(1761), nullptr); + avl = grpc_avl_add(avl, box(942), box(1762), nullptr); + avl = remove_int(avl, 361); + avl = grpc_avl_add(avl, box(66), box(1764), nullptr); + avl = grpc_avl_add(avl, box(299), box(1765), nullptr); + avl = grpc_avl_add(avl, box(929), box(1766), nullptr); + avl = grpc_avl_add(avl, box(797), box(1767), nullptr); + avl = remove_int(avl, 869); + avl = remove_int(avl, 907); + avl = grpc_avl_add(avl, box(870), box(1770), nullptr); + avl = remove_int(avl, 580); + avl = remove_int(avl, 120); + avl = grpc_avl_add(avl, box(913), box(1773), nullptr); + avl = remove_int(avl, 480); + avl = grpc_avl_add(avl, box(489), box(1775), nullptr); + avl = remove_int(avl, 845); + avl = grpc_avl_add(avl, box(896), box(1777), nullptr); + avl = remove_int(avl, 567); + avl = remove_int(avl, 427); + avl = grpc_avl_add(avl, box(443), box(1780), nullptr); + avl = grpc_avl_add(avl, box(3), box(1781), nullptr); + avl = remove_int(avl, 12); + avl = grpc_avl_add(avl, box(376), box(1783), nullptr); + avl = grpc_avl_add(avl, box(155), box(1784), nullptr); + avl = grpc_avl_add(avl, box(188), box(1785), nullptr); + avl = grpc_avl_add(avl, box(149), box(1786), nullptr); + avl = grpc_avl_add(avl, box(178), box(1787), nullptr); + avl = remove_int(avl, 84); + avl = grpc_avl_add(avl, box(805), box(1789), nullptr); + avl = grpc_avl_add(avl, box(612), box(1790), nullptr); + avl = remove_int(avl, 991); + avl = grpc_avl_add(avl, box(837), box(1792), nullptr); + avl = remove_int(avl, 173); + avl = remove_int(avl, 72); + avl = grpc_avl_add(avl, box(1014), box(1795), nullptr); + avl = remove_int(avl, 303); + avl = grpc_avl_add(avl, box(865), box(1797), nullptr); + avl = grpc_avl_add(avl, box(793), box(1798), nullptr); + avl = remove_int(avl, 173); + avl = remove_int(avl, 477); + avl = grpc_avl_add(avl, box(950), box(1801), nullptr); + avl = grpc_avl_add(avl, box(105), box(1802), nullptr); + avl = grpc_avl_add(avl, box(895), box(1803), nullptr); + avl = grpc_avl_add(avl, box(171), box(1804), nullptr); + avl = grpc_avl_add(avl, box(753), box(1805), nullptr); + avl = grpc_avl_add(avl, box(946), box(1806), nullptr); + avl = remove_int(avl, 194); + avl = remove_int(avl, 559); + avl = remove_int(avl, 116); + avl = grpc_avl_add(avl, box(968), box(1810), nullptr); + avl = remove_int(avl, 124); + avl = remove_int(avl, 99); + avl = grpc_avl_add(avl, box(563), box(1813), nullptr); + avl = remove_int(avl, 182); + avl = grpc_avl_add(avl, box(816), box(1815), nullptr); + avl = remove_int(avl, 73); + avl = remove_int(avl, 261); + avl = grpc_avl_add(avl, box(847), box(1818), nullptr); + avl = grpc_avl_add(avl, box(368), box(1819), nullptr); + avl = grpc_avl_add(avl, box(808), box(1820), nullptr); + avl = grpc_avl_add(avl, box(779), box(1821), nullptr); + avl = remove_int(avl, 818); + avl = grpc_avl_add(avl, box(466), box(1823), nullptr); + avl = remove_int(avl, 316); + avl = grpc_avl_add(avl, box(986), box(1825), nullptr); + avl = grpc_avl_add(avl, box(688), box(1826), nullptr); + avl = grpc_avl_add(avl, box(509), box(1827), nullptr); + avl = grpc_avl_add(avl, box(51), box(1828), nullptr); + avl = remove_int(avl, 655); + avl = remove_int(avl, 785); + avl = remove_int(avl, 893); + avl = grpc_avl_add(avl, box(167), box(1832), nullptr); + avl = remove_int(avl, 13); + avl = remove_int(avl, 263); + avl = grpc_avl_add(avl, box(1009), box(1835), nullptr); + avl = remove_int(avl, 480); + avl = remove_int(avl, 778); + avl = remove_int(avl, 713); + avl = remove_int(avl, 628); + avl = grpc_avl_add(avl, box(803), box(1840), nullptr); + avl = remove_int(avl, 267); + avl = grpc_avl_add(avl, box(676), box(1842), nullptr); + avl = grpc_avl_add(avl, box(231), box(1843), nullptr); + avl = grpc_avl_add(avl, box(824), box(1844), nullptr); + avl = remove_int(avl, 961); + avl = grpc_avl_add(avl, box(311), box(1846), nullptr); + avl = grpc_avl_add(avl, box(420), box(1847), nullptr); + avl = grpc_avl_add(avl, box(960), box(1848), nullptr); + avl = grpc_avl_add(avl, box(468), box(1849), nullptr); + avl = grpc_avl_add(avl, box(815), box(1850), nullptr); + avl = remove_int(avl, 247); + avl = remove_int(avl, 194); + avl = grpc_avl_add(avl, box(546), box(1853), nullptr); + avl = remove_int(avl, 222); + avl = remove_int(avl, 914); + avl = remove_int(avl, 741); + avl = grpc_avl_add(avl, box(470), box(1857), nullptr); + avl = grpc_avl_add(avl, box(933), box(1858), nullptr); + avl = grpc_avl_add(avl, box(97), box(1859), nullptr); + avl = remove_int(avl, 564); + avl = remove_int(avl, 295); + avl = grpc_avl_add(avl, box(864), box(1862), nullptr); + avl = remove_int(avl, 329); + avl = grpc_avl_add(avl, box(124), box(1864), nullptr); + avl = grpc_avl_add(avl, box(1000), box(1865), nullptr); + avl = grpc_avl_add(avl, box(228), box(1866), nullptr); + avl = grpc_avl_add(avl, box(187), box(1867), nullptr); + avl = remove_int(avl, 224); + avl = remove_int(avl, 306); + avl = remove_int(avl, 884); + avl = grpc_avl_add(avl, box(449), box(1871), nullptr); + avl = grpc_avl_add(avl, box(353), box(1872), nullptr); + avl = grpc_avl_add(avl, box(994), box(1873), nullptr); + avl = grpc_avl_add(avl, box(596), box(1874), nullptr); + avl = grpc_avl_add(avl, box(996), box(1875), nullptr); + avl = grpc_avl_add(avl, box(101), box(1876), nullptr); + avl = grpc_avl_add(avl, box(1012), box(1877), nullptr); + avl = grpc_avl_add(avl, box(982), box(1878), nullptr); + avl = grpc_avl_add(avl, box(742), box(1879), nullptr); + avl = remove_int(avl, 92); + avl = remove_int(avl, 1022); + avl = grpc_avl_add(avl, box(941), box(1882), nullptr); + avl = remove_int(avl, 742); + avl = remove_int(avl, 919); + avl = grpc_avl_add(avl, box(588), box(1885), nullptr); + avl = remove_int(avl, 221); + avl = grpc_avl_add(avl, box(356), box(1887), nullptr); + avl = grpc_avl_add(avl, box(932), box(1888), nullptr); + avl = remove_int(avl, 837); + avl = grpc_avl_add(avl, box(394), box(1890), nullptr); + avl = grpc_avl_add(avl, box(642), box(1891), nullptr); + avl = grpc_avl_add(avl, box(52), box(1892), nullptr); + avl = grpc_avl_add(avl, box(437), box(1893), nullptr); + avl = grpc_avl_add(avl, box(948), box(1894), nullptr); + avl = grpc_avl_add(avl, box(93), box(1895), nullptr); + avl = remove_int(avl, 873); + avl = remove_int(avl, 336); + avl = remove_int(avl, 277); + avl = remove_int(avl, 932); + avl = grpc_avl_add(avl, box(80), box(1900), nullptr); + avl = grpc_avl_add(avl, box(952), box(1901), nullptr); + avl = grpc_avl_add(avl, box(510), box(1902), nullptr); + avl = remove_int(avl, 876); + avl = remove_int(avl, 612); + avl = grpc_avl_add(avl, box(923), box(1905), nullptr); + avl = grpc_avl_add(avl, box(475), box(1906), nullptr); + avl = remove_int(avl, 478); + avl = remove_int(avl, 148); + avl = grpc_avl_add(avl, box(538), box(1909), nullptr); + avl = remove_int(avl, 47); + avl = grpc_avl_add(avl, box(89), box(1911), nullptr); + avl = remove_int(avl, 723); + avl = grpc_avl_add(avl, box(687), box(1913), nullptr); + avl = grpc_avl_add(avl, box(480), box(1914), nullptr); + avl = grpc_avl_add(avl, box(149), box(1915), nullptr); + avl = remove_int(avl, 68); + avl = remove_int(avl, 862); + avl = remove_int(avl, 363); + avl = grpc_avl_add(avl, box(996), box(1919), nullptr); + avl = remove_int(avl, 380); + avl = grpc_avl_add(avl, box(957), box(1921), nullptr); + avl = remove_int(avl, 413); + avl = grpc_avl_add(avl, box(360), box(1923), nullptr); + avl = grpc_avl_add(avl, box(304), box(1924), nullptr); + avl = grpc_avl_add(avl, box(634), box(1925), nullptr); + avl = grpc_avl_add(avl, box(506), box(1926), nullptr); + avl = remove_int(avl, 248); + avl = grpc_avl_add(avl, box(124), box(1928), nullptr); + avl = grpc_avl_add(avl, box(181), box(1929), nullptr); + avl = remove_int(avl, 507); + avl = grpc_avl_add(avl, box(141), box(1931), nullptr); + avl = remove_int(avl, 409); + avl = remove_int(avl, 129); + avl = remove_int(avl, 694); + avl = remove_int(avl, 723); + avl = grpc_avl_add(avl, box(998), box(1936), nullptr); + avl = grpc_avl_add(avl, box(906), box(1937), nullptr); + avl = grpc_avl_add(avl, box(44), box(1938), nullptr); + avl = remove_int(avl, 949); + avl = remove_int(avl, 117); + avl = grpc_avl_add(avl, box(700), box(1941), nullptr); + avl = grpc_avl_add(avl, box(258), box(1942), nullptr); + avl = remove_int(avl, 828); + avl = grpc_avl_add(avl, box(860), box(1944), nullptr); + avl = grpc_avl_add(avl, box(987), box(1945), nullptr); + avl = grpc_avl_add(avl, box(316), box(1946), nullptr); + avl = grpc_avl_add(avl, box(919), box(1947), nullptr); + avl = remove_int(avl, 84); + avl = grpc_avl_add(avl, box(473), box(1949), nullptr); + avl = remove_int(avl, 127); + avl = remove_int(avl, 829); + avl = remove_int(avl, 829); + avl = grpc_avl_add(avl, box(488), box(1953), nullptr); + avl = grpc_avl_add(avl, box(954), box(1954), nullptr); + avl = remove_int(avl, 198); + avl = remove_int(avl, 972); + avl = remove_int(avl, 670); + avl = grpc_avl_add(avl, box(822), box(1958), nullptr); + avl = remove_int(avl, 589); + avl = remove_int(avl, 459); + avl = grpc_avl_add(avl, box(1003), box(1961), nullptr); + avl = grpc_avl_add(avl, box(657), box(1962), nullptr); + avl = grpc_avl_add(avl, box(477), box(1963), nullptr); + avl = grpc_avl_add(avl, box(923), box(1964), nullptr); + avl = remove_int(avl, 496); + avl = remove_int(avl, 99); + avl = grpc_avl_add(avl, box(127), box(1967), nullptr); + avl = grpc_avl_add(avl, box(1013), box(1968), nullptr); + avl = grpc_avl_add(avl, box(778), box(1969), nullptr); + avl = remove_int(avl, 5); + avl = remove_int(avl, 990); + avl = remove_int(avl, 850); + avl = remove_int(avl, 160); + avl = remove_int(avl, 86); + avl = grpc_avl_add(avl, box(283), box(1975), nullptr); + avl = remove_int(avl, 278); + avl = remove_int(avl, 297); + avl = remove_int(avl, 137); + avl = remove_int(avl, 653); + avl = grpc_avl_add(avl, box(702), box(1980), nullptr); + avl = remove_int(avl, 63); + avl = remove_int(avl, 427); + avl = remove_int(avl, 706); + avl = remove_int(avl, 806); + avl = grpc_avl_add(avl, box(335), box(1985), nullptr); + avl = grpc_avl_add(avl, box(412), box(1986), nullptr); + avl = remove_int(avl, 766); + avl = remove_int(avl, 937); + avl = remove_int(avl, 886); + avl = remove_int(avl, 652); + avl = grpc_avl_add(avl, box(545), box(1991), nullptr); + avl = grpc_avl_add(avl, box(408), box(1992), nullptr); + avl = grpc_avl_add(avl, box(841), box(1993), nullptr); + avl = remove_int(avl, 593); + avl = grpc_avl_add(avl, box(582), box(1995), nullptr); + avl = grpc_avl_add(avl, box(597), box(1996), nullptr); + avl = remove_int(avl, 49); + avl = remove_int(avl, 835); + avl = grpc_avl_add(avl, box(417), box(1999), nullptr); + avl = grpc_avl_add(avl, box(191), box(2000), nullptr); + avl = remove_int(avl, 406); + avl = grpc_avl_add(avl, box(30), box(2002), nullptr); + avl = remove_int(avl, 841); + avl = remove_int(avl, 50); + avl = grpc_avl_add(avl, box(967), box(2005), nullptr); + avl = grpc_avl_add(avl, box(849), box(2006), nullptr); + avl = remove_int(avl, 608); + avl = grpc_avl_add(avl, box(306), box(2008), nullptr); + avl = remove_int(avl, 779); + avl = grpc_avl_add(avl, box(897), box(2010), nullptr); + avl = grpc_avl_add(avl, box(147), box(2011), nullptr); + avl = remove_int(avl, 982); + avl = grpc_avl_add(avl, box(470), box(2013), nullptr); + avl = remove_int(avl, 951); + avl = grpc_avl_add(avl, box(388), box(2015), nullptr); + avl = remove_int(avl, 616); + avl = remove_int(avl, 721); + avl = remove_int(avl, 942); + avl = remove_int(avl, 589); + avl = grpc_avl_add(avl, box(218), box(2020), nullptr); + avl = remove_int(avl, 671); + avl = grpc_avl_add(avl, box(1020), box(2022), nullptr); + avl = remove_int(avl, 277); + avl = grpc_avl_add(avl, box(681), box(2024), nullptr); + avl = grpc_avl_add(avl, box(179), box(2025), nullptr); + avl = grpc_avl_add(avl, box(370), box(2026), nullptr); + avl = grpc_avl_add(avl, box(0), box(2027), nullptr); + avl = remove_int(avl, 523); + avl = grpc_avl_add(avl, box(99), box(2029), nullptr); + avl = grpc_avl_add(avl, box(334), box(2030), nullptr); + avl = grpc_avl_add(avl, box(569), box(2031), nullptr); + avl = grpc_avl_add(avl, box(257), box(2032), nullptr); + avl = remove_int(avl, 572); + avl = grpc_avl_add(avl, box(805), box(2034), nullptr); + avl = grpc_avl_add(avl, box(143), box(2035), nullptr); + avl = grpc_avl_add(avl, box(670), box(2036), nullptr); + avl = remove_int(avl, 42); + avl = grpc_avl_add(avl, box(46), box(2038), nullptr); + avl = remove_int(avl, 970); + avl = grpc_avl_add(avl, box(353), box(2040), nullptr); + avl = remove_int(avl, 258); + avl = grpc_avl_add(avl, box(451), box(2042), nullptr); + avl = grpc_avl_add(avl, box(28), box(2043), nullptr); + avl = grpc_avl_add(avl, box(729), box(2044), nullptr); + avl = grpc_avl_add(avl, box(401), box(2045), nullptr); + avl = grpc_avl_add(avl, box(614), box(2046), nullptr); + avl = remove_int(avl, 990); + avl = remove_int(avl, 212); + avl = remove_int(avl, 22); + avl = remove_int(avl, 677); + avl = grpc_avl_add(avl, box(1016), box(2051), nullptr); + avl = grpc_avl_add(avl, box(980), box(2052), nullptr); + avl = grpc_avl_add(avl, box(990), box(2053), nullptr); + avl = grpc_avl_add(avl, box(355), box(2054), nullptr); + avl = remove_int(avl, 730); + avl = remove_int(avl, 37); + avl = grpc_avl_add(avl, box(407), box(2057), nullptr); + avl = grpc_avl_add(avl, box(222), box(2058), nullptr); + avl = grpc_avl_add(avl, box(439), box(2059), nullptr); + avl = grpc_avl_add(avl, box(563), box(2060), nullptr); + avl = remove_int(avl, 992); + avl = remove_int(avl, 786); + avl = grpc_avl_add(avl, box(1), box(2063), nullptr); + avl = grpc_avl_add(avl, box(473), box(2064), nullptr); + avl = grpc_avl_add(avl, box(992), box(2065), nullptr); + avl = remove_int(avl, 190); + avl = remove_int(avl, 450); + avl = remove_int(avl, 1020); + avl = remove_int(avl, 149); + avl = grpc_avl_add(avl, box(329), box(2070), nullptr); + avl = grpc_avl_add(avl, box(35), box(2071), nullptr); + avl = remove_int(avl, 843); + avl = grpc_avl_add(avl, box(855), box(2073), nullptr); + avl = remove_int(avl, 878); + avl = grpc_avl_add(avl, box(993), box(2075), nullptr); + avl = grpc_avl_add(avl, box(87), box(2076), nullptr); + avl = grpc_avl_add(avl, box(572), box(2077), nullptr); + avl = remove_int(avl, 896); + avl = grpc_avl_add(avl, box(849), box(2079), nullptr); + avl = remove_int(avl, 597); + avl = grpc_avl_add(avl, box(472), box(2081), nullptr); + avl = remove_int(avl, 778); + avl = remove_int(avl, 934); + avl = remove_int(avl, 314); + avl = grpc_avl_add(avl, box(101), box(2085), nullptr); + avl = remove_int(avl, 938); + avl = remove_int(avl, 1010); + avl = grpc_avl_add(avl, box(579), box(2088), nullptr); + avl = remove_int(avl, 798); + avl = remove_int(avl, 88); + avl = grpc_avl_add(avl, box(851), box(2091), nullptr); + avl = remove_int(avl, 705); + avl = grpc_avl_add(avl, box(26), box(2093), nullptr); + avl = remove_int(avl, 973); + avl = grpc_avl_add(avl, box(923), box(2095), nullptr); + avl = remove_int(avl, 668); + avl = grpc_avl_add(avl, box(310), box(2097), nullptr); + avl = grpc_avl_add(avl, box(269), box(2098), nullptr); + avl = remove_int(avl, 173); + avl = grpc_avl_add(avl, box(279), box(2100), nullptr); + avl = remove_int(avl, 203); + avl = grpc_avl_add(avl, box(411), box(2102), nullptr); + avl = remove_int(avl, 950); + avl = grpc_avl_add(avl, box(6), box(2104), nullptr); + avl = remove_int(avl, 400); + avl = remove_int(avl, 468); + avl = remove_int(avl, 271); + avl = grpc_avl_add(avl, box(627), box(2108), nullptr); + avl = remove_int(avl, 727); + avl = remove_int(avl, 148); + avl = remove_int(avl, 98); + avl = remove_int(avl, 997); + avl = remove_int(avl, 215); + avl = remove_int(avl, 628); + avl = remove_int(avl, 826); + avl = remove_int(avl, 664); + avl = grpc_avl_add(avl, box(76), box(2117), nullptr); + avl = remove_int(avl, 194); + avl = remove_int(avl, 18); + avl = grpc_avl_add(avl, box(727), box(2120), nullptr); + avl = remove_int(avl, 295); + avl = grpc_avl_add(avl, box(645), box(2122), nullptr); + avl = remove_int(avl, 321); + avl = remove_int(avl, 863); + avl = grpc_avl_add(avl, box(824), box(2125), nullptr); + avl = grpc_avl_add(avl, box(651), box(2126), nullptr); + avl = grpc_avl_add(avl, box(804), box(2127), nullptr); + avl = remove_int(avl, 307); + avl = grpc_avl_add(avl, box(867), box(2129), nullptr); + avl = remove_int(avl, 384); + avl = grpc_avl_add(avl, box(819), box(2131), nullptr); + avl = remove_int(avl, 674); + avl = grpc_avl_add(avl, box(76), box(2133), nullptr); + avl = remove_int(avl, 898); + avl = grpc_avl_add(avl, box(45), box(2135), nullptr); + avl = grpc_avl_add(avl, box(512), box(2136), nullptr); + avl = remove_int(avl, 773); + avl = remove_int(avl, 907); + avl = remove_int(avl, 382); + avl = remove_int(avl, 95); + avl = remove_int(avl, 734); + avl = remove_int(avl, 81); + avl = grpc_avl_add(avl, box(348), box(2143), nullptr); + avl = remove_int(avl, 509); + avl = remove_int(avl, 301); + avl = grpc_avl_add(avl, box(861), box(2146), nullptr); + avl = grpc_avl_add(avl, box(918), box(2147), nullptr); + avl = remove_int(avl, 992); + avl = grpc_avl_add(avl, box(356), box(2149), nullptr); + avl = remove_int(avl, 64); + avl = remove_int(avl, 444); + avl = remove_int(avl, 741); + avl = grpc_avl_add(avl, box(710), box(2153), nullptr); + avl = grpc_avl_add(avl, box(264), box(2154), nullptr); + avl = remove_int(avl, 347); + avl = remove_int(avl, 250); + avl = grpc_avl_add(avl, box(82), box(2157), nullptr); + avl = grpc_avl_add(avl, box(571), box(2158), nullptr); + avl = remove_int(avl, 721); + avl = remove_int(avl, 622); + avl = grpc_avl_add(avl, box(950), box(2161), nullptr); + avl = grpc_avl_add(avl, box(94), box(2162), nullptr); + avl = remove_int(avl, 970); + avl = grpc_avl_add(avl, box(815), box(2164), nullptr); + avl = remove_int(avl, 930); + avl = remove_int(avl, 703); + avl = grpc_avl_add(avl, box(432), box(2167), nullptr); + avl = remove_int(avl, 544); + avl = grpc_avl_add(avl, box(21), box(2169), nullptr); + avl = grpc_avl_add(avl, box(186), box(2170), nullptr); + avl = remove_int(avl, 143); + avl = grpc_avl_add(avl, box(425), box(2172), nullptr); + avl = remove_int(avl, 769); + avl = grpc_avl_add(avl, box(656), box(2174), nullptr); + avl = remove_int(avl, 29); + avl = grpc_avl_add(avl, box(464), box(2176), nullptr); + avl = remove_int(avl, 713); + avl = grpc_avl_add(avl, box(800), box(2178), nullptr); + avl = remove_int(avl, 621); + avl = grpc_avl_add(avl, box(962), box(2180), nullptr); + avl = remove_int(avl, 448); + avl = grpc_avl_add(avl, box(878), box(2182), nullptr); + avl = remove_int(avl, 39); + avl = remove_int(avl, 999); + avl = grpc_avl_add(avl, box(182), box(2185), nullptr); + avl = grpc_avl_add(avl, box(429), box(2186), nullptr); + avl = grpc_avl_add(avl, box(598), box(2187), nullptr); + avl = remove_int(avl, 551); + avl = grpc_avl_add(avl, box(827), box(2189), nullptr); + avl = grpc_avl_add(avl, box(809), box(2190), nullptr); + avl = remove_int(avl, 438); + avl = remove_int(avl, 811); + avl = grpc_avl_add(avl, box(808), box(2193), nullptr); + avl = grpc_avl_add(avl, box(788), box(2194), nullptr); + avl = remove_int(avl, 156); + avl = grpc_avl_add(avl, box(933), box(2196), nullptr); + avl = grpc_avl_add(avl, box(344), box(2197), nullptr); + avl = remove_int(avl, 460); + avl = grpc_avl_add(avl, box(161), box(2199), nullptr); + avl = grpc_avl_add(avl, box(444), box(2200), nullptr); + avl = remove_int(avl, 597); + avl = remove_int(avl, 668); + avl = grpc_avl_add(avl, box(703), box(2203), nullptr); + avl = remove_int(avl, 515); + avl = grpc_avl_add(avl, box(380), box(2205), nullptr); + avl = grpc_avl_add(avl, box(338), box(2206), nullptr); + avl = remove_int(avl, 550); + avl = remove_int(avl, 946); + avl = remove_int(avl, 714); + avl = remove_int(avl, 739); + avl = grpc_avl_add(avl, box(413), box(2211), nullptr); + avl = remove_int(avl, 450); + avl = grpc_avl_add(avl, box(411), box(2213), nullptr); + avl = grpc_avl_add(avl, box(117), box(2214), nullptr); + avl = grpc_avl_add(avl, box(322), box(2215), nullptr); + avl = grpc_avl_add(avl, box(915), box(2216), nullptr); + avl = grpc_avl_add(avl, box(410), box(2217), nullptr); + avl = grpc_avl_add(avl, box(66), box(2218), nullptr); + avl = remove_int(avl, 756); + avl = remove_int(avl, 596); + avl = grpc_avl_add(avl, box(882), box(2221), nullptr); + avl = grpc_avl_add(avl, box(930), box(2222), nullptr); + avl = grpc_avl_add(avl, box(36), box(2223), nullptr); + avl = remove_int(avl, 742); + avl = grpc_avl_add(avl, box(539), box(2225), nullptr); + avl = grpc_avl_add(avl, box(596), box(2226), nullptr); + avl = remove_int(avl, 82); + avl = remove_int(avl, 686); + avl = remove_int(avl, 933); + avl = remove_int(avl, 42); + avl = remove_int(avl, 340); + avl = grpc_avl_add(avl, box(126), box(2232), nullptr); + avl = grpc_avl_add(avl, box(493), box(2233), nullptr); + avl = grpc_avl_add(avl, box(839), box(2234), nullptr); + avl = remove_int(avl, 774); + avl = grpc_avl_add(avl, box(337), box(2236), nullptr); + avl = remove_int(avl, 322); + avl = grpc_avl_add(avl, box(16), box(2238), nullptr); + avl = remove_int(avl, 73); + avl = remove_int(avl, 85); + avl = remove_int(avl, 191); + avl = remove_int(avl, 541); + avl = grpc_avl_add(avl, box(704), box(2243), nullptr); + avl = remove_int(avl, 767); + avl = remove_int(avl, 1006); + avl = remove_int(avl, 844); + avl = remove_int(avl, 742); + avl = grpc_avl_add(avl, box(48), box(2248), nullptr); + avl = grpc_avl_add(avl, box(138), box(2249), nullptr); + avl = grpc_avl_add(avl, box(437), box(2250), nullptr); + avl = grpc_avl_add(avl, box(275), box(2251), nullptr); + avl = remove_int(avl, 520); + avl = grpc_avl_add(avl, box(1019), box(2253), nullptr); + avl = remove_int(avl, 955); + avl = grpc_avl_add(avl, box(270), box(2255), nullptr); + avl = remove_int(avl, 680); + avl = remove_int(avl, 698); + avl = grpc_avl_add(avl, box(735), box(2258), nullptr); + avl = grpc_avl_add(avl, box(400), box(2259), nullptr); + avl = remove_int(avl, 991); + avl = grpc_avl_add(avl, box(263), box(2261), nullptr); + avl = remove_int(avl, 704); + avl = grpc_avl_add(avl, box(757), box(2263), nullptr); + avl = remove_int(avl, 194); + avl = remove_int(avl, 616); + avl = remove_int(avl, 784); + avl = grpc_avl_add(avl, box(382), box(2267), nullptr); + avl = grpc_avl_add(avl, box(464), box(2268), nullptr); + avl = grpc_avl_add(avl, box(817), box(2269), nullptr); + avl = remove_int(avl, 445); + avl = grpc_avl_add(avl, box(412), box(2271), nullptr); + avl = remove_int(avl, 525); + avl = grpc_avl_add(avl, box(299), box(2273), nullptr); + avl = grpc_avl_add(avl, box(464), box(2274), nullptr); + avl = grpc_avl_add(avl, box(715), box(2275), nullptr); + avl = remove_int(avl, 58); + avl = remove_int(avl, 218); + avl = grpc_avl_add(avl, box(961), box(2278), nullptr); + avl = grpc_avl_add(avl, box(491), box(2279), nullptr); + avl = remove_int(avl, 846); + avl = grpc_avl_add(avl, box(762), box(2281), nullptr); + avl = remove_int(avl, 974); + avl = remove_int(avl, 887); + avl = grpc_avl_add(avl, box(498), box(2284), nullptr); + avl = remove_int(avl, 810); + avl = remove_int(avl, 743); + avl = remove_int(avl, 22); + avl = remove_int(avl, 284); + avl = grpc_avl_add(avl, box(482), box(2289), nullptr); + avl = grpc_avl_add(avl, box(1021), box(2290), nullptr); + avl = remove_int(avl, 155); + avl = remove_int(avl, 128); + avl = grpc_avl_add(avl, box(819), box(2293), nullptr); + avl = grpc_avl_add(avl, box(324), box(2294), nullptr); + avl = remove_int(avl, 196); + avl = remove_int(avl, 370); + avl = remove_int(avl, 753); + avl = remove_int(avl, 56); + avl = remove_int(avl, 735); + avl = grpc_avl_add(avl, box(272), box(2300), nullptr); + avl = grpc_avl_add(avl, box(474), box(2301), nullptr); + avl = grpc_avl_add(avl, box(719), box(2302), nullptr); + avl = grpc_avl_add(avl, box(236), box(2303), nullptr); + avl = remove_int(avl, 818); + avl = grpc_avl_add(avl, box(727), box(2305), nullptr); + avl = remove_int(avl, 892); + avl = remove_int(avl, 871); + avl = remove_int(avl, 231); + avl = grpc_avl_add(avl, box(62), box(2309), nullptr); + avl = grpc_avl_add(avl, box(953), box(2310), nullptr); + avl = remove_int(avl, 701); + avl = grpc_avl_add(avl, box(193), box(2312), nullptr); + avl = remove_int(avl, 619); + avl = remove_int(avl, 22); + avl = remove_int(avl, 804); + avl = remove_int(avl, 851); + avl = grpc_avl_add(avl, box(286), box(2317), nullptr); + avl = grpc_avl_add(avl, box(751), box(2318), nullptr); + avl = remove_int(avl, 525); + avl = grpc_avl_add(avl, box(217), box(2320), nullptr); + avl = remove_int(avl, 336); + avl = grpc_avl_add(avl, box(86), box(2322), nullptr); + avl = grpc_avl_add(avl, box(81), box(2323), nullptr); + avl = grpc_avl_add(avl, box(850), box(2324), nullptr); + avl = remove_int(avl, 872); + avl = grpc_avl_add(avl, box(402), box(2326), nullptr); + avl = grpc_avl_add(avl, box(54), box(2327), nullptr); + avl = grpc_avl_add(avl, box(980), box(2328), nullptr); + avl = grpc_avl_add(avl, box(845), box(2329), nullptr); + avl = remove_int(avl, 1004); + avl = remove_int(avl, 273); + avl = remove_int(avl, 879); + avl = grpc_avl_add(avl, box(354), box(2333), nullptr); + avl = grpc_avl_add(avl, box(58), box(2334), nullptr); + avl = grpc_avl_add(avl, box(127), box(2335), nullptr); + avl = remove_int(avl, 84); + avl = grpc_avl_add(avl, box(360), box(2337), nullptr); + avl = remove_int(avl, 648); + avl = remove_int(avl, 488); + avl = remove_int(avl, 585); + avl = remove_int(avl, 230); + avl = grpc_avl_add(avl, box(887), box(2342), nullptr); + avl = remove_int(avl, 558); + avl = remove_int(avl, 958); + avl = grpc_avl_add(avl, box(822), box(2345), nullptr); + avl = remove_int(avl, 1004); + avl = remove_int(avl, 747); + avl = grpc_avl_add(avl, box(631), box(2348), nullptr); + avl = grpc_avl_add(avl, box(442), box(2349), nullptr); + avl = remove_int(avl, 957); + avl = remove_int(avl, 964); + avl = grpc_avl_add(avl, box(10), box(2352), nullptr); + avl = remove_int(avl, 189); + avl = grpc_avl_add(avl, box(742), box(2354), nullptr); + avl = remove_int(avl, 108); + avl = grpc_avl_add(avl, box(1014), box(2356), nullptr); + avl = remove_int(avl, 266); + avl = remove_int(avl, 623); + avl = remove_int(avl, 697); + avl = grpc_avl_add(avl, box(180), box(2360), nullptr); + avl = remove_int(avl, 472); + avl = grpc_avl_add(avl, box(567), box(2362), nullptr); + avl = remove_int(avl, 1020); + avl = remove_int(avl, 273); + avl = grpc_avl_add(avl, box(864), box(2365), nullptr); + avl = grpc_avl_add(avl, box(1009), box(2366), nullptr); + avl = remove_int(avl, 224); + avl = remove_int(avl, 81); + avl = grpc_avl_add(avl, box(653), box(2369), nullptr); + avl = remove_int(avl, 67); + avl = remove_int(avl, 102); + avl = remove_int(avl, 76); + avl = remove_int(avl, 935); + avl = remove_int(avl, 169); + avl = remove_int(avl, 232); + avl = remove_int(avl, 79); + avl = grpc_avl_add(avl, box(509), box(2377), nullptr); + avl = remove_int(avl, 900); + avl = remove_int(avl, 822); + avl = remove_int(avl, 945); + avl = remove_int(avl, 356); + avl = grpc_avl_add(avl, box(443), box(2382), nullptr); + avl = grpc_avl_add(avl, box(925), box(2383), nullptr); + avl = remove_int(avl, 994); + avl = remove_int(avl, 324); + avl = grpc_avl_add(avl, box(291), box(2386), nullptr); + avl = remove_int(avl, 94); + avl = remove_int(avl, 795); + avl = remove_int(avl, 42); + avl = grpc_avl_add(avl, box(613), box(2390), nullptr); + avl = remove_int(avl, 289); + avl = grpc_avl_add(avl, box(980), box(2392), nullptr); + avl = remove_int(avl, 316); + avl = grpc_avl_add(avl, box(281), box(2394), nullptr); + avl = grpc_avl_add(avl, box(1006), box(2395), nullptr); + avl = remove_int(avl, 776); + avl = grpc_avl_add(avl, box(108), box(2397), nullptr); + avl = grpc_avl_add(avl, box(918), box(2398), nullptr); + avl = remove_int(avl, 721); + avl = remove_int(avl, 563); + avl = grpc_avl_add(avl, box(925), box(2401), nullptr); + avl = remove_int(avl, 448); + avl = remove_int(avl, 198); + avl = remove_int(avl, 1); + avl = grpc_avl_add(avl, box(160), box(2405), nullptr); + avl = remove_int(avl, 515); + avl = grpc_avl_add(avl, box(284), box(2407), nullptr); + avl = grpc_avl_add(avl, box(225), box(2408), nullptr); + avl = remove_int(avl, 304); + avl = grpc_avl_add(avl, box(714), box(2410), nullptr); + avl = grpc_avl_add(avl, box(708), box(2411), nullptr); + avl = grpc_avl_add(avl, box(624), box(2412), nullptr); + avl = remove_int(avl, 662); + avl = remove_int(avl, 825); + avl = remove_int(avl, 383); + avl = remove_int(avl, 381); + avl = grpc_avl_add(avl, box(194), box(2417), nullptr); + avl = remove_int(avl, 280); + avl = remove_int(avl, 25); + avl = remove_int(avl, 633); + avl = grpc_avl_add(avl, box(897), box(2421), nullptr); + avl = remove_int(avl, 636); + avl = remove_int(avl, 596); + avl = remove_int(avl, 757); + avl = remove_int(avl, 343); + avl = remove_int(avl, 162); + avl = remove_int(avl, 913); + avl = remove_int(avl, 843); + avl = remove_int(avl, 280); + avl = remove_int(avl, 911); + avl = grpc_avl_add(avl, box(1008), box(2431), nullptr); + avl = remove_int(avl, 948); + avl = remove_int(avl, 74); + avl = remove_int(avl, 571); + avl = grpc_avl_add(avl, box(486), box(2435), nullptr); + avl = grpc_avl_add(avl, box(285), box(2436), nullptr); + avl = remove_int(avl, 304); + avl = remove_int(avl, 516); + avl = grpc_avl_add(avl, box(758), box(2439), nullptr); + avl = grpc_avl_add(avl, box(776), box(2440), nullptr); + avl = remove_int(avl, 696); + avl = grpc_avl_add(avl, box(104), box(2442), nullptr); + avl = grpc_avl_add(avl, box(700), box(2443), nullptr); + avl = grpc_avl_add(avl, box(114), box(2444), nullptr); + avl = grpc_avl_add(avl, box(567), box(2445), nullptr); + avl = remove_int(avl, 620); + avl = grpc_avl_add(avl, box(270), box(2447), nullptr); + avl = remove_int(avl, 730); + avl = grpc_avl_add(avl, box(749), box(2449), nullptr); + avl = grpc_avl_add(avl, box(443), box(2450), nullptr); + avl = remove_int(avl, 457); + avl = grpc_avl_add(avl, box(571), box(2452), nullptr); + avl = grpc_avl_add(avl, box(626), box(2453), nullptr); + avl = remove_int(avl, 638); + avl = remove_int(avl, 313); + + grpc_avl_unref(avl, nullptr); +} + +static void test_stress(int amount_of_stress) { + int added[1024]; + int i, j; + int deletions = 0; + grpc_avl avl; + + unsigned seed = static_cast<unsigned>(time(nullptr)); + + gpr_log(GPR_DEBUG, "test_stress amount=%d seed=%u", amount_of_stress, seed); + + srand(static_cast<unsigned>(time(nullptr))); + avl = grpc_avl_create(&int_int_vtable); + + memset(added, 0, sizeof(added)); + + for (i = 1; deletions < amount_of_stress; i++) { + int idx = rand() % static_cast<int> GPR_ARRAY_SIZE(added); + GPR_ASSERT(i); + if (rand() < RAND_MAX / 2) { + added[idx] = i; + printf("avl = grpc_avl_add(avl, box(%d), box(%d), NULL); /* d=%d */\n", + idx, i, deletions); + avl = grpc_avl_add(avl, box(idx), box(i), nullptr); + } else { + deletions += (added[idx] != 0); + added[idx] = 0; + printf("avl = remove_int(avl, %d); /* d=%d */\n", idx, deletions); + avl = remove_int(avl, idx); + } + for (j = 0; j < static_cast<int> GPR_ARRAY_SIZE(added); j++) { + if (added[j] != 0) { + check_get(avl, j, added[j]); + } else { + check_negget(avl, j); + } + } + } + + grpc_avl_unref(avl, nullptr); +} + +int main(int argc, char* argv[]) { + grpc_test_init(argc, argv); + + test_get(); + test_ll(); + test_lr(); + test_rr(); + test_rl(); + test_unbalanced(); + test_replace(); + test_remove(); + test_badcase1(); + test_badcase2(); + test_badcase3(); + test_stress(10); + + return 0; +} diff --git a/test/core/backoff/BUILD b/test/core/backoff/BUILD index 4cd7acf066..6fbd6542d4 100644 --- a/test/core/backoff/BUILD +++ b/test/core/backoff/BUILD @@ -26,11 +26,14 @@ package( grpc_cc_test( name = "backoff_test", srcs = ["backoff_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ - "//:grpc", - "//test/core/util:grpc_test_util", "//:gpr", + "//:grpc", "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/backoff/backoff_test.cc b/test/core/backoff/backoff_test.cc index d3115fe1dd..1998a83977 100644 --- a/test/core/backoff/backoff_test.cc +++ b/test/core/backoff/backoff_test.cc @@ -18,171 +18,160 @@ #include "src/core/lib/backoff/backoff.h" -#include <grpc/grpc.h> +#include <algorithm> + #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include <gtest/gtest.h> #include "test/core/util/test_config.h" -static void test_constant_backoff(void) { - grpc_backoff backoff; +namespace grpc { +namespace testing { +namespace { + +using grpc_core::BackOff; + +TEST(BackOffTest, ConstantBackOff) { const grpc_millis initial_backoff = 200; const double multiplier = 1.0; const double jitter = 0.0; - const grpc_millis min_connect_timeout = 100; const grpc_millis max_backoff = 1000; - grpc_backoff_init(&backoff, initial_backoff, multiplier, jitter, - min_connect_timeout, max_backoff); grpc_core::ExecCtx exec_ctx; - grpc_backoff_result next_deadlines = grpc_backoff_begin(&backoff); - GPR_ASSERT(next_deadlines.current_deadline - - grpc_core::ExecCtx::Get()->Now() == - initial_backoff); - GPR_ASSERT(next_deadlines.next_attempt_start_time - - grpc_core::ExecCtx::Get()->Now() == - initial_backoff); + BackOff::Options options; + options.set_initial_backoff(initial_backoff) + .set_multiplier(multiplier) + .set_jitter(jitter) + .set_max_backoff(max_backoff); + BackOff backoff(options); + + grpc_millis next_attempt_start_time = backoff.NextAttemptTime(); + EXPECT_EQ(next_attempt_start_time - grpc_core::ExecCtx::Get()->Now(), + initial_backoff); for (int i = 0; i < 10000; i++) { - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline - - grpc_core::ExecCtx::Get()->Now() == - initial_backoff); - GPR_ASSERT(next_deadlines.next_attempt_start_time - - grpc_core::ExecCtx::Get()->Now() == - initial_backoff); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); + next_attempt_start_time = backoff.NextAttemptTime(); + EXPECT_EQ(next_attempt_start_time - grpc_core::ExecCtx::Get()->Now(), + initial_backoff); } } -static void test_min_connect(void) { - grpc_backoff backoff; +TEST(BackOffTest, MinConnect) { const grpc_millis initial_backoff = 100; const double multiplier = 1.0; const double jitter = 0.0; - const grpc_millis min_connect_timeout = 200; const grpc_millis max_backoff = 1000; - grpc_backoff_init(&backoff, initial_backoff, multiplier, jitter, - min_connect_timeout, max_backoff); grpc_core::ExecCtx exec_ctx; - grpc_backoff_result next = grpc_backoff_begin(&backoff); - // Because the min_connect_timeout > initial_backoff, current_deadline is used - // as the deadline for the current attempt. - GPR_ASSERT(next.current_deadline - grpc_core::ExecCtx::Get()->Now() == - min_connect_timeout); - // ... while, if the current attempt fails, the next one will happen after - // initial_backoff. - GPR_ASSERT(next.next_attempt_start_time - grpc_core::ExecCtx::Get()->Now() == - initial_backoff); + BackOff::Options options; + options.set_initial_backoff(initial_backoff) + .set_multiplier(multiplier) + .set_jitter(jitter) + .set_max_backoff(max_backoff); + BackOff backoff(options); + grpc_millis next = backoff.NextAttemptTime(); + EXPECT_EQ(next - grpc_core::ExecCtx::Get()->Now(), initial_backoff); } -static void test_no_jitter_backoff(void) { - grpc_backoff backoff; +TEST(BackOffTest, NoJitterBackOff) { const grpc_millis initial_backoff = 2; const double multiplier = 2.0; const double jitter = 0.0; - const grpc_millis min_connect_timeout = 1; const grpc_millis max_backoff = 513; - grpc_backoff_init(&backoff, initial_backoff, multiplier, jitter, - min_connect_timeout, max_backoff); + BackOff::Options options; + options.set_initial_backoff(initial_backoff) + .set_multiplier(multiplier) + .set_jitter(jitter) + .set_max_backoff(max_backoff); + BackOff backoff(options); // x_1 = 2 // x_n = 2**i + x_{i-1} ( = 2**(n+1) - 2 ) grpc_core::ExecCtx exec_ctx; grpc_core::ExecCtx::Get()->TestOnlySetNow(0); - grpc_backoff_result next_deadlines = grpc_backoff_begin(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == - next_deadlines.next_attempt_start_time); - GPR_ASSERT(next_deadlines.current_deadline == 2); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 6); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 14); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 30); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 62); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 126); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 254); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 510); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 1022); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); + grpc_millis next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 2); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 6); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 14); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 30); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 62); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 126); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 254); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 510); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 1022); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); // Hit the maximum timeout. From this point onwards, retries will increase // only by max timeout. - GPR_ASSERT(next_deadlines.current_deadline == 1535); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 2048); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); - next_deadlines = grpc_backoff_step(&backoff); - GPR_ASSERT(next_deadlines.current_deadline == 2561); + EXPECT_EQ(next, 1535); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 2048); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.NextAttemptTime(); + EXPECT_EQ(next, 2561); } -static void test_jitter_backoff(void) { +TEST(BackOffTest, JitterBackOff) { const grpc_millis initial_backoff = 500; grpc_millis current_backoff = initial_backoff; const grpc_millis max_backoff = 1000; - const grpc_millis min_connect_timeout = 100; const double multiplier = 1.0; const double jitter = 0.1; - grpc_backoff backoff; - grpc_backoff_init(&backoff, initial_backoff, multiplier, jitter, - min_connect_timeout, max_backoff); + BackOff::Options options; + options.set_initial_backoff(initial_backoff) + .set_multiplier(multiplier) + .set_jitter(jitter) + .set_max_backoff(max_backoff); + BackOff backoff(options); - backoff.rng_state = 0; // force consistent PRNG + backoff.SetRandomSeed(0); // force consistent PRNG grpc_core::ExecCtx exec_ctx; - grpc_backoff_result next_deadlines = grpc_backoff_begin(&backoff); - GPR_ASSERT(next_deadlines.current_deadline - - grpc_core::ExecCtx::Get()->Now() == - initial_backoff); - GPR_ASSERT(next_deadlines.next_attempt_start_time - - grpc_core::ExecCtx::Get()->Now() == - initial_backoff); - - grpc_millis expected_next_lower_bound = - (grpc_millis)((double)current_backoff * (1 - jitter)); - grpc_millis expected_next_upper_bound = - (grpc_millis)((double)current_backoff * (1 + jitter)); + grpc_millis next = backoff.NextAttemptTime(); + EXPECT_EQ(next - grpc_core::ExecCtx::Get()->Now(), initial_backoff); + + grpc_millis expected_next_lower_bound = static_cast<grpc_millis>( + static_cast<double>(current_backoff) * (1 - jitter)); + grpc_millis expected_next_upper_bound = static_cast<grpc_millis>( + static_cast<double>(current_backoff) * (1 + jitter)); for (int i = 0; i < 10000; i++) { - next_deadlines = grpc_backoff_step(&backoff); + next = backoff.NextAttemptTime(); // next-now must be within (jitter*100)% of the current backoff (which // increases by * multiplier up to max_backoff). - const grpc_millis timeout_millis = - next_deadlines.current_deadline - grpc_core::ExecCtx::Get()->Now(); - GPR_ASSERT(timeout_millis >= expected_next_lower_bound); - GPR_ASSERT(timeout_millis <= expected_next_upper_bound); - current_backoff = GPR_MIN( - (grpc_millis)((double)current_backoff * multiplier), max_backoff); - expected_next_lower_bound = - (grpc_millis)((double)current_backoff * (1 - jitter)); - expected_next_upper_bound = - (grpc_millis)((double)current_backoff * (1 + jitter)); - grpc_core::ExecCtx::Get()->TestOnlySetNow(next_deadlines.current_deadline); + const grpc_millis timeout_millis = next - grpc_core::ExecCtx::Get()->Now(); + EXPECT_GE(timeout_millis, expected_next_lower_bound); + EXPECT_LE(timeout_millis, expected_next_upper_bound); + current_backoff = + std::min(static_cast<grpc_millis>(static_cast<double>(current_backoff) * + multiplier), + max_backoff); + expected_next_lower_bound = static_cast<grpc_millis>( + static_cast<double>(current_backoff) * (1 - jitter)); + expected_next_upper_bound = static_cast<grpc_millis>( + static_cast<double>(current_backoff) * (1 + jitter)); } } +} // namespace +} // namespace testing +} // namespace grpc + int main(int argc, char** argv) { grpc_test_init(argc, argv); - grpc_init(); - gpr_time_init(); - - test_constant_backoff(); - test_min_connect(); - test_no_jitter_backoff(); - test_jitter_backoff(); - - grpc_shutdown(); - return 0; + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index 4c1642aa5d..c03ebcf409 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -23,175 +23,220 @@ #include <grpc/support/alloc.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/support/murmur_hash.h" -#include "src/core/lib/support/string.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" +#include "test/core/end2end/cq_verifier.h" +#define MIN_HTTP2_FRAME_SIZE 9 + +/* Args to provide to thread running server side validator */ typedef struct { grpc_server* server; grpc_completion_queue* cq; grpc_bad_client_server_side_validator validator; void* registered_method; gpr_event done_thd; - gpr_event done_write; } thd_args; +/* Run the server side validator and set done_thd once done */ static void thd_func(void* arg) { - thd_args* a = (thd_args*)arg; - a->validator(a->server, a->cq, a->registered_method); + thd_args* a = static_cast<thd_args*>(arg); + if (a->validator != nullptr) { + a->validator(a->server, a->cq, a->registered_method); + } gpr_event_set(&a->done_thd, (void*)1); } -static void done_write(void* arg, grpc_error* error) { - thd_args* a = (thd_args*)arg; - gpr_event_set(&a->done_write, (void*)1); +/* Sets the done_write event */ +static void set_done_write(void* arg, grpc_error* error) { + gpr_event* done_write = static_cast<gpr_event*>(arg); + gpr_event_set(done_write, (void*)1); } static void server_setup_transport(void* ts, grpc_transport* transport) { - thd_args* a = (thd_args*)ts; + thd_args* a = static_cast<thd_args*>(ts); grpc_core::ExecCtx exec_ctx; grpc_server_setup_transport(a->server, transport, nullptr, grpc_server_get_channel_args(a->server)); } -static void read_done(void* arg, grpc_error* error) { - gpr_event* read_done = (gpr_event*)arg; +/* Sets the read_done event */ +static void set_read_done(void* arg, grpc_error* error) { + gpr_event* read_done = static_cast<gpr_event*>(arg); gpr_event_set(read_done, (void*)1); } -void grpc_run_bad_client_test( - grpc_bad_client_server_side_validator server_validator, - grpc_bad_client_client_stream_validator client_validator, - const char* client_payload, size_t client_payload_length, uint32_t flags) { - grpc_endpoint_pair sfd; - thd_args a; - gpr_thd_id id; - char* hex; - grpc_transport* transport; - grpc_slice slice = - grpc_slice_from_copied_buffer(client_payload, client_payload_length); - grpc_slice_buffer outgoing; - grpc_closure done_write_closure; - grpc_core::ExecCtx exec_ctx; - grpc_completion_queue* shutdown_cq; +/* shutdown client */ +static void shutdown_client(grpc_endpoint** client_fd) { + if (*client_fd != nullptr) { + grpc_endpoint_shutdown( + *client_fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Disconnect")); + grpc_endpoint_destroy(*client_fd); + grpc_core::ExecCtx::Get()->Flush(); + *client_fd = nullptr; + } +} - if (client_payload_length < 4 * 1024) { - hex = gpr_dump(client_payload, client_payload_length, +/* Runs client side validator */ +void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, + grpc_endpoint_pair* sfd, + grpc_completion_queue* client_cq) { + char* hex; + gpr_event done_write; + if (arg->client_payload_length < 4 * 1024) { + hex = gpr_dump(arg->client_payload, arg->client_payload_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); - /* Add a debug log */ gpr_log(GPR_INFO, "TEST: %s", hex); - gpr_free(hex); } else { gpr_log(GPR_INFO, "TEST: (%" PRIdPTR " byte long string)", - client_payload_length); + arg->client_payload_length); } - /* Init grpc */ - grpc_init(); - - /* Create endpoints */ - sfd = grpc_iomgr_create_endpoint_pair("fixture", nullptr); - - /* Create server, completion events */ - a.server = grpc_server_create(nullptr, nullptr); - a.cq = grpc_completion_queue_create_for_next(nullptr); - gpr_event_init(&a.done_thd); - gpr_event_init(&a.done_write); - a.validator = server_validator; - grpc_server_register_completion_queue(a.server, a.cq, nullptr); - a.registered_method = - grpc_server_register_method(a.server, GRPC_BAD_CLIENT_REGISTERED_METHOD, - GRPC_BAD_CLIENT_REGISTERED_HOST, - GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, 0); - grpc_server_start(a.server); - transport = grpc_create_chttp2_transport(nullptr, sfd.server, false); - server_setup_transport(&a, transport); - grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); - - /* Bind everything into the same pollset */ - grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(a.cq)); - grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq)); - - /* Check a ground truth */ - GPR_ASSERT(grpc_server_has_open_connections(a.server)); - - /* Start validator */ - gpr_thd_new(&id, "grpc_bad_client", thd_func, &a, nullptr); + grpc_slice slice = grpc_slice_from_copied_buffer(arg->client_payload, + arg->client_payload_length); + grpc_slice_buffer outgoing; + grpc_closure done_write_closure; + gpr_event_init(&done_write); grpc_slice_buffer_init(&outgoing); grpc_slice_buffer_add(&outgoing, slice); - GRPC_CLOSURE_INIT(&done_write_closure, done_write, &a, + GRPC_CLOSURE_INIT(&done_write_closure, set_done_write, &done_write, grpc_schedule_on_exec_ctx); /* Write data */ - grpc_endpoint_write(sfd.client, &outgoing, &done_write_closure); + grpc_endpoint_write(sfd->client, &outgoing, &done_write_closure); grpc_core::ExecCtx::Get()->Flush(); /* Await completion, unless the request is large and write may not finish * before the peer shuts down. */ if (!(flags & GRPC_BAD_CLIENT_LARGE_REQUEST)) { GPR_ASSERT( - gpr_event_wait(&a.done_write, grpc_timeout_seconds_to_deadline(5))); + gpr_event_wait(&done_write, grpc_timeout_seconds_to_deadline(5))); } if (flags & GRPC_BAD_CLIENT_DISCONNECT) { - grpc_endpoint_shutdown( - sfd.client, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Disconnect")); - grpc_endpoint_destroy(sfd.client); - grpc_core::ExecCtx::Get()->Flush(); - sfd.client = nullptr; + shutdown_client(&sfd->client); } - GPR_ASSERT(gpr_event_wait(&a.done_thd, grpc_timeout_seconds_to_deadline(5))); - - if (sfd.client != nullptr) { - // Validate client stream, if requested. - if (client_validator != nullptr) { + if (sfd->client != nullptr) { + /* Validate client stream, if requested. */ + if (arg->client_validator != nullptr) { gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5); grpc_slice_buffer incoming; grpc_slice_buffer_init(&incoming); - // We may need to do multiple reads to read the complete server response. + /* We may need to do multiple reads to read the complete server + * response. */ while (true) { gpr_event read_done_event; gpr_event_init(&read_done_event); grpc_closure read_done_closure; - GRPC_CLOSURE_INIT(&read_done_closure, read_done, &read_done_event, + GRPC_CLOSURE_INIT(&read_done_closure, set_read_done, &read_done_event, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(sfd.client, &incoming, &read_done_closure); + grpc_endpoint_read(sfd->client, &incoming, &read_done_closure); grpc_core::ExecCtx::Get()->Flush(); do { GPR_ASSERT(gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0); - GPR_ASSERT( - grpc_completion_queue_next( - a.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr) - .type == GRPC_QUEUE_TIMEOUT); + /* Perform a cq next just to provide a thread that can read incoming + bytes on the client fd */ + GPR_ASSERT(grpc_completion_queue_next( + client_cq, grpc_timeout_milliseconds_to_deadline(100), + nullptr) + .type == GRPC_QUEUE_TIMEOUT); } while (!gpr_event_get(&read_done_event)); - if (client_validator(&incoming)) break; + if (arg->client_validator(&incoming, arg->client_validator_arg)) break; gpr_log(GPR_INFO, "client validator failed; trying additional read " "in case we didn't get all the data"); } grpc_slice_buffer_destroy_internal(&incoming); } - // Shutdown. - grpc_endpoint_shutdown( - sfd.client, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown")); - grpc_endpoint_destroy(sfd.client); grpc_core::ExecCtx::Get()->Flush(); } - GPR_ASSERT( - gpr_event_wait(&a.done_write, grpc_timeout_seconds_to_deadline(1))); + /* If the request was too large, then we need to forcefully shut down the + * client, so that the write can be considered completed */ + if (flags & GRPC_BAD_CLIENT_LARGE_REQUEST) { + shutdown_client(&sfd->client); + } + + /* Make sure that the client is done writing */ + while (!gpr_event_get(&done_write)) { + GPR_ASSERT( + grpc_completion_queue_next( + client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr) + .type == GRPC_QUEUE_TIMEOUT); + } + + grpc_slice_buffer_destroy_internal(&outgoing); + grpc_core::ExecCtx::Get()->Flush(); +} + +void grpc_run_bad_client_test( + grpc_bad_client_server_side_validator server_validator, + grpc_bad_client_arg args[], int num_args, uint32_t flags) { + grpc_endpoint_pair sfd; + thd_args a; + grpc_transport* transport; + grpc_core::ExecCtx exec_ctx; + grpc_completion_queue* shutdown_cq; + grpc_completion_queue* client_cq; + + /* Init grpc */ + grpc_init(); + + /* Create endpoints */ + sfd = grpc_iomgr_create_endpoint_pair("fixture", nullptr); + + /* Create server, completion events */ + a.server = grpc_server_create(nullptr, nullptr); + a.cq = grpc_completion_queue_create_for_next(nullptr); + client_cq = grpc_completion_queue_create_for_next(nullptr); + + grpc_server_register_completion_queue(a.server, a.cq, nullptr); + a.registered_method = + grpc_server_register_method(a.server, GRPC_BAD_CLIENT_REGISTERED_METHOD, + GRPC_BAD_CLIENT_REGISTERED_HOST, + GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, 0); + grpc_server_start(a.server); + transport = grpc_create_chttp2_transport(nullptr, sfd.server, false); + server_setup_transport(&a, transport); + grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); + + /* Bind fds to pollsets */ + grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(client_cq)); + grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq)); + + /* Check a ground truth */ + GPR_ASSERT(grpc_server_has_open_connections(a.server)); + + gpr_event_init(&a.done_thd); + a.validator = server_validator; + /* Start validator */ + + grpc_core::Thread server_validator_thd("grpc_bad_client", thd_func, &a); + server_validator_thd.Start(); + for (int i = 0; i < num_args; i++) { + grpc_run_client_side_validator(&args[i], i == (num_args - 1) ? flags : 0, + &sfd, client_cq); + } + /* Wait for server thread to finish */ + GPR_ASSERT(gpr_event_wait(&a.done_thd, grpc_timeout_seconds_to_deadline(1))); + + /* Shutdown. */ + shutdown_client(&sfd.client); + server_validator_thd.Join(); + shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); grpc_server_shutdown_and_notify(a.server, shutdown_cq, nullptr); GPR_ASSERT(grpc_completion_queue_pluck(shutdown_cq, nullptr, @@ -201,7 +246,91 @@ void grpc_run_bad_client_test( grpc_completion_queue_destroy(shutdown_cq); grpc_server_destroy(a.server); grpc_completion_queue_destroy(a.cq); - grpc_slice_buffer_destroy_internal(&outgoing); - + grpc_completion_queue_destroy(client_cq); grpc_shutdown(); } + +bool client_connection_preface_validator(grpc_slice_buffer* incoming, + void* arg) { + if (incoming->count < 1) { + return false; + } + grpc_slice slice = incoming->slices[0]; + /* There should be atleast a settings frame present */ + if (GRPC_SLICE_LENGTH(slice) < MIN_HTTP2_FRAME_SIZE) { + return false; + } + const uint8_t* p = GRPC_SLICE_START_PTR(slice); + /* Check the frame type (SETTINGS) */ + if (*(p + 3) != 4) { + return false; + } + return true; +} + +/* connection preface and settings frame to be sent by the client */ +#define CONNECTION_PREFACE_FROM_CLIENT \ + "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ + "\x00\x00\x00\x04\x00\x00\x00\x00\x00" + +grpc_bad_client_arg connection_preface_arg = { + client_connection_preface_validator, nullptr, + CONNECTION_PREFACE_FROM_CLIENT, sizeof(CONNECTION_PREFACE_FROM_CLIENT) - 1}; + +bool rst_stream_client_validator(grpc_slice_buffer* incoming, void* arg) { + // Get last frame from incoming slice buffer. + grpc_slice_buffer last_frame_buffer; + grpc_slice_buffer_init(&last_frame_buffer); + grpc_slice_buffer_trim_end(incoming, 13, &last_frame_buffer); + GPR_ASSERT(last_frame_buffer.count == 1); + grpc_slice last_frame = last_frame_buffer.slices[0]; + + const uint8_t* p = GRPC_SLICE_START_PTR(last_frame); + bool success = + // Length == 4 + *p++ != 0 || *p++ != 0 || *p++ != 4 || + // Frame type (RST_STREAM) + *p++ != 3 || + // Flags + *p++ != 0 || + // Stream ID. + *p++ != 0 || *p++ != 0 || *p++ != 0 || *p++ != 1 || + // Payload (error code) + *p++ == 0 || *p++ == 0 || *p++ == 0 || *p == 0 || *p == 11; + + if (!success) { + gpr_log(GPR_INFO, "client expected RST_STREAM frame, not found"); + } + + grpc_slice_buffer_destroy(&last_frame_buffer); + return success; +} + +static void* tag(intptr_t t) { return (void*)t; } + +void server_verifier_request_call(grpc_server* server, + grpc_completion_queue* cq, + void* registered_method) { + grpc_call_error error; + grpc_call* s; + grpc_call_details call_details; + cq_verifier* cqv = cq_verifier_create(cq); + grpc_metadata_array request_metadata_recv; + + grpc_call_details_init(&call_details); + grpc_metadata_array_init(&request_metadata_recv); + + error = grpc_server_request_call(server, &s, &call_details, + &request_metadata_recv, cq, cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar")); + + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_unref(s); + cq_verifier_destroy(cqv); +} diff --git a/test/core/bad_client/bad_client.h b/test/core/bad_client/bad_client.h index d3abfac2aa..de7d830cd7 100644 --- a/test/core/bad_client/bad_client.h +++ b/test/core/bad_client/bad_client.h @@ -28,30 +28,69 @@ #define GRPC_BAD_CLIENT_REGISTERED_METHOD "/registered/bar" #define GRPC_BAD_CLIENT_REGISTERED_HOST "localhost" +/* The server side validator function to run */ typedef void (*grpc_bad_client_server_side_validator)(grpc_server* server, grpc_completion_queue* cq, void* registered_method); -// Returns false if we need to read more data. +/* Returns false if we need to read more data. */ typedef bool (*grpc_bad_client_client_stream_validator)( - grpc_slice_buffer* incoming); + grpc_slice_buffer* incoming, void* arg); +struct grpc_bad_client_arg { + grpc_bad_client_client_stream_validator client_validator; + void* client_validator_arg; + const char* client_payload; + size_t client_payload_length; +}; + +/* Flags for grpc_run_bad_client_test */ #define GRPC_BAD_CLIENT_DISCONNECT 1 #define GRPC_BAD_CLIENT_LARGE_REQUEST 2 /* Test runner. - - Create a server, and send client_payload to it as bytes from a client. - Execute server_validator in a separate thread to assert that the bytes are - handled as expected. */ + * + * Create a server, and for each arg in \a args send client_payload. For each + * payload, run client_validator to make sure that the response is as expected. + * Also execute \a server_validator in a separate thread to assert that the + * bytes are handled as expected. + * + * The flags are only applicable to the last validator in the array. (This can + * be changed in the future if necessary) + */ void grpc_run_bad_client_test( grpc_bad_client_server_side_validator server_validator, - grpc_bad_client_client_stream_validator client_validator, - const char* client_payload, size_t client_payload_length, uint32_t flags); + grpc_bad_client_arg args[], int num_args, uint32_t flags); + +/* A hack to let old tests work as before. In these tests, instead of an array, + * the tests provide a single client_validator and payload + */ +#define COMBINE1(X, Y) X##Y +#define COMBINE(X, Y) COMBINE1(X, Y) + +#define GRPC_RUN_BAD_CLIENT_TEST(server_validator, client_validator, payload, \ + flags) \ + grpc_bad_client_arg COMBINE(bca, __LINE__) = {client_validator, nullptr, \ + payload, sizeof(payload) - 1}; \ + grpc_run_bad_client_test(server_validator, &COMBINE(bca, __LINE__), 1, flags) + +/* Helper validator functions */ +/* Client side validator for connection preface from server. \a arg is unused */ +bool client_connection_preface_validator(grpc_slice_buffer* incoming, + void* arg); + +/* Client side validator for checking if reset stream is present at the end + * of the buffer. \a arg is unused. + */ +bool rst_stream_client_validator(grpc_slice_buffer* incoming, void* arg); -#define GRPC_RUN_BAD_CLIENT_TEST(server_validator, client_validator, payload, \ - flags) \ - grpc_run_bad_client_test(server_validator, client_validator, payload, \ - sizeof(payload) - 1, flags) +/* Helper grpc_bad_client_arg arguments for direct use */ +/* Sends a connection preface from the client with an empty settings frame */ +extern grpc_bad_client_arg connection_preface_arg; +/* Server side verifier function that performs a + * single grpc_server_request_call */ +void server_verifier_request_call(grpc_server* server, + grpc_completion_queue* cq, + void* registered_method); #endif /* GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H */ diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index 14c8a27334..32afba5b1f 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -27,10 +27,11 @@ default_test_options = TestOptions(False, 1.0) BAD_CLIENT_TESTS = { 'badreq': default_test_options, 'connection_prefix': default_test_options._replace(cpu_cost=0.2), + 'duplicate_header': default_test_options, 'headers': default_test_options._replace(cpu_cost=0.2), 'initial_settings_frame': default_test_options._replace(cpu_cost=0.2), 'head_of_line_blocking': default_test_options, - # 'large_metadata': default_test_options, #disabling as per issue #11745 + 'large_metadata': default_test_options, 'server_registered_method': default_test_options, 'simple_request': default_test_options, 'window_overflow': default_test_options, diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index 022edf3ff3..2769d5c3bb 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -16,6 +16,7 @@ """Generates the appropriate build.json data for all the bad_client tests.""" +load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library") def test_options(): return struct() @@ -25,10 +26,11 @@ def test_options(): BAD_CLIENT_TESTS = { 'badreq': test_options(), 'connection_prefix': test_options(), + 'duplicate_header': test_options(), 'headers': test_options(), 'initial_settings_frame': test_options(), 'head_of_line_blocking': test_options(), - # 'large_metadata': test_options(), # disabling as per issue #11745 + 'large_metadata': test_options(), 'server_registered_method': test_options(), 'simple_request': test_options(), 'window_overflow': test_options(), @@ -36,14 +38,14 @@ BAD_CLIENT_TESTS = { } def grpc_bad_client_tests(): - native.cc_library( + grpc_cc_library( name = 'bad_client_test', srcs = ['bad_client.cc'], hdrs = ['bad_client.h'], deps = ['//test/core/util:grpc_test_util', '//:grpc', '//:gpr', '//test/core/end2end:cq_verifier'] ) for t, topt in BAD_CLIENT_TESTS.items(): - native.cc_test( + grpc_cc_test( name = '%s_bad_client_test' % t, srcs = ['tests/%s.cc' % t], deps = [':bad_client_test'], diff --git a/test/core/bad_client/tests/duplicate_header.cc b/test/core/bad_client/tests/duplicate_header.cc new file mode 100644 index 0000000000..e3cae8b595 --- /dev/null +++ b/test/core/bad_client/tests/duplicate_header.cc @@ -0,0 +1,136 @@ +/* + * + * 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/bad_client/bad_client.h" + +#include <string.h> + +#include <grpc/grpc.h> + +#include "src/core/lib/surface/server.h" +#include "test/core/end2end/cq_verifier.h" + +#define PFX_STR \ + "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ + "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */ + +#define HEADER_STR \ + "\x00\x00\xc9\x01\x04\x00\x00\x00\x01" /* headers: generated from \ + simple_request.headers in this \ + directory */ \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15" \ + "deflate,identity,gzip" \ + "\x10\x02te\x08trailers" \ + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + +#define PAYLOAD_STR \ + "\x00\x00\x20\x00\x00\x00\x00\x00\x01" \ + "\x00\x00\x00\x00" + +static void* tag(intptr_t t) { return (void*)t; } + +static void verifier(grpc_server* server, grpc_completion_queue* cq, + void* registered_method) { + grpc_call_error error; + grpc_call* s; + grpc_call_details call_details; + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_op* op; + grpc_op ops[6]; + cq_verifier* cqv = cq_verifier_create(cq); + grpc_metadata_array request_metadata_recv; + int was_cancelled = 2; + + grpc_call_details_init(&call_details); + grpc_metadata_array_init(&request_metadata_recv); + + error = grpc_server_request_call(server, &s, &call_details, + &request_metadata_recv, cq, cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar")); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_unref(s); + cq_verifier_destroy(cqv); +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + + /* Verify that sending multiple headers doesn't segfault */ + GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, + PFX_STR HEADER_STR HEADER_STR PAYLOAD_STR, 0); + GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, + PFX_STR HEADER_STR HEADER_STR HEADER_STR PAYLOAD_STR, + 0); + grpc_shutdown(); + return 0; +} diff --git a/test/core/bad_client/tests/head_of_line_blocking.cc b/test/core/bad_client/tests/head_of_line_blocking.cc index f56c4d71dd..427db46446 100644 --- a/test/core/bad_client/tests/head_of_line_blocking.cc +++ b/test/core/bad_client/tests/head_of_line_blocking.cc @@ -117,9 +117,9 @@ int main(int argc, char** argv) { addbuf(prefix, sizeof(prefix) - 1); for (i = 0; i < NUM_FRAMES; i++) { - uint8_t hdr[9] = {(uint8_t)(FRAME_SIZE >> 16), - (uint8_t)(FRAME_SIZE >> 8), - (uint8_t)FRAME_SIZE, + uint8_t hdr[9] = {static_cast<uint8_t>(FRAME_SIZE >> 16), + static_cast<uint8_t>(FRAME_SIZE >> 8), + static_cast<uint8_t>(FRAME_SIZE), 0, 0, 0, @@ -131,7 +131,8 @@ int main(int argc, char** argv) { addbuf(hdr, sizeof(hdr)); addbuf(msg, FRAME_SIZE); } - grpc_run_bad_client_test(verifier, nullptr, g_buffer, g_count, 0); + grpc_bad_client_arg bca = {nullptr, nullptr, g_buffer, g_count}; + grpc_run_bad_client_test(verifier, &bca, 1, 0); gpr_free(g_buffer); grpc_shutdown(); diff --git a/test/core/bad_client/tests/large_metadata.cc b/test/core/bad_client/tests/large_metadata.cc index 1ce0f28967..d534753f53 100644 --- a/test/core/bad_client/tests/large_metadata.cc +++ b/test/core/bad_client/tests/large_metadata.cc @@ -22,7 +22,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/string_util.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/cq_verifier.h" @@ -31,23 +31,20 @@ // be longer than the C99 string literal limit. Instead, we dynamically // construct it by adding the large headers one at a time. -#define PFX_TOO_MUCH_METADATA_FROM_CLIENT_PREFIX_STR \ - "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" /* settings frame */ \ - "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* headers: generated from \ - large_metadata.headers in this \ - directory */ \ - "\x00\x00\x00\x04\x01\x00\x00\x00\x00" \ - "\x00" \ - "5{\x01\x05\x00\x00\x00\x01" \ - "\x10\x05:path\x08/foo/bar" \ - "\x10\x07:scheme\x04http" \ - "\x10\x07:method\x04POST" \ - "\x10\x0a:authority\x09localhost" \ - "\x10\x0c" \ - "content-type\x10" \ - "application/grpc" \ - "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip" \ - "\x10\x02te\x08trailers" \ +/* headers: generated from large_metadata.headers in this directory */ +#define PFX_TOO_MUCH_METADATA_FROM_CLIENT_REQUEST \ + "\x00\x00\x00\x04\x01\x00\x00\x00\x00" \ + "\x00" \ + "5{\x01\x05\x00\x00\x00\x01" \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip" \ + "\x10\x02te\x08trailers" \ "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" // Each large-metadata header is constructed from these start and end @@ -65,8 +62,8 @@ // The number of headers we're adding and the total size of the client // payload. #define NUM_HEADERS 46 -#define PFX_TOO_MUCH_METADATA_FROM_CLIENT_PAYLOAD_SIZE \ - ((sizeof(PFX_TOO_MUCH_METADATA_FROM_CLIENT_PREFIX_STR) - 1) + \ +#define TOO_MUCH_METADATA_FROM_CLIENT_REQUEST_SIZE \ + ((sizeof(PFX_TOO_MUCH_METADATA_FROM_CLIENT_REQUEST) - 1) + \ (NUM_HEADERS * PFX_TOO_MUCH_METADATA_FROM_CLIENT_HEADER_SIZE) + 1) #define PFX_TOO_MUCH_METADATA_FROM_SERVER_STR \ @@ -95,32 +92,6 @@ static void* tag(intptr_t t) { return (void*)t; } -static void server_verifier(grpc_server* server, grpc_completion_queue* cq, - void* registered_method) { - grpc_call_error error; - grpc_call* s; - grpc_call_details call_details; - cq_verifier* cqv = cq_verifier_create(cq); - grpc_metadata_array request_metadata_recv; - - grpc_call_details_init(&call_details); - grpc_metadata_array_init(&request_metadata_recv); - - error = grpc_server_request_call(server, &s, &call_details, - &request_metadata_recv, cq, cq, tag(101)); - GPR_ASSERT(GRPC_CALL_OK == error); - CQ_EXPECT_COMPLETION(cqv, tag(101), 1); - cq_verify(cqv); - - GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost")); - GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar")); - - grpc_metadata_array_destroy(&request_metadata_recv); - grpc_call_details_destroy(&call_details); - grpc_call_unref(s); - cq_verifier_destroy(cqv); -} - static void server_verifier_sends_too_much_metadata(grpc_server* server, grpc_completion_queue* cq, void* registered_method) { @@ -167,43 +138,6 @@ static void server_verifier_sends_too_much_metadata(grpc_server* server, cq_verifier_destroy(cqv); } -static bool client_validator(grpc_slice_buffer* incoming) { - for (size_t i = 0; i < incoming->count; ++i) { - const char* s = (const char*)GRPC_SLICE_START_PTR(incoming->slices[i]); - char* hex = gpr_dump(s, GRPC_SLICE_LENGTH(incoming->slices[i]), - GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_INFO, "RESPONSE SLICE %" PRIdPTR ": %s", i, hex); - gpr_free(hex); - } - - // Get last frame from incoming slice buffer. - grpc_slice_buffer last_frame_buffer; - grpc_slice_buffer_init(&last_frame_buffer); - grpc_slice_buffer_trim_end(incoming, 13, &last_frame_buffer); - GPR_ASSERT(last_frame_buffer.count == 1); - grpc_slice last_frame = last_frame_buffer.slices[0]; - - const uint8_t* p = GRPC_SLICE_START_PTR(last_frame); - bool success = - // Length == 4 - *p++ != 0 || *p++ != 0 || *p++ != 4 || - // Frame type (RST_STREAM) - *p++ != 3 || - // Flags - *p++ != 0 || - // Stream ID. - *p++ != 0 || *p++ != 0 || *p++ != 0 || *p++ != 1 || - // Payload (error code) - *p++ == 0 || *p++ == 0 || *p++ == 0 || *p == 0 || *p == 11; - - if (!success) { - gpr_log(GPR_INFO, "client expected RST_STREAM frame, not found"); - } - - grpc_slice_buffer_destroy(&last_frame_buffer); - return success; -} - int main(int argc, char** argv) { int i; @@ -222,19 +156,22 @@ int main(int argc, char** argv) { size_t headers_len; const char* client_headers = gpr_strvec_flatten(&headers, &headers_len); gpr_strvec_destroy(&headers); - char client_payload[PFX_TOO_MUCH_METADATA_FROM_CLIENT_PAYLOAD_SIZE] = - PFX_TOO_MUCH_METADATA_FROM_CLIENT_PREFIX_STR; - memcpy( - client_payload + sizeof(PFX_TOO_MUCH_METADATA_FROM_CLIENT_PREFIX_STR) - 1, - client_headers, headers_len); - GRPC_RUN_BAD_CLIENT_TEST(server_verifier, client_validator, client_payload, - 0); + char client_payload[TOO_MUCH_METADATA_FROM_CLIENT_REQUEST_SIZE] = + PFX_TOO_MUCH_METADATA_FROM_CLIENT_REQUEST; + memcpy(client_payload + sizeof(PFX_TOO_MUCH_METADATA_FROM_CLIENT_REQUEST) - 1, + client_headers, headers_len); + grpc_bad_client_arg args[2]; + args[0] = connection_preface_arg; + args[1].client_validator = rst_stream_client_validator; + args[1].client_payload = client_payload; + args[1].client_payload_length = sizeof(client_payload) - 1; + + grpc_run_bad_client_test(server_verifier_request_call, args, 2, 0); gpr_free((void*)client_headers); // Test sending more metadata than the client will accept. GRPC_RUN_BAD_CLIENT_TEST(server_verifier_sends_too_much_metadata, - client_validator, + rst_stream_client_validator, PFX_TOO_MUCH_METADATA_FROM_SERVER_STR, 0); - return 0; } diff --git a/test/core/bad_client/tests/window_overflow.cc b/test/core/bad_client/tests/window_overflow.cc index ed8279c951..b552704e9c 100644 --- a/test/core/bad_client/tests/window_overflow.cc +++ b/test/core/bad_client/tests/window_overflow.cc @@ -26,8 +26,7 @@ #include "src/core/lib/surface/server.h" #define PFX_STR \ - "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ - "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */ \ + "\x00\x00\x00\x04\x01\x00\x00\x00\x00" \ "\x00\x00\xc9\x01\x04\x00\x00\x00\x01" /* headers: generated from \ simple_request.headers in this \ directory */ \ @@ -70,16 +69,17 @@ int main(int argc, char** argv) { #define MAX_FRAME_SIZE 16384 #define MESSAGES_PER_FRAME (MAX_FRAME_SIZE / 5) #define FRAME_SIZE (MESSAGES_PER_FRAME * 5) -#define SEND_SIZE (6 * 1024 * 1024) +#define SEND_SIZE (4 * 1024 * 1024) #define NUM_FRAMES (SEND_SIZE / FRAME_SIZE + 1) grpc_test_init(argc, argv); grpc_init(); addbuf(PFX_STR, sizeof(PFX_STR) - 1); for (i = 0; i < NUM_FRAMES; i++) { - uint8_t hdr[9] = {(uint8_t)(FRAME_SIZE >> 16), - (uint8_t)(FRAME_SIZE >> 8), - (uint8_t)FRAME_SIZE, + uint8_t hdr[9] = {static_cast<uint8_t>(FRAME_SIZE >> 16), + static_cast<uint8_t>(FRAME_SIZE >> 8), + static_cast<uint8_t> + FRAME_SIZE, 0, 0, 0, @@ -92,8 +92,10 @@ int main(int argc, char** argv) { addbuf(message, sizeof(message)); } } - grpc_run_bad_client_test(verifier, nullptr, g_buffer, g_count, - GRPC_BAD_CLIENT_LARGE_REQUEST); + grpc_bad_client_arg bca[2]; + bca[0] = connection_preface_arg; + bca[1] = {rst_stream_client_validator, nullptr, g_buffer, g_count}; + grpc_run_bad_client_test(verifier, bca, 2, GRPC_BAD_CLIENT_LARGE_REQUEST); gpr_free(g_buffer); grpc_shutdown(); diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index 0e74a62f19..e2ea7540ef 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -22,14 +22,15 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/subprocess.h> -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" +#include "test/core/util/subprocess.h" #include "test/core/util/test_config.h" static void* tag(intptr_t t) { return (void*)t; } @@ -126,7 +127,7 @@ int main(int argc, char** argv) { gpr_subprocess* svr; /* figure out where we are */ if (lslash) { - memcpy(root, me, (size_t)(lslash - me)); + memcpy(root, me, static_cast<size_t>(lslash - me)); root[lslash - me] = 0; } else { strcpy(root, "."); @@ -138,7 +139,7 @@ int main(int argc, char** argv) { tmp = lunder - 1; while (*tmp != '_') tmp--; tmp++; - memcpy(test, tmp, (size_t)(lunder - tmp)); + memcpy(test, tmp, static_cast<size_t>(lunder - tmp)); /* start the server */ gpr_asprintf(&args[0], "%s/bad_ssl_%s_server%s", root, test, gpr_subprocess_binary_extension()); diff --git a/test/core/bad_ssl/generate_tests.bzl b/test/core/bad_ssl/generate_tests.bzl index b7cb8f86e6..22e7d3a692 100755 --- a/test/core/bad_ssl/generate_tests.bzl +++ b/test/core/bad_ssl/generate_tests.bzl @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary") def test_options(): return struct() @@ -22,16 +23,27 @@ def test_options(): BAD_SSL_TESTS = ['cert', 'alpn'] def grpc_bad_ssl_tests(): - native.cc_library( + grpc_cc_library( name = 'bad_ssl_test_server', srcs = ['server_common.cc'], hdrs = ['server_common.h'], - deps = ['//test/core/util:grpc_test_util', '//:grpc', '//test/core/end2end:ssl_test_data'] + deps = ['//test/core/util:grpc_test_util', + '//:grpc', + '//test/core/end2end:ssl_test_data'] ) for t in BAD_SSL_TESTS: - native.cc_test( + grpc_cc_binary( name = 'bad_ssl_%s_server' % t, srcs = ['servers/%s.cc' % t], deps = [':bad_ssl_test_server'], ) - + grpc_cc_test( + name = 'bad_ssl_%s_test' % t, + srcs = ['bad_ssl_test.cc'], + data = [':bad_ssl_%s_server' % t, + '//src/core/tsi/test_creds:badserver.key', + '//src/core/tsi/test_creds:badserver.pem',], + deps = ['//test/core/util:grpc_test_util', + '//:gpr', + '//test/core/end2end:cq_verifier'], + ) diff --git a/test/core/bad_ssl/server_common.cc b/test/core/bad_ssl/server_common.cc index 08842b8350..809539aff3 100644 --- a/test/core/bad_ssl/server_common.cc +++ b/test/core/bad_ssl/server_common.cc @@ -16,11 +16,11 @@ * */ -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> #include <signal.h> #include "test/core/bad_ssl/server_common.h" +#include "test/core/util/cmdline.h" #include "test/core/util/test_config.h" /* Common server implementation details for all servers in servers/. diff --git a/test/core/bad_ssl/servers/alpn.cc b/test/core/bad_ssl/servers/alpn.cc index 23954d82fd..4a04178b1c 100644 --- a/test/core/bad_ssl/servers/alpn.cc +++ b/test/core/bad_ssl/servers/alpn.cc @@ -21,9 +21,9 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> #include "src/core/ext/transport/chttp2/alpn/alpn.h" +#include "src/core/lib/gpr/useful.h" #include "test/core/bad_ssl/server_common.h" #include "test/core/end2end/data/ssl_test_data.h" diff --git a/test/core/bad_ssl/servers/cert.cc b/test/core/bad_ssl/servers/cert.cc index a51dd34e4b..0722d6b57c 100644 --- a/test/core/bad_ssl/servers/cert.cc +++ b/test/core/bad_ssl/servers/cert.cc @@ -21,7 +21,6 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> #include "src/core/lib/iomgr/load_file.h" @@ -46,8 +45,10 @@ int main(int argc, char** argv) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "load_file", grpc_load_file("src/core/tsi/test_creds/badserver.key", 1, &key_slice))); - pem_key_cert_pair.private_key = (const char*)GRPC_SLICE_START_PTR(key_slice); - pem_key_cert_pair.cert_chain = (const char*)GRPC_SLICE_START_PTR(cert_slice); + pem_key_cert_pair.private_key = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice); + pem_key_cert_pair.cert_chain = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); ssl_creds = grpc_ssl_server_credentials_create(nullptr, &pem_key_cert_pair, 1, 0, nullptr); diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index 92f5907aac..c554b20148 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -53,3 +53,60 @@ grpc_cc_test( "//test/core/util:grpc_test_util", ], ) + +grpc_cc_test( + name = "minimal_stack_is_minimal_test", + srcs = ["minimal_stack_is_minimal_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "channel_trace_test", + srcs = ["channel_trace_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:channel_trace_proto_helper", + ], + external_deps = [ + "gtest", + ], +) + +grpc_cc_test( + name = "channelz_registry_test", + srcs = ["channelz_registry_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], + external_deps = [ + "gtest", + ], +) + +grpc_cc_test( + name = "status_util_test", + srcs = ["status_util_test.cc"], + language = "C++", + deps = [ + "//:grpc", + ], + external_deps = [ + "gtest", + ], +) diff --git a/test/core/channel/channel_args_test.cc b/test/core/channel/channel_args_test.cc index 4a8195e984..41c62a8f16 100644 --- a/test/core/channel/channel_args_test.cc +++ b/test/core/channel/channel_args_test.cc @@ -19,9 +19,9 @@ #include <string.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" @@ -74,44 +74,53 @@ static void test_set_compression_algorithm(void) { static void test_compression_algorithm_states(void) { grpc_core::ExecCtx exec_ctx; - grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate; + grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate, + *ch_args_wo_gzip_deflate_gzip; unsigned states_bitset; size_t i; ch_args = grpc_channel_args_copy_and_add(nullptr, nullptr, 0); /* by default, all enabled */ - states_bitset = - (unsigned)grpc_channel_args_compression_algorithm_get_states(ch_args); + states_bitset = static_cast<unsigned>( + grpc_channel_args_compression_algorithm_get_states(ch_args)); for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { GPR_ASSERT(GPR_BITGET(states_bitset, i)); } - /* disable gzip and deflate */ + /* disable gzip and deflate and stream/gzip */ ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( &ch_args, GRPC_COMPRESS_GZIP, 0); GPR_ASSERT(ch_args == ch_args_wo_gzip); ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state( &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0); GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate); + ch_args_wo_gzip_deflate_gzip = + grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip_deflate, GRPC_COMPRESS_STREAM_GZIP, 0); + GPR_ASSERT(ch_args_wo_gzip_deflate == ch_args_wo_gzip_deflate_gzip); - states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states( - ch_args_wo_gzip_deflate); + states_bitset = + static_cast<unsigned>(grpc_channel_args_compression_algorithm_get_states( + ch_args_wo_gzip_deflate)); for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { - if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE) { + if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE || + i == GRPC_COMPRESS_STREAM_GZIP) { GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); } else { GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); } } - /* re-enabled gzip only */ + /* re-enabled gzip and stream/gzip only */ ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip_deflate, GRPC_COMPRESS_GZIP, 1); - GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate); + &ch_args_wo_gzip_deflate_gzip, GRPC_COMPRESS_GZIP, 1); + ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip, GRPC_COMPRESS_STREAM_GZIP, 1); + GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate_gzip); - states_bitset = (unsigned)grpc_channel_args_compression_algorithm_get_states( - ch_args_wo_gzip); + states_bitset = static_cast<unsigned>( + grpc_channel_args_compression_algorithm_get_states(ch_args_wo_gzip)); for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { if (i == GRPC_COMPRESS_DEFLATE) { GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); @@ -139,6 +148,88 @@ static void test_set_socket_mutator(void) { } } +struct fake_class { + int foo; +}; + +static void* fake_pointer_arg_copy(void* arg) { + gpr_log(GPR_DEBUG, "fake_pointer_arg_copy"); + fake_class* fc = static_cast<fake_class*>(arg); + fake_class* new_fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class))); + new_fc->foo = fc->foo; + return new_fc; +} + +static void fake_pointer_arg_destroy(void* arg) { + gpr_log(GPR_DEBUG, "fake_pointer_arg_destroy"); + fake_class* fc = static_cast<fake_class*>(arg); + gpr_free(fc); +} + +static int fake_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } + +static const grpc_arg_pointer_vtable fake_pointer_arg_vtable = { + fake_pointer_arg_copy, fake_pointer_arg_destroy, fake_pointer_cmp}; + +static void test_channel_create_with_args(void) { + grpc_arg client_a[3]; + + // adds integer arg + client_a[0].type = GRPC_ARG_INTEGER; + client_a[0].key = const_cast<char*>("arg_int"); + client_a[0].value.integer = 0; + + // adds const str arg + client_a[1].type = GRPC_ARG_STRING; + client_a[1].key = const_cast<char*>("arg_str"); + client_a[1].value.string = const_cast<char*>("arg_str_val"); + + // allocated and adds custom pointer arg + fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class))); + fc->foo = 42; + client_a[2].type = GRPC_ARG_POINTER; + client_a[2].key = const_cast<char*>("arg_pointer"); + client_a[2].value.pointer.vtable = &fake_pointer_arg_vtable; + client_a[2].value.pointer.p = fc; + + // creates channel + grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a}; + grpc_channel* c = + grpc_insecure_channel_create("fake_target", &client_args, nullptr); + // user is can free the memory they allocated here + gpr_free(fc); + grpc_channel_destroy(c); +} + +static void test_server_create_with_args(void) { + grpc_arg server_a[3]; + + // adds integer arg + server_a[0].type = GRPC_ARG_INTEGER; + server_a[0].key = const_cast<char*>("arg_int"); + server_a[0].value.integer = 0; + + // adds const str arg + server_a[1].type = GRPC_ARG_STRING; + server_a[1].key = const_cast<char*>("arg_str"); + server_a[1].value.string = const_cast<char*>("arg_str_val"); + + // allocated and adds custom pointer arg + fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class))); + fc->foo = 42; + server_a[2].type = GRPC_ARG_POINTER; + server_a[2].key = const_cast<char*>("arg_pointer"); + server_a[2].value.pointer.vtable = &fake_pointer_arg_vtable; + server_a[2].value.pointer.p = fc; + + // creates server + grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a}; + grpc_server* s = grpc_server_create(&server_args, nullptr); + // user is can free the memory they allocated here + gpr_free(fc); + grpc_server_destroy(s); +} + int main(int argc, char** argv) { grpc_test_init(argc, argv); grpc_init(); @@ -146,6 +237,8 @@ int main(int argc, char** argv) { test_set_compression_algorithm(); test_compression_algorithm_states(); test_set_socket_mutator(); + test_channel_create_with_args(); + test_server_create_with_args(); grpc_shutdown(); return 0; } diff --git a/test/core/channel/channel_stack_builder_test.cc b/test/core/channel/channel_stack_builder_test.cc index ef6db81b0b..aad6d6eee9 100644 --- a/test/core/channel/channel_stack_builder_test.cc +++ b/test/core/channel/channel_stack_builder_test.cc @@ -116,7 +116,7 @@ static bool add_replacement_filter(grpc_channel_stack_builder* builder, static bool add_original_filter(grpc_channel_stack_builder* builder, void* arg) { return grpc_channel_stack_builder_prepend_filter( - builder, (const grpc_channel_filter*)arg, set_arg_once_fn, + builder, static_cast<const grpc_channel_filter*>(arg), set_arg_once_fn, &g_original_fn_called); } diff --git a/test/core/channel/channel_stack_test.cc b/test/core/channel/channel_stack_test.cc index ef43facd6e..2f5329a96d 100644 --- a/test/core/channel/channel_stack_test.cc +++ b/test/core/channel/channel_stack_test.cc @@ -35,14 +35,14 @@ static grpc_error* channel_init_func(grpc_channel_element* elem, GPR_ASSERT(args->channel_args->args[0].value.integer == 42); GPR_ASSERT(args->is_first); GPR_ASSERT(args->is_last); - *(int*)(elem->channel_data) = 0; + *static_cast<int*>(elem->channel_data) = 0; return GRPC_ERROR_NONE; } static grpc_error* call_init_func(grpc_call_element* elem, const grpc_call_element_args* args) { - ++*(int*)(elem->channel_data); - *(int*)(elem->call_data) = 0; + ++*static_cast<int*>(elem->channel_data); + *static_cast<int*>(elem->call_data) = 0; return GRPC_ERROR_NONE; } @@ -51,16 +51,16 @@ static void channel_destroy_func(grpc_channel_element* elem) {} static void call_destroy_func(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) { - ++*(int*)(elem->channel_data); + ++*static_cast<int*>(elem->channel_data); } static void call_func(grpc_call_element* elem, grpc_transport_stream_op_batch* op) { - ++*(int*)(elem->call_data); + ++*static_cast<int*>(elem->call_data); } static void channel_func(grpc_channel_element* elem, grpc_transport_op* op) { - ++*(int*)(elem->channel_data); + ++*static_cast<int*>(elem->channel_data); } static void free_channel(void* arg, grpc_error* error) { @@ -111,7 +111,7 @@ static void test_create_channel_stack(void) { &chan_args, nullptr, "test", channel_stack); GPR_ASSERT(channel_stack->count == 1); channel_elem = grpc_channel_stack_element(channel_stack, 0); - channel_data = (int*)channel_elem->channel_data; + channel_data = static_cast<int*>(channel_elem->channel_data); GPR_ASSERT(*channel_data == 0); call_stack = @@ -133,7 +133,7 @@ static void test_create_channel_stack(void) { call_elem = grpc_call_stack_element(call_stack, 0); GPR_ASSERT(call_elem->filter == channel_elem->filter); GPR_ASSERT(call_elem->channel_data == channel_elem->channel_data); - call_data = (int*)call_elem->call_data; + call_data = static_cast<int*>(call_elem->call_data); GPR_ASSERT(*call_data == 0); GPR_ASSERT(*channel_data == 1); diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc new file mode 100644 index 0000000000..64de05bc0a --- /dev/null +++ b/test/core/channel/channel_trace_test.cc @@ -0,0 +1,239 @@ +/* + * + * 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 <stdlib.h> +#include <string.h> + +#include <gtest/gtest.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/channel/channel_trace.h" +#include "src/core/lib/channel/channelz_registry.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/json/json.h" + +#include "test/core/util/test_config.h" +#include "test/cpp/util/channel_trace_proto_helper.h" + +// remove me +#include <grpc/support/string_util.h> +#include <stdlib.h> +#include <string.h> + +namespace grpc_core { +namespace testing { +namespace { + +grpc_json* GetJsonChild(grpc_json* parent, const char* key) { + EXPECT_NE(parent, nullptr); + for (grpc_json* child = parent->child; child != nullptr; + child = child->next) { + if (child->key != nullptr && strcmp(child->key, key) == 0) return child; + } + return nullptr; +} + +void ValidateJsonArraySize(grpc_json* json, const char* key, + size_t expected_size) { + grpc_json* arr = GetJsonChild(json, key); + ASSERT_NE(arr, nullptr); + ASSERT_EQ(arr->type, GRPC_JSON_ARRAY); + size_t count = 0; + for (grpc_json* child = arr->child; child != nullptr; child = child->next) { + ++count; + } + ASSERT_EQ(count, expected_size); +} + +void ValidateChannelTraceData(grpc_json* json, + size_t num_events_logged_expected, + size_t actual_num_events_expected) { + ASSERT_NE(json, nullptr); + grpc_json* num_events_logged_json = GetJsonChild(json, "numEventsLogged"); + ASSERT_NE(num_events_logged_json, nullptr); + grpc_json* start_time = GetJsonChild(json, "creationTime"); + ASSERT_NE(start_time, nullptr); + size_t num_events_logged = + (size_t)strtol(num_events_logged_json->value, nullptr, 0); + ASSERT_EQ(num_events_logged, num_events_logged_expected); + ValidateJsonArraySize(json, "events", actual_num_events_expected); +} + +void AddSimpleTrace(RefCountedPtr<ChannelTrace> tracer) { + tracer->AddTraceEvent(ChannelTrace::Severity::Info, + grpc_slice_from_static_string("simple trace")); +} + +// checks for the existence of all the required members of the tracer. +void ValidateChannelTrace(RefCountedPtr<ChannelTrace> tracer, + size_t expected_num_event_logged, size_t max_nodes) { + if (!max_nodes) return; + char* json_str = tracer->RenderTrace(); + grpc::testing::ValidateChannelTraceProtoJsonTranslation(json_str); + grpc_json* json = grpc_json_parse_string(json_str); + ValidateChannelTraceData(json, expected_num_event_logged, + GPR_MIN(expected_num_event_logged, max_nodes)); + grpc_json_destroy(json); + gpr_free(json_str); +} + +void ValidateTraceDataMatchedUuidLookup(RefCountedPtr<ChannelTrace> tracer) { + intptr_t uuid = tracer->GetUuid(); + if (uuid == -1) return; // Doesn't make sense to lookup if tracing disabled + char* tracer_json_str = tracer->RenderTrace(); + ChannelTrace* uuid_lookup = ChannelzRegistry::Get<ChannelTrace>(uuid); + char* uuid_lookup_json_str = uuid_lookup->RenderTrace(); + EXPECT_EQ(strcmp(tracer_json_str, uuid_lookup_json_str), 0); + gpr_free(tracer_json_str); + gpr_free(uuid_lookup_json_str); +} + +} // anonymous namespace + +class ChannelTracerTest : public ::testing::TestWithParam<size_t> {}; + +// Tests basic ChannelTrace functionality like construction, adding trace, and +// lookups by uuid. +TEST_P(ChannelTracerTest, BasicTest) { + grpc_core::ExecCtx exec_ctx; + RefCountedPtr<ChannelTrace> tracer = MakeRefCounted<ChannelTrace>(GetParam()); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + ValidateTraceDataMatchedUuidLookup(tracer); + tracer->AddTraceEvent(ChannelTrace::Severity::Info, + grpc_slice_from_static_string("trace three")); + tracer->AddTraceEvent(ChannelTrace::Severity::Error, + grpc_slice_from_static_string("trace four error")); + ValidateChannelTrace(tracer, 4, GetParam()); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + ValidateChannelTrace(tracer, 6, GetParam()); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + ValidateChannelTrace(tracer, 10, GetParam()); + ValidateTraceDataMatchedUuidLookup(tracer); + tracer.reset(nullptr); +} + +// Tests more complex functionality, like a parent channel tracking +// subchannles. This exercises the ref/unref patterns since the parent tracer +// and this function will both hold refs to the subchannel. +TEST_P(ChannelTracerTest, ComplexTest) { + grpc_core::ExecCtx exec_ctx; + RefCountedPtr<ChannelTrace> tracer = MakeRefCounted<ChannelTrace>(GetParam()); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + RefCountedPtr<ChannelTrace> sc1 = MakeRefCounted<ChannelTrace>(GetParam()); + tracer->AddTraceEventReferencingSubchannel( + ChannelTrace::Severity::Info, + grpc_slice_from_static_string("subchannel one created"), sc1); + ValidateChannelTrace(tracer, 3, GetParam()); + AddSimpleTrace(sc1); + AddSimpleTrace(sc1); + AddSimpleTrace(sc1); + ValidateChannelTrace(sc1, 3, GetParam()); + AddSimpleTrace(sc1); + AddSimpleTrace(sc1); + AddSimpleTrace(sc1); + ValidateChannelTrace(sc1, 6, GetParam()); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + ValidateChannelTrace(tracer, 5, GetParam()); + ValidateTraceDataMatchedUuidLookup(tracer); + RefCountedPtr<ChannelTrace> sc2 = MakeRefCounted<ChannelTrace>(GetParam()); + tracer->AddTraceEventReferencingChannel( + ChannelTrace::Severity::Info, + grpc_slice_from_static_string("LB channel two created"), sc2); + tracer->AddTraceEventReferencingSubchannel( + ChannelTrace::Severity::Warning, + grpc_slice_from_static_string("subchannel one inactive"), sc1); + ValidateChannelTrace(tracer, 7, GetParam()); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + ValidateTraceDataMatchedUuidLookup(tracer); + tracer.reset(nullptr); + sc1.reset(nullptr); + sc2.reset(nullptr); +} + +// Test a case in which the parent channel has subchannels and the subchannels +// have connections. Ensures that everything lives as long as it should then +// gets deleted. +TEST_P(ChannelTracerTest, TestNesting) { + grpc_core::ExecCtx exec_ctx; + RefCountedPtr<ChannelTrace> tracer = MakeRefCounted<ChannelTrace>(GetParam()); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + ValidateChannelTrace(tracer, 2, GetParam()); + RefCountedPtr<ChannelTrace> sc1 = MakeRefCounted<ChannelTrace>(GetParam()); + tracer->AddTraceEventReferencingChannel( + ChannelTrace::Severity::Info, + grpc_slice_from_static_string("subchannel one created"), sc1); + ValidateChannelTrace(tracer, 3, GetParam()); + AddSimpleTrace(sc1); + RefCountedPtr<ChannelTrace> conn1 = MakeRefCounted<ChannelTrace>(GetParam()); + // nesting one level deeper. + sc1->AddTraceEventReferencingSubchannel( + ChannelTrace::Severity::Info, + grpc_slice_from_static_string("connection one created"), conn1); + ValidateChannelTrace(tracer, 3, GetParam()); + AddSimpleTrace(conn1); + AddSimpleTrace(tracer); + AddSimpleTrace(tracer); + ValidateChannelTrace(tracer, 5, GetParam()); + ValidateChannelTrace(conn1, 1, GetParam()); + RefCountedPtr<ChannelTrace> sc2 = MakeRefCounted<ChannelTrace>(GetParam()); + tracer->AddTraceEventReferencingSubchannel( + ChannelTrace::Severity::Info, + grpc_slice_from_static_string("subchannel two created"), sc2); + // this trace should not get added to the parents children since it is already + // present in the tracer. + tracer->AddTraceEventReferencingChannel( + ChannelTrace::Severity::Warning, + grpc_slice_from_static_string("subchannel one inactive"), sc1); + AddSimpleTrace(tracer); + ValidateChannelTrace(tracer, 8, GetParam()); + tracer.reset(nullptr); + sc1.reset(nullptr); + sc2.reset(nullptr); + conn1.reset(nullptr); +} + +INSTANTIATE_TEST_CASE_P(ChannelTracerTestSweep, ChannelTracerTest, + ::testing::Values(0, 1, 2, 6, 10, 15)); + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc new file mode 100644 index 0000000000..37696dc0e8 --- /dev/null +++ b/test/core/channel/channelz_registry_test.cc @@ -0,0 +1,121 @@ +/* + * + * 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 <stdlib.h> +#include <string.h> + +#include <gtest/gtest.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/channel/channel_trace.h" +#include "src/core/lib/channel/channelz_registry.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/json/json.h" + +#include "test/core/util/test_config.h" + +#include <stdlib.h> +#include <string.h> + +namespace grpc_core { +namespace testing { + +// Tests basic ChannelTrace functionality like construction, adding trace, and +// lookups by uuid. +TEST(ChannelzRegistryTest, UuidStartsAboveZeroTest) { + int object_to_register; + intptr_t uuid = ChannelzRegistry::Register(&object_to_register); + EXPECT_GT(uuid, 0) << "First uuid chose must be greater than zero. Zero if " + "reserved according to " + "https://github.com/grpc/proposal/blob/master/" + "A14-channelz.md"; + ChannelzRegistry::Unregister(uuid); +} + +TEST(ChannelzRegistryTest, UuidsAreIncreasing) { + int object_to_register; + std::vector<intptr_t> uuids; + for (int i = 0; i < 10; ++i) { + // reregister the same object. It's ok since we are just testing uuids + uuids.push_back(ChannelzRegistry::Register(&object_to_register)); + } + for (size_t i = 1; i < uuids.size(); ++i) { + EXPECT_LT(uuids[i - 1], uuids[i]) << "Uuids must always be increasing"; + } +} + +TEST(ChannelzRegistryTest, RegisterGetTest) { + int object_to_register = 42; + intptr_t uuid = ChannelzRegistry::Register(&object_to_register); + int* retrieved = ChannelzRegistry::Get<int>(uuid); + EXPECT_EQ(&object_to_register, retrieved); +} + +TEST(ChannelzRegistryTest, MultipleTypeTest) { + int int_to_register = 42; + intptr_t int_uuid = ChannelzRegistry::Register(&int_to_register); + std::string str_to_register = "hello world"; + intptr_t str_uuid = ChannelzRegistry::Register(&str_to_register); + int* retrieved_int = ChannelzRegistry::Get<int>(int_uuid); + std::string* retrieved_str = ChannelzRegistry::Get<std::string>(str_uuid); + EXPECT_EQ(&int_to_register, retrieved_int); + EXPECT_EQ(&str_to_register, retrieved_str); +} + +namespace { +class Foo { + public: + int bar; +}; +} // namespace + +TEST(ChannelzRegistryTest, CustomObjectTest) { + Foo* foo = New<Foo>(); + foo->bar = 1024; + intptr_t uuid = ChannelzRegistry::Register(foo); + Foo* retrieved = ChannelzRegistry::Get<Foo>(uuid); + EXPECT_EQ(foo, retrieved); + Delete(foo); +} + +TEST(ChannelzRegistryTest, NullIfNotPresentTest) { + int object_to_register = 42; + intptr_t uuid = ChannelzRegistry::Register(&object_to_register); + // try to pull out a uuid that does not exist. + int* nonexistant = ChannelzRegistry::Get<int>(uuid + 1); + EXPECT_EQ(nonexistant, nullptr); + int* retrieved = ChannelzRegistry::Get<int>(uuid); + EXPECT_EQ(object_to_register, *retrieved); + EXPECT_EQ(&object_to_register, retrieved); +} + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/test/core/channel/minimal_stack_is_minimal_test.cc b/test/core/channel/minimal_stack_is_minimal_test.cc index 3495f603e4..e5953acedc 100644 --- a/test/core/channel/minimal_stack_is_minimal_test.cc +++ b/test/core/channel/minimal_stack_is_minimal_test.cc @@ -35,7 +35,7 @@ #include <string.h> #include "src/core/lib/channel/channel_stack_builder.h" -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/surface/channel_stack_type.h" #include "src/core/lib/transport/transport_impl.h" @@ -66,35 +66,37 @@ int main(int argc, char** argv) { minimal_stack_arg.key = const_cast<char*>(GRPC_ARG_MINIMAL_STACK); minimal_stack_arg.value.integer = 1; grpc_channel_args minimal_stack_args = {1, &minimal_stack_arg}; - errors += CHECK_STACK("unknown", &minimal_stack_args, - GRPC_CLIENT_DIRECT_CHANNEL, "connected", NULL); + errors += + CHECK_STACK("unknown", &minimal_stack_args, GRPC_CLIENT_DIRECT_CHANNEL, + "authority", "connected", NULL); errors += CHECK_STACK("unknown", &minimal_stack_args, GRPC_CLIENT_SUBCHANNEL, - "connected", NULL); + "authority", "connected", NULL); errors += CHECK_STACK("unknown", &minimal_stack_args, GRPC_SERVER_CHANNEL, "server", "connected", NULL); errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_CLIENT_DIRECT_CHANNEL, - "http-client", "connected", NULL); + "authority", "http-client", "connected", NULL); errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_CLIENT_SUBCHANNEL, - "http-client", "connected", NULL); + "authority", "http-client", "connected", NULL); errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_SERVER_CHANNEL, "server", "http-server", "connected", NULL); errors += CHECK_STACK(nullptr, &minimal_stack_args, GRPC_CLIENT_CHANNEL, "client-channel", NULL); // tests with a default stack - errors += CHECK_STACK("unknown", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, - "message_size", "deadline", "connected", NULL); - errors += CHECK_STACK("unknown", nullptr, GRPC_CLIENT_SUBCHANNEL, + errors += + CHECK_STACK("unknown", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, "authority", + "message_size", "deadline", "connected", NULL); + errors += CHECK_STACK("unknown", nullptr, GRPC_CLIENT_SUBCHANNEL, "authority", "message_size", "connected", NULL); errors += CHECK_STACK("unknown", nullptr, GRPC_SERVER_CHANNEL, "server", "message_size", "deadline", "connected", NULL); errors += CHECK_STACK("chttp2", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, - "message_size", "deadline", "http-client", + "authority", "message_size", "deadline", "http-client", "message_compress", "connected", NULL); - errors += - CHECK_STACK("chttp2", nullptr, GRPC_CLIENT_SUBCHANNEL, "message_size", - "http-client", "message_compress", "connected", NULL); + errors += CHECK_STACK("chttp2", nullptr, GRPC_CLIENT_SUBCHANNEL, "authority", + "message_size", "http-client", "message_compress", + "connected", NULL); errors += CHECK_STACK("chttp2", nullptr, GRPC_SERVER_CHANNEL, "server", "message_size", "deadline", "http-server", "message_compress", "connected", NULL); diff --git a/test/core/channel/status_util_test.cc b/test/core/channel/status_util_test.cc new file mode 100644 index 0000000000..1d64bf1995 --- /dev/null +++ b/test/core/channel/status_util_test.cc @@ -0,0 +1,49 @@ +/* + * + * 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 "src/core/lib/channel/status_util.h" + +#include <gtest/gtest.h> + +namespace grpc_core { +namespace internal { +namespace { + +TEST(StatusCodeSet, Basic) { + StatusCodeSet set; + EXPECT_TRUE(set.Empty()); + EXPECT_FALSE(set.Contains(GRPC_STATUS_OK)); + EXPECT_FALSE(set.Contains(GRPC_STATUS_UNAVAILABLE)); + set.Add(GRPC_STATUS_OK); + EXPECT_FALSE(set.Empty()); + EXPECT_TRUE(set.Contains(GRPC_STATUS_OK)); + EXPECT_FALSE(set.Contains(GRPC_STATUS_UNAVAILABLE)); + set.Add(GRPC_STATUS_UNAVAILABLE); + EXPECT_FALSE(set.Empty()); + EXPECT_TRUE(set.Contains(GRPC_STATUS_OK)); + EXPECT_TRUE(set.Contains(GRPC_STATUS_UNAVAILABLE)); +} + +} // namespace +} // namespace internal +} // namespace grpc_core + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index ec72e0ea72..db98ffab77 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -23,8 +23,19 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "uri_fuzzer_test", srcs = ["uri_fuzzer_test.cc"], - language = "C++", corpus = "uri_corpus", + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "parse_address_test", + srcs = ["parse_address_test.cc"], + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -33,13 +44,26 @@ grpc_fuzzer( ) grpc_cc_test( - name = "lb_policies_test", - srcs = ["lb_policies_test.cc"], + name = "uri_parser_test", + srcs = ["uri_parser_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "retry_throttle_test", + srcs = ["retry_throttle_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/end2end:cq_verifier", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], diff --git a/test/core/client_channel/lb_policies_test.cc b/test/core/client_channel/lb_policies_test.cc deleted file mode 100644 index 847ea0066b..0000000000 --- a/test/core/client_channel/lb_policies_test.cc +++ /dev/null @@ -1,1029 +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 <stdarg.h> -#include <string.h> - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpc/support/time.h> - -#include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/surface/channel.h" -#include "src/core/lib/surface/server.h" -#include "test/core/end2end/cq_verifier.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -#define RETRY_TIMEOUT 300 - -typedef struct servers_fixture { - size_t num_servers; - grpc_server** servers; - grpc_call** server_calls; - grpc_completion_queue* cq; - grpc_completion_queue* shutdown_cq; - char** servers_hostports; - grpc_metadata_array* request_metadata_recv; -} servers_fixture; - -typedef struct request_sequences { - size_t n; /* number of iterations */ - int* connections; /* indexed by the interation number, value is the index of - the server it connected to or -1 if none */ - /* indexed by the interation number, value is the client connectivity state */ - grpc_connectivity_state* connectivity_states; -} request_sequences; - -typedef void (*verifier_fn)(const servers_fixture*, grpc_channel*, - const request_sequences*, const size_t); - -typedef struct test_spec { - size_t num_iters; - size_t num_servers; - - int** kill_at; - int** revive_at; - - const char* description; - - verifier_fn verifier; - -} test_spec; - -static void test_spec_reset(test_spec* spec) { - size_t i, j; - - for (i = 0; i < spec->num_iters; i++) { - for (j = 0; j < spec->num_servers; j++) { - spec->kill_at[i][j] = 0; - spec->revive_at[i][j] = 0; - } - } -} - -static test_spec* test_spec_create(size_t num_iters, size_t num_servers) { - test_spec* spec; - size_t i; - - spec = static_cast<test_spec*>(gpr_malloc(sizeof(test_spec))); - spec->num_iters = num_iters; - spec->num_servers = num_servers; - spec->kill_at = static_cast<int**>(gpr_malloc(sizeof(int*) * num_iters)); - spec->revive_at = static_cast<int**>(gpr_malloc(sizeof(int*) * num_iters)); - for (i = 0; i < num_iters; i++) { - spec->kill_at[i] = static_cast<int*>(gpr_malloc(sizeof(int) * num_servers)); - spec->revive_at[i] = - static_cast<int*>(gpr_malloc(sizeof(int) * num_servers)); - } - - test_spec_reset(spec); - return spec; -} - -static void test_spec_destroy(test_spec* spec) { - size_t i; - for (i = 0; i < spec->num_iters; i++) { - gpr_free(spec->kill_at[i]); - gpr_free(spec->revive_at[i]); - } - - gpr_free(spec->kill_at); - gpr_free(spec->revive_at); - - gpr_free(spec); -} - -static void* tag(intptr_t t) { return (void*)t; } - -static gpr_timespec n_millis_time(int n) { - return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(n, GPR_TIMESPAN)); -} - -static void drain_cq(grpc_completion_queue* cq) { - grpc_event ev; - do { - ev = grpc_completion_queue_next(cq, n_millis_time(5000), nullptr); - } while (ev.type != GRPC_QUEUE_SHUTDOWN); -} - -static void kill_server(const servers_fixture* f, size_t i) { - gpr_log(GPR_INFO, "KILLING SERVER %" PRIuPTR, i); - GPR_ASSERT(f->servers[i] != nullptr); - grpc_server_shutdown_and_notify(f->servers[i], f->shutdown_cq, tag(10000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(10000), - n_millis_time(5000), nullptr) - .type == GRPC_OP_COMPLETE); - grpc_server_destroy(f->servers[i]); - f->servers[i] = nullptr; -} - -typedef struct request_data { - grpc_metadata_array initial_metadata_recv; - grpc_metadata_array trailing_metadata_recv; - grpc_slice details; - grpc_status_code status; - grpc_call_details* call_details; -} request_data; - -static void revive_server(const servers_fixture* f, request_data* rdata, - size_t i) { - int got_port; - gpr_log(GPR_INFO, "RAISE AGAIN SERVER %" PRIuPTR, i); - GPR_ASSERT(f->servers[i] == nullptr); - - gpr_log(GPR_DEBUG, "revive: %s", f->servers_hostports[i]); - - f->servers[i] = grpc_server_create(nullptr, nullptr); - grpc_server_register_completion_queue(f->servers[i], f->cq, nullptr); - GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port( - f->servers[i], f->servers_hostports[i])) > 0); - grpc_server_start(f->servers[i]); - - GPR_ASSERT(GRPC_CALL_OK == - grpc_server_request_call(f->servers[i], &f->server_calls[i], - &rdata->call_details[i], - &f->request_metadata_recv[i], f->cq, - f->cq, tag(1000 + (int)i))); -} - -static servers_fixture* setup_servers(const char* server_host, - request_data* rdata, - const size_t num_servers) { - servers_fixture* f = - static_cast<servers_fixture*>(gpr_malloc(sizeof(servers_fixture))); - size_t i; - - f->num_servers = num_servers; - f->server_calls = - static_cast<grpc_call**>(gpr_malloc(sizeof(grpc_call*) * num_servers)); - f->request_metadata_recv = static_cast<grpc_metadata_array*>( - gpr_malloc(sizeof(grpc_metadata_array) * num_servers)); - /* Create servers. */ - f->servers = static_cast<grpc_server**>( - gpr_malloc(sizeof(grpc_server*) * num_servers)); - f->servers_hostports = - static_cast<char**>(gpr_malloc(sizeof(char*) * num_servers)); - f->cq = grpc_completion_queue_create_for_next(nullptr); - f->shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - for (i = 0; i < num_servers; i++) { - grpc_metadata_array_init(&f->request_metadata_recv[i]); - gpr_join_host_port(&f->servers_hostports[i], server_host, - grpc_pick_unused_port_or_die()); - f->servers[i] = nullptr; - revive_server(f, rdata, i); - } - return f; -} - -static void teardown_servers(servers_fixture* f) { - size_t i; - /* Destroy server. */ - for (i = 0; i < f->num_servers; i++) { - if (f->servers[i] == nullptr) continue; - grpc_server_shutdown_and_notify(f->servers[i], f->shutdown_cq, tag(10000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(10000), - n_millis_time(5000), nullptr) - .type == GRPC_OP_COMPLETE); - grpc_server_destroy(f->servers[i]); - } - grpc_completion_queue_shutdown(f->cq); - drain_cq(f->cq); - grpc_completion_queue_destroy(f->cq); - grpc_completion_queue_destroy(f->shutdown_cq); - - gpr_free(f->servers); - - for (i = 0; i < f->num_servers; i++) { - gpr_free(f->servers_hostports[i]); - grpc_metadata_array_destroy(&f->request_metadata_recv[i]); - } - - gpr_free(f->servers_hostports); - gpr_free(f->request_metadata_recv); - gpr_free(f->server_calls); - gpr_free(f); -} - -static request_sequences request_sequences_create(size_t n) { - request_sequences res; - res.n = n; - res.connections = static_cast<int*>(gpr_malloc(sizeof(*res.connections) * n)); - res.connectivity_states = static_cast<grpc_connectivity_state*>( - gpr_malloc(sizeof(*res.connectivity_states) * n)); - memset(res.connections, 0, sizeof(*res.connections) * n); - memset(res.connectivity_states, 0, sizeof(*res.connectivity_states) * n); - return res; -} - -static void request_sequences_destroy(const request_sequences* rseqs) { - gpr_free(rseqs->connections); - gpr_free(rseqs->connectivity_states); -} - -/** Returns connection sequence (server indices), which must be freed */ -static request_sequences perform_request(servers_fixture* f, - grpc_channel* client, - request_data* rdata, - const test_spec* spec) { - grpc_call* c; - int s_idx; - int* s_valid; - grpc_op ops[6]; - grpc_op* op; - int was_cancelled; - size_t i, iter_num; - grpc_event ev; - int read_tag; - int completed_client; - const request_sequences sequences = request_sequences_create(spec->num_iters); - - s_valid = static_cast<int*>(gpr_malloc(sizeof(int) * f->num_servers)); - - for (iter_num = 0; iter_num < spec->num_iters; iter_num++) { - cq_verifier* cqv = cq_verifier_create(f->cq); - was_cancelled = 2; - - for (i = 0; i < f->num_servers; i++) { - if (spec->kill_at[iter_num][i] != 0) { - kill_server(f, i); - } else if (spec->revive_at[iter_num][i] != 0) { - /* killing takes precedence */ - revive_server(f, rdata, i); - } - } - - sequences.connections[iter_num] = -1; - grpc_metadata_array_init(&rdata->initial_metadata_recv); - grpc_metadata_array_init(&rdata->trailing_metadata_recv); - - for (i = 0; i < f->num_servers; i++) { - grpc_call_details_init(&rdata->call_details[i]); - } - memset(s_valid, 0, f->num_servers * sizeof(int)); - - grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr"); - c = grpc_channel_create_call(client, nullptr, GRPC_PROPAGATE_DEFAULTS, - f->cq, grpc_slice_from_static_string("/foo"), - &host, gpr_inf_future(GPR_CLOCK_REALTIME), - nullptr); - GPR_ASSERT(c); - completed_client = 0; - - memset(ops, 0, sizeof(ops)); - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_INITIAL_METADATA; - op->data.recv_initial_metadata.recv_initial_metadata = - &rdata->initial_metadata_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; - op->data.recv_status_on_client.trailing_metadata = - &rdata->trailing_metadata_recv; - op->data.recv_status_on_client.status = &rdata->status; - op->data.recv_status_on_client.status_details = &rdata->details; - op->flags = 0; - op->reserved = nullptr; - op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, (size_t)(op - ops), - tag(1), nullptr)); - - s_idx = -1; - while ((ev = grpc_completion_queue_next( - f->cq, grpc_timeout_milliseconds_to_deadline(RETRY_TIMEOUT), - nullptr)) - .type != GRPC_QUEUE_TIMEOUT) { - GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); - read_tag = ((int)(intptr_t)ev.tag); - const grpc_connectivity_state conn_state = - grpc_channel_check_connectivity_state(client, 0); - sequences.connectivity_states[iter_num] = conn_state; - gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%" PRIuPTR, - ev.success, ev.type, read_tag, iter_num); - if (ev.success && read_tag >= 1000) { - GPR_ASSERT(s_idx == -1); /* only one server must reply */ - /* only server notifications for non-shutdown events */ - s_idx = read_tag - 1000; - s_valid[s_idx] = 1; - sequences.connections[iter_num] = s_idx; - break; - } else if (read_tag == 1) { - gpr_log(GPR_DEBUG, "client timed out"); - GPR_ASSERT(ev.success); - completed_client = 1; - } - } - - if (s_idx >= 0) { - memset(ops, 0, sizeof(ops)); - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; - op->data.send_status_from_server.trailing_metadata_count = 0; - op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; - grpc_slice status_details = grpc_slice_from_static_string("xyz"); - op->data.send_status_from_server.status_details = &status_details; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op->flags = 0; - op->reserved = nullptr; - op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(f->server_calls[s_idx], - ops, (size_t)(op - ops), - tag(102), nullptr)); - - CQ_EXPECT_COMPLETION(cqv, tag(102), 1); - if (!completed_client) { - CQ_EXPECT_COMPLETION(cqv, tag(1), 1); - } - cq_verify(cqv); - - GPR_ASSERT(rdata->status == GRPC_STATUS_UNIMPLEMENTED); - GPR_ASSERT(0 == grpc_slice_str_cmp(rdata->details, "xyz")); - GPR_ASSERT(0 == - grpc_slice_str_cmp(rdata->call_details[s_idx].method, "/foo")); - GPR_ASSERT(0 == grpc_slice_str_cmp(rdata->call_details[s_idx].host, - "foo.test.google.fr")); - GPR_ASSERT(was_cancelled == 1); - - grpc_call_unref(f->server_calls[s_idx]); - - /* ask for the next request on this server */ - GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( - f->servers[s_idx], &f->server_calls[s_idx], - &rdata->call_details[s_idx], - &f->request_metadata_recv[s_idx], f->cq, - f->cq, tag(1000 + (int)s_idx))); - } else { /* no response from server */ - grpc_call_cancel(c, nullptr); - if (!completed_client) { - CQ_EXPECT_COMPLETION(cqv, tag(1), 1); - cq_verify(cqv); - } - } - - GPR_ASSERT(grpc_completion_queue_next( - f->cq, grpc_timeout_milliseconds_to_deadline(RETRY_TIMEOUT), - nullptr) - .type == GRPC_QUEUE_TIMEOUT); - - grpc_metadata_array_destroy(&rdata->initial_metadata_recv); - grpc_metadata_array_destroy(&rdata->trailing_metadata_recv); - - cq_verifier_destroy(cqv); - - grpc_call_unref(c); - - for (i = 0; i < f->num_servers; i++) { - grpc_call_details_destroy(&rdata->call_details[i]); - } - grpc_slice_unref(rdata->details); - } - - gpr_free(s_valid); - - return sequences; -} - -static grpc_call** perform_multirequest(servers_fixture* f, - grpc_channel* client, - size_t concurrent_calls) { - grpc_call** calls; - grpc_op ops[6]; - grpc_op* op; - size_t i; - - calls = static_cast<grpc_call**>( - gpr_malloc(sizeof(grpc_call*) * concurrent_calls)); - for (i = 0; i < f->num_servers; i++) { - kill_server(f, i); - } - - memset(ops, 0, sizeof(ops)); - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; - op->flags = 0; - op->reserved = nullptr; - - grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr"); - for (i = 0; i < concurrent_calls; i++) { - calls[i] = grpc_channel_create_call( - client, nullptr, GRPC_PROPAGATE_DEFAULTS, f->cq, - grpc_slice_from_static_string("/foo"), &host, - gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); - GPR_ASSERT(calls[i]); - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(calls[i], ops, - (size_t)(op - ops), tag(1), - nullptr)); - } - - return calls; -} - -void run_spec(const test_spec* spec) { - grpc_channel* client; - char* client_hostport; - char* servers_hostports_str; - request_data rdata; - servers_fixture* f; - grpc_channel_args args; - grpc_arg arg_array[2]; - rdata.call_details = static_cast<grpc_call_details*>( - gpr_malloc(sizeof(grpc_call_details) * spec->num_servers)); - f = setup_servers("127.0.0.1", &rdata, spec->num_servers); - - /* Create client. */ - servers_hostports_str = gpr_strjoin_sep((const char**)f->servers_hostports, - f->num_servers, ",", nullptr); - gpr_asprintf(&client_hostport, "ipv4:%s", servers_hostports_str); - - arg_array[0].type = GRPC_ARG_INTEGER; - arg_array[0].key = - const_cast<char*>("grpc.testing.fixed_reconnect_backoff_ms"); - arg_array[0].value.integer = RETRY_TIMEOUT; - arg_array[1].type = GRPC_ARG_STRING; - arg_array[1].key = const_cast<char*>(GRPC_ARG_LB_POLICY_NAME); - arg_array[1].value.string = const_cast<char*>("round_robin"); - args.num_args = 2; - args.args = arg_array; - - client = grpc_insecure_channel_create(client_hostport, &args, nullptr); - - gpr_log(GPR_INFO, "Testing '%s' with servers=%s client=%s", spec->description, - servers_hostports_str, client_hostport); - - const request_sequences sequences = perform_request(f, client, &rdata, spec); - - spec->verifier(f, client, &sequences, spec->num_iters); - - gpr_free(client_hostport); - gpr_free(servers_hostports_str); - gpr_free(rdata.call_details); - request_sequences_destroy(&sequences); - - grpc_channel_destroy(client); /* calls the LB's shutdown func */ - teardown_servers(f); -} - -static grpc_channel* create_client(const servers_fixture* f) { - grpc_channel* client; - char* client_hostport; - char* servers_hostports_str; - grpc_arg arg_array[3]; - grpc_channel_args args; - - servers_hostports_str = gpr_strjoin_sep((const char**)f->servers_hostports, - f->num_servers, ",", nullptr); - gpr_asprintf(&client_hostport, "ipv4:%s", servers_hostports_str); - - arg_array[0].type = GRPC_ARG_INTEGER; - arg_array[0].key = - const_cast<char*>("grpc.testing.fixed_reconnect_backoff_ms"); - arg_array[0].value.integer = RETRY_TIMEOUT; - arg_array[1].type = GRPC_ARG_STRING; - arg_array[1].key = const_cast<char*>(GRPC_ARG_LB_POLICY_NAME); - arg_array[1].value.string = const_cast<char*>("ROUND_ROBIN"); - arg_array[2].type = GRPC_ARG_INTEGER; - arg_array[2].key = - const_cast<char*>(GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS); - arg_array[2].value.integer = 0; - args.num_args = GPR_ARRAY_SIZE(arg_array); - args.args = arg_array; - - client = grpc_insecure_channel_create(client_hostport, &args, nullptr); - gpr_free(client_hostport); - gpr_free(servers_hostports_str); - - return client; -} - -static void test_ping() { - grpc_channel* client; - request_data rdata; - servers_fixture* f; - cq_verifier* cqv; - grpc_connectivity_state state = GRPC_CHANNEL_IDLE; - const size_t num_servers = 1; - int i; - - rdata.call_details = static_cast<grpc_call_details*>( - gpr_malloc(sizeof(grpc_call_details) * num_servers)); - f = setup_servers("127.0.0.1", &rdata, num_servers); - cqv = cq_verifier_create(f->cq); - - client = create_client(f); - - grpc_channel_ping(client, f->cq, tag(0), nullptr); - CQ_EXPECT_COMPLETION(cqv, tag(0), 0); - - /* check that we're still in idle, and start connecting */ - GPR_ASSERT(grpc_channel_check_connectivity_state(client, 1) == - GRPC_CHANNEL_IDLE); - /* we'll go through some set of transitions (some might be missed), until - READY is reached */ - while (state != GRPC_CHANNEL_READY) { - grpc_channel_watch_connectivity_state( - client, state, grpc_timeout_seconds_to_deadline(3), f->cq, tag(99)); - CQ_EXPECT_COMPLETION(cqv, tag(99), 1); - cq_verify(cqv); - state = grpc_channel_check_connectivity_state(client, 0); - GPR_ASSERT(state == GRPC_CHANNEL_READY || - state == GRPC_CHANNEL_CONNECTING || - state == GRPC_CHANNEL_TRANSIENT_FAILURE); - } - - for (i = 1; i <= 5; i++) { - grpc_channel_ping(client, f->cq, tag(i), nullptr); - CQ_EXPECT_COMPLETION(cqv, tag(i), 1); - cq_verify(cqv); - } - gpr_free(rdata.call_details); - - grpc_channel_destroy(client); - teardown_servers(f); - - cq_verifier_destroy(cqv); -} - -static void test_pending_calls(size_t concurrent_calls) { - size_t i; - grpc_call** calls; - grpc_channel* client; - request_data rdata; - servers_fixture* f; - test_spec* spec = test_spec_create(0, 4); - rdata.call_details = static_cast<grpc_call_details*>( - gpr_malloc(sizeof(grpc_call_details) * spec->num_servers)); - f = setup_servers("127.0.0.1", &rdata, spec->num_servers); - - client = create_client(f); - calls = perform_multirequest(f, client, concurrent_calls); - grpc_call_cancel(calls[0], nullptr); /* exercise the cancel pick path whilst - there are pending picks */ - - gpr_free(rdata.call_details); - - grpc_channel_destroy(client); /* calls the LB's shutdown func */ - /* destroy the calls after the channel so that they are still around for the - * LB's shutdown func to process */ - for (i = 0; i < concurrent_calls; i++) { - grpc_call_unref(calls[i]); - } - gpr_free(calls); - teardown_servers(f); - test_spec_destroy(spec); -} - -static void test_get_channel_info() { - grpc_channel* channel = - grpc_insecure_channel_create("ipv4:127.0.0.1:1234", nullptr, nullptr); - // Ensures that resolver returns. - grpc_channel_check_connectivity_state(channel, true /* try_to_connect */); - // First, request no fields. This is a no-op. - grpc_channel_info channel_info; - memset(&channel_info, 0, sizeof(channel_info)); - grpc_channel_get_info(channel, &channel_info); - // Request LB policy name. - char* lb_policy_name = nullptr; - channel_info.lb_policy_name = &lb_policy_name; - grpc_channel_get_info(channel, &channel_info); - GPR_ASSERT(lb_policy_name != nullptr); - GPR_ASSERT(strcmp(lb_policy_name, "pick_first") == 0); - gpr_free(lb_policy_name); - // Request service config, which does not exist, so we'll get nothing back. - memset(&channel_info, 0, sizeof(channel_info)); - char* service_config_json = const_cast<char*>("dummy_string"); - channel_info.service_config_json = &service_config_json; - grpc_channel_get_info(channel, &channel_info); - GPR_ASSERT(service_config_json == nullptr); - // Recreate the channel such that it has a service config. - grpc_channel_destroy(channel); - grpc_arg arg; - arg.type = GRPC_ARG_STRING; - arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); - arg.value.string = - const_cast<char*>("{\"loadBalancingPolicy\": \"ROUND_ROBIN\"}"); - grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); - channel = grpc_insecure_channel_create("ipv4:127.0.0.1:1234", args, nullptr); - { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args_destroy(args); - } - // Ensures that resolver returns. - grpc_channel_check_connectivity_state(channel, true /* try_to_connect */); - // Now request the service config again. - grpc_channel_get_info(channel, &channel_info); - GPR_ASSERT(service_config_json != nullptr); - GPR_ASSERT(strcmp(service_config_json, arg.value.string) == 0); - gpr_free(service_config_json); - // Clean up. - grpc_channel_destroy(channel); -} - -static void print_failed_expectations(const int* expected_connection_sequence, - const int* actual_connection_sequence, - const size_t expected_seq_length, - const size_t num_iters) { - size_t i; - for (i = 0; i < num_iters; i++) { - gpr_log(GPR_ERROR, - "FAILURE: Iter (expected, actual): %" PRIuPTR " (%d, %d)", i, - expected_connection_sequence[i % expected_seq_length], - actual_connection_sequence[i]); - } -} - -static void verify_vanilla_round_robin(const servers_fixture* f, - grpc_channel* client, - const request_sequences* sequences, - const size_t num_iters) { - const size_t expected_seq_length = f->num_servers; - - /* verify conn. seq. expectation */ - /* get the first sequence of "num_servers" elements */ - int* expected_connection_sequence = - static_cast<int*>(gpr_malloc(sizeof(int) * expected_seq_length)); - memcpy(expected_connection_sequence, sequences->connections, - sizeof(int) * expected_seq_length); - - for (size_t i = 0; i < num_iters; i++) { - const int actual = sequences->connections[i]; - const int expected = expected_connection_sequence[i % expected_seq_length]; - if (actual != expected) { - gpr_log( - GPR_ERROR, - "CONNECTION SEQUENCE FAILURE: expected %d, got %d at iteration #%d", - expected, actual, (int)i); - abort(); - } - } - - /* All servers are available, therefore all client subchannels are READY, even - * when we only need one for the client channel state to be READY */ - for (size_t i = 0; i < sequences->n; i++) { - const grpc_connectivity_state actual = - static_cast<grpc_connectivity_state>(sequences->connectivity_states[i]); - const grpc_connectivity_state expected = GRPC_CHANNEL_READY; - if (actual != expected) { - gpr_log(GPR_ERROR, - "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " - "at iteration #%d", - grpc_connectivity_state_name(expected), - grpc_connectivity_state_name(actual), (int)i); - abort(); - } - } - - gpr_free(expected_connection_sequence); -} - -/* At the start of the second iteration, all but the first and last servers (as - * given in "f") are killed */ -static void verify_vanishing_floor_round_robin( - const servers_fixture* f, grpc_channel* client, - const request_sequences* sequences, const size_t num_iters) { - int* expected_connection_sequence; - const size_t expected_seq_length = 2; - size_t i; - - /* verify conn. seq. expectation */ - /* copy the first full sequence (without -1s) */ - expected_connection_sequence = - static_cast<int*>(gpr_malloc(sizeof(int) * expected_seq_length)); - memcpy(expected_connection_sequence, sequences->connections + 2, - expected_seq_length * sizeof(int)); - - /* first two elements of the sequence should be [0 (1st server), -1 (failure)] - */ - GPR_ASSERT(sequences->connections[0] == 0); - GPR_ASSERT(sequences->connections[1] == -1); - - /* the next two element must be [3, 0], repeating from that point: the 3 is - * brought forth by servers 1 and 2 disappearing after the intial pick of 0 */ - GPR_ASSERT(sequences->connections[2] == 3); - GPR_ASSERT(sequences->connections[3] == 0); - - /* make sure that the expectation obliges */ - for (i = 2; i < num_iters; i++) { - const int actual = sequences->connections[i]; - const int expected = expected_connection_sequence[i % expected_seq_length]; - if (actual != expected) { - print_failed_expectations(expected_connection_sequence, - sequences->connections, expected_seq_length, - num_iters); - abort(); - } - } - - /* There's always at least one subchannel READY (connected), therefore the - * overall state of the client channel is READY at all times. */ - for (i = 0; i < sequences->n; i++) { - const grpc_connectivity_state actual = - static_cast<grpc_connectivity_state>(sequences->connectivity_states[i]); - const grpc_connectivity_state expected = GRPC_CHANNEL_READY; - if (actual != expected) { - gpr_log(GPR_ERROR, - "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " - "at iteration #%d", - grpc_connectivity_state_name(expected), - grpc_connectivity_state_name(actual), (int)i); - abort(); - } - } - - gpr_free(expected_connection_sequence); -} - -static void verify_total_carnage_round_robin(const servers_fixture* f, - grpc_channel* client, - const request_sequences* sequences, - const size_t num_iters) { - for (size_t i = 0; i < num_iters; i++) { - const int actual = sequences->connections[i]; - const int expected = -1; - if (actual != expected) { - gpr_log( - GPR_ERROR, - "CONNECTION SEQUENCE FAILURE: expected %d, got %d at iteration #%d", - expected, actual, (int)i); - abort(); - } - } - - /* No server is ever available. There should be no READY states (or SHUTDOWN). - * Note that all other states (IDLE, CONNECTING, TRANSIENT_FAILURE) are still - * possible, as the policy transitions while attempting to reconnect. */ - for (size_t i = 0; i < sequences->n; i++) { - const grpc_connectivity_state actual = - static_cast<grpc_connectivity_state>(sequences->connectivity_states[i]); - if (actual == GRPC_CHANNEL_READY || actual == GRPC_CHANNEL_SHUTDOWN) { - gpr_log(GPR_ERROR, - "CONNECTIVITY STATUS SEQUENCE FAILURE: got unexpected state " - "'%s' at iteration #%d.", - grpc_connectivity_state_name(actual), (int)i); - abort(); - } - } -} - -static void verify_partial_carnage_round_robin( - const servers_fixture* f, grpc_channel* client, - const request_sequences* sequences, const size_t num_iters) { - int* expected_connection_sequence; - size_t i; - const size_t expected_seq_length = f->num_servers; - - /* verify conn. seq. expectation */ - /* get the first sequence of "num_servers" elements */ - expected_connection_sequence = - static_cast<int*>(gpr_malloc(sizeof(int) * expected_seq_length)); - memcpy(expected_connection_sequence, sequences->connections, - sizeof(int) * expected_seq_length); - - for (i = 0; i < num_iters / 2; i++) { - const int actual = sequences->connections[i]; - const int expected = expected_connection_sequence[i % expected_seq_length]; - if (actual != expected) { - print_failed_expectations(expected_connection_sequence, - sequences->connections, expected_seq_length, - num_iters); - abort(); - } - } - - /* second half of the iterations go without response */ - for (; i < num_iters; i++) { - GPR_ASSERT(sequences->connections[i] == -1); - } - - /* We can assert that the first client channel state should be READY, when all - * servers were available */ - grpc_connectivity_state actual = - static_cast<grpc_connectivity_state>(sequences->connectivity_states[0]); - grpc_connectivity_state expected = GRPC_CHANNEL_READY; - if (actual != expected) { - gpr_log(GPR_ERROR, - "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " - "at iteration #%d", - grpc_connectivity_state_name(expected), - grpc_connectivity_state_name(actual), 0); - abort(); - } - - /* ... and that the last one shouldn't be READY (or SHUTDOWN): all servers are - * gone. It may be all other states (IDLE, CONNECTING, TRANSIENT_FAILURE), as - * the policy transitions while attempting to reconnect. */ - actual = static_cast<grpc_connectivity_state>( - sequences->connectivity_states[num_iters - 1]); - for (i = 0; i < sequences->n; i++) { - if (actual == GRPC_CHANNEL_READY || actual == GRPC_CHANNEL_SHUTDOWN) { - gpr_log(GPR_ERROR, - "CONNECTIVITY STATUS SEQUENCE FAILURE: got unexpected state " - "'%s' at iteration #%d.", - grpc_connectivity_state_name(actual), (int)i); - abort(); - } - } - gpr_free(expected_connection_sequence); -} - -static void dump_array(const char* desc, const int* data, const size_t count) { - gpr_strvec s; - char* tmp; - size_t i; - gpr_strvec_init(&s); - gpr_strvec_add(&s, gpr_strdup(desc)); - gpr_strvec_add(&s, gpr_strdup(":")); - for (i = 0; i < count; i++) { - gpr_asprintf(&tmp, " %d", data[i]); - gpr_strvec_add(&s, tmp); - } - tmp = gpr_strvec_flatten(&s, nullptr); - gpr_strvec_destroy(&s); - gpr_log(GPR_DEBUG, "%s", tmp); - gpr_free(tmp); -} - -static void verify_rebirth_round_robin(const servers_fixture* f, - grpc_channel* client, - const request_sequences* sequences, - const size_t num_iters) { - dump_array("actual_connection_sequence", sequences->connections, num_iters); - - /* first iteration succeeds */ - GPR_ASSERT(sequences->connections[0] != -1); - /* then we fail for a while... */ - GPR_ASSERT(sequences->connections[1] == -1); - /* ... but should be up eventually */ - size_t first_iter_back_up = ~0ul; - for (size_t i = 2; i < sequences->n; ++i) { - if (sequences->connections[i] != -1) { - first_iter_back_up = i; - break; - } - } - GPR_ASSERT(first_iter_back_up != ~0ul); - - /* We can assert that the first client channel state should be READY, when all - * servers were available; same thing for the last one. In the middle - * somewhere there must exist at least one TRANSIENT_FAILURE */ - grpc_connectivity_state actual = - static_cast<grpc_connectivity_state>(sequences->connectivity_states[0]); - grpc_connectivity_state expected = GRPC_CHANNEL_READY; - if (actual != expected) { - gpr_log(GPR_ERROR, - "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " - "at iteration #%d", - grpc_connectivity_state_name(expected), - grpc_connectivity_state_name(actual), 0); - abort(); - } - - actual = static_cast<grpc_connectivity_state>( - sequences->connectivity_states[num_iters - 1]); - expected = GRPC_CHANNEL_READY; - if (actual != expected) { - gpr_log(GPR_ERROR, - "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " - "at iteration #%d", - grpc_connectivity_state_name(expected), - grpc_connectivity_state_name(actual), (int)num_iters - 1); - abort(); - } - - bool found_failure_status = false; - for (size_t i = 1; i < sequences->n - 1; i++) { - if (sequences->connectivity_states[i] == GRPC_CHANNEL_TRANSIENT_FAILURE) { - found_failure_status = true; - break; - } - } - if (!found_failure_status) { - gpr_log( - GPR_ERROR, - "CONNECTIVITY STATUS SEQUENCE FAILURE: " - "GRPC_CHANNEL_TRANSIENT_FAILURE status not found. Got the following " - "instead:"); - for (size_t i = 0; i < num_iters; i++) { - gpr_log(GPR_ERROR, "[%d]: %s", (int)i, - grpc_connectivity_state_name(static_cast<grpc_connectivity_state>( - sequences->connectivity_states[i]))); - } - } -} - -int main(int argc, char** argv) { - grpc_core::ExecCtx exec_ctx; - test_spec* spec; - size_t i; - const size_t NUM_ITERS = 10; - const size_t NUM_SERVERS = 4; - - grpc_init(); - grpc_test_init(argc, argv); - grpc_tracer_set_enabled("round_robin", 1); - - GPR_ASSERT(grpc_lb_policy_create("this-lb-policy-does-not-exist", nullptr) == - nullptr); - GPR_ASSERT(grpc_lb_policy_create(nullptr, nullptr) == nullptr); - - spec = test_spec_create(NUM_ITERS, NUM_SERVERS); - /* everything is fine, all servers stay up the whole time and life's peachy - */ - spec->verifier = verify_vanilla_round_robin; - spec->description = "test_all_server_up"; - run_spec(spec); - - /* Kill all servers first thing in the morning */ - test_spec_reset(spec); - spec->verifier = verify_total_carnage_round_robin; - spec->description = "test_kill_all_server"; - for (i = 0; i < NUM_SERVERS; i++) { - spec->kill_at[0][i] = 1; - } - run_spec(spec); - - /* at the start of the 2nd iteration, kill all but the first and last - * servers. - * This should knock down the server bound to be selected next */ - test_spec_reset(spec); - spec->verifier = verify_vanishing_floor_round_robin; - spec->description = "test_kill_middle_servers_at_2nd_iteration"; - for (i = 1; i < NUM_SERVERS - 1; i++) { - spec->kill_at[1][i] = 1; - } - run_spec(spec); - - /* Midway, kill all servers. */ - test_spec_reset(spec); - spec->verifier = verify_partial_carnage_round_robin; - spec->description = "test_kill_all_server_midway"; - for (i = 0; i < NUM_SERVERS; i++) { - spec->kill_at[spec->num_iters / 2][i] = 1; - } - run_spec(spec); - - /* After first iteration, kill all servers. On the third one, bring them all - * back up. */ - test_spec_reset(spec); - spec->verifier = verify_rebirth_round_robin; - spec->description = "test_kill_all_server_after_1st_resurrect_at_3rd"; - for (i = 0; i < NUM_SERVERS; i++) { - spec->kill_at[1][i] = 1; - spec->revive_at[3][i] = 1; - } - run_spec(spec); - test_spec_destroy(spec); - - test_pending_calls(4); - test_ping(); - test_get_channel_info(); - - grpc_shutdown(); - return 0; -} diff --git a/test/core/client_channel/parse_address_test.cc b/test/core/client_channel/parse_address_test.cc index 6d56961d84..ae157fbb8b 100644 --- a/test/core/client_channel/parse_address_test.cc +++ b/test/core/client_channel/parse_address_test.cc @@ -18,6 +18,7 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/socket_utils.h" #include <string.h> #ifdef GRPC_HAVE_UNIX_SOCKET @@ -39,7 +40,8 @@ static void test_grpc_parse_unix(const char* uri_text, const char* pathname) { grpc_resolved_address addr; GPR_ASSERT(1 == grpc_parse_unix(uri, &addr)); - struct sockaddr_un* addr_un = (struct sockaddr_un*)addr.addr; + struct sockaddr_un* addr_un = + reinterpret_cast<struct sockaddr_un*>(addr.addr); GPR_ASSERT(AF_UNIX == addr_un->sun_family); GPR_ASSERT(0 == strcmp(addr_un->sun_path, pathname)); @@ -57,15 +59,15 @@ static void test_grpc_parse_ipv4(const char* uri_text, const char* host, grpc_core::ExecCtx exec_ctx; grpc_uri* uri = grpc_uri_parse(uri_text, 0); grpc_resolved_address addr; - char ntop_buf[INET_ADDRSTRLEN]; + char ntop_buf[GRPC_INET_ADDRSTRLEN]; GPR_ASSERT(1 == grpc_parse_ipv4(uri, &addr)); - struct sockaddr_in* addr_in = (struct sockaddr_in*)addr.addr; - GPR_ASSERT(AF_INET == addr_in->sin_family); - GPR_ASSERT(nullptr != grpc_inet_ntop(AF_INET, &addr_in->sin_addr, ntop_buf, - sizeof(ntop_buf))); + grpc_sockaddr_in* addr_in = reinterpret_cast<grpc_sockaddr_in*>(addr.addr); + GPR_ASSERT(GRPC_AF_INET == addr_in->sin_family); + GPR_ASSERT(nullptr != grpc_inet_ntop(GRPC_AF_INET, &addr_in->sin_addr, + ntop_buf, sizeof(ntop_buf))); GPR_ASSERT(0 == strcmp(ntop_buf, host)); - GPR_ASSERT(ntohs(addr_in->sin_port) == port); + GPR_ASSERT(grpc_ntohs(addr_in->sin_port) == port); grpc_uri_destroy(uri); } @@ -75,15 +77,15 @@ static void test_grpc_parse_ipv6(const char* uri_text, const char* host, grpc_core::ExecCtx exec_ctx; grpc_uri* uri = grpc_uri_parse(uri_text, 0); grpc_resolved_address addr; - char ntop_buf[INET6_ADDRSTRLEN]; + char ntop_buf[GRPC_INET6_ADDRSTRLEN]; GPR_ASSERT(1 == grpc_parse_ipv6(uri, &addr)); - struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)addr.addr; - GPR_ASSERT(AF_INET6 == addr_in6->sin6_family); - GPR_ASSERT(nullptr != grpc_inet_ntop(AF_INET6, &addr_in6->sin6_addr, ntop_buf, - sizeof(ntop_buf))); + grpc_sockaddr_in6* addr_in6 = reinterpret_cast<grpc_sockaddr_in6*>(addr.addr); + GPR_ASSERT(GRPC_AF_INET6 == addr_in6->sin6_family); + GPR_ASSERT(nullptr != grpc_inet_ntop(GRPC_AF_INET6, &addr_in6->sin6_addr, + ntop_buf, sizeof(ntop_buf))); GPR_ASSERT(0 == strcmp(ntop_buf, host)); - GPR_ASSERT(ntohs(addr_in6->sin6_port) == port); + GPR_ASSERT(grpc_ntohs(addr_in6->sin6_port) == port); GPR_ASSERT(addr_in6->sin6_scope_id == scope_id); grpc_uri_destroy(uri); diff --git a/test/core/client_channel/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD index b5269c7ef0..d8b0395846 100644 --- a/test/core/client_channel/resolvers/BUILD +++ b/test/core/client_channel/resolvers/BUILD @@ -43,6 +43,18 @@ grpc_cc_test( ) grpc_cc_test( + name = "dns_resolver_cooldown_test", + srcs = ["dns_resolver_cooldown_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( name = "sockaddr_resolver_test", srcs = ["sockaddr_resolver_test.cc"], language = "C++", diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index 18a795fbcb..e34aa2e676 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -57,6 +57,9 @@ static void my_resolve_address(const char* addr, const char* default_port, GRPC_CLOSURE_SCHED(on_done, error); } +static grpc_address_resolver_vtable test_resolver = {my_resolve_address, + nullptr}; + static grpc_ares_request* my_dns_lookup_ares( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, @@ -79,23 +82,23 @@ static grpc_ares_request* my_dns_lookup_ares( return nullptr; } -static grpc_resolver* create_resolver(const char* name) { - grpc_resolver_factory* factory = grpc_resolver_factory_lookup("dns"); +static grpc_core::OrphanablePtr<grpc_core::Resolver> create_resolver( + const char* name) { + grpc_core::ResolverFactory* factory = + grpc_core::ResolverRegistry::LookupResolverFactory("dns"); grpc_uri* uri = grpc_uri_parse(name, 0); GPR_ASSERT(uri); - grpc_resolver_args args; - memset(&args, 0, sizeof(args)); + grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - grpc_resolver* resolver = - grpc_resolver_factory_create_resolver(factory, &args); - grpc_resolver_factory_unref(factory); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + factory->CreateResolver(args); grpc_uri_destroy(uri); return resolver; } static void on_done(void* ev, grpc_error* error) { - gpr_event_set((gpr_event*)ev, (void*)1); + gpr_event_set(static_cast<gpr_event*>(ev), (void*)1); } // interleave waiting for an event with a timer check @@ -112,7 +115,7 @@ static bool wait_loop(int deadline_seconds, gpr_event* ev) { } typedef struct next_args { - grpc_resolver* resolver; + grpc_core::Resolver* resolver; grpc_channel_args** result; grpc_closure* on_complete; } next_args; @@ -120,21 +123,21 @@ typedef struct next_args { static void call_resolver_next_now_lock_taken(void* arg, grpc_error* error_unused) { next_args* a = static_cast<next_args*>(arg); - grpc_resolver_next_locked(a->resolver, a->result, a->on_complete); + a->resolver->NextLocked(a->result, a->on_complete); gpr_free(a); } -static void call_resolver_next_after_locking(grpc_resolver* resolver, +static void call_resolver_next_after_locking(grpc_core::Resolver* resolver, grpc_channel_args** result, - grpc_closure* on_complete) { + grpc_closure* on_complete, + grpc_combiner* combiner) { next_args* a = static_cast<next_args*>(gpr_malloc(sizeof(*a))); a->resolver = resolver; a->result = result; a->on_complete = on_complete; - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(call_resolver_next_now_lock_taken, a, - grpc_combiner_scheduler(resolver->combiner)), - GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(call_resolver_next_now_lock_taken, a, + grpc_combiner_scheduler(combiner)), + GRPC_ERROR_NONE); } int main(int argc, char** argv) { @@ -143,18 +146,20 @@ int main(int argc, char** argv) { grpc_init(); gpr_mu_init(&g_mu); g_combiner = grpc_combiner_create(); - grpc_resolve_address = my_resolve_address; + grpc_set_resolver_impl(&test_resolver); grpc_dns_lookup_ares = my_dns_lookup_ares; grpc_channel_args* result = (grpc_channel_args*)1; { grpc_core::ExecCtx exec_ctx; - grpc_resolver* resolver = create_resolver("dns:test"); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + create_resolver("dns:test"); gpr_event ev1; gpr_event_init(&ev1); call_resolver_next_after_locking( - resolver, &result, - GRPC_CLOSURE_CREATE(on_done, &ev1, grpc_schedule_on_exec_ctx)); + resolver.get(), &result, + GRPC_CLOSURE_CREATE(on_done, &ev1, grpc_schedule_on_exec_ctx), + g_combiner); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(wait_loop(5, &ev1)); GPR_ASSERT(result == nullptr); @@ -162,14 +167,14 @@ int main(int argc, char** argv) { gpr_event ev2; gpr_event_init(&ev2); call_resolver_next_after_locking( - resolver, &result, - GRPC_CLOSURE_CREATE(on_done, &ev2, grpc_schedule_on_exec_ctx)); + resolver.get(), &result, + GRPC_CLOSURE_CREATE(on_done, &ev2, grpc_schedule_on_exec_ctx), + g_combiner); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(wait_loop(30, &ev2)); GPR_ASSERT(result != nullptr); grpc_channel_args_destroy(result); - GRPC_RESOLVER_UNREF(resolver, "test"); GRPC_COMBINER_UNREF(g_combiner, "test"); } diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc new file mode 100644 index 0000000000..521fc3107e --- /dev/null +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -0,0 +1,325 @@ +/* + * + * 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 <grpc/support/log.h> + +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "test/core/util/test_config.h" + +extern grpc_address_resolver_vtable* grpc_resolve_address_impl; +static grpc_address_resolver_vtable* default_resolve_address; + +static grpc_combiner* g_combiner; + +grpc_ares_request* (*g_default_dns_lookup_ares)( + const char* dns_server, const char* name, const char* default_port, + grpc_pollset_set* interested_parties, grpc_closure* on_done, + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json); + +// Counter incremented by test_resolve_address_impl indicating the number of +// times a system-level resolution has happened. +static int g_resolution_count; + +struct iomgr_args { + gpr_event ev; + gpr_atm done_atm; + gpr_mu* mu; + grpc_pollset* pollset; + grpc_pollset_set* pollset_set; +} g_iomgr_args; + +// Wrapper around default resolve_address in order to count the number of +// times we incur in a system-level name resolution. +static void test_resolve_address_impl(const char* name, + const char* default_port, + grpc_pollset_set* interested_parties, + grpc_closure* on_done, + grpc_resolved_addresses** addrs) { + default_resolve_address->resolve_address( + name, default_port, g_iomgr_args.pollset_set, on_done, addrs); + ++g_resolution_count; +} + +static grpc_error* test_blocking_resolve_address_impl( + const char* name, const char* default_port, + grpc_resolved_addresses** addresses) { + return default_resolve_address->blocking_resolve_address(name, default_port, + addresses); +} + +static grpc_address_resolver_vtable test_resolver = { + test_resolve_address_impl, test_blocking_resolve_address_impl}; + +grpc_ares_request* test_dns_lookup_ares( + const char* dns_server, const char* name, const char* default_port, + grpc_pollset_set* interested_parties, grpc_closure* on_done, + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json) { + grpc_ares_request* result = g_default_dns_lookup_ares( + dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, + check_grpclb, service_config_json); + ++g_resolution_count; + return result; +} + +static gpr_timespec test_deadline(void) { + return grpc_timeout_seconds_to_deadline(100); +} + +static void do_nothing(void* arg, grpc_error* error) {} + +void iomgr_args_init(iomgr_args* args) { + gpr_event_init(&args->ev); + args->pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); + grpc_pollset_init(args->pollset, &args->mu); + args->pollset_set = grpc_pollset_set_create(); + grpc_pollset_set_add_pollset(args->pollset_set, args->pollset); + gpr_atm_rel_store(&args->done_atm, 0); +} + +void iomgr_args_finish(iomgr_args* args) { + GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline())); + grpc_pollset_set_del_pollset(args->pollset_set, args->pollset); + grpc_pollset_set_destroy(args->pollset_set); + grpc_closure do_nothing_cb; + GRPC_CLOSURE_INIT(&do_nothing_cb, do_nothing, nullptr, + grpc_schedule_on_exec_ctx); + gpr_mu_lock(args->mu); + grpc_pollset_shutdown(args->pollset, &do_nothing_cb); + gpr_mu_unlock(args->mu); + // exec_ctx needs to be flushed before calling grpc_pollset_destroy() + grpc_core::ExecCtx::Get()->Flush(); + grpc_pollset_destroy(args->pollset); + gpr_free(args->pollset); +} + +static grpc_millis n_sec_deadline(int seconds) { + return grpc_timespec_to_millis_round_up( + grpc_timeout_seconds_to_deadline(seconds)); +} + +static void poll_pollset_until_request_done(iomgr_args* args) { + grpc_core::ExecCtx exec_ctx; + grpc_millis deadline = n_sec_deadline(10); + while (true) { + bool done = gpr_atm_acq_load(&args->done_atm) != 0; + if (done) { + break; + } + grpc_millis time_left = deadline - grpc_core::ExecCtx::Get()->Now(); + gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64, done, time_left); + GPR_ASSERT(time_left >= 0); + grpc_pollset_worker* worker = nullptr; + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_work", grpc_pollset_work(args->pollset, &worker, + n_sec_deadline(1))); + gpr_mu_unlock(args->mu); + grpc_core::ExecCtx::Get()->Flush(); + } + gpr_event_set(&args->ev, (void*)1); +} + +struct OnResolutionCallbackArg { + const char* uri_str = nullptr; + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver; + grpc_channel_args* result = nullptr; + grpc_millis delay_before_second_resolution = 0; +}; + +// Counter for the number of times a resolution notification callback has been +// invoked. +static int g_on_resolution_invocations_count; + +// Set to true by the last callback in the resolution chain. +bool g_all_callbacks_invoked; + +void on_fourth_resolution(void* arg, grpc_error* error) { + OnResolutionCallbackArg* cb_arg = static_cast<OnResolutionCallbackArg*>(arg); + grpc_channel_args_destroy(cb_arg->result); + GPR_ASSERT(error == GRPC_ERROR_NONE); + ++g_on_resolution_invocations_count; + gpr_log(GPR_INFO, + "4th: g_on_resolution_invocations_count: %d, g_resolution_count: %d", + g_on_resolution_invocations_count, g_resolution_count); + // In this case we expect to have incurred in another system-level resolution + // because on_third_resolution slept for longer than the min resolution + // period. + GPR_ASSERT(g_on_resolution_invocations_count == 4); + GPR_ASSERT(g_resolution_count == 3); + cb_arg->resolver.reset(); + gpr_atm_rel_store(&g_iomgr_args.done_atm, 1); + gpr_mu_lock(g_iomgr_args.mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); + gpr_mu_unlock(g_iomgr_args.mu); + grpc_core::Delete(cb_arg); + g_all_callbacks_invoked = true; +} + +void on_third_resolution(void* arg, grpc_error* error) { + OnResolutionCallbackArg* cb_arg = static_cast<OnResolutionCallbackArg*>(arg); + grpc_channel_args_destroy(cb_arg->result); + GPR_ASSERT(error == GRPC_ERROR_NONE); + ++g_on_resolution_invocations_count; + gpr_log(GPR_INFO, + "3rd: g_on_resolution_invocations_count: %d, g_resolution_count: %d", + g_on_resolution_invocations_count, g_resolution_count); + // The timer set because of the previous re-resolution request fires, so a new + // system-level resolution happened. + GPR_ASSERT(g_on_resolution_invocations_count == 3); + GPR_ASSERT(g_resolution_count == 2); + grpc_core::ExecCtx::Get()->TestOnlySetNow( + cb_arg->delay_before_second_resolution * 2); + cb_arg->resolver->NextLocked( + &cb_arg->result, + GRPC_CLOSURE_CREATE(on_fourth_resolution, arg, + grpc_combiner_scheduler(g_combiner))); + cb_arg->resolver->RequestReresolutionLocked(); + gpr_mu_lock(g_iomgr_args.mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); + gpr_mu_unlock(g_iomgr_args.mu); +} + +void on_second_resolution(void* arg, grpc_error* error) { + OnResolutionCallbackArg* cb_arg = static_cast<OnResolutionCallbackArg*>(arg); + grpc_channel_args_destroy(cb_arg->result); + GPR_ASSERT(error == GRPC_ERROR_NONE); + ++g_on_resolution_invocations_count; + gpr_log(GPR_INFO, + "2nd: g_on_resolution_invocations_count: %d, g_resolution_count: %d", + g_on_resolution_invocations_count, g_resolution_count); + // The resolution request for which this function is the callback happened + // before the min resolution period. Therefore, no new system-level + // resolutions happened, as indicated by g_resolution_count. But a resolution + // timer was set to fire when the cooldown finishes. + GPR_ASSERT(g_on_resolution_invocations_count == 2); + GPR_ASSERT(g_resolution_count == 1); + // Register a new callback to capture the timer firing. + cb_arg->resolver->NextLocked( + &cb_arg->result, + GRPC_CLOSURE_CREATE(on_third_resolution, arg, + grpc_combiner_scheduler(g_combiner))); + gpr_mu_lock(g_iomgr_args.mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); + gpr_mu_unlock(g_iomgr_args.mu); +} + +void on_first_resolution(void* arg, grpc_error* error) { + OnResolutionCallbackArg* cb_arg = static_cast<OnResolutionCallbackArg*>(arg); + grpc_channel_args_destroy(cb_arg->result); + GPR_ASSERT(error == GRPC_ERROR_NONE); + ++g_on_resolution_invocations_count; + gpr_log(GPR_INFO, + "1st: g_on_resolution_invocations_count: %d, g_resolution_count: %d", + g_on_resolution_invocations_count, g_resolution_count); + // There's one initial system-level resolution and one invocation of a + // notification callback (the current function). + GPR_ASSERT(g_on_resolution_invocations_count == 1); + GPR_ASSERT(g_resolution_count == 1); + cb_arg->resolver->NextLocked( + &cb_arg->result, + GRPC_CLOSURE_CREATE(on_second_resolution, arg, + grpc_combiner_scheduler(g_combiner))); + cb_arg->resolver->RequestReresolutionLocked(); + gpr_mu_lock(g_iomgr_args.mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); + gpr_mu_unlock(g_iomgr_args.mu); +} + +static void start_test_under_combiner(void* arg, grpc_error* error) { + OnResolutionCallbackArg* res_cb_arg = + static_cast<OnResolutionCallbackArg*>(arg); + + grpc_core::ResolverFactory* factory = + grpc_core::ResolverRegistry::LookupResolverFactory("dns"); + grpc_uri* uri = grpc_uri_parse(res_cb_arg->uri_str, 0); + gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", res_cb_arg->uri_str, + factory->scheme()); + GPR_ASSERT(uri != nullptr); + grpc_core::ResolverArgs args; + args.uri = uri; + args.combiner = g_combiner; + g_on_resolution_invocations_count = 0; + g_resolution_count = 0; + constexpr int kMinResolutionPeriodMs = 1000; + + grpc_arg cooldown_arg; + cooldown_arg.key = + const_cast<char*>(GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); + cooldown_arg.type = GRPC_ARG_INTEGER; + cooldown_arg.value.integer = kMinResolutionPeriodMs; + auto* cooldown_channel_args = + grpc_channel_args_copy_and_add(nullptr, &cooldown_arg, 1); + args.args = cooldown_channel_args; + res_cb_arg->resolver = factory->CreateResolver(args); + grpc_channel_args_destroy(cooldown_channel_args); + GPR_ASSERT(res_cb_arg->resolver != nullptr); + res_cb_arg->delay_before_second_resolution = kMinResolutionPeriodMs; + // First resolution, would incur in system-level resolution. + res_cb_arg->resolver->NextLocked( + &res_cb_arg->result, + GRPC_CLOSURE_CREATE(on_first_resolution, res_cb_arg, + grpc_combiner_scheduler(g_combiner))); + grpc_uri_destroy(uri); +} + +static void test_cooldown() { + grpc_core::ExecCtx exec_ctx; + iomgr_args_init(&g_iomgr_args); + OnResolutionCallbackArg* res_cb_arg = + grpc_core::New<OnResolutionCallbackArg>(); + res_cb_arg->uri_str = "dns:127.0.0.1"; + + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(start_test_under_combiner, res_cb_arg, + grpc_combiner_scheduler(g_combiner)), + GRPC_ERROR_NONE); + grpc_core::ExecCtx::Get()->Flush(); + poll_pollset_until_request_done(&g_iomgr_args); + iomgr_args_finish(&g_iomgr_args); +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + + g_combiner = grpc_combiner_create(); + + g_default_dns_lookup_ares = grpc_dns_lookup_ares; + grpc_dns_lookup_ares = test_dns_lookup_ares; + default_resolve_address = grpc_resolve_address_impl; + grpc_set_resolver_impl(&test_resolver); + + test_cooldown(); + + { + grpc_core::ExecCtx exec_ctx; + GRPC_COMBINER_UNREF(g_combiner, "test"); + } + grpc_shutdown(); + GPR_ASSERT(g_all_callbacks_invoked); + return 0; +} diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index 80667908ef..103b2916c4 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -27,58 +27,57 @@ static grpc_combiner* g_combiner; -static void test_succeeds(grpc_resolver_factory* factory, const char* string) { +static void test_succeeds(grpc_core::ResolverFactory* factory, + const char* string) { + gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, + factory->scheme()); grpc_core::ExecCtx exec_ctx; grpc_uri* uri = grpc_uri_parse(string, 0); - grpc_resolver_args args; - grpc_resolver* resolver; - gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, - factory->vtable->scheme); GPR_ASSERT(uri); - memset(&args, 0, sizeof(args)); + grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - resolver = grpc_resolver_factory_create_resolver(factory, &args); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + factory->CreateResolver(args); GPR_ASSERT(resolver != nullptr); - GRPC_RESOLVER_UNREF(resolver, "test_succeeds"); grpc_uri_destroy(uri); } -static void test_fails(grpc_resolver_factory* factory, const char* string) { +static void test_fails(grpc_core::ResolverFactory* factory, + const char* string) { + gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, + factory->scheme()); grpc_core::ExecCtx exec_ctx; grpc_uri* uri = grpc_uri_parse(string, 0); - grpc_resolver_args args; - grpc_resolver* resolver; - gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, - factory->vtable->scheme); GPR_ASSERT(uri); - memset(&args, 0, sizeof(args)); + grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - resolver = grpc_resolver_factory_create_resolver(factory, &args); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + factory->CreateResolver(args); GPR_ASSERT(resolver == nullptr); grpc_uri_destroy(uri); } int main(int argc, char** argv) { - grpc_resolver_factory* dns; grpc_test_init(argc, argv); grpc_init(); g_combiner = grpc_combiner_create(); - dns = grpc_resolver_factory_lookup("dns"); + grpc_core::ResolverFactory* dns = + grpc_core::ResolverRegistry::LookupResolverFactory("dns"); test_succeeds(dns, "dns:10.2.1.1"); test_succeeds(dns, "dns:10.2.1.1:1234"); - test_succeeds(dns, "ipv4:www.google.com"); + test_succeeds(dns, "dns:www.google.com"); + test_succeeds(dns, "dns:///www.google.com"); if (grpc_resolve_address == grpc_resolve_address_ares) { - test_succeeds(dns, "ipv4://8.8.8.8/8.8.8.8:8888"); + test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); } else { - test_fails(dns, "ipv4://8.8.8.8/8.8.8.8:8888"); + test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888"); } - grpc_resolver_factory_unref(dns); { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index d85cbb1d03..14caa3ea5d 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -27,25 +27,26 @@ #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/util/test_config.h" -static grpc_resolver* build_fake_resolver( +static grpc_core::OrphanablePtr<grpc_core::Resolver> build_fake_resolver( grpc_combiner* combiner, - grpc_fake_resolver_response_generator* response_generator) { - grpc_resolver_factory* factory = grpc_resolver_factory_lookup("fake"); + grpc_core::FakeResolverResponseGenerator* response_generator) { + grpc_core::ResolverFactory* factory = + grpc_core::ResolverRegistry::LookupResolverFactory("fake"); grpc_arg generator_arg = - grpc_fake_resolver_response_generator_arg(response_generator); - grpc_resolver_args args; - memset(&args, 0, sizeof(args)); + grpc_core::FakeResolverResponseGenerator::MakeChannelArg( + response_generator); grpc_channel_args channel_args = {1, &generator_arg}; + grpc_core::ResolverArgs args; args.args = &channel_args; args.combiner = combiner; - grpc_resolver* resolver = - grpc_resolver_factory_create_resolver(factory, &args); - grpc_resolver_factory_unref(factory); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + factory->CreateResolver(args); return resolver; } @@ -55,11 +56,13 @@ typedef struct on_resolution_arg { gpr_event ev; } on_resolution_arg; +// Callback to check the resolution result is as expected. void on_resolution_cb(void* arg, grpc_error* error) { + if (error != GRPC_ERROR_NONE) return; on_resolution_arg* res = static_cast<on_resolution_arg*>(arg); // We only check the addresses channel arg because that's the only one // explicitly set by the test via - // grpc_fake_resolver_response_generator_set_response. + // FakeResolverResponseGenerator::SetResponse(). const grpc_lb_addresses* actual_lb_addresses = grpc_lb_addresses_find_channel_arg(res->resolver_result); const grpc_lb_addresses* expected_lb_addresses = @@ -71,97 +74,172 @@ void on_resolution_cb(void* arg, grpc_error* error) { gpr_event_set(&res->ev, (void*)1); } -static void test_fake_resolver() { - grpc_core::ExecCtx exec_ctx; - grpc_combiner* combiner = grpc_combiner_create(); - // Create resolver. - grpc_fake_resolver_response_generator* response_generator = - grpc_fake_resolver_response_generator_create(); - grpc_resolver* resolver = build_fake_resolver(combiner, response_generator); - GPR_ASSERT(resolver != nullptr); - - // Setup expectations. - grpc_uri* uris[] = {grpc_uri_parse("ipv4:10.2.1.1:1234", true), - grpc_uri_parse("ipv4:127.0.0.1:4321", true)}; - const char* balancer_names[] = {"name1", "name2"}; - const bool is_balancer[] = {true, false}; - grpc_lb_addresses* addresses = grpc_lb_addresses_create(3, nullptr); - for (size_t i = 0; i < GPR_ARRAY_SIZE(uris); ++i) { +// Create a new resolution containing 2 addresses. +static grpc_channel_args* create_new_resolver_result() { + static size_t test_counter = 0; + const size_t num_addresses = 2; + char* uri_string; + char* balancer_name; + // Create grpc_lb_addresses. + grpc_lb_addresses* addresses = + grpc_lb_addresses_create(num_addresses, nullptr); + for (size_t i = 0; i < num_addresses; ++i) { + gpr_asprintf(&uri_string, "ipv4:127.0.0.1:100%" PRIuPTR, + test_counter * num_addresses + i); + grpc_uri* uri = grpc_uri_parse(uri_string, true); + gpr_asprintf(&balancer_name, "balancer%" PRIuPTR, + test_counter * num_addresses + i); grpc_lb_addresses_set_address_from_uri( - addresses, i, uris[i], is_balancer[i], balancer_names[i], nullptr); - grpc_uri_destroy(uris[i]); + addresses, i, uri, bool(num_addresses % 2), balancer_name, nullptr); + gpr_free(balancer_name); + grpc_uri_destroy(uri); + gpr_free(uri_string); } + // Convert grpc_lb_addresses to grpc_channel_args. const grpc_arg addresses_arg = grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args* results = grpc_channel_args_copy_and_add(nullptr, &addresses_arg, 1); grpc_lb_addresses_destroy(addresses); + ++test_counter; + return results; +} + +static on_resolution_arg create_on_resolution_arg(grpc_channel_args* results) { on_resolution_arg on_res_arg; memset(&on_res_arg, 0, sizeof(on_res_arg)); on_res_arg.expected_resolver_result = results; gpr_event_init(&on_res_arg.ev); + return on_res_arg; +} + +static void test_fake_resolver() { + grpc_core::ExecCtx exec_ctx; + grpc_combiner* combiner = grpc_combiner_create(); + // Create resolver. + grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> + response_generator = + grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + build_fake_resolver(combiner, response_generator.get()); + GPR_ASSERT(resolver.get() != nullptr); + // Test 1: normal resolution. + // next_results != NULL, reresolution_results == NULL, last_used_results == + // NULL. Expected response is next_results. + grpc_channel_args* results = create_new_resolver_result(); + on_resolution_arg on_res_arg = create_on_resolution_arg(results); grpc_closure* on_resolution = GRPC_CLOSURE_CREATE( on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner)); - - // Set resolver results and trigger first resolution. on_resolution_cb - // performs the checks. - grpc_fake_resolver_response_generator_set_response(response_generator, - results); - grpc_resolver_next_locked(resolver, &on_res_arg.resolver_result, - on_resolution); + // Resolution won't be triggered until next_results is set. + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + response_generator->SetResponse(results); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, grpc_timeout_seconds_to_deadline(5)) != nullptr); - - // Setup update. - grpc_uri* uris_update[] = {grpc_uri_parse("ipv4:192.168.1.0:31416", true)}; - const char* balancer_names_update[] = {"name3"}; - const bool is_balancer_update[] = {false}; - grpc_lb_addresses* addresses_update = grpc_lb_addresses_create(1, nullptr); - for (size_t i = 0; i < GPR_ARRAY_SIZE(uris_update); ++i) { - grpc_lb_addresses_set_address_from_uri(addresses_update, i, uris_update[i], - is_balancer_update[i], - balancer_names_update[i], nullptr); - grpc_uri_destroy(uris_update[i]); - } - - grpc_arg addresses_update_arg = - grpc_lb_addresses_create_channel_arg(addresses_update); - grpc_channel_args* results_update = - grpc_channel_args_copy_and_add(nullptr, &addresses_update_arg, 1); - grpc_lb_addresses_destroy(addresses_update); - - // Setup expectations for the update. - on_resolution_arg on_res_arg_update; - memset(&on_res_arg_update, 0, sizeof(on_res_arg_update)); - on_res_arg_update.expected_resolver_result = results_update; - gpr_event_init(&on_res_arg_update.ev); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg_update, + // Test 2: update resolution. + // next_results != NULL, reresolution_results == NULL, last_used_results != + // NULL. Expected response is next_results. + results = create_new_resolver_result(); + grpc_channel_args* last_used_results = grpc_channel_args_copy(results); + on_res_arg = create_on_resolution_arg(results); + on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner)); - - // Set updated resolver results and trigger a second resolution. - grpc_fake_resolver_response_generator_set_response(response_generator, - results_update); - grpc_resolver_next_locked(resolver, &on_res_arg_update.resolver_result, - on_resolution); + // Resolution won't be triggered until next_results is set. + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + response_generator->SetResponse(results); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg_update.ev, + GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, grpc_timeout_seconds_to_deadline(5)) != nullptr); - - // Requesting a new resolution without re-senting the response shouldn't - // trigger the resolution callback. + // Test 3: fallback re-resolution. + // next_results == NULL, reresolution_results == NULL, last_used_results != + // NULL. Expected response is last_used_results. + on_res_arg = create_on_resolution_arg(last_used_results); + on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, + grpc_combiner_scheduler(combiner)); + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + // Trigger a re-resolution. + resolver->RequestReresolutionLocked(); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, + grpc_timeout_seconds_to_deadline(5)) != nullptr); + // Test 4: normal re-resolution. + // next_results == NULL, reresolution_results != NULL, last_used_results != + // NULL. Expected response is reresolution_results. + grpc_channel_args* reresolution_results = create_new_resolver_result(); + on_res_arg = + create_on_resolution_arg(grpc_channel_args_copy(reresolution_results)); + on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, + grpc_combiner_scheduler(combiner)); + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + // Set reresolution_results. + response_generator->SetReresolutionResponse(reresolution_results); + // Flush here to guarantee that the response has been set. + grpc_core::ExecCtx::Get()->Flush(); + // Trigger a re-resolution. + resolver->RequestReresolutionLocked(); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, + grpc_timeout_seconds_to_deadline(5)) != nullptr); + // Test 5: repeat re-resolution. + // next_results == NULL, reresolution_results != NULL, last_used_results != + // NULL. Expected response is reresolution_results. + on_res_arg = create_on_resolution_arg(reresolution_results); + on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, + grpc_combiner_scheduler(combiner)); + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + // Trigger a re-resolution. + resolver->RequestReresolutionLocked(); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, + grpc_timeout_seconds_to_deadline(5)) != nullptr); + // Test 6: normal resolution. + // next_results != NULL, reresolution_results != NULL, last_used_results != + // NULL. Expected response is next_results. + results = create_new_resolver_result(); + last_used_results = grpc_channel_args_copy(results); + on_res_arg = create_on_resolution_arg(results); + on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, + grpc_combiner_scheduler(combiner)); + // Resolution won't be triggered until next_results is set. + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + response_generator->SetResponse(results); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, + grpc_timeout_seconds_to_deadline(5)) != nullptr); + // Test 7: fallback re-resolution. + // next_results == NULL, reresolution_results == NULL, last_used_results != + // NULL. Expected response is last_used_results. + on_res_arg = create_on_resolution_arg(last_used_results); + on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, + grpc_combiner_scheduler(combiner)); + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + // Reset reresolution_results. + response_generator->SetReresolutionResponse(nullptr); + // Flush here to guarantee that reresolution_results has been reset. + grpc_core::ExecCtx::Get()->Flush(); + // Trigger a re-resolution. + resolver->RequestReresolutionLocked(); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, + grpc_timeout_seconds_to_deadline(5)) != nullptr); + // Test 8: no-op. + // Requesting a new resolution without setting the response shouldn't trigger + // the resolution callback. memset(&on_res_arg, 0, sizeof(on_res_arg)); - grpc_resolver_next_locked(resolver, &on_res_arg.resolver_result, - on_resolution); + on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, + grpc_combiner_scheduler(combiner)); + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, grpc_timeout_milliseconds_to_deadline(100)) == nullptr); - + // Clean up. + // Note: Need to explicitly unref the resolver and flush the exec_ctx + // to make sure that the final resolver callback (with error set to + // "Resolver Shutdown") is invoked before on_res_arg goes out of scope. + resolver.reset(); + grpc_core::ExecCtx::Get()->Flush(); GRPC_COMBINER_UNREF(combiner, "test_fake_resolver"); - GRPC_RESOLVER_UNREF(resolver, "test_fake_resolver"); - - grpc_fake_resolver_response_generator_unref(response_generator); } int main(int argc, char** argv) { diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc index 4d16a77924..b9287c2468 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc @@ -40,18 +40,18 @@ void on_resolution_cb(void* arg, grpc_error* error) { grpc_channel_args_destroy(res->resolver_result); } -static void test_succeeds(grpc_resolver_factory* factory, const char* string) { +static void test_succeeds(grpc_core::ResolverFactory* factory, + const char* string) { + gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, + factory->scheme()); grpc_core::ExecCtx exec_ctx; grpc_uri* uri = grpc_uri_parse(string, 0); - grpc_resolver_args args; - grpc_resolver* resolver; - gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, - factory->vtable->scheme); GPR_ASSERT(uri); - memset(&args, 0, sizeof(args)); + grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - resolver = grpc_resolver_factory_create_resolver(factory, &args); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + factory->CreateResolver(args); GPR_ASSERT(resolver != nullptr); on_resolution_arg on_res_arg; @@ -60,38 +60,39 @@ static void test_succeeds(grpc_resolver_factory* factory, const char* string) { grpc_closure* on_resolution = GRPC_CLOSURE_CREATE( on_resolution_cb, &on_res_arg, grpc_schedule_on_exec_ctx); - grpc_resolver_next_locked(resolver, &on_res_arg.resolver_result, - on_resolution); - GRPC_RESOLVER_UNREF(resolver, "test_succeeds"); - + resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); grpc_uri_destroy(uri); + /* Flush ExecCtx to avoid stack-use-after-scope on on_res_arg which is + * accessed in the closure on_resolution_cb */ + grpc_core::ExecCtx::Get()->Flush(); } -static void test_fails(grpc_resolver_factory* factory, const char* string) { +static void test_fails(grpc_core::ResolverFactory* factory, + const char* string) { + gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, + factory->scheme()); grpc_core::ExecCtx exec_ctx; grpc_uri* uri = grpc_uri_parse(string, 0); - grpc_resolver_args args; - grpc_resolver* resolver; - gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, - factory->vtable->scheme); GPR_ASSERT(uri); - memset(&args, 0, sizeof(args)); + grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - resolver = grpc_resolver_factory_create_resolver(factory, &args); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + factory->CreateResolver(args); GPR_ASSERT(resolver == nullptr); grpc_uri_destroy(uri); } int main(int argc, char** argv) { - grpc_resolver_factory *ipv4, *ipv6; grpc_test_init(argc, argv); grpc_init(); g_combiner = grpc_combiner_create(); - ipv4 = grpc_resolver_factory_lookup("ipv4"); - ipv6 = grpc_resolver_factory_lookup("ipv6"); + grpc_core::ResolverFactory* ipv4 = + grpc_core::ResolverRegistry::LookupResolverFactory("ipv4"); + grpc_core::ResolverFactory* ipv6 = + grpc_core::ResolverRegistry::LookupResolverFactory("ipv6"); test_fails(ipv4, "ipv4:10.2.1.1"); test_succeeds(ipv4, "ipv4:10.2.1.1:1234"); @@ -107,9 +108,6 @@ int main(int argc, char** argv) { test_fails(ipv6, "ipv6:[::]:123456"); test_fails(ipv6, "ipv6:www.google.com"); - grpc_resolver_factory_unref(ipv4); - grpc_resolver_factory_unref(ipv6); - { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/core/client_channel/retry_throttle_test.cc b/test/core/client_channel/retry_throttle_test.cc new file mode 100644 index 0000000000..c6d5d3ebbb --- /dev/null +++ b/test/core/client_channel/retry_throttle_test.cc @@ -0,0 +1,142 @@ +/* + * + * 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 "src/core/ext/filters/client_channel/retry_throttle.h" + +#include <gtest/gtest.h> + +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace internal { +namespace { + +TEST(ServerRetryThrottleData, Basic) { + // Max token count is 4, so threshold for retrying is 2. + // Token count starts at 4. + // Each failure decrements by 1. Each success increments by 1.6. + auto throttle_data = + MakeRefCounted<ServerRetryThrottleData>(4000, 1600, nullptr); + // Failure: token_count=3. Above threshold. + EXPECT_TRUE(throttle_data->RecordFailure()); + // Success: token_count=4. Not incremented beyond max. + throttle_data->RecordSuccess(); + // Failure: token_count=3. Above threshold. + EXPECT_TRUE(throttle_data->RecordFailure()); + // Failure: token_count=2. At threshold, so no retries. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Failure: token_count=1. Below threshold, so no retries. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Failure: token_count=0. Below threshold, so no retries. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Failure: token_count=0. Below threshold, so no retries. Not + // decremented below min. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Success: token_count=1.6. + throttle_data->RecordSuccess(); + // Success: token_count=3.2. + throttle_data->RecordSuccess(); + // Failure: token_count=2.2. Above threshold. + EXPECT_TRUE(throttle_data->RecordFailure()); + // Failure: token_count=1.2. Below threshold, so no retries. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Success: token_count=2.8. + throttle_data->RecordSuccess(); + // Failure: token_count=1.8. Below threshold, so no retries. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Success: token_count=3.4. + throttle_data->RecordSuccess(); + // Failure: token_count=2.4. Above threshold. + EXPECT_TRUE(throttle_data->RecordFailure()); +} + +TEST(ServerRetryThrottleData, Replacement) { + // Create old throttle data. + // Max token count is 4, so threshold for retrying is 2. + // Token count starts at 4. + // Each failure decrements by 1. Each success increments by 1. + auto old_throttle_data = + MakeRefCounted<ServerRetryThrottleData>(4000, 1000, nullptr); + // Failure: token_count=3. Above threshold. + EXPECT_TRUE(old_throttle_data->RecordFailure()); + // Create new throttle data. + // Max token count is 10, so threshold for retrying is 5. + // Token count starts at 7.5 (ratio inherited from old_throttle_data). + // Each failure decrements by 1. Each success increments by 3. + auto throttle_data = MakeRefCounted<ServerRetryThrottleData>( + 10000, 3000, old_throttle_data.get()); + // Failure via old_throttle_data: token_count=6.5. + EXPECT_TRUE(old_throttle_data->RecordFailure()); + // Failure: token_count=5.5. + EXPECT_TRUE(old_throttle_data->RecordFailure()); + // Failure via old_throttle_data: token_count=4.5. Below threshold. + EXPECT_FALSE(old_throttle_data->RecordFailure()); + // Failure: token_count=3.5. Below threshold. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Success: token_count=6.5. + throttle_data->RecordSuccess(); + // Failure via old_throttle_data: token_count=5.5. Above threshold. + EXPECT_TRUE(old_throttle_data->RecordFailure()); + // Failure: token_count=4.5. Below threshold. + EXPECT_FALSE(throttle_data->RecordFailure()); +} + +TEST(ServerRetryThrottleMap, Replacement) { + ServerRetryThrottleMap::Init(); + const char kServerName[] = "server_name"; + // Create old throttle data. + // Max token count is 4, so threshold for retrying is 2. + // Token count starts at 4. + // Each failure decrements by 1. Each success increments by 1. + auto old_throttle_data = + ServerRetryThrottleMap::GetDataForServer(kServerName, 4000, 1000); + // Failure: token_count=3. Above threshold. + EXPECT_TRUE(old_throttle_data->RecordFailure()); + // Create new throttle data. + // Max token count is 10, so threshold for retrying is 5. + // Token count starts at 7.5 (ratio inherited from old_throttle_data). + // Each failure decrements by 1. Each success increments by 3. + auto throttle_data = + ServerRetryThrottleMap::GetDataForServer(kServerName, 10000, 3000); + // Failure via old_throttle_data: token_count=6.5. + EXPECT_TRUE(old_throttle_data->RecordFailure()); + // Failure: token_count=5.5. + EXPECT_TRUE(old_throttle_data->RecordFailure()); + // Failure via old_throttle_data: token_count=4.5. Below threshold. + EXPECT_FALSE(old_throttle_data->RecordFailure()); + // Failure: token_count=3.5. Below threshold. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Success: token_count=6.5. + throttle_data->RecordSuccess(); + // Failure via old_throttle_data: token_count=5.5. Above threshold. + EXPECT_TRUE(old_throttle_data->RecordFailure()); + // Failure: token_count=4.5. Below threshold. + EXPECT_FALSE(throttle_data->RecordFailure()); + // Clean up. + ServerRetryThrottleMap::Shutdown(); +} + +} // namespace +} // namespace internal +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD index ee71eecfeb..b60390dbfe 100644 --- a/test/core/compression/BUILD +++ b/test/core/compression/BUILD @@ -53,3 +53,15 @@ grpc_cc_test( "//test/core/util:grpc_test_util", ], ) + +grpc_cc_test( + name = "stream_compress_test", + srcs = ["stream_compression_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/compression/algorithm_test.cc b/test/core/compression/algorithm_test.cc index 9e811e9af1..8989a41989 100644 --- a/test/core/compression/algorithm_test.cc +++ b/test/core/compression/algorithm_test.cc @@ -23,12 +23,14 @@ #include <grpc/grpc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/static_metadata.h" #include "test/core/util/test_config.h" +const uint32_t message_prefix_length = 0; +const uint32_t stream_prefix_length = 7; static void test_algorithm_mesh(void) { int i; @@ -48,9 +50,26 @@ static void test_algorithm_mesh(void) { mdstr = grpc_slice_from_copied_string(name); GPR_ASSERT(grpc_slice_eq(mdstr, grpc_compression_algorithm_slice(parsed))); GPR_ASSERT(parsed == grpc_compression_algorithm_from_slice(mdstr)); - mdelem = grpc_compression_encoding_mdelem(parsed); - GPR_ASSERT(grpc_slice_eq(GRPC_MDVALUE(mdelem), mdstr)); - GPR_ASSERT(grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_GRPC_ENCODING)); + if (parsed == 0) { + continue; + } else if (grpc_compression_algorithm_is_message(parsed)) { + mdelem = grpc_message_compression_encoding_mdelem( + grpc_compression_algorithm_to_message_compression_algorithm(parsed)); + grpc_slice value = GRPC_MDVALUE(mdelem); + GPR_ASSERT(0 == memcmp(&name[message_prefix_length], + GRPC_SLICE_START_PTR(value), + GRPC_SLICE_LENGTH(value))); + GPR_ASSERT(grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_GRPC_ENCODING)); + } else { + mdelem = grpc_stream_compression_encoding_mdelem( + grpc_compression_algorithm_to_stream_compression_algorithm(parsed)); + grpc_slice value = GRPC_MDVALUE(mdelem); + GPR_ASSERT(0 == memcmp(&name[stream_prefix_length], + GRPC_SLICE_START_PTR(value), + GRPC_SLICE_LENGTH(value))); + GPR_ASSERT( + grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_CONTENT_ENCODING)); + } grpc_slice_unref_internal(mdstr); GRPC_MDELEM_UNREF(mdelem); } diff --git a/test/core/compression/compression_test.cc b/test/core/compression/compression_test.cc index a1a9441c8d..6522988c66 100644 --- a/test/core/compression/compression_test.cc +++ b/test/core/compression/compression_test.cc @@ -22,15 +22,16 @@ #include <grpc/compression.h> #include <grpc/grpc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "test/core/util/test_config.h" static void test_compression_algorithm_parse(void) { size_t i; - const char* valid_names[] = {"identity", "gzip", "deflate"}; + const char* valid_names[] = {"identity", "gzip", "deflate", "stream/gzip"}; const grpc_compression_algorithm valid_algorithms[] = { - GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_DEFLATE}; + GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_DEFLATE, + GRPC_COMPRESS_STREAM_GZIP}; const char* invalid_names[] = {"gzip2", "foo", "", "2gzip"}; gpr_log(GPR_DEBUG, "test_compression_algorithm_parse"); @@ -59,9 +60,10 @@ static void test_compression_algorithm_name(void) { int success; const char* name; size_t i; - const char* valid_names[] = {"identity", "gzip", "deflate"}; + const char* valid_names[] = {"identity", "gzip", "deflate", "stream/gzip"}; const grpc_compression_algorithm valid_algorithms[] = { - GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_DEFLATE}; + GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_DEFLATE, + GRPC_COMPRESS_STREAM_GZIP}; gpr_log(GPR_DEBUG, "test_compression_algorithm_name"); @@ -171,6 +173,54 @@ static void test_compression_algorithm_for_level(void) { grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH, accepted_encodings)); } + + { + /* accept stream gzip */ + uint32_t accepted_encodings = 0; + GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */ + GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_STREAM_GZIP); + + GPR_ASSERT(GRPC_COMPRESS_NONE == + grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE, + accepted_encodings)); + + GPR_ASSERT(GRPC_COMPRESS_NONE == + grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW, + accepted_encodings)); + + GPR_ASSERT(GRPC_COMPRESS_NONE == + grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED, + accepted_encodings)); + + GPR_ASSERT(GRPC_COMPRESS_NONE == + grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH, + accepted_encodings)); + } + + { + /* accept all algorithms */ + uint32_t accepted_encodings = 0; + GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */ + GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_GZIP); + GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_DEFLATE); + GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_STREAM_GZIP); + + GPR_ASSERT(GRPC_COMPRESS_NONE == + grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE, + accepted_encodings)); + + GPR_ASSERT(GRPC_COMPRESS_GZIP == + grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW, + accepted_encodings)); + + GPR_ASSERT(GRPC_COMPRESS_DEFLATE == + grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED, + accepted_encodings)); + + GPR_ASSERT(GRPC_COMPRESS_DEFLATE == + grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH, + accepted_encodings)); + } } static void test_compression_enable_disable_algorithm(void) { diff --git a/test/core/compression/message_compress_test.cc b/test/core/compression/message_compress_test.cc index 6ca07b70c4..e3fe825fdf 100644 --- a/test/core/compression/message_compress_test.cc +++ b/test/core/compression/message_compress_test.cc @@ -23,10 +23,10 @@ #include <grpc/grpc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/support/murmur_hash.h" #include "test/core/util/slice_splitter.h" #include "test/core/util/test_config.h" @@ -39,7 +39,7 @@ typedef enum { } compressability; static void assert_passthrough(grpc_slice value, - grpc_compression_algorithm algorithm, + grpc_message_compression_algorithm algorithm, grpc_slice_split_mode uncompressed_split_mode, grpc_slice_split_mode compressed_split_mode, compressability compress_result_check) { @@ -51,7 +51,8 @@ static void assert_passthrough(grpc_slice value, int was_compressed; const char* algorithm_name; - GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algorithm_name) != 0); + GPR_ASSERT( + grpc_message_compression_algorithm_name(algorithm, &algorithm_name) != 0); gpr_log(GPR_INFO, "assert_passthrough: value_length=%" PRIuPTR " value_hash=0x%08x " @@ -92,7 +93,8 @@ static void assert_passthrough(grpc_slice value, { grpc_core::ExecCtx exec_ctx; GPR_ASSERT(grpc_msg_decompress( - was_compressed ? algorithm : GRPC_COMPRESS_NONE, &compressed, &output)); + was_compressed ? algorithm : GRPC_MESSAGE_COMPRESS_NONE, &compressed, + &output)); } final = grpc_slice_merge(output.slices, output.count); @@ -112,8 +114,8 @@ static grpc_slice repeated(char c, size_t length) { } static compressability get_compressability( - test_value id, grpc_compression_algorithm algorithm) { - if (algorithm == GRPC_COMPRESS_NONE) return SHOULD_NOT_COMPRESS; + test_value id, grpc_message_compression_algorithm algorithm) { + if (algorithm == GRPC_MESSAGE_COMPRESS_NONE) return SHOULD_NOT_COMPRESS; switch (id) { case ONE_A: return SHOULD_NOT_COMPRESS; @@ -150,13 +152,13 @@ static void test_tiny_data_compress(void) { grpc_slice_buffer_init(&output); grpc_slice_buffer_add(&input, create_test_value(ONE_A)); - for (int i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { - if (i == GRPC_COMPRESS_NONE) continue; + for (int i = 0; i < GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; i++) { + if (i == GRPC_MESSAGE_COMPRESS_NONE) continue; grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(0 == - grpc_msg_compress(static_cast<grpc_compression_algorithm>(i), - &input, &output)); + GPR_ASSERT(0 == grpc_msg_compress( + static_cast<grpc_message_compression_algorithm>(i), + &input, &output)); GPR_ASSERT(1 == output.count); } @@ -178,7 +180,7 @@ static void test_bad_decompression_data_crc(void) { grpc_core::ExecCtx exec_ctx; /* compress it */ - grpc_msg_compress(GRPC_COMPRESS_GZIP, &input, &corrupted); + grpc_msg_compress(GRPC_MESSAGE_COMPRESS_GZIP, &input, &corrupted); /* corrupt the output by smashing the CRC */ GPR_ASSERT(corrupted.count > 1); GPR_ASSERT(GRPC_SLICE_LENGTH(corrupted.slices[1]) > 8); @@ -186,7 +188,8 @@ static void test_bad_decompression_data_crc(void) { memcpy(GRPC_SLICE_START_PTR(corrupted.slices[1]) + idx, &bad, 4); /* try (and fail) to decompress the corrupted compresed buffer */ - GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_GZIP, &corrupted, &output)); + GPR_ASSERT(0 == grpc_msg_decompress(GRPC_MESSAGE_COMPRESS_GZIP, &corrupted, + &output)); grpc_slice_buffer_destroy(&input); grpc_slice_buffer_destroy(&corrupted); @@ -206,7 +209,8 @@ static void test_bad_decompression_data_trailing_garbage(void) { /* try (and fail) to decompress the invalid compresed buffer */ grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output)); + GPR_ASSERT( + 0 == grpc_msg_decompress(GRPC_MESSAGE_COMPRESS_DEFLATE, &input, &output)); grpc_slice_buffer_destroy(&input); grpc_slice_buffer_destroy(&output); @@ -223,7 +227,8 @@ static void test_bad_decompression_data_stream(void) { /* try (and fail) to decompress the invalid compresed buffer */ grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(0 == grpc_msg_decompress(GRPC_COMPRESS_DEFLATE, &input, &output)); + GPR_ASSERT( + 0 == grpc_msg_decompress(GRPC_MESSAGE_COMPRESS_DEFLATE, &input, &output)); grpc_slice_buffer_destroy(&input); grpc_slice_buffer_destroy(&output); @@ -240,13 +245,14 @@ static void test_bad_compression_algorithm(void) { &input, grpc_slice_from_copied_string("Never gonna give you up")); grpc_core::ExecCtx exec_ctx; - was_compressed = - grpc_msg_compress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output); + was_compressed = grpc_msg_compress(GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT, + &input, &output); GPR_ASSERT(0 == was_compressed); - was_compressed = grpc_msg_compress(static_cast<grpc_compression_algorithm>( - GRPC_COMPRESS_ALGORITHMS_COUNT + 123), - &input, &output); + was_compressed = + grpc_msg_compress(static_cast<grpc_message_compression_algorithm>( + GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT + 123), + &input, &output); GPR_ASSERT(0 == was_compressed); grpc_slice_buffer_destroy(&input); @@ -264,13 +270,13 @@ static void test_bad_decompression_algorithm(void) { grpc_slice_from_copied_string( "I'm not really compressed but it doesn't matter")); grpc_core::ExecCtx exec_ctx; - was_decompressed = - grpc_msg_decompress(GRPC_COMPRESS_ALGORITHMS_COUNT, &input, &output); + was_decompressed = grpc_msg_decompress(GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT, + &input, &output); GPR_ASSERT(0 == was_decompressed); was_decompressed = - grpc_msg_decompress(static_cast<grpc_compression_algorithm>( - GRPC_COMPRESS_ALGORITHMS_COUNT + 123), + grpc_msg_decompress(static_cast<grpc_message_compression_algorithm>( + GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT + 123), &input, &output); GPR_ASSERT(0 == was_decompressed); @@ -289,17 +295,18 @@ int main(int argc, char** argv) { grpc_test_init(argc, argv); grpc_init(); - for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + for (i = 0; i < GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; i++) { for (j = 0; j < GPR_ARRAY_SIZE(uncompressed_split_modes); j++) { for (k = 0; k < GPR_ARRAY_SIZE(compressed_split_modes); k++) { for (m = 0; m < TEST_VALUE_COUNT; m++) { grpc_slice slice = create_test_value(static_cast<test_value>(m)); assert_passthrough( - slice, static_cast<grpc_compression_algorithm>(i), + slice, static_cast<grpc_message_compression_algorithm>(i), static_cast<grpc_slice_split_mode>(j), static_cast<grpc_slice_split_mode>(k), - get_compressability(static_cast<test_value>(m), - static_cast<grpc_compression_algorithm>(i))); + get_compressability( + static_cast<test_value>(m), + static_cast<grpc_message_compression_algorithm>(i))); grpc_slice_unref(slice); } } diff --git a/test/core/compression/stream_compression_test.cc b/test/core/compression/stream_compression_test.cc index 2f30b7fc19..0b84366198 100644 --- a/test/core/compression/stream_compression_test.cc +++ b/test/core/compression/stream_compression_test.cc @@ -29,7 +29,7 @@ static void generate_random_payload(char* payload, size_t size) { size_t i; static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; for (i = 0; i < size - 1; ++i) { - payload[i] = chars[rand() % (int)(sizeof(chars) - 1)]; + payload[i] = chars[rand() % static_cast<int>(sizeof(chars) - 1)]; } payload[size - 1] = '\0'; } @@ -43,8 +43,10 @@ static bool slice_buffer_equals_string(grpc_slice_buffer* buf, size_t pointer = 0; for (i = 0; i < buf->count; i++) { size_t slice_len = GRPC_SLICE_LENGTH(buf->slices[i]); - if (0 != strncmp(str + pointer, (char*)GRPC_SLICE_START_PTR(buf->slices[i]), - slice_len)) { + if (0 != + strncmp(str + pointer, + reinterpret_cast<char*> GRPC_SLICE_START_PTR(buf->slices[i]), + slice_len)) { return false; } pointer += slice_len; @@ -112,7 +114,7 @@ test_stream_compression_simple_compress_decompress_with_output_size_constraint() GPR_ASSERT(output_size == max_output_size); GPR_ASSERT(end_of_context == false); grpc_slice slice_recv = grpc_slice_buffer_take_first(&sink); - char* str_recv = (char*)GRPC_SLICE_START_PTR(slice_recv); + char* str_recv = reinterpret_cast<char*> GRPC_SLICE_START_PTR(slice_recv); GPR_ASSERT(GRPC_SLICE_LENGTH(slice_recv) == max_output_size); GPR_ASSERT(0 == strncmp(test_str, str_recv, max_output_size)); grpc_slice_unref(slice_recv); diff --git a/test/core/debug/stats_test.cc b/test/core/debug/stats_test.cc index e60e54b2fd..aeb13655bf 100644 --- a/test/core/debug/stats_test.cc +++ b/test/core/debug/stats_test.cc @@ -47,22 +47,22 @@ class Snapshot { TEST(StatsTest, IncCounters) { for (int i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) { - Snapshot snapshot; + std::unique_ptr<Snapshot> snapshot(new Snapshot); grpc_core::ExecCtx exec_ctx; GRPC_STATS_INC_COUNTER((grpc_stats_counters)i); - EXPECT_EQ(snapshot.delta().counters[i], 1); + EXPECT_EQ(snapshot->delta().counters[i], 1); } } TEST(StatsTest, IncSpecificCounter) { - Snapshot snapshot; + std::unique_ptr<Snapshot> snapshot(new Snapshot); grpc_core::ExecCtx exec_ctx; GRPC_STATS_INC_SYSCALL_POLL(); - EXPECT_EQ(snapshot.delta().counters[GRPC_STATS_COUNTER_SYSCALL_POLL], 1); + EXPECT_EQ(snapshot->delta().counters[GRPC_STATS_COUNTER_SYSCALL_POLL], 1); } static int FindExpectedBucket(int i, int j) { @@ -90,12 +90,12 @@ TEST_P(HistogramTest, IncHistogram) { gpr_log(GPR_DEBUG, "expected_bucket:%d nvalues=%" PRIdPTR, expected_bucket, test_values.size()); for (auto j : test_values) { - Snapshot snapshot; + std::unique_ptr<Snapshot> snapshot(new Snapshot); grpc_core::ExecCtx exec_ctx; grpc_stats_inc_histogram[kHistogram](j); - auto delta = snapshot.delta(); + auto delta = snapshot->delta(); EXPECT_EQ( delta @@ -142,9 +142,14 @@ INSTANTIATE_TEST_CASE_P(HistogramTestCases, HistogramTest, } // namespace grpc int main(int argc, char** argv) { +/* Only run this test if GRPC_COLLECT_STATS is defined or if it is a debug + * build. + */ +#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) ::testing::InitGoogleTest(&argc, argv); grpc_init(); int ret = RUN_ALL_TESTS(); grpc_shutdown(); return ret; +#endif } diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index f8281bfe6f..dd16694204 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -71,4 +71,112 @@ grpc_cc_library( ], ) +grpc_cc_test( + name = "bad_server_response_test", + srcs = ["bad_server_response_test.cc"], + language = "C++", + deps = [ + ":cq_verifier", + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "connection_refused_test", + srcs = ["connection_refused_test.cc"], + language = "C++", + deps = [ + ":cq_verifier", + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "dualstack_socket_test", + srcs = ["dualstack_socket_test.cc"], + language = "C++", + deps = [ + ":cq_verifier", + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "goaway_server_test", + srcs = ["goaway_server_test.cc"], + language = "C++", + deps = [ + ":cq_verifier", + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "invalid_call_argument_test", + srcs = ["invalid_call_argument_test.cc"], + language = "C++", + deps = [ + ":cq_verifier", + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "multiple_server_queues_test", + srcs = ["multiple_server_queues_test.cc"], + language = "C++", + deps = [ + ":cq_verifier", + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "no_server_test", + srcs = ["no_server_test.cc"], + language = "C++", + deps = [ + ":cq_verifier", + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + grpc_end2end_tests() + +grpc_cc_test( + name = "h2_ssl_session_reuse_test", + srcs = ["h2_ssl_session_reuse_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + ':end2end_tests', + '//:gpr', + '//:grpc', + '//:tsi', + '//test/core/util:gpr_test_util', + '//test/core/util:grpc_test_util', + ], +) diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 93809ac37a..3d133cfc18 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -27,14 +27,15 @@ #include <grpc/grpc.h> #include <grpc/slice.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -133,7 +134,7 @@ static void on_connect(void* arg, grpc_endpoint* tcp, grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor) { gpr_free(acceptor); - test_tcp_server* server = (test_tcp_server*)arg; + test_tcp_server* server = static_cast<test_tcp_server*>(arg); GRPC_CLOSURE_INIT(&on_read, handle_read, nullptr, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&on_write, done_write, nullptr, grpc_schedule_on_exec_ctx); grpc_slice_buffer_init(&state.temp_incoming_buffer); @@ -196,8 +197,8 @@ static void start_rpc(int target_port, grpc_status_code expected_status, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(state.call, ops, (size_t)(op - ops), tag(1), - nullptr); + error = grpc_call_start_batch(state.call, ops, static_cast<size_t>(op - ops), + tag(1), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); @@ -236,7 +237,7 @@ typedef struct { } poll_args; static void actually_poll_server(void* arg) { - poll_args* pa = (poll_args*)arg; + poll_args* pa = static_cast<poll_args*>(arg); gpr_timespec deadline = n_sec_deadline(10); while (true) { bool done = gpr_atm_acq_load(&state.done_atm) != 0; @@ -253,15 +254,17 @@ static void actually_poll_server(void* arg) { gpr_free(pa); } -static void poll_server_until_read_done(test_tcp_server* server, - gpr_event* signal_when_done) { +static grpc_core::Thread* poll_server_until_read_done( + test_tcp_server* server, gpr_event* signal_when_done) { gpr_atm_rel_store(&state.done_atm, 0); state.write_done = 0; - gpr_thd_id id; - poll_args* pa = (poll_args*)gpr_malloc(sizeof(*pa)); + poll_args* pa = static_cast<poll_args*>(gpr_malloc(sizeof(*pa))); pa->server = server; pa->signal_when_done = signal_when_done; - gpr_thd_new(&id, "grpc_poll_server", actually_poll_server, pa, nullptr); + auto* th = grpc_core::New<grpc_core::Thread>("grpc_poll_server", + actually_poll_server, pa); + th->Start(); + return th; } static void run_test(const char* response_payload, @@ -281,9 +284,11 @@ static void run_test(const char* response_payload, state.response_payload_length = response_payload_length; /* poll server until sending out the response */ - poll_server_until_read_done(&test_server, &ev); + grpc_core::UniquePtr<grpc_core::Thread> thdptr( + poll_server_until_read_done(&test_server, &ev)); start_rpc(server_port, expected_status, expected_detail); gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME)); + thdptr->Join(); /* clean up */ grpc_endpoint_shutdown(state.tcp, diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index ca6d17e7c8..33812ec8e5 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -20,11 +20,12 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/service_config.h" diff --git a/test/core/end2end/cq_verifier.cc b/test/core/end2end/cq_verifier.cc index 8686f4e7b7..f7e64effcd 100644 --- a/test/core/end2end/cq_verifier.cc +++ b/test/core/end2end/cq_verifier.cc @@ -18,6 +18,7 @@ #include "test/core/end2end/cq_verifier.h" +#include <inttypes.h> #include <stdarg.h> #include <stdio.h> #include <string.h> @@ -28,8 +29,7 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/event_string.h" #define ROOT_EXPECTATION 1000 @@ -62,7 +62,7 @@ struct cq_verifier { }; cq_verifier* cq_verifier_create(grpc_completion_queue* cq) { - cq_verifier* v = (cq_verifier*)gpr_malloc(sizeof(cq_verifier)); + cq_verifier* v = static_cast<cq_verifier*>(gpr_malloc(sizeof(cq_verifier))); v->cq = cq; v->first_expectation = nullptr; return v; @@ -306,7 +306,7 @@ void cq_verify_empty(cq_verifier* v) { cq_verify_empty_timeout(v, 1); } static void add(cq_verifier* v, const char* file, int line, grpc_completion_type type, void* tag, bool success) { - expectation* e = (expectation*)gpr_malloc(sizeof(expectation)); + expectation* e = static_cast<expectation*>(gpr_malloc(sizeof(expectation))); e->type = type; e->file = file; e->line = line; diff --git a/test/core/end2end/cq_verifier_uv.cc b/test/core/end2end/cq_verifier_uv.cc index e23b3ae2a0..45d827ef61 100644 --- a/test/core/end2end/cq_verifier_uv.cc +++ b/test/core/end2end/cq_verifier_uv.cc @@ -58,7 +58,7 @@ static void timer_close_cb(uv_handle_t* handle) { void cq_verifier_destroy(cq_verifier* v) { cq_verify(v); uv_close((uv_handle_t*)&v->timer, timer_close_cb); - while (reinterpret_cast<timer_state>(v->timer.data) != TIMER_CLOSED) { + while (static_cast<timer_state>(v->timer.data) != TIMER_CLOSED) { uv_run(uv_default_loop(), UV_RUN_NOWAIT); } gpr_free(v); @@ -85,7 +85,7 @@ grpc_event cq_verifier_next_event(cq_verifier* v, int timeout_seconds) { ev = grpc_completion_queue_next(v->cq, gpr_inf_past(GPR_CLOCK_MONOTONIC), NULL); // Stop the loop if the timer goes off or we get a non-timeout event - while ((reinterpret_cast<timer_state>(v->timer.data) != TIMER_TRIGGERED) && + while ((static_cast<timer_state>(v->timer.data) != TIMER_TRIGGERED) && ev.type == GRPC_QUEUE_TIMEOUT) { uv_run(uv_default_loop(), UV_RUN_ONCE); ev = grpc_completion_queue_next(v->cq, gpr_inf_past(GPR_CLOCK_MONOTONIC), diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index 2ba1c17c2c..eb1d043fb2 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -25,16 +25,16 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/socket_utils_posix.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -43,14 +43,11 @@ static void* tag(intptr_t i) { return (void*)i; } -static gpr_timespec ms_from_now(int ms) { - return grpc_timeout_milliseconds_to_deadline(ms); -} - static void drain_cq(grpc_completion_queue* cq) { grpc_event ev; do { - ev = grpc_completion_queue_next(cq, ms_from_now(5000), nullptr); + ev = grpc_completion_queue_next( + cq, grpc_timeout_milliseconds_to_deadline(5000), nullptr); } while (ev.type != GRPC_QUEUE_SHUTDOWN); } @@ -131,8 +128,8 @@ void test_connect(const char* server_host, const char* client_host, int port, grpc_slice_buffer uri_parts; char** hosts_with_port; - uri_slice = - grpc_slice_new((char*)client_host, strlen(client_host), do_nothing); + uri_slice = grpc_slice_new(const_cast<char*>(client_host), + strlen(client_host), do_nothing); grpc_slice_buffer_init(&uri_parts); grpc_slice_split(uri_slice, ",", &uri_parts); hosts_with_port = @@ -165,11 +162,11 @@ void test_connect(const char* server_host, const char* client_host, int port, if (expect_ok) { /* Normal deadline, shouldn't be reached. */ - deadline = ms_from_now(60000); + deadline = grpc_timeout_milliseconds_to_deadline(60000); } else { /* Give up faster when failure is expected. BUG: Setting this to 1000 reveals a memory leak (b/18608927). */ - deadline = ms_from_now(1500); + deadline = grpc_timeout_milliseconds_to_deadline(8000); } /* Send a trivial request. */ @@ -202,7 +199,8 @@ void test_connect(const char* server_host, const char* client_host, int port, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); if (expect_ok) { @@ -230,8 +228,8 @@ void test_connect(const char* server_host, const char* client_host, int port, op->data.recv_close_on_server.cancelled = &was_cancelled; op->flags = 0; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(102), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc index 3236feea56..59eb643a93 100644 --- a/test/core/end2end/end2end_nosec_tests.cc +++ b/test/core/end2end/end2end_nosec_tests.cc @@ -38,6 +38,8 @@ extern void bad_ping(grpc_end2end_test_config config); extern void bad_ping_pre_init(void); extern void binary_metadata(grpc_end2end_test_config config); extern void binary_metadata_pre_init(void); +extern void call_host_override(grpc_end2end_test_config config); +extern void call_host_override_pre_init(void); extern void cancel_after_accept(grpc_end2end_test_config config); extern void cancel_after_accept_pre_init(void); extern void cancel_after_client_done(grpc_end2end_test_config config); @@ -68,6 +70,8 @@ extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); extern void filter_latency(grpc_end2end_test_config config); extern void filter_latency_pre_init(void); +extern void filter_status_code(grpc_end2end_test_config config); +extern void filter_status_code_pre_init(void); extern void graceful_server_shutdown(grpc_end2end_test_config config); extern void graceful_server_shutdown_pre_init(void); extern void high_initial_seqno(grpc_end2end_test_config config); @@ -116,6 +120,38 @@ extern void request_with_payload(grpc_end2end_test_config config); extern void request_with_payload_pre_init(void); extern void resource_quota_server(grpc_end2end_test_config config); extern void resource_quota_server_pre_init(void); +extern void retry(grpc_end2end_test_config config); +extern void retry_pre_init(void); +extern void retry_cancellation(grpc_end2end_test_config config); +extern void retry_cancellation_pre_init(void); +extern void retry_disabled(grpc_end2end_test_config config); +extern void retry_disabled_pre_init(void); +extern void retry_exceeds_buffer_size_in_initial_batch(grpc_end2end_test_config config); +extern void retry_exceeds_buffer_size_in_initial_batch_pre_init(void); +extern void retry_exceeds_buffer_size_in_subsequent_batch(grpc_end2end_test_config config); +extern void retry_exceeds_buffer_size_in_subsequent_batch_pre_init(void); +extern void retry_non_retriable_status(grpc_end2end_test_config config); +extern void retry_non_retriable_status_pre_init(void); +extern void retry_non_retriable_status_before_recv_trailing_metadata_started(grpc_end2end_test_config config); +extern void retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init(void); +extern void retry_recv_initial_metadata(grpc_end2end_test_config config); +extern void retry_recv_initial_metadata_pre_init(void); +extern void retry_recv_message(grpc_end2end_test_config config); +extern void retry_recv_message_pre_init(void); +extern void retry_server_pushback_delay(grpc_end2end_test_config config); +extern void retry_server_pushback_delay_pre_init(void); +extern void retry_server_pushback_disabled(grpc_end2end_test_config config); +extern void retry_server_pushback_disabled_pre_init(void); +extern void retry_streaming(grpc_end2end_test_config config); +extern void retry_streaming_pre_init(void); +extern void retry_streaming_after_commit(grpc_end2end_test_config config); +extern void retry_streaming_after_commit_pre_init(void); +extern void retry_streaming_succeeds_before_replay_finished(grpc_end2end_test_config config); +extern void retry_streaming_succeeds_before_replay_finished_pre_init(void); +extern void retry_throttled(grpc_end2end_test_config config); +extern void retry_throttled_pre_init(void); +extern void retry_too_many_attempts(grpc_end2end_test_config config); +extern void retry_too_many_attempts_pre_init(void); extern void server_finishes_request(grpc_end2end_test_config config); extern void server_finishes_request_pre_init(void); extern void shutdown_finishes_calls(grpc_end2end_test_config config); @@ -155,6 +191,7 @@ void grpc_end2end_tests_pre_init(void) { bad_hostname_pre_init(); bad_ping_pre_init(); binary_metadata_pre_init(); + call_host_override_pre_init(); cancel_after_accept_pre_init(); cancel_after_client_done_pre_init(); cancel_after_invoke_pre_init(); @@ -170,6 +207,7 @@ void grpc_end2end_tests_pre_init(void) { filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); filter_latency_pre_init(); + filter_status_code_pre_init(); graceful_server_shutdown_pre_init(); high_initial_seqno_pre_init(); hpack_size_pre_init(); @@ -194,6 +232,22 @@ void grpc_end2end_tests_pre_init(void) { request_with_flags_pre_init(); request_with_payload_pre_init(); resource_quota_server_pre_init(); + retry_pre_init(); + retry_cancellation_pre_init(); + retry_disabled_pre_init(); + retry_exceeds_buffer_size_in_initial_batch_pre_init(); + retry_exceeds_buffer_size_in_subsequent_batch_pre_init(); + retry_non_retriable_status_pre_init(); + retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init(); + retry_recv_initial_metadata_pre_init(); + retry_recv_message_pre_init(); + retry_server_pushback_delay_pre_init(); + retry_server_pushback_disabled_pre_init(); + retry_streaming_pre_init(); + retry_streaming_after_commit_pre_init(); + retry_streaming_succeeds_before_replay_finished_pre_init(); + retry_throttled_pre_init(); + retry_too_many_attempts_pre_init(); server_finishes_request_pre_init(); shutdown_finishes_calls_pre_init(); shutdown_finishes_tags_pre_init(); @@ -222,6 +276,7 @@ void grpc_end2end_tests(int argc, char **argv, bad_hostname(config); bad_ping(config); binary_metadata(config); + call_host_override(config); cancel_after_accept(config); cancel_after_client_done(config); cancel_after_invoke(config); @@ -237,6 +292,7 @@ void grpc_end2end_tests(int argc, char **argv, filter_call_init_fails(config); filter_causes_close(config); filter_latency(config); + filter_status_code(config); graceful_server_shutdown(config); high_initial_seqno(config); hpack_size(config); @@ -261,6 +317,22 @@ void grpc_end2end_tests(int argc, char **argv, request_with_flags(config); request_with_payload(config); resource_quota_server(config); + retry(config); + retry_cancellation(config); + retry_disabled(config); + retry_exceeds_buffer_size_in_initial_batch(config); + retry_exceeds_buffer_size_in_subsequent_batch(config); + retry_non_retriable_status(config); + retry_non_retriable_status_before_recv_trailing_metadata_started(config); + retry_recv_initial_metadata(config); + retry_recv_message(config); + retry_server_pushback_delay(config); + retry_server_pushback_disabled(config); + retry_streaming(config); + retry_streaming_after_commit(config); + retry_streaming_succeeds_before_replay_finished(config); + retry_throttled(config); + retry_too_many_attempts(config); server_finishes_request(config); shutdown_finishes_calls(config); shutdown_finishes_tags(config); @@ -296,6 +368,10 @@ void grpc_end2end_tests(int argc, char **argv, binary_metadata(config); continue; } + if (0 == strcmp("call_host_override", argv[i])) { + call_host_override(config); + continue; + } if (0 == strcmp("cancel_after_accept", argv[i])) { cancel_after_accept(config); continue; @@ -356,6 +432,10 @@ void grpc_end2end_tests(int argc, char **argv, filter_latency(config); continue; } + if (0 == strcmp("filter_status_code", argv[i])) { + filter_status_code(config); + continue; + } if (0 == strcmp("graceful_server_shutdown", argv[i])) { graceful_server_shutdown(config); continue; @@ -452,6 +532,70 @@ void grpc_end2end_tests(int argc, char **argv, resource_quota_server(config); continue; } + if (0 == strcmp("retry", argv[i])) { + retry(config); + continue; + } + if (0 == strcmp("retry_cancellation", argv[i])) { + retry_cancellation(config); + continue; + } + if (0 == strcmp("retry_disabled", argv[i])) { + retry_disabled(config); + continue; + } + if (0 == strcmp("retry_exceeds_buffer_size_in_initial_batch", argv[i])) { + retry_exceeds_buffer_size_in_initial_batch(config); + continue; + } + if (0 == strcmp("retry_exceeds_buffer_size_in_subsequent_batch", argv[i])) { + retry_exceeds_buffer_size_in_subsequent_batch(config); + continue; + } + if (0 == strcmp("retry_non_retriable_status", argv[i])) { + retry_non_retriable_status(config); + continue; + } + if (0 == strcmp("retry_non_retriable_status_before_recv_trailing_metadata_started", argv[i])) { + retry_non_retriable_status_before_recv_trailing_metadata_started(config); + continue; + } + if (0 == strcmp("retry_recv_initial_metadata", argv[i])) { + retry_recv_initial_metadata(config); + continue; + } + if (0 == strcmp("retry_recv_message", argv[i])) { + retry_recv_message(config); + continue; + } + if (0 == strcmp("retry_server_pushback_delay", argv[i])) { + retry_server_pushback_delay(config); + continue; + } + if (0 == strcmp("retry_server_pushback_disabled", argv[i])) { + retry_server_pushback_disabled(config); + continue; + } + if (0 == strcmp("retry_streaming", argv[i])) { + retry_streaming(config); + continue; + } + if (0 == strcmp("retry_streaming_after_commit", argv[i])) { + retry_streaming_after_commit(config); + continue; + } + if (0 == strcmp("retry_streaming_succeeds_before_replay_finished", argv[i])) { + retry_streaming_succeeds_before_replay_finished(config); + continue; + } + if (0 == strcmp("retry_throttled", argv[i])) { + retry_throttled(config); + continue; + } + if (0 == strcmp("retry_too_many_attempts", argv[i])) { + retry_too_many_attempts(config); + continue; + } if (0 == strcmp("server_finishes_request", argv[i])) { server_finishes_request(config); continue; diff --git a/test/core/end2end/end2end_test.sh b/test/core/end2end/end2end_test.sh index 3b18ae30af..5bfb253090 100755 --- a/test/core/end2end/end2end_test.sh +++ b/test/core/end2end/end2end_test.sh @@ -15,4 +15,8 @@ # 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 +if [ -z "$3" ] + then + export GRPC_POLL_STRATEGY=$3 +fi +"$1" "$2" diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index ca9443b642..9f164b4ead 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -40,6 +40,8 @@ extern void binary_metadata(grpc_end2end_test_config config); extern void binary_metadata_pre_init(void); extern void call_creds(grpc_end2end_test_config config); extern void call_creds_pre_init(void); +extern void call_host_override(grpc_end2end_test_config config); +extern void call_host_override_pre_init(void); extern void cancel_after_accept(grpc_end2end_test_config config); extern void cancel_after_accept_pre_init(void); extern void cancel_after_client_done(grpc_end2end_test_config config); @@ -70,6 +72,8 @@ extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); extern void filter_latency(grpc_end2end_test_config config); extern void filter_latency_pre_init(void); +extern void filter_status_code(grpc_end2end_test_config config); +extern void filter_status_code_pre_init(void); extern void graceful_server_shutdown(grpc_end2end_test_config config); extern void graceful_server_shutdown_pre_init(void); extern void high_initial_seqno(grpc_end2end_test_config config); @@ -118,6 +122,38 @@ extern void request_with_payload(grpc_end2end_test_config config); extern void request_with_payload_pre_init(void); extern void resource_quota_server(grpc_end2end_test_config config); extern void resource_quota_server_pre_init(void); +extern void retry(grpc_end2end_test_config config); +extern void retry_pre_init(void); +extern void retry_cancellation(grpc_end2end_test_config config); +extern void retry_cancellation_pre_init(void); +extern void retry_disabled(grpc_end2end_test_config config); +extern void retry_disabled_pre_init(void); +extern void retry_exceeds_buffer_size_in_initial_batch(grpc_end2end_test_config config); +extern void retry_exceeds_buffer_size_in_initial_batch_pre_init(void); +extern void retry_exceeds_buffer_size_in_subsequent_batch(grpc_end2end_test_config config); +extern void retry_exceeds_buffer_size_in_subsequent_batch_pre_init(void); +extern void retry_non_retriable_status(grpc_end2end_test_config config); +extern void retry_non_retriable_status_pre_init(void); +extern void retry_non_retriable_status_before_recv_trailing_metadata_started(grpc_end2end_test_config config); +extern void retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init(void); +extern void retry_recv_initial_metadata(grpc_end2end_test_config config); +extern void retry_recv_initial_metadata_pre_init(void); +extern void retry_recv_message(grpc_end2end_test_config config); +extern void retry_recv_message_pre_init(void); +extern void retry_server_pushback_delay(grpc_end2end_test_config config); +extern void retry_server_pushback_delay_pre_init(void); +extern void retry_server_pushback_disabled(grpc_end2end_test_config config); +extern void retry_server_pushback_disabled_pre_init(void); +extern void retry_streaming(grpc_end2end_test_config config); +extern void retry_streaming_pre_init(void); +extern void retry_streaming_after_commit(grpc_end2end_test_config config); +extern void retry_streaming_after_commit_pre_init(void); +extern void retry_streaming_succeeds_before_replay_finished(grpc_end2end_test_config config); +extern void retry_streaming_succeeds_before_replay_finished_pre_init(void); +extern void retry_throttled(grpc_end2end_test_config config); +extern void retry_throttled_pre_init(void); +extern void retry_too_many_attempts(grpc_end2end_test_config config); +extern void retry_too_many_attempts_pre_init(void); extern void server_finishes_request(grpc_end2end_test_config config); extern void server_finishes_request_pre_init(void); extern void shutdown_finishes_calls(grpc_end2end_test_config config); @@ -158,6 +194,7 @@ void grpc_end2end_tests_pre_init(void) { bad_ping_pre_init(); binary_metadata_pre_init(); call_creds_pre_init(); + call_host_override_pre_init(); cancel_after_accept_pre_init(); cancel_after_client_done_pre_init(); cancel_after_invoke_pre_init(); @@ -173,6 +210,7 @@ void grpc_end2end_tests_pre_init(void) { filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); filter_latency_pre_init(); + filter_status_code_pre_init(); graceful_server_shutdown_pre_init(); high_initial_seqno_pre_init(); hpack_size_pre_init(); @@ -197,6 +235,22 @@ void grpc_end2end_tests_pre_init(void) { request_with_flags_pre_init(); request_with_payload_pre_init(); resource_quota_server_pre_init(); + retry_pre_init(); + retry_cancellation_pre_init(); + retry_disabled_pre_init(); + retry_exceeds_buffer_size_in_initial_batch_pre_init(); + retry_exceeds_buffer_size_in_subsequent_batch_pre_init(); + retry_non_retriable_status_pre_init(); + retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init(); + retry_recv_initial_metadata_pre_init(); + retry_recv_message_pre_init(); + retry_server_pushback_delay_pre_init(); + retry_server_pushback_disabled_pre_init(); + retry_streaming_pre_init(); + retry_streaming_after_commit_pre_init(); + retry_streaming_succeeds_before_replay_finished_pre_init(); + retry_throttled_pre_init(); + retry_too_many_attempts_pre_init(); server_finishes_request_pre_init(); shutdown_finishes_calls_pre_init(); shutdown_finishes_tags_pre_init(); @@ -226,6 +280,7 @@ void grpc_end2end_tests(int argc, char **argv, bad_ping(config); binary_metadata(config); call_creds(config); + call_host_override(config); cancel_after_accept(config); cancel_after_client_done(config); cancel_after_invoke(config); @@ -241,6 +296,7 @@ void grpc_end2end_tests(int argc, char **argv, filter_call_init_fails(config); filter_causes_close(config); filter_latency(config); + filter_status_code(config); graceful_server_shutdown(config); high_initial_seqno(config); hpack_size(config); @@ -265,6 +321,22 @@ void grpc_end2end_tests(int argc, char **argv, request_with_flags(config); request_with_payload(config); resource_quota_server(config); + retry(config); + retry_cancellation(config); + retry_disabled(config); + retry_exceeds_buffer_size_in_initial_batch(config); + retry_exceeds_buffer_size_in_subsequent_batch(config); + retry_non_retriable_status(config); + retry_non_retriable_status_before_recv_trailing_metadata_started(config); + retry_recv_initial_metadata(config); + retry_recv_message(config); + retry_server_pushback_delay(config); + retry_server_pushback_disabled(config); + retry_streaming(config); + retry_streaming_after_commit(config); + retry_streaming_succeeds_before_replay_finished(config); + retry_throttled(config); + retry_too_many_attempts(config); server_finishes_request(config); shutdown_finishes_calls(config); shutdown_finishes_tags(config); @@ -304,6 +376,10 @@ void grpc_end2end_tests(int argc, char **argv, call_creds(config); continue; } + if (0 == strcmp("call_host_override", argv[i])) { + call_host_override(config); + continue; + } if (0 == strcmp("cancel_after_accept", argv[i])) { cancel_after_accept(config); continue; @@ -364,6 +440,10 @@ void grpc_end2end_tests(int argc, char **argv, filter_latency(config); continue; } + if (0 == strcmp("filter_status_code", argv[i])) { + filter_status_code(config); + continue; + } if (0 == strcmp("graceful_server_shutdown", argv[i])) { graceful_server_shutdown(config); continue; @@ -460,6 +540,70 @@ void grpc_end2end_tests(int argc, char **argv, resource_quota_server(config); continue; } + if (0 == strcmp("retry", argv[i])) { + retry(config); + continue; + } + if (0 == strcmp("retry_cancellation", argv[i])) { + retry_cancellation(config); + continue; + } + if (0 == strcmp("retry_disabled", argv[i])) { + retry_disabled(config); + continue; + } + if (0 == strcmp("retry_exceeds_buffer_size_in_initial_batch", argv[i])) { + retry_exceeds_buffer_size_in_initial_batch(config); + continue; + } + if (0 == strcmp("retry_exceeds_buffer_size_in_subsequent_batch", argv[i])) { + retry_exceeds_buffer_size_in_subsequent_batch(config); + continue; + } + if (0 == strcmp("retry_non_retriable_status", argv[i])) { + retry_non_retriable_status(config); + continue; + } + if (0 == strcmp("retry_non_retriable_status_before_recv_trailing_metadata_started", argv[i])) { + retry_non_retriable_status_before_recv_trailing_metadata_started(config); + continue; + } + if (0 == strcmp("retry_recv_initial_metadata", argv[i])) { + retry_recv_initial_metadata(config); + continue; + } + if (0 == strcmp("retry_recv_message", argv[i])) { + retry_recv_message(config); + continue; + } + if (0 == strcmp("retry_server_pushback_delay", argv[i])) { + retry_server_pushback_delay(config); + continue; + } + if (0 == strcmp("retry_server_pushback_disabled", argv[i])) { + retry_server_pushback_disabled(config); + continue; + } + if (0 == strcmp("retry_streaming", argv[i])) { + retry_streaming(config); + continue; + } + if (0 == strcmp("retry_streaming_after_commit", argv[i])) { + retry_streaming_after_commit(config); + continue; + } + if (0 == strcmp("retry_streaming_succeeds_before_replay_finished", argv[i])) { + retry_streaming_succeeds_before_replay_finished(config); + continue; + } + if (0 == strcmp("retry_throttled", argv[i])) { + retry_throttled(config); + continue; + } + if (0 == strcmp("retry_too_many_attempts", argv[i])) { + retry_too_many_attempts(config); + continue; + } if (0 == strcmp("server_finishes_request", argv[i])) { server_finishes_request(config); continue; diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h index b42d90b55c..a1ebdedea8 100644 --- a/test/core/end2end/end2end_tests.h +++ b/test/core/end2end/end2end_tests.h @@ -52,6 +52,11 @@ struct grpc_end2end_test_config { /* Which features are supported by this fixture. See feature flags above. */ uint32_t feature_mask; + /* If the call host is setup by the fixture (for example, via the + * GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg), which value should the test + * expect to find in call_details.host */ + const char* overridden_call_host; + grpc_end2end_test_fixture (*create_fixture)(grpc_channel_args* client_args, grpc_channel_args* server_args); void (*init_client)(grpc_end2end_test_fixture* f, diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc index 75c80aa1ff..29b1d6d883 100644 --- a/test/core/end2end/fixtures/h2_census.cc +++ b/test/core/end2end/fixtures/h2_census.cc @@ -21,16 +21,15 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -112,7 +111,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index 5b9181586c..4aaadf715c 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -21,16 +21,15 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -110,7 +109,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_fullstack_compression, + nullptr, chttp2_create_fixture_fullstack_compression, chttp2_init_client_fullstack_compression, chttp2_init_server_fullstack_compression, chttp2_tear_down_fullstack_compression}, diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc index 87d4668d50..a653d7c477 100644 --- a/test/core/end2end/fixtures/h2_fakesec.cc +++ b/test/core/end2end/fixtures/h2_fakesec.cc @@ -22,9 +22,10 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> + #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -131,10 +132,9 @@ static void chttp2_init_server_fake_secure_fullstack( static grpc_end2end_test_config configs[] = { {"chttp2/fake_secure_fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | - FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_secure_fullstack, + nullptr, chttp2_create_fixture_secure_fullstack, chttp2_init_client_fake_secure_fullstack, chttp2_init_server_fake_secure_fullstack, chttp2_tear_down_secure_fullstack}, diff --git a/test/core/end2end/fixtures/h2_fd.cc b/test/core/end2end/fixtures/h2_fd.cc index 9157ab04d0..52be0f7fd5 100644 --- a/test/core/end2end/fixtures/h2_fd.cc +++ b/test/core/end2end/fixtures/h2_fd.cc @@ -96,7 +96,7 @@ static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) { /* All test configurations */ static grpc_end2end_test_config configs[] = { - {"chttp2/fd", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, + {"chttp2/fd", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr, chttp2_create_fixture_socketpair, chttp2_init_client_socketpair, chttp2_init_server_socketpair, chttp2_tear_down_socketpair}, }; diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc index b080591e85..c5329640dc 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.cc +++ b/test/core/end2end/fixtures/h2_full+pipe.cc @@ -26,15 +26,14 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" @@ -97,7 +96,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index a49de96009..ba7a780304 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -26,16 +26,15 @@ #endif #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/support/env.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -97,7 +96,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc index 237841d185..78da8418f6 100644 --- a/test/core/end2end/fixtures/h2_full+workarounds.cc +++ b/test/core/end2end/fixtures/h2_full+workarounds.cc @@ -21,16 +21,16 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include <grpc/support/workaround_list.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -107,7 +107,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | FEATURE_MASK_SUPPORTS_WORKAROUNDS, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc index 6d15c28662..0c826b6836 100644 --- a/test/core/end2end/fixtures/h2_full.cc +++ b/test/core/end2end/fixtures/h2_full.cc @@ -21,15 +21,14 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -91,7 +90,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc index 099367d91b..0af8a29a15 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.cc +++ b/test/core/end2end/fixtures/h2_http_proxy.cc @@ -21,17 +21,16 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/support/env.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/http_proxy_fixture.h" @@ -72,11 +71,12 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, /* If testing for proxy auth, add credentials to proxy uri */ const grpc_arg* proxy_auth_arg = grpc_channel_args_find(client_args, GRPC_ARG_HTTP_PROXY_AUTH_CREDS); - if (proxy_auth_arg == nullptr || proxy_auth_arg->type != GRPC_ARG_STRING) { + const char* proxy_auth_str = grpc_channel_arg_get_string(proxy_auth_arg); + if (proxy_auth_str == nullptr) { gpr_asprintf(&proxy_uri, "http://%s", grpc_end2end_http_proxy_get_proxy_name(ffd->proxy)); } else { - gpr_asprintf(&proxy_uri, "http://%s@%s", proxy_auth_arg->value.string, + gpr_asprintf(&proxy_uri, "http://%s@%s", proxy_auth_str, grpc_end2end_http_proxy_get_proxy_name(ffd->proxy)); } gpr_setenv("http_proxy", proxy_uri); @@ -113,7 +113,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_load_reporting.cc b/test/core/end2end/fixtures/h2_load_reporting.cc index fda5f4b052..18ea10a8d2 100644 --- a/test/core/end2end/fixtures/h2_load_reporting.cc +++ b/test/core/end2end/fixtures/h2_load_reporting.cc @@ -21,17 +21,16 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/filters/load_reporting/server_load_reporting_plugin.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -99,8 +98,9 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_load_reporting, chttp2_init_client_load_reporting, - chttp2_init_server_load_reporting, chttp2_tear_down_load_reporting}, + nullptr, chttp2_create_fixture_load_reporting, + chttp2_init_client_load_reporting, chttp2_init_server_load_reporting, + chttp2_tear_down_load_reporting}, }; int main(int argc, char** argv) { diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc index 5fed4434de..d44aafd50a 100644 --- a/test/core/end2end/fixtures/h2_oauth2.cc +++ b/test/core/end2end/fixtures/h2_oauth2.cc @@ -22,9 +22,10 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> + #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -65,7 +66,7 @@ static void process_oauth2_success(void* state, grpc_auth_context* ctx, test_processor_state* s; GPR_ASSERT(state != nullptr); - s = (test_processor_state*)state; + s = static_cast<test_processor_state*>(state); GPR_ASSERT(s->pseudo_refcount == 1); GPR_ASSERT(oauth2 != nullptr); grpc_auth_context_add_cstring_property(ctx, client_identity_property_name, @@ -83,7 +84,7 @@ static void process_oauth2_failure(void* state, grpc_auth_context* ctx, find_metadata(md, md_count, "authorization", oauth2_md); test_processor_state* s; GPR_ASSERT(state != nullptr); - s = (test_processor_state*)state; + s = static_cast<test_processor_state*>(state); GPR_ASSERT(s->pseudo_refcount == 1); GPR_ASSERT(oauth2 != nullptr); cb(user_data, oauth2, 1, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr); @@ -176,7 +177,7 @@ static int fail_server_auth_check(grpc_channel_args* server_args) { } static void processor_destroy(void* state) { - test_processor_state* s = (test_processor_state*)state; + test_processor_state* s = static_cast<test_processor_state*>(state); GPR_ASSERT((s->pseudo_refcount--) == 1); gpr_free(s); } @@ -215,7 +216,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_secure_fullstack, + "foo.test.google.fr", chttp2_create_fixture_secure_fullstack, chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack, chttp2_init_server_simple_ssl_secure_fullstack, chttp2_tear_down_secure_fullstack}, diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc index 295654cb6a..a32000061a 100644 --- a/test/core/end2end/fixtures/h2_proxy.cc +++ b/test/core/end2end/fixtures/h2_proxy.cc @@ -21,15 +21,14 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/proxy.h" @@ -49,7 +48,17 @@ static grpc_server* create_proxy_server(const char* port, static grpc_channel* create_proxy_client(const char* target, grpc_channel_args* client_args) { - return grpc_insecure_channel_create(target, client_args, nullptr); + // Disable retries in proxy client. + grpc_arg arg; + arg.type = GRPC_ARG_INTEGER; + arg.key = const_cast<char*>(GRPC_ARG_ENABLE_RETRIES); + arg.value.integer = 0; + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(client_args, &arg, 1); + grpc_channel* channel = + grpc_insecure_channel_create(target, new_args, nullptr); + grpc_channel_args_destroy(new_args); + return channel; } static const grpc_end2end_proxy_def proxy_def = {create_proxy_server, @@ -108,7 +117,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_REQUEST_PROXYING | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index 9807e929af..cdefcf4546 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -28,17 +28,16 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/client/http_client_filter.h" #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/support/env.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" @@ -64,9 +63,14 @@ typedef struct { static void client_setup_transport(void* ts, grpc_transport* transport) { sp_client_setup* cs = static_cast<sp_client_setup*>(ts); - - cs->f->client = grpc_channel_create("socketpair-target", cs->client_args, + grpc_arg authority_arg = grpc_channel_arg_string_create( + const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), + const_cast<char*>("test-authority")); + grpc_channel_args* args = + grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1); + cs->f->client = grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport); + grpc_channel_args_destroy(args); } static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( @@ -119,7 +123,7 @@ static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) { /* All test configurations */ static grpc_end2end_test_config configs[] = { - {"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, + {"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr, chttp2_create_fixture_socketpair, chttp2_init_client_socketpair, chttp2_init_server_socketpair, chttp2_tear_down_socketpair}, }; diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc index b68279fd71..8966cb38d4 100644 --- a/test/core/end2end/fixtures/h2_sockpair.cc +++ b/test/core/end2end/fixtures/h2_sockpair.cc @@ -23,8 +23,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/client/http_client_filter.h" #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" @@ -59,8 +58,14 @@ typedef struct { static void client_setup_transport(void* ts, grpc_transport* transport) { sp_client_setup* cs = static_cast<sp_client_setup*>(ts); - cs->f->client = grpc_channel_create("socketpair-target", cs->client_args, + grpc_arg authority_arg = grpc_channel_arg_string_create( + const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), + const_cast<char*>("test-authority")); + grpc_channel_args* args = + grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1); + cs->f->client = grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport); + grpc_channel_args_destroy(args); } static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( @@ -113,7 +118,7 @@ static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) { /* All test configurations */ static grpc_end2end_test_config configs[] = { - {"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, + {"chttp2/socketpair", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr, chttp2_create_fixture_socketpair, chttp2_init_client_socketpair, chttp2_init_server_socketpair, chttp2_tear_down_socketpair}, }; diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc index 350be138ca..ebf4162217 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc @@ -23,8 +23,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/client/http_client_filter.h" #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" @@ -59,8 +58,14 @@ typedef struct { static void client_setup_transport(void* ts, grpc_transport* transport) { sp_client_setup* cs = static_cast<sp_client_setup*>(ts); - cs->f->client = grpc_channel_create("socketpair-target", cs->client_args, + grpc_arg authority_arg = grpc_channel_arg_string_create( + const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), + const_cast<char*>("test-authority")); + grpc_channel_args* args = + grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1); + cs->f->client = grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport); + grpc_channel_args_destroy(args); } static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( @@ -125,9 +130,9 @@ static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) { /* All test configurations */ static grpc_end2end_test_config configs[] = { {"chttp2/socketpair_one_byte_at_a_time", - FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, chttp2_create_fixture_socketpair, - chttp2_init_client_socketpair, chttp2_init_server_socketpair, - chttp2_tear_down_socketpair}, + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr, + chttp2_create_fixture_socketpair, chttp2_init_client_socketpair, + chttp2_init_server_socketpair, chttp2_tear_down_socketpair}, }; int main(int argc, char** argv) { diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 9a0680c40e..999cd4cdfb 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -22,14 +22,14 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -109,10 +109,7 @@ static void chttp2_init_client_simple_ssl_secure_fullstack( grpc_channel_args* new_client_args = grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds); - { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args_destroy(new_client_args); - } + grpc_channel_args_destroy(new_client_args); } static int fail_server_auth_check(grpc_channel_args* server_args) { @@ -149,7 +146,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_secure_fullstack, + "foo.test.google.fr", chttp2_create_fixture_secure_fullstack, chttp2_init_client_simple_ssl_secure_fullstack, chttp2_init_server_simple_ssl_secure_fullstack, chttp2_tear_down_secure_fullstack}, diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index 5ddbdefc8c..9ab50c6217 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -22,14 +22,14 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/end2end/fixtures/proxy.h" #include "test/core/util/port.h" @@ -187,7 +187,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_secure_fullstack, + "foo.test.google.fr", chttp2_create_fixture_secure_fullstack, chttp2_init_client_simple_ssl_secure_fullstack, chttp2_init_server_simple_ssl_secure_fullstack, chttp2_tear_down_secure_fullstack}, diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc index 28f0a50e15..2c81c3d362 100644 --- a/test/core/end2end/fixtures/h2_uds.cc +++ b/test/core/end2end/fixtures/h2_uds.cc @@ -23,17 +23,16 @@ #include <unistd.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -96,7 +95,7 @@ static grpc_end2end_test_config configs[] = { FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index 137f7c9fa3..f02fa9d998 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -26,14 +26,14 @@ #include <grpc/slice_buffer.h> #include <grpc/support/alloc.h> #include <grpc/support/atm.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" @@ -49,12 +49,11 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/b64.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/support/string.h" #include "test/core/util/port.h" struct grpc_end2end_http_proxy { char* proxy_name; - gpr_thd_id thd; + grpc_core::Thread thd; grpc_tcp_server* server; grpc_channel_args* channel_args; gpr_mu* mu; @@ -186,7 +185,7 @@ static void proxy_connection_failed(proxy_connection* conn, // Callback for writing proxy data to the client. static void on_client_write_done(void* arg, grpc_error* error) { - proxy_connection* conn = (proxy_connection*)arg; + proxy_connection* conn = static_cast<proxy_connection*>(arg); conn->client_is_writing = false; if (error != GRPC_ERROR_NONE) { proxy_connection_failed(conn, CLIENT_WRITE_FAILED, @@ -211,7 +210,7 @@ static void on_client_write_done(void* arg, grpc_error* error) { // Callback for writing proxy data to the backend server. static void on_server_write_done(void* arg, grpc_error* error) { - proxy_connection* conn = (proxy_connection*)arg; + proxy_connection* conn = static_cast<proxy_connection*>(arg); conn->server_is_writing = false; if (error != GRPC_ERROR_NONE) { proxy_connection_failed(conn, SERVER_WRITE_FAILED, @@ -237,7 +236,7 @@ static void on_server_write_done(void* arg, grpc_error* error) { // Callback for reading data from the client, which will be proxied to // the backend server. static void on_client_read_done(void* arg, grpc_error* error) { - proxy_connection* conn = (proxy_connection*)arg; + proxy_connection* conn = static_cast<proxy_connection*>(arg); if (error != GRPC_ERROR_NONE) { proxy_connection_failed(conn, CLIENT_READ_FAILED, "HTTP proxy client read", GRPC_ERROR_REF(error)); @@ -268,7 +267,7 @@ static void on_client_read_done(void* arg, grpc_error* error) { // Callback for reading data from the backend server, which will be // proxied to the client. static void on_server_read_done(void* arg, grpc_error* error) { - proxy_connection* conn = (proxy_connection*)arg; + proxy_connection* conn = static_cast<proxy_connection*>(arg); if (error != GRPC_ERROR_NONE) { proxy_connection_failed(conn, SERVER_READ_FAILED, "HTTP proxy server read", GRPC_ERROR_REF(error)); @@ -298,7 +297,7 @@ static void on_server_read_done(void* arg, grpc_error* error) { // Callback to write the HTTP response for the CONNECT request. static void on_write_response_done(void* arg, grpc_error* error) { - proxy_connection* conn = (proxy_connection*)arg; + proxy_connection* conn = static_cast<proxy_connection*>(arg); conn->client_is_writing = false; if (error != GRPC_ERROR_NONE) { proxy_connection_failed(conn, SETUP_FAILED, "HTTP proxy write response", @@ -322,7 +321,7 @@ static void on_write_response_done(void* arg, grpc_error* error) { // Callback to connect to the backend server specified by the HTTP // CONNECT request. static void on_server_connect_done(void* arg, grpc_error* error) { - proxy_connection* conn = (proxy_connection*)arg; + proxy_connection* conn = static_cast<proxy_connection*>(arg); if (error != GRPC_ERROR_NONE) { // TODO(roth): Technically, in this case, we should handle the error // by returning an HTTP response to the client indicating that the @@ -371,7 +370,7 @@ static bool proxy_auth_header_matches(char* proxy_auth_header_val, // of this test code, it's fine to pretend this is a client-side error, // which will cause the client connection to be dropped. static void on_read_request_done(void* arg, grpc_error* error) { - proxy_connection* conn = (proxy_connection*)arg; + proxy_connection* conn = static_cast<proxy_connection*>(arg); gpr_log(GPR_DEBUG, "on_read_request_done: %p %s", conn, grpc_error_string(error)); if (error != GRPC_ERROR_NONE) { @@ -414,12 +413,13 @@ static void on_read_request_done(void* arg, grpc_error* error) { // If proxy auth is being used, check if the header is present and as expected const grpc_arg* proxy_auth_arg = grpc_channel_args_find( conn->proxy->channel_args, GRPC_ARG_HTTP_PROXY_AUTH_CREDS); - if (proxy_auth_arg != nullptr && proxy_auth_arg->type == GRPC_ARG_STRING) { + char* proxy_auth_str = grpc_channel_arg_get_string(proxy_auth_arg); + if (proxy_auth_str != nullptr) { bool client_authenticated = false; for (size_t i = 0; i < conn->http_request.hdr_count; i++) { if (strcmp(conn->http_request.hdrs[i].key, "Proxy-Authorization") == 0) { client_authenticated = proxy_auth_header_matches( - conn->http_request.hdrs[i].value, proxy_auth_arg->value.string); + conn->http_request.hdrs[i].value, proxy_auth_str); break; } } @@ -457,9 +457,10 @@ static void on_accept(void* arg, grpc_endpoint* endpoint, grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor) { gpr_free(acceptor); - grpc_end2end_http_proxy* proxy = (grpc_end2end_http_proxy*)arg; + grpc_end2end_http_proxy* proxy = static_cast<grpc_end2end_http_proxy*>(arg); // Instantiate proxy_connection. - proxy_connection* conn = (proxy_connection*)gpr_zalloc(sizeof(*conn)); + proxy_connection* conn = + static_cast<proxy_connection*>(gpr_zalloc(sizeof(*conn))); gpr_ref(&proxy->users); conn->client_endpoint = endpoint; conn->proxy = proxy; @@ -500,7 +501,7 @@ static void on_accept(void* arg, grpc_endpoint* endpoint, // static void thread_main(void* arg) { - grpc_end2end_http_proxy* proxy = (grpc_end2end_http_proxy*)arg; + grpc_end2end_http_proxy* proxy = static_cast<grpc_end2end_http_proxy*>(arg); grpc_core::ExecCtx exec_ctx; do { gpr_ref(&proxy->users); @@ -519,7 +520,7 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( grpc_channel_args* args) { grpc_core::ExecCtx exec_ctx; grpc_end2end_http_proxy* proxy = - (grpc_end2end_http_proxy*)gpr_malloc(sizeof(*proxy)); + static_cast<grpc_end2end_http_proxy*>(gpr_malloc(sizeof(*proxy))); memset(proxy, 0, sizeof(*proxy)); proxy->combiner = grpc_combiner_create(); gpr_ref_init(&proxy->users, 1); @@ -534,29 +535,28 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( GPR_ASSERT(error == GRPC_ERROR_NONE); // Bind to port. grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + grpc_sockaddr_in* addr = + reinterpret_cast<grpc_sockaddr_in*>(resolved_addr.addr); memset(&resolved_addr, 0, sizeof(resolved_addr)); - addr->sin_family = AF_INET; + addr->sin_family = GRPC_AF_INET; grpc_sockaddr_set_port(&resolved_addr, proxy_port); int port; error = grpc_tcp_server_add_port(proxy->server, &resolved_addr, &port); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(port == proxy_port); // Start server. - proxy->pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); + proxy->pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(proxy->pollset, &proxy->mu); grpc_tcp_server_start(proxy->server, &proxy->pollset, 1, on_accept, proxy); // Start proxy thread. - gpr_thd_options opt = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&opt); - GPR_ASSERT( - gpr_thd_new(&proxy->thd, "grpc_http_proxy", thread_main, proxy, &opt)); + proxy->thd = grpc_core::Thread("grpc_http_proxy", thread_main, proxy); + proxy->thd.Start(); return proxy; } static void destroy_pollset(void* arg, grpc_error* error) { - grpc_pollset* pollset = (grpc_pollset*)arg; + grpc_pollset* pollset = static_cast<grpc_pollset*>(arg); grpc_pollset_destroy(pollset); gpr_free(pollset); } @@ -564,7 +564,7 @@ static void destroy_pollset(void* arg, grpc_error* error) { void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { gpr_unref(&proxy->users); // Signal proxy thread to shutdown. grpc_core::ExecCtx exec_ctx; - gpr_thd_join(proxy->thd); + proxy->thd.Join(); grpc_tcp_server_shutdown_listeners(proxy->server); grpc_tcp_server_unref(proxy->server); gpr_free(proxy->proxy_name); diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc index b748fbf09a..be6eda8483 100644 --- a/test/core/end2end/fixtures/inproc.cc +++ b/test/core/end2end/fixtures/inproc.cc @@ -21,15 +21,14 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/inproc/inproc_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -76,8 +75,9 @@ void inproc_tear_down(grpc_end2end_test_fixture* f) { /* All test configurations */ static grpc_end2end_test_config configs[] = { - {"inproc", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, inproc_create_fixture, - inproc_init_client, inproc_init_server, inproc_tear_down}, + {"inproc", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr, + inproc_create_fixture, inproc_init_client, inproc_init_server, + inproc_tear_down}, }; int main(int argc, char** argv) { diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc index b1698c804c..042c858b4c 100644 --- a/test/core/end2end/fixtures/proxy.cc +++ b/test/core/end2end/fixtures/proxy.cc @@ -21,16 +21,16 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" #include "test/core/util/port.h" struct grpc_end2end_proxy { - gpr_thd_id thd; + grpc_core::Thread thd; char* proxy_port; char* server_port; grpc_completion_queue* cq; @@ -76,11 +76,11 @@ static void request_call(grpc_end2end_proxy* proxy); grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def, grpc_channel_args* client_args, grpc_channel_args* server_args) { - gpr_thd_options opt = gpr_thd_options_default(); int proxy_port = grpc_pick_unused_port_or_die(); int server_port = grpc_pick_unused_port_or_die(); - grpc_end2end_proxy* proxy = (grpc_end2end_proxy*)gpr_malloc(sizeof(*proxy)); + grpc_end2end_proxy* proxy = + static_cast<grpc_end2end_proxy*>(gpr_malloc(sizeof(*proxy))); memset(proxy, 0, sizeof(*proxy)); gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port); @@ -97,9 +97,8 @@ grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def, grpc_server_start(proxy->server); grpc_call_details_init(&proxy->new_call_details); - gpr_thd_options_set_joinable(&opt); - GPR_ASSERT( - gpr_thd_new(&proxy->thd, "grpc_end2end_proxy", thread_main, proxy, &opt)); + proxy->thd = grpc_core::Thread("grpc_end2end_proxy", thread_main, proxy); + proxy->thd.Start(); request_call(proxy); @@ -107,14 +106,14 @@ grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def, } static closure* new_closure(void (*func)(void* arg, int success), void* arg) { - closure* cl = (closure*)gpr_malloc(sizeof(*cl)); + closure* cl = static_cast<closure*>(gpr_malloc(sizeof(*cl))); cl->func = func; cl->arg = arg; return cl; } static void shutdown_complete(void* arg, int success) { - grpc_end2end_proxy* proxy = (grpc_end2end_proxy*)arg; + grpc_end2end_proxy* proxy = static_cast<grpc_end2end_proxy*>(arg); proxy->shutdown = 1; grpc_completion_queue_shutdown(proxy->cq); } @@ -122,7 +121,7 @@ static void shutdown_complete(void* arg, int success) { void grpc_end2end_proxy_destroy(grpc_end2end_proxy* proxy) { grpc_server_shutdown_and_notify(proxy->server, proxy->cq, new_closure(shutdown_complete, proxy)); - gpr_thd_join(proxy->thd); + proxy->thd.Join(); gpr_free(proxy->proxy_port); gpr_free(proxy->server_port); grpc_server_destroy(proxy->server); @@ -147,12 +146,12 @@ static void unrefpc(proxy_call* pc, const char* reason) { static void refpc(proxy_call* pc, const char* reason) { gpr_ref(&pc->refs); } static void on_c2p_sent_initial_metadata(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); unrefpc(pc, "on_c2p_sent_initial_metadata"); } static void on_p2s_recv_initial_metadata(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); grpc_op op; grpc_call_error err; @@ -174,14 +173,14 @@ static void on_p2s_recv_initial_metadata(void* arg, int success) { } static void on_p2s_sent_initial_metadata(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); unrefpc(pc, "on_p2s_sent_initial_metadata"); } static void on_c2p_recv_msg(void* arg, int success); static void on_p2s_sent_message(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); grpc_op op; grpc_call_error err; @@ -201,12 +200,12 @@ static void on_p2s_sent_message(void* arg, int success) { } static void on_p2s_sent_close(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); unrefpc(pc, "on_p2s_sent_close"); } static void on_c2p_recv_msg(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); grpc_op op; grpc_call_error err; @@ -241,7 +240,7 @@ static void on_c2p_recv_msg(void* arg, int success) { static void on_p2s_recv_msg(void* arg, int success); static void on_c2p_sent_message(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); grpc_op op; grpc_call_error err; @@ -261,7 +260,7 @@ static void on_c2p_sent_message(void* arg, int success) { } static void on_p2s_recv_msg(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); grpc_op op; grpc_call_error err; @@ -281,12 +280,12 @@ static void on_p2s_recv_msg(void* arg, int success) { } static void on_c2p_sent_status(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); unrefpc(pc, "on_c2p_sent_status"); } static void on_p2s_status(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); grpc_op op; grpc_call_error err; @@ -311,18 +310,18 @@ static void on_p2s_status(void* arg, int success) { } static void on_c2p_closed(void* arg, int success) { - proxy_call* pc = (proxy_call*)arg; + proxy_call* pc = static_cast<proxy_call*>(arg); unrefpc(pc, "on_c2p_closed"); } static void on_new_call(void* arg, int success) { - grpc_end2end_proxy* proxy = (grpc_end2end_proxy*)arg; + grpc_end2end_proxy* proxy = static_cast<grpc_end2end_proxy*>(arg); grpc_call_error err; if (success) { grpc_op op; memset(&op, 0, sizeof(op)); - proxy_call* pc = (proxy_call*)gpr_malloc(sizeof(*pc)); + proxy_call* pc = static_cast<proxy_call*>(gpr_malloc(sizeof(*pc))); memset(pc, 0, sizeof(*pc)); pc->proxy = proxy; GPR_SWAP(grpc_metadata_array, pc->c2p_initial_metadata, @@ -412,7 +411,7 @@ static void request_call(grpc_end2end_proxy* proxy) { } static void thread_main(void* arg) { - grpc_end2end_proxy* proxy = (grpc_end2end_proxy*)arg; + grpc_end2end_proxy* proxy = static_cast<grpc_end2end_proxy*>(arg); closure* cl; for (;;) { grpc_event ev = grpc_completion_queue_next( @@ -424,7 +423,7 @@ static void thread_main(void* arg) { case GRPC_QUEUE_SHUTDOWN: return; case GRPC_OP_COMPLETE: - cl = (closure*)ev.tag; + cl = static_cast<closure*>(ev.tag); cl->func(cl->arg, ev.success); gpr_free(cl); break; diff --git a/test/core/end2end/fuzzers/BUILD b/test/core/end2end/fuzzers/BUILD index d33e2b0ff4..c12cfc6983 100644 --- a/test/core/end2end/fuzzers/BUILD +++ b/test/core/end2end/fuzzers/BUILD @@ -25,6 +25,8 @@ grpc_fuzzer( srcs = ["api_fuzzer.cc"], language = "C++", corpus = "api_fuzzer_corpus", + size = "enormous", + timeout = "eternal", deps = [ "//:gpr", "//:grpc", diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index 967a6d560f..36f257d6da 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -28,18 +28,24 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/support/env.h" #include "src/core/lib/surface/server.h" #include "src/core/lib/transport/metadata.h" #include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/fuzzer_util.h" #include "test/core/util/passthru_endpoint.h" +using grpc_core::testing::grpc_fuzzer_get_next_byte; +using grpc_core::testing::grpc_fuzzer_get_next_string; +using grpc_core::testing::grpc_fuzzer_get_next_uint32; +using grpc_core::testing::input_stream; + //////////////////////////////////////////////////////////////////////////////// // logging @@ -65,58 +71,20 @@ static gpr_timespec now_impl(gpr_clock_type clock_type) { return ts; } -//////////////////////////////////////////////////////////////////////////////// -// input_stream: 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; - -static uint8_t next_byte(input_stream* inp) { - if (inp->cur == inp->end) { - return 0; - } - return *inp->cur++; -} - static void end(input_stream* inp) { inp->cur = inp->end; } -static char* read_string(input_stream* inp, bool* special) { - char* str = nullptr; - size_t cap = 0; - size_t sz = 0; - char c; - do { - if (cap == sz) { - cap = GPR_MAX(3 * cap / 2, cap + 8); - str = static_cast<char*>(gpr_realloc(str, cap)); - } - c = (char)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; -} - static void read_buffer(input_stream* inp, char** buffer, size_t* length, bool* special) { - *length = next_byte(inp); + *length = grpc_fuzzer_get_next_byte(inp); if (*length == 255) { if (special != nullptr) *special = true; - *length = next_byte(inp); + *length = grpc_fuzzer_get_next_byte(inp); } else { if (special != nullptr) *special = false; } *buffer = static_cast<char*>(gpr_malloc(*length)); for (size_t i = 0; i < *length; i++) { - (*buffer)[i] = (char)next_byte(inp); + (*buffer)[i] = static_cast<char>(grpc_fuzzer_get_next_byte(inp)); } } @@ -128,7 +96,7 @@ static grpc_slice maybe_intern(grpc_slice s, bool intern) { static grpc_slice read_string_like_slice(input_stream* inp) { bool special; - char* s = read_string(inp, &special); + char* s = grpc_fuzzer_get_next_string(inp, &special); grpc_slice r = maybe_intern(grpc_slice_from_copied_string(s), special); gpr_free(s); return r; @@ -146,39 +114,15 @@ static grpc_slice read_buffer_like_slice(input_stream* inp) { } static uint32_t read_uint22(input_stream* inp) { - uint8_t b = next_byte(inp); + uint8_t b = grpc_fuzzer_get_next_byte(inp); uint32_t x = b & 0x7f; if (b & 0x80) { x <<= 7; - b = next_byte(inp); + b = grpc_fuzzer_get_next_byte(inp); x |= b & 0x7f; if (b & 0x80) { x <<= 8; - x |= next_byte(inp); - } - } - return x; -} - -static uint32_t read_uint32(input_stream* inp) { - uint8_t b = next_byte(inp); - uint32_t x = b & 0x7f; - if (b & 0x80) { - x <<= 7; - b = next_byte(inp); - x |= b & 0x7f; - if (b & 0x80) { - x <<= 7; - b = next_byte(inp); - x |= b & 0x7f; - if (b & 0x80) { - x <<= 7; - b = next_byte(inp); - x |= b & 0x7f; - if (b & 0x80) { - x = (x << 4) | (next_byte(inp) & 0x0f); - } - } + x |= grpc_fuzzer_get_next_byte(inp); } } return x; @@ -192,21 +136,23 @@ static grpc_byte_buffer* read_message(input_stream* inp) { return out; } -static int read_int(input_stream* inp) { return (int)read_uint32(inp); } +static int read_int(input_stream* inp) { + return static_cast<int>(grpc_fuzzer_get_next_uint32(inp)); +} static grpc_channel_args* read_args(input_stream* inp) { - size_t n = next_byte(inp); + size_t n = grpc_fuzzer_get_next_byte(inp); grpc_arg* args = static_cast<grpc_arg*>(gpr_malloc(sizeof(*args) * n)); for (size_t i = 0; i < n; i++) { - switch (next_byte(inp)) { + switch (grpc_fuzzer_get_next_byte(inp)) { case 1: args[i].type = GRPC_ARG_STRING; - args[i].key = read_string(inp, nullptr); - args[i].value.string = read_string(inp, nullptr); + args[i].key = grpc_fuzzer_get_next_string(inp, nullptr); + args[i].value.string = grpc_fuzzer_get_next_string(inp, nullptr); break; case 2: args[i].type = GRPC_ARG_INTEGER; - args[i].key = read_string(inp, nullptr); + args[i].key = grpc_fuzzer_get_next_string(inp, nullptr); args[i].value.integer = read_int(inp); break; case 3: @@ -247,10 +193,11 @@ static void cred_artifact_ctx_finish(cred_artifact_ctx* ctx) { static const char* read_cred_artifact(cred_artifact_ctx* ctx, input_stream* inp, const char** builtins, size_t num_builtins) { - uint8_t b = next_byte(inp); + uint8_t b = grpc_fuzzer_get_next_byte(inp); if (b == 0) return nullptr; if (b == 1) - return ctx->release[ctx->num_release++] = read_string(inp, nullptr); + return ctx->release[ctx->num_release++] = + grpc_fuzzer_get_next_string(inp, nullptr); if (b >= num_builtins + 1) { end(inp); return nullptr; @@ -280,16 +227,21 @@ static grpc_channel_credentials* read_ssl_channel_creds(input_stream* inp) { return creds; } -static grpc_call_credentials* read_call_creds(input_stream* inp) { - switch (next_byte(inp)) { +static grpc_call_credentials* read_call_creds(input_stream* inp, int depth) { + if (depth > 64) { + // prevent creating infinitely deep call creds + end(inp); + return nullptr; + } + switch (grpc_fuzzer_get_next_byte(inp)) { default: end(inp); return nullptr; case 0: return nullptr; case 1: { - grpc_call_credentials* c1 = read_call_creds(inp); - grpc_call_credentials* c2 = read_call_creds(inp); + grpc_call_credentials* c1 = read_call_creds(inp, depth + 1); + grpc_call_credentials* c2 = read_call_creds(inp, depth + 1); if (c1 != nullptr && c2 != nullptr) { grpc_call_credentials* out = grpc_composite_call_credentials_create(c1, c2, nullptr); @@ -332,13 +284,13 @@ static grpc_call_credentials* read_call_creds(input_stream* inp) { } static grpc_channel_credentials* read_channel_creds(input_stream* inp) { - switch (next_byte(inp)) { + switch (grpc_fuzzer_get_next_byte(inp)) { case 0: return read_ssl_channel_creds(inp); break; case 1: { grpc_channel_credentials* c1 = read_channel_creds(inp); - grpc_call_credentials* c2 = read_call_creds(inp); + grpc_call_credentials* c2 = read_call_creds(inp, 0); if (c1 != nullptr && c2 != nullptr) { grpc_channel_credentials* out = grpc_composite_channel_credentials_create(c1, c2, nullptr); @@ -419,6 +371,9 @@ void my_resolve_address(const char* addr, const char* default_port, GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); } +static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address, + nullptr}; + grpc_ares_request* my_dns_lookup_ares(const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, @@ -440,12 +395,6 @@ grpc_ares_request* my_dns_lookup_ares(const char* dns_server, const char* addr, //////////////////////////////////////////////////////////////////////////////// // client connection -// defined in tcp_client_posix.c -extern void (*grpc_tcp_client_connect_impl)( - 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); - static void sched_connect(grpc_closure* closure, grpc_endpoint** ep, gpr_timespec deadline); @@ -506,6 +455,8 @@ static void my_tcp_client_connect(grpc_closure* closure, grpc_endpoint** ep, grpc_millis_to_timespec(deadline, GPR_CLOCK_MONOTONIC)); } +grpc_tcp_client_vtable fuzz_tcp_client_vtable = {my_tcp_client_connect}; + //////////////////////////////////////////////////////////////////////////////// // test driver @@ -524,10 +475,12 @@ static validator* create_validator(void (*validate)(void* arg, bool success), static void assert_success_and_decrement(void* counter, bool success) { GPR_ASSERT(success); - --*(int*)counter; + --*static_cast<int*>(counter); } -static void decrement(void* counter, bool success) { --*(int*)counter; } +static void decrement(void* counter, bool success) { + --*static_cast<int*>(counter); +} typedef struct connectivity_watch { int* counter; @@ -571,6 +524,7 @@ typedef struct call_state { grpc_slice recv_status_details; int cancelled; int pending_ops; + bool sent_initial_metadata; grpc_call_details call_details; grpc_byte_buffer* send_message; // starts at 0, individual flags from DONE_FLAG_xxx are set @@ -664,7 +618,7 @@ static grpc_slice* add_slice_to_unref(call_state* call, grpc_slice s) { static void read_metadata(input_stream* inp, size_t* count, grpc_metadata** metadata, call_state* cs) { - *count = next_byte(inp); + *count = grpc_fuzzer_get_next_byte(inp); if (*count) { *metadata = static_cast<grpc_metadata*>(gpr_malloc(*count * sizeof(**metadata))); @@ -672,7 +626,7 @@ static void read_metadata(input_stream* inp, size_t* count, for (size_t i = 0; i < *count; i++) { (*metadata)[i].key = read_string_like_slice(inp); (*metadata)[i].value = read_buffer_like_slice(inp); - (*metadata)[i].flags = read_uint32(inp); + (*metadata)[i].flags = grpc_fuzzer_get_next_uint32(inp); add_slice_to_unref(cs, (*metadata)[i].key); add_slice_to_unref(cs, (*metadata)[i].value); } @@ -743,7 +697,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (squelch && grpc_trace_fuzzer == nullptr) gpr_set_log_function(dont_log); gpr_free(grpc_trace_fuzzer); input_stream inp = {data, data + size}; - grpc_tcp_client_connect_impl = my_tcp_client_connect; + grpc_set_tcp_client_impl(&fuzz_tcp_client_vtable); gpr_now_impl = now_impl; grpc_init(); grpc_timer_manager_set_threading(false); @@ -751,7 +705,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_core::ExecCtx exec_ctx; grpc_executor_set_threading(false); } - grpc_resolve_address = my_resolve_address; + grpc_set_resolver_impl(&fuzzer_resolver); grpc_dns_lookup_ares = my_dns_lookup_ares; GPR_ASSERT(g_channel == nullptr); @@ -802,7 +756,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_timer_manager_tick(); - switch (next_byte(&inp)) { + switch (grpc_fuzzer_get_next_byte(&inp)) { // terminate on bad bytes default: end(&inp); @@ -829,13 +783,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // increment global time case 1: { g_now = gpr_time_add( - g_now, gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)); + g_now, gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp), + GPR_TIMESPAN)); break; } // create an insecure channel case 2: { if (g_channel == nullptr) { - char* target = read_string(&inp, nullptr); + char* target = grpc_fuzzer_get_next_string(&inp, nullptr); char* target_uri; gpr_asprintf(&target_uri, "dns:%s", target); grpc_channel_args* args = read_args(&inp); @@ -918,7 +873,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // check connectivity case 8: { if (g_channel != nullptr) { - uint8_t try_to_connect = next_byte(&inp); + uint8_t try_to_connect = grpc_fuzzer_get_next_byte(&inp); if (try_to_connect == 0 || try_to_connect == 1) { grpc_channel_check_connectivity_state(g_channel, try_to_connect); } else { @@ -937,7 +892,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (st != GRPC_CHANNEL_SHUTDOWN) { gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)); + gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp), + GPR_TIMESPAN)); grpc_channel_watch_connectivity_state( g_channel, st, deadline, cq, create_validator(validate_connectivity_watch, @@ -962,7 +918,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } parent_call = g_active_call->call; } - uint32_t propagation_mask = read_uint32(&inp); + uint32_t propagation_mask = grpc_fuzzer_get_next_uint32(&inp); grpc_slice method = read_string_like_slice(&inp); if (GRPC_SLICE_LENGTH(method) == 0) { ok = false; @@ -970,7 +926,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_slice host = read_string_like_slice(&inp); gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)); + gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp), + GPR_TIMESPAN)); if (ok) { call_state* cs = new_call(g_active_call, CLIENT); @@ -996,7 +953,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { end(&inp); break; } - size_t num_ops = next_byte(&inp); + size_t num_ops = grpc_fuzzer_get_next_byte(&inp); if (num_ops > 6) { end(&inp); break; @@ -1010,18 +967,23 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { uint8_t has_ops = 0; for (i = 0; i < num_ops; i++) { op = &ops[i]; - switch (next_byte(&inp)) { + switch (grpc_fuzzer_get_next_byte(&inp)) { default: /* invalid value */ op->op = (grpc_op_type)-1; ok = false; break; case GRPC_OP_SEND_INITIAL_METADATA: - op->op = GRPC_OP_SEND_INITIAL_METADATA; - has_ops |= 1 << GRPC_OP_SEND_INITIAL_METADATA; - read_metadata(&inp, &op->data.send_initial_metadata.count, - &op->data.send_initial_metadata.metadata, - g_active_call); + if (g_active_call->sent_initial_metadata) { + ok = false; + } else { + g_active_call->sent_initial_metadata = true; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + has_ops |= 1 << GRPC_OP_SEND_INITIAL_METADATA; + read_metadata(&inp, &op->data.send_initial_metadata.count, + &op->data.send_initial_metadata.metadata, + g_active_call); + } break; case GRPC_OP_SEND_MESSAGE: op->op = GRPC_OP_SEND_MESSAGE; @@ -1046,7 +1008,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { &op->data.send_status_from_server.trailing_metadata, g_active_call); op->data.send_status_from_server.status = - static_cast<grpc_status_code>(next_byte(&inp)); + static_cast<grpc_status_code>( + grpc_fuzzer_get_next_byte(&inp)); op->data.send_status_from_server.status_details = add_slice_to_unref(g_active_call, read_buffer_like_slice(&inp)); @@ -1058,9 +1021,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { &g_active_call->recv_initial_metadata; break; case GRPC_OP_RECV_MESSAGE: - op->op = GRPC_OP_RECV_MESSAGE; - has_ops |= 1 << GRPC_OP_RECV_MESSAGE; - op->data.recv_message.recv_message = &g_active_call->recv_message; + if (g_active_call->done_flags & DONE_FLAG_CALL_CLOSED) { + ok = false; + } else { + op->op = GRPC_OP_RECV_MESSAGE; + has_ops |= 1 << GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = + &g_active_call->recv_message; + } break; case GRPC_OP_RECV_STATUS_ON_CLIENT: op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; @@ -1078,7 +1046,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { break; } op->reserved = nullptr; - op->flags = read_uint32(&inp); + op->flags = grpc_fuzzer_get_next_uint32(&inp); } if (ok) { validator* v = make_finished_batch_validator(g_active_call, has_ops); @@ -1141,14 +1109,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } // enable a tracer case 17: { - char* tracer = read_string(&inp, nullptr); + char* tracer = grpc_fuzzer_get_next_string(&inp, nullptr); grpc_tracer_set_enabled(tracer, 1); gpr_free(tracer); break; } // disable a tracer case 18: { - char* tracer = read_string(&inp, nullptr); + char* tracer = grpc_fuzzer_get_next_string(&inp, nullptr); grpc_tracer_set_enabled(tracer, 0); gpr_free(tracer); break; @@ -1190,7 +1158,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // create a secure channel case 22: { if (g_channel == nullptr) { - char* target = read_string(&inp, nullptr); + char* target = grpc_fuzzer_get_next_string(&inp, nullptr); char* target_uri; gpr_asprintf(&target_uri, "dns:%s", target); grpc_channel_args* args = read_args(&inp); diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5406804084260864 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5406804084260864 Binary files differnew file mode 100644 index 0000000000..121aac7ec8 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5406804084260864 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5471994809155584 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5471994809155584 Binary files differnew file mode 100644 index 0000000000..e5d3d38e96 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-5471994809155584 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-6609852341157888 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-6609852341157888 Binary files differnew file mode 100644 index 0000000000..b7debabf19 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-api_fuzzer-6609852341157888 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4774951120797696 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4774951120797696 Binary files differnew file mode 100644 index 0000000000..36103166b7 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4774951120797696 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4829913342279680 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4829913342279680 Binary files differnew file mode 100644 index 0000000000..33bf2804b6 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4829913342279680 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-5632636438446080 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-5632636438446080 Binary files differnew file mode 100644 index 0000000000..4f995ac8e1 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-5632636438446080 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-6192640044302336 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-6192640044302336 Binary files differnew file mode 100644 index 0000000000..07b4b33231 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-6192640044302336 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/fuzz-input-d2ab5 b/test/core/end2end/fuzzers/api_fuzzer_corpus/fuzz-input-d2ab5 Binary files differnew file mode 100644 index 0000000000..1745798b68 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/fuzz-input-d2ab5 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-2d730ebd78b3052e4367ad0d485208dcb205482cbcd6289f17907989b8de1fba b/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-2d730ebd78b3052e4367ad0d485208dcb205482cbcd6289f17907989b8de1fba Binary files differnew file mode 100644 index 0000000000..89e28bbe37 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-2d730ebd78b3052e4367ad0d485208dcb205482cbcd6289f17907989b8de1fba diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index c17d581d8b..e21006bb67 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -20,6 +20,7 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> +#include <grpc/support/string_util.h> #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/iomgr/executor.h" @@ -33,7 +34,7 @@ bool leak_check = true; static void discard_write(grpc_slice slice) {} -static void* tag(int n) { return (void*)(uintptr_t)n; } +static void* tag(int n) { return (void*)static_cast<uintptr_t>(n); } static void dont_log(gpr_log_func_args* args) {} @@ -58,8 +59,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_create_chttp2_transport(nullptr, mock_endpoint, true); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); + grpc_arg authority_arg = grpc_channel_arg_string_create( + const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), + const_cast<char*>("test-authority")); + grpc_channel_args* args = + grpc_channel_args_copy_and_add(nullptr, &authority_arg, 1); grpc_channel* channel = grpc_channel_create( - "test-target", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, transport); + "test-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport); + grpc_channel_args_destroy(args); grpc_slice host = grpc_slice_from_static_string("localhost"); grpc_call* call = grpc_channel_create_call( channel, nullptr, 0, cq, grpc_slice_from_static_string("/foo"), &host, diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index 7c77512aa9..c719d0fa84 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -21,19 +21,24 @@ "\x0Auser-agent" "\x04host" "\x08lb-token" +"\x1Agrpc-previous-rpc-attempts" +"\x16grpc-retry-pushback-ms" "\x0Cgrpc-timeout" +"\x011" +"\x012" +"\x013" +"\x014" "\x00" "\x13grpc.wait_for_ready" "\x0Cgrpc.timeout" "\x1Egrpc.max_request_message_bytes" "\x1Fgrpc.max_response_message_bytes" "$/grpc.lb.v1.LoadBalancer/BalanceLoad" +"\x07deflate" +"\x04gzip" +"\x0Bstream/gzip" "\x010" -"\x011" -"\x012" "\x08identity" -"\x04gzip" -"\x07deflate" "\x08trailers" "\x10application/grpc" "\x04POST" diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc index 61c55e0afd..248c34cbc1 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.cc +++ b/test/core/end2end/fuzzers/server_fuzzer.cc @@ -30,8 +30,8 @@ bool leak_check = true; static void discard_write(grpc_slice slice) {} -static void* tag(int n) { return (void*)(uintptr_t)n; } -static int detag(void* p) { return (int)(uintptr_t)p; } +static void* tag(int n) { return (void*)static_cast<uintptr_t>(n); } +static int detag(void* p) { return static_cast<int>((uintptr_t)p); } static void dont_log(gpr_log_func_args* args) {} @@ -103,15 +103,33 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_metadata_array_destroy(&request_metadata1); grpc_server_shutdown_and_notify(server, cq, tag(0xdead)); grpc_server_cancel_all_calls(server); + grpc_millis deadline = grpc_core::ExecCtx::Get()->Now() + 5000; for (int i = 0; i <= requested_calls; i++) { - ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), - nullptr); + // A single grpc_completion_queue_next might not be sufficient for getting + // the tag from shutdown, because we might potentially get blocked by + // an operation happening on the timer thread. + // For example, the deadline timer might expire, leading to the timer + // thread trying to cancel the RPC and thereby acquiring a few references + // to the call. This will prevent the shutdown to complete till the timer + // thread releases those references. + // As a solution, we are going to keep performing a cq_next for a + // liberal period of 5 seconds for the timer thread to complete its work. + do { + ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), + nullptr); + grpc_core::ExecCtx::Get()->InvalidateNow(); + } while (ev.type != GRPC_OP_COMPLETE && + grpc_core::ExecCtx::Get()->Now() < deadline); GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); } grpc_completion_queue_shutdown(cq); for (int i = 0; i <= requested_calls; i++) { - ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), - nullptr); + do { + ev = grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), + nullptr); + grpc_core::ExecCtx::Get()->InvalidateNow(); + } while (ev.type != GRPC_QUEUE_SHUTDOWN && + grpc_core::ExecCtx::Get()->Now() < deadline); GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN); } grpc_server_destroy(server); diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 7c8e7f420a..c355fc24b5 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -24,15 +24,24 @@ import hashlib FixtureOptions = collections.namedtuple( 'FixtureOptions', - 'fullstack includes_proxy dns_resolver name_resolution secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression supports_compression is_inproc is_http2 supports_proxy_auth supports_write_buffering') + 'fullstack includes_proxy dns_resolver name_resolution secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression supports_compression is_inproc is_http2 supports_proxy_auth supports_write_buffering client_channel') default_unsecure_fixture_options = FixtureOptions( - True, False, True, True, False, ['windows', 'linux', 'mac', 'posix'], True, False, [], [], True, False, True, False, True, False, True) -socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(fullstack=False, dns_resolver=False) -default_secure_fixture_options = default_unsecure_fixture_options._replace(secure=True) -uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv']) + True, False, True, True, False, ['windows', 'linux', 'mac', 'posix'], + True, False, [], [], True, False, True, False, True, False, True, True) +socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace( + fullstack=False, dns_resolver=False, client_channel=False) +default_secure_fixture_options = default_unsecure_fixture_options._replace( + secure=True) +uds_fixture_options = default_unsecure_fixture_options._replace( + dns_resolver=False, platforms=['linux', 'mac', 'posix'], + exclude_iomgrs=['uv']) fd_unsecure_fixture_options = default_unsecure_fixture_options._replace( - dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv']) -inproc_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, fullstack=False, name_resolution=False, supports_compression=False, is_inproc=True, is_http2=False, supports_write_buffering=False) + dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'], + exclude_iomgrs=['uv'], client_channel=False) +inproc_fixture_options = default_unsecure_fixture_options._replace( + dns_resolver=False, fullstack=False, name_resolution=False, + supports_compression=False, is_inproc=True, is_http2=False, + supports_write_buffering=False, client_channel=False) # maps fixture name to whether it requires the security library END2END_FIXTURES = { @@ -68,9 +77,12 @@ END2END_FIXTURES = { TestOptions = collections.namedtuple( 'TestOptions', - 'needs_fullstack needs_dns needs_names proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allows_compression needs_compression exclude_inproc needs_http2 needs_proxy_auth needs_write_buffering') -default_test_options = TestOptions(False, False, False, True, False, True, 1.0, [], False, False, True, False, False, False, False, False) -connectivity_test_options = default_test_options._replace(needs_fullstack=True) + 'needs_fullstack needs_dns needs_names proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allows_compression needs_compression exclude_inproc needs_http2 needs_proxy_auth needs_write_buffering needs_client_channel') +default_test_options = TestOptions( + False, False, False, True, False, True, 1.0, [], False, False, True, + False, False, False, False, False, False) +connectivity_test_options = default_test_options._replace( + needs_fullstack=True) LOWCPU = 0.1 @@ -80,9 +92,8 @@ END2END_TESTS = { 'bad_hostname': default_test_options._replace(needs_names=True), 'bad_ping': connectivity_test_options._replace(proxyable=False), 'binary_metadata': default_test_options._replace(cpu_cost=LOWCPU), - 'resource_quota_server': default_test_options._replace(large_writes=True, - proxyable=False, - allows_compression=False), + 'resource_quota_server': default_test_options._replace( + large_writes=True, proxyable=False, allows_compression=False), 'call_creds': default_test_options._replace(secure=True), 'cancel_after_accept': default_test_options._replace(cpu_cost=LOWCPU), 'cancel_after_client_done': default_test_options._replace(cpu_cost=LOWCPU), @@ -91,17 +102,23 @@ END2END_TESTS = { 'cancel_before_invoke': default_test_options._replace(cpu_cost=LOWCPU), 'cancel_in_a_vacuum': default_test_options._replace(cpu_cost=LOWCPU), 'cancel_with_status': default_test_options._replace(cpu_cost=LOWCPU), - 'compressed_payload': default_test_options._replace(proxyable=False,needs_compression=True), + 'compressed_payload': default_test_options._replace(proxyable=False, + needs_compression=True), 'connectivity': connectivity_test_options._replace(needs_names=True, proxyable=False, cpu_cost=LOWCPU, exclude_iomgrs=['uv']), - 'default_host': default_test_options._replace(needs_fullstack=True, - needs_dns=True,needs_names=True), - 'disappearing_server': connectivity_test_options._replace(flaky=True,needs_names=True), + 'default_host': default_test_options._replace( + needs_fullstack=True, needs_dns=True, needs_names=True), + 'call_host_override': default_test_options._replace( + needs_fullstack=True, needs_dns=True, needs_names=True), + 'disappearing_server': connectivity_test_options._replace(flaky=True, + needs_names=True), 'empty_batch': default_test_options._replace(cpu_cost=LOWCPU), 'filter_causes_close': default_test_options._replace(cpu_cost=LOWCPU), 'filter_call_init_fails': default_test_options, 'filter_latency': default_test_options._replace(cpu_cost=LOWCPU), - 'graceful_server_shutdown': default_test_options._replace(cpu_cost=LOWCPU,exclude_inproc=True), + 'filter_status_code': default_test_options._replace(cpu_cost=LOWCPU), + 'graceful_server_shutdown': default_test_options._replace( + cpu_cost=LOWCPU, exclude_inproc=True), 'hpack_size': default_test_options._replace(proxyable=False, traceable=False, cpu_cost=LOWCPU), @@ -126,30 +143,78 @@ END2END_TESTS = { 'payload': default_test_options, 'load_reporting_hook': default_test_options, 'ping_pong_streaming': default_test_options._replace(cpu_cost=LOWCPU), - 'ping': connectivity_test_options._replace(proxyable=False, cpu_cost=LOWCPU), + 'ping': connectivity_test_options._replace(proxyable=False, + cpu_cost=LOWCPU), 'proxy_auth': default_test_options._replace(needs_proxy_auth=True), 'registered_call': default_test_options, 'request_with_flags': default_test_options._replace( proxyable=False, cpu_cost=LOWCPU), 'request_with_payload': default_test_options._replace(cpu_cost=LOWCPU), + # TODO(roth): Remove proxyable=False for all retry tests once we + # have a way for the proxy to propagate the fact that trailing + # metadata is available when initial metadata is returned. + # See https://github.com/grpc/grpc/issues/14467 for context. + 'retry': default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_cancellation': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_disabled': default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_exceeds_buffer_size_in_initial_batch': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_exceeds_buffer_size_in_subsequent_batch': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_non_retriable_status': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_non_retriable_status_before_recv_trailing_metadata_started': + default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_recv_initial_metadata': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_recv_message': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_server_pushback_delay': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_server_pushback_disabled': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_streaming': default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_streaming_after_commit': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), + 'retry_streaming_succeeds_before_replay_finished': + default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_throttled': default_test_options._replace(cpu_cost=LOWCPU, + needs_client_channel=True, + proxyable=False), + 'retry_too_many_attempts': default_test_options._replace( + cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False), 'server_finishes_request': default_test_options._replace(cpu_cost=LOWCPU), 'shutdown_finishes_calls': default_test_options._replace(cpu_cost=LOWCPU), 'shutdown_finishes_tags': default_test_options._replace(cpu_cost=LOWCPU), 'simple_cacheable_request': default_test_options._replace(cpu_cost=LOWCPU), - 'stream_compression_compressed_payload': default_test_options._replace(proxyable=False, - exclude_inproc=True), - 'stream_compression_payload': default_test_options._replace(exclude_inproc=True), - 'stream_compression_ping_pong_streaming': default_test_options._replace(exclude_inproc=True), + 'stream_compression_compressed_payload': default_test_options._replace( + proxyable=False, exclude_inproc=True), + 'stream_compression_payload': default_test_options._replace( + exclude_inproc=True), + 'stream_compression_ping_pong_streaming': default_test_options._replace( + exclude_inproc=True), 'simple_delayed_request': connectivity_test_options, 'simple_metadata': default_test_options, 'simple_request': default_test_options, 'streaming_error_response': default_test_options._replace(cpu_cost=LOWCPU), 'trailing_metadata': default_test_options, 'workaround_cronet_compression': default_test_options, - 'write_buffering': default_test_options._replace(cpu_cost=LOWCPU, - needs_write_buffering=True), - 'write_buffering_at_end': default_test_options._replace(cpu_cost=LOWCPU, - needs_write_buffering=True), + 'write_buffering': default_test_options._replace( + cpu_cost=LOWCPU, needs_write_buffering=True), + 'write_buffering_at_end': default_test_options._replace( + cpu_cost=LOWCPU, needs_write_buffering=True), } @@ -190,6 +255,9 @@ def compatible(f, t): if END2END_TESTS[t].needs_write_buffering: if not END2END_FIXTURES[f].supports_write_buffering: return False + if END2END_TESTS[t].needs_client_channel: + if not END2END_FIXTURES[f].client_channel: + return False return True diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index b9a42bdb88..11fc576165 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +POLLERS = ['epollex', 'epollsig', 'epoll1', 'poll', 'poll-cv'] + load("//bazel:grpc_build_system.bzl", "grpc_sh_test", "grpc_cc_binary", "grpc_cc_library") """Generates the appropriate build.json data for all the end2end tests.""" @@ -22,7 +24,7 @@ def fixture_options(fullstack=True, includes_proxy=False, dns_resolver=True, name_resolution=True, secure=True, tracing=False, platforms=['windows', 'linux', 'mac', 'posix'], is_inproc=False, is_http2=True, supports_proxy_auth=False, - supports_write_buffering=True): + supports_write_buffering=True, client_channel=True): return struct( fullstack=fullstack, includes_proxy=includes_proxy, @@ -33,8 +35,9 @@ def fixture_options(fullstack=True, includes_proxy=False, dns_resolver=True, is_inproc=is_inproc, is_http2=is_http2, supports_proxy_auth=supports_proxy_auth, - supports_write_buffering=supports_write_buffering - #platforms=platforms + supports_write_buffering=supports_write_buffering, + client_channel=client_channel, + #platforms=platforms, ) @@ -45,6 +48,7 @@ END2END_FIXTURES = { 'h2_load_reporting': fixture_options(), 'h2_fakesec': fixture_options(), 'h2_fd': fixture_options(dns_resolver=False, fullstack=False, + client_channel=False, platforms=['linux', 'mac', 'posix']), 'h2_full': fixture_options(), 'h2_full+pipe': fixture_options(platforms=['linux']), @@ -53,24 +57,28 @@ END2END_FIXTURES = { 'h2_http_proxy': fixture_options(supports_proxy_auth=True), 'h2_oauth2': fixture_options(), 'h2_proxy': fixture_options(includes_proxy=True), - 'h2_sockpair_1byte': fixture_options(fullstack=False, dns_resolver=False), - 'h2_sockpair': fixture_options(fullstack=False, dns_resolver=False), + 'h2_sockpair_1byte': fixture_options(fullstack=False, dns_resolver=False, + client_channel=False), + 'h2_sockpair': fixture_options(fullstack=False, dns_resolver=False, + client_channel=False), 'h2_sockpair+trace': fixture_options(fullstack=False, dns_resolver=False, - tracing=True), + tracing=True, client_channel=False), 'h2_ssl': fixture_options(secure=True), 'h2_ssl_proxy': fixture_options(includes_proxy=True, secure=True), 'h2_uds': fixture_options(dns_resolver=False, platforms=['linux', 'mac', 'posix']), 'inproc': fixture_options(fullstack=False, dns_resolver=False, name_resolution=False, is_inproc=True, - is_http2=False, supports_write_buffering=False), + is_http2=False, supports_write_buffering=False, + client_channel=False), } def test_options(needs_fullstack=False, needs_dns=False, needs_names=False, proxyable=True, secure=False, traceable=False, exclude_inproc=False, needs_http2=False, - needs_proxy_auth=False, needs_write_buffering=False): + needs_proxy_auth=False, needs_write_buffering=False, + needs_client_channel=False): return struct( needs_fullstack=needs_fullstack, needs_dns=needs_dns, @@ -81,7 +89,8 @@ def test_options(needs_fullstack=False, needs_dns=False, needs_names=False, exclude_inproc=exclude_inproc, needs_http2=needs_http2, needs_proxy_auth=needs_proxy_auth, - needs_write_buffering=needs_write_buffering + needs_write_buffering=needs_write_buffering, + needs_client_channel=needs_client_channel, ) @@ -92,6 +101,8 @@ END2END_TESTS = { 'binary_metadata': test_options(), 'resource_quota_server': test_options(proxyable=False), 'call_creds': test_options(secure=True), + 'call_host_override': test_options(needs_fullstack=True, needs_dns=True, + needs_names=True), 'cancel_after_accept': test_options(), 'cancel_after_client_done': test_options(), 'cancel_after_invoke': test_options(), @@ -116,7 +127,8 @@ END2END_TESTS = { 'invoke_large_request': test_options(), 'keepalive_timeout': test_options(proxyable=False, needs_http2=True), 'large_metadata': test_options(), - 'max_concurrent_streams': test_options(proxyable=False, exclude_inproc=True), + 'max_concurrent_streams': test_options(proxyable=False, + exclude_inproc=True), 'max_connection_age': test_options(exclude_inproc=True), 'max_connection_idle': test_options(needs_fullstack=True, proxyable=False), 'max_message_length': test_options(), @@ -132,6 +144,39 @@ END2END_TESTS = { 'registered_call': test_options(), 'request_with_flags': test_options(proxyable=False), 'request_with_payload': test_options(), + # TODO(roth): Remove proxyable=False for all retry tests once we + # have a way for the proxy to propagate the fact that trailing + # metadata is available when initial metadata is returned. + # See https://github.com/grpc/grpc/issues/14467 for context. + 'retry': test_options(needs_client_channel=True, proxyable=False), + 'retry_cancellation': test_options(needs_client_channel=True, + proxyable=False), + 'retry_disabled': test_options(needs_client_channel=True, proxyable=False), + 'retry_exceeds_buffer_size_in_initial_batch': test_options( + needs_client_channel=True, proxyable=False), + 'retry_exceeds_buffer_size_in_subsequent_batch': test_options( + needs_client_channel=True, proxyable=False), + 'retry_non_retriable_status': test_options(needs_client_channel=True, + proxyable=False), + 'retry_non_retriable_status_before_recv_trailing_metadata_started': + test_options(needs_client_channel=True, proxyable=False), + 'retry_recv_initial_metadata': test_options(needs_client_channel=True, + proxyable=False), + 'retry_recv_message': test_options(needs_client_channel=True, + proxyable=False), + 'retry_server_pushback_delay': test_options(needs_client_channel=True, + proxyable=False), + 'retry_server_pushback_disabled': test_options(needs_client_channel=True, + proxyable=False), + 'retry_streaming': test_options(needs_client_channel=True, proxyable=False), + 'retry_streaming_after_commit': test_options(needs_client_channel=True, + proxyable=False), + 'retry_streaming_succeeds_before_replay_finished': test_options( + needs_client_channel=True, proxyable=False), + 'retry_throttled': test_options(needs_client_channel=True, + proxyable=False), + 'retry_too_many_attempts': test_options(needs_client_channel=True, + proxyable=False), 'server_finishes_request': test_options(), 'shutdown_finishes_calls': test_options(), 'shutdown_finishes_tags': test_options(), @@ -140,12 +185,14 @@ END2END_TESTS = { 'simple_metadata': test_options(), 'simple_request': test_options(), 'streaming_error_response': test_options(), - 'stream_compression_compressed_payload': test_options(proxyable=False, exclude_inproc=True), + 'stream_compression_compressed_payload': test_options(proxyable=False, + exclude_inproc=True), 'stream_compression_payload': test_options(exclude_inproc=True), 'stream_compression_ping_pong_streaming': test_options(exclude_inproc=True), 'trailing_metadata': test_options(), 'authority_not_supported': test_options(), 'filter_latency': test_options(), + 'filter_status_code': test_options(), 'workaround_cronet_compression': test_options(), 'write_buffering': test_options(needs_write_buffering=True), 'write_buffering_at_end': test_options(needs_write_buffering=True), @@ -180,6 +227,9 @@ def compatible(fopt, topt): if topt.needs_write_buffering: if not fopt.supports_write_buffering: return False + if topt.needs_client_channel: + if not fopt.client_channel: + return False return True @@ -218,9 +268,14 @@ def grpc_end2end_tests(): for t, topt in END2END_TESTS.items(): #print(compatible(fopt, topt), f, t, fopt, topt) if not compatible(fopt, topt): continue - grpc_sh_test( - name = '%s_test@%s' % (f, t), - srcs = ['end2end_test.sh'], - args = ['$(location %s_test)' % f, t], - data = [':%s_test' % f], - ) + for poller in POLLERS: + native.sh_test( + name = '%s_test@%s@poller=%s' % (f, t, poller), + data = [':%s_test' % f], + srcs = ['end2end_test.sh'], + args = [ + '$(location %s_test)' % f, + t, + poller, + ], + ) diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 94cfbdda7e..0188698f17 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -21,6 +21,7 @@ including windows.h on Windows, uv.h must be included before other system headers. Therefore, sockaddr.h must always be included first */ #include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/socket_utils.h" #include <grpc/grpc.h> #include <grpc/support/alloc.h> @@ -35,14 +36,13 @@ #include "test/core/util/port.h" #include "test/core/util/test_config.h" +extern grpc_address_resolver_vtable* grpc_resolve_address_impl; +static grpc_address_resolver_vtable* default_resolver; + static void* tag(intptr_t i) { return (void*)i; } static gpr_mu g_mu; static int g_resolve_port = -1; -static void (*iomgr_resolve_address)(const char* addr, const char* default_port, - grpc_pollset_set* interested_parties, - grpc_closure* on_done, - grpc_resolved_addresses** addresses); static grpc_ares_request* (*iomgr_dns_lookup_ares)( const char* dns_server, const char* addr, const char* default_port, @@ -61,8 +61,8 @@ static void my_resolve_address(const char* addr, const char* default_port, grpc_closure* on_done, grpc_resolved_addresses** addrs) { if (0 != strcmp(addr, "test")) { - iomgr_resolve_address(addr, default_port, interested_parties, on_done, - addrs); + default_resolver->resolve_address(addr, default_port, interested_parties, + on_done, addrs); return; } @@ -77,16 +77,27 @@ static void my_resolve_address(const char* addr, const char* default_port, (*addrs)->addrs = static_cast<grpc_resolved_address*>( gpr_malloc(sizeof(*(*addrs)->addrs))); memset((*addrs)->addrs, 0, sizeof(*(*addrs)->addrs)); - struct sockaddr_in* sa = (struct sockaddr_in*)(*addrs)->addrs[0].addr; - sa->sin_family = AF_INET; - sa->sin_addr.s_addr = htonl(0x7f000001); - sa->sin_port = htons((uint16_t)g_resolve_port); - (*addrs)->addrs[0].len = sizeof(*sa); + grpc_sockaddr_in* sa = + reinterpret_cast<grpc_sockaddr_in*>((*addrs)->addrs[0].addr); + sa->sin_family = GRPC_AF_INET; + sa->sin_addr.s_addr = 0x100007f; + sa->sin_port = grpc_htons(static_cast<uint16_t>(g_resolve_port)); + (*addrs)->addrs[0].len = static_cast<socklen_t>(sizeof(*sa)); gpr_mu_unlock(&g_mu); } GRPC_CLOSURE_SCHED(on_done, error); } +static grpc_error* my_blocking_resolve_address( + const char* name, const char* default_port, + grpc_resolved_addresses** addresses) { + return default_resolver->blocking_resolve_address(name, default_port, + addresses); +} + +static grpc_address_resolver_vtable test_resolver = { + my_resolve_address, my_blocking_resolve_address}; + static grpc_ares_request* my_dns_lookup_ares( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, @@ -105,11 +116,11 @@ static grpc_ares_request* my_dns_lookup_ares( error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { *lb_addrs = grpc_lb_addresses_create(1, nullptr); - struct sockaddr_in* sa = static_cast<struct sockaddr_in*>( - gpr_zalloc(sizeof(struct sockaddr_in))); - sa->sin_family = AF_INET; - sa->sin_addr.s_addr = htonl(0x7f000001); - sa->sin_port = htons((uint16_t)g_resolve_port); + grpc_sockaddr_in* sa = + static_cast<grpc_sockaddr_in*>(gpr_zalloc(sizeof(grpc_sockaddr_in))); + sa->sin_family = GRPC_AF_INET; + sa->sin_addr.s_addr = 0x100007f; + sa->sin_port = grpc_htons(static_cast<uint16_t>(g_resolve_port)); grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, nullptr, nullptr); gpr_free(sa); @@ -129,9 +140,9 @@ int main(int argc, char** argv) { gpr_mu_init(&g_mu); grpc_init(); - iomgr_resolve_address = grpc_resolve_address; + default_resolver = grpc_resolve_address_impl; + grpc_set_resolver_impl(&test_resolver); iomgr_dns_lookup_ares = grpc_dns_lookup_ares; - grpc_resolve_address = my_resolve_address; grpc_dns_lookup_ares = my_dns_lookup_ares; int was_cancelled1; @@ -187,7 +198,7 @@ int main(int argc, char** argv) { op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; - op->flags = 0; + op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY; op->reserved = nullptr; op++; GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call1, ops, @@ -263,7 +274,7 @@ int main(int argc, char** argv) { op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; - op->flags = 0; + op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY; op->reserved = nullptr; op++; GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call2, ops, diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index d50d1f4d81..9ed6f23798 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -22,14 +22,14 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -57,8 +57,6 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); - f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - return f; } @@ -202,6 +200,7 @@ typedef enum { SUCCESS, FAIL } test_result; FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | \ FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | \ FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL, \ + "foo.test.google.fr", \ chttp2_create_fixture_secure_fullstack, \ CLIENT_INIT_NAME(cert_type), \ SERVER_INIT_NAME(request_type), \ @@ -270,13 +269,13 @@ static void drain_cq(grpc_completion_queue* cq) { } while (ev.type != GRPC_QUEUE_SHUTDOWN); } +// Shuts down the server. +// Side effect - Also shuts down and drains the completion queue. static void shutdown_server(grpc_end2end_test_fixture* f) { if (!f->server) return; - grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), - grpc_timeout_seconds_to_deadline(5), - nullptr) - .type == GRPC_OP_COMPLETE); + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); grpc_server_destroy(f->server); f->server = nullptr; } @@ -288,13 +287,9 @@ static void shutdown_client(grpc_end2end_test_fixture* f) { } static void end_test(grpc_end2end_test_fixture* f) { - shutdown_server(f); shutdown_client(f); - - grpc_completion_queue_shutdown(f->cq); - drain_cq(f->cq); + shutdown_server(f); grpc_completion_queue_destroy(f->cq); - grpc_completion_queue_destroy(f->shutdown_cq); } static void simple_request_body(grpc_end2end_test_fixture f, @@ -319,7 +314,8 @@ static void simple_request_body(grpc_end2end_test_fixture f, op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), expected_result == SUCCESS); diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc new file mode 100644 index 0000000000..d5984be93f --- /dev/null +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -0,0 +1,280 @@ +/* + * + * 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/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +#include <gtest/gtest.h> + +namespace grpc { +namespace testing { +namespace { + +void* tag(intptr_t t) { return (void*)t; } + +gpr_timespec five_seconds_time() { return grpc_timeout_seconds_to_deadline(5); } + +grpc_server* server_create(grpc_completion_queue* cq, char* server_addr) { + grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, + test_server1_cert}; + grpc_server_credentials* server_creds = grpc_ssl_server_credentials_create_ex( + test_root_cert, &pem_cert_key_pair, 1, + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, nullptr); + + grpc_server* server = grpc_server_create(nullptr, nullptr); + grpc_server_register_completion_queue(server, cq, nullptr); + GPR_ASSERT( + grpc_server_add_secure_http2_port(server, server_addr, server_creds)); + grpc_server_credentials_release(server_creds); + grpc_server_start(server); + + return server; +} + +grpc_channel* client_create(char* server_addr, grpc_ssl_session_cache* cache) { + grpc_ssl_pem_key_cert_pair signed_client_key_cert_pair = { + test_signed_client_key, test_signed_client_cert}; + grpc_channel_credentials* client_creds = grpc_ssl_credentials_create( + test_root_cert, &signed_client_key_cert_pair, nullptr); + + grpc_arg args[] = { + grpc_channel_arg_string_create( + const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), + const_cast<char*>("waterzooi.test.google.be")), + grpc_ssl_session_cache_create_channel_arg(cache), + }; + + grpc_channel_args* client_args = + grpc_channel_args_copy_and_add(nullptr, args, GPR_ARRAY_SIZE(args)); + + grpc_channel* client = grpc_secure_channel_create(client_creds, server_addr, + client_args, nullptr); + GPR_ASSERT(client != nullptr); + grpc_channel_credentials_release(client_creds); + + { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args_destroy(client_args); + } + + return client; +} + +void do_round_trip(grpc_completion_queue* cq, grpc_server* server, + char* server_addr, grpc_ssl_session_cache* cache, + bool expect_session_reuse) { + grpc_channel* client = client_create(server_addr, cache); + + cq_verifier* cqv = cq_verifier_create(cq); + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(60); + grpc_call* c = grpc_channel_create_call( + client, nullptr, GRPC_PROPAGATE_DEFAULTS, cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + grpc_call* s; + error = grpc_server_request_call(server, &s, &call_details, + &request_metadata_recv, cq, cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + grpc_auth_context* auth = grpc_call_auth_context(s); + grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( + auth, GRPC_SSL_SESSION_REUSED_PROPERTY); + const grpc_auth_property* property = grpc_auth_property_iterator_next(&it); + GPR_ASSERT(property != nullptr); + + if (expect_session_reuse) { + GPR_ASSERT(strcmp(property->value, "true") == 0); + } else { + GPR_ASSERT(strcmp(property->value, "false") == 0); + } + grpc_auth_context_release(auth); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + grpc_channel_destroy(client); +} + +void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +TEST(H2SessionReuseTest, SingleReuse) { + int port = grpc_pick_unused_port_or_die(); + + char* server_addr; + gpr_join_host_port(&server_addr, "localhost", port); + + grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); + grpc_ssl_session_cache* cache = grpc_ssl_session_cache_create_lru(16); + + grpc_server* server = server_create(cq, server_addr); + + do_round_trip(cq, server, server_addr, cache, false); + do_round_trip(cq, server, server_addr, cache, true); + do_round_trip(cq, server, server_addr, cache, true); + + gpr_free(server_addr); + grpc_ssl_session_cache_destroy(cache); + + GPR_ASSERT(grpc_completion_queue_next( + cq, grpc_timeout_milliseconds_to_deadline(100), nullptr) + .type == GRPC_QUEUE_TIMEOUT); + + grpc_completion_queue* shutdown_cq = + grpc_completion_queue_create_for_pluck(nullptr); + grpc_server_shutdown_and_notify(server, shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(server); + grpc_completion_queue_destroy(shutdown_cq); + + grpc_completion_queue_shutdown(cq); + drain_cq(cq); + grpc_completion_queue_destroy(cq); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + FILE* roots_file; + size_t roots_size = strlen(test_root_cert); + char* roots_filename; + + grpc_test_init(argc, argv); + /* Set the SSL roots env var. */ + roots_file = gpr_tmpfile("chttp2_ssl_session_reuse_test", &roots_filename); + GPR_ASSERT(roots_filename != nullptr); + GPR_ASSERT(roots_file != nullptr); + GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); + fclose(roots_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + + /* Cleanup. */ + remove(roots_filename); + gpr_free(roots_filename); + + return ret; +} diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index cb6b4c08ef..6cb2e3ee80 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -23,9 +23,9 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> +#include "src/core/lib/gpr/host_port.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -209,7 +209,7 @@ static void test_too_many_metadata() { op = g_state.ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = (size_t)INT_MAX + 1; + op->data.send_initial_metadata.count = static_cast<size_t>(INT_MAX) + 1; op->flags = 0; op->reserved = nullptr; op++; @@ -499,7 +499,7 @@ static void test_too_many_trailing_metadata() { op = g_state.ops; op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; op->data.send_status_from_server.trailing_metadata_count = - (size_t)INT_MAX + 1; + static_cast<size_t>(INT_MAX) + 1; op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; grpc_slice status_details = grpc_slice_from_static_string("xyz"); op->data.send_status_from_server.status_details = &status_details; diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index 6113885171..e8ce4032e0 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -22,45 +22,47 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/test_config.h" static void* tag(intptr_t i) { return (void*)i; } -int main(int argc, char** argv) { - grpc_channel* chan; - grpc_call* call; - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2); - grpc_completion_queue* cq; - cq_verifier* cqv; - grpc_op ops[6]; - grpc_op* op; - grpc_metadata_array trailing_metadata_recv; - grpc_status_code status; - grpc_slice details; +void run_test(bool wait_for_ready) { + gpr_log(GPR_INFO, "TEST: wait_for_ready=%d", wait_for_ready); - grpc_test_init(argc, argv); grpc_init(); - grpc_metadata_array_init(&trailing_metadata_recv); + grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); + cq_verifier* cqv = cq_verifier_create(cq); - cq = grpc_completion_queue_create_for_next(nullptr); - cqv = cq_verifier_create(cq); + grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> + response_generator = + grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); + grpc_arg arg = grpc_core::FakeResolverResponseGenerator::MakeChannelArg( + response_generator.get()); + grpc_channel_args args = {1, &arg}; /* create a call, channel to a non existant server */ - chan = grpc_insecure_channel_create("nonexistant:54321", nullptr, nullptr); - grpc_slice host = grpc_slice_from_static_string("nonexistant"); - call = grpc_channel_create_call(chan, nullptr, GRPC_PROPAGATE_DEFAULTS, cq, - grpc_slice_from_static_string("/Foo"), &host, - deadline, nullptr); + grpc_channel* chan = + grpc_insecure_channel_create("fake:nonexistant", &args, nullptr); + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2); + grpc_call* call = grpc_channel_create_call( + chan, nullptr, GRPC_PROPAGATE_DEFAULTS, cq, + grpc_slice_from_static_string("/Foo"), nullptr, deadline, nullptr); + grpc_op ops[6]; memset(ops, 0, sizeof(ops)); - op = ops; + grpc_op* op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; - op->flags = 0; + op->flags = wait_for_ready ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0; op->reserved = nullptr; op++; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_status_code status; + grpc_slice details; op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; op->data.recv_status_on_client.status = &status; @@ -71,11 +73,25 @@ int main(int argc, char** argv) { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(1), nullptr)); + + { + grpc_core::ExecCtx exec_ctx; + response_generator->SetFailure(); + } + /* verify that all tags get completed */ CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); - GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED); + gpr_log(GPR_INFO, "call status: %d", status); + if (wait_for_ready) { + GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED); + } else { + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + } + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&trailing_metadata_recv); grpc_completion_queue_shutdown(cq); while (grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), @@ -87,10 +103,12 @@ int main(int argc, char** argv) { grpc_channel_destroy(chan); cq_verifier_destroy(cqv); - grpc_slice_unref(details); - grpc_metadata_array_destroy(&trailing_metadata_recv); - grpc_shutdown(); +} +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + run_test(true /* wait_for_ready */); + run_test(false /* wait_for_ready */); return 0; } diff --git a/test/core/end2end/tests/authority_not_supported.cc b/test/core/end2end/tests/authority_not_supported.cc index 9c8545058c..01a95e4e10 100644 --- a/test/core/end2end/tests/authority_not_supported.cc +++ b/test/core/end2end/tests/authority_not_supported.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -155,7 +154,8 @@ static void test_with_authority_header(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); diff --git a/test/core/end2end/tests/bad_hostname.cc b/test/core/end2end/tests/bad_hostname.cc index 97ef62b5e3..b6f06a20d6 100644 --- a/test/core/end2end/tests/bad_hostname.cc +++ b/test/core/end2end/tests/bad_hostname.cc @@ -26,8 +26,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -134,7 +133,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); diff --git a/test/core/end2end/tests/bad_ping.cc b/test/core/end2end/tests/bad_ping.cc index 30a1b8de77..98d893f64d 100644 --- a/test/core/end2end/tests/bad_ping.cc +++ b/test/core/end2end/tests/bad_ping.cc @@ -23,13 +23,12 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" -#define MAX_PING_STRIKES 1 +#define MAX_PING_STRIKES 2 static void* tag(intptr_t t) { return (void*)t; } @@ -63,6 +62,7 @@ static void end_test(grpc_end2end_test_fixture* f) { grpc_completion_queue_destroy(f->shutdown_cq); } +// Send more pings than server allows to trigger server's GOAWAY. static void test_bad_ping(grpc_end2end_test_config config) { grpc_end2end_test_fixture f = config.create_fixture(nullptr, nullptr); cq_verifier* cqv = cq_verifier_create(f.cq); @@ -108,11 +108,9 @@ static void test_bad_ping(grpc_end2end_test_config config) { grpc_slice details; int was_cancelled = 2; - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -144,7 +142,8 @@ static void test_bad_ping(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -155,14 +154,15 @@ static void test_bad_ping(grpc_end2end_test_config config) { cq_verify(cqv); // Send too many pings to the server to trigger the punishment: - // Each ping will trigger a ping strike, and we need at least MAX_PING_STRIKES - // strikes to trigger the punishment. So (MAX_PING_STRIKES + 1) pings are + // The first ping will let server mark its last_recv time. Afterwards, each + // ping will trigger a ping strike, and we need at least MAX_PING_STRIKES + // strikes to trigger the punishment. So (MAX_PING_STRIKES + 2) pings are // needed here. int i; - for (i = 1; i <= MAX_PING_STRIKES + 1; i++) { + for (i = 1; i <= MAX_PING_STRIKES + 2; i++) { grpc_channel_ping(f.client, f.cq, tag(200 + i), nullptr); CQ_EXPECT_COMPLETION(cqv, tag(200 + i), 1); - if (i == MAX_PING_STRIKES + 1) { + if (i == MAX_PING_STRIKES + 2) { CQ_EXPECT_COMPLETION(cqv, tag(1), 1); } cq_verify(cqv); @@ -188,7 +188,8 @@ static void test_bad_ping(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -204,8 +205,6 @@ static void test_bad_ping(grpc_end2end_test_config config) { // the in-progress RPC should fail. GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); @@ -219,9 +218,171 @@ static void test_bad_ping(grpc_end2end_test_config config) { config.tear_down_data(&f); } +// Try sending more pings than server allows, but server should be fine because +// max_pings_without_data should limit pings sent out on wire. +static void test_pings_without_data(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f = config.create_fixture(nullptr, nullptr); + cq_verifier* cqv = cq_verifier_create(f.cq); + grpc_arg client_a[3]; + client_a[0].type = GRPC_ARG_INTEGER; + client_a[0].key = + const_cast<char*>(GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS); + client_a[0].value.integer = 10; + // Only allow MAX_PING_STRIKES pings without data (DATA/HEADERS/WINDOW_UPDATE) + // so that the transport will throttle the excess pings. + client_a[1].type = GRPC_ARG_INTEGER; + client_a[1].key = const_cast<char*>(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA); + client_a[1].value.integer = MAX_PING_STRIKES; + client_a[2].type = GRPC_ARG_INTEGER; + client_a[2].key = const_cast<char*>(GRPC_ARG_HTTP2_BDP_PROBE); + client_a[2].value.integer = 0; + grpc_arg server_a[3]; + server_a[0].type = GRPC_ARG_INTEGER; + server_a[0].key = + const_cast<char*>(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS); + server_a[0].value.integer = 300000 /* 5 minutes */; + server_a[1].type = GRPC_ARG_INTEGER; + server_a[1].key = const_cast<char*>(GRPC_ARG_HTTP2_MAX_PING_STRIKES); + server_a[1].value.integer = MAX_PING_STRIKES; + server_a[2].type = GRPC_ARG_INTEGER; + server_a[2].key = const_cast<char*>(GRPC_ARG_HTTP2_BDP_PROBE); + server_a[2].value.integer = 0; + grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a}; + grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a}; + + config.init_client(&f, &client_args); + config.init_server(&f, &server_args); + + grpc_call* c; + grpc_call* s; + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10); + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->data.send_initial_metadata.metadata = nullptr; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + // Send too many pings to the server similar to the prevous test case. + // However, since we set the MAX_PINGS_WITHOUT_DATA at the client side, only + // MAX_PING_STRIKES will actually be sent and the rpc will still succeed. + int i; + for (i = 1; i <= MAX_PING_STRIKES + 2; i++) { + grpc_channel_ping(f.client, f.cq, tag(200 + i), nullptr); + if (i <= MAX_PING_STRIKES) { + CQ_EXPECT_COMPLETION(cqv, tag(200 + i), 1); + } + cq_verify(cqv); + } + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + // Client call should return. + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead)); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1); + + // Also expect the previously blocked pings to complete with an error + CQ_EXPECT_COMPLETION(cqv, tag(200 + MAX_PING_STRIKES + 1), 0); + CQ_EXPECT_COMPLETION(cqv, tag(200 + MAX_PING_STRIKES + 2), 0); + + cq_verify(cqv); + + grpc_call_unref(s); + + // The rpc should be successful. + GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_unref(c); + cq_verifier_destroy(cqv); + end_test(&f); + config.tear_down_data(&f); +} + void bad_ping(grpc_end2end_test_config config) { GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION); test_bad_ping(config); + test_pings_without_data(config); } void bad_ping_pre_init(void) {} diff --git a/test/core/end2end/tests/binary_metadata.cc b/test/core/end2end/tests/binary_metadata.cc index 381671e331..cdf5b1eb94 100644 --- a/test/core/end2end/tests/binary_metadata.cc +++ b/test/core/end2end/tests/binary_metadata.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -137,11 +136,9 @@ static void test_request_response_with_metadata_and_payload( int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -183,7 +180,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -206,7 +204,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -247,7 +246,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -276,8 +276,6 @@ static void test_request_response_with_metadata_and_payload( "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0" "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); diff --git a/test/core/end2end/tests/call_creds.cc b/test/core/end2end/tests/call_creds.cc index e1c868232c..ead6ecb1f7 100644 --- a/test/core/end2end/tests/call_creds.cc +++ b/test/core/end2end/tests/call_creds.cc @@ -26,9 +26,9 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" static const char iam_token[] = "token"; @@ -156,11 +156,9 @@ static void request_response_with_payload_and_call_creds( cqv = cq_verifier_create(f.cq); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr); GPR_ASSERT(creds != nullptr); @@ -219,7 +217,8 @@ static void request_response_with_payload_and_call_creds( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -253,7 +252,8 @@ static void request_response_with_payload_and_call_creds( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -279,7 +279,8 @@ static void request_response_with_payload_and_call_creds( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -289,8 +290,6 @@ static void request_response_with_payload_and_call_creds( GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); @@ -393,11 +392,9 @@ static void test_request_with_server_rejecting_client_creds( f = begin_test(config, "test_request_with_server_rejecting_client_creds", 1); cqv = cq_verifier_create(f.cq); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr); @@ -443,7 +440,8 @@ static void test_request_with_server_rejecting_client_creds( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(error == GRPC_CALL_OK); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); diff --git a/test/core/end2end/tests/call_host_override.cc b/test/core/end2end/tests/call_host_override.cc new file mode 100644 index 0000000000..251dc6d045 --- /dev/null +++ b/test/core/end2end/tests/call_host_override.cc @@ -0,0 +1,230 @@ +/* + * + * 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/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "test/core/end2end/cq_verifier.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + grpc_arg fake_security_name_override = { + GRPC_ARG_STRING, + const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), + {const_cast<char*>("foo.test.google.fr:1234")}}; + grpc_channel_args* new_client_args = grpc_channel_args_copy_and_add( + client_args, &fake_security_name_override, 1); + config.init_client(&f, new_client_args); + grpc_channel_args_destroy(new_client_args); + config.init_server(&f, server_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +static void test_invoke_simple_request(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f = + begin_test(config, "test_invoke_simple_request", nullptr, nullptr); + grpc_call* c; + grpc_call* s; + cq_verifier* cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call( + f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), + get_host_override_slice("foo.test.google.fr:1234", config), deadline, + nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); + GPR_ASSERT(error == GRPC_CALL_OK); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(error == GRPC_CALL_OK); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); + GPR_ASSERT(error == GRPC_CALL_OK); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); + validate_host_override_string("foo.test.google.fr:1234", call_details.host, + config); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void call_host_override(grpc_end2end_test_config config) { + test_invoke_simple_request(config); +} + +void call_host_override_pre_init(void) {} diff --git a/test/core/end2end/tests/cancel_after_accept.cc b/test/core/end2end/tests/cancel_after_accept.cc index f59caf7e35..788d374baa 100644 --- a/test/core/end2end/tests/cancel_after_accept.cc +++ b/test/core/end2end/tests/cancel_after_accept.cc @@ -25,9 +25,9 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/service_config.h" @@ -146,11 +146,9 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, gpr_timespec deadline = use_service_config ? gpr_inf_future(GPR_CLOCK_MONOTONIC) : five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/service/method"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -187,7 +185,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = grpc_server_request_call(f.server, &s, &call_details, @@ -218,7 +217,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr)); diff --git a/test/core/end2end/tests/cancel_after_client_done.cc b/test/core/end2end/tests/cancel_after_client_done.cc index 9b832d435d..6e9378378e 100644 --- a/test/core/end2end/tests/cancel_after_client_done.cc +++ b/test/core/end2end/tests/cancel_after_client_done.cc @@ -25,7 +25,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" @@ -118,11 +119,9 @@ static void test_cancel_after_accept_and_writes_closed( int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -163,7 +162,8 @@ static void test_cancel_after_accept_and_writes_closed( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = grpc_server_request_call(f.server, &s, &call_details, @@ -194,7 +194,8 @@ static void test_cancel_after_accept_and_writes_closed( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr)); diff --git a/test/core/end2end/tests/cancel_after_invoke.cc b/test/core/end2end/tests/cancel_after_invoke.cc index d3891b160e..78009eb3bb 100644 --- a/test/core/end2end/tests/cancel_after_invoke.cc +++ b/test/core/end2end/tests/cancel_after_invoke.cc @@ -18,6 +18,7 @@ #include "test/core/end2end/end2end_tests.h" +#include <inttypes.h> #include <stdio.h> #include <string.h> @@ -25,7 +26,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" @@ -111,11 +113,9 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config, grpc_raw_byte_buffer_create(&request_payload_slice, 1); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); diff --git a/test/core/end2end/tests/cancel_after_round_trip.cc b/test/core/end2end/tests/cancel_after_round_trip.cc index b10b93978d..061b273f18 100644 --- a/test/core/end2end/tests/cancel_after_round_trip.cc +++ b/test/core/end2end/tests/cancel_after_round_trip.cc @@ -25,9 +25,9 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/service_config.h" @@ -148,11 +148,9 @@ static void test_cancel_after_round_trip(grpc_end2end_test_config config, gpr_timespec deadline = use_service_config ? gpr_inf_future(GPR_CLOCK_MONOTONIC) : five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/service/method"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -182,7 +180,8 @@ static void test_cancel_after_round_trip(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -209,7 +208,8 @@ static void test_cancel_after_round_trip(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -235,7 +235,8 @@ static void test_cancel_after_round_trip(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr)); @@ -252,7 +253,8 @@ static void test_cancel_after_round_trip(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), 1); diff --git a/test/core/end2end/tests/cancel_before_invoke.cc b/test/core/end2end/tests/cancel_before_invoke.cc index 1112375176..abb2dbc8c3 100644 --- a/test/core/end2end/tests/cancel_before_invoke.cc +++ b/test/core/end2end/tests/cancel_before_invoke.cc @@ -18,6 +18,7 @@ #include "test/core/end2end/end2end_tests.h" +#include <inttypes.h> #include <stdio.h> #include <string.h> @@ -25,7 +26,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -109,11 +109,9 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config, grpc_raw_byte_buffer_create(&request_payload_slice, 1); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); GPR_ASSERT(GRPC_CALL_OK == grpc_call_cancel(c, nullptr)); diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.cc b/test/core/end2end/tests/cancel_in_a_vacuum.cc index a6c534eb08..4672e64a4e 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.cc +++ b/test/core/end2end/tests/cancel_in_a_vacuum.cc @@ -25,7 +25,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" @@ -96,11 +97,9 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config, cq_verifier* v_client = cq_verifier_create(f.cq); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr)); diff --git a/test/core/end2end/tests/cancel_with_status.cc b/test/core/end2end/tests/cancel_with_status.cc index c867751d53..2fc9d2ff27 100644 --- a/test/core/end2end/tests/cancel_with_status.cc +++ b/test/core/end2end/tests/cancel_with_status.cc @@ -18,6 +18,7 @@ #include "test/core/end2end/end2end_tests.h" +#include <inttypes.h> #include <stdio.h> #include <string.h> @@ -27,8 +28,7 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -104,11 +104,9 @@ static void simple_request_body(grpc_end2end_test_config config, gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); diff --git a/test/core/end2end/tests/compressed_payload.cc b/test/core/end2end/tests/compressed_payload.cc index 944edc7a70..178d68c608 100644 --- a/test/core/end2end/tests/compressed_payload.cc +++ b/test/core/end2end/tests/compressed_payload.cc @@ -28,7 +28,6 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/surface/call.h" @@ -138,11 +137,9 @@ static void request_for_disabled_algorithm( cqv = cq_verifier_create(f.cq); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -188,7 +185,8 @@ static void request_for_disabled_algorithm( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(101), true); @@ -206,7 +204,8 @@ static void request_for_disabled_algorithm( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), false); @@ -217,7 +216,8 @@ static void request_for_disabled_algorithm( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), true); @@ -237,8 +237,6 @@ static void request_for_disabled_algorithm( GPR_ASSERT(0 == grpc_slice_str_cmp(details, expected_details)); gpr_free(expected_details); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); grpc_slice_unref(details); grpc_metadata_array_destroy(&initial_metadata_recv); @@ -318,11 +316,9 @@ static void request_with_payload_template( cqv = cq_verifier_create(f.cq); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -339,7 +335,8 @@ static void request_with_payload_template( op->flags = client_send_flags_bitmask; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), true); } @@ -368,7 +365,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -404,7 +402,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(101), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); for (int i = 0; i < 2; i++) { @@ -419,8 +418,8 @@ static void request_with_payload_template( op->flags = client_send_flags_bitmask; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), + tag(2), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), 1); } @@ -432,8 +431,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(102), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -451,8 +450,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(103), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -462,7 +461,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -496,7 +496,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -509,7 +510,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); @@ -521,8 +523,6 @@ static void request_with_payload_template( GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/connectivity.cc b/test/core/end2end/tests/connectivity.cc index da65080bc0..caa4265aa2 100644 --- a/test/core/end2end/tests/connectivity.cc +++ b/test/core/end2end/tests/connectivity.cc @@ -20,9 +20,9 @@ #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> +#include "src/core/lib/gprpp/thd.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -34,7 +34,7 @@ typedef struct { } child_events; static void child_thread(void* arg) { - child_events* ce = (child_events*)arg; + child_events* ce = static_cast<child_events*>(arg); grpc_event ev; gpr_event_set(&ce->started, (void*)1); gpr_log(GPR_DEBUG, "verifying"); @@ -50,8 +50,6 @@ static void test_connectivity(grpc_end2end_test_config config) { grpc_connectivity_state state; cq_verifier* cqv = cq_verifier_create(f.cq); child_events ce; - gpr_thd_options thdopt = gpr_thd_options_default(); - gpr_thd_id thdid; grpc_channel_args client_args; grpc_arg arg_array[1]; @@ -67,9 +65,8 @@ static void test_connectivity(grpc_end2end_test_config config) { ce.channel = f.client; ce.cq = f.cq; gpr_event_init(&ce.started); - gpr_thd_options_set_joinable(&thdopt); - GPR_ASSERT( - gpr_thd_new(&thdid, "grpc_connectivity", child_thread, &ce, &thdopt)); + grpc_core::Thread thd("grpc_connectivity", child_thread, &ce); + thd.Start(); gpr_event_wait(&ce.started, gpr_inf_future(GPR_CLOCK_MONOTONIC)); @@ -86,7 +83,7 @@ static void test_connectivity(grpc_end2end_test_config config) { f.client, GRPC_CHANNEL_IDLE, gpr_now(GPR_CLOCK_MONOTONIC), f.cq, tag(1)); /* eventually the child thread completion should trigger */ - gpr_thd_join(thdid); + thd.Join(); /* check that we're still in idle, and start connecting */ GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) == diff --git a/test/core/end2end/tests/default_host.cc b/test/core/end2end/tests/default_host.cc index 85f92b0ab0..22c3102d1a 100644 --- a/test/core/end2end/tests/default_host.cc +++ b/test/core/end2end/tests/default_host.cc @@ -26,8 +26,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -86,7 +85,9 @@ static void end_test(grpc_end2end_test_fixture* f) { grpc_completion_queue_destroy(f->shutdown_cq); } -static void simple_request_body(grpc_end2end_test_fixture f) { +static void test_invoke_simple_request(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f = + begin_test(config, "test_invoke_simple_request", nullptr, nullptr); grpc_call* c; grpc_call* s; cq_verifier* cqv = cq_verifier_create(f.cq); @@ -141,7 +142,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(error == GRPC_CALL_OK); error = @@ -180,7 +182,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(error == GRPC_CALL_OK); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -190,7 +193,14 @@ static void simple_request_body(grpc_end2end_test_fixture f) { GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - GPR_ASSERT(grpc_slice_buf_start_eq(call_details.host, "localhost", 9)); + + if (config.overridden_call_host != nullptr) { + validate_host_override_string(config.overridden_call_host, + call_details.host, config); + } else { + GPR_ASSERT(grpc_slice_buf_start_eq(call_details.host, "localhost", 9) || + grpc_slice_buf_start_eq(call_details.host, "127.0.0.1", 9)); + } GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); @@ -203,22 +213,12 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_call_unref(s); cq_verifier_destroy(cqv); -} - -static void test_invoke_simple_request(grpc_end2end_test_config config) { - grpc_end2end_test_fixture f; - f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr); - simple_request_body(f); end_test(&f); config.tear_down_data(&f); } void default_host(grpc_end2end_test_config config) { - if ((config.feature_mask & FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION) == 0) - return; - if ((config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION) == 0) - return; test_invoke_simple_request(config); } diff --git a/test/core/end2end/tests/disappearing_server.cc b/test/core/end2end/tests/disappearing_server.cc index 29fb19463f..fdd780f117 100644 --- a/test/core/end2end/tests/disappearing_server.cc +++ b/test/core/end2end/tests/disappearing_server.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -86,11 +85,9 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config, int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, f->cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f->cq, grpc_slice_from_static_string("/foo"), + nullptr, deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -121,7 +118,8 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -155,7 +153,8 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -166,8 +165,6 @@ static void do_request_and_shutdown_server(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/empty_batch.cc b/test/core/end2end/tests/empty_batch.cc index b249c141de..317bb7aeb0 100644 --- a/test/core/end2end/tests/empty_batch.cc +++ b/test/core/end2end/tests/empty_batch.cc @@ -26,8 +26,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -94,11 +93,9 @@ static void empty_batch_body(grpc_end2end_test_config config, grpc_op* op = nullptr; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); error = grpc_call_start_batch(c, op, 0, tag(1), nullptr); diff --git a/test/core/end2end/tests/filter_call_init_fails.cc b/test/core/end2end/tests/filter_call_init_fails.cc index 8f46f0bb91..ab96879fe4 100644 --- a/test/core/end2end/tests/filter_call_init_fails.cc +++ b/test/core/end2end/tests/filter_call_init_fails.cc @@ -27,7 +27,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/surface/channel_init.h" #include "test/core/end2end/cq_verifier.h" @@ -118,11 +117,9 @@ static void test_server_channel_filter(grpc_end2end_test_config config) { grpc_slice details; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -159,7 +156,8 @@ static void test_server_channel_filter(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -213,11 +211,9 @@ static void test_client_channel_filter(grpc_end2end_test_config config) { grpc_call_error error; grpc_slice details; - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -254,7 +250,8 @@ static void test_client_channel_filter(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); @@ -303,11 +300,9 @@ static void test_client_subchannel_filter(grpc_end2end_test_config config) { grpc_call_error error; grpc_slice details; - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -345,7 +340,8 @@ static void test_client_subchannel_filter(grpc_end2end_test_config config) { op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); @@ -362,14 +358,13 @@ static void test_client_subchannel_filter(grpc_end2end_test_config config) { grpc_slice_unref(details); details = grpc_empty_slice(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), 1); diff --git a/test/core/end2end/tests/filter_causes_close.cc b/test/core/end2end/tests/filter_causes_close.cc index ec8f9dbe00..a7f4268803 100644 --- a/test/core/end2end/tests/filter_causes_close.cc +++ b/test/core/end2end/tests/filter_causes_close.cc @@ -26,7 +26,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/surface/channel_init.h" #include "test/core/end2end/cq_verifier.h" @@ -112,11 +111,9 @@ static void test_request(grpc_end2end_test_config config) { grpc_slice details; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -153,7 +150,8 @@ static void test_request(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -198,8 +196,8 @@ typedef struct { } channel_data; static void recv_im_ready(void* arg, grpc_error* error) { - grpc_call_element* elem = (grpc_call_element*)arg; - call_data* calld = (call_data*)elem->call_data; + grpc_call_element* elem = static_cast<grpc_call_element*>(arg); + call_data* calld = static_cast<call_data*>(elem->call_data); GRPC_CLOSURE_RUN( calld->recv_im_ready, grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -210,7 +208,7 @@ static void recv_im_ready(void* arg, grpc_error* error) { static void start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* op) { - call_data* calld = (call_data*)elem->call_data; + call_data* calld = static_cast<call_data*>(elem->call_data); if (op->recv_initial_metadata) { calld->recv_im_ready = op->payload->recv_initial_metadata.recv_initial_metadata_ready; diff --git a/test/core/end2end/tests/filter_latency.cc b/test/core/end2end/tests/filter_latency.cc index 845cbc01cf..a89db7b094 100644 --- a/test/core/end2end/tests/filter_latency.cc +++ b/test/core/end2end/tests/filter_latency.cc @@ -27,7 +27,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/surface/channel_init.h" @@ -126,10 +125,9 @@ static void test_request(grpc_end2end_test_config config) { const gpr_timespec start_time = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr", config), deadline, nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -166,7 +164,8 @@ static void test_request(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -197,7 +196,8 @@ static void test_request(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -306,7 +306,7 @@ static const grpc_channel_filter test_server_filter = { */ static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) { - grpc_channel_filter* filter = (grpc_channel_filter*)arg; + grpc_channel_filter* filter = static_cast<grpc_channel_filter*>(arg); if (g_enable_filter) { // Want to add the filter as close to the end as possible, to make // sure that all of the filters work well together. However, we diff --git a/test/core/end2end/tests/filter_status_code.cc b/test/core/end2end/tests/filter_status_code.cc new file mode 100644 index 0000000000..ba3cbfa6d1 --- /dev/null +++ b/test/core/end2end/tests/filter_status_code.cc @@ -0,0 +1,378 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <limits.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/channel_init.h" +#include "test/core/end2end/cq_verifier.h" + +static bool g_enable_filter = false; +static gpr_mu g_mu; +static grpc_call_stack* g_client_call_stack; +static grpc_call_stack* g_server_call_stack; +static bool g_client_code_recv; +static bool g_server_code_recv; +static gpr_cv g_client_code_cv; +static gpr_cv g_server_code_cv; +static grpc_status_code g_client_status_code; +static grpc_status_code g_server_status_code; + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Simple request via a server filter that saves the reported status code. +static void test_request(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_end2end_test_fixture f = + begin_test(config, "filter_status_code", nullptr, nullptr); + cq_verifier* cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + + gpr_mu_lock(&g_mu); + g_client_call_stack = nullptr; + g_server_call_stack = nullptr; + g_client_status_code = GRPC_STATUS_OK; + g_server_status_code = GRPC_STATUS_OK; + gpr_mu_unlock(&g_mu); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); + GPR_ASSERT(c); + gpr_mu_lock(&g_mu); + g_client_call_stack = grpc_call_get_call_stack(c); + gpr_mu_unlock(&g_mu); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->data.send_initial_metadata.metadata = nullptr; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + gpr_mu_lock(&g_mu); + g_server_call_stack = grpc_call_get_call_stack(s); + gpr_mu_unlock(&g_mu); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + grpc_slice status_string = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_string; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_unref(s); + grpc_call_unref(c); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); + + // Perform checks after test tear-down + // Guards against the case that there's outstanding channel-related work on a + // call prior to verification + gpr_mu_lock(&g_mu); + if (!g_client_code_recv) { + GPR_ASSERT(gpr_cv_wait(&g_client_code_cv, &g_mu, + grpc_timeout_seconds_to_deadline(3)) == 0); + } + if (!g_server_code_recv) { + GPR_ASSERT(gpr_cv_wait(&g_server_code_cv, &g_mu, + grpc_timeout_seconds_to_deadline(3)) == 0); + } + GPR_ASSERT(g_client_status_code == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(g_server_status_code == GRPC_STATUS_UNIMPLEMENTED); + gpr_mu_unlock(&g_mu); +} + +/******************************************************************************* + * Test status_code filter + */ + +typedef struct final_status_data { + grpc_call_stack* call; +} final_status_data; + +static grpc_error* init_call_elem(grpc_call_element* elem, + const grpc_call_element_args* args) { + final_status_data* data = static_cast<final_status_data*>(elem->call_data); + data->call = args->call_stack; + return GRPC_ERROR_NONE; +} + +static void client_destroy_call_elem(grpc_call_element* elem, + const grpc_call_final_info* final_info, + grpc_closure* ignored) { + final_status_data* data = static_cast<final_status_data*>(elem->call_data); + gpr_mu_lock(&g_mu); + // Some fixtures, like proxies, will spawn intermidiate calls + // We only want the results from our explicit calls + if (data->call == g_client_call_stack) { + g_client_status_code = final_info->final_status; + g_client_code_recv = true; + gpr_cv_signal(&g_client_code_cv); + } + gpr_mu_unlock(&g_mu); +} + +static void server_destroy_call_elem(grpc_call_element* elem, + const grpc_call_final_info* final_info, + grpc_closure* ignored) { + final_status_data* data = static_cast<final_status_data*>(elem->call_data); + gpr_mu_lock(&g_mu); + // Some fixtures, like proxies, will spawn intermidiate calls + // We only want the results from our explicit calls + if (data->call == g_server_call_stack) { + g_server_status_code = final_info->final_status; + g_server_code_recv = true; + gpr_cv_signal(&g_server_code_cv); + } + gpr_mu_unlock(&g_mu); +} + +static grpc_error* init_channel_elem(grpc_channel_element* elem, + grpc_channel_element_args* args) { + return GRPC_ERROR_NONE; +} + +static void destroy_channel_elem(grpc_channel_element* elem) {} + +static const grpc_channel_filter test_client_filter = { + grpc_call_next_op, + grpc_channel_next_op, + sizeof(final_status_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset_or_pollset_set, + client_destroy_call_elem, + 0, + init_channel_elem, + destroy_channel_elem, + grpc_channel_next_get_info, + "client_filter_status_code"}; + +static const grpc_channel_filter test_server_filter = { + grpc_call_next_op, + grpc_channel_next_op, + sizeof(final_status_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset_or_pollset_set, + server_destroy_call_elem, + 0, + init_channel_elem, + destroy_channel_elem, + grpc_channel_next_get_info, + "server_filter_status_code"}; + +/******************************************************************************* + * Registration + */ + +static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) { + grpc_channel_filter* filter = static_cast<grpc_channel_filter*>(arg); + if (g_enable_filter) { + // Want to add the filter as close to the end as possible, to make + // sure that all of the filters work well together. However, we + // can't add it at the very end, because the + // connected_channel/client_channel filter must be the last one. + // So we add it right before the last one. + grpc_channel_stack_builder_iterator* it = + grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); + const bool retval = grpc_channel_stack_builder_add_filter_before( + it, filter, nullptr, nullptr); + grpc_channel_stack_builder_iterator_destroy(it); + return retval; + } else { + return true; + } +} + +static void init_plugin(void) { + gpr_mu_init(&g_mu); + gpr_cv_init(&g_client_code_cv); + gpr_cv_init(&g_server_code_cv); + g_client_code_recv = false; + g_server_code_recv = false; + + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_client_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_client_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_server_filter); +} + +static void destroy_plugin(void) { + gpr_cv_destroy(&g_client_code_cv); + gpr_cv_destroy(&g_server_code_cv); + gpr_mu_destroy(&g_mu); +} + +void filter_status_code(grpc_end2end_test_config config) { + g_enable_filter = true; + test_request(config); + g_enable_filter = false; +} + +void filter_status_code_pre_init(void) { + grpc_register_plugin(init_plugin, destroy_plugin); +} diff --git a/test/core/end2end/tests/graceful_server_shutdown.cc b/test/core/end2end/tests/graceful_server_shutdown.cc index bf11b49fa4..42f2d1a414 100644 --- a/test/core/end2end/tests/graceful_server_shutdown.cc +++ b/test/core/end2end/tests/graceful_server_shutdown.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -100,11 +99,9 @@ static void test_early_server_shutdown_finishes_inflight_calls( int was_cancelled = 2; gpr_timespec deadline = n_seconds_from_now(10); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -136,7 +133,8 @@ static void test_early_server_shutdown_finishes_inflight_calls( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -170,7 +168,8 @@ static void test_early_server_shutdown_finishes_inflight_calls( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -182,8 +181,6 @@ static void test_early_server_shutdown_finishes_inflight_calls( GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/high_initial_seqno.cc b/test/core/end2end/tests/high_initial_seqno.cc index d390a954e5..18e6ee90ef 100644 --- a/test/core/end2end/tests/high_initial_seqno.cc +++ b/test/core/end2end/tests/high_initial_seqno.cc @@ -27,9 +27,8 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -105,11 +104,9 @@ static void simple_request_body(grpc_end2end_test_config config, int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -140,7 +137,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -170,7 +168,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -180,8 +179,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/hpack_size.cc b/test/core/end2end/tests/hpack_size.cc index 7ac5fefa22..7c51294e1c 100644 --- a/test/core/end2end/tests/hpack_size.cc +++ b/test/core/end2end/tests/hpack_size.cc @@ -27,9 +27,9 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -257,11 +257,9 @@ static void simple_request_body(grpc_end2end_test_config config, grpc_slice_from_static_string(dragons[index % GPR_ARRAY_SIZE(dragons)]); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -293,7 +291,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -323,7 +322,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -333,8 +333,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/idempotent_request.cc b/test/core/end2end/tests/idempotent_request.cc index e39975382a..80908d5210 100644 --- a/test/core/end2end/tests/idempotent_request.cc +++ b/test/core/end2end/tests/idempotent_request.cc @@ -26,8 +26,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" + +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -104,11 +104,9 @@ static void simple_request_body(grpc_end2end_test_config config, char* peer; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); peer = grpc_call_get_peer(c); @@ -144,7 +142,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -183,7 +182,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -193,8 +193,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST == call_details.flags); GPR_ASSERT(was_cancelled == 1); diff --git a/test/core/end2end/tests/invoke_large_request.cc b/test/core/end2end/tests/invoke_large_request.cc index 8a67e3c2b1..39d90ab64d 100644 --- a/test/core/end2end/tests/invoke_large_request.cc +++ b/test/core/end2end/tests/invoke_large_request.cc @@ -26,7 +26,8 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -130,11 +131,9 @@ static void test_invoke_large_request(grpc_end2end_test_config config, int was_cancelled = 2; gpr_timespec deadline = n_seconds_from_now(30); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -175,7 +174,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -197,7 +197,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -223,7 +224,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -233,8 +235,6 @@ static void test_invoke_large_request(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 822565510f..1ee5285027 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -25,11 +25,12 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + #include "src/core/ext/transport/chttp2/transport/frame_ping.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/support/env.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -101,7 +102,7 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { grpc_arg keepalive_arg_elems[3]; keepalive_arg_elems[0].type = GRPC_ARG_INTEGER; keepalive_arg_elems[0].key = const_cast<char*>(GRPC_ARG_KEEPALIVE_TIME_MS); - keepalive_arg_elems[0].value.integer = 1500; + keepalive_arg_elems[0].value.integer = 3500; keepalive_arg_elems[1].type = GRPC_ARG_INTEGER; keepalive_arg_elems[1].key = const_cast<char*>(GRPC_ARG_KEEPALIVE_TIMEOUT_MS); keepalive_arg_elems[1].value.integer = 0; @@ -129,11 +130,9 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { grpc_set_disable_ping_ack(true); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -154,7 +153,8 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message.recv_message = &response_payload_recv; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -171,7 +171,8 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message.send_message = response_payload; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -185,7 +186,8 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { op->data.recv_status_on_client.status = &status; op->data.recv_status_on_client.status_details = &details; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(3), 1); @@ -196,8 +198,6 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_INTERNAL); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "keepalive watchdog timeout")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); gpr_free(details_str); gpr_free(method_str); diff --git a/test/core/end2end/tests/large_metadata.cc b/test/core/end2end/tests/large_metadata.cc index 8ddf433ac0..c7f72a1cab 100644 --- a/test/core/end2end/tests/large_metadata.cc +++ b/test/core/end2end/tests/large_metadata.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -97,7 +96,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { grpc_arg arg; arg.type = GRPC_ARG_INTEGER; arg.key = const_cast<char*>(GRPC_ARG_MAX_METADATA_SIZE); - arg.value.integer = (int)large_size + 1024; + arg.value.integer = static_cast<int>(large_size) + 1024; grpc_channel_args args = {1, &arg}; grpc_end2end_test_fixture f = begin_test(config, "test_request_with_large_metadata", &args, &args); @@ -115,11 +114,9 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); meta.key = grpc_slice_from_static_string("key"); @@ -161,7 +158,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -185,7 +183,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -208,7 +207,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -218,8 +218,6 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(contains_metadata_slices(&request_metadata_recv, diff --git a/test/core/end2end/tests/load_reporting_hook.cc b/test/core/end2end/tests/load_reporting_hook.cc index e056bd547b..4324e9dfc1 100644 --- a/test/core/end2end/tests/load_reporting_hook.cc +++ b/test/core/end2end/tests/load_reporting_hook.cc @@ -24,7 +24,6 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/ext/filters/load_reporting/server_load_reporting_filter.h" #include "src/core/ext/filters/load_reporting/server_load_reporting_plugin.h" @@ -139,11 +138,9 @@ static void request_response_with_payload( int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string(method_name), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string(method_name), + nullptr, deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -186,7 +183,8 @@ static void request_response_with_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -208,7 +206,8 @@ static void request_response_with_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -236,7 +235,8 @@ static void request_response_with_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); diff --git a/test/core/end2end/tests/max_concurrent_streams.cc b/test/core/end2end/tests/max_concurrent_streams.cc index c0539739e1..86a8d22443 100644 --- a/test/core/end2end/tests/max_concurrent_streams.cc +++ b/test/core/end2end/tests/max_concurrent_streams.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -101,11 +100,9 @@ static void simple_request_body(grpc_end2end_test_config config, int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -136,7 +133,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -166,7 +164,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -176,8 +175,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); @@ -247,17 +244,13 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { /* start two requests - ensuring that the second is not accepted until the first completes */ deadline = n_seconds_from_now(1000); - c1 = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/alpha"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c1 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f.cq, grpc_slice_from_static_string("/alpha"), + nullptr, deadline, nullptr); GPR_ASSERT(c1); - c2 = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/beta"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c2 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f.cq, grpc_slice_from_static_string("/beta"), + nullptr, deadline, nullptr); GPR_ASSERT(c2); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -275,7 +268,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(301), nullptr); + error = grpc_call_start_batch(c1, ops, static_cast<size_t>(op - ops), + tag(301), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -293,7 +287,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(302), nullptr); + error = grpc_call_start_batch(c1, ops, static_cast<size_t>(op - ops), + tag(302), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -307,7 +302,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(401), nullptr); + error = grpc_call_start_batch(c2, ops, static_cast<size_t>(op - ops), + tag(401), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -325,7 +321,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(402), nullptr); + error = grpc_call_start_batch(c2, ops, static_cast<size_t>(op - ops), + tag(402), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); got_client_start = 0; @@ -346,7 +343,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { * both); * check this here */ /* We'll get tag 303 or 403, we want 300, 400 */ - live_call = ((int)(intptr_t)ev.tag) - 1; + live_call = (static_cast<int>((intptr_t)ev.tag)) - 1; got_client_start = 1; } } @@ -372,7 +369,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s1, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s1, ops, static_cast<size_t>(op - ops), + tag(102), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -409,7 +407,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s2, ops, (size_t)(op - ops), tag(202), nullptr); + error = grpc_call_start_batch(s2, ops, static_cast<size_t>(op - ops), + tag(202), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(live_call + 2), 1); @@ -487,17 +486,13 @@ static void test_max_concurrent_streams_with_timeout_on_first( /* start two requests - ensuring that the second is not accepted until the first completes */ - c1 = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/alpha"), - get_host_override_slice("foo.test.google.fr:1234", config), - n_seconds_from_now(3), nullptr); + c1 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f.cq, grpc_slice_from_static_string("/alpha"), + nullptr, n_seconds_from_now(3), nullptr); GPR_ASSERT(c1); - c2 = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/beta"), - get_host_override_slice("foo.test.google.fr:1234", config), - n_seconds_from_now(1000), nullptr); + c2 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f.cq, grpc_slice_from_static_string("/beta"), + nullptr, n_seconds_from_now(1000), nullptr); GPR_ASSERT(c2); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -515,7 +510,8 @@ static void test_max_concurrent_streams_with_timeout_on_first( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(301), nullptr); + error = grpc_call_start_batch(c1, ops, static_cast<size_t>(op - ops), + tag(301), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -533,7 +529,8 @@ static void test_max_concurrent_streams_with_timeout_on_first( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(302), nullptr); + error = grpc_call_start_batch(c1, ops, static_cast<size_t>(op - ops), + tag(302), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(101), 1); @@ -551,7 +548,8 @@ static void test_max_concurrent_streams_with_timeout_on_first( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(401), nullptr); + error = grpc_call_start_batch(c2, ops, static_cast<size_t>(op - ops), + tag(401), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -569,7 +567,8 @@ static void test_max_concurrent_streams_with_timeout_on_first( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(402), nullptr); + error = grpc_call_start_batch(c2, ops, static_cast<size_t>(op - ops), + tag(402), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); grpc_call_details_destroy(&call_details); @@ -604,7 +603,8 @@ static void test_max_concurrent_streams_with_timeout_on_first( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s2, ops, (size_t)(op - ops), tag(202), nullptr); + error = grpc_call_start_batch(s2, ops, static_cast<size_t>(op - ops), + tag(202), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(402), 1); @@ -682,17 +682,13 @@ static void test_max_concurrent_streams_with_timeout_on_second( /* start two requests - ensuring that the second is not accepted until the first completes , and the second request will timeout in the concurrent_list */ - c1 = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/alpha"), - get_host_override_slice("foo.test.google.fr:1234", config), - n_seconds_from_now(1000), nullptr); + c1 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f.cq, grpc_slice_from_static_string("/alpha"), + nullptr, n_seconds_from_now(1000), nullptr); GPR_ASSERT(c1); - c2 = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/beta"), - get_host_override_slice("foo.test.google.fr:1234", config), - n_seconds_from_now(3), nullptr); + c2 = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f.cq, grpc_slice_from_static_string("/beta"), + nullptr, n_seconds_from_now(3), nullptr); GPR_ASSERT(c2); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -710,7 +706,8 @@ static void test_max_concurrent_streams_with_timeout_on_second( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(301), nullptr); + error = grpc_call_start_batch(c1, ops, static_cast<size_t>(op - ops), + tag(301), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -728,7 +725,8 @@ static void test_max_concurrent_streams_with_timeout_on_second( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(302), nullptr); + error = grpc_call_start_batch(c1, ops, static_cast<size_t>(op - ops), + tag(302), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(101), 1); @@ -746,7 +744,8 @@ static void test_max_concurrent_streams_with_timeout_on_second( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(401), nullptr); + error = grpc_call_start_batch(c2, ops, static_cast<size_t>(op - ops), + tag(401), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -764,7 +763,8 @@ static void test_max_concurrent_streams_with_timeout_on_second( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(402), nullptr); + error = grpc_call_start_batch(c2, ops, static_cast<size_t>(op - ops), + tag(402), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); /* the second request is time out*/ @@ -797,7 +797,8 @@ static void test_max_concurrent_streams_with_timeout_on_second( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s1, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s1, ops, static_cast<size_t>(op - ops), + tag(102), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(302), 1); diff --git a/test/core/end2end/tests/max_connection_age.cc b/test/core/end2end/tests/max_connection_age.cc index ddccfc3b51..fcb0aaffc4 100644 --- a/test/core/end2end/tests/max_connection_age.cc +++ b/test/core/end2end/tests/max_connection_age.cc @@ -24,8 +24,8 @@ #include <grpc/support/log.h> #include <grpc/support/sync.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" #define MAX_CONNECTION_AGE_MS 500 @@ -109,11 +109,9 @@ static void test_max_age_forcibly_close(grpc_end2end_test_config config) { grpc_slice details; int was_cancelled = 2; - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -145,7 +143,8 @@ static void test_max_age_forcibly_close(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -156,7 +155,8 @@ static void test_max_age_forcibly_close(grpc_end2end_test_config config) { cq_verify(cqv); gpr_timespec expect_shutdown_time = grpc_timeout_milliseconds_to_deadline( - (int)(MAX_CONNECTION_AGE_MS * MAX_CONNECTION_AGE_JITTER_MULTIPLIER) + + static_cast<int>(MAX_CONNECTION_AGE_MS * + MAX_CONNECTION_AGE_JITTER_MULTIPLIER) + MAX_CONNECTION_AGE_GRACE_MS + IMMEDIATE_SHUTDOWN_GRACE_TIME_MS); /* Wait for the channel to reach its max age */ @@ -190,7 +190,8 @@ static void test_max_age_forcibly_close(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), true); cq_verify(cqv); @@ -205,8 +206,6 @@ static void test_max_age_forcibly_close(grpc_end2end_test_config config) { the in-progress RPC should fail. */ GPR_ASSERT(status == GRPC_STATUS_INTERNAL); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); @@ -252,11 +251,9 @@ static void test_max_age_gracefully_close(grpc_end2end_test_config config) { grpc_slice details; int was_cancelled = 2; - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -288,7 +285,8 @@ static void test_max_age_gracefully_close(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -325,7 +323,8 @@ static void test_max_age_gracefully_close(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), true); @@ -343,8 +342,6 @@ static void test_max_age_gracefully_close(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/max_connection_idle.cc b/test/core/end2end/tests/max_connection_idle.cc index 293ff7d1f2..faa1383207 100644 --- a/test/core/end2end/tests/max_connection_idle.cc +++ b/test/core/end2end/tests/max_connection_idle.cc @@ -25,8 +25,8 @@ #include <grpc/support/log.h> #include <grpc/support/sync.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" #define MAX_CONNECTION_IDLE_MS 500 @@ -60,11 +60,9 @@ static void simple_request_body(grpc_end2end_test_config config, char* peer; gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5); - c = grpc_channel_create_call( - f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, f->cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f->cq, grpc_slice_from_static_string("/foo"), + nullptr, deadline, nullptr); GPR_ASSERT(c); peer = grpc_call_get_peer(c); @@ -100,7 +98,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -139,7 +138,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -149,8 +149,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(0 == call_details.flags); GPR_ASSERT(was_cancelled == 1); diff --git a/test/core/end2end/tests/max_message_length.cc b/test/core/end2end/tests/max_message_length.cc index e581f1fc20..6ac941e0da 100644 --- a/test/core/end2end/tests/max_message_length.cc +++ b/test/core/end2end/tests/max_message_length.cc @@ -25,9 +25,9 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/service_config.h" @@ -180,11 +180,10 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config, cqv = cq_verifier_create(f.cq); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/service/method"), - get_host_override_slice("foo.test.google.fr:1234", config), - gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, gpr_inf_future(GPR_CLOCK_REALTIME), + nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -220,7 +219,8 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); if (send_limit) { @@ -248,7 +248,8 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -256,8 +257,6 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config, cq_verify(cqv); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); done: @@ -369,11 +368,10 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config, } cqv = cq_verifier_create(f.cq); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/service/method"), - get_host_override_slice("foo.test.google.fr:1234", config), - gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, gpr_inf_future(GPR_CLOCK_REALTIME), + nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -409,7 +407,8 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -444,7 +443,8 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -452,9 +452,6 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config, cq_verify(cqv); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); - GPR_ASSERT(0 == - grpc_slice_str_cmp(call_details.host, "foo.test.google.fr:1234")); - GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED); GPR_ASSERT( grpc_slice_str_cmp( diff --git a/test/core/end2end/tests/negative_deadline.cc b/test/core/end2end/tests/negative_deadline.cc index b793964b48..2b2ff126c4 100644 --- a/test/core/end2end/tests/negative_deadline.cc +++ b/test/core/end2end/tests/negative_deadline.cc @@ -18,6 +18,7 @@ #include "test/core/end2end/end2end_tests.h" +#include <inttypes.h> #include <stdio.h> #include <string.h> @@ -26,8 +27,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -101,11 +101,9 @@ static void simple_request_body(grpc_end2end_test_config config, gpr_log(GPR_DEBUG, "test with %" PRIuPTR " ops", num_ops); gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_REALTIME); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); diff --git a/test/core/end2end/tests/network_status_change.cc b/test/core/end2end/tests/network_status_change.cc index 7d0318fda6..98a9558204 100644 --- a/test/core/end2end/tests/network_status_change.cc +++ b/test/core/end2end/tests/network_status_change.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" /* this is a private API but exposed here for testing*/ @@ -111,11 +110,9 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -151,7 +148,8 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -171,7 +169,8 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -194,7 +193,8 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -207,8 +207,6 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); grpc_slice_unref(details); grpc_metadata_array_destroy(&initial_metadata_recv); diff --git a/test/core/end2end/tests/no_logging.cc b/test/core/end2end/tests/no_logging.cc index bf8651221a..c8154023b8 100644 --- a/test/core/end2end/tests/no_logging.cc +++ b/test/core/end2end/tests/no_logging.cc @@ -27,9 +27,8 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/error.h" -#include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -132,11 +131,9 @@ static void simple_request_body(grpc_end2end_test_config config, char* peer; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); peer = grpc_call_get_peer(c); @@ -171,7 +168,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -208,7 +206,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -218,8 +217,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(0 == call_details.flags); GPR_ASSERT(was_cancelled == 1); diff --git a/test/core/end2end/tests/no_op.cc b/test/core/end2end/tests/no_op.cc index 18c2367ac4..020f842219 100644 --- a/test/core/end2end/tests/no_op.cc +++ b/test/core/end2end/tests/no_op.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } diff --git a/test/core/end2end/tests/payload.cc b/test/core/end2end/tests/payload.cc index 2e9513b9cb..cb6eb47de9 100644 --- a/test/core/end2end/tests/payload.cc +++ b/test/core/end2end/tests/payload.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -91,9 +90,9 @@ static grpc_slice generate_random_slice() { static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; char* output; const size_t output_size = 1024 * 1024; - output = (char*)gpr_malloc(output_size); + output = static_cast<char*>(gpr_malloc(output_size)); for (i = 0; i < output_size - 1; ++i) { - output[i] = chars[rand() % (int)(sizeof(chars) - 1)]; + output[i] = chars[rand() % static_cast<int>(sizeof(chars) - 1)]; } output[output_size - 1] = '\0'; grpc_slice out = grpc_slice_from_copied_string(output); @@ -130,11 +129,9 @@ static void request_response_with_payload(grpc_end2end_test_config config, int was_cancelled = 2; gpr_timespec deadline = n_seconds_from_now(60); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -175,7 +172,8 @@ static void request_response_with_payload(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -197,7 +195,8 @@ static void request_response_with_payload(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -223,7 +222,8 @@ static void request_response_with_payload(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -233,8 +233,6 @@ static void request_response_with_payload(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); GPR_ASSERT( diff --git a/test/core/end2end/tests/ping.cc b/test/core/end2end/tests/ping.cc index 725a425fbf..f523cbb0c7 100644 --- a/test/core/end2end/tests/ping.cc +++ b/test/core/end2end/tests/ping.cc @@ -20,10 +20,9 @@ #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "test/core/end2end/cq_verifier.h" #define PING_NUM 5 diff --git a/test/core/end2end/tests/ping_pong_streaming.cc b/test/core/end2end/tests/ping_pong_streaming.cc index ec7981fdcb..30ee0bf8b8 100644 --- a/test/core/end2end/tests/ping_pong_streaming.cc +++ b/test/core/end2end/tests/ping_pong_streaming.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -113,11 +112,9 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, grpc_slice_from_copied_string("hello you"); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -144,7 +141,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -166,7 +164,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(101), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); for (i = 0; i < messages; i++) { @@ -185,7 +184,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -195,8 +195,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(102), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); @@ -208,8 +208,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(103), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); CQ_EXPECT_COMPLETION(cqv, tag(2), 1); @@ -230,7 +230,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -243,7 +244,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); diff --git a/test/core/end2end/tests/proxy_auth.cc b/test/core/end2end/tests/proxy_auth.cc index e4b91ab879..3b12869d2f 100644 --- a/test/core/end2end/tests/proxy_auth.cc +++ b/test/core/end2end/tests/proxy_auth.cc @@ -31,8 +31,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -109,11 +108,9 @@ static void simple_request_body(grpc_end2end_test_config config, char* peer; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); peer = grpc_call_get_peer(c); @@ -149,7 +146,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -188,7 +186,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -198,8 +197,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(0 == call_details.flags); GPR_ASSERT(was_cancelled == 1); diff --git a/test/core/end2end/tests/registered_call.cc b/test/core/end2end/tests/registered_call.cc index 440d817cf1..3e05fd1421 100644 --- a/test/core/end2end/tests/registered_call.cc +++ b/test/core/end2end/tests/registered_call.cc @@ -26,8 +26,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" + +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -135,7 +135,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -165,7 +166,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -175,8 +177,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); @@ -194,9 +194,7 @@ static void simple_request_body(grpc_end2end_test_config config, static void test_invoke_simple_request(grpc_end2end_test_config config) { grpc_end2end_test_fixture f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr); - void* rc = grpc_channel_register_call( - f.client, "/foo", - get_host_override_string("foo.test.google.fr:1234", config), nullptr); + void* rc = grpc_channel_register_call(f.client, "/foo", nullptr, nullptr); simple_request_body(config, f, rc); end_test(&f); @@ -207,9 +205,7 @@ static void test_invoke_10_simple_requests(grpc_end2end_test_config config) { int i; grpc_end2end_test_fixture f = begin_test(config, "test_invoke_10_simple_requests", nullptr, nullptr); - void* rc = grpc_channel_register_call( - f.client, "/foo", - get_host_override_string("foo.test.google.fr:1234", config), nullptr); + void* rc = grpc_channel_register_call(f.client, "/foo", nullptr, nullptr); for (i = 0; i < 10; i++) { simple_request_body(config, f, rc); diff --git a/test/core/end2end/tests/request_with_flags.cc b/test/core/end2end/tests/request_with_flags.cc index 984d8b10f1..f3baf3790f 100644 --- a/test/core/end2end/tests/request_with_flags.cc +++ b/test/core/end2end/tests/request_with_flags.cc @@ -25,7 +25,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/transport/byte_stream.h" #include "test/core/end2end/cq_verifier.h" @@ -47,14 +48,12 @@ static gpr_timespec n_seconds_from_now(int n) { return grpc_timeout_seconds_to_deadline(n); } -static gpr_timespec five_seconds_from_now(void) { - return n_seconds_from_now(5); -} +static gpr_timespec one_second_from_now(void) { return n_seconds_from_now(1); } static void drain_cq(grpc_completion_queue* cq) { grpc_event ev; do { - ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + ev = grpc_completion_queue_next(cq, one_second_from_now(), nullptr); } while (ev.type != GRPC_QUEUE_SHUTDOWN); } @@ -108,12 +107,10 @@ static void test_invoke_request_with_flags( grpc_slice details; grpc_call_error expectation; - gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + gpr_timespec deadline = one_second_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -150,7 +147,8 @@ static void test_invoke_request_with_flags( op->reserved = nullptr; op++; expectation = call_start_batch_expected_result; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(expectation == error); if (expectation == GRPC_CALL_OK) { diff --git a/test/core/end2end/tests/request_with_payload.cc b/test/core/end2end/tests/request_with_payload.cc index b3b9ee5726..37d9481f28 100644 --- a/test/core/end2end/tests/request_with_payload.cc +++ b/test/core/end2end/tests/request_with_payload.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -108,11 +107,9 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -148,7 +145,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -169,7 +167,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -190,7 +189,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -200,8 +200,6 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); diff --git a/test/core/end2end/tests/resource_quota_server.cc b/test/core/end2end/tests/resource_quota_server.cc index 0ee014f97d..df83caa662 100644 --- a/test/core/end2end/tests/resource_quota_server.cc +++ b/test/core/end2end/tests/resource_quota_server.cc @@ -25,7 +25,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -91,9 +91,9 @@ static grpc_slice generate_random_slice() { static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; char* output; const size_t output_size = 1024 * 1024; - output = (char*)gpr_malloc(output_size); + output = static_cast<char*>(gpr_malloc(output_size)); for (i = 0; i < output_size - 1; ++i) { - output[i] = chars[rand() % (int)(sizeof(chars) - 1)]; + output[i] = chars[rand() % static_cast<int>(sizeof(chars) - 1)]; } output[output_size - 1] = '\0'; grpc_slice out = grpc_slice_from_copied_string(output); @@ -132,25 +132,29 @@ void resource_quota_server(grpc_end2end_test_config config) { grpc_slice request_payload_slice = generate_random_slice(); grpc_call** client_calls = - (grpc_call**)malloc(sizeof(grpc_call*) * NUM_CALLS); + static_cast<grpc_call**>(malloc(sizeof(grpc_call*) * NUM_CALLS)); grpc_call** server_calls = - (grpc_call**)malloc(sizeof(grpc_call*) * NUM_CALLS); + static_cast<grpc_call**>(malloc(sizeof(grpc_call*) * NUM_CALLS)); grpc_metadata_array* initial_metadata_recv = - (grpc_metadata_array*)malloc(sizeof(grpc_metadata_array) * NUM_CALLS); + static_cast<grpc_metadata_array*>( + malloc(sizeof(grpc_metadata_array) * NUM_CALLS)); grpc_metadata_array* trailing_metadata_recv = - (grpc_metadata_array*)malloc(sizeof(grpc_metadata_array) * NUM_CALLS); + static_cast<grpc_metadata_array*>( + malloc(sizeof(grpc_metadata_array) * NUM_CALLS)); grpc_metadata_array* request_metadata_recv = - (grpc_metadata_array*)malloc(sizeof(grpc_metadata_array) * NUM_CALLS); - grpc_call_details* call_details = - (grpc_call_details*)malloc(sizeof(grpc_call_details) * NUM_CALLS); - grpc_status_code* status = - (grpc_status_code*)malloc(sizeof(grpc_status_code) * NUM_CALLS); - grpc_slice* details = (grpc_slice*)malloc(sizeof(grpc_slice) * NUM_CALLS); - grpc_byte_buffer** request_payload = - (grpc_byte_buffer**)malloc(sizeof(grpc_byte_buffer*) * NUM_CALLS); - grpc_byte_buffer** request_payload_recv = - (grpc_byte_buffer**)malloc(sizeof(grpc_byte_buffer*) * NUM_CALLS); - int* was_cancelled = (int*)malloc(sizeof(int) * NUM_CALLS); + static_cast<grpc_metadata_array*>( + malloc(sizeof(grpc_metadata_array) * NUM_CALLS)); + grpc_call_details* call_details = static_cast<grpc_call_details*>( + malloc(sizeof(grpc_call_details) * NUM_CALLS)); + grpc_status_code* status = static_cast<grpc_status_code*>( + malloc(sizeof(grpc_status_code) * NUM_CALLS)); + grpc_slice* details = + static_cast<grpc_slice*>(malloc(sizeof(grpc_slice) * NUM_CALLS)); + grpc_byte_buffer** request_payload = static_cast<grpc_byte_buffer**>( + malloc(sizeof(grpc_byte_buffer*) * NUM_CALLS)); + grpc_byte_buffer** request_payload_recv = static_cast<grpc_byte_buffer**>( + malloc(sizeof(grpc_byte_buffer*) * NUM_CALLS)); + int* was_cancelled = static_cast<int*>(malloc(sizeof(int) * NUM_CALLS)); grpc_call_error error; int pending_client_calls = 0; int pending_server_start_calls = 0; @@ -184,11 +188,10 @@ void resource_quota_server(grpc_end2end_test_config config) { } for (int i = 0; i < NUM_CALLS; i++) { - client_calls[i] = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr", config), - n_seconds_from_now(60), nullptr); + client_calls[i] = + grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f.cq, grpc_slice_from_static_string("/foo"), + nullptr, n_seconds_from_now(60), nullptr); memset(ops, 0, sizeof(ops)); op = ops; @@ -220,7 +223,8 @@ void resource_quota_server(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(client_calls[i], ops, (size_t)(op - ops), + error = grpc_call_start_batch(client_calls[i], ops, + static_cast<size_t>(op - ops), tag(CLIENT_BASE_TAG + i), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); @@ -234,7 +238,7 @@ void resource_quota_server(grpc_end2end_test_config config) { grpc_completion_queue_next(f.cq, n_seconds_from_now(60), nullptr); GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); - int ev_tag = (int)(intptr_t)ev.tag; + int ev_tag = static_cast<int>((intptr_t)ev.tag); if (ev_tag < CLIENT_BASE_TAG) { abort(); /* illegal tag */ } else if (ev_tag < SERVER_START_BASE_TAG) { @@ -285,9 +289,9 @@ void resource_quota_server(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(server_calls[call_id], ops, (size_t)(op - ops), - tag(SERVER_RECV_BASE_TAG + call_id), nullptr); + error = grpc_call_start_batch( + server_calls[call_id], ops, static_cast<size_t>(op - ops), + tag(SERVER_RECV_BASE_TAG + call_id), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(pending_server_start_calls > 0); @@ -326,9 +330,9 @@ void resource_quota_server(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(server_calls[call_id], ops, (size_t)(op - ops), - tag(SERVER_END_BASE_TAG + call_id), nullptr); + error = grpc_call_start_batch( + server_calls[call_id], ops, static_cast<size_t>(op - ops), + tag(SERVER_END_BASE_TAG + call_id), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(pending_server_recv_calls > 0); diff --git a/test/core/end2end/tests/retry.cc b/test/core/end2end/tests/retry.cc new file mode 100644 index 0000000000..243dedc62c --- /dev/null +++ b/test/core/end2end/tests/retry.cc @@ -0,0 +1,321 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests a basic retry scenario: +// - 2 retries allowed for ABORTED status +// - first attempt returns ABORTED +// - second attempt returns OK +static void test_retry(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + // Make sure the "grpc-previous-rpc-attempts" header was not sent in the + // initial attempt. + for (size_t i = 0; i < request_metadata_recv.count; ++i) { + GPR_ASSERT(!grpc_slice_eq(request_metadata_recv.metadata[i].key, + GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS)); + } + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + grpc_call_unref(s); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_details_init(&call_details); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(201)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(201), true); + cq_verify(cqv); + + // Make sure the "grpc-previous-rpc-attempts" header was sent in the retry. + bool found_retry_header = false; + for (size_t i = 0; i < request_metadata_recv.count; ++i) { + if (grpc_slice_eq(request_metadata_recv.metadata[i].key, + GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS)) { + GPR_ASSERT( + grpc_slice_eq(request_metadata_recv.metadata[i].value, GRPC_MDSTR_1)); + found_retry_header = true; + break; + } + } + GPR_ASSERT(found_retry_header); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(202), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 0); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry(config); +} + +void retry_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_cancellation.cc b/test/core/end2end/tests/retry_cancellation.cc new file mode 100644 index 0000000000..e764fe70a6 --- /dev/null +++ b/test/core/end2end/tests/retry_cancellation.cc @@ -0,0 +1,275 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests retry cancellation. +static void test_retry_cancellation(grpc_end2end_test_config config, + cancellation_mode mode) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " },\n" + " \"timeout\": \"5s\"\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + char* name; + gpr_asprintf(&name, "retry_cancellation/%s", mode.name); + grpc_end2end_test_fixture f = begin_test(config, name, &client_args, nullptr); + gpr_free(name); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + // Client starts a batch with all 6 ops. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + // Server gets a call and fails with retryable status. + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + grpc_call_unref(s); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_details_init(&call_details); + + // Server gets a second call (the retry). + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(201)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(201), true); + cq_verify(cqv); + + // Initiate cancellation. + GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr)); + + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == mode.expect_status); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_cancellation(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + for (size_t i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); ++i) { + test_retry_cancellation(config, cancellation_modes[i]); + } +} + +void retry_cancellation_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_disabled.cc b/test/core/end2end/tests/retry_disabled.cc new file mode 100644 index 0000000000..ed3535409f --- /dev/null +++ b/test/core/end2end/tests/retry_disabled.cc @@ -0,0 +1,258 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we don't retry when retries are disabled via the +// GRPC_ARG_ENABLE_RETRIES channel arg, even when there is retry +// configuration in the service config. +// - 1 retry allowed for ABORTED status +// - first attempt returns ABORTED but does not retry +static void test_retry_disabled(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg args[2]; + args[0].type = GRPC_ARG_STRING; + args[0].key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + args[0].value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + args[1].type = GRPC_ARG_INTEGER; + args[1].key = const_cast<char*>(GRPC_ARG_ENABLE_RETRIES); + args[1].value.integer = 0; + grpc_channel_args client_args = {GPR_ARRAY_SIZE(args), args}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_disabled", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_disabled(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_disabled(config); +} + +void retry_disabled_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc b/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc new file mode 100644 index 0000000000..a033a0aa95 --- /dev/null +++ b/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc @@ -0,0 +1,262 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we don't make any further attempts after we exceed the +// max buffer size. +// - 1 retry allowed for ABORTED status +// - buffer size set to 2 bytes +// - client sends a 3-byte message +// - first attempt gets ABORTED but is not retried +static void test_retry_exceeds_buffer_size_in_initial_batch( + grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg args[2]; + args[0].type = GRPC_ARG_STRING; + args[0].key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + args[0].value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + args[1].type = GRPC_ARG_INTEGER; + args[1].key = const_cast<char*>(GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE); + args[1].value.integer = 2; + grpc_channel_args client_args = {GPR_ARRAY_SIZE(args), args}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_exceeds_buffer_size_in_initial_batch", + &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_exceeds_buffer_size_in_initial_batch( + grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_exceeds_buffer_size_in_initial_batch(config); +} + +void retry_exceeds_buffer_size_in_initial_batch_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc b/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc new file mode 100644 index 0000000000..c1070e6191 --- /dev/null +++ b/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc @@ -0,0 +1,275 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Similar to the retry_exceeds_buffer_size_in_initial_batch test, but we +// don't exceed the buffer size until the second batch. +// - 1 retry allowed for ABORTED status +// - buffer size set to 100 KiB (larger than initial metadata) +// - client sends a 100 KiB message +// - first attempt gets ABORTED but is not retried +static void test_retry_exceeds_buffer_size_in_subsequent_batch( + grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + const size_t buf_size = 102401; + char* buf = static_cast<char*>(gpr_malloc(buf_size * sizeof(*buf))); + memset(buf, 'a', buf_size - 1); + buf[buf_size - 1] = '\0'; + // TODO(markdroth): buf is not a static string, so fix the next line + grpc_slice request_payload_slice = grpc_slice_from_static_string(buf); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg args[2]; + args[0].type = GRPC_ARG_STRING; + args[0].key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + args[0].value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + args[1].type = GRPC_ARG_INTEGER; + args[1].key = const_cast<char*>(GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE); + args[1].value.integer = 102400; + grpc_channel_args client_args = {GPR_ARRAY_SIZE(args), args}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_exceeds_buffer_size_in_subsequent_batch", + &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + CQ_EXPECT_COMPLETION(cqv, tag(2), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); + gpr_free(buf); +} + +void retry_exceeds_buffer_size_in_subsequent_batch( + grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_exceeds_buffer_size_in_subsequent_batch(config); +} + +void retry_exceeds_buffer_size_in_subsequent_batch_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_non_retriable_status.cc b/test/core/end2end/tests/retry_non_retriable_status.cc new file mode 100644 index 0000000000..b8d094749a --- /dev/null +++ b/test/core/end2end/tests/retry_non_retriable_status.cc @@ -0,0 +1,253 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we don't retry for non-retryable status codes. +// - 1 retry allowed for ABORTED status +// - first attempt gets INVALID_ARGUMENT, so no retry is done +static void test_retry_non_retriable_status(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_non_retriable_status", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_INVALID_ARGUMENT; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_non_retriable_status(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_non_retriable_status(config); +} + +void retry_non_retriable_status_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc b/test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc new file mode 100644 index 0000000000..eb016a3de9 --- /dev/null +++ b/test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc @@ -0,0 +1,266 @@ +/* + * + * 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/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we don't retry for non-retryable status codes, even if +// status is received before the recv_trailing_metadata op is started. +// - 1 retry allowed for ABORTED status +// - first attempt gets INVALID_ARGUMENT, so no retry is done +static void +test_retry_non_retriable_status_before_recv_trailing_metadata_started( + grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_non_retriable_status", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_INVALID_ARGUMENT; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(2), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_non_retriable_status_before_recv_trailing_metadata_started( + grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_non_retriable_status_before_recv_trailing_metadata_started(config); +} + +void retry_non_retriable_status_before_recv_trailing_metadata_started_pre_init() { +} diff --git a/test/core/end2end/tests/retry_recv_initial_metadata.cc b/test/core/end2end/tests/retry_recv_initial_metadata.cc new file mode 100644 index 0000000000..839b870367 --- /dev/null +++ b/test/core/end2end/tests/retry_recv_initial_metadata.cc @@ -0,0 +1,264 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that receiving initial metadata commits the call. +// - 1 retry allowed for ABORTED status +// - first attempt receives initial metadata before trailing metadata, +// so no retry is done even though status was ABORTED +static void test_retry_recv_initial_metadata(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_recv_initial_metadata", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + // Server sends initial metadata in its own batch, before sending + // trailing metadata. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_recv_initial_metadata(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_recv_initial_metadata(config); +} + +void retry_recv_initial_metadata_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_recv_message.cc b/test/core/end2end/tests/retry_recv_message.cc new file mode 100644 index 0000000000..5fdaad0b88 --- /dev/null +++ b/test/core/end2end/tests/retry_recv_message.cc @@ -0,0 +1,257 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that receiving a message commits the call. +// - 1 retry allowed for ABORTED status +// - first attempt receives a message and therefore does not retry even +// though the final status is ABORTED +static void test_retry_recv_message(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_recv_message", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_recv_message(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_recv_message(config); +} + +void retry_recv_message_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_server_pushback_delay.cc b/test/core/end2end/tests/retry_server_pushback_delay.cc new file mode 100644 index 0000000000..221b416828 --- /dev/null +++ b/test/core/end2end/tests/retry_server_pushback_delay.cc @@ -0,0 +1,314 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we honor server push-back delay. +// - 2 retries allowed for ABORTED status +// - first attempt gets ABORTED with a long delay +// - second attempt succeeds +static void test_retry_server_pushback_delay(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_metadata pushback_md; + memset(&pushback_md, 0, sizeof(pushback_md)); + pushback_md.key = GRPC_MDSTR_GRPC_RETRY_PUSHBACK_MS; + pushback_md.value = grpc_slice_from_static_string("2000"); + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_server_pushback_delay", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 1; + op->data.send_status_from_server.trailing_metadata = &pushback_md; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + gpr_timespec before_retry = gpr_now(GPR_CLOCK_MONOTONIC); + + grpc_call_unref(s); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_details_init(&call_details); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(201)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(201), true); + cq_verify(cqv); + + gpr_timespec after_retry = gpr_now(GPR_CLOCK_MONOTONIC); + gpr_timespec retry_delay = gpr_time_sub(after_retry, before_retry); + // Configured back-off was 1 second, server push-back said 2 seconds. + // To avoid flakiness, we allow some fudge factor here. + gpr_log(GPR_INFO, "retry delay was {.tv_sec=%" PRId64 ", .tv_nsec=%d}", + retry_delay.tv_sec, retry_delay.tv_nsec); + GPR_ASSERT(retry_delay.tv_sec >= 1); + if (retry_delay.tv_sec == 1) { + GPR_ASSERT(retry_delay.tv_nsec >= 800000000); + } + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(202), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 0); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_server_pushback_delay(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_server_pushback_delay(config); +} + +void retry_server_pushback_delay_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_server_pushback_disabled.cc b/test/core/end2end/tests/retry_server_pushback_disabled.cc new file mode 100644 index 0000000000..1c56476183 --- /dev/null +++ b/test/core/end2end/tests/retry_server_pushback_disabled.cc @@ -0,0 +1,302 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we don't retry when disabled by server push-back. +// - 2 retries allowed for ABORTED status +// - first attempt gets ABORTED +// - second attempt gets ABORTED but server push back disables retrying +static void test_retry_server_pushback_disabled( + grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_metadata pushback_md; + memset(&pushback_md, 0, sizeof(pushback_md)); + pushback_md.key = GRPC_MDSTR_GRPC_RETRY_PUSHBACK_MS; + pushback_md.value = grpc_slice_from_static_string("-1"); + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = begin_test( + config, "retry_server_pushback_disabled", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + grpc_call_unref(s); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_details_init(&call_details); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(201)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(201), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 1; + op->data.send_status_from_server.trailing_metadata = &pushback_md; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(202), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_server_pushback_disabled(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_server_pushback_disabled(config); +} + +void retry_server_pushback_disabled_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_streaming.cc b/test/core/end2end/tests/retry_streaming.cc new file mode 100644 index 0000000000..d06d124ca4 --- /dev/null +++ b/test/core/end2end/tests/retry_streaming.cc @@ -0,0 +1,420 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests retrying a streaming RPC. This is the same as +// the basic retry test, except that the client sends two messages on the +// call before the initial attempt fails. +// FIXME: We should also test the case where the retry is committed after +// replaying 1 of 2 previously-completed send_message ops. However, +// there's no way to trigger that from an end2end test, because the +// replayed ops happen under the hood -- they are not surfaced to the +// C-core API, and therefore we have no way to inject the commit at the +// right point. +static void test_retry_streaming(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice request2_payload_slice = grpc_slice_from_static_string("bar"); + grpc_slice request3_payload_slice = grpc_slice_from_static_string("baz"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("quux"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* request2_payload = + grpc_raw_byte_buffer_create(&request2_payload_slice, 1); + grpc_byte_buffer* request3_payload = + grpc_raw_byte_buffer_create(&request3_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* request2_payload_recv = nullptr; + grpc_byte_buffer* request3_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_streaming", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + // Client starts a batch for receiving initial metadata, a message, + // and trailing metadata. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + // Client sends initial metadata and a message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(2), true); + cq_verify(cqv); + + // Server gets a call with received initial metadata. + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + // Server receives a message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + // Client sends a second message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request2_payload; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(3), true); + cq_verify(cqv); + + // Server receives the second message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request2_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(103), true); + cq_verify(cqv); + + // Server sends both initial and trailing metadata. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(104), true); + cq_verify(cqv); + + // Clean up from first attempt. + grpc_call_unref(s); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_details_init(&call_details); + GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); + grpc_byte_buffer_destroy(request_payload_recv); + request_payload_recv = nullptr; + GPR_ASSERT( + byte_buffer_eq_slice(request2_payload_recv, request2_payload_slice)); + grpc_byte_buffer_destroy(request2_payload_recv); + request2_payload_recv = nullptr; + + // Server gets a second call (the retry). + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(201)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(201), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + // Server receives a message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(202), true); + cq_verify(cqv); + + // Server receives a second message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request2_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(203), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(203), true); + cq_verify(cqv); + + // Client sends a third message and a close. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request3_payload; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(4), true); + cq_verify(cqv); + + // Server receives a third message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request3_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(204), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(204), true); + cq_verify(cqv); + + // Server receives a close and sends initial metadata, a message, and + // trailing metadata. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + // Returning a retriable code, but because we are also sending a + // message, the client will commit instead of retrying again. + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(205), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(205), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(request2_payload); + grpc_byte_buffer_destroy(request3_payload); + grpc_byte_buffer_destroy(response_payload); + GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); + grpc_byte_buffer_destroy(request_payload_recv); + GPR_ASSERT( + byte_buffer_eq_slice(request2_payload_recv, request2_payload_slice)); + grpc_byte_buffer_destroy(request2_payload_recv); + GPR_ASSERT( + byte_buffer_eq_slice(request3_payload_recv, request3_payload_slice)); + grpc_byte_buffer_destroy(request3_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_streaming(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_streaming(config); +} + +void retry_streaming_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_streaming_after_commit.cc b/test/core/end2end/tests/retry_streaming_after_commit.cc new file mode 100644 index 0000000000..05025d0a10 --- /dev/null +++ b/test/core/end2end/tests/retry_streaming_after_commit.cc @@ -0,0 +1,350 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we can continue to send/recv messages on a streaming call +// after retries are committed. +static void test_retry_streaming_after_commit(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice request2_payload_slice = grpc_slice_from_static_string("bar"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("baz"); + grpc_slice response2_payload_slice = grpc_slice_from_static_string("quux"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* request2_payload = + grpc_raw_byte_buffer_create(&request2_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* response2_payload = + grpc_raw_byte_buffer_create(&response2_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* request2_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_byte_buffer* response2_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_streaming_after_commit", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + // Client starts a batch for receiving initial metadata and a message. + // This will commit retries. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + // Client sends initial metadata and a message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(3), true); + cq_verify(cqv); + + // Server gets a call with received initial metadata. + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + // Server receives a message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + // Server sends initial metadata and a message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(103), true); + // Client receives initial metadata and a message. + CQ_EXPECT_COMPLETION(cqv, tag(2), true); + cq_verify(cqv); + + // Client sends a second message and a close. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request2_payload; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(4), true); + cq_verify(cqv); + + // Server receives a second message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request2_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(104), true); + cq_verify(cqv); + + // Server receives a close, sends a second message, and sends status. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response2_payload; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + // Returning a retriable code, but because retries are already + // committed, the client will not retry. + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(105), true); + cq_verify(cqv); + + // Client receives a second message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response2_payload_recv; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(5), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(5), true); + cq_verify(cqv); + + // Client receives status. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(request2_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(response2_payload); + GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); + grpc_byte_buffer_destroy(request_payload_recv); + GPR_ASSERT( + byte_buffer_eq_slice(request2_payload_recv, request2_payload_slice)); + grpc_byte_buffer_destroy(request2_payload_recv); + GPR_ASSERT( + byte_buffer_eq_slice(response_payload_recv, response_payload_slice)); + grpc_byte_buffer_destroy(response_payload_recv); + GPR_ASSERT( + byte_buffer_eq_slice(response2_payload_recv, response2_payload_slice)); + grpc_byte_buffer_destroy(response2_payload_recv); + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_streaming_after_commit(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_streaming_after_commit(config); +} + +void retry_streaming_after_commit_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc b/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc new file mode 100644 index 0000000000..14460d2a46 --- /dev/null +++ b/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc @@ -0,0 +1,396 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we correctly clean up if the second attempt finishes +// before we have finished replaying all of the send ops. +static void test_retry_streaming_succeeds_before_replay_finished( + grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice request2_payload_slice = grpc_slice_from_static_string("bar"); + grpc_slice request3_payload_slice = grpc_slice_from_static_string("baz"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("quux"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* request2_payload = + grpc_raw_byte_buffer_create(&request2_payload_slice, 1); + grpc_byte_buffer* request3_payload = + grpc_raw_byte_buffer_create(&request3_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* request2_payload_recv = nullptr; + grpc_byte_buffer* request3_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_streaming", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + // Client starts a batch for receiving initial metadata, a message, + // and trailing metadata. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + // Client sends initial metadata and a message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(2), true); + cq_verify(cqv); + + // Server gets a call with received initial metadata. + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + // Server receives a message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + // Client sends a second message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request2_payload; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(3), true); + cq_verify(cqv); + + // Server receives the second message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request2_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(103), true); + cq_verify(cqv); + + // Client sends a third message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request3_payload; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(4), true); + cq_verify(cqv); + + // Server receives the third message. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request3_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(104), true); + cq_verify(cqv); + + // Server sends both initial and trailing metadata. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(105), true); + cq_verify(cqv); + + // Clean up from first attempt. + grpc_call_unref(s); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_details_init(&call_details); + GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); + grpc_byte_buffer_destroy(request_payload_recv); + request_payload_recv = nullptr; + GPR_ASSERT( + byte_buffer_eq_slice(request2_payload_recv, request2_payload_slice)); + grpc_byte_buffer_destroy(request2_payload_recv); + request2_payload_recv = nullptr; + GPR_ASSERT( + byte_buffer_eq_slice(request3_payload_recv, request3_payload_slice)); + grpc_byte_buffer_destroy(request3_payload_recv); + request3_payload_recv = nullptr; + + // Server gets a second call (the retry). + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(201)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(201), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + // Server receives the first message (and does not receive any others). + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(202), true); + cq_verify(cqv); + + // Server sends initial metadata, a message, and trailing metadata. + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + // Returning a retriable code, but because we are also sending a + // message, the client will commit instead of retrying again. + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(205), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(205), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(request2_payload); + grpc_byte_buffer_destroy(request3_payload); + grpc_byte_buffer_destroy(response_payload); + GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_streaming_succeeds_before_replay_finished( + grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_streaming_succeeds_before_replay_finished(config); +} + +void retry_streaming_succeeds_before_replay_finished_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_throttled.cc b/test/core/end2end/tests/retry_throttled.cc new file mode 100644 index 0000000000..f5b28def0a --- /dev/null +++ b/test/core/end2end/tests/retry_throttled.cc @@ -0,0 +1,260 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we don't retry when throttled. +// - 1 retry allowed for ABORTED status +// - first attempt gets ABORTED but is over limit, so no retry is done +static void test_retry_throttled(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ],\n" + // A single failure will cause us to be throttled. + // (This is not a very realistic config, but it works for the + // purposes of this test.) + " \"retryThrottling\": {\n" + " \"maxTokens\": 2,\n" + " \"tokenRatio\": 1.0,\n" + " }\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_throttled", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_throttled(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_throttled(config); +} + +void retry_throttled_pre_init(void) {} diff --git a/test/core/end2end/tests/retry_too_many_attempts.cc b/test/core/end2end/tests/retry_too_many_attempts.cc new file mode 100644 index 0000000000..2af32679f1 --- /dev/null +++ b/test/core/end2end/tests/retry_too_many_attempts.cc @@ -0,0 +1,295 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/transport/static_metadata.h" + +#include "test/core/end2end/cq_verifier.h" +#include "test/core/end2end/tests/cancel_test_helpers.h" + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Tests that we stop retrying after the configured number of attempts. +// - 1 retry allowed for ABORTED status +// - first attempt gets ABORTED +// - second attempt gets ABORTED but does not retry +static void test_retry_too_many_attempts(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_slice request_payload_slice = grpc_slice_from_static_string("foo"); + grpc_slice response_payload_slice = grpc_slice_from_static_string("bar"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); + arg.value.string = const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 2,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + grpc_channel_args client_args = {1, &arg}; + grpc_end2end_test_fixture f = + begin_test(config, "retry_too_many_attempts", &client_args, nullptr); + + cq_verifier* cqv = cq_verifier_create(f.cq); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/service/method"), + nullptr, deadline, nullptr); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), true); + cq_verify(cqv); + + grpc_call_unref(s); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_details_init(&call_details); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(201)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(201), true); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "server_peer=%s", peer); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != nullptr); + gpr_log(GPR_DEBUG, "client_peer=%s", peer); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_ABORTED; + op->data.send_status_from_server.status_details = &status_details; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(202), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_ABORTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + end_test(&f); + config.tear_down_data(&f); +} + +void retry_too_many_attempts(grpc_end2end_test_config config) { + GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_too_many_attempts(config); +} + +void retry_too_many_attempts_pre_init(void) {} diff --git a/test/core/end2end/tests/server_finishes_request.cc b/test/core/end2end/tests/server_finishes_request.cc index 46b874b569..c81b309a1e 100644 --- a/test/core/end2end/tests/server_finishes_request.cc +++ b/test/core/end2end/tests/server_finishes_request.cc @@ -26,8 +26,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -103,11 +102,9 @@ static void simple_request_body(grpc_end2end_test_config config, int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -134,7 +131,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -164,7 +162,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -174,8 +173,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/shutdown_finishes_calls.cc b/test/core/end2end/tests/shutdown_finishes_calls.cc index fce23f3b6a..5dd5bb2ad6 100644 --- a/test/core/end2end/tests/shutdown_finishes_calls.cc +++ b/test/core/end2end/tests/shutdown_finishes_calls.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -93,11 +92,9 @@ static void test_early_server_shutdown_finishes_inflight_calls( int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -129,7 +126,8 @@ static void test_early_server_shutdown_finishes_inflight_calls( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -146,9 +144,17 @@ static void test_early_server_shutdown_finishes_inflight_calls( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); + /* Make sure we don't shutdown the server while HTTP/2 PING frames are still + * being exchanged on the newly established connection. It can lead to + * failures when testing with HTTP proxy. See + * https://github.com/grpc/grpc/issues/14471 + */ + gpr_sleep_until(n_seconds_from_now(1)); + /* shutdown and destroy the server */ grpc_server_shutdown_and_notify(f.server, f.cq, tag(1000)); grpc_server_cancel_all_calls(f.server); @@ -164,8 +170,6 @@ static void test_early_server_shutdown_finishes_inflight_calls( GPR_ASSERT(status == GRPC_STATUS_INTERNAL || status == GRPC_STATUS_UNAVAILABLE); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/shutdown_finishes_tags.cc b/test/core/end2end/tests/shutdown_finishes_tags.cc index de64eba612..55caacb7ff 100644 --- a/test/core/end2end/tests/shutdown_finishes_tags.cc +++ b/test/core/end2end/tests/shutdown_finishes_tags.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -78,7 +77,7 @@ static void test_early_server_shutdown_finishes_tags( grpc_end2end_test_fixture f = begin_test( config, "test_early_server_shutdown_finishes_tags", nullptr, nullptr); cq_verifier* cqv = cq_verifier_create(f.cq); - grpc_call* s = (grpc_call*)(uintptr_t)1; + grpc_call* s = (grpc_call*)static_cast<uintptr_t>(1); grpc_call_details call_details; grpc_metadata_array request_metadata_recv; diff --git a/test/core/end2end/tests/simple_cacheable_request.cc b/test/core/end2end/tests/simple_cacheable_request.cc index d8034dcf6d..be6d16ecad 100644 --- a/test/core/end2end/tests/simple_cacheable_request.cc +++ b/test/core/end2end/tests/simple_cacheable_request.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" enum { TIMEOUT = 200000 }; @@ -133,11 +132,9 @@ static void test_cacheable_request_response_with_metadata_and_payload( int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -179,7 +176,8 @@ static void test_cacheable_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -202,7 +200,8 @@ static void test_cacheable_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -228,7 +227,8 @@ static void test_cacheable_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -238,8 +238,6 @@ static void test_cacheable_request_response_with_metadata_and_payload( GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) { // Our simple proxy does not support cacheable requests } else { diff --git a/test/core/end2end/tests/simple_delayed_request.cc b/test/core/end2end/tests/simple_delayed_request.cc index 0ad224f579..8d11699945 100644 --- a/test/core/end2end/tests/simple_delayed_request.cc +++ b/test/core/end2end/tests/simple_delayed_request.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -95,11 +94,9 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, config.init_server(f, server_args); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, f->cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f->client, nullptr, GRPC_PROPAGATE_DEFAULTS, + f->cq, grpc_slice_from_static_string("/foo"), + nullptr, deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -130,7 +127,8 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -160,7 +158,8 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -170,8 +169,6 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/simple_metadata.cc b/test/core/end2end/tests/simple_metadata.cc index 1a741169d4..3e476c2129 100644 --- a/test/core/end2end/tests/simple_metadata.cc +++ b/test/core/end2end/tests/simple_metadata.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -131,11 +130,9 @@ static void test_request_response_with_metadata_and_payload( int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -177,7 +174,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -200,7 +198,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -226,7 +225,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -236,8 +236,6 @@ static void test_request_response_with_metadata_and_payload( GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); diff --git a/test/core/end2end/tests/simple_request.cc b/test/core/end2end/tests/simple_request.cc index 7eb7467981..941d9ae319 100644 --- a/test/core/end2end/tests/simple_request.cc +++ b/test/core/end2end/tests/simple_request.cc @@ -26,9 +26,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/debug/stats.h" -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -112,11 +111,9 @@ static void simple_request_body(grpc_end2end_test_config config, grpc_stats_collect(before); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); peer = grpc_call_get_peer(c); @@ -153,7 +150,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -192,7 +190,8 @@ static void simple_request_body(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -211,8 +210,6 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(nullptr != strstr(error_string, "grpc_message")); GPR_ASSERT(nullptr != strstr(error_string, "grpc_status")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(0 == call_details.flags); GPR_ASSERT(was_cancelled == 1); @@ -238,12 +235,14 @@ static void simple_request_body(grpc_end2end_test_config config, if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) { expected_calls *= 2; } +#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] - before->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] == expected_calls); GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] - before->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] == expected_calls); +#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */ gpr_free(before); gpr_free(after); } diff --git a/test/core/end2end/tests/stream_compression_compressed_payload.cc b/test/core/end2end/tests/stream_compression_compressed_payload.cc index ec3050ad45..839f0912a8 100644 --- a/test/core/end2end/tests/stream_compression_compressed_payload.cc +++ b/test/core/end2end/tests/stream_compression_compressed_payload.cc @@ -28,7 +28,6 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/surface/call.h" @@ -95,8 +94,8 @@ static void end_test(grpc_end2end_test_fixture* f) { static void request_for_disabled_algorithm( grpc_end2end_test_config config, const char* test_name, uint32_t send_flags_bitmask, - grpc_stream_compression_algorithm algorithm_to_disable, - grpc_stream_compression_algorithm requested_client_compression_algorithm, + grpc_compression_algorithm algorithm_to_disable, + grpc_compression_algorithm requested_client_compression_algorithm, grpc_status_code expected_error, grpc_metadata* client_metadata) { grpc_call* c; grpc_call* s; @@ -124,13 +123,13 @@ static void request_for_disabled_algorithm( request_payload_slice = grpc_slice_from_copied_string(str); request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); - client_args = grpc_channel_args_set_stream_compression_algorithm( + client_args = grpc_channel_args_set_compression_algorithm( nullptr, requested_client_compression_algorithm); - server_args = grpc_channel_args_set_stream_compression_algorithm( - nullptr, GRPC_STREAM_COMPRESS_NONE); + server_args = + grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_NONE); { grpc_core::ExecCtx exec_ctx; - server_args = grpc_channel_args_stream_compression_algorithm_set_state( + server_args = grpc_channel_args_compression_algorithm_set_state( &server_args, algorithm_to_disable, false); } @@ -138,11 +137,9 @@ static void request_for_disabled_algorithm( cqv = cq_verifier_create(f.cq); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -188,7 +185,8 @@ static void request_for_disabled_algorithm( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(101), true); @@ -206,7 +204,8 @@ static void request_for_disabled_algorithm( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), false); @@ -217,7 +216,8 @@ static void request_for_disabled_algorithm( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), true); @@ -229,17 +229,14 @@ static void request_for_disabled_algorithm( GPR_ASSERT(status == expected_error); const char* algo_name = nullptr; - GPR_ASSERT( - grpc_stream_compression_algorithm_name(algorithm_to_disable, &algo_name)); + GPR_ASSERT(grpc_compression_algorithm_name(algorithm_to_disable, &algo_name)); char* expected_details = nullptr; - gpr_asprintf(&expected_details, - "Stream compression algorithm '%s' is disabled.", algo_name); + gpr_asprintf(&expected_details, "Compression algorithm '%s' is disabled.", + algo_name); /* and we expect a specific reason for it */ GPR_ASSERT(0 == grpc_slice_str_cmp(details, expected_details)); gpr_free(expected_details); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); grpc_slice_unref(details); grpc_metadata_array_destroy(&initial_metadata_recv); @@ -269,14 +266,12 @@ static void request_for_disabled_algorithm( static void request_with_payload_template( grpc_end2end_test_config config, const char* test_name, uint32_t client_send_flags_bitmask, - grpc_stream_compression_algorithm - default_client_channel_compression_algorithm, - grpc_stream_compression_algorithm - default_server_channel_compression_algorithm, - grpc_stream_compression_algorithm expected_client_compression_algorithm, - grpc_stream_compression_algorithm expected_server_compression_algorithm, + grpc_compression_algorithm default_client_channel_compression_algorithm, + grpc_compression_algorithm default_server_channel_compression_algorithm, + grpc_compression_algorithm expected_client_compression_algorithm, + grpc_compression_algorithm expected_server_compression_algorithm, grpc_metadata* client_init_metadata, bool set_server_level, - grpc_stream_compression_level server_compression_level, + grpc_compression_level server_compression_level, bool send_message_before_initial_metadata, bool set_default_server_message_compression_algorithm, grpc_compression_algorithm default_server_message_compression_algorithm) { @@ -314,13 +309,13 @@ static void request_with_payload_template( grpc_slice response_payload_slice = grpc_slice_from_copied_string(response_str); - client_args = grpc_channel_args_set_stream_compression_algorithm( + client_args = grpc_channel_args_set_compression_algorithm( nullptr, default_client_channel_compression_algorithm); if (set_default_server_message_compression_algorithm) { server_args = grpc_channel_args_set_compression_algorithm( nullptr, default_server_message_compression_algorithm); } else { - server_args = grpc_channel_args_set_stream_compression_algorithm( + server_args = grpc_channel_args_set_compression_algorithm( nullptr, default_server_channel_compression_algorithm); } @@ -328,11 +323,9 @@ static void request_with_payload_template( cqv = cq_verifier_create(f.cq); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -349,7 +342,8 @@ static void request_with_payload_template( op->flags = client_send_flags_bitmask; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), true); } @@ -378,7 +372,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -396,23 +391,18 @@ static void request_with_payload_template( GRPC_COMPRESS_DEFLATE) != 0); GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s), GRPC_COMPRESS_GZIP) != 0); - GPR_ASSERT( - GPR_BITCOUNT(grpc_call_test_only_get_stream_encodings_accepted_by_peer( - s)) == GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT); - GPR_ASSERT( - GPR_BITGET(grpc_call_test_only_get_stream_encodings_accepted_by_peer(s), - GRPC_STREAM_COMPRESS_NONE) != 0); - GPR_ASSERT( - GPR_BITGET(grpc_call_test_only_get_stream_encodings_accepted_by_peer(s), - GRPC_STREAM_COMPRESS_GZIP) != 0); + GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s), + GRPC_COMPRESS_STREAM_GZIP) != 0); + GPR_ASSERT(GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer( + s)) == GRPC_COMPRESS_ALGORITHMS_COUNT); memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; if (set_server_level) { - op->data.send_initial_metadata.maybe_stream_compression_level.is_set = true; - op->data.send_initial_metadata.maybe_stream_compression_level.level = + op->data.send_initial_metadata.maybe_compression_level.is_set = true; + op->data.send_initial_metadata.maybe_compression_level.level = server_compression_level; } op->flags = 0; @@ -423,7 +413,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(101), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); for (int i = 0; i < 2; i++) { @@ -438,8 +429,8 @@ static void request_with_payload_template( op->flags = client_send_flags_bitmask; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), + tag(2), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), 1); } @@ -451,8 +442,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(102), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -468,8 +459,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(103), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -479,7 +470,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -504,7 +496,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -517,7 +510,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); @@ -529,8 +523,6 @@ static void request_with_payload_template( GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); grpc_slice_unref(details); @@ -558,30 +550,20 @@ static void test_invoke_request_with_compressed_payload( grpc_end2end_test_config config) { request_with_payload_template( config, "test_invoke_request_with_compressed_payload", 0, - GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP, - GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP, nullptr, + GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP, + GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP, nullptr, false, /* ignored */ - GRPC_STREAM_COMPRESS_LEVEL_NONE, false, false, GRPC_COMPRESS_NONE); + GRPC_COMPRESS_LEVEL_NONE, false, false, GRPC_COMPRESS_NONE); } static void test_invoke_request_with_send_message_before_initial_metadata( grpc_end2end_test_config config) { request_with_payload_template( config, "test_invoke_request_with_send_message_before_initial_metadata", - 0, GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP, - GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP, nullptr, + 0, GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP, + GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP, nullptr, false, /* ignored */ - GRPC_STREAM_COMPRESS_LEVEL_NONE, true, false, GRPC_COMPRESS_NONE); -} - -static void test_invoke_request_with_server_level( - grpc_end2end_test_config config) { - request_with_payload_template( - config, "test_invoke_request_with_server_level", 0, - GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE, - GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_GZIP, - /* ignored */ nullptr, true, GRPC_STREAM_COMPRESS_LEVEL_HIGH, false, - false, GRPC_COMPRESS_NONE); + GRPC_COMPRESS_LEVEL_NONE, true, false, GRPC_COMPRESS_NONE); } static void test_invoke_request_with_compressed_payload_md_override( @@ -591,7 +573,8 @@ static void test_invoke_request_with_compressed_payload_md_override( gzip_compression_override.key = GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST; - gzip_compression_override.value = grpc_slice_from_static_string("gzip"); + gzip_compression_override.value = + grpc_slice_from_static_string("stream/gzip"); memset(&gzip_compression_override.internal_data, 0, sizeof(gzip_compression_override.internal_data)); @@ -605,49 +588,31 @@ static void test_invoke_request_with_compressed_payload_md_override( /* Channel default NONE (aka IDENTITY), call override to stream GZIP */ request_with_payload_template( config, "test_invoke_request_with_compressed_payload_md_override_1", 0, - GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE, - GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_NONE, - &gzip_compression_override, false, - /*ignored*/ GRPC_STREAM_COMPRESS_LEVEL_NONE, false, false, - GRPC_COMPRESS_NONE); + GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_STREAM_GZIP, + GRPC_COMPRESS_NONE, &gzip_compression_override, false, + /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false, false, GRPC_COMPRESS_NONE); /* Channel default stream GZIP, call override to NONE (aka IDENTITY) */ request_with_payload_template( config, "test_invoke_request_with_compressed_payload_md_override_3", 0, - GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_NONE, - GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE, - &identity_compression_override, false, - /*ignored*/ GRPC_STREAM_COMPRESS_LEVEL_NONE, false, false, - GRPC_COMPRESS_NONE); + GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, + GRPC_COMPRESS_NONE, &identity_compression_override, false, + /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false, false, GRPC_COMPRESS_NONE); } static void test_invoke_request_with_disabled_algorithm( grpc_end2end_test_config config) { request_for_disabled_algorithm( config, "test_invoke_request_with_disabled_algorithm", 0, - GRPC_STREAM_COMPRESS_GZIP, GRPC_STREAM_COMPRESS_GZIP, + GRPC_COMPRESS_STREAM_GZIP, GRPC_COMPRESS_STREAM_GZIP, GRPC_STATUS_UNIMPLEMENTED, nullptr); } -static void test_stream_compression_override_message_compression( - grpc_end2end_test_config config) { - grpc_stream_compression_level level = GRPC_STREAM_COMPRESS_LEVEL_MED; - request_with_payload_template( - config, "test_stream_compression_override_message_compression", 0, - GRPC_STREAM_COMPRESS_NONE, GRPC_STREAM_COMPRESS_NONE, - GRPC_STREAM_COMPRESS_NONE, - grpc_stream_compression_algorithm_for_level( - level, (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1), - /* ignored */ nullptr, true, level, false, true, GRPC_COMPRESS_GZIP); -} - void stream_compression_compressed_payload(grpc_end2end_test_config config) { test_invoke_request_with_compressed_payload(config); test_invoke_request_with_send_message_before_initial_metadata(config); - test_invoke_request_with_server_level(config); test_invoke_request_with_compressed_payload_md_override(config); test_invoke_request_with_disabled_algorithm(config); - test_stream_compression_override_message_compression(config); } void stream_compression_compressed_payload_pre_init(void) {} diff --git a/test/core/end2end/tests/stream_compression_payload.cc b/test/core/end2end/tests/stream_compression_payload.cc index b95e6528cd..4c08150723 100644 --- a/test/core/end2end/tests/stream_compression_payload.cc +++ b/test/core/end2end/tests/stream_compression_payload.cc @@ -26,7 +26,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/surface/call.h" #include "test/core/end2end/cq_verifier.h" @@ -94,9 +93,9 @@ static grpc_slice generate_random_slice() { static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; char* output; const size_t output_size = 1024 * 1024; - output = (char*)gpr_malloc(output_size); + output = static_cast<char*>(gpr_malloc(output_size)); for (i = 0; i < output_size - 1; ++i) { - output[i] = chars[rand() % (int)(sizeof(chars) - 1)]; + output[i] = chars[rand() % static_cast<int>(sizeof(chars) - 1)]; } output[output_size - 1] = '\0'; grpc_slice out = grpc_slice_from_copied_string(output); @@ -133,11 +132,9 @@ static void request_response_with_payload(grpc_end2end_test_config config, int was_cancelled = 2; gpr_timespec deadline = n_seconds_from_now(60); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -178,7 +175,8 @@ static void request_response_with_payload(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -200,7 +198,8 @@ static void request_response_with_payload(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -226,7 +225,8 @@ static void request_response_with_payload(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -236,8 +236,6 @@ static void request_response_with_payload(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); GPR_ASSERT( @@ -264,12 +262,10 @@ static void request_response_with_payload(grpc_end2end_test_config config, payload and status. */ static void test_invoke_request_response_with_payload( grpc_end2end_test_config config) { - grpc_channel_args* client_args = - grpc_channel_args_set_stream_compression_algorithm( - nullptr, GRPC_STREAM_COMPRESS_GZIP); - grpc_channel_args* server_args = - grpc_channel_args_set_stream_compression_algorithm( - nullptr, GRPC_STREAM_COMPRESS_GZIP); + grpc_channel_args* client_args = grpc_channel_args_set_compression_algorithm( + nullptr, GRPC_COMPRESS_STREAM_GZIP); + grpc_channel_args* server_args = grpc_channel_args_set_compression_algorithm( + nullptr, GRPC_COMPRESS_STREAM_GZIP); grpc_end2end_test_fixture f = begin_test(config, "test_invoke_request_response_with_payload", client_args, server_args); diff --git a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc index 2a8799ee67..f7af59febe 100644 --- a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc +++ b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc @@ -26,7 +26,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/surface/call.h" #include "test/core/end2end/cq_verifier.h" @@ -90,12 +90,10 @@ static void end_test(grpc_end2end_test_fixture* f) { /* Client pings and server pongs. Repeat messages rounds before finishing. */ static void test_pingpong_streaming(grpc_end2end_test_config config, int messages) { - grpc_channel_args* client_args = - grpc_channel_args_set_stream_compression_algorithm( - nullptr, GRPC_STREAM_COMPRESS_GZIP); - grpc_channel_args* server_args = - grpc_channel_args_set_stream_compression_algorithm( - nullptr, GRPC_STREAM_COMPRESS_GZIP); + grpc_channel_args* client_args = grpc_channel_args_set_compression_algorithm( + nullptr, GRPC_COMPRESS_STREAM_GZIP); + grpc_channel_args* server_args = grpc_channel_args_set_compression_algorithm( + nullptr, GRPC_COMPRESS_STREAM_GZIP); grpc_end2end_test_fixture f = begin_test(config, "test_pingpong_streaming", client_args, server_args); grpc_call* c; @@ -122,11 +120,9 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, grpc_slice_from_copied_string("hello you"); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -153,7 +149,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -175,7 +172,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(101), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); for (i = 0; i < messages; i++) { @@ -194,7 +192,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -204,8 +203,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(102), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); @@ -217,8 +216,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(103), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); CQ_EXPECT_COMPLETION(cqv, tag(2), 1); @@ -239,7 +238,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -252,7 +252,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); diff --git a/test/core/end2end/tests/streaming_error_response.cc b/test/core/end2end/tests/streaming_error_response.cc index fe53fda9ef..4c357e077e 100644 --- a/test/core/end2end/tests/streaming_error_response.cc +++ b/test/core/end2end/tests/streaming_error_response.cc @@ -28,7 +28,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -111,17 +110,15 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { grpc_byte_buffer* response_payload1_recv = nullptr; grpc_byte_buffer* response_payload2_recv = nullptr; grpc_call_details call_details; - grpc_status_code status; + grpc_status_code status = GRPC_STATUS_OK; grpc_call_error error; grpc_slice details; int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -149,7 +146,8 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { op->data.recv_status_on_client.status_details = &details; op++; } - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -166,7 +164,8 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message.send_message = response_payload1; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -180,7 +179,8 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message.send_message = response_payload2; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -191,7 +191,8 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message.recv_message = &response_payload2_recv; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), 1); @@ -209,7 +210,8 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { grpc_slice status_details = grpc_slice_from_static_string("xyz"); op->data.send_status_from_server.status_details = &status_details; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(104), 1); @@ -226,7 +228,8 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { op->data.recv_status_on_client.status = &status; op->data.recv_status_on_client.status_details = &details; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(3), 1); @@ -239,8 +242,6 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { GPR_ASSERT(status == GRPC_STATUS_FAILED_PRECONDITION); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 1); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/trailing_metadata.cc b/test/core/end2end/tests/trailing_metadata.cc index afc56c8dfa..5cf6f2bb11 100644 --- a/test/core/end2end/tests/trailing_metadata.cc +++ b/test/core/end2end/tests/trailing_metadata.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -139,11 +138,9 @@ static void test_request_response_with_metadata_and_payload( int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -185,7 +182,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -208,7 +206,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); @@ -235,7 +234,8 @@ static void test_request_response_with_metadata_and_payload( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); @@ -245,8 +245,6 @@ static void test_request_response_with_metadata_and_payload( GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); GPR_ASSERT(contains_metadata(&request_metadata_recv, "key1", "val1")); diff --git a/test/core/end2end/tests/workaround_cronet_compression.cc b/test/core/end2end/tests/workaround_cronet_compression.cc index d4decce0aa..f44ddca3b1 100644 --- a/test/core/end2end/tests/workaround_cronet_compression.cc +++ b/test/core/end2end/tests/workaround_cronet_compression.cc @@ -28,7 +28,6 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/surface/call.h" @@ -156,11 +155,9 @@ static void request_with_payload_template( cqv = cq_verifier_create(f.cq); gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -192,7 +189,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); error = @@ -228,7 +226,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(101), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); for (int i = 0; i < 2; i++) { @@ -247,7 +246,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -257,8 +257,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(102), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); @@ -275,8 +275,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), + tag(103), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), 1); CQ_EXPECT_COMPLETION(cqv, tag(2), 1); @@ -309,7 +309,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -322,7 +323,8 @@ static void request_with_payload_template( op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); @@ -334,8 +336,6 @@ static void request_with_payload_template( GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); grpc_slice_unref(details); diff --git a/test/core/end2end/tests/write_buffering.cc b/test/core/end2end/tests/write_buffering.cc index 40821dd6f0..2f7ee9c892 100644 --- a/test/core/end2end/tests/write_buffering.cc +++ b/test/core/end2end/tests/write_buffering.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -112,11 +111,9 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -129,7 +126,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -139,7 +137,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -155,7 +154,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->data.send_message.send_message = request_payload1; op->flags = GRPC_WRITE_BUFFER_HINT; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -163,7 +163,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); /* recv message should not succeed yet - it's buffered at the client still */ @@ -172,7 +173,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message.recv_message = &request_payload_recv1; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), true); @@ -187,7 +189,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->data.send_message.send_message = request_payload2; op->flags = 0; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); /* now the first send should match up with the first recv */ @@ -201,7 +204,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message.recv_message = &request_payload_recv2; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(104), true); @@ -220,7 +224,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4), + nullptr); memset(ops, 0, sizeof(ops)); op = ops; @@ -237,7 +242,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(105), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(105), 1); @@ -247,8 +253,6 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv1, "hello world")); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv2, "abc123")); diff --git a/test/core/end2end/tests/write_buffering_at_end.cc b/test/core/end2end/tests/write_buffering_at_end.cc index 1b9dc9632b..886d491a10 100644 --- a/test/core/end2end/tests/write_buffering_at_end.cc +++ b/test/core/end2end/tests/write_buffering_at_end.cc @@ -25,7 +25,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" static void* tag(intptr_t t) { return (void*)t; } @@ -109,11 +108,9 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { int was_cancelled = 2; gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call( - f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), - get_host_override_slice("foo.test.google.fr:1234", config), deadline, - nullptr); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -126,7 +123,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -136,7 +134,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( @@ -152,7 +151,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->data.send_message.send_message = request_payload; op->flags = GRPC_WRITE_BUFFER_HINT; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); memset(ops, 0, sizeof(ops)); @@ -160,7 +160,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); /* recv message should not succeed yet - it's buffered at the client still */ @@ -169,7 +170,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message.recv_message = &request_payload_recv1; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(2), true); @@ -182,7 +184,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op = ops; op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); /* now the first send should match up with the first recv */ @@ -196,7 +199,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message.recv_message = &request_payload_recv2; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(104), true); @@ -211,7 +215,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr); + error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4), + nullptr); memset(ops, 0, sizeof(ops)); op = ops; @@ -228,7 +233,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), nullptr); + error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(105), + nullptr); GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(105), 1); @@ -238,8 +244,6 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_OK); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - validate_host_override_string("foo.test.google.fr:1234", call_details.host, - config); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv1, "hello world")); GPR_ASSERT(request_payload_recv2 == nullptr); diff --git a/test/core/fling/client.cc b/test/core/fling/client.cc index 69fb6dc7c7..05dc3052d1 100644 --- a/test/core/fling/client.cc +++ b/test/core/fling/client.cc @@ -21,11 +21,12 @@ #include <stdio.h> #include <string.h> -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/profiling/timers.h" +#include "test/core/util/cmdline.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/histogram.h" #include "test/core/util/test_config.h" @@ -74,7 +75,7 @@ static void init_ping_pong_request(void) { } static void step_ping_pong_request(void) { - GPR_TIMER_BEGIN("ping_pong", 1); + GPR_TIMER_SCOPE("ping_pong", 1); grpc_slice host = grpc_slice_from_static_string("localhost"); call = grpc_channel_create_call( channel, nullptr, GRPC_PROPAGATE_DEFAULTS, cq, @@ -87,7 +88,6 @@ static void step_ping_pong_request(void) { grpc_call_unref(call); grpc_byte_buffer_destroy(response_payload_recv); call = nullptr; - GPR_TIMER_END("ping_pong", 1); } static void init_ping_pong_stream(void) { @@ -117,18 +117,17 @@ static void init_ping_pong_stream(void) { } static void step_ping_pong_stream(void) { + GPR_TIMER_SCOPE("ping_pong", 1); grpc_call_error error; - GPR_TIMER_BEGIN("ping_pong", 1); error = grpc_call_start_batch(call, stream_step_ops, 2, (void*)1, nullptr); GPR_ASSERT(GRPC_CALL_OK == error); grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); grpc_byte_buffer_destroy(response_payload_recv); - GPR_TIMER_END("ping_pong", 1); } static double now(void) { gpr_timespec tv = gpr_now(GPR_CLOCK_REALTIME); - return 1e9 * (double)tv.tv_sec + tv.tv_nsec; + return 1e9 * static_cast<double>(tv.tv_sec) + tv.tv_nsec; } typedef struct { @@ -186,15 +185,18 @@ int main(int argc, char** argv) { } if (!sc.name) { fprintf(stderr, "unsupported scenario '%s'. Valid are:", scenario_name); + fflush(stderr); for (i = 0; i < GPR_ARRAY_SIZE(scenarios); i++) { fprintf(stderr, " %s", scenarios[i].name); + fflush(stderr); } return 1; } channel = grpc_insecure_channel_create(target, nullptr, nullptr); cq = grpc_completion_queue_create_for_next(nullptr); - the_buffer = grpc_raw_byte_buffer_create(&slice, (size_t)payload_size); + the_buffer = + grpc_raw_byte_buffer_create(&slice, static_cast<size_t>(payload_size)); histogram = grpc_histogram_create(0.01, 60e9); sc.init(); diff --git a/test/core/fling/fling_stream_test.cc b/test/core/fling/fling_stream_test.cc index b476f2e128..32bc989641 100644 --- a/test/core/fling/fling_stream_test.cc +++ b/test/core/fling/fling_stream_test.cc @@ -20,11 +20,12 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/string_util.h> -#include <grpc/support/subprocess.h> -#include "src/core/lib/support/string.h" + +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" +#include "test/core/util/subprocess.h" int main(int argc, char** argv) { char* me = argv[0]; @@ -36,7 +37,7 @@ int main(int argc, char** argv) { gpr_subprocess *svr, *cli; /* figure out where we are */ if (lslash) { - memcpy(root, me, (size_t)(lslash - me)); + memcpy(root, me, static_cast<size_t>(lslash - me)); root[lslash - me] = 0; } else { strcpy(root, "."); diff --git a/test/core/fling/fling_test.cc b/test/core/fling/fling_test.cc index 0e8b3c1028..3587a4acaa 100644 --- a/test/core/fling/fling_test.cc +++ b/test/core/fling/fling_test.cc @@ -20,11 +20,12 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/string_util.h> -#include <grpc/support/subprocess.h> -#include "src/core/lib/support/string.h" + +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" +#include "test/core/util/subprocess.h" int main(int argc, const char** argv) { const char* me = argv[0]; @@ -36,7 +37,7 @@ int main(int argc, const char** argv) { gpr_subprocess *svr, *cli; /* figure out where we are */ if (lslash) { - memcpy(root, me, (size_t)(lslash - me)); + memcpy(root, me, static_cast<size_t>(lslash - me)); root[lslash - me] = 0; } else { strcpy(root, "."); diff --git a/test/core/fling/server.cc b/test/core/fling/server.cc index f3a8a1ccf8..cf7e2465d9 100644 --- a/test/core/fling/server.cc +++ b/test/core/fling/server.cc @@ -30,12 +30,13 @@ #endif #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/time.h> + +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" #include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/cmdline.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -111,7 +112,8 @@ static void handle_unary_method(void) { op->data.recv_close_on_server.cancelled = &was_cancelled; op++; - error = grpc_call_start_batch(call, unary_ops, (size_t)(op - unary_ops), + error = grpc_call_start_batch(call, unary_ops, + static_cast<size_t>(op - unary_ops), tag(FLING_SERVER_BATCH_OPS_FOR_UNARY), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); } @@ -188,7 +190,7 @@ int main(int argc, char** argv) { grpc_test_init(1, fake_argv); grpc_init(); - srand((unsigned)clock()); + srand(static_cast<unsigned>(clock())); cl = gpr_cmdline_create("fling server"); gpr_cmdline_add_string(cl, "bind", "Bind host:port", &addr); diff --git a/test/core/support/BUILD b/test/core/gpr/BUILD index 4372b49b54..5308ea0934 100644 --- a/test/core/support/BUILD +++ b/test/core/gpr/BUILD @@ -16,7 +16,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_c licenses(["notice"]) # Apache v2 -grpc_package(name = "test/core/support") +grpc_package(name = "test/core/gpr") grpc_cc_test( name = "alloc_test", @@ -29,18 +29,8 @@ grpc_cc_test( ) grpc_cc_test( - name = "avl_test", - srcs = ["avl_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//test/core/util:gpr_test_util", - ], -) - -grpc_cc_test( - name = "cmdline_test", - srcs = ["cmdline_test.cc"], + name = "arena_test", + srcs = ["arena_test.cc"], language = "C++", deps = [ "//:gpr", @@ -119,16 +109,6 @@ grpc_cc_test( ) grpc_cc_test( - name = "manual_constructor_test", - srcs = ["manual_constructor_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//test/core/util:gpr_test_util", - ], -) - -grpc_cc_test( name = "spinlock_test", srcs = ["spinlock_test.cc"], language = "C++", @@ -149,16 +129,6 @@ grpc_cc_test( ) grpc_cc_test( - name = "thd_test", - srcs = ["thd_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//test/core/util:gpr_test_util", - ], -) - -grpc_cc_test( name = "time_test", srcs = ["time_test.cc"], language = "C++", @@ -187,56 +157,3 @@ grpc_cc_test( "//test/core/util:gpr_test_util", ], ) - -grpc_cc_test( - name = "memory_test", - srcs = ["memory_test.cc"], - external_deps = [ - "gtest", - ], - language = "C++", - deps = [ - "//:grpc", - "//test/core/util:gpr_test_util", - ], -) - -grpc_cc_test( - name = "vector_test", - srcs = ["vector_test.cc"], - external_deps = [ - "gtest", - ], - language = "C++", - deps = [ - "//:grpc", - "//test/core/util:gpr_test_util", - ], -) - -grpc_cc_test( - name = "ref_counted_test", - srcs = ["ref_counted_test.cc"], - language = "C++", - deps = [ - "//:ref_counted", - "//test/core/util:gpr_test_util", - ], - external_deps = [ - "gtest", - ], -) - -grpc_cc_test( - name = "ref_counted_ptr_test", - srcs = ["ref_counted_ptr_test.cc"], - language = "C++", - deps = [ - "//:ref_counted", - "//:ref_counted_ptr", - "//test/core/util:gpr_test_util", - ], - external_deps = [ - "gtest", - ], -) diff --git a/test/core/support/alloc_test.cc b/test/core/gpr/alloc_test.cc index 6074c6e6e7..36cdc02ff2 100644 --- a/test/core/support/alloc_test.cc +++ b/test/core/gpr/alloc_test.cc @@ -16,15 +16,20 @@ * */ +#include <string.h> + #include <grpc/support/alloc.h> #include <grpc/support/log.h> + #include "test/core/util/test_config.h" static void* fake_malloc(size_t size) { return (void*)size; } static void* fake_realloc(void* addr, size_t size) { return (void*)size; } -static void fake_free(void* addr) { *((intptr_t*)addr) = (intptr_t)0xdeadd00d; } +static void fake_free(void* addr) { + *(static_cast<intptr_t*>(addr)) = static_cast<intptr_t>(0xdeadd00d); +} static void test_custom_allocs() { const gpr_allocation_functions default_fns = gpr_get_allocation_functions(); @@ -48,8 +53,19 @@ static void test_custom_allocs() { gpr_free(i); } +static void test_malloc_aligned() { + for (size_t size = 1; size <= 256; ++size) { + void* ptr = gpr_malloc_aligned(size, 16); + GPR_ASSERT(ptr != nullptr); + GPR_ASSERT(((intptr_t)ptr & 0xf) == 0); + memset(ptr, 0, size); + gpr_free_aligned(ptr); + } +} + int main(int argc, char** argv) { grpc_test_init(argc, argv); test_custom_allocs(); + test_malloc_aligned(); return 0; } diff --git a/test/core/support/arena_test.cc b/test/core/gpr/arena_test.cc index ada0f43854..3e7c906591 100644 --- a/test/core/support/arena_test.cc +++ b/test/core/gpr/arena_test.cc @@ -16,18 +16,19 @@ * */ -#include "src/core/lib/support/arena.h" +#include "src/core/lib/gpr/arena.h" + +#include <inttypes.h> +#include <string.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/thd.h> -#include <grpc/support/useful.h> -#include <inttypes.h> -#include <string.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" static void test_noop(void) { gpr_arena_destroy(gpr_arena_create(1)); } @@ -53,6 +54,8 @@ static void test(const char* name, size_t init_size, const size_t* allocs, void** ps = static_cast<void**>(gpr_zalloc(sizeof(*ps) * nallocs)); for (size_t i = 0; i < nallocs; i++) { ps[i] = gpr_arena_alloc(a, allocs[i]); + // ensure the returned address is aligned + GPR_ASSERT(((intptr_t)ps[i] & 0xf) == 0); // ensure no duplicate results for (size_t j = 0; j < i; j++) { GPR_ASSERT(ps[i] != ps[j]); @@ -68,7 +71,7 @@ static void test(const char* name, size_t init_size, const size_t* allocs, static const size_t allocs_##name[] = {__VA_ARGS__}; \ test(#name, init_size, allocs_##name, GPR_ARRAY_SIZE(allocs_##name)) -#define CONCURRENT_TEST_THREADS 100 +#define CONCURRENT_TEST_THREADS 10 size_t concurrent_test_iterations() { if (sizeof(void*) < 8) return 1000; @@ -84,7 +87,7 @@ static void concurrent_test_body(void* arg) { concurrent_test_args* a = static_cast<concurrent_test_args*>(arg); gpr_event_wait(&a->ev_start, gpr_inf_future(GPR_CLOCK_REALTIME)); for (size_t i = 0; i < concurrent_test_iterations(); i++) { - *(char*)gpr_arena_alloc(a->arena, 1) = (char)i; + *static_cast<char*>(gpr_arena_alloc(a->arena, 1)) = static_cast<char>(i); } } @@ -95,19 +98,18 @@ static void concurrent_test(void) { gpr_event_init(&args.ev_start); args.arena = gpr_arena_create(1024); - gpr_thd_id thds[CONCURRENT_TEST_THREADS]; + grpc_core::Thread thds[CONCURRENT_TEST_THREADS]; for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) { - gpr_thd_options opt = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&opt); - gpr_thd_new(&thds[i], "grpc_concurrent_test", concurrent_test_body, &args, - &opt); + thds[i] = + grpc_core::Thread("grpc_concurrent_test", concurrent_test_body, &args); + thds[i].Start(); } gpr_event_set(&args.ev_start, (void*)1); - for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) { - gpr_thd_join(thds[i]); + for (auto& th : thds) { + th.Join(); } gpr_arena_destroy(args.arena); diff --git a/test/core/support/cpu_test.cc b/test/core/gpr/cpu_test.cc index 334c4318e1..1052d40b42 100644 --- a/test/core/support/cpu_test.cc +++ b/test/core/gpr/cpu_test.cc @@ -21,14 +21,17 @@ gpr_cpu_current_cpu() */ -#include <grpc/support/alloc.h> #include <grpc/support/cpu.h> + +#include <stdio.h> +#include <string.h> + +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <stdio.h> -#include <string.h> + +#include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" /* Test structure is essentially: @@ -62,7 +65,7 @@ struct cpu_test { }; static void worker_thread(void* arg) { - struct cpu_test* ct = (struct cpu_test*)arg; + struct cpu_test* ct = static_cast<struct cpu_test*>(arg); uint32_t cpu; unsigned r = 12345678; unsigned i, j; @@ -100,32 +103,43 @@ static void cpu_test(void) { uint32_t i; int cores_seen = 0; struct cpu_test ct; - gpr_thd_id thd; ct.ncores = gpr_cpu_num_cores(); GPR_ASSERT(ct.ncores > 0); - ct.nthreads = (int)ct.ncores * 3; + ct.nthreads = static_cast<int>(ct.ncores) * 3; ct.used = static_cast<int*>(gpr_malloc(ct.ncores * sizeof(int))); memset(ct.used, 0, ct.ncores * sizeof(int)); gpr_mu_init(&ct.mu); gpr_cv_init(&ct.done_cv); ct.is_done = 0; - for (i = 0; i < ct.ncores * 3; i++) { - GPR_ASSERT( - gpr_thd_new(&thd, "grpc_cpu_test", &worker_thread, &ct, nullptr)); + + uint32_t nthreads = ct.ncores * 3; + grpc_core::Thread* thd = + static_cast<grpc_core::Thread*>(gpr_malloc(sizeof(*thd) * nthreads)); + + for (i = 0; i < nthreads; i++) { + thd[i] = grpc_core::Thread("grpc_cpu_test", &worker_thread, &ct); + thd[i].Start(); } gpr_mu_lock(&ct.mu); while (!ct.is_done) { gpr_cv_wait(&ct.done_cv, &ct.mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); } gpr_mu_unlock(&ct.mu); + for (i = 0; i < nthreads; i++) { + thd[i].Join(); + } + gpr_free(thd); fprintf(stderr, "Saw cores ["); + fflush(stderr); for (i = 0; i < ct.ncores; i++) { if (ct.used[i]) { fprintf(stderr, "%d,", i); + fflush(stderr); cores_seen++; } } fprintf(stderr, "] (%d/%d)\n", cores_seen, ct.ncores); + fflush(stderr); gpr_free(ct.used); } diff --git a/test/core/support/env_test.cc b/test/core/gpr/env_test.cc index b12c04d06f..3f4b493239 100644 --- a/test/core/support/env_test.cc +++ b/test/core/gpr/env_test.cc @@ -22,8 +22,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" #include "test/core/util/test_config.h" #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/support/host_port_test.cc b/test/core/gpr/host_port_test.cc index 42dd56524f..b5d88b2b01 100644 --- a/test/core/support/host_port_test.cc +++ b/test/core/gpr/host_port_test.cc @@ -19,8 +19,9 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> + +#include "src/core/lib/gpr/host_port.h" #include "test/core/util/test_config.h" static void join_host_port_expect(const char* host, int port, diff --git a/test/core/support/log_test.cc b/test/core/gpr/log_test.cc index 7dba35c13e..839ff0aef9 100644 --- a/test/core/support/log_test.cc +++ b/test/core/gpr/log_test.cc @@ -21,7 +21,7 @@ #include <stdbool.h> #include <string.h> -#include "src/core/lib/support/env.h" +#include "src/core/lib/gpr/env.h" #include "test/core/util/test_config.h" static bool log_func_reached = false; diff --git a/test/core/support/mpscq_test.cc b/test/core/gpr/mpscq_test.cc index 1b83f7d5be..f51bdf8c50 100644 --- a/test/core/support/mpscq_test.cc +++ b/test/core/gpr/mpscq_test.cc @@ -16,15 +16,17 @@ * */ -#include "src/core/lib/support/mpscq.h" +#include "src/core/lib/gpr/mpscq.h" +#include <inttypes.h> #include <stdlib.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" typedef struct test_node { @@ -48,7 +50,7 @@ static void test_serial(void) { gpr_mpscq_push(&q, &new_node(i, nullptr)->node); } for (size_t i = 0; i < 10000000; i++) { - test_node* n = (test_node*)gpr_mpscq_pop(&q); + test_node* n = reinterpret_cast<test_node*>(gpr_mpscq_pop(&q)); GPR_ASSERT(n); GPR_ASSERT(n->i == i); gpr_free(n); @@ -75,18 +77,16 @@ static void test_mt(void) { gpr_log(GPR_DEBUG, "test_mt"); gpr_event start; gpr_event_init(&start); - gpr_thd_id thds[100]; + grpc_core::Thread thds[100]; thd_args ta[GPR_ARRAY_SIZE(thds)]; gpr_mpscq q; gpr_mpscq_init(&q); for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { - gpr_thd_options options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&options); ta[i].ctr = 0; ta[i].q = &q; ta[i].start = &start; - GPR_ASSERT( - gpr_thd_new(&thds[i], "grpc_mt_test", test_thread, &ta[i], &options)); + thds[i] = grpc_core::Thread("grpc_mt_test", test_thread, &ta[i]); + thds[i].Start(); } size_t num_done = 0; size_t spins = 0; @@ -96,15 +96,15 @@ static void test_mt(void) { while ((n = gpr_mpscq_pop(&q)) == nullptr) { spins++; } - test_node* tn = (test_node*)n; + test_node* tn = reinterpret_cast<test_node*>(n); GPR_ASSERT(*tn->ctr == tn->i - 1); *tn->ctr = tn->i; if (tn->i == THREAD_ITERATIONS) num_done++; gpr_free(tn); } gpr_log(GPR_DEBUG, "spins: %" PRIdPTR, spins); - for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { - gpr_thd_join(thds[i]); + for (auto& th : thds) { + th.Join(); } gpr_mpscq_destroy(&q); } @@ -133,7 +133,7 @@ static void pull_thread(void* arg) { while ((n = gpr_mpscq_pop(pa->q)) == nullptr) { pa->spins++; } - test_node* tn = (test_node*)n; + test_node* tn = reinterpret_cast<test_node*>(n); GPR_ASSERT(*tn->ctr == tn->i - 1); *tn->ctr = tn->i; if (tn->i == THREAD_ITERATIONS) pa->num_done++; @@ -146,19 +146,17 @@ static void test_mt_multipop(void) { gpr_log(GPR_DEBUG, "test_mt_multipop"); gpr_event start; gpr_event_init(&start); - gpr_thd_id thds[100]; - gpr_thd_id pull_thds[100]; + grpc_core::Thread thds[50]; + grpc_core::Thread pull_thds[50]; thd_args ta[GPR_ARRAY_SIZE(thds)]; gpr_mpscq q; gpr_mpscq_init(&q); for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { - gpr_thd_options options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&options); ta[i].ctr = 0; ta[i].q = &q; ta[i].start = &start; - GPR_ASSERT(gpr_thd_new(&thds[i], "grpc_multipop_test", test_thread, &ta[i], - &options)); + thds[i] = grpc_core::Thread("grpc_multipop_test", test_thread, &ta[i]); + thds[i].Start(); } pull_args pa; pa.ta = ta; @@ -169,18 +167,16 @@ static void test_mt_multipop(void) { pa.start = &start; gpr_mu_init(&pa.mu); for (size_t i = 0; i < GPR_ARRAY_SIZE(pull_thds); i++) { - gpr_thd_options options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&options); - GPR_ASSERT(gpr_thd_new(&pull_thds[i], "grpc_multipop_pull", pull_thread, - &pa, &options)); + pull_thds[i] = grpc_core::Thread("grpc_multipop_pull", pull_thread, &pa); + pull_thds[i].Start(); } gpr_event_set(&start, (void*)1); - for (size_t i = 0; i < GPR_ARRAY_SIZE(pull_thds); i++) { - gpr_thd_join(pull_thds[i]); + for (auto& pth : pull_thds) { + pth.Join(); } gpr_log(GPR_DEBUG, "spins: %" PRIdPTR, pa.spins); - for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { - gpr_thd_join(thds[i]); + for (auto& th : thds) { + th.Join(); } gpr_mpscq_destroy(&q); } diff --git a/test/core/support/murmur_hash_test.cc b/test/core/gpr/murmur_hash_test.cc index 461c728951..2d2fa72cfb 100644 --- a/test/core/support/murmur_hash_test.cc +++ b/test/core/gpr/murmur_hash_test.cc @@ -16,7 +16,7 @@ * */ -#include "src/core/lib/support/murmur_hash.h" +#include "src/core/lib/gpr/murmur_hash.h" #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include "test/core/util/test_config.h" @@ -42,8 +42,8 @@ static void verification_test(hash_func hash, uint32_t expected) { the seed */ for (i = 0; i < 256; i++) { - key[i] = (uint8_t)i; - hashes[i] = hash(key, i, (uint32_t)(256u - i)); + key[i] = static_cast<uint8_t>(i); + hashes[i] = hash(key, i, static_cast<uint32_t>(256u - i)); } /* Then hash the result array */ diff --git a/test/core/support/spinlock_test.cc b/test/core/gpr/spinlock_test.cc index 58d5fcd42b..0ee72edb15 100644 --- a/test/core/support/spinlock_test.cc +++ b/test/core/gpr/spinlock_test.cc @@ -16,23 +16,26 @@ * */ -/* Test of gpr synchronization support. */ +/* Test of gpr spin-lock support. */ + +#include "src/core/lib/gpr/spinlock.h" + +#include <stdio.h> +#include <stdlib.h> -#include "src/core/lib/support/spinlock.h" #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <stdio.h> -#include <stdlib.h> + +#include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" /* ------------------------------------------------- */ /* Tests for gpr_spinlock. */ struct test { int thread_count; /* number of threads */ - gpr_thd_id* threads; + grpc_core::Thread* threads; int64_t iterations; /* number of iterations per thread */ int64_t counter; @@ -45,8 +48,8 @@ struct test { static struct test* test_new(int threads, int64_t iterations, int incr_step) { struct test* m = static_cast<struct test*>(gpr_malloc(sizeof(*m))); m->thread_count = threads; - m->threads = static_cast<gpr_thd_id*>( - gpr_malloc(sizeof(*m->threads) * (size_t)threads)); + m->threads = static_cast<grpc_core::Thread*>( + gpr_malloc(sizeof(*m->threads) * static_cast<size_t>(threads))); m->iterations = iterations; m->counter = 0; m->thread_count = 0; @@ -65,10 +68,8 @@ static void test_destroy(struct test* m) { static void test_create_threads(struct test* m, void (*body)(void* arg)) { int i; for (i = 0; i != m->thread_count; i++) { - gpr_thd_options opt = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&opt); - GPR_ASSERT( - gpr_thd_new(&m->threads[i], "grpc_create_threads", body, m, &opt)); + m->threads[i] = grpc_core::Thread("grpc_create_threads", body, m); + m->threads[i].Start(); } } @@ -76,7 +77,7 @@ static void test_create_threads(struct test* m, void (*body)(void* arg)) { static void test_wait(struct test* m) { int i; for (i = 0; i != m->thread_count; i++) { - gpr_thd_join(m->threads[i]); + m->threads[i].Join(); } } @@ -93,24 +94,31 @@ static void test(const char* name, void (*body)(void* m), int timeout_s, gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME); gpr_timespec time_taken; gpr_timespec deadline = gpr_time_add( - start, gpr_time_from_micros((int64_t)timeout_s * 1000000, GPR_TIMESPAN)); + start, gpr_time_from_micros(static_cast<int64_t>(timeout_s) * 1000000, + GPR_TIMESPAN)); fprintf(stderr, "%s:", name); + fflush(stderr); while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) { if (iterations < INT64_MAX / 2) iterations <<= 1; - fprintf(stderr, " %ld", (long)iterations); + fprintf(stderr, " %ld", static_cast<long>(iterations)); + fflush(stderr); m = test_new(10, iterations, incr_step); test_create_threads(m, body); test_wait(m); if (m->counter != m->thread_count * m->iterations * m->incr_step) { fprintf(stderr, "counter %ld threads %d iterations %ld\n", - (long)m->counter, m->thread_count, (long)m->iterations); + static_cast<long>(m->counter), m->thread_count, + static_cast<long>(m->iterations)); + fflush(stderr); GPR_ASSERT(0); } test_destroy(m); } time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start); - fprintf(stderr, " done %lld.%09d s\n", (long long)time_taken.tv_sec, - (int)time_taken.tv_nsec); + fprintf(stderr, " done %lld.%09d s\n", + static_cast<long long>(time_taken.tv_sec), + static_cast<int>(time_taken.tv_nsec)); + fflush(stderr); } /* Increment m->counter on each iteration; then mark thread as done. */ diff --git a/test/core/support/string_test.cc b/test/core/gpr/string_test.cc index fd7f7cde59..9f3b312465 100644 --- a/test/core/support/string_test.cc +++ b/test/core/gpr/string_test.cc @@ -16,7 +16,7 @@ * */ -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include <limits.h> #include <stddef.h> @@ -26,7 +26,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> + #include "test/core/util/test_config.h" #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/support/sync_test.cc b/test/core/gpr/sync_test.cc index fb7ec44754..24b4562819 100644 --- a/test/core/support/sync_test.cc +++ b/test/core/gpr/sync_test.cc @@ -18,13 +18,16 @@ /* Test of gpr synchronization support. */ -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/time.h> + #include <stdio.h> #include <stdlib.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> + +#include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" /* ==================Example use of interface=================== @@ -132,7 +135,8 @@ int queue_remove(queue* q, int* head, gpr_timespec abs_deadline) { /* ------------------------------------------------- */ /* Tests for gpr_mu and gpr_cv, and the queue example. */ struct test { - int threads; /* number of threads */ + int nthreads; /* number of threads */ + grpc_core::Thread* threads; int64_t iterations; /* number of iterations per thread */ int64_t counter; @@ -156,13 +160,15 @@ struct test { }; /* Return pointer to a new struct test. */ -static struct test* test_new(int threads, int64_t iterations, int incr_step) { +static struct test* test_new(int nthreads, int64_t iterations, int incr_step) { struct test* m = static_cast<struct test*>(gpr_malloc(sizeof(*m))); - m->threads = threads; + m->nthreads = nthreads; + m->threads = static_cast<grpc_core::Thread*>( + gpr_malloc(sizeof(*m->threads) * nthreads)); m->iterations = iterations; m->counter = 0; m->thread_count = 0; - m->done = threads; + m->done = nthreads; m->incr_step = incr_step; gpr_mu_init(&m->mu); gpr_cv_init(&m->cv); @@ -170,7 +176,7 @@ static struct test* test_new(int threads, int64_t iterations, int incr_step) { queue_init(&m->q); gpr_stats_init(&m->stats_counter, 0); gpr_ref_init(&m->refcount, 0); - gpr_ref_init(&m->thread_refcount, threads); + gpr_ref_init(&m->thread_refcount, nthreads); gpr_event_init(&m->event); return m; } @@ -181,15 +187,16 @@ static void test_destroy(struct test* m) { gpr_cv_destroy(&m->cv); gpr_cv_destroy(&m->done_cv); queue_destroy(&m->q); + gpr_free(m->threads); gpr_free(m); } -/* Create m->threads threads, each running (*body)(m) */ +/* Create m->nthreads threads, each running (*body)(m) */ static void test_create_threads(struct test* m, void (*body)(void* arg)) { - gpr_thd_id id; int i; - for (i = 0; i != m->threads; i++) { - GPR_ASSERT(gpr_thd_new(&id, "grpc_create_threads", body, m, nullptr)); + for (i = 0; i != m->nthreads; i++) { + m->threads[i] = grpc_core::Thread("grpc_create_threads", body, m); + m->threads[i].Start(); } } @@ -200,9 +207,12 @@ static void test_wait(struct test* m) { gpr_cv_wait(&m->done_cv, &m->mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); } gpr_mu_unlock(&m->mu); + for (int i = 0; i != m->nthreads; i++) { + m->threads[i].Join(); + } } -/* Get an integer thread id in the raneg 0..threads-1 */ +/* Get an integer thread id in the raneg 0..nthreads-1 */ static int thread_id(struct test* m) { int id; gpr_mu_lock(&m->mu); @@ -231,34 +241,45 @@ static void mark_thread_done(struct test* m) { */ static void test(const char* name, void (*body)(void* m), void (*extra)(void* m), int timeout_s, int incr_step) { - int64_t iterations = 1024; + int64_t iterations = 256; struct test* m; gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME); gpr_timespec time_taken; gpr_timespec deadline = gpr_time_add( - start, gpr_time_from_micros((int64_t)timeout_s * 1000000, GPR_TIMESPAN)); + start, gpr_time_from_micros(static_cast<int64_t>(timeout_s) * 1000000, + GPR_TIMESPAN)); fprintf(stderr, "%s:", name); + fflush(stderr); while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) { - iterations <<= 1; - fprintf(stderr, " %ld", (long)iterations); + fprintf(stderr, " %ld", static_cast<long>(iterations)); + fflush(stderr); m = test_new(10, iterations, incr_step); + grpc_core::Thread extra_thd; if (extra != nullptr) { - gpr_thd_id id; - GPR_ASSERT(gpr_thd_new(&id, name, extra, m, nullptr)); + extra_thd = grpc_core::Thread(name, extra, m); + extra_thd.Start(); m->done++; /* one more thread to wait for */ } test_create_threads(m, body); test_wait(m); - if (m->counter != m->threads * m->iterations * m->incr_step) { + if (extra != nullptr) { + extra_thd.Join(); + } + if (m->counter != m->nthreads * m->iterations * m->incr_step) { fprintf(stderr, "counter %ld threads %d iterations %ld\n", - (long)m->counter, m->threads, (long)m->iterations); + static_cast<long>(m->counter), m->nthreads, + static_cast<long>(m->iterations)); + fflush(stderr); GPR_ASSERT(0); } test_destroy(m); + iterations <<= 1; } time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start); - fprintf(stderr, " done %lld.%09d s\n", (long long)time_taken.tv_sec, - (int)time_taken.tv_nsec); + fprintf(stderr, " done %lld.%09d s\n", + static_cast<long long>(time_taken.tv_sec), + static_cast<int>(time_taken.tv_nsec)); + fflush(stderr); } /* Increment m->counter on each iteration; then mark thread as done. */ @@ -288,7 +309,7 @@ static void inctry(void* v /*=m*/) { mark_thread_done(m); } -/* Increment counter only when (m->counter%m->threads)==m->thread_id; then mark +/* Increment counter only when (m->counter%m->nthreads)==m->thread_id; then mark thread as done. */ static void inc_by_turns(void* v /*=m*/) { struct test* m = static_cast<struct test*>(v); @@ -296,7 +317,7 @@ static void inc_by_turns(void* v /*=m*/) { int id = thread_id(m); for (i = 0; i != m->iterations; i++) { gpr_mu_lock(&m->mu); - while ((m->counter % m->threads) != id) { + while ((m->counter % m->nthreads) != id) { gpr_cv_wait(&m->cv, &m->mu, gpr_inf_future(GPR_CLOCK_MONOTONIC)); } m->counter++; @@ -361,12 +382,12 @@ static void many_producers(void* v /*=m*/) { mark_thread_done(m); } -/* Consume elements from m->q until m->threads*m->iterations are seen, +/* Consume elements from m->q until m->nthreads*m->iterations are seen, wait an extra second to confirm that no more elements are arriving, then mark thread as done. */ static void consumer(void* v /*=m*/) { struct test* m = static_cast<struct test*>(v); - int64_t n = m->iterations * m->threads; + int64_t n = m->iterations * m->nthreads; int64_t i; int value; for (i = 0; i != n; i++) { @@ -416,11 +437,11 @@ static void refinc(void* v /*=m*/) { } /* Wait until m->event is set to (void *)1, then decrement m->refcount by 1 - (m->threads * m->iterations * m->incr_step) times, and ensure that the last + (m->nthreads * m->iterations * m->incr_step) times, and ensure that the last decrement caused the counter to reach zero, then mark thread as done. */ static void refcheck(void* v /*=m*/) { struct test* m = static_cast<struct test*>(v); - int64_t n = m->iterations * m->threads * m->incr_step; + int64_t n = m->iterations * m->nthreads * m->incr_step; int64_t i; GPR_ASSERT(gpr_event_wait(&m->event, gpr_inf_future(GPR_CLOCK_REALTIME)) == (void*)1); diff --git a/test/core/support/time_test.cc b/test/core/gpr/time_test.cc index 608169274f..6f070f58df 100644 --- a/test/core/support/time_test.cc +++ b/test/core/gpr/time_test.cc @@ -20,16 +20,17 @@ #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> +#include <inttypes.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> + #include "test/core/util/test_config.h" static void to_fp(void* arg, const char* buf, size_t len) { - fwrite(buf, 1, len, (FILE*)arg); + fwrite(buf, 1, len, static_cast<FILE*>(arg)); } /* Convert gpr_intmax x to ascii base b (2..16), and write with @@ -66,21 +67,28 @@ static void test_values(void) { x = gpr_inf_future(GPR_CLOCK_REALTIME); fprintf(stderr, "far future "); + fflush(stderr); i_to_s(x.tv_sec, 16, 16, &to_fp, stderr); fprintf(stderr, "\n"); GPR_ASSERT(x.tv_sec == INT64_MAX); fprintf(stderr, "far future "); + fflush(stderr); ts_to_s(x, &to_fp, stderr); fprintf(stderr, "\n"); + fflush(stderr); x = gpr_inf_past(GPR_CLOCK_REALTIME); fprintf(stderr, "far past "); + fflush(stderr); i_to_s(x.tv_sec, 16, 16, &to_fp, stderr); fprintf(stderr, "\n"); + fflush(stderr); GPR_ASSERT(x.tv_sec == INT64_MIN); fprintf(stderr, "far past "); + fflush(stderr); ts_to_s(x, &to_fp, stderr); fprintf(stderr, "\n"); + fflush(stderr); for (i = 1; i != 1000 * 1000 * 1000; i *= 10) { x = gpr_time_from_micros(i, GPR_TIMESPAN); @@ -135,15 +143,19 @@ static void test_add_sub(void) { if (gpr_time_cmp(gpr_time_from_micros(sum * k, GPR_TIMESPAN), sumt) != 0) { fprintf(stderr, "i %d j %d sum %d sumt ", i, j, sum); + fflush(stderr); ts_to_s(sumt, &to_fp, stderr); fprintf(stderr, "\n"); + fflush(stderr); GPR_ASSERT(0); } if (gpr_time_cmp(gpr_time_from_micros(diff * k, GPR_TIMESPAN), difft) != 0) { fprintf(stderr, "i %d j %d diff %d diff ", i, j, diff); + fflush(stderr); ts_to_s(sumt, &to_fp, stderr); fprintf(stderr, "\n"); + fflush(stderr); GPR_ASSERT(0); } } diff --git a/test/core/support/tls_test.cc b/test/core/gpr/tls_test.cc index 743b10f090..0502fc7ef4 100644 --- a/test/core/support/tls_test.cc +++ b/test/core/gpr/tls_test.cc @@ -18,12 +18,15 @@ /* Test of gpr thread local storage support. */ -#include <grpc/support/log.h> -#include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/tls.h> +#include "src/core/lib/gpr/tls.h" + #include <stdio.h> #include <stdlib.h> + +#include <grpc/support/log.h> +#include <grpc/support/sync.h> + +#include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" #define NUM_THREADS 100 @@ -45,21 +48,18 @@ static void thd_body(void* arg) { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - gpr_thd_options opt = gpr_thd_options_default(); - int i; - gpr_thd_id threads[NUM_THREADS]; + grpc_core::Thread threads[NUM_THREADS]; grpc_test_init(argc, argv); gpr_tls_init(&test_var); - gpr_thd_options_set_joinable(&opt); - - for (i = 0; i < NUM_THREADS; i++) { - gpr_thd_new(&threads[i], "grpc_tls_test", thd_body, nullptr, &opt); + for (auto& th : threads) { + th = grpc_core::Thread("grpc_tls_test", thd_body, nullptr); + th.Start(); } - for (i = 0; i < NUM_THREADS; i++) { - gpr_thd_join(threads[i]); + for (auto& th : threads) { + th.Join(); } gpr_tls_destroy(&test_var); diff --git a/test/core/support/useful_test.cc b/test/core/gpr/useful_test.cc index 2f86010d77..619c800c4d 100644 --- a/test/core/support/useful_test.cc +++ b/test/core/gpr/useful_test.cc @@ -18,7 +18,8 @@ #include <grpc/support/log.h> #include <grpc/support/port_platform.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "test/core/util/test_config.h" int main(int argc, char** argv) { diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD new file mode 100644 index 0000000000..e7232d9df8 --- /dev/null +++ b/test/core/gprpp/BUILD @@ -0,0 +1,115 @@ +# 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. + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package") + +licenses(["notice"]) # Apache v2 + +grpc_package(name = "test/core/gprpp") + +grpc_cc_test( + name = "fork_test", + srcs = ["fork_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:gpr_test_util", + ], +) + +grpc_cc_test( + name = "manual_constructor_test", + srcs = ["manual_constructor_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:gpr_test_util", + ], +) + +grpc_cc_test( + name = "memory_test", + srcs = ["memory_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr_base", + "//test/core/util:gpr_test_util", + ], +) + +grpc_cc_test( + name = "inlined_vector_test", + srcs = ["inlined_vector_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:inlined_vector", + "//test/core/util:gpr_test_util", + ], +) + +grpc_cc_test( + name = "orphanable_test", + srcs = ["orphanable_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:orphanable", + "//test/core/util:gpr_test_util", + ], +) + +grpc_cc_test( + name = "ref_counted_test", + srcs = ["ref_counted_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:ref_counted", + "//test/core/util:gpr_test_util", + ], +) + +grpc_cc_test( + name = "ref_counted_ptr_test", + srcs = ["ref_counted_ptr_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:ref_counted", + "//:ref_counted_ptr", + "//test/core/util:gpr_test_util", + ], +) + +grpc_cc_test( + name = "thd_test", + srcs = ["thd_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:gpr_test_util", + ], +) diff --git a/test/core/gprpp/fork_test.cc b/test/core/gprpp/fork_test.cc new file mode 100644 index 0000000000..642f910489 --- /dev/null +++ b/test/core/gprpp/fork_test.cc @@ -0,0 +1,139 @@ +/* + * + * 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 "src/core/lib/gprpp/fork.h" + +#include "src/core/lib/gprpp/thd.h" +#include "test/core/util/test_config.h" + +static void test_init() { + GPR_ASSERT(!grpc_core::Fork::Enabled()); + + // Default fork support (disabled) + grpc_core::Fork::GlobalInit(); + GPR_ASSERT(!grpc_core::Fork::Enabled()); + grpc_core::Fork::GlobalShutdown(); + + // Explicitly disabled fork support + grpc_core::Fork::Enable(false); + grpc_core::Fork::GlobalInit(); + GPR_ASSERT(!grpc_core::Fork::Enabled()); + grpc_core::Fork::GlobalShutdown(); + + // Explicitly enabled fork support + grpc_core::Fork::Enable(true); + grpc_core::Fork::GlobalInit(); + GPR_ASSERT(grpc_core::Fork::Enabled()); + grpc_core::Fork::GlobalShutdown(); +} + +// This spawns CONCURRENT_TEST_THREADS that last up to +// THREAD_DELAY_MS, and checks that the Fork::AwaitThreads() +// returns roughly after THREAD_DELAY_MS. The epsilon is high +// because tsan threads can take a while to spawn/join. +#define THREAD_DELAY_MS 6000 +#define THREAD_DELAY_EPSILON 1500 +#define CONCURRENT_TEST_THREADS 100 + +static void sleeping_thd(void* arg) { + int64_t sleep_ms = (int64_t)arg; + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(sleep_ms, GPR_TIMESPAN))); +} + +static void test_thd_count() { + // Test no active threads + grpc_core::Fork::Enable(true); + grpc_core::Fork::GlobalInit(); + grpc_core::Fork::AwaitThreads(); + grpc_core::Fork::GlobalShutdown(); + + grpc_core::Fork::Enable(true); + grpc_core::Fork::GlobalInit(); + grpc_core::Thread thds[CONCURRENT_TEST_THREADS]; + gpr_timespec est_end_time = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(THREAD_DELAY_MS, GPR_TIMESPAN)); + gpr_timespec tolerance = + gpr_time_from_millis(THREAD_DELAY_EPSILON, GPR_TIMESPAN); + for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) { + intptr_t sleep_time_ms = + (i * THREAD_DELAY_MS) / (CONCURRENT_TEST_THREADS - 1); + thds[i] = + grpc_core::Thread("grpc_fork_test", sleeping_thd, (void*)sleep_time_ms); + thds[i].Start(); + } + grpc_core::Fork::AwaitThreads(); + gpr_timespec end_time = gpr_now(GPR_CLOCK_REALTIME); + for (auto& thd : thds) { + thd.Join(); + } + GPR_ASSERT(gpr_time_similar(end_time, est_end_time, tolerance)); + grpc_core::Fork::GlobalShutdown(); +} + +static void exec_ctx_thread(void* arg) { + bool* exec_ctx_created = (bool*)arg; + grpc_core::Fork::IncExecCtxCount(); + *exec_ctx_created = true; +} + +static void test_exec_count() { + grpc_core::Fork::Enable(true); + grpc_core::Fork::GlobalInit(); + + grpc_core::Fork::IncExecCtxCount(); + GPR_ASSERT(grpc_core::Fork::BlockExecCtx()); + grpc_core::Fork::DecExecCtxCount(); + grpc_core::Fork::AllowExecCtx(); + + grpc_core::Fork::IncExecCtxCount(); + grpc_core::Fork::IncExecCtxCount(); + GPR_ASSERT(!grpc_core::Fork::BlockExecCtx()); + grpc_core::Fork::DecExecCtxCount(); + grpc_core::Fork::DecExecCtxCount(); + + grpc_core::Fork::IncExecCtxCount(); + GPR_ASSERT(grpc_core::Fork::BlockExecCtx()); + grpc_core::Fork::DecExecCtxCount(); + grpc_core::Fork::AllowExecCtx(); + + // Test that block_exec_ctx() blocks grpc_core::Fork::IncExecCtxCount + bool exec_ctx_created = false; + grpc_core::Thread thd = + grpc_core::Thread("grpc_fork_test", exec_ctx_thread, &exec_ctx_created); + grpc_core::Fork::IncExecCtxCount(); + GPR_ASSERT(grpc_core::Fork::BlockExecCtx()); + grpc_core::Fork::DecExecCtxCount(); + thd.Start(); + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(1, GPR_TIMESPAN))); + GPR_ASSERT(!exec_ctx_created); + grpc_core::Fork::AllowExecCtx(); + thd.Join(); // This ensure that the call got un-blocked + grpc_core::Fork::GlobalShutdown(); +} + +int main(int argc, char* argv[]) { + grpc_test_init(argc, argv); + test_init(); + test_thd_count(); + test_exec_count(); + + return 0; +} diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc new file mode 100644 index 0000000000..ae34947718 --- /dev/null +++ b/test/core/gprpp/inlined_vector_test.cc @@ -0,0 +1,116 @@ +/* + * + * 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 "src/core/lib/gprpp/inlined_vector.h" +#include <gtest/gtest.h> +#include "src/core/lib/gprpp/memory.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { + +TEST(InlinedVectorTest, CreateAndIterate) { + const int kNumElements = 9; + InlinedVector<int, 2> v; + for (int i = 0; i < kNumElements; ++i) { + v.push_back(i); + } + EXPECT_EQ(static_cast<size_t>(kNumElements), v.size()); + for (int i = 0; i < kNumElements; ++i) { + EXPECT_EQ(i, v[i]); + EXPECT_EQ(i, &v[i] - &v[0]); // Ensure contiguous allocation. + } +} + +TEST(InlinedVectorTest, ValuesAreInlined) { + const int kNumElements = 5; + InlinedVector<int, 10> v; + for (int i = 0; i < kNumElements; ++i) { + v.push_back(i); + } + EXPECT_EQ(static_cast<size_t>(kNumElements), v.size()); + for (int i = 0; i < kNumElements; ++i) { + EXPECT_EQ(i, v[i]); + } +} + +TEST(InlinedVectorTest, PushBackWithMove) { + InlinedVector<UniquePtr<int>, 1> v; + UniquePtr<int> i = MakeUnique<int>(3); + v.push_back(std::move(i)); + EXPECT_EQ(nullptr, i.get()); + EXPECT_EQ(1UL, v.size()); + EXPECT_EQ(3, *v[0]); +} + +TEST(InlinedVectorTest, EmplaceBack) { + InlinedVector<UniquePtr<int>, 1> v; + v.emplace_back(New<int>(3)); + EXPECT_EQ(1UL, v.size()); + EXPECT_EQ(3, *v[0]); +} + +TEST(InlinedVectorTest, ClearAndRepopulate) { + const int kNumElements = 10; + InlinedVector<int, 5> v; + EXPECT_EQ(0UL, v.size()); + for (int i = 0; i < kNumElements; ++i) { + v.push_back(i); + EXPECT_EQ(i + 1UL, v.size()); + } + for (int i = 0; i < kNumElements; ++i) { + EXPECT_EQ(i, v[i]); + } + v.clear(); + EXPECT_EQ(0UL, v.size()); + for (int i = 0; i < kNumElements; ++i) { + v.push_back(kNumElements + i); + EXPECT_EQ(i + 1UL, v.size()); + } + for (int i = 0; i < kNumElements; ++i) { + EXPECT_EQ(kNumElements + i, v[i]); + } +} + +TEST(InlinedVectorTest, ConstIndexOperator) { + constexpr int kNumElements = 10; + InlinedVector<int, 5> v; + EXPECT_EQ(0UL, v.size()); + for (int i = 0; i < kNumElements; ++i) { + v.push_back(i); + EXPECT_EQ(i + 1UL, v.size()); + } + // The following lambda function is exceptionally allowed to use an anonymous + // capture due to the erroneous behavior of the MSVC compiler, that refuses to + // capture the kNumElements constexpr, something allowed by the standard. + auto const_func = [&](const InlinedVector<int, 5>& v) { + for (int i = 0; i < kNumElements; ++i) { + EXPECT_EQ(i, v[i]); + } + }; + const_func(v); +} + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/support/manual_constructor_test.cc b/test/core/gprpp/manual_constructor_test.cc index 714f8b21a0..af162ae8e8 100644 --- a/test/core/support/manual_constructor_test.cc +++ b/test/core/gprpp/manual_constructor_test.cc @@ -18,15 +18,15 @@ /* Test of gpr synchronization support. */ -#include "src/core/lib/support/manual_constructor.h" +#include "src/core/lib/gprpp/manual_constructor.h" #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <stdio.h> #include <stdlib.h> #include <cstring> -#include "src/core/lib/support/abstract.h" + +#include "src/core/lib/gprpp/abstract.h" #include "test/core/util/test_config.h" class A { diff --git a/test/core/support/memory_test.cc b/test/core/gprpp/memory_test.cc index 79ab631a78..180c36fad7 100644 --- a/test/core/support/memory_test.cc +++ b/test/core/gprpp/memory_test.cc @@ -16,7 +16,7 @@ * */ -#include "src/core/lib/support/memory.h" +#include "src/core/lib/gprpp/memory.h" #include <gtest/gtest.h> #include "test/core/util/test_config.h" diff --git a/test/core/gprpp/orphanable_test.cc b/test/core/gprpp/orphanable_test.cc new file mode 100644 index 0000000000..ad6b9ac867 --- /dev/null +++ b/test/core/gprpp/orphanable_test.cc @@ -0,0 +1,120 @@ +/* + * + * 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 "src/core/lib/gprpp/orphanable.h" + +#include <gtest/gtest.h> + +#include "src/core/lib/gprpp/memory.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { +namespace { + +class Foo : public Orphanable { + public: + Foo() : Foo(0) {} + explicit Foo(int value) : value_(value) {} + void Orphan() override { Delete(this); } + int value() const { return value_; } + + private: + int value_; +}; + +TEST(Orphanable, Basic) { + Foo* foo = New<Foo>(); + foo->Orphan(); +} + +TEST(OrphanablePtr, Basic) { + OrphanablePtr<Foo> foo(New<Foo>()); + EXPECT_EQ(0, foo->value()); +} + +TEST(MakeOrphanable, DefaultConstructor) { + auto foo = MakeOrphanable<Foo>(); + EXPECT_EQ(0, foo->value()); +} + +TEST(MakeOrphanable, WithParameters) { + auto foo = MakeOrphanable<Foo>(5); + EXPECT_EQ(5, foo->value()); +} + +class Bar : public InternallyRefCounted<Bar> { + public: + Bar() : Bar(0) {} + explicit Bar(int value) : value_(value) {} + void Orphan() override { Unref(); } + int value() const { return value_; } + + void StartWork() { self_ref_ = Ref(); } + void FinishWork() { self_ref_.reset(); } + + private: + int value_; + RefCountedPtr<Bar> self_ref_; +}; + +TEST(OrphanablePtr, InternallyRefCounted) { + auto bar = MakeOrphanable<Bar>(); + bar->StartWork(); + bar->FinishWork(); +} + +// Note: We use DebugOnlyTraceFlag instead of TraceFlag to ensure that +// things build properly in both debug and non-debug cases. +DebugOnlyTraceFlag baz_tracer(true, "baz"); + +class Baz : public InternallyRefCountedWithTracing<Baz> { + public: + Baz() : Baz(0) {} + explicit Baz(int value) + : InternallyRefCountedWithTracing<Baz>(&baz_tracer), value_(value) {} + void Orphan() override { Unref(); } + int value() const { return value_; } + + void StartWork() { self_ref_ = Ref(DEBUG_LOCATION, "work"); } + void FinishWork() { + // This is a little ugly, but it makes the logged ref and unref match up. + self_ref_.release(); + Unref(DEBUG_LOCATION, "work"); + } + + private: + int value_; + RefCountedPtr<Baz> self_ref_; +}; + +TEST(OrphanablePtr, InternallyRefCountedWithTracing) { + auto baz = MakeOrphanable<Baz>(); + baz->StartWork(); + baz->FinishWork(); +} + +} // namespace +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/support/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc index 1830edc4e5..c810345166 100644 --- a/test/core/support/ref_counted_ptr_test.cc +++ b/test/core/gprpp/ref_counted_ptr_test.cc @@ -16,21 +16,21 @@ * */ -#include "src/core/lib/support/ref_counted_ptr.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include <gtest/gtest.h> #include <grpc/support/log.h> -#include "src/core/lib/support/memory.h" -#include "src/core/lib/support/ref_counted.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "test/core/util/test_config.h" namespace grpc_core { namespace testing { namespace { -class Foo : public RefCounted { +class Foo : public RefCounted<Foo> { public: Foo() : value_(0) {} @@ -88,7 +88,7 @@ TEST(RefCountedPtr, CopyAssignmentWhenEmpty) { TEST(RefCountedPtr, CopyAssignmentToSelf) { RefCountedPtr<Foo> foo(New<Foo>()); - foo = foo; + foo = *&foo; // The "*&" avoids warnings from LLVM -Wself-assign. } TEST(RefCountedPtr, EnclosedScope) { @@ -138,6 +138,19 @@ TEST(RefCountedPtr, DerefernceOperators) { foo_ref.value(); } +TEST(RefCountedPtr, EqualityOperators) { + RefCountedPtr<Foo> foo(New<Foo>()); + RefCountedPtr<Foo> bar = foo; + RefCountedPtr<Foo> empty; + // Test equality between RefCountedPtrs. + EXPECT_EQ(foo, bar); + EXPECT_NE(foo, empty); + // Test equality with bare pointers. + EXPECT_EQ(foo, foo.get()); + EXPECT_EQ(empty, nullptr); + EXPECT_NE(foo, nullptr); +} + TEST(MakeRefCounted, NoArgs) { RefCountedPtr<Foo> foo = MakeRefCounted<Foo>(); EXPECT_EQ(0, foo->value()); @@ -150,14 +163,15 @@ TEST(MakeRefCounted, Args) { TraceFlag foo_tracer(true, "foo"); -class FooWithTracing : public RefCountedWithTracing { +class FooWithTracing : public RefCountedWithTracing<FooWithTracing> { public: FooWithTracing() : RefCountedWithTracing(&foo_tracer) {} }; TEST(RefCountedPtr, RefCountedWithTracing) { RefCountedPtr<FooWithTracing> foo(New<FooWithTracing>()); - foo->Ref(DEBUG_LOCATION, "foo"); + RefCountedPtr<FooWithTracing> foo2 = foo->Ref(DEBUG_LOCATION, "foo"); + foo2.release(); foo->Unref(DEBUG_LOCATION, "foo"); } diff --git a/test/core/support/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc index be9b6ff7c2..f85a2e4675 100644 --- a/test/core/support/ref_counted_test.cc +++ b/test/core/gprpp/ref_counted_test.cc @@ -16,18 +16,18 @@ * */ -#include "src/core/lib/support/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted.h" #include <gtest/gtest.h> -#include "src/core/lib/support/memory.h" +#include "src/core/lib/gprpp/memory.h" #include "test/core/util/test_config.h" namespace grpc_core { namespace testing { namespace { -class Foo : public RefCounted { +class Foo : public RefCounted<Foo> { public: Foo() {} }; @@ -39,24 +39,29 @@ TEST(RefCounted, Basic) { TEST(RefCounted, ExtraRef) { Foo* foo = New<Foo>(); - foo->Ref(); + RefCountedPtr<Foo> foop = foo->Ref(); + foop.release(); foo->Unref(); foo->Unref(); } -TraceFlag foo_tracer(true, "foo"); +// Note: We use DebugOnlyTraceFlag instead of TraceFlag to ensure that +// things build properly in both debug and non-debug cases. +DebugOnlyTraceFlag foo_tracer(true, "foo"); -class FooWithTracing : public RefCountedWithTracing { +class FooWithTracing : public RefCountedWithTracing<FooWithTracing> { public: FooWithTracing() : RefCountedWithTracing(&foo_tracer) {} }; TEST(RefCountedWithTracing, Basic) { FooWithTracing* foo = New<FooWithTracing>(); - foo->Ref(DEBUG_LOCATION, "extra_ref"); + RefCountedPtr<FooWithTracing> foop = foo->Ref(DEBUG_LOCATION, "extra_ref"); + foop.release(); foo->Unref(DEBUG_LOCATION, "extra_ref"); // Can use the no-argument methods, too. - foo->Ref(); + foop = foo->Ref(); + foop.release(); foo->Unref(); foo->Unref(DEBUG_LOCATION, "original_ref"); } diff --git a/test/core/support/thd_test.cc b/test/core/gprpp/thd_test.cc index b755bf18f3..82dd681049 100644 --- a/test/core/support/thd_test.cc +++ b/test/core/gprpp/thd_test.cc @@ -18,15 +18,18 @@ /* Test of gpr thread support. */ +#include "src/core/lib/gprpp/thd.h" + +#include <stdio.h> +#include <stdlib.h> + #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <stdio.h> -#include <stdlib.h> + #include "test/core/util/test_config.h" -#define NUM_THREADS 300 +#define NUM_THREADS 100 struct test { gpr_mu mu; @@ -36,7 +39,7 @@ struct test { }; /* A Thread body. Decrement t->n, and if is becomes zero, set t->done. */ -static void thd_body(void* v) { +static void thd_body1(void* v) { struct test* t = static_cast<struct test*>(v); gpr_mu_lock(&t->mu); t->n--; @@ -47,48 +50,42 @@ static void thd_body(void* v) { gpr_mu_unlock(&t->mu); } -static void thd_body_joinable(void* v) {} - -/* Test thread options work as expected */ -static void test_options(void) { - gpr_thd_options options = gpr_thd_options_default(); - GPR_ASSERT(!gpr_thd_options_is_joinable(&options)); - GPR_ASSERT(gpr_thd_options_is_detached(&options)); - gpr_thd_options_set_joinable(&options); - GPR_ASSERT(gpr_thd_options_is_joinable(&options)); - GPR_ASSERT(!gpr_thd_options_is_detached(&options)); - gpr_thd_options_set_detached(&options); - GPR_ASSERT(!gpr_thd_options_is_joinable(&options)); - GPR_ASSERT(gpr_thd_options_is_detached(&options)); -} - -/* Test that we can create a number of threads and wait for them. */ -static void test(void) { - int i; - gpr_thd_id thd; - gpr_thd_id thds[NUM_THREADS]; +/* Test that we can create a number of threads, wait for them, and join them. */ +static void test1(void) { + grpc_core::Thread thds[NUM_THREADS]; struct test t; - gpr_thd_options options = gpr_thd_options_default(); gpr_mu_init(&t.mu); gpr_cv_init(&t.done_cv); t.n = NUM_THREADS; t.is_done = 0; - for (i = 0; i < NUM_THREADS; i++) { - GPR_ASSERT(gpr_thd_new(&thd, "grpc_thread_test", &thd_body, &t, nullptr)); + for (auto& th : thds) { + th = grpc_core::Thread("grpc_thread_body1_test", &thd_body1, &t); + th.Start(); } gpr_mu_lock(&t.mu); while (!t.is_done) { gpr_cv_wait(&t.done_cv, &t.mu, gpr_inf_future(GPR_CLOCK_REALTIME)); } gpr_mu_unlock(&t.mu); + for (auto& th : thds) { + th.Join(); + } GPR_ASSERT(t.n == 0); - gpr_thd_options_set_joinable(&options); - for (i = 0; i < NUM_THREADS; i++) { - GPR_ASSERT(gpr_thd_new(&thds[i], "grpc_joinable_thread_test", - &thd_body_joinable, nullptr, &options)); +} + +static void thd_body2(void* v) {} + +/* Test that we can create a number of threads and join them. */ +static void test2(void) { + grpc_core::Thread thds[NUM_THREADS]; + for (auto& th : thds) { + bool ok; + th = grpc_core::Thread("grpc_thread_body2_test", &thd_body2, nullptr, &ok); + GPR_ASSERT(ok); + th.Start(); } - for (i = 0; i < NUM_THREADS; i++) { - gpr_thd_join(thds[i]); + for (auto& th : thds) { + th.Join(); } } @@ -96,7 +93,7 @@ static void test(void) { int main(int argc, char* argv[]) { grpc_test_init(argc, argv); - test_options(); - test(); + test1(); + test2(); return 0; } diff --git a/test/core/handshake/client_ssl.cc b/test/core/handshake/client_ssl.cc index 2302e3da2f..8ac763ac4b 100644 --- a/test/core/handshake/client_ssl.cc +++ b/test/core/handshake/client_ssl.cc @@ -34,7 +34,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/thd.h> + +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/load_file.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -68,7 +69,7 @@ static int create_socket(int* out_port) { return -1; } - if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + if (bind(s, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) < 0) { perror("Unable to bind"); gpr_log(GPR_ERROR, "%s", "Unable to bind to any port"); close(s); @@ -82,7 +83,8 @@ static int create_socket(int* out_port) { } addr_len = sizeof(addr); - if (getsockname(s, (struct sockaddr*)&addr, &addr_len) != 0 || + if (getsockname(s, reinterpret_cast<struct sockaddr*>(&addr), &addr_len) != + 0 || addr_len > sizeof(addr)) { perror("getsockname"); gpr_log(GPR_ERROR, "%s", "Unable to get socket local address"); @@ -98,19 +100,19 @@ static int create_socket(int* out_port) { // SSL_CTX_set_alpn_select_cb. static int alpn_select_cb(SSL* ssl, const uint8_t** out, uint8_t* out_len, const uint8_t* in, unsigned in_len, void* arg) { - const uint8_t* alpn_preferred = (const uint8_t*)arg; + const uint8_t* alpn_preferred = static_cast<const uint8_t*>(arg); *out = alpn_preferred; - *out_len = (uint8_t)strlen((char*)alpn_preferred); + *out_len = static_cast<uint8_t>(strlen((char*)alpn_preferred)); // Validate that the ALPN list includes "h2" and "grpc-exp", that "grpc-exp" // precedes "h2". bool grpc_exp_seen = false; bool h2_seen = false; - const char* inp = (const char*)in; + const char* inp = reinterpret_cast<const char*>(in); const char* in_end = inp + in_len; while (inp < in_end) { - const size_t length = (size_t)*inp++; + const size_t length = static_cast<size_t>(*inp++); if (length == strlen("grpc-exp") && strncmp(inp, "grpc-exp", length) == 0) { grpc_exp_seen = true; GPR_ASSERT(!h2_seen); @@ -133,7 +135,7 @@ static int alpn_select_cb(SSL* ssl, const uint8_t** out, uint8_t* out_len, // https://wiki.openssl.org/index.php/Simple_TLS_Server and the gRPC core // internals in src/core/tsi/ssl_transport_security.c. static void server_thread(void* arg) { - const server_args* args = (server_args*)arg; + const server_args* args = static_cast<server_args*>(arg); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); @@ -175,7 +177,8 @@ static void server_thread(void* arg) { gpr_log(GPR_INFO, "Server listening"); struct sockaddr_in addr; socklen_t len = sizeof(addr); - const int client = accept(sock, (struct sockaddr*)&addr, &len); + const int client = + accept(sock, reinterpret_cast<struct sockaddr*>(&addr), &len); if (client < 0) { perror("Unable to accept"); abort(); @@ -227,12 +230,11 @@ static bool client_ssl_test(char* server_alpn_preferred) { GPR_ASSERT(server_socket > 0 && port > 0); // Launch the TLS server thread. - gpr_thd_options thdopt = gpr_thd_options_default(); - gpr_thd_id thdid; - gpr_thd_options_set_joinable(&thdopt); server_args args = {server_socket, server_alpn_preferred}; - GPR_ASSERT(gpr_thd_new(&thdid, "grpc_client_ssl_test", server_thread, &args, - &thdopt)); + bool ok; + grpc_core::Thread thd("grpc_client_ssl_test", server_thread, &args, &ok); + GPR_ASSERT(ok); + thd.Start(); // Load key pair and establish client SSL credentials. grpc_ssl_pem_key_cert_pair pem_key_cert_pair; @@ -243,9 +245,12 @@ static bool client_ssl_test(char* server_alpn_preferred) { grpc_load_file(SSL_CERT_PATH, 1, &cert_slice))); GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", grpc_load_file(SSL_KEY_PATH, 1, &key_slice))); - const char* ca_cert = (const char*)GRPC_SLICE_START_PTR(ca_slice); - pem_key_cert_pair.private_key = (const char*)GRPC_SLICE_START_PTR(key_slice); - pem_key_cert_pair.cert_chain = (const char*)GRPC_SLICE_START_PTR(cert_slice); + const char* ca_cert = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice); + pem_key_cert_pair.private_key = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice); + pem_key_cert_pair.cert_chain = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); grpc_channel_credentials* ssl_creds = grpc_ssl_credentials_create(ca_cert, &pem_key_cert_pair, nullptr); @@ -297,7 +302,7 @@ static bool client_ssl_test(char* server_alpn_preferred) { grpc_slice_unref(key_slice); grpc_slice_unref(ca_slice); - gpr_thd_join(thdid); + thd.Join(); grpc_shutdown(); diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index 599e0e16e2..97e9c20ee4 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -29,7 +29,7 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> + #include "src/core/lib/iomgr/load_file.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -64,10 +64,11 @@ static void readahead_handshaker_do_handshake( const grpc_handshaker_vtable readahead_handshaker_vtable = { readahead_handshaker_destroy, readahead_handshaker_shutdown, - readahead_handshaker_do_handshake}; + readahead_handshaker_do_handshake, "read_ahead"}; static grpc_handshaker* readahead_handshaker_create() { - grpc_handshaker* h = (grpc_handshaker*)gpr_zalloc(sizeof(grpc_handshaker)); + grpc_handshaker* h = + static_cast<grpc_handshaker*>(gpr_zalloc(sizeof(grpc_handshaker))); grpc_handshaker_init(&readahead_handshaker_vtable, h); return h; } diff --git a/test/core/handshake/server_ssl.cc b/test/core/handshake/server_ssl.cc index 736d3e578e..8fa5f7fb35 100644 --- a/test/core/handshake/server_ssl.cc +++ b/test/core/handshake/server_ssl.cc @@ -29,7 +29,7 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> + #include "src/core/lib/iomgr/load_file.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/handshake/server_ssl_common.cc b/test/core/handshake/server_ssl_common.cc index 0bf453a204..41b2829d8b 100644 --- a/test/core/handshake/server_ssl_common.cc +++ b/test/core/handshake/server_ssl_common.cc @@ -31,7 +31,8 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> + +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/load_file.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -48,7 +49,7 @@ static int create_socket(int port) { struct sockaddr_in addr; addr.sin_family = AF_INET; - addr.sin_port = htons((uint16_t)port); + addr.sin_port = htons(static_cast<uint16_t>(port)); addr.sin_addr.s_addr = htonl(INADDR_ANY); s = socket(AF_INET, SOCK_STREAM, 0); @@ -57,7 +58,7 @@ static int create_socket(int port) { return -1; } - if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + if (connect(s, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) < 0) { perror("Unable to connect"); return -1; } @@ -67,7 +68,7 @@ static int create_socket(int port) { // Simple gRPC server. This listens until client_handshake_complete occurs. static void server_thread(void* arg) { - const int port = *(int*)arg; + const int port = *static_cast<int*>(arg); // Load key pair and establish server SSL credentials. grpc_ssl_pem_key_cert_pair pem_key_cert_pair; @@ -78,9 +79,12 @@ static void server_thread(void* arg) { grpc_load_file(SSL_CERT_PATH, 1, &cert_slice))); GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", grpc_load_file(SSL_KEY_PATH, 1, &key_slice))); - const char* ca_cert = (const char*)GRPC_SLICE_START_PTR(ca_slice); - pem_key_cert_pair.private_key = (const char*)GRPC_SLICE_START_PTR(key_slice); - pem_key_cert_pair.cert_chain = (const char*)GRPC_SLICE_START_PTR(cert_slice); + const char* ca_cert = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice); + pem_key_cert_pair.private_key = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice); + pem_key_cert_pair.cert_chain = + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create( ca_cert, &pem_key_cert_pair, 1, 0, nullptr); @@ -134,11 +138,10 @@ bool server_ssl_test(const char* alpn_list[], unsigned int alpn_list_len, gpr_event_init(&client_handshake_complete); // Launch the gRPC server thread. - gpr_thd_options thdopt = gpr_thd_options_default(); - gpr_thd_id thdid; - gpr_thd_options_set_joinable(&thdopt); - GPR_ASSERT( - gpr_thd_new(&thdid, "grpc_ssl_test", server_thread, &port, &thdopt)); + bool ok; + grpc_core::Thread thd("grpc_ssl_test", server_thread, &port, &ok); + GPR_ASSERT(ok); + thd.Start(); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); @@ -176,13 +179,13 @@ bool server_ssl_test(const char* alpn_list[], unsigned int alpn_list_len, // wire format, see documentation for SSL_CTX_set_alpn_protos. unsigned int alpn_protos_len = alpn_list_len; for (unsigned int i = 0; i < alpn_list_len; ++i) { - alpn_protos_len += (unsigned int)strlen(alpn_list[i]); + alpn_protos_len += static_cast<unsigned int>(strlen(alpn_list[i])); } unsigned char* alpn_protos = static_cast<unsigned char*>(gpr_malloc(alpn_protos_len)); unsigned char* p = alpn_protos; for (unsigned int i = 0; i < alpn_list_len; ++i) { - const uint8_t len = (uint8_t)strlen(alpn_list[i]); + const uint8_t len = static_cast<uint8_t>(strlen(alpn_list[i])); *p++ = len; memcpy(p, alpn_list[i], len); p += len; @@ -217,8 +220,8 @@ bool server_ssl_test(const char* alpn_list[], unsigned int alpn_list_len, unsigned int alpn_selected_len; SSL_get0_alpn_selected(ssl, &alpn_selected, &alpn_selected_len); if (strlen(alpn_expected) != alpn_selected_len || - strncmp((const char*)alpn_selected, alpn_expected, alpn_selected_len) != - 0) { + strncmp(reinterpret_cast<const char*>(alpn_selected), alpn_expected, + alpn_selected_len) != 0) { gpr_log(GPR_ERROR, "Unexpected ALPN protocol preference"); success = false; } @@ -231,7 +234,7 @@ bool server_ssl_test(const char* alpn_list[], unsigned int alpn_list_len, EVP_cleanup(); close(sock); - gpr_thd_join(thdid); + thd.Join(); grpc_shutdown(); diff --git a/test/core/handshake/server_ssl_common.h b/test/core/handshake/server_ssl_common.h index 77865a408f..32bc6f9897 100644 --- a/test/core/handshake/server_ssl_common.h +++ b/test/core/handshake/server_ssl_common.h @@ -25,7 +25,7 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> + #include "src/core/lib/iomgr/load_file.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/http/BUILD b/test/core/http/BUILD index a5ae6272db..be51ea0737 100644 --- a/test/core/http/BUILD +++ b/test/core/http/BUILD @@ -66,7 +66,12 @@ grpc_cc_test( name = "httpcli_test", srcs = ["httpcli_test.cc"], language = "C++", - data = ["test_server.py"], + data = [ + "python_wrapper.sh", + "test_server.py", + "//src/core/tsi/test_creds:server1.pem", + "//src/core/tsi/test_creds:server1.key" + ], deps = [ "//:gpr", "//:grpc", @@ -80,7 +85,13 @@ grpc_cc_test( name = "httpscli_test", srcs = ["httpscli_test.cc"], language = "C++", - data = ["test_server.py"], + data = [ + "python_wrapper.sh", + "test_server.py", + "//src/core/tsi/test_creds:ca.pem", + "//src/core/tsi/test_creds:server1.pem", + "//src/core/tsi/test_creds:server1.key" + ], deps = [ "//:gpr", "//:grpc", @@ -102,3 +113,16 @@ grpc_cc_test( "//test/core/util:grpc_test_util", ], ) + +grpc_cc_test( + name = "format_request_test", + srcs = ["format_request_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/end2end:ssl_test_data", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/http/httpcli_test.cc b/test/core/http/httpcli_test.cc index 259e3aa463..a51a0a5f6d 100644 --- a/test/core/http/httpcli_test.cc +++ b/test/core/http/httpcli_test.cc @@ -24,10 +24,11 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/subprocess.h> #include <grpc/support/sync.h> + #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/port.h" +#include "test/core/util/subprocess.h" #include "test/core/util/test_config.h" static int g_done = 0; @@ -46,6 +47,8 @@ static void on_finish(void* arg, grpc_error* error) { "<body><p>This is a test</p></body></html>"; grpc_http_response* response = static_cast<grpc_http_response*>(arg); GPR_ASSERT(response); + gpr_log(GPR_INFO, "response status=%d error=%s", response->status, + grpc_error_string(error)); GPR_ASSERT(response->status == 200); GPR_ASSERT(response->body_length == strlen(expect)); GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length)); @@ -154,10 +157,17 @@ int main(int argc, char** argv) { int arg_shift = 0; /* figure out where we are */ char* root; - if (lslash) { - root = static_cast<char*>(gpr_malloc((size_t)(lslash - me + 1))); - memcpy(root, me, (size_t)(lslash - me)); - root[lslash - me] = 0; + if (lslash != nullptr) { + /* Hack for bazel target */ + if (static_cast<unsigned>(lslash - me) >= (sizeof("http") - 1) && + strncmp(me + (lslash - me) - sizeof("http") + 1, "http", + sizeof("http") - 1) == 0) { + lslash = me + (lslash - me) - sizeof("http"); + } + root = static_cast<char*>( + gpr_malloc(static_cast<size_t>(lslash - me + sizeof("/../..")))); + memcpy(root, me, static_cast<size_t>(lslash - me)); + memcpy(root + (lslash - me), "/../..", sizeof("/../..")); } else { root = gpr_strdup("."); } @@ -167,8 +177,8 @@ int main(int argc, char** argv) { args[0] = gpr_strdup(argv[1]); } else { arg_shift = 1; - gpr_asprintf(&args[0], "%s/../../tools/distrib/python_wrapper.sh", root); - gpr_asprintf(&args[1], "%s/../../test/core/http/test_server.py", root); + gpr_asprintf(&args[0], "%s/test/core/http/python_wrapper.sh", root); + gpr_asprintf(&args[1], "%s/test/core/http/test_server.py", root); } /* start the server */ diff --git a/test/core/http/httpscli_test.cc b/test/core/http/httpscli_test.cc index adf69f1b16..3fecf2b08b 100644 --- a/test/core/http/httpscli_test.cc +++ b/test/core/http/httpscli_test.cc @@ -21,13 +21,16 @@ #include <string.h> #include <grpc/grpc.h> +#include <grpc/grpc_security_constants.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/subprocess.h> #include <grpc/support/sync.h> + +#include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/port.h" +#include "test/core/util/subprocess.h" #include "test/core/util/test_config.h" static int g_done = 0; @@ -46,6 +49,8 @@ static void on_finish(void* arg, grpc_error* error) { "<body><p>This is a test</p></body></html>"; grpc_http_response* response = static_cast<grpc_http_response*>(arg); GPR_ASSERT(response); + gpr_log(GPR_INFO, "response status=%d error=%s", response->status, + grpc_error_string(error)); GPR_ASSERT(response->status == 200); GPR_ASSERT(response->body_length == strlen(expect)); GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length)); @@ -152,10 +157,17 @@ int main(int argc, char** argv) { int arg_shift = 0; /* figure out where we are */ char* root; - if (lslash) { - root = static_cast<char*>(gpr_malloc((size_t)(lslash - me + 1))); - memcpy(root, me, (size_t)(lslash - me)); - root[lslash - me] = 0; + if (lslash != nullptr) { + /* Hack for bazel target */ + if (static_cast<unsigned>(lslash - me) >= (sizeof("http") - 1) && + strncmp(me + (lslash - me) - sizeof("http") + 1, "http", + sizeof("http") - 1) == 0) { + lslash = me + (lslash - me) - sizeof("http"); + } + root = static_cast<char*>( + gpr_malloc(static_cast<size_t>(lslash - me + sizeof("/../..")))); + memcpy(root, me, static_cast<size_t>(lslash - me)); + memcpy(root + (lslash - me), "/../..", sizeof("/../..")); } else { root = gpr_strdup("."); } @@ -165,10 +177,16 @@ int main(int argc, char** argv) { args[0] = gpr_strdup(argv[1]); } else { arg_shift = 1; - gpr_asprintf(&args[0], "%s/../../tools/distrib/python_wrapper.sh", root); - gpr_asprintf(&args[1], "%s/../../test/core/http/test_server.py", root); + gpr_asprintf(&args[0], "%s/test/core/http/python_wrapper.sh", root); + gpr_asprintf(&args[1], "%s/test/core/http/test_server.py", root); } + /* Set the environment variable for the SSL certificate file */ + char* pem_file; + gpr_asprintf(&pem_file, "%s/src/core/tsi/test_creds/ca.pem", root); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, pem_file); + gpr_free(pem_file); + /* start the server */ args[1 + arg_shift] = const_cast<char*>("--port"); gpr_asprintf(&args[2 + arg_shift], "%d", port); diff --git a/test/core/http/parser_test.cc b/test/core/http/parser_test.cc index 18f19856bd..fe824f57fc 100644 --- a/test/core/http/parser_test.cc +++ b/test/core/http/parser_test.cc @@ -25,7 +25,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "test/core/util/slice_splitter.h" #include "test/core/util/test_config.h" diff --git a/test/core/http/python_wrapper.sh b/test/core/http/python_wrapper.sh new file mode 120000 index 0000000000..9ed6e3293f --- /dev/null +++ b/test/core/http/python_wrapper.sh @@ -0,0 +1 @@ +../../../tools/distrib/python_wrapper.sh
\ No newline at end of file diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 41e2607646..349a06d578 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -60,6 +60,19 @@ grpc_cc_test( ) grpc_cc_test( + name = "error_test", + srcs = ["error_test.cc"], + language = "C++", + deps = [ + ":endpoint_tests", + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( name = "ev_epollsig_linux_test", srcs = ["ev_epollsig_linux_test.cc"], deps = [ diff --git a/test/core/iomgr/combiner_test.cc b/test/core/iomgr/combiner_test.cc index 891008c774..cf2c7db846 100644 --- a/test/core/iomgr/combiner_test.cc +++ b/test/core/iomgr/combiner_test.cc @@ -21,9 +21,9 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" static void test_no_op(void) { @@ -97,21 +97,19 @@ static void test_execute_many(void) { gpr_log(GPR_DEBUG, "test_execute_many"); grpc_combiner* lock = grpc_combiner_create(); - gpr_thd_id thds[100]; + grpc_core::Thread thds[100]; thd_args ta[GPR_ARRAY_SIZE(thds)]; for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { - gpr_thd_options options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&options); ta[i].ctr = 0; ta[i].lock = lock; gpr_event_init(&ta[i].done); - GPR_ASSERT(gpr_thd_new(&thds[i], "grpc_execute_many", execute_many_loop, - &ta[i], &options)); + thds[i] = grpc_core::Thread("grpc_execute_many", execute_many_loop, &ta[i]); + thds[i].Start(); } for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { GPR_ASSERT(gpr_event_wait(&ta[i].done, gpr_inf_future(GPR_CLOCK_REALTIME)) != nullptr); - gpr_thd_join(thds[i]); + thds[i].Join(); } grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(lock, "test_execute_many"); diff --git a/test/core/iomgr/endpoint_pair_test.cc b/test/core/iomgr/endpoint_pair_test.cc index 90dd40d9c4..ad38076b51 100644 --- a/test/core/iomgr/endpoint_pair_test.cc +++ b/test/core/iomgr/endpoint_pair_test.cc @@ -21,7 +21,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "test/core/iomgr/endpoint_tests.h" #include "test/core/util/test_config.h" @@ -37,7 +38,7 @@ static grpc_endpoint_test_fixture create_fixture_endpoint_pair( grpc_arg a[1]; a[0].key = const_cast<char*>(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER; - a[0].value.integer = (int)slice_size; + a[0].value.integer = static_cast<int>(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; grpc_endpoint_pair p = grpc_iomgr_create_endpoint_pair("test", &args); diff --git a/test/core/iomgr/endpoint_tests.cc b/test/core/iomgr/endpoint_tests.cc index 8ccae52067..8db8ac5ed6 100644 --- a/test/core/iomgr/endpoint_tests.cc +++ b/test/core/iomgr/endpoint_tests.cc @@ -25,8 +25,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/util/test_config.h" @@ -77,7 +77,8 @@ static void end_test(grpc_endpoint_test_config config) { config.clean_up(); } static grpc_slice* allocate_blocks(size_t num_bytes, size_t slice_size, size_t* num_blocks, uint8_t* current_data) { size_t nslices = num_bytes / slice_size + (num_bytes % slice_size ? 1 : 0); - grpc_slice* slices = (grpc_slice*)gpr_malloc(sizeof(grpc_slice) * nslices); + grpc_slice* slices = + static_cast<grpc_slice*>(gpr_malloc(sizeof(grpc_slice) * nslices)); size_t num_bytes_left = num_bytes; size_t i; size_t j; @@ -117,7 +118,7 @@ struct read_and_write_test_state { static void read_and_write_test_read_handler(void* data, grpc_error* error) { struct read_and_write_test_state* state = - (struct read_and_write_test_state*)data; + static_cast<struct read_and_write_test_state*>(data); state->bytes_read += count_slices( state->incoming.slices, state->incoming.count, &state->current_read_data); @@ -134,7 +135,7 @@ static void read_and_write_test_read_handler(void* data, grpc_error* error) { static void read_and_write_test_write_handler(void* data, grpc_error* error) { struct read_and_write_test_state* state = - (struct read_and_write_test_state*)data; + static_cast<struct read_and_write_test_state*>(data); grpc_slice* slices = nullptr; size_t nslices; @@ -246,7 +247,7 @@ static void read_and_write_test(grpc_endpoint_test_config config, static void inc_on_failure(void* arg, grpc_error* error) { gpr_mu_lock(g_mu); - *(int*)arg += (error != GRPC_ERROR_NONE); + *static_cast<int*>(arg) += (error != GRPC_ERROR_NONE); GPR_ASSERT(GRPC_LOG_IF_ERROR("kick", grpc_pollset_kick(g_pollset, nullptr))); gpr_mu_unlock(g_mu); } diff --git a/test/core/iomgr/error_test.cc b/test/core/iomgr/error_test.cc index 51f8af1957..a1628a1f71 100644 --- a/test/core/iomgr/error_test.cc +++ b/test/core/iomgr/error_test.cc @@ -21,8 +21,6 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> #include <string.h> diff --git a/test/core/iomgr/ev_epollsig_linux_test.cc b/test/core/iomgr/ev_epollsig_linux_test.cc index e767e01f21..c3ba6d7c14 100644 --- a/test/core/iomgr/ev_epollsig_linux_test.cc +++ b/test/core/iomgr/ev_epollsig_linux_test.cc @@ -18,7 +18,7 @@ #include "src/core/lib/iomgr/port.h" /* This test only relevant on linux systems where epoll() is available */ -#ifdef GRPC_LINUX_EPOLL +#ifdef GRPC_LINUX_EPOLL_CREATE1 #include "src/core/lib/iomgr/ev_epollsig_linux.h" #include "src/core/lib/iomgr/ev_posix.h" @@ -29,9 +29,9 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" @@ -98,7 +98,7 @@ static void test_pollset_init(test_pollset* pollsets, int num_pollsets) { } static void destroy_pollset(void* p, grpc_error* error) { - grpc_pollset_destroy((grpc_pollset*)p); + grpc_pollset_destroy(static_cast<grpc_pollset*>(p)); } static void test_pollset_cleanup(test_pollset* pollsets, int num_pollsets) { @@ -259,11 +259,10 @@ static void test_threading(void) { shared.pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(shared.pollset, &shared.mu); - gpr_thd_id thds[10]; - for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { - gpr_thd_options opt = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&opt); - gpr_thd_new(&thds[i], "test_thread", test_threading_loop, &shared, &opt); + grpc_core::Thread thds[10]; + for (auto& th : thds) { + th = grpc_core::Thread("test_thread", test_threading_loop, &shared); + th.Start(); } grpc_wakeup_fd fd; GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_fd_init", grpc_wakeup_fd_init(&fd))); @@ -280,8 +279,8 @@ static void test_threading(void) { } GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_first", grpc_wakeup_fd_wakeup(shared.wakeup_fd))); - for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { - gpr_thd_join(thds[i]); + for (auto& th : thds) { + th.Join(); } fd.read_fd = 0; grpc_wakeup_fd_destroy(&fd); @@ -319,6 +318,6 @@ int main(int argc, char** argv) { grpc_shutdown(); return 0; } -#else /* defined(GRPC_LINUX_EPOLL) */ +#else /* defined(GRPC_LINUX_EPOLL_CREATE1) */ int main(int argc, char** argv) { return 0; } -#endif /* !defined(GRPC_LINUX_EPOLL) */ +#endif /* !defined(GRPC_LINUX_EPOLL_CREATE1) */ diff --git a/test/core/iomgr/fd_conservation_posix_test.cc b/test/core/iomgr/fd_conservation_posix_test.cc index aaa14010f8..4866e350d5 100644 --- a/test/core/iomgr/fd_conservation_posix_test.cc +++ b/test/core/iomgr/fd_conservation_posix_test.cc @@ -43,7 +43,7 @@ int main(int argc, char** argv) { grpc_resource_quota_create("fd_conservation_posix_test"); for (i = 0; i < 100; i++) { - p = grpc_iomgr_create_endpoint_pair("test", NULL); + p = grpc_iomgr_create_endpoint_pair("test", nullptr); grpc_endpoint_destroy(p.client); grpc_endpoint_destroy(p.server); grpc_core::ExecCtx::Get()->Flush(); diff --git a/test/core/iomgr/fd_posix_test.cc b/test/core/iomgr/fd_posix_test.cc index cf75517538..b81c73b2c0 100644 --- a/test/core/iomgr/fd_posix_test.cc +++ b/test/core/iomgr/fd_posix_test.cc @@ -78,7 +78,7 @@ static void create_test_socket(int port, int* socket_fd, sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x7f000001); GPR_ASSERT(port >= 0 && port < 65536); - sin->sin_port = htons((uint16_t)port); + sin->sin_port = htons(static_cast<uint16_t>(port)); } /* Dummy gRPC callback */ @@ -196,7 +196,8 @@ static void listen_cb(void* arg, /*=sv_arg*/ return; } - fd = accept(grpc_fd_wrapped_fd(listen_em_fd), (struct sockaddr*)&ss, &slen); + fd = accept(grpc_fd_wrapped_fd(listen_em_fd), + reinterpret_cast<struct sockaddr*>(&ss), &slen); GPR_ASSERT(fd >= 0); GPR_ASSERT(fd < FD_SETSIZE); flags = fcntl(fd, F_GETFL, 0); @@ -335,7 +336,8 @@ static void client_start(client* cl, int port) { int fd; struct sockaddr_in sin; create_test_socket(port, &fd, &sin); - if (connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == -1) { + if (connect(fd, reinterpret_cast<struct sockaddr*>(&sin), sizeof(sin)) == + -1) { if (errno == EINPROGRESS) { struct pollfd pfd; pfd.fd = fd; diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm new file mode 100644 index 0000000000..414b6c78c0 --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm @@ -0,0 +1,201 @@ +/* + * + * 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. + * + */ + +#import <XCTest/XCTest.h> + +#include "src/core/lib/iomgr/port.h" + +#ifdef GRPC_CFSTREAM + +#include <netinet/in.h> + +#include <grpc/impl/codegen/sync.h> +#include <grpc/support/sync.h> + +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "test/core/util/test_config.h" + +// static int g_connections_complete = 0; +static gpr_mu g_mu; +static int g_connections_complete = 0; +static grpc_endpoint* g_connecting = nullptr; + +static void finish_connection() { + gpr_mu_lock(&g_mu); + g_connections_complete++; + gpr_mu_unlock(&g_mu); +} + +static void must_succeed(void* arg, grpc_error* error) { + GPR_ASSERT(g_connecting != nullptr); + GPR_ASSERT(error == GRPC_ERROR_NONE); + grpc_endpoint_shutdown(g_connecting, GRPC_ERROR_CREATE_FROM_STATIC_STRING("must_succeed called")); + grpc_endpoint_destroy(g_connecting); + g_connecting = nullptr; + finish_connection(); +} + +static void must_fail(void* arg, grpc_error* error) { + GPR_ASSERT(g_connecting == nullptr); + GPR_ASSERT(error != GRPC_ERROR_NONE); + const char* error_str = grpc_error_string(error); + NSLog(@"%s", error_str); + finish_connection(); +} + +@interface CFStreamClientTests : XCTestCase + +@end + +@implementation CFStreamClientTests + ++ (void)setUp { + grpc_init(); + gpr_mu_init(&g_mu); +} + ++ (void)tearDown { + grpc_shutdown(); +} + +- (void)testSucceeds { + grpc_resolved_address resolved_addr; + struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); + int svr_fd; + int r; + int connections_complete_before; + grpc_closure done; + grpc_core::ExecCtx exec_ctx; + + gpr_log(GPR_DEBUG, "test_succeeds"); + + memset(&resolved_addr, 0, sizeof(resolved_addr)); + resolved_addr.len = sizeof(struct sockaddr_in); + addr->sin_family = AF_INET; + + /* create a dummy server */ + svr_fd = socket(AF_INET, SOCK_STREAM, 0); + GPR_ASSERT(svr_fd >= 0); + GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr*)addr, (socklen_t)resolved_addr.len)); + GPR_ASSERT(0 == listen(svr_fd, 1)); + + gpr_mu_lock(&g_mu); + connections_complete_before = g_connections_complete; + gpr_mu_unlock(&g_mu); + + /* connect to it */ + GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len) == 0); + GRPC_CLOSURE_INIT(&done, must_succeed, nullptr, grpc_schedule_on_exec_ctx); + grpc_tcp_client_connect(&done, &g_connecting, nullptr, nullptr, &resolved_addr, + GRPC_MILLIS_INF_FUTURE); + + /* await the connection */ + do { + resolved_addr.len = sizeof(addr); + r = accept(svr_fd, reinterpret_cast<struct sockaddr*>(addr), + reinterpret_cast<socklen_t*>(&resolved_addr.len)); + } while (r == -1 && errno == EINTR); + GPR_ASSERT(r >= 0); + close(r); + + grpc_core::ExecCtx::Get()->Flush(); + + /* wait for the connection callback to finish */ + gpr_mu_lock(&g_mu); + NSDate* deadline = [NSDate dateWithTimeIntervalSinceNow:5]; + while (connections_complete_before == g_connections_complete) { + gpr_mu_unlock(&g_mu); + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:deadline]; + gpr_mu_lock(&g_mu); + } + XCTAssertGreaterThan(g_connections_complete, connections_complete_before); + + gpr_mu_unlock(&g_mu); +} + +- (void)testFails { + grpc_core::ExecCtx exec_ctx; + + grpc_resolved_address resolved_addr; + struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); + int connections_complete_before; + grpc_closure done; + int svr_fd; + + gpr_log(GPR_DEBUG, "test_fails"); + + memset(&resolved_addr, 0, sizeof(resolved_addr)); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in)); + addr->sin_family = AF_INET; + + svr_fd = socket(AF_INET, SOCK_STREAM, 0); + GPR_ASSERT(svr_fd >= 0); + GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr*)addr, (socklen_t)resolved_addr.len)); + GPR_ASSERT(0 == listen(svr_fd, 1)); + GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len) == 0); + close(svr_fd); + + gpr_mu_lock(&g_mu); + connections_complete_before = g_connections_complete; + gpr_mu_unlock(&g_mu); + + /* connect to a broken address */ + GRPC_CLOSURE_INIT(&done, must_fail, nullptr, grpc_schedule_on_exec_ctx); + grpc_tcp_client_connect(&done, &g_connecting, nullptr, nullptr, &resolved_addr, + GRPC_MILLIS_INF_FUTURE); + + grpc_core::ExecCtx::Get()->Flush(); + + /* wait for the connection callback to finish */ + gpr_mu_lock(&g_mu); + NSDate* deadline = [NSDate dateWithTimeIntervalSinceNow:5]; + while (g_connections_complete == connections_complete_before) { + gpr_mu_unlock(&g_mu); + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:deadline]; + gpr_mu_lock(&g_mu); + } + + XCTAssertGreaterThan(g_connections_complete, connections_complete_before); + + gpr_mu_unlock(&g_mu); +} + +@end + +#else // GRPC_CFSTREAM + +// Dummy test suite +@interface CFStreamClientTests : XCTestCase + +@end + +@implementation CFStreamClientTests + +- (void)setUp { + [super setUp]; +} + +- (void)tearDown { + [super tearDown]; +} + +@end + +#endif // GRPC_CFSTREAM diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm new file mode 100644 index 0000000000..fbc34c74d6 --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm @@ -0,0 +1,344 @@ +/* + * + * 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. + * + */ + +#import <XCTest/XCTest.h> + +#include "src/core/lib/iomgr/port.h" + +#ifdef GRPC_CFSTREAM + +#include <netinet/in.h> + +#include <grpc/impl/codegen/sync.h> +#include <grpc/support/sync.h> + +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "test/core/util/test_config.h" + +static const int kConnectTimeout = 5; +static const int kWriteTimeout = 5; +static const int kReadTimeout = 5; + +static const int kBufferSize = 10000; + +static const int kRunLoopTimeout = 1; + +static void set_atm(void *arg, grpc_error *error) { + gpr_atm *p = static_cast<gpr_atm *>(arg); + gpr_atm_full_cas(p, -1, reinterpret_cast<gpr_atm>(error)); +} + +static void init_event_closure(grpc_closure *closure, gpr_atm *atm) { + *atm = -1; + GRPC_CLOSURE_INIT(closure, set_atm, static_cast<void *>(atm), grpc_schedule_on_exec_ctx); +} + +static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const char *buffer, + size_t buffer_len) { + if (slices->length != buffer_len) { + return false; + } + + for (int i = 0; i < slices->count; i++) { + grpc_slice slice = slices->slices[i]; + if (0 != memcmp(buffer, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice))) { + return false; + } + buffer += GRPC_SLICE_LENGTH(slice); + } + + return true; +} + +@interface CFStreamEndpointTests : XCTestCase + +@end + +@implementation CFStreamEndpointTests { + grpc_endpoint *ep_; + int svr_fd_; +} + +- (BOOL)waitForEvent:(gpr_atm *)event timeout:(int)timeout { + grpc_core::ExecCtx::Get()->Flush(); + + NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:kConnectTimeout]; + while (gpr_atm_acq_load(event) == -1 && [deadline timeIntervalSinceNow] > 0) { + NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:kRunLoopTimeout]; + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:deadline]; + } + + return (gpr_atm_acq_load(event) != -1); +} + ++ (void)setUp { + grpc_init(); +} + ++ (void)tearDown { + grpc_shutdown(); +} + +- (void)setUp { + self.continueAfterFailure = NO; + + // Set up CFStream connection before testing the endpoint + + grpc_core::ExecCtx exec_ctx; + + grpc_resolved_address resolved_addr; + struct sockaddr_in *addr = reinterpret_cast<struct sockaddr_in *>(resolved_addr.addr); + int svr_fd; + int r; + gpr_atm connected = -1; + grpc_closure done; + + gpr_log(GPR_DEBUG, "test_succeeds"); + + memset(&resolved_addr, 0, sizeof(resolved_addr)); + resolved_addr.len = sizeof(struct sockaddr_in); + addr->sin_family = AF_INET; + + /* create a dummy server */ + svr_fd = socket(AF_INET, SOCK_STREAM, 0); + XCTAssertGreaterThanOrEqual(svr_fd, 0); + XCTAssertEqual(bind(svr_fd, (struct sockaddr *)addr, (socklen_t)resolved_addr.len), 0); + XCTAssertEqual(listen(svr_fd, 1), 0); + + /* connect to it */ + XCTAssertEqual(getsockname(svr_fd, (struct sockaddr *)addr, (socklen_t *)&resolved_addr.len), 0); + init_event_closure(&done, &connected); + grpc_tcp_client_connect(&done, &ep_, nullptr, nullptr, &resolved_addr, GRPC_MILLIS_INF_FUTURE); + + /* await the connection */ + do { + resolved_addr.len = sizeof(addr); + r = accept(svr_fd, reinterpret_cast<struct sockaddr *>(addr), + reinterpret_cast<socklen_t *>(&resolved_addr.len)); + } while (r == -1 && errno == EINTR); + XCTAssertGreaterThanOrEqual(r, 0); + svr_fd_ = r; + + /* wait for the connection callback to finish */ + XCTAssertEqual([self waitForEvent:&connected timeout:kConnectTimeout], YES); + XCTAssertEqual(reinterpret_cast<grpc_error *>(connected), GRPC_ERROR_NONE); +} + +- (void)tearDown { + grpc_core::ExecCtx exec_ctx; + close(svr_fd_); + grpc_endpoint_destroy(ep_); +} + +- (void)testReadWrite { + grpc_core::ExecCtx exec_ctx; + + gpr_atm read; + grpc_closure read_done; + grpc_slice_buffer read_slices; + grpc_slice_buffer read_one_slice; + gpr_atm write; + grpc_closure write_done; + grpc_slice_buffer write_slices; + + grpc_slice slice; + char write_buffer[kBufferSize]; + char read_buffer[kBufferSize]; + size_t recv_size = 0; + + grpc_slice_buffer_init(&write_slices); + slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); + grpc_slice_buffer_add(&write_slices, slice); + init_event_closure(&write_done, &write); + grpc_endpoint_write(ep_, &write_slices, &write_done); + + XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); + XCTAssertEqual(reinterpret_cast<grpc_error *>(write), GRPC_ERROR_NONE); + + while (recv_size < kBufferSize) { + ssize_t size = recv(svr_fd_, read_buffer, kBufferSize, 0); + XCTAssertGreaterThanOrEqual(size, 0); + recv_size += size; + } + + XCTAssertEqual(recv_size, kBufferSize); + XCTAssertEqual(memcmp(read_buffer, write_buffer, kBufferSize), 0); + ssize_t send_size = send(svr_fd_, read_buffer, kBufferSize, 0); + XCTAssertGreaterThanOrEqual(send_size, 0); + + grpc_slice_buffer_init(&read_slices); + grpc_slice_buffer_init(&read_one_slice); + while (read_slices.length < kBufferSize) { + init_event_closure(&read_done, &read); + grpc_endpoint_read(ep_, &read_one_slice, &read_done); + XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES); + XCTAssertEqual(reinterpret_cast<grpc_error *>(read), GRPC_ERROR_NONE); + grpc_slice_buffer_move_into(&read_one_slice, &read_slices); + XCTAssertLessThanOrEqual(read_slices.length, kBufferSize); + } + XCTAssertTrue(compare_slice_buffer_with_buffer(&read_slices, read_buffer, kBufferSize)); + + grpc_endpoint_shutdown(ep_, GRPC_ERROR_NONE); + grpc_slice_buffer_reset_and_unref(&read_slices); + grpc_slice_buffer_reset_and_unref(&write_slices); + grpc_slice_buffer_reset_and_unref(&read_one_slice); +} + +- (void)testShutdownBeforeRead { + grpc_core::ExecCtx exec_ctx; + + gpr_atm read; + grpc_closure read_done; + grpc_slice_buffer read_slices; + gpr_atm write; + grpc_closure write_done; + grpc_slice_buffer write_slices; + + grpc_slice slice; + char write_buffer[kBufferSize]; + char read_buffer[kBufferSize]; + size_t recv_size = 0; + + grpc_slice_buffer_init(&read_slices); + init_event_closure(&read_done, &read); + grpc_endpoint_read(ep_, &read_slices, &read_done); + + grpc_slice_buffer_init(&write_slices); + slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); + grpc_slice_buffer_add(&write_slices, slice); + init_event_closure(&write_done, &write); + grpc_endpoint_write(ep_, &write_slices, &write_done); + + XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); + XCTAssertEqual(reinterpret_cast<grpc_error *>(write), GRPC_ERROR_NONE); + + while (recv_size < kBufferSize) { + ssize_t size = recv(svr_fd_, read_buffer, kBufferSize, 0); + XCTAssertGreaterThanOrEqual(size, 0); + recv_size += size; + } + + XCTAssertEqual(recv_size, kBufferSize); + XCTAssertEqual(memcmp(read_buffer, write_buffer, kBufferSize), 0); + + XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], NO); + + grpc_endpoint_shutdown(ep_, GRPC_ERROR_NONE); + + grpc_core::ExecCtx::Get()->Flush(); + XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES); + XCTAssertNotEqual(reinterpret_cast<grpc_error *>(read), GRPC_ERROR_NONE); + + grpc_slice_buffer_reset_and_unref(&read_slices); + grpc_slice_buffer_reset_and_unref(&write_slices); +} + +- (void)testRemoteClosed { + grpc_core::ExecCtx exec_ctx; + + gpr_atm read; + grpc_closure read_done; + grpc_slice_buffer read_slices; + gpr_atm write; + grpc_closure write_done; + grpc_slice_buffer write_slices; + + grpc_slice slice; + char write_buffer[kBufferSize]; + char read_buffer[kBufferSize]; + size_t recv_size = 0; + + init_event_closure(&read_done, &read); + grpc_slice_buffer_init(&read_slices); + grpc_endpoint_read(ep_, &read_slices, &read_done); + + grpc_slice_buffer_init(&write_slices); + slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); + grpc_slice_buffer_add(&write_slices, slice); + init_event_closure(&write_done, &write); + grpc_endpoint_write(ep_, &write_slices, &write_done); + + XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); + XCTAssertEqual(reinterpret_cast<grpc_error *>(write), GRPC_ERROR_NONE); + + while (recv_size < kBufferSize) { + ssize_t size = recv(svr_fd_, read_buffer, kBufferSize, 0); + XCTAssertGreaterThanOrEqual(size, 0); + recv_size += size; + } + + XCTAssertEqual(recv_size, kBufferSize); + XCTAssertEqual(memcmp(read_buffer, write_buffer, kBufferSize), 0); + + close(svr_fd_); + + XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES); + XCTAssertNotEqual(reinterpret_cast<grpc_error *>(read), GRPC_ERROR_NONE); + + grpc_endpoint_shutdown(ep_, GRPC_ERROR_NONE); + grpc_slice_buffer_reset_and_unref(&read_slices); + grpc_slice_buffer_reset_and_unref(&write_slices); +} + +- (void)testRemoteReset { + grpc_core::ExecCtx exec_ctx; + + gpr_atm read; + grpc_closure read_done; + grpc_slice_buffer read_slices; + + init_event_closure(&read_done, &read); + grpc_slice_buffer_init(&read_slices); + grpc_endpoint_read(ep_, &read_slices, &read_done); + + struct linger so_linger; + so_linger.l_onoff = 1; + so_linger.l_linger = 0; + setsockopt(svr_fd_, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)); + + close(svr_fd_); + + XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES); + XCTAssertNotEqual(reinterpret_cast<grpc_error *>(read), GRPC_ERROR_NONE); + + grpc_endpoint_shutdown(ep_, GRPC_ERROR_NONE); + grpc_slice_buffer_reset_and_unref(&read_slices); +} + +@end + +#else // GRPC_CFSTREAM + +// Dummy test suite +@interface CFStreamEndpointTests : XCTestCase +@end + +@implementation CFStreamEndpointTests +- (void)setUp { + [super setUp]; +} + +- (void)tearDown { + [super tearDown]; +} + +@end + +#endif // GRPC_CFSTREAM diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..2218f129ae --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj @@ -0,0 +1,338 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 5E143B892069D72200715A6E /* CFStreamClientTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E143B882069D72200715A6E /* CFStreamClientTests.mm */; }; + 5E143B8C206B5F9F00715A6E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5E143B8A2069D72700715A6E /* Info.plist */; }; + 5E143B8E206C5B9A00715A6E /* CFStreamEndpointTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E143B8D206C5B9A00715A6E /* CFStreamEndpointTests.mm */; }; + 604EA96D9CD477A8EA411BDF /* libPods-CFStreamTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AFFA154D492751CEAC05D591 /* libPods-CFStreamTests.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 5E143B792069D67300715A6E /* CFStreamTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CFStreamTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E143B882069D72200715A6E /* CFStreamClientTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CFStreamClientTests.mm; sourceTree = "<group>"; }; + 5E143B8A2069D72700715A6E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + 5E143B8D206C5B9A00715A6E /* CFStreamEndpointTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CFStreamEndpointTests.mm; sourceTree = "<group>"; }; + 8CB4409E07E180CCA59987DF /* Pods-CFStreamTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CFStreamTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CFStreamTests/Pods-CFStreamTests.release.xcconfig"; sourceTree = "<group>"; }; + 9E3FAF9DA6B98ED4FE6D6848 /* Pods-CFStreamTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CFStreamTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CFStreamTests/Pods-CFStreamTests.debug.xcconfig"; sourceTree = "<group>"; }; + AFFA154D492751CEAC05D591 /* libPods-CFStreamTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CFStreamTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5E143B762069D67300715A6E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 604EA96D9CD477A8EA411BDF /* libPods-CFStreamTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5E143B582069D67300715A6E = { + isa = PBXGroup; + children = ( + 5E143B8D206C5B9A00715A6E /* CFStreamEndpointTests.mm */, + 5E143B8A2069D72700715A6E /* Info.plist */, + 5E143B882069D72200715A6E /* CFStreamClientTests.mm */, + 5E143B622069D67300715A6E /* Products */, + A331D95F7F230B507FBF6D22 /* Pods */, + 6AC36F6C5DB5CA8F717D1B67 /* Frameworks */, + ); + sourceTree = "<group>"; + }; + 5E143B622069D67300715A6E /* Products */ = { + isa = PBXGroup; + children = ( + 5E143B792069D67300715A6E /* CFStreamTests.xctest */, + ); + name = Products; + sourceTree = "<group>"; + }; + 6AC36F6C5DB5CA8F717D1B67 /* Frameworks */ = { + isa = PBXGroup; + children = ( + AFFA154D492751CEAC05D591 /* libPods-CFStreamTests.a */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; + A331D95F7F230B507FBF6D22 /* Pods */ = { + isa = PBXGroup; + children = ( + 9E3FAF9DA6B98ED4FE6D6848 /* Pods-CFStreamTests.debug.xcconfig */, + 8CB4409E07E180CCA59987DF /* Pods-CFStreamTests.release.xcconfig */, + ); + name = Pods; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5E143B782069D67300715A6E /* CFStreamTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E143B852069D67300715A6E /* Build configuration list for PBXNativeTarget "CFStreamTests" */; + buildPhases = ( + 4EBA55D3E23FC6C84596E3D5 /* [CP] Check Pods Manifest.lock */, + 5E143B752069D67300715A6E /* Sources */, + 5E143B762069D67300715A6E /* Frameworks */, + 5E143B772069D67300715A6E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CFStreamTests; + productName = CFStreamTestsTests; + productReference = 5E143B792069D67300715A6E /* CFStreamTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5E143B592069D67300715A6E /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0920; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 5E143B782069D67300715A6E = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 5E143B5C2069D67300715A6E /* Build configuration list for PBXProject "CFStreamTests" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5E143B582069D67300715A6E; + productRefGroup = 5E143B622069D67300715A6E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5E143B782069D67300715A6E /* CFStreamTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5E143B772069D67300715A6E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E143B8C206B5F9F00715A6E /* Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4EBA55D3E23FC6C84596E3D5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-CFStreamTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5E143B752069D67300715A6E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E143B892069D72200715A6E /* CFStreamClientTests.mm in Sources */, + 5E143B8E206C5B9A00715A6E /* CFStreamEndpointTests.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 5E143B802069D67300715A6E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 5E143B812069D67300715A6E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5E143B862069D67300715A6E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9E3FAF9DA6B98ED4FE6D6848 /* Pods-CFStreamTests.debug.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "PB_FIELD_32BIT=1", + "PB_NO_PACKED_STRUCTS=1", + "GRPC_CFSTREAM=1", + ); + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CFStreamTestsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ../../../../..; + }; + name = Debug; + }; + 5E143B872069D67300715A6E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8CB4409E07E180CCA59987DF /* Pods-CFStreamTests.release.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CFStreamTestsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ../../../../..; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5E143B5C2069D67300715A6E /* Build configuration list for PBXProject "CFStreamTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E143B802069D67300715A6E /* Debug */, + 5E143B812069D67300715A6E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5E143B852069D67300715A6E /* Build configuration list for PBXNativeTarget "CFStreamTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E143B862069D67300715A6E /* Debug */, + 5E143B872069D67300715A6E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5E143B592069D67300715A6E /* Project object */; +} diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme new file mode 100644 index 0000000000..25d6f780a1 --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0920" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + <TestableReference + skipped = "NO"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "5E143B782069D67300715A6E" + BuildableName = "CFStreamTests.xctest" + BlueprintName = "CFStreamTests" + ReferencedContainer = "container:CFStreamTests.xcodeproj"> + </BuildableReference> + </TestableReference> + </Testables> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme new file mode 100644 index 0000000000..6c5c43aa72 --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0920" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + enableAddressSanitizer = "YES" + enableASanStackUseAfterReturn = "YES" + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + <TestableReference + skipped = "NO"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "5E143B782069D67300715A6E" + BuildableName = "CFStreamTests.xctest" + BlueprintName = "CFStreamTests" + ReferencedContainer = "container:CFStreamTests.xcodeproj"> + </BuildableReference> + </TestableReference> + </Testables> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + enableASanStackUseAfterReturn = "YES" + language = "" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme new file mode 100644 index 0000000000..3e39ff84d0 --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0920" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + <TestableReference + skipped = "NO"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "5E143B782069D67300715A6E" + BuildableName = "CFStreamTests.xctest" + BlueprintName = "CFStreamTests" + ReferencedContainer = "container:CFStreamTests.xcodeproj"> + </BuildableReference> + </TestableReference> + </Testables> + <AdditionalOptions> + <AdditionalOption + key = "DYLD_INSERT_LIBRARIES" + value = "/usr/lib/libgmalloc.dylib" + isEnabled = "YES"> + </AdditionalOption> + <AdditionalOption + key = "NSZombieEnabled" + value = "YES" + isEnabled = "YES"> + </AdditionalOption> + <AdditionalOption + key = "MallocGuardEdges" + value = "" + isEnabled = "YES"> + </AdditionalOption> + <AdditionalOption + key = "MallocScribble" + value = "" + isEnabled = "YES"> + </AdditionalOption> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme new file mode 100644 index 0000000000..f0bde837c5 --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0920" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + enableThreadSanitizer = "YES" + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + <TestableReference + skipped = "NO"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "5E143B782069D67300715A6E" + BuildableName = "CFStreamTests.xctest" + BlueprintName = "CFStreamTests" + ReferencedContainer = "container:CFStreamTests.xcodeproj"> + </BuildableReference> + </TestableReference> + </Testables> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + stopOnEveryThreadSanitizerIssue = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/test/core/iomgr/ios/CFStreamTests/Info.plist b/test/core/iomgr/ios/CFStreamTests/Info.plist new file mode 100644 index 0000000000..6c40a6cd0c --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/Info.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleVersion</key> + <string>1</string> +</dict> +</plist> diff --git a/test/core/iomgr/ios/CFStreamTests/Podfile b/test/core/iomgr/ios/CFStreamTests/Podfile new file mode 100644 index 0000000000..630168a363 --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/Podfile @@ -0,0 +1,50 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +install! 'cocoapods', :deterministic_uuids => false + +# Location of gRPC's repo root relative to this file. +GRPC_LOCAL_SRC = '../../../../..' + +# Install the dependencies in the main target plus all test targets. +target 'CFStreamTests' do + pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC +end + +pre_install do |installer| + # This is the gRPC-Core podspec object, as initialized by its podspec file. + grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Core'}.root_spec + + # Copied from gRPC-Core.podspec, except for the adjusted src_root: + src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" + grpc_core_spec.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/gpr/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the + # build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' + end + + # CocoaPods creates duplicated library targets of gRPC-Core when the test targets include + # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core' + # and require the same error suppresion. + if target.name.start_with?('gRPC-Core') + target.build_configurations.each do |config| + # TODO(zyc): Remove this setting after the issue is resolved + # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void + # function" warning + config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' + end + end + end +end diff --git a/test/core/iomgr/ios/CFStreamTests/build_tests.sh b/test/core/iomgr/ios/CFStreamTests/build_tests.sh new file mode 100755 index 0000000000..d23f26f5db --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/build_tests.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# 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. + +# Don't run this script standalone. Instead, run from the repository root: +# ./tools/run_tests/run_tests.py -l objc + +set -e + +# CocoaPods requires the terminal to be using UTF-8 encoding. +export LANG=en_US.UTF-8 + +cd "$(dirname "$0")" + +hash pod 2>/dev/null || { echo >&2 "Cocoapods needs to be installed."; exit 1; } +hash xcodebuild 2>/dev/null || { + echo >&2 "XCode command-line tools need to be installed." + exit 1 +} + +# clean the directory +rm -rf Pods +rm -rf CFStreamTests.xcworkspace +rm -f Podfile.lock + +echo "TIME: $(date)" +pod install + diff --git a/test/core/iomgr/ios/CFStreamTests/run_tests.sh b/test/core/iomgr/ios/CFStreamTests/run_tests.sh new file mode 100755 index 0000000000..1045ec10a8 --- /dev/null +++ b/test/core/iomgr/ios/CFStreamTests/run_tests.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# 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. + +# Don't run this script standalone. Instead, run from the repository root: +# ./tools/run_tests/run_tests.py -l objc + +set -ev + +cd "$(dirname "$0")" + +echo "TIME: $(date)" + +XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ *[^ ]*libtool |^CpHeader |^ *builtin-copy )' + +xcodebuild \ + -workspace CFStreamTests.xcworkspace \ + -scheme CFStreamTests \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + +echo "TIME: $(date)" + +xcodebuild \ + -workspace CFStreamTests.xcworkspace \ + -scheme CFStreamTests_Asan \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + +echo "TIME: $(date)" + +xcodebuild \ + -workspace CFStreamTests.xcworkspace \ + -scheme CFStreamTests_Tsan \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + +echo "TIME: $(date)" + +xcodebuild \ + -workspace CFStreamTests.xcworkspace \ + -scheme CFStreamTests_Msan \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - diff --git a/test/core/iomgr/load_file_test.cc b/test/core/iomgr/load_file_test.cc index 797d0ef1a4..38c8710535 100644 --- a/test/core/iomgr/load_file_test.cc +++ b/test/core/iomgr/load_file_test.cc @@ -24,9 +24,9 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/iomgr/load_file.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" #include "test/core/util/test_config.h" #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/iomgr/pollset_set_test.cc b/test/core/iomgr/pollset_set_test.cc index f27079134b..0dc75a5f3f 100644 --- a/test/core/iomgr/pollset_set_test.cc +++ b/test/core/iomgr/pollset_set_test.cc @@ -18,7 +18,7 @@ #include "src/core/lib/iomgr/port.h" /* This test only relevant on linux systems where epoll is available */ -#ifdef GRPC_LINUX_EPOLL +#ifdef GRPC_LINUX_EPOLL_CREATE1 #include <errno.h> #include <string.h> @@ -27,8 +27,8 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" @@ -103,7 +103,7 @@ typedef struct test_fd { } test_fd; void on_readable(void* tfd, grpc_error* error) { - ((test_fd*)tfd)->is_on_readable_called = true; + (static_cast<test_fd*>(tfd))->is_on_readable_called = true; } static void reset_test_fd(test_fd* tfd) { @@ -443,6 +443,6 @@ int main(int argc, char** argv) { grpc_shutdown(); return 0; } -#else /* defined(GRPC_LINUX_EPOLL) */ +#else /* defined(GRPC_LINUX_EPOLL_CREATE1) */ int main(int argc, char** argv) { return 0; } -#endif /* !defined(GRPC_LINUX_EPOLL) */ +#endif /* !defined(GRPC_LINUX_EPOLL_CREATE1) */ diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index e36315333c..e495e4c877 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -25,10 +25,10 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" @@ -38,6 +38,7 @@ static gpr_timespec test_deadline(void) { } typedef struct args_struct { + grpc_core::Thread thd; gpr_event ev; grpc_resolved_addresses* addrs; gpr_atm done_atm; @@ -59,6 +60,9 @@ void args_init(args_struct* args) { void args_finish(args_struct* args) { GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline())); + args->thd.Join(); + // Don't need to explicitly destruct args->thd since + // args is actually going to be destructed, not just freed grpc_resolved_addresses_destroy(args->addrs); grpc_pollset_set_del_pollset(args->pollset_set, args->pollset); grpc_pollset_set_destroy(args->pollset_set); @@ -87,7 +91,7 @@ static void actually_poll(void* argsp) { break; } grpc_millis time_left = deadline - grpc_core::ExecCtx::Get()->Now(); - gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRIdPTR, done, time_left); + gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64, done, time_left); GPR_ASSERT(time_left >= 0); grpc_pollset_worker* worker = nullptr; gpr_mu_lock(args->mu); @@ -101,8 +105,8 @@ static void actually_poll(void* argsp) { static void poll_pollset_until_request_done(args_struct* args) { gpr_atm_rel_store(&args->done_atm, 0); - gpr_thd_id id; - gpr_thd_new(&id, "grpc_poll_pollset", actually_poll, args, nullptr); + args->thd = grpc_core::Thread("grpc_poll_pollset", actually_poll, args); + args->thd.Start(); } static void must_succeed(void* argsp, grpc_error* err) { diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index a0dc484f3e..2fb831a6a4 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -82,7 +82,7 @@ static void poll_pollset_until_request_done(args_struct* args) { break; } grpc_millis time_left = deadline - grpc_core::ExecCtx::Get()->Now(); - gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRIdPTR, done, time_left); + gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64, done, time_left); GPR_ASSERT(time_left >= 0); grpc_pollset_worker* worker = nullptr; gpr_mu_lock(args->mu); diff --git a/test/core/iomgr/resource_quota_test.cc b/test/core/iomgr/resource_quota_test.cc index ae26f72701..059ff7b5f8 100644 --- a/test/core/iomgr/resource_quota_test.cc +++ b/test/core/iomgr/resource_quota_test.cc @@ -21,6 +21,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/util/test_config.h" @@ -29,7 +30,7 @@ gpr_cv g_cv; static void inc_int_cb(void* a, grpc_error* error) { gpr_mu_lock(&g_mu); - ++*(int*)a; + ++*static_cast<int*>(a); gpr_cv_signal(&g_cv); gpr_mu_unlock(&g_mu); } @@ -44,7 +45,7 @@ static void assert_counter_becomes(int* ctr, int value) { } static void set_event_cb(void* a, grpc_error* error) { - gpr_event_set((gpr_event*)a, (void*)1); + gpr_event_set(static_cast<gpr_event*>(a), (void*)1); } grpc_closure* set_event(gpr_event* ev) { return GRPC_CLOSURE_CREATE(set_event_cb, ev, grpc_schedule_on_exec_ctx); @@ -118,7 +119,7 @@ static void test_instant_alloc_then_free(void) { grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); { grpc_core::ExecCtx exec_ctx; - grpc_resource_user_alloc(usr, 1024, NULL); + grpc_resource_user_alloc(usr, 1024, nullptr); } { grpc_core::ExecCtx exec_ctx; @@ -136,7 +137,7 @@ static void test_instant_alloc_free_pair(void) { grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); { grpc_core::ExecCtx exec_ctx; - grpc_resource_user_alloc(usr, 1024, NULL); + grpc_resource_user_alloc(usr, 1024, nullptr); grpc_resource_user_free(usr, 1024); } grpc_resource_quota_unref(q); @@ -565,7 +566,7 @@ static void test_resource_user_stays_allocated_until_memory_released(void) { grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); { grpc_core::ExecCtx exec_ctx; - grpc_resource_user_alloc(usr, 1024, NULL); + grpc_resource_user_alloc(usr, 1024, nullptr); } { grpc_core::ExecCtx exec_ctx; @@ -608,8 +609,8 @@ test_resource_user_stays_allocated_and_reclaimers_unrun_until_memory_released( grpc_core::ExecCtx exec_ctx; grpc_resource_user_alloc(usr, 1024, set_event(&allocated)); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&allocated, - grpc_timeout_seconds_to_deadline(5)) != NULL); + GPR_ASSERT(gpr_event_wait(&allocated, grpc_timeout_seconds_to_deadline( + 5)) != nullptr); GPR_ASSERT(gpr_event_wait(&reclaimer_cancelled, grpc_timeout_milliseconds_to_deadline(100)) == nullptr); @@ -667,8 +668,8 @@ static void test_reclaimers_can_be_posted_repeatedly(void) { grpc_core::ExecCtx exec_ctx; grpc_resource_user_alloc(usr, 1024, set_event(&allocated)); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&allocated, - grpc_timeout_seconds_to_deadline(5)) != NULL); + GPR_ASSERT(gpr_event_wait(&allocated, grpc_timeout_seconds_to_deadline( + 5)) != nullptr); GPR_ASSERT(gpr_event_wait(&reclaimer_done, grpc_timeout_seconds_to_deadline(5)) != nullptr); diff --git a/test/core/iomgr/sockaddr_utils_test.cc b/test/core/iomgr/sockaddr_utils_test.cc index a445714851..3783f968b7 100644 --- a/test/core/iomgr/sockaddr_utils_test.cc +++ b/test/core/iomgr/sockaddr_utils_test.cc @@ -22,6 +22,7 @@ headers. Therefore, sockaddr.h must always be included first */ #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/socket_utils.h" #include <errno.h> #include <string.h> @@ -33,31 +34,33 @@ static grpc_resolved_address make_addr4(const uint8_t* data, size_t data_len) { grpc_resolved_address resolved_addr4; - struct sockaddr_in* addr4 = (struct sockaddr_in*)resolved_addr4.addr; + grpc_sockaddr_in* addr4 = + reinterpret_cast<grpc_sockaddr_in*>(resolved_addr4.addr); memset(&resolved_addr4, 0, sizeof(resolved_addr4)); - addr4->sin_family = AF_INET; + addr4->sin_family = GRPC_AF_INET; GPR_ASSERT(data_len == sizeof(addr4->sin_addr.s_addr)); memcpy(&addr4->sin_addr.s_addr, data, data_len); - addr4->sin_port = htons(12345); - resolved_addr4.len = sizeof(struct sockaddr_in); + addr4->sin_port = grpc_htons(12345); + resolved_addr4.len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in)); return resolved_addr4; } static grpc_resolved_address make_addr6(const uint8_t* data, size_t data_len) { grpc_resolved_address resolved_addr6; - struct sockaddr_in6* addr6 = (struct sockaddr_in6*)resolved_addr6.addr; + grpc_sockaddr_in6* addr6 = + reinterpret_cast<grpc_sockaddr_in6*>(resolved_addr6.addr); memset(&resolved_addr6, 0, sizeof(resolved_addr6)); - addr6->sin6_family = AF_INET6; + addr6->sin6_family = GRPC_AF_INET6; GPR_ASSERT(data_len == sizeof(addr6->sin6_addr.s6_addr)); memcpy(&addr6->sin6_addr.s6_addr, data, data_len); - addr6->sin6_port = htons(12345); - resolved_addr6.len = sizeof(struct sockaddr_in6); + addr6->sin6_port = grpc_htons(12345); + resolved_addr6.len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in6)); return resolved_addr6; } static void set_addr6_scope_id(grpc_resolved_address* addr, uint32_t scope_id) { - struct sockaddr_in6* addr6 = (struct sockaddr_in6*)addr->addr; - GPR_ASSERT(addr6->sin6_family == AF_INET6); + grpc_sockaddr_in6* addr6 = reinterpret_cast<grpc_sockaddr_in6*>(addr->addr); + GPR_ASSERT(addr6->sin6_family == GRPC_AF_INET6); addr6->sin6_scope_id = scope_id; } @@ -128,9 +131,9 @@ static void test_sockaddr_is_wildcard(void) { grpc_resolved_address wild6; grpc_resolved_address wild_mapped; grpc_resolved_address dummy; - struct sockaddr_in* wild4_addr; - struct sockaddr_in6* wild6_addr; - struct sockaddr_in6* wild_mapped_addr; + grpc_sockaddr_in* wild4_addr; + grpc_sockaddr_in6* wild6_addr; + grpc_sockaddr_in6* wild_mapped_addr; int port; gpr_log(GPR_INFO, "%s", "test_sockaddr_is_wildcard"); @@ -143,7 +146,7 @@ static void test_sockaddr_is_wildcard(void) { port = -1; GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild4, &port)); GPR_ASSERT(port == 555); - wild4_addr = (struct sockaddr_in*)&wild4.addr; + wild4_addr = reinterpret_cast<grpc_sockaddr_in*>(&wild4.addr); memset(&wild4_addr->sin_addr.s_addr, 0xbd, 1); GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild4, &port)); @@ -151,7 +154,7 @@ static void test_sockaddr_is_wildcard(void) { port = -1; GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild6, &port)); GPR_ASSERT(port == 555); - wild6_addr = (struct sockaddr_in6*)&wild6.addr; + wild6_addr = reinterpret_cast<grpc_sockaddr_in6*>(&wild6.addr); memset(&wild6_addr->sin6_addr.s6_addr, 0xbd, 1); GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild6, &port)); @@ -159,7 +162,7 @@ static void test_sockaddr_is_wildcard(void) { port = -1; GPR_ASSERT(grpc_sockaddr_is_wildcard(&wild_mapped, &port)); GPR_ASSERT(port == 555); - wild_mapped_addr = (struct sockaddr_in6*)&wild_mapped.addr; + wild_mapped_addr = reinterpret_cast<grpc_sockaddr_in6*>(&wild_mapped.addr); memset(&wild_mapped_addr->sin6_addr.s6_addr, 0xbd, 1); GPR_ASSERT(!grpc_sockaddr_is_wildcard(&wild_mapped, &port)); @@ -197,7 +200,7 @@ static void test_sockaddr_to_string(void) { grpc_resolved_address input4; grpc_resolved_address input6; grpc_resolved_address dummy; - struct sockaddr* dummy_addr; + grpc_sockaddr* dummy_addr; gpr_log(GPR_INFO, "%s", "test_sockaddr_to_string"); @@ -234,7 +237,7 @@ static void test_sockaddr_to_string(void) { expect_sockaddr_uri("ipv6:[::fffe:c000:263]:12345", &input6); memset(&dummy, 0, sizeof(dummy)); - dummy_addr = (struct sockaddr*)dummy.addr; + dummy_addr = reinterpret_cast<grpc_sockaddr*>(dummy.addr); dummy_addr->sa_family = 123; expect_sockaddr_str("(sockaddr family=123)", &dummy, 0); expect_sockaddr_str("(sockaddr family=123)", &dummy, 1); @@ -245,7 +248,7 @@ static void test_sockaddr_set_get_port(void) { grpc_resolved_address input4; grpc_resolved_address input6; grpc_resolved_address dummy; - struct sockaddr* dummy_addr; + grpc_sockaddr* dummy_addr; gpr_log(GPR_DEBUG, "test_sockaddr_set_get_port"); @@ -260,7 +263,7 @@ static void test_sockaddr_set_get_port(void) { GPR_ASSERT(grpc_sockaddr_get_port(&input6) == 54321); memset(&dummy, 0, sizeof(dummy)); - dummy_addr = (struct sockaddr*)dummy.addr; + dummy_addr = reinterpret_cast<grpc_sockaddr*>(dummy.addr); dummy_addr->sa_family = 123; GPR_ASSERT(grpc_sockaddr_get_port(&dummy) == 0); GPR_ASSERT(grpc_sockaddr_set_port(&dummy, 1234) == 0); diff --git a/test/core/iomgr/socket_utils_test.cc b/test/core/iomgr/socket_utils_test.cc index 49c6f799e7..a21f3fac62 100644 --- a/test/core/iomgr/socket_utils_test.cc +++ b/test/core/iomgr/socket_utils_test.cc @@ -30,7 +30,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/socket_mutator.h" #include "test/core/util/test_config.h" @@ -42,7 +43,8 @@ struct test_socket_mutator { static bool mutate_fd(int fd, grpc_socket_mutator* mutator) { int newval; socklen_t intlen = sizeof(newval); - struct test_socket_mutator* m = (struct test_socket_mutator*)mutator; + struct test_socket_mutator* m = + reinterpret_cast<struct test_socket_mutator*>(mutator); if (0 != setsockopt(fd, IPPROTO_IP, IP_TOS, &m->option_value, sizeof(m->option_value))) { @@ -58,14 +60,17 @@ static bool mutate_fd(int fd, grpc_socket_mutator* mutator) { } static void destroy_test_mutator(grpc_socket_mutator* mutator) { - struct test_socket_mutator* m = (struct test_socket_mutator*)mutator; + struct test_socket_mutator* m = + reinterpret_cast<struct test_socket_mutator*>(mutator); gpr_free(m); } static int compare_test_mutator(grpc_socket_mutator* a, grpc_socket_mutator* b) { - struct test_socket_mutator* ma = (struct test_socket_mutator*)a; - struct test_socket_mutator* mb = (struct test_socket_mutator*)b; + struct test_socket_mutator* ma = + reinterpret_cast<struct test_socket_mutator*>(a); + struct test_socket_mutator* mb = + reinterpret_cast<struct test_socket_mutator*>(b); return GPR_ICMP(ma->option_value, mb->option_value); } @@ -116,7 +121,8 @@ int main(int argc, char** argv) { grpc_set_socket_with_mutator(sock, (grpc_socket_mutator*)&mutator))); mutator.option_value = -1; - err = grpc_set_socket_with_mutator(sock, (grpc_socket_mutator*)&mutator); + err = grpc_set_socket_with_mutator( + sock, reinterpret_cast<grpc_socket_mutator*>(&mutator)); GPR_ASSERT(err != GRPC_ERROR_NONE); GRPC_ERROR_UNREF(err); diff --git a/test/core/iomgr/tcp_client_posix_test.cc b/test/core/iomgr/tcp_client_posix_test.cc index 40a050ed9f..a4c38af86f 100644 --- a/test/core/iomgr/tcp_client_posix_test.cc +++ b/test/core/iomgr/tcp_client_posix_test.cc @@ -78,7 +78,8 @@ static void must_fail(void* arg, grpc_error* error) { void test_succeeds(void) { grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + struct sockaddr_in* addr = + reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); int svr_fd; int r; int connections_complete_before; @@ -88,7 +89,7 @@ void test_succeeds(void) { gpr_log(GPR_DEBUG, "test_succeeds"); memset(&resolved_addr, 0, sizeof(resolved_addr)); - resolved_addr.len = sizeof(struct sockaddr_in); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; /* create a dummy server */ @@ -111,8 +112,9 @@ void test_succeeds(void) { /* await the connection */ do { - resolved_addr.len = sizeof(addr); - r = accept(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len); + resolved_addr.len = static_cast<socklen_t>(sizeof(addr)); + r = accept(svr_fd, reinterpret_cast<struct sockaddr*>(addr), + reinterpret_cast<socklen_t*>(&resolved_addr.len)); } while (r == -1 && errno == EINTR); GPR_ASSERT(r >= 0); close(r); @@ -136,7 +138,8 @@ void test_succeeds(void) { void test_fails(void) { grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + struct sockaddr_in* addr = + reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); int connections_complete_before; grpc_closure done; grpc_core::ExecCtx exec_ctx; @@ -144,7 +147,7 @@ void test_fails(void) { gpr_log(GPR_DEBUG, "test_fails"); memset(&resolved_addr, 0, sizeof(resolved_addr)); - resolved_addr.len = sizeof(struct sockaddr_in); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; gpr_mu_lock(g_mu); diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index f4acba8302..f4df6fca23 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -34,8 +34,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/iomgr/endpoint_tests.h" #include "test/core/util/test_config.h" @@ -74,7 +74,7 @@ static ssize_t fill_socket(int fd) { int i; unsigned char buf[256]; for (i = 0; i < 256; ++i) { - buf[i] = (uint8_t)i; + buf[i] = static_cast<uint8_t>(i); } do { write_bytes = write(fd, buf, 256); @@ -89,16 +89,16 @@ static ssize_t fill_socket(int fd) { static size_t fill_socket_partial(int fd, size_t bytes) { ssize_t write_bytes; size_t total_bytes = 0; - unsigned char* buf = (unsigned char*)gpr_malloc(bytes); + unsigned char* buf = static_cast<unsigned char*>(gpr_malloc(bytes)); unsigned i; for (i = 0; i < bytes; ++i) { - buf[i] = (uint8_t)(i % 256); + buf[i] = static_cast<uint8_t>(i % 256); } do { write_bytes = write(fd, buf, bytes - total_bytes); if (write_bytes > 0) { - total_bytes += (size_t)write_bytes; + total_bytes += static_cast<size_t>(write_bytes); } } while ((write_bytes >= 0 || errno == EINTR) && bytes > total_bytes); @@ -132,7 +132,8 @@ static size_t count_slices(grpc_slice* slices, size_t nslices, } static void read_cb(void* user_data, grpc_error* error) { - struct read_socket_state* state = (struct read_socket_state*)user_data; + struct read_socket_state* state = + static_cast<struct read_socket_state*>(user_data); size_t read_bytes; int current_data; @@ -172,7 +173,8 @@ static void read_test(size_t num_bytes, size_t slice_size) { grpc_arg a[1]; a[0].key = const_cast<char*>(GRPC_ARG_TCP_READ_CHUNK_SIZE); - a[0].type = GRPC_ARG_INTEGER, a[0].value.integer = (int)slice_size; + a[0].type = GRPC_ARG_INTEGER, + a[0].value.integer = static_cast<int>(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), &args, "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); @@ -222,7 +224,7 @@ static void large_read_test(size_t slice_size) { grpc_arg a[1]; a[0].key = const_cast<char*>(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER; - a[0].value.integer = (int)slice_size; + a[0].value.integer = static_cast<int>(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), &args, "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); @@ -232,7 +234,7 @@ static void large_read_test(size_t slice_size) { state.ep = ep; state.read_bytes = 0; - state.target_read_bytes = (size_t)written_bytes; + state.target_read_bytes = static_cast<size_t>(written_bytes); grpc_slice_buffer_init(&state.incoming); GRPC_CLOSURE_INIT(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx); @@ -262,7 +264,8 @@ struct write_socket_state { static grpc_slice* allocate_blocks(size_t num_bytes, size_t slice_size, size_t* num_blocks, uint8_t* current_data) { size_t nslices = num_bytes / slice_size + (num_bytes % slice_size ? 1u : 0u); - grpc_slice* slices = (grpc_slice*)gpr_malloc(sizeof(grpc_slice) * nslices); + grpc_slice* slices = + static_cast<grpc_slice*>(gpr_malloc(sizeof(grpc_slice) * nslices)); size_t num_bytes_left = num_bytes; unsigned i, j; unsigned char* buf; @@ -284,7 +287,8 @@ static grpc_slice* allocate_blocks(size_t num_bytes, size_t slice_size, static void write_done(void* user_data /* write_socket_state */, grpc_error* error) { - struct write_socket_state* state = (struct write_socket_state*)user_data; + struct write_socket_state* state = + static_cast<struct write_socket_state*>(user_data); gpr_log(GPR_INFO, "Write done callback called"); gpr_mu_lock(g_mu); gpr_log(GPR_INFO, "Signalling write done"); @@ -295,7 +299,7 @@ static void write_done(void* user_data /* write_socket_state */, } void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) { - unsigned char* buf = (unsigned char*)gpr_malloc(read_size); + unsigned char* buf = static_cast<unsigned char*>(gpr_malloc(read_size)); ssize_t bytes_read; size_t bytes_left = num_bytes; int flags; @@ -325,7 +329,7 @@ void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) { GPR_ASSERT(buf[i] == current); current = (current + 1) % 256; } - bytes_left -= (size_t)bytes_read; + bytes_left -= static_cast<size_t>(bytes_read); if (bytes_left == 0) break; } flags = fcntl(fd, F_GETFL, 0); @@ -358,7 +362,8 @@ static void write_test(size_t num_bytes, size_t slice_size) { grpc_arg a[1]; a[0].key = const_cast<char*>(GRPC_ARG_TCP_READ_CHUNK_SIZE); - a[0].type = GRPC_ARG_INTEGER, a[0].value.integer = (int)slice_size; + a[0].type = GRPC_ARG_INTEGER, + a[0].value.integer = static_cast<int>(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"), &args, "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); @@ -395,7 +400,7 @@ static void write_test(size_t num_bytes, size_t slice_size) { } void on_fd_released(void* arg, grpc_error* errors) { - int* done = (int*)arg; + int* done = static_cast<int*>(arg); *done = 1; GPR_ASSERT( GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr))); @@ -426,7 +431,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { grpc_arg a[1]; a[0].key = const_cast<char*>(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER; - a[0].value.integer = (int)slice_size; + a[0].value.integer = static_cast<int>(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), &args, "test"); GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0); @@ -515,7 +520,7 @@ static grpc_endpoint_test_fixture create_fixture_tcp_socketpair( grpc_arg a[1]; a[0].key = const_cast<char*>(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER; - a[0].value.integer = (int)slice_size; + a[0].value.integer = static_cast<int>(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; f.client_ep = grpc_tcp_create(grpc_fd_create(sv[0], "fixture:client"), &args, "test"); @@ -533,7 +538,7 @@ static grpc_endpoint_test_config configs[] = { }; static void destroy_pollset(void* p, grpc_error* error) { - grpc_pollset_destroy((grpc_pollset*)p); + grpc_pollset_destroy(static_cast<grpc_pollset*>(p)); } int main(int argc, char** argv) { @@ -542,7 +547,7 @@ int main(int argc, char** argv) { grpc_init(); { grpc_core::ExecCtx exec_ctx; - g_pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); + g_pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(g_pollset, &g_mu); grpc_endpoint_tests(configs[0], g_pollset, g_mu); run_tests(); diff --git a/test/core/iomgr/tcp_server_posix_test.cc b/test/core/iomgr/tcp_server_posix_test.cc index 3c9ca2109e..d646df1dae 100644 --- a/test/core/iomgr/tcp_server_posix_test.cc +++ b/test/core/iomgr/tcp_server_posix_test.cc @@ -181,13 +181,14 @@ static void test_no_op_with_start(void) { static void test_no_op_with_port(void) { grpc_core::ExecCtx exec_ctx; grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + struct sockaddr_in* addr = + reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); grpc_tcp_server* s; GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, nullptr, &s)); LOG_TEST("test_no_op_with_port"); memset(&resolved_addr, 0, sizeof(resolved_addr)); - resolved_addr.len = sizeof(struct sockaddr_in); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; int port = -1; GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) == @@ -200,14 +201,15 @@ static void test_no_op_with_port(void) { static void test_no_op_with_port_and_start(void) { grpc_core::ExecCtx exec_ctx; grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + struct sockaddr_in* addr = + reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); grpc_tcp_server* s; GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, nullptr, &s)); LOG_TEST("test_no_op_with_port_and_start"); int port = -1; memset(&resolved_addr, 0, sizeof(resolved_addr)); - resolved_addr.len = sizeof(struct sockaddr_in); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; GPR_ASSERT(grpc_tcp_server_add_port(s, &resolved_addr, &port) == GRPC_ERROR_NONE && @@ -225,7 +227,7 @@ static grpc_error* tcp_connect(const test_addr* remote, int clifd; int nconnects_before; const struct sockaddr* remote_addr = - (const struct sockaddr*)remote->addr.addr; + reinterpret_cast<const struct sockaddr*>(remote->addr.addr); gpr_log(GPR_INFO, "Connecting to %s", remote->str); gpr_mu_lock(g_mu); @@ -237,7 +239,8 @@ static grpc_error* tcp_connect(const test_addr* remote, return GRPC_OS_ERROR(errno, "Failed to create socket"); } gpr_log(GPR_DEBUG, "start connect to %s", remote->str); - if (connect(clifd, remote_addr, (socklen_t)remote->addr.len) != 0) { + if (connect(clifd, remote_addr, static_cast<socklen_t>(remote->addr.len)) != + 0) { gpr_mu_unlock(g_mu); close(clifd); return GRPC_OS_ERROR(errno, "connect"); @@ -286,9 +289,9 @@ static void test_connect(size_t num_connects, grpc_resolved_address resolved_addr; grpc_resolved_address resolved_addr1; struct sockaddr_storage* const addr = - (struct sockaddr_storage*)resolved_addr.addr; + reinterpret_cast<struct sockaddr_storage*>(resolved_addr.addr); struct sockaddr_storage* const addr1 = - (struct sockaddr_storage*)resolved_addr1.addr; + reinterpret_cast<struct sockaddr_storage*>(resolved_addr1.addr); unsigned svr_fd_count; int port; int svr_port; @@ -305,13 +308,14 @@ static void test_connect(size_t num_connects, LOG_TEST("test_connect"); gpr_log(GPR_INFO, "clients=%lu, num chan args=%lu, remote IP=%s, test_dst_addrs=%d", - (unsigned long)num_connects, - (unsigned long)(channel_args != nullptr ? channel_args->num_args : 0), + static_cast<unsigned long>(num_connects), + static_cast<unsigned long>( + channel_args != nullptr ? channel_args->num_args : 0), dst_addrs != nullptr ? "<specific>" : "::", test_dst_addrs); memset(&resolved_addr, 0, sizeof(resolved_addr)); memset(&resolved_addr1, 0, sizeof(resolved_addr1)); - resolved_addr.len = sizeof(struct sockaddr_storage); - resolved_addr1.len = sizeof(struct sockaddr_storage); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage)); + resolved_addr1.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage)); addr->ss_family = addr1->ss_family = AF_INET; GPR_ASSERT(GRPC_LOG_IF_ERROR( "grpc_tcp_server_add_port", @@ -383,7 +387,7 @@ static void test_connect(size_t num_connects, size_t connect_num; test_addr dst; GPR_ASSERT(fd >= 0); - dst.addr.len = sizeof(dst.addr.addr); + dst.addr.len = static_cast<socklen_t>(sizeof(dst.addr.addr)); GPR_ASSERT(getsockname(fd, (struct sockaddr*)dst.addr.addr, (socklen_t*)&dst.addr.len) == 0); GPR_ASSERT(dst.addr.len <= sizeof(dst.addr.addr)); @@ -456,10 +460,10 @@ int main(int argc, char** argv) { continue; } else if (ifa_it->ifa_addr->sa_family == AF_INET) { dst_addrs->addrs[dst_addrs->naddrs].addr.len = - sizeof(struct sockaddr_in); + static_cast<socklen_t>(sizeof(struct sockaddr_in)); } else if (ifa_it->ifa_addr->sa_family == AF_INET6) { dst_addrs->addrs[dst_addrs->naddrs].addr.len = - sizeof(struct sockaddr_in6); + static_cast<socklen_t>(sizeof(struct sockaddr_in6)); } else { continue; } diff --git a/test/core/iomgr/timer_heap_test.cc b/test/core/iomgr/timer_heap_test.cc index f0ab4343cb..ebe5e6610d 100644 --- a/test/core/iomgr/timer_heap_test.cc +++ b/test/core/iomgr/timer_heap_test.cc @@ -18,9 +18,6 @@ #include "src/core/lib/iomgr/port.h" -// This test only works with the generic timer implementation -#ifdef GRPC_TIMER_USE_GENERIC - #include "src/core/lib/iomgr/timer_heap.h" #include <stdlib.h> @@ -28,8 +25,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "test/core/util/test_config.h" static gpr_atm random_deadline(void) { return rand(); } @@ -102,7 +99,7 @@ static void test1(void) { check_valid(&pq); for (i = 0; i < num_test_operations; ++i) { - size_t elem_num = (size_t)rand() % num_test_elements; + size_t elem_num = static_cast<size_t>(rand()) % num_test_elements; grpc_timer* el = &test_elements[elem_num]; if (!inpq[elem_num]) { /* not in pq */ GPR_ASSERT(!contains(&pq, el)); @@ -142,8 +139,8 @@ static elem_struct* search_elems(elem_struct* elems, size_t count, search_order[i] = i; } for (size_t i = 0; i < count * 2; i++) { - size_t a = (size_t)rand() % count; - size_t b = (size_t)rand() % count; + size_t a = static_cast<size_t>(rand()) % count; + size_t b = static_cast<size_t>(rand()) % count; GPR_SWAP(size_t, search_order[a], search_order[b]); } elem_struct* out = nullptr; @@ -207,7 +204,7 @@ static void test2(void) { } if (num_inserted) { - gpr_atm* min_deadline = nullptr; + grpc_millis* min_deadline = nullptr; for (size_t i = 0; i < elems_size; i++) { if (elems[i].inserted) { if (min_deadline == nullptr) { @@ -235,7 +232,7 @@ static void shrink_test(void) { size_t expected_size; /* A large random number to allow for multiple shrinkages, at least 512. */ - const size_t num_elements = (size_t)rand() % 2000 + 512; + const size_t num_elements = static_cast<size_t>(rand()) % 2000 + 512; grpc_timer_heap_init(&pq); @@ -265,7 +262,7 @@ static void shrink_test(void) { 4 times the Size and not less than 2 times, but never goes below 16. */ expected_size = pq.timer_count; while (pq.timer_count > 0) { - const size_t which = (size_t)rand() % pq.timer_count; + const size_t which = static_cast<size_t>(rand()) % pq.timer_count; grpc_timer* te = pq.timers[which]; grpc_timer_heap_remove(&pq, te); gpr_free(te); @@ -299,9 +296,3 @@ int main(int argc, char** argv) { return 0; } - -#else /* GRPC_TIMER_USE_GENERIC */ - -int main(int argc, char** argv) { return 1; } - -#endif /* GRPC_TIMER_USE_GENERIC */ diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc index deb8c4d87e..b1d919b292 100644 --- a/test/core/iomgr/timer_list_test.cc +++ b/test/core/iomgr/timer_list_test.cc @@ -19,8 +19,9 @@ #include "src/core/lib/iomgr/port.h" // This test only works with the generic timer implementation -#ifdef GRPC_TIMER_USE_GENERIC +#ifndef GRPC_CUSTOM_SOCKET +#include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/timer.h" #include <string.h> @@ -153,15 +154,19 @@ void destruction_test(void) { int main(int argc, char** argv) { grpc_test_init(argc, argv); grpc_core::ExecCtx::GlobalInit(); + grpc_core::ExecCtx exec_ctx; + grpc_determine_iomgr_platform(); + grpc_iomgr_platform_init(); gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); add_test(); destruction_test(); + grpc_iomgr_platform_shutdown(); grpc_core::ExecCtx::GlobalShutdown(); return 0; } -#else /* GRPC_TIMER_USE_GENERIC */ +#else /* GRPC_CUSTOM_SOCKET */ int main(int argc, char** argv) { return 1; } -#endif /* GRPC_TIMER_USE_GENERIC */ +#endif /* GRPC_CUSTOM_SOCKET */ diff --git a/test/core/iomgr/udp_server_test.cc b/test/core/iomgr/udp_server_test.cc index 0deb534abd..d167c0131f 100644 --- a/test/core/iomgr/udp_server_test.cc +++ b/test/core/iomgr/udp_server_test.cc @@ -33,12 +33,14 @@ #include <grpc/support/log.h> #include <grpc/support/sync.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/socket_factory_posix.h" +#include "src/core/lib/iomgr/socket_utils_posix.h" #include "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x) @@ -49,41 +51,78 @@ static int g_number_of_reads = 0; static int g_number_of_writes = 0; static int g_number_of_bytes_read = 0; static int g_number_of_orphan_calls = 0; +static int g_number_of_starts = 0; -static bool on_read(grpc_fd* emfd, void* user_data) { - char read_buffer[512]; - ssize_t byte_count; +int rcv_buf_size = 1024; +int snd_buf_size = 1024; - gpr_mu_lock(g_mu); - byte_count = - recv(grpc_fd_wrapped_fd(emfd), read_buffer, sizeof(read_buffer), 0); +static int g_num_listeners = 1; - g_number_of_reads++; - g_number_of_bytes_read += (int)byte_count; +class TestGrpcUdpHandler : public GrpcUdpHandler { + public: + TestGrpcUdpHandler(grpc_fd* emfd, void* user_data) + : GrpcUdpHandler(emfd, user_data), emfd_(emfd) { + g_number_of_starts++; + } + ~TestGrpcUdpHandler() override {} - GPR_ASSERT( - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr))); - gpr_mu_unlock(g_mu); - return false; -} + protected: + bool Read() override { + char read_buffer[512]; + ssize_t byte_count; -static void on_write(grpc_fd* emfd, void* user_data, - grpc_closure* notify_on_write_closure) { - gpr_mu_lock(g_mu); - g_number_of_writes++; + gpr_mu_lock(g_mu); + byte_count = + recv(grpc_fd_wrapped_fd(emfd()), read_buffer, sizeof(read_buffer), 0); - GPR_ASSERT( - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr))); - gpr_mu_unlock(g_mu); -} + g_number_of_reads++; + g_number_of_bytes_read += static_cast<int>(byte_count); -static void on_fd_orphaned(grpc_fd* emfd, grpc_closure* closure, - void* user_data) { - gpr_log(GPR_INFO, "gRPC FD about to be orphaned: %d", - grpc_fd_wrapped_fd(emfd)); - GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_NONE); - g_number_of_orphan_calls++; -} + gpr_log(GPR_DEBUG, "receive %zu on handler %p", byte_count, this); + GPR_ASSERT(GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_pollset, nullptr))); + gpr_mu_unlock(g_mu); + return false; + } + + void OnCanWrite(void* user_data, + grpc_closure* notify_on_write_closure) override { + gpr_mu_lock(g_mu); + g_number_of_writes++; + + GPR_ASSERT(GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_pollset, nullptr))); + gpr_mu_unlock(g_mu); + } + + void OnFdAboutToOrphan(grpc_closure* orphan_fd_closure, + void* user_data) override { + gpr_log(GPR_INFO, "gRPC FD about to be orphaned: %d", + grpc_fd_wrapped_fd(emfd())); + GRPC_CLOSURE_SCHED(orphan_fd_closure, GRPC_ERROR_NONE); + g_number_of_orphan_calls++; + } + + grpc_fd* emfd() { return emfd_; } + + private: + grpc_fd* emfd_; +}; + +class TestGrpcUdpHandlerFactory : public GrpcUdpHandlerFactory { + public: + GrpcUdpHandler* CreateUdpHandler(grpc_fd* emfd, void* user_data) override { + gpr_log(GPR_INFO, "create udp handler for fd %d", grpc_fd_wrapped_fd(emfd)); + return grpc_core::New<TestGrpcUdpHandler>(emfd, user_data); + } + + void DestroyUdpHandler(GrpcUdpHandler* handler) override { + gpr_log(GPR_INFO, "Destroy handler"); + grpc_core::Delete(reinterpret_cast<TestGrpcUdpHandler*>(handler)); + } +}; + +TestGrpcUdpHandlerFactory handler_factory; struct test_socket_factory { grpc_socket_factory base; @@ -94,16 +133,18 @@ typedef struct test_socket_factory test_socket_factory; static int test_socket_factory_socket(grpc_socket_factory* factory, int domain, int type, int protocol) { - test_socket_factory* f = (test_socket_factory*)factory; + test_socket_factory* f = reinterpret_cast<test_socket_factory*>(factory); f->number_of_socket_calls++; return socket(domain, type, protocol); } static int test_socket_factory_bind(grpc_socket_factory* factory, int sockfd, const grpc_resolved_address* addr) { - test_socket_factory* f = (test_socket_factory*)factory; + test_socket_factory* f = reinterpret_cast<test_socket_factory*>(factory); f->number_of_bind_calls++; - return bind(sockfd, (struct sockaddr*)addr->addr, (socklen_t)addr->len); + return bind(sockfd, + reinterpret_cast<struct sockaddr*>(const_cast<char*>(addr->addr)), + static_cast<socklen_t>(addr->len)); } static int test_socket_factory_compare(grpc_socket_factory* a, @@ -112,7 +153,7 @@ static int test_socket_factory_compare(grpc_socket_factory* a, } static void test_socket_factory_destroy(grpc_socket_factory* factory) { - test_socket_factory* f = (test_socket_factory*)factory; + test_socket_factory* f = reinterpret_cast<test_socket_factory*>(factory); gpr_free(f); } @@ -129,45 +170,70 @@ static test_socket_factory* test_socket_factory_create(void) { return factory; } +static void destroy_pollset(void* p, grpc_error* error) { + grpc_pollset_destroy(static_cast<grpc_pollset*>(p)); +} + +static void shutdown_and_destroy_pollset() { + gpr_mu_lock(g_mu); + auto closure = GRPC_CLOSURE_CREATE(destroy_pollset, g_pollset, + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(g_pollset, closure); + gpr_mu_unlock(g_mu); + /* Flush exec_ctx to run |destroyed| */ + grpc_core::ExecCtx::Get()->Flush(); +} + static void test_no_op(void) { + grpc_pollset_init(g_pollset, &g_mu); grpc_core::ExecCtx exec_ctx; grpc_udp_server* s = grpc_udp_server_create(nullptr); + LOG_TEST("test_no_op"); grpc_udp_server_destroy(s, nullptr); + shutdown_and_destroy_pollset(); } static void test_no_op_with_start(void) { + grpc_pollset_init(g_pollset, &g_mu); grpc_core::ExecCtx exec_ctx; grpc_udp_server* s = grpc_udp_server_create(nullptr); LOG_TEST("test_no_op_with_start"); grpc_udp_server_start(s, nullptr, 0, nullptr); grpc_udp_server_destroy(s, nullptr); + shutdown_and_destroy_pollset(); } static void test_no_op_with_port(void) { + grpc_pollset_init(g_pollset, &g_mu); g_number_of_orphan_calls = 0; grpc_core::ExecCtx exec_ctx; grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + struct sockaddr_in* addr = + reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); grpc_udp_server* s = grpc_udp_server_create(nullptr); LOG_TEST("test_no_op_with_port"); memset(&resolved_addr, 0, sizeof(resolved_addr)); - resolved_addr.len = sizeof(struct sockaddr_in); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; - GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, on_read, on_write, - on_fd_orphaned)); + GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size, + snd_buf_size, &handler_factory, + g_num_listeners)); grpc_udp_server_destroy(s, nullptr); - /* The server had a single FD, which should have been orphaned. */ - GPR_ASSERT(g_number_of_orphan_calls == 1); + /* The server haven't start listening, so no udp handler to be notified. */ + GPR_ASSERT(g_number_of_orphan_calls == 0); + shutdown_and_destroy_pollset(); } static void test_no_op_with_port_and_socket_factory(void) { + grpc_pollset_init(g_pollset, &g_mu); g_number_of_orphan_calls = 0; grpc_core::ExecCtx exec_ctx; grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + struct sockaddr_in* addr = + reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); test_socket_factory* socket_factory = test_socket_factory_create(); grpc_arg socket_factory_arg = @@ -180,48 +246,56 @@ static void test_no_op_with_port_and_socket_factory(void) { LOG_TEST("test_no_op_with_port_and_socket_factory"); memset(&resolved_addr, 0, sizeof(resolved_addr)); - resolved_addr.len = sizeof(struct sockaddr_in); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; - GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, on_read, on_write, - on_fd_orphaned)); - GPR_ASSERT(socket_factory->number_of_socket_calls == 1); - GPR_ASSERT(socket_factory->number_of_bind_calls == 1); + GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size, + snd_buf_size, &handler_factory, + g_num_listeners)); + GPR_ASSERT(socket_factory->number_of_socket_calls == g_num_listeners); + GPR_ASSERT(socket_factory->number_of_bind_calls == g_num_listeners); grpc_udp_server_destroy(s, nullptr); grpc_socket_factory_unref(&socket_factory->base); - /* The server had a single FD, which should have been orphaned. */ - GPR_ASSERT(g_number_of_orphan_calls == 1); + /* The server haven't start listening, so no udp handler to be notified. */ + GPR_ASSERT(g_number_of_orphan_calls == 0); + shutdown_and_destroy_pollset(); } static void test_no_op_with_port_and_start(void) { + grpc_pollset_init(g_pollset, &g_mu); g_number_of_orphan_calls = 0; grpc_core::ExecCtx exec_ctx; grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + struct sockaddr_in* addr = + reinterpret_cast<struct sockaddr_in*>(resolved_addr.addr); grpc_udp_server* s = grpc_udp_server_create(nullptr); LOG_TEST("test_no_op_with_port_and_start"); memset(&resolved_addr, 0, sizeof(resolved_addr)); - resolved_addr.len = sizeof(struct sockaddr_in); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; - GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, on_read, on_write, - on_fd_orphaned)); + GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size, + snd_buf_size, &handler_factory, + g_num_listeners)); grpc_udp_server_start(s, nullptr, 0, nullptr); - + GPR_ASSERT(g_number_of_starts == g_num_listeners); grpc_udp_server_destroy(s, nullptr); /* The server had a single FD, which is orphaned exactly once in * * grpc_udp_server_destroy. */ - GPR_ASSERT(g_number_of_orphan_calls == 1); + GPR_ASSERT(g_number_of_orphan_calls == g_num_listeners); + shutdown_and_destroy_pollset(); } static void test_receive(int number_of_clients) { + grpc_pollset_init(g_pollset, &g_mu); grpc_core::ExecCtx exec_ctx; grpc_resolved_address resolved_addr; - struct sockaddr_storage* addr = (struct sockaddr_storage*)resolved_addr.addr; + struct sockaddr_storage* addr = + reinterpret_cast<struct sockaddr_storage*>(resolved_addr.addr); int clifd, svrfd; grpc_udp_server* s = grpc_udp_server_create(nullptr); int i; @@ -234,10 +308,11 @@ static void test_receive(int number_of_clients) { g_number_of_orphan_calls = 0; memset(&resolved_addr, 0, sizeof(resolved_addr)); - resolved_addr.len = sizeof(struct sockaddr_storage); + resolved_addr.len = static_cast<socklen_t>(sizeof(struct sockaddr_storage)); addr->ss_family = AF_INET; - GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, on_read, on_write, - on_fd_orphaned)); + GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size, + snd_buf_size, &handler_factory, + g_num_listeners)); svrfd = grpc_udp_server_get_fd(s, 0); GPR_ASSERT(svrfd >= 0); @@ -280,21 +355,19 @@ static void test_receive(int number_of_clients) { /* The server had a single FD, which is orphaned exactly once in * * grpc_udp_server_destroy. */ - GPR_ASSERT(g_number_of_orphan_calls == 1); -} - -static void destroy_pollset(void* p, grpc_error* error) { - grpc_pollset_destroy(static_cast<grpc_pollset*>(p)); + GPR_ASSERT(g_number_of_orphan_calls == g_num_listeners); + shutdown_and_destroy_pollset(); } int main(int argc, char** argv) { - grpc_closure destroyed; grpc_test_init(argc, argv); grpc_init(); + if (grpc_is_socket_reuse_port_supported()) { + g_num_listeners = 10; + } { grpc_core::ExecCtx exec_ctx; g_pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); - grpc_pollset_init(g_pollset, &g_mu); test_no_op(); test_no_op_with_start(); @@ -304,10 +377,6 @@ int main(int argc, char** argv) { test_receive(1); test_receive(10); - GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, - grpc_schedule_on_exec_ctx); - grpc_pollset_shutdown(g_pollset, &destroyed); - grpc_core::ExecCtx::Get()->Flush(); gpr_free(g_pollset); } grpc_shutdown(); diff --git a/test/core/iomgr/wakeup_fd_cv_test.cc b/test/core/iomgr/wakeup_fd_cv_test.cc index d4e05bd7ef..f297a569d2 100644 --- a/test/core/iomgr/wakeup_fd_cv_test.cc +++ b/test/core/iomgr/wakeup_fd_cv_test.cc @@ -23,13 +23,12 @@ #include <pthread.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/iomgr_posix.h" -#include "src/core/lib/support/env.h" typedef struct poll_args { struct pollfd* fds; @@ -85,7 +84,7 @@ int mock_poll(struct pollfd* fds, nfds_t nfds, int timeout) { } void background_poll(void* args) { - poll_args* pargs = (poll_args*)args; + poll_args* pargs = static_cast<poll_args*>(args); pargs->result = grpc_poll_function(pargs->fds, pargs->nfds, pargs->timeout); } @@ -104,8 +103,6 @@ void test_poll_cv_trigger(void) { grpc_wakeup_fd cvfd1, cvfd2, cvfd3; struct pollfd pfds[6]; poll_args pargs; - gpr_thd_id t_id; - gpr_thd_options opt; GPR_ASSERT(grpc_wakeup_fd_init(&cvfd1) == GRPC_ERROR_NONE); GPR_ASSERT(grpc_wakeup_fd_init(&cvfd2) == GRPC_ERROR_NONE); @@ -136,79 +133,91 @@ void test_poll_cv_trigger(void) { pargs.timeout = 1000; pargs.result = -2; - opt = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&opt); - gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt); - - // Wakeup wakeup_fd not listening for events - GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE); - gpr_thd_join(t_id); - GPR_ASSERT(pargs.result == 0); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - - // Pollin on socket fd - pargs.timeout = -1; - pargs.result = -2; - gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt); - trigger_socket_event(); - gpr_thd_join(t_id); - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == POLLIN); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - - // Pollin on wakeup fd - reset_socket_event(); - pargs.result = -2; - gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt); - GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE); - gpr_thd_join(t_id); - - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == POLLIN); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - - // Pollin on wakeupfd before poll() - pargs.result = -2; - gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt); - gpr_thd_join(t_id); - - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == POLLIN); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - - // No Events - pargs.result = -2; - pargs.timeout = 1000; - reset_socket_event(); - GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE); - gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt); - gpr_thd_join(t_id); - - GPR_ASSERT(pargs.result == 0); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); + { + grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); + thd.Start(); + // Wakeup wakeup_fd not listening for events + GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE); + thd.Join(); + GPR_ASSERT(pargs.result == 0); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + } + + { + // Pollin on socket fd + pargs.timeout = -1; + pargs.result = -2; + grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); + thd.Start(); + trigger_socket_event(); + thd.Join(); + GPR_ASSERT(pargs.result == 1); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == POLLIN); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + } + + { + // Pollin on wakeup fd + reset_socket_event(); + pargs.result = -2; + grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); + thd.Start(); + GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE); + thd.Join(); + + GPR_ASSERT(pargs.result == 1); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == POLLIN); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + } + + { + // Pollin on wakeupfd before poll() + pargs.result = -2; + grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); + thd.Start(); + thd.Join(); + + GPR_ASSERT(pargs.result == 1); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == POLLIN); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + } + + { + // No Events + pargs.result = -2; + pargs.timeout = 1000; + reset_socket_event(); + GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE); + grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); + thd.Start(); + thd.Join(); + + GPR_ASSERT(pargs.result == 0); + GPR_ASSERT(pfds[0].revents == 0); + GPR_ASSERT(pfds[1].revents == 0); + GPR_ASSERT(pfds[2].revents == 0); + GPR_ASSERT(pfds[3].revents == 0); + GPR_ASSERT(pfds[4].revents == 0); + GPR_ASSERT(pfds[5].revents == 0); + } } int main(int argc, char** argv) { @@ -216,7 +225,7 @@ int main(int argc, char** argv) { grpc_poll_function = &mock_poll; gpr_mu_init(&poll_mu); gpr_cv_init(&poll_cv); - + grpc_determine_iomgr_platform(); grpc_iomgr_platform_init(); test_many_fds(); grpc_iomgr_platform_shutdown(); diff --git a/test/core/json/json_rewrite.cc b/test/core/json/json_rewrite.cc index 6891a57f9f..da2f50ec59 100644 --- a/test/core/json/json_rewrite.cc +++ b/test/core/json/json_rewrite.cc @@ -20,11 +20,11 @@ #include <stdlib.h> #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> #include "src/core/lib/json/json_reader.h" #include "src/core/lib/json/json_writer.h" +#include "test/core/util/cmdline.h" typedef struct json_writer_userdata { FILE* out; @@ -86,7 +86,7 @@ static void json_reader_string_add_char(void* userdata, uint32_t c) { json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); check_string(state, 1); GPR_ASSERT(c < 256); - state->scratchpad[state->string_len++] = (char)c; + state->scratchpad[state->string_len++] = static_cast<char>(c); } static void json_reader_string_add_utf32(void* userdata, uint32_t c) { @@ -122,7 +122,7 @@ static uint32_t json_reader_read_char(void* userdata) { r = fgetc(state->in); if (r == EOF) r = GRPC_JSON_READ_CHAR_EOF; - return (uint32_t)r; + return static_cast<uint32_t>(r); } static void json_reader_container_begins(void* userdata, grpc_json_type type) { diff --git a/test/core/json/json_rewrite_test.cc b/test/core/json/json_rewrite_test.cc index 3104afc442..2fade12e13 100644 --- a/test/core/json/json_rewrite_test.cc +++ b/test/core/json/json_rewrite_test.cc @@ -21,9 +21,9 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> #include "test/core/util/test_config.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/json/json_reader.h" #include "src/core/lib/json/json_writer.h" @@ -97,7 +97,7 @@ static void json_reader_string_add_char(void* userdata, uint32_t c) { json_reader_userdata* state = static_cast<json_reader_userdata*>(userdata); check_string(state, 1); GPR_ASSERT(c <= 256); - state->scratchpad[state->string_len++] = (char)c; + state->scratchpad[state->string_len++] = static_cast<char>(c); } static void json_reader_string_add_utf32(void* userdata, uint32_t c) { @@ -140,7 +140,7 @@ static uint32_t json_reader_read_char(void* userdata) { r = fgetc(state->in); if (r == EOF) r = GRPC_JSON_READ_CHAR_EOF; - return (uint32_t)r; + return static_cast<uint32_t>(r); } static void json_reader_container_begins(void* userdata, grpc_json_type type) { diff --git a/test/core/json/json_stream_error_test.cc b/test/core/json/json_stream_error_test.cc index b367d3fbf7..00288d6d5e 100644 --- a/test/core/json/json_stream_error_test.cc +++ b/test/core/json/json_stream_error_test.cc @@ -21,7 +21,6 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> #include "test/core/util/test_config.h" #include "src/core/lib/json/json_reader.h" diff --git a/test/core/json/json_test.cc b/test/core/json/json_test.cc index 18b9c55ee7..7f1dbb774a 100644 --- a/test/core/json/json_test.cc +++ b/test/core/json/json_test.cc @@ -21,9 +21,9 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/json/json.h" -#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc index eb90067970..3c3fa53b51 100644 --- a/test/core/memory_usage/client.cc +++ b/test/core/memory_usage/client.cc @@ -24,12 +24,13 @@ #include <grpc/byte_buffer.h> #include <grpc/byte_buffer_reader.h> #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" + +#include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" #include "test/core/util/test_config.h" @@ -154,16 +155,20 @@ static struct grpc_memory_counters send_snapshot_request(int call_idx, struct grpc_memory_counters snapshot; snapshot.total_size_absolute = - ((struct grpc_memory_counters*)GRPC_SLICE_START_PTR(response)) + (reinterpret_cast<struct grpc_memory_counters*> GRPC_SLICE_START_PTR( + response)) ->total_size_absolute; snapshot.total_allocs_absolute = - ((struct grpc_memory_counters*)GRPC_SLICE_START_PTR(response)) + (reinterpret_cast<struct grpc_memory_counters*> GRPC_SLICE_START_PTR( + response)) ->total_allocs_absolute; snapshot.total_size_relative = - ((struct grpc_memory_counters*)GRPC_SLICE_START_PTR(response)) + (reinterpret_cast<struct grpc_memory_counters*> GRPC_SLICE_START_PTR( + response)) ->total_size_relative; snapshot.total_allocs_relative = - ((struct grpc_memory_counters*)GRPC_SLICE_START_PTR(response)) + (reinterpret_cast<struct grpc_memory_counters*> GRPC_SLICE_START_PTR( + response)) ->total_allocs_relative; grpc_metadata_array_destroy(&calls[call_idx].initial_metadata_recv); @@ -283,10 +288,11 @@ int main(int argc, char** argv) { grpc_shutdown(); gpr_log(GPR_INFO, "---------client stats--------"); - gpr_log(GPR_INFO, "client call memory usage: %f bytes per call", - (double)(client_calls_inflight.total_size_relative - - client_benchmark_calls_start.total_size_relative) / - benchmark_iterations); + gpr_log( + GPR_INFO, "client call memory usage: %f bytes per call", + static_cast<double>(client_calls_inflight.total_size_relative - + client_benchmark_calls_start.total_size_relative) / + benchmark_iterations); gpr_log(GPR_INFO, "client channel memory usage %zi bytes", client_channel_end.total_size_relative - client_channel_start.total_size_relative); @@ -295,10 +301,11 @@ int main(int argc, char** argv) { gpr_log(GPR_INFO, "server create: %zi bytes", after_server_create.total_size_relative - before_server_create.total_size_relative); - gpr_log(GPR_INFO, "server call memory usage: %f bytes per call", - (double)(server_calls_inflight.total_size_relative - - server_benchmark_calls_start.total_size_relative) / - benchmark_iterations); + gpr_log( + GPR_INFO, "server call memory usage: %f bytes per call", + static_cast<double>(server_calls_inflight.total_size_relative - + server_benchmark_calls_start.total_size_relative) / + benchmark_iterations); gpr_log(GPR_INFO, "server channel memory usage %zi bytes", server_calls_end.total_size_relative - after_server_create.total_size_relative); @@ -308,21 +315,22 @@ int main(int argc, char** argv) { if (csv) { char* env_build = gpr_getenv("BUILD_NUMBER"); char* env_job = gpr_getenv("JOB_NAME"); - fprintf(csv, "%f,%zi,%zi,%f,%zi,%s,%s\n", - (double)(client_calls_inflight.total_size_relative - - client_benchmark_calls_start.total_size_relative) / - benchmark_iterations, - client_channel_end.total_size_relative - - client_channel_start.total_size_relative, - after_server_create.total_size_relative - - before_server_create.total_size_relative, - (double)(server_calls_inflight.total_size_relative - - server_benchmark_calls_start.total_size_relative) / - benchmark_iterations, - server_calls_end.total_size_relative - - after_server_create.total_size_relative, - env_build == nullptr ? "" : env_build, - env_job == nullptr ? "" : env_job); + fprintf( + csv, "%f,%zi,%zi,%f,%zi,%s,%s\n", + static_cast<double>(client_calls_inflight.total_size_relative - + client_benchmark_calls_start.total_size_relative) / + benchmark_iterations, + client_channel_end.total_size_relative - + client_channel_start.total_size_relative, + after_server_create.total_size_relative - + before_server_create.total_size_relative, + static_cast<double>(server_calls_inflight.total_size_relative - + server_benchmark_calls_start.total_size_relative) / + benchmark_iterations, + server_calls_end.total_size_relative - + after_server_create.total_size_relative, + env_build == nullptr ? "" : env_build, + env_job == nullptr ? "" : env_job); fclose(csv); gpr_log(GPR_INFO, "Summary written to %s", csv_file); } diff --git a/test/core/memory_usage/memory_usage_test.cc b/test/core/memory_usage/memory_usage_test.cc index 58e31c9531..c170f5ad26 100644 --- a/test/core/memory_usage/memory_usage_test.cc +++ b/test/core/memory_usage/memory_usage_test.cc @@ -20,11 +20,12 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/string_util.h> -#include <grpc/support/subprocess.h> -#include "src/core/lib/support/string.h" + +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" +#include "test/core/util/subprocess.h" int main(int argc, char** argv) { char* me = argv[0]; @@ -36,7 +37,7 @@ int main(int argc, char** argv) { gpr_subprocess *svr, *cli; /* figure out where we are */ if (lslash) { - memcpy(root, me, (size_t)(lslash - me)); + memcpy(root, me, static_cast<size_t>(lslash - me)); root[lslash - me] = 0; } else { strcpy(root, "."); diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 60ebcece3e..3e7bb7e11f 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -30,11 +30,12 @@ #endif #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/time.h> + +#include "src/core/lib/gpr/host_port.h" #include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -72,7 +73,7 @@ typedef struct { static fling_call calls[100006]; static void request_call_unary(int call_idx) { - if (call_idx == (int)(sizeof(calls) / sizeof(fling_call))) { + if (call_idx == static_cast<int>(sizeof(calls) / sizeof(fling_call))) { gpr_log(GPR_INFO, "Used all call slots (10000) on server. Server exit."); _exit(0); } @@ -83,7 +84,8 @@ static void request_call_unary(int call_idx) { } static void send_initial_metadata_unary(void* tag) { - grpc_metadata_array_init(&(*(fling_call*)tag).initial_metadata_send); + grpc_metadata_array_init( + &(*static_cast<fling_call*>(tag)).initial_metadata_send); metadata_ops[0].op = GRPC_OP_SEND_INITIAL_METADATA; metadata_ops[0].data.send_initial_metadata.count = 0; @@ -110,7 +112,8 @@ static void send_snapshot(void* tag, struct grpc_memory_counters* snapshot) { grpc_slice snapshot_slice = grpc_slice_new(snapshot, sizeof(*snapshot), gpr_free); payload_buffer = grpc_raw_byte_buffer_create(&snapshot_slice, 1); - grpc_metadata_array_init(&(*(fling_call*)tag).initial_metadata_send); + grpc_metadata_array_init( + &(*static_cast<fling_call*>(tag)).initial_metadata_send); op = snapshot_ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; @@ -162,7 +165,7 @@ int main(int argc, char** argv) { grpc_test_init(1, fake_argv); grpc_init(); - srand((unsigned)clock()); + srand(static_cast<unsigned>(clock())); cl = gpr_cmdline_create("fling server"); gpr_cmdline_add_string(cl, "bind", "Bind host:port", &addr); @@ -203,7 +206,8 @@ int main(int argc, char** argv) { addr = addr_buf = nullptr; // initialize call instances - for (int i = 0; i < (int)(sizeof(calls) / sizeof(fling_call)); i++) { + for (int i = 0; i < static_cast<int>(sizeof(calls) / sizeof(fling_call)); + i++) { grpc_call_details_init(&calls[i].call_details); calls[i].state = FLING_SERVER_NEW_REQUEST; } @@ -280,7 +284,8 @@ int main(int argc, char** argv) { grpc_metadata_array_destroy(&s->request_metadata_recv); break; case FLING_SERVER_BATCH_SEND_STATUS_FLING_CALL: - for (int k = 0; k < (int)(sizeof(calls) / sizeof(fling_call)); + for (int k = 0; + k < static_cast<int>(sizeof(calls) / sizeof(fling_call)); ++k) { if (calls[k].state == FLING_SERVER_WAIT_FOR_DESTROY) { calls[k].state = FLING_SERVER_SEND_STATUS_FLING_CALL; @@ -289,6 +294,7 @@ int main(int argc, char** argv) { } // no break here since we want to continue to case // FLING_SERVER_SEND_STATUS_SNAPSHOT to destroy the snapshot call + /* fallthrough */ case FLING_SERVER_SEND_STATUS_SNAPSHOT: grpc_byte_buffer_destroy(payload_buffer); grpc_byte_buffer_destroy(terminal_buffer); diff --git a/test/core/network_benchmarks/low_level_ping_pong.cc b/test/core/network_benchmarks/low_level_ping_pong.cc index 96b0745f52..a983b1876d 100644 --- a/test/core/network_benchmarks/low_level_ping_pong.cc +++ b/test/core/network_benchmarks/low_level_ping_pong.cc @@ -35,13 +35,14 @@ #include <sys/socket.h> #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/socket_utils_posix.h" +#include "test/core/util/cmdline.h" #include "test/core/util/histogram.h" typedef struct fd_pair { @@ -83,7 +84,7 @@ static int read_bytes(int fd, char* buf, size_t read_size, int spin) { return -1; } } else { - bytes_read += (size_t)err; + bytes_read += static_cast<size_t>(err); } } while (bytes_read < read_size); return 0; @@ -126,7 +127,7 @@ static int poll_read_bytes(int fd, char* buf, size_t read_size, int spin) { gpr_log(GPR_ERROR, "Read failed: %s", strerror(errno)); return -1; } - bytes_read += (size_t)err2; + bytes_read += static_cast<size_t>(err2); } while (bytes_read < read_size); return 0; } @@ -165,7 +166,7 @@ static int epoll_read_bytes(struct thread_args* args, char* buf, int spin) { read(args->fds.read_fd, buf + bytes_read, read_size - bytes_read); } while (err2 < 0 && errno == EINTR); if (errno == EAGAIN) break; - bytes_read += (size_t)err2; + bytes_read += static_cast<size_t>(err2); /* TODO(klempner): This should really be doing an extra call after we are done to ensure we see an EAGAIN */ } while (bytes_read < read_size); @@ -202,7 +203,7 @@ static int blocking_write_bytes(struct thread_args* args, char* buf) { return -1; } } else { - bytes_written += (size_t)err; + bytes_written += static_cast<size_t>(err); } } while (bytes_written < write_size); return 0; @@ -287,7 +288,7 @@ static void print_histogram(grpc_histogram* histogram) { static double now(void) { gpr_timespec tv = gpr_now(GPR_CLOCK_REALTIME); - return 1e9 * (double)tv.tv_sec + (double)tv.tv_nsec; + return 1e9 * static_cast<double>(tv.tv_sec) + static_cast<double>(tv.tv_nsec); } static void client_thread(thread_args* args) { @@ -419,7 +420,7 @@ static int create_sockets_tcp(fd_pair* client_fds, fd_pair* server_fds) { int server_fd = -1; struct sockaddr_in port; - struct sockaddr* sa_port = (struct sockaddr*)&port; + struct sockaddr* sa_port = reinterpret_cast<struct sockaddr*>(&port); port.sin_family = AF_INET; port.sin_port = 0; @@ -535,6 +536,7 @@ void print_usage(char* argv0) { fprintf(stderr, " tcp: fds are endpoints of a TCP connection\n"); fprintf(stderr, " socketpair: fds come from socketpair()\n"); fprintf(stderr, " pipe: fds come from pipe()\n"); + fflush(stderr); } typedef struct test_strategy { @@ -565,6 +567,7 @@ int create_socket(const char* socket_type, fd_pair* client_fds, create_sockets_pipe(client_fds, server_fds); } else { fprintf(stderr, "Invalid socket type %s\n", socket_type); + fflush(stderr); return -1; } return 0; @@ -572,7 +575,6 @@ int create_socket(const char* socket_type, fd_pair* client_fds, static int run_benchmark(const char* socket_type, thread_args* client_args, thread_args* server_args) { - gpr_thd_id tid; int rv = 0; rv = create_socket(socket_type, &client_args->fds, &server_args->fds); @@ -583,8 +585,11 @@ static int run_benchmark(const char* socket_type, thread_args* client_args, gpr_log(GPR_INFO, "Starting test %s %s %zu", client_args->strategy_name, socket_type, client_args->msg_size); - gpr_thd_new(&tid, "server_thread", server_thread_wrap, server_args, nullptr); + grpc_core::Thread server("server_thread", server_thread_wrap, server_args); + server.Start(); client_thread(client_args); + server.Join(); + return 0; } @@ -649,7 +654,7 @@ int main(int argc, char** argv) { if (read_strategy == nullptr) { gpr_log(GPR_INFO, "No strategy specified, running all benchmarks"); - return run_all_benchmarks((size_t)msg_size); + return run_all_benchmarks(static_cast<size_t>(msg_size)); } if (socket_type == nullptr) { @@ -657,6 +662,7 @@ int main(int argc, char** argv) { } if (msg_size <= 0) { fprintf(stderr, "msg_size must be > 0\n"); + fflush(stderr); print_usage(argv[0]); return -1; } @@ -668,18 +674,19 @@ int main(int argc, char** argv) { } if (strategy == nullptr) { fprintf(stderr, "Invalid read strategy %s\n", read_strategy); + fflush(stderr); return -1; } client_args->read_bytes = strategy->read_strategy; client_args->write_bytes = blocking_write_bytes; client_args->setup = strategy->setup; - client_args->msg_size = (size_t)msg_size; + client_args->msg_size = static_cast<size_t>(msg_size); client_args->strategy_name = read_strategy; server_args->read_bytes = strategy->read_strategy; server_args->write_bytes = blocking_write_bytes; server_args->setup = strategy->setup; - server_args->msg_size = (size_t)msg_size; + server_args->msg_size = static_cast<size_t>(msg_size); server_args->strategy_name = read_strategy; error = run_benchmark(socket_type, client_args, server_args); diff --git a/test/core/security/BUILD b/test/core/security/BUILD index 7cd3ae58da..70bcc8c9c3 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -21,10 +21,22 @@ grpc_package(name = "test/core/security") load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( + name = "alts_credentials_fuzzer", + srcs = ["alts_credentials_fuzzer.cc"], + language = "C++", + corpus = "corpus/alts_credentials_corpus", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_fuzzer( name = "ssl_server_fuzzer", srcs = ["ssl_server_fuzzer.cc"], language = "C++", - corpus = "corpus", + corpus = "corpus/ssl_server_corpus", deps = [ "//:gpr", "//:grpc", @@ -67,6 +79,31 @@ grpc_cc_test( ) grpc_cc_test( + name = "json_token_test", + srcs = ["json_token_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "jwt_verifier_test", + srcs = ["jwt_verifier_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + + +grpc_cc_test( name = "secure_endpoint_test", srcs = ["secure_endpoint_test.cc"], language = "C++", @@ -110,6 +147,7 @@ grpc_cc_binary( deps = [ "//:gpr", "//:grpc", + "//test/core/util:grpc_test_util", ], ) @@ -121,6 +159,7 @@ grpc_cc_binary( ":oauth2_utils", "//:gpr", "//:grpc", + "//test/core/util:grpc_test_util", ], ) @@ -131,5 +170,55 @@ grpc_cc_binary( deps = [ "//:gpr", "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "check_gcp_environment_linux_test", + srcs = ["check_gcp_environment_linux_test.cc"], + language = "C++", + deps = [ + "//:alts_util", + "//:gpr", + "//:gpr_base", + "//:grpc", + ], +) + +grpc_cc_test( + name = "check_gcp_environment_windows_test", + srcs = ["check_gcp_environment_windows_test.cc"], + language = "C++", + deps = [ + "//:alts_util", + "//:gpr", + "//:gpr_base", + "//:grpc", + ], +) + +grpc_cc_test( + name = "grpc_alts_credentials_options_test", + srcs = ["grpc_alts_credentials_options_test.cc"], + language = "C++", + deps = [ + "//:alts_util", + "//:gpr", + "//:grpc", + ], +) + +grpc_cc_test( + name = "alts_security_connector_test", + srcs = ["alts_security_connector_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//:grpc_base_c", + "//:grpc_secure", + "//:tsi", + "//:tsi_interface", ], ) diff --git a/test/core/security/alts_credentials_fuzzer.cc b/test/core/security/alts_credentials_fuzzer.cc new file mode 100644 index 0000000000..bf18f0a589 --- /dev/null +++ b/test/core/security/alts_credentials_fuzzer.cc @@ -0,0 +1,120 @@ +/* + * + * 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 <string.h> + +#include <grpc/grpc.h> +#include <grpc/grpc_security.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include "test/core/util/fuzzer_util.h" +#include "test/core/util/memory_counters.h" + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/security/credentials/alts/alts_credentials.h" +#include "src/core/lib/security/credentials/alts/check_gcp_environment.h" +#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" + +using grpc_core::testing::grpc_fuzzer_get_next_byte; +using grpc_core::testing::grpc_fuzzer_get_next_string; +using grpc_core::testing::input_stream; + +// Logging +bool squelch = true; +bool leak_check = true; + +static void dont_log(gpr_log_func_args* args) {} + +// Add a random number of target service accounts to client options. +static void read_target_service_accounts( + input_stream* inp, grpc_alts_credentials_options* options) { + size_t n = grpc_fuzzer_get_next_byte(inp); + for (size_t i = 0; i < n; i++) { + char* service_account = grpc_fuzzer_get_next_string(inp, nullptr); + if (service_account != nullptr) { + grpc_alts_credentials_client_options_add_target_service_account( + options, service_account); + gpr_free(service_account); + } + } + // Added to improve code coverage. + grpc_alts_credentials_client_options_add_target_service_account(options, + nullptr); + grpc_alts_credentials_client_options_add_target_service_account( + nullptr, "this is service account"); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + char* grpc_trace_fuzzer = gpr_getenv("GRPC_TRACE_FUZZER"); + if (squelch && grpc_trace_fuzzer == nullptr) { + gpr_set_log_function(dont_log); + } + gpr_free(grpc_trace_fuzzer); + struct grpc_memory_counters counters; + if (leak_check) { + grpc_memory_counters_init(); + } + input_stream inp = {data, data + size}; + grpc_init(); + bool is_on_gcp = grpc_alts_is_running_on_gcp(); + while (inp.cur != inp.end) { + bool enable_untrusted_alts = grpc_fuzzer_get_next_byte(&inp) & 0x01; + char* handshaker_service_url = + grpc_fuzzer_get_next_byte(&inp) & 0x01 + ? grpc_fuzzer_get_next_string(&inp, nullptr) + : nullptr; + if (grpc_fuzzer_get_next_byte(&inp) & 0x01) { + // Test ALTS channel credentials. + grpc_alts_credentials_options* options = + grpc_alts_credentials_client_options_create(); + read_target_service_accounts(&inp, options); + grpc_channel_credentials* cred = grpc_alts_credentials_create_customized( + options, handshaker_service_url, enable_untrusted_alts); + if (!enable_untrusted_alts && !is_on_gcp) { + GPR_ASSERT(cred == nullptr); + } else { + GPR_ASSERT(cred != nullptr); + } + grpc_channel_credentials_release(cred); + grpc_alts_credentials_options_destroy(options); + } else { + // Test ALTS server credentials. + grpc_alts_credentials_options* options = + grpc_alts_credentials_server_options_create(); + grpc_server_credentials* cred = + grpc_alts_server_credentials_create_customized( + options, handshaker_service_url, enable_untrusted_alts); + if (!enable_untrusted_alts && !is_on_gcp) { + GPR_ASSERT(cred == nullptr); + } else { + GPR_ASSERT(cred != nullptr); + } + grpc_server_credentials_release(cred); + grpc_alts_credentials_options_destroy(options); + } + gpr_free(handshaker_service_url); + } + grpc_shutdown(); + if (leak_check) { + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); + } + return 0; +} diff --git a/test/core/security/alts_security_connector_test.cc b/test/core/security/alts_security_connector_test.cc new file mode 100644 index 0000000000..103a493526 --- /dev/null +++ b/test/core/security/alts_security_connector_test.cc @@ -0,0 +1,166 @@ +/* + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/security/security_connector/alts_security_connector.h" +#include "src/core/lib/transport/transport.h" +#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" +#include "src/core/tsi/transport_security.h" + +using grpc_core::internal::grpc_alts_auth_context_from_tsi_peer; + +/* This file contains unit tests of grpc_alts_auth_context_from_tsi_peer(). */ +static void test_invalid_input_failure() { + tsi_peer peer; + grpc_auth_context* ctx; + GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(nullptr, &ctx) == + GRPC_SECURITY_ERROR); + GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, nullptr) == + GRPC_SECURITY_ERROR); +} + +static void test_empty_certificate_type_failure() { + tsi_peer peer; + grpc_auth_context* ctx = nullptr; + GPR_ASSERT(tsi_construct_peer(0, &peer) == TSI_OK); + GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == + GRPC_SECURITY_ERROR); + GPR_ASSERT(ctx == nullptr); + tsi_peer_destruct(&peer); +} + +static void test_empty_peer_property_failure() { + tsi_peer peer; + grpc_auth_context* ctx; + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == + GRPC_SECURITY_ERROR); + GPR_ASSERT(ctx == nullptr); + tsi_peer_destruct(&peer); +} + +static void test_missing_rpc_protocol_versions_property_failure() { + tsi_peer peer; + grpc_auth_context* ctx; + GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice", + &peer.properties[1]) == TSI_OK); + GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == + GRPC_SECURITY_ERROR); + GPR_ASSERT(ctx == nullptr); + tsi_peer_destruct(&peer); +} + +static void test_unknown_peer_property_failure() { + tsi_peer peer; + grpc_auth_context* ctx; + GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + "unknown", "alice", &peer.properties[1]) == TSI_OK); + GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == + GRPC_SECURITY_ERROR); + GPR_ASSERT(ctx == nullptr); + tsi_peer_destruct(&peer); +} + +static bool test_identity(const grpc_auth_context* ctx, + const char* expected_property_name, + const char* expected_identity) { + grpc_auth_property_iterator it; + const grpc_auth_property* prop; + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); + it = grpc_auth_context_peer_identity(ctx); + prop = grpc_auth_property_iterator_next(&it); + GPR_ASSERT(prop != nullptr); + if (strcmp(prop->name, expected_property_name) != 0) { + gpr_log(GPR_ERROR, "Expected peer identity property name %s and got %s.", + expected_property_name, prop->name); + return false; + } + if (strncmp(prop->value, expected_identity, prop->value_length) != 0) { + gpr_log(GPR_ERROR, "Expected peer identity %s and got got %s.", + expected_identity, prop->value); + return false; + } + return true; +} + +static void test_alts_peer_to_auth_context_success() { + tsi_peer peer; + grpc_auth_context* ctx; + GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice", + &peer.properties[1]) == TSI_OK); + grpc_gcp_rpc_protocol_versions peer_versions; + grpc_gcp_rpc_protocol_versions_set_max(&peer_versions, + GRPC_PROTOCOL_VERSION_MAX_MAJOR, + GRPC_PROTOCOL_VERSION_MAX_MINOR); + grpc_gcp_rpc_protocol_versions_set_min(&peer_versions, + GRPC_PROTOCOL_VERSION_MIN_MAJOR, + GRPC_PROTOCOL_VERSION_MIN_MINOR); + grpc_slice serialized_peer_versions; + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_encode(&peer_versions, + &serialized_peer_versions)); + + GPR_ASSERT(tsi_construct_string_peer_property( + TSI_ALTS_RPC_VERSIONS, + reinterpret_cast<char*>( + GRPC_SLICE_START_PTR(serialized_peer_versions)), + GRPC_SLICE_LENGTH(serialized_peer_versions), + &peer.properties[2]) == TSI_OK); + GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == + GRPC_SECURITY_OK); + GPR_ASSERT( + test_identity(ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice")); + GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + grpc_slice_unref(serialized_peer_versions); + tsi_peer_destruct(&peer); +} + +int main(int argc, char** argv) { + /* Test. */ + test_invalid_input_failure(); + test_empty_certificate_type_failure(); + test_empty_peer_property_failure(); + test_unknown_peer_property_failure(); + test_missing_rpc_protocol_versions_property_failure(); + test_alts_peer_to_auth_context_success(); + + return 0; +} diff --git a/test/core/security/auth_context_test.cc b/test/core/security/auth_context_test.cc index d8e41326c0..58f0d8e1c2 100644 --- a/test/core/security/auth_context_test.cc +++ b/test/core/security/auth_context_test.cc @@ -18,8 +18,8 @@ #include <string.h> +#include "src/core/lib/gpr/string.h" #include "src/core/lib/security/context/security_context.h" -#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" #include <grpc/support/log.h> diff --git a/test/core/security/check_gcp_environment_linux_test.cc b/test/core/security/check_gcp_environment_linux_test.cc new file mode 100644 index 0000000000..6c436a3945 --- /dev/null +++ b/test/core/security/check_gcp_environment_linux_test.cc @@ -0,0 +1,83 @@ +/* + * + * 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 "src/core/lib/security/credentials/alts/check_gcp_environment.h" + +#if GPR_LINUX + +#include <stdio.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/gpr/tmpfile.h" + +static bool check_bios_data_linux_test(const char* data) { + /* Create a file with contents data. */ + char* filename = nullptr; + FILE* fp = gpr_tmpfile("check_gcp_environment_test", &filename); + GPR_ASSERT(filename != nullptr); + GPR_ASSERT(fp != nullptr); + GPR_ASSERT(fwrite(data, 1, strlen(data), fp) == strlen(data)); + fclose(fp); + bool result = grpc_core::internal::check_bios_data( + reinterpret_cast<const char*>(filename)); + /* Cleanup. */ + remove(filename); + gpr_free(filename); + return result; +} + +static void test_gcp_environment_check_success() { + /* Exact match. */ + GPR_ASSERT(check_bios_data_linux_test("Google")); + GPR_ASSERT(check_bios_data_linux_test("Google Compute Engine")); + /* With leading and trailing whitespaces. */ + GPR_ASSERT(check_bios_data_linux_test(" Google ")); + GPR_ASSERT(check_bios_data_linux_test("Google ")); + GPR_ASSERT(check_bios_data_linux_test(" Google")); + GPR_ASSERT(check_bios_data_linux_test(" Google Compute Engine ")); + GPR_ASSERT(check_bios_data_linux_test("Google Compute Engine ")); + GPR_ASSERT(check_bios_data_linux_test(" Google Compute Engine")); + /* With leading and trailing \t and \n. */ + GPR_ASSERT(check_bios_data_linux_test("\t\tGoogle Compute Engine\t")); + GPR_ASSERT(check_bios_data_linux_test("Google Compute Engine\n")); + GPR_ASSERT(check_bios_data_linux_test("\n\n\tGoogle Compute Engine \n\t\t")); +} + +static void test_gcp_environment_check_failure() { + GPR_ASSERT(!check_bios_data_linux_test("non_existing-file")); + GPR_ASSERT(!check_bios_data_linux_test("Google-Chrome")); + GPR_ASSERT(!check_bios_data_linux_test("Amazon")); + GPR_ASSERT(!check_bios_data_linux_test("Google-Chrome\t\t")); + GPR_ASSERT(!check_bios_data_linux_test("Amazon")); +} + +int main(int argc, char** argv) { + /* Tests. */ + test_gcp_environment_check_success(); + test_gcp_environment_check_failure(); + return 0; +} + +#else // GPR_LINUX + +int main(int argc, char** argv) { return 0; } + +#endif // GPR_LINUX diff --git a/test/core/security/check_gcp_environment_windows_test.cc b/test/core/security/check_gcp_environment_windows_test.cc new file mode 100644 index 0000000000..46179b747d --- /dev/null +++ b/test/core/security/check_gcp_environment_windows_test.cc @@ -0,0 +1,71 @@ +/* + * + * 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 "src/core/lib/security/credentials/alts/check_gcp_environment.h" + +#ifdef GPR_WINDOWS + +#include <stdio.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include "src/core/lib/gpr/tmpfile.h" + +static bool check_bios_data_windows_test(const char* data) { + /* Create a file with contents data. */ + char* filename = nullptr; + FILE* fp = gpr_tmpfile("check_gcp_environment_test", &filename); + GPR_ASSERT(filename != nullptr); + GPR_ASSERT(fp != nullptr); + GPR_ASSERT(fwrite(data, 1, strlen(data), fp) == strlen(data)); + fclose(fp); + bool result = grpc_core::internal::check_bios_data( + reinterpret_cast<const char*>(filename)); + /* Cleanup. */ + remove(filename); + gpr_free(filename); + return result; +} + +static void test_gcp_environment_check_success() { + GPR_ASSERT(check_bios_data_windows_test("Google")); + GPR_ASSERT(check_bios_data_windows_test("Google\n")); + GPR_ASSERT(check_bios_data_windows_test("Google\r")); + GPR_ASSERT(check_bios_data_windows_test("Google\r\n")); + GPR_ASSERT(check_bios_data_windows_test(" Google \r\n")); + GPR_ASSERT(check_bios_data_windows_test(" \t\t Google\r\n")); + GPR_ASSERT(check_bios_data_windows_test(" \t\t Google\t\t \r\n")); +} + +static void test_gcp_environment_check_failure() { + GPR_ASSERT(!check_bios_data_windows_test("\t\tAmazon\n")); + GPR_ASSERT(!check_bios_data_windows_test(" Amazon\r\n")); +} + +int main(int argc, char** argv) { + /* Tests. */ + test_gcp_environment_check_success(); + test_gcp_environment_check_failure(); + return 0; +} +#else // GPR_WINDOWS + +int main(int argc, char** argv) { return 0; } + +#endif // GPR_WINDOWS diff --git a/test/core/security/corpus/alts_credentials_corpus/0149b46b88d583e05be0fb1423d10f2a14d36c48 b/test/core/security/corpus/alts_credentials_corpus/0149b46b88d583e05be0fb1423d10f2a14d36c48 Binary files differnew file mode 100644 index 0000000000..c062c7f179 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/0149b46b88d583e05be0fb1423d10f2a14d36c48 diff --git a/test/core/security/corpus/alts_credentials_corpus/047fc351e73f760d329d5a8845944720be9ce773 b/test/core/security/corpus/alts_credentials_corpus/047fc351e73f760d329d5a8845944720be9ce773 Binary files differnew file mode 100644 index 0000000000..d943cfeacd --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/047fc351e73f760d329d5a8845944720be9ce773 diff --git a/test/core/security/corpus/alts_credentials_corpus/04ef96c66d8222d1a2c07e6b2a6548e6a527042b b/test/core/security/corpus/alts_credentials_corpus/04ef96c66d8222d1a2c07e6b2a6548e6a527042b Binary files differnew file mode 100644 index 0000000000..e7346f33ef --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/04ef96c66d8222d1a2c07e6b2a6548e6a527042b diff --git a/test/core/security/corpus/alts_credentials_corpus/05a7e16c1d7f92111f43e9c777421879920e79a4 b/test/core/security/corpus/alts_credentials_corpus/05a7e16c1d7f92111f43e9c777421879920e79a4 Binary files differnew file mode 100644 index 0000000000..43b8b47d03 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/05a7e16c1d7f92111f43e9c777421879920e79a4 diff --git a/test/core/security/corpus/alts_credentials_corpus/063eb46f202fdfe7935c30ca38d7eb81c82db419 b/test/core/security/corpus/alts_credentials_corpus/063eb46f202fdfe7935c30ca38d7eb81c82db419 Binary files differnew file mode 100644 index 0000000000..5b30f12418 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/063eb46f202fdfe7935c30ca38d7eb81c82db419 diff --git a/test/core/security/corpus/alts_credentials_corpus/064773597c295fa871c184fc12d17b6de8aab31b b/test/core/security/corpus/alts_credentials_corpus/064773597c295fa871c184fc12d17b6de8aab31b Binary files differnew file mode 100644 index 0000000000..758709b022 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/064773597c295fa871c184fc12d17b6de8aab31b diff --git a/test/core/security/corpus/alts_credentials_corpus/087449740758b114d16790067707934479946bd6 b/test/core/security/corpus/alts_credentials_corpus/087449740758b114d16790067707934479946bd6 Binary files differnew file mode 100644 index 0000000000..099636f9ca --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/087449740758b114d16790067707934479946bd6 diff --git a/test/core/security/corpus/alts_credentials_corpus/0a5d068feb57a2782c6eba57b637abe8668ac82f b/test/core/security/corpus/alts_credentials_corpus/0a5d068feb57a2782c6eba57b637abe8668ac82f Binary files differnew file mode 100644 index 0000000000..fd7d7c8ebc --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/0a5d068feb57a2782c6eba57b637abe8668ac82f diff --git a/test/core/security/corpus/alts_credentials_corpus/0b81e6d89bf7df80e87e5ee7c49f7cc1431f77e8 b/test/core/security/corpus/alts_credentials_corpus/0b81e6d89bf7df80e87e5ee7c49f7cc1431f77e8 Binary files differnew file mode 100644 index 0000000000..a40664b4ef --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/0b81e6d89bf7df80e87e5ee7c49f7cc1431f77e8 diff --git a/test/core/security/corpus/alts_credentials_corpus/11409339cec708a5e353893101bfe76364337d5c b/test/core/security/corpus/alts_credentials_corpus/11409339cec708a5e353893101bfe76364337d5c Binary files differnew file mode 100644 index 0000000000..c8b350d21c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/11409339cec708a5e353893101bfe76364337d5c diff --git a/test/core/security/corpus/alts_credentials_corpus/147696a264cd6f197adb7c68aff834c30b1b77f8 b/test/core/security/corpus/alts_credentials_corpus/147696a264cd6f197adb7c68aff834c30b1b77f8 new file mode 100644 index 0000000000..5f68d8a10f --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/147696a264cd6f197adb7c68aff834c30b1b77f8 @@ -0,0 +1 @@ ++
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/160e5cac38c5c9e919ed6e4fbafee76907d63044 b/test/core/security/corpus/alts_credentials_corpus/160e5cac38c5c9e919ed6e4fbafee76907d63044 Binary files differnew file mode 100644 index 0000000000..c11ad6674d --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/160e5cac38c5c9e919ed6e4fbafee76907d63044 diff --git a/test/core/security/corpus/alts_credentials_corpus/173d02167db431040b0540d98f6fc5e8b456587d b/test/core/security/corpus/alts_credentials_corpus/173d02167db431040b0540d98f6fc5e8b456587d new file mode 100644 index 0000000000..662cc9bc79 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/173d02167db431040b0540d98f6fc5e8b456587d @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/18a3fe239806b3c7d1af24bcd2bd23aeeb072d5c b/test/core/security/corpus/alts_credentials_corpus/18a3fe239806b3c7d1af24bcd2bd23aeeb072d5c Binary files differnew file mode 100644 index 0000000000..9239e10f44 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/18a3fe239806b3c7d1af24bcd2bd23aeeb072d5c diff --git a/test/core/security/corpus/alts_credentials_corpus/195abd83b2e9d32b1b5b854fe33da44b6db40880 b/test/core/security/corpus/alts_credentials_corpus/195abd83b2e9d32b1b5b854fe33da44b6db40880 new file mode 100644 index 0000000000..db7815ee2f --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/195abd83b2e9d32b1b5b854fe33da44b6db40880 @@ -0,0 +1 @@ +ap~!A~;
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/19af2509c7d84334b9ec64de4767a07d5294fd72 b/test/core/security/corpus/alts_credentials_corpus/19af2509c7d84334b9ec64de4767a07d5294fd72 Binary files differnew file mode 100644 index 0000000000..b87c814597 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/19af2509c7d84334b9ec64de4767a07d5294fd72 diff --git a/test/core/security/corpus/alts_credentials_corpus/1b9864b948fcf08b062fd4401ef55b214c259535 b/test/core/security/corpus/alts_credentials_corpus/1b9864b948fcf08b062fd4401ef55b214c259535 Binary files differnew file mode 100644 index 0000000000..8cb97c5ea7 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/1b9864b948fcf08b062fd4401ef55b214c259535 diff --git a/test/core/security/corpus/alts_credentials_corpus/1edddfa67de854d7faaba41418fda845e9c6a89d b/test/core/security/corpus/alts_credentials_corpus/1edddfa67de854d7faaba41418fda845e9c6a89d Binary files differnew file mode 100644 index 0000000000..035f07c06b --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/1edddfa67de854d7faaba41418fda845e9c6a89d diff --git a/test/core/security/corpus/alts_credentials_corpus/20031bb00e6608e1b570aa96e6afb9de06d42167 b/test/core/security/corpus/alts_credentials_corpus/20031bb00e6608e1b570aa96e6afb9de06d42167 Binary files differnew file mode 100644 index 0000000000..27753dfa09 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/20031bb00e6608e1b570aa96e6afb9de06d42167 diff --git a/test/core/security/corpus/alts_credentials_corpus/22b4c7ce7db99b0df63c9eae9265de484b695922 b/test/core/security/corpus/alts_credentials_corpus/22b4c7ce7db99b0df63c9eae9265de484b695922 Binary files differnew file mode 100644 index 0000000000..ab8f18d934 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/22b4c7ce7db99b0df63c9eae9265de484b695922 diff --git a/test/core/security/corpus/alts_credentials_corpus/27416437ad287bd3cc1c5efdecebc39f20df73c1 b/test/core/security/corpus/alts_credentials_corpus/27416437ad287bd3cc1c5efdecebc39f20df73c1 new file mode 100644 index 0000000000..c400e3e3af --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/27416437ad287bd3cc1c5efdecebc39f20df73c1 @@ -0,0 +1 @@ +=ļyyyyyyyyyz
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/27e8cd785c2b9346f68dba75761b52fbabaf2b72 b/test/core/security/corpus/alts_credentials_corpus/27e8cd785c2b9346f68dba75761b52fbabaf2b72 Binary files differnew file mode 100644 index 0000000000..746dee96af --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/27e8cd785c2b9346f68dba75761b52fbabaf2b72 diff --git a/test/core/security/corpus/alts_credentials_corpus/28236f860d3d8e5ea11176746cb4c1c5c4f1f6c0 b/test/core/security/corpus/alts_credentials_corpus/28236f860d3d8e5ea11176746cb4c1c5c4f1f6c0 Binary files differnew file mode 100644 index 0000000000..982c97b1ed --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/28236f860d3d8e5ea11176746cb4c1c5c4f1f6c0 diff --git a/test/core/security/corpus/alts_credentials_corpus/29e15b492c5a409938092a30c003c5c34df7e283 b/test/core/security/corpus/alts_credentials_corpus/29e15b492c5a409938092a30c003c5c34df7e283 Binary files differnew file mode 100644 index 0000000000..c3e5b25e0d --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/29e15b492c5a409938092a30c003c5c34df7e283 diff --git a/test/core/security/corpus/alts_credentials_corpus/2a47864d77749aa042b772895dbdf46f608ccc6d b/test/core/security/corpus/alts_credentials_corpus/2a47864d77749aa042b772895dbdf46f608ccc6d Binary files differnew file mode 100644 index 0000000000..141d94d982 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/2a47864d77749aa042b772895dbdf46f608ccc6d diff --git a/test/core/security/corpus/alts_credentials_corpus/2cca5cb1b135c35f6e5e1ec4c37deb9e12d37dc0 b/test/core/security/corpus/alts_credentials_corpus/2cca5cb1b135c35f6e5e1ec4c37deb9e12d37dc0 new file mode 100644 index 0000000000..a956708b56 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/2cca5cb1b135c35f6e5e1ec4c37deb9e12d37dc0 @@ -0,0 +1,2 @@ + +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/2df27b6c42dbaee382a29a87338d64ee87354acb b/test/core/security/corpus/alts_credentials_corpus/2df27b6c42dbaee382a29a87338d64ee87354acb Binary files differnew file mode 100644 index 0000000000..a35f0e83cd --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/2df27b6c42dbaee382a29a87338d64ee87354acb diff --git a/test/core/security/corpus/alts_credentials_corpus/2e9ddd1339d8e599cef658a08965985c4f45e428 b/test/core/security/corpus/alts_credentials_corpus/2e9ddd1339d8e599cef658a08965985c4f45e428 new file mode 100644 index 0000000000..17c98e7ca0 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/2e9ddd1339d8e599cef658a08965985c4f45e428 @@ -0,0 +1,2 @@ + +e
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/31a2d12a84a7a56ace831a9668d6ab4847390679 b/test/core/security/corpus/alts_credentials_corpus/31a2d12a84a7a56ace831a9668d6ab4847390679 new file mode 100644 index 0000000000..745dc42bc0 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/31a2d12a84a7a56ace831a9668d6ab4847390679 @@ -0,0 +1,2 @@ + +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/33cb9ec0ce3538ed6079b5fcb127649a5d05955b b/test/core/security/corpus/alts_credentials_corpus/33cb9ec0ce3538ed6079b5fcb127649a5d05955b Binary files differnew file mode 100644 index 0000000000..293176466e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/33cb9ec0ce3538ed6079b5fcb127649a5d05955b diff --git a/test/core/security/corpus/alts_credentials_corpus/348d9ae6eebb2e1644addf7f07231d108cf6f3b8 b/test/core/security/corpus/alts_credentials_corpus/348d9ae6eebb2e1644addf7f07231d108cf6f3b8 new file mode 100644 index 0000000000..02326f0b69 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/348d9ae6eebb2e1644addf7f07231d108cf6f3b8 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/359f76f3c802292e92b0640de2bfe051e780a3b6 b/test/core/security/corpus/alts_credentials_corpus/359f76f3c802292e92b0640de2bfe051e780a3b6 Binary files differnew file mode 100644 index 0000000000..f31c54bad8 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/359f76f3c802292e92b0640de2bfe051e780a3b6 diff --git a/test/core/security/corpus/alts_credentials_corpus/35a479988e965a6e3e75138b64b0bd1f45073e2f b/test/core/security/corpus/alts_credentials_corpus/35a479988e965a6e3e75138b64b0bd1f45073e2f Binary files differnew file mode 100644 index 0000000000..4e44bcc27f --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/35a479988e965a6e3e75138b64b0bd1f45073e2f diff --git a/test/core/security/corpus/alts_credentials_corpus/362b00d713686ff70cb0199f3d7d0058e5a1a27a b/test/core/security/corpus/alts_credentials_corpus/362b00d713686ff70cb0199f3d7d0058e5a1a27a Binary files differnew file mode 100644 index 0000000000..3e22fca175 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/362b00d713686ff70cb0199f3d7d0058e5a1a27a diff --git a/test/core/security/corpus/alts_credentials_corpus/3849c1625071791ceae709b9c6c705b28d099d67 b/test/core/security/corpus/alts_credentials_corpus/3849c1625071791ceae709b9c6c705b28d099d67 Binary files differnew file mode 100644 index 0000000000..5bc905de15 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/3849c1625071791ceae709b9c6c705b28d099d67 diff --git a/test/core/security/corpus/alts_credentials_corpus/39ef03c66ee2d4bcfb6c8da50486dcd40f02fb12 b/test/core/security/corpus/alts_credentials_corpus/39ef03c66ee2d4bcfb6c8da50486dcd40f02fb12 Binary files differnew file mode 100644 index 0000000000..467004c97d --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/39ef03c66ee2d4bcfb6c8da50486dcd40f02fb12 diff --git a/test/core/security/corpus/alts_credentials_corpus/3a3ca061863499ebc171a4f910fa1b49523baad4 b/test/core/security/corpus/alts_credentials_corpus/3a3ca061863499ebc171a4f910fa1b49523baad4 new file mode 100644 index 0000000000..97f09bf5c7 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/3a3ca061863499ebc171a4f910fa1b49523baad4 @@ -0,0 +1 @@ +9
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/3a890f3fd01b048ac9db65a9a9b4f4443268b91a b/test/core/security/corpus/alts_credentials_corpus/3a890f3fd01b048ac9db65a9a9b4f4443268b91a Binary files differnew file mode 100644 index 0000000000..97b05e80ba --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/3a890f3fd01b048ac9db65a9a9b4f4443268b91a diff --git a/test/core/security/corpus/alts_credentials_corpus/3b9554038a425bd1fae057ba41f9366bb467e946 b/test/core/security/corpus/alts_credentials_corpus/3b9554038a425bd1fae057ba41f9366bb467e946 new file mode 100644 index 0000000000..d0ef6342d0 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/3b9554038a425bd1fae057ba41f9366bb467e946 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/3ce0ae4aa226f205a3a4e66bbb253419d9d754bf b/test/core/security/corpus/alts_credentials_corpus/3ce0ae4aa226f205a3a4e66bbb253419d9d754bf Binary files differnew file mode 100644 index 0000000000..08e6df0ee2 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/3ce0ae4aa226f205a3a4e66bbb253419d9d754bf diff --git a/test/core/security/corpus/alts_credentials_corpus/3dccc5523986c37e27684659bba8a1037e7a92e8 b/test/core/security/corpus/alts_credentials_corpus/3dccc5523986c37e27684659bba8a1037e7a92e8 Binary files differnew file mode 100644 index 0000000000..09b735e831 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/3dccc5523986c37e27684659bba8a1037e7a92e8 diff --git a/test/core/security/corpus/alts_credentials_corpus/3e0908c15b1cede4541d25f388b1345e8641e221 b/test/core/security/corpus/alts_credentials_corpus/3e0908c15b1cede4541d25f388b1345e8641e221 Binary files differnew file mode 100644 index 0000000000..eabd458c03 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/3e0908c15b1cede4541d25f388b1345e8641e221 diff --git a/test/core/security/corpus/alts_credentials_corpus/3fcb181ff6a8c8e2ba38ed34cf78f7482eb55cb7 b/test/core/security/corpus/alts_credentials_corpus/3fcb181ff6a8c8e2ba38ed34cf78f7482eb55cb7 Binary files differnew file mode 100644 index 0000000000..bbef93b5ad --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/3fcb181ff6a8c8e2ba38ed34cf78f7482eb55cb7 diff --git a/test/core/security/corpus/alts_credentials_corpus/41c9b5f720eb8f8fa04c840375a881781a849b43 b/test/core/security/corpus/alts_credentials_corpus/41c9b5f720eb8f8fa04c840375a881781a849b43 Binary files differnew file mode 100644 index 0000000000..d611c732db --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/41c9b5f720eb8f8fa04c840375a881781a849b43 diff --git a/test/core/security/corpus/alts_credentials_corpus/4257a018f08f13a3a9adc848ef808e1be50bc4cf b/test/core/security/corpus/alts_credentials_corpus/4257a018f08f13a3a9adc848ef808e1be50bc4cf new file mode 100644 index 0000000000..607c97117a --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/4257a018f08f13a3a9adc848ef808e1be50bc4cf @@ -0,0 +1,2 @@ +99999999999999999999999999999999999///// +NSt6locale5
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/42dfc5c4d13261b7259e65cd692df9c9d607194e b/test/core/security/corpus/alts_credentials_corpus/42dfc5c4d13261b7259e65cd692df9c9d607194e Binary files differnew file mode 100644 index 0000000000..48ffa853fb --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/42dfc5c4d13261b7259e65cd692df9c9d607194e diff --git a/test/core/security/corpus/alts_credentials_corpus/43144664aedb585d45d42aa5249ddbfe81afe470 b/test/core/security/corpus/alts_credentials_corpus/43144664aedb585d45d42aa5249ddbfe81afe470 Binary files differnew file mode 100644 index 0000000000..fee2672260 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/43144664aedb585d45d42aa5249ddbfe81afe470 diff --git a/test/core/security/corpus/alts_credentials_corpus/43e5ad495a47593b17dbcbd3e70c2e25a417bb6e b/test/core/security/corpus/alts_credentials_corpus/43e5ad495a47593b17dbcbd3e70c2e25a417bb6e Binary files differnew file mode 100644 index 0000000000..32ffc96267 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/43e5ad495a47593b17dbcbd3e70c2e25a417bb6e diff --git a/test/core/security/corpus/alts_credentials_corpus/446614e45b7bef49118b17e031c48faf167ebe3e b/test/core/security/corpus/alts_credentials_corpus/446614e45b7bef49118b17e031c48faf167ebe3e Binary files differnew file mode 100644 index 0000000000..849aadf08a --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/446614e45b7bef49118b17e031c48faf167ebe3e diff --git a/test/core/security/corpus/alts_credentials_corpus/46492477fa84ca88e85df914801af0b09b0939f6 b/test/core/security/corpus/alts_credentials_corpus/46492477fa84ca88e85df914801af0b09b0939f6 Binary files differnew file mode 100644 index 0000000000..98885bcde8 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/46492477fa84ca88e85df914801af0b09b0939f6 diff --git a/test/core/security/corpus/alts_credentials_corpus/47157f83b166b57e0052c98a65c6db864fa6cb9b b/test/core/security/corpus/alts_credentials_corpus/47157f83b166b57e0052c98a65c6db864fa6cb9b Binary files differnew file mode 100644 index 0000000000..fad1e0faf1 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/47157f83b166b57e0052c98a65c6db864fa6cb9b diff --git a/test/core/security/corpus/alts_credentials_corpus/473fc9b6d768a925527d3ad805ca363d490dc741 b/test/core/security/corpus/alts_credentials_corpus/473fc9b6d768a925527d3ad805ca363d490dc741 Binary files differnew file mode 100644 index 0000000000..1775a17df6 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/473fc9b6d768a925527d3ad805ca363d490dc741 diff --git a/test/core/security/corpus/alts_credentials_corpus/483c0b4015100eee00f6b23d1100d8c4953dd3b1 b/test/core/security/corpus/alts_credentials_corpus/483c0b4015100eee00f6b23d1100d8c4953dd3b1 Binary files differnew file mode 100644 index 0000000000..2d52687fda --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/483c0b4015100eee00f6b23d1100d8c4953dd3b1 diff --git a/test/core/security/corpus/alts_credentials_corpus/48be2dc4cdc5462407b319caa855d976cda88153 b/test/core/security/corpus/alts_credentials_corpus/48be2dc4cdc5462407b319caa855d976cda88153 Binary files differnew file mode 100644 index 0000000000..c1c2cd98cf --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/48be2dc4cdc5462407b319caa855d976cda88153 diff --git a/test/core/security/corpus/alts_credentials_corpus/4e84eb54a0e438052b0c2e83653135042d9eb59a b/test/core/security/corpus/alts_credentials_corpus/4e84eb54a0e438052b0c2e83653135042d9eb59a new file mode 100644 index 0000000000..66b525f713 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/4e84eb54a0e438052b0c2e83653135042d9eb59a @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/50839d5c8bf33f0970986dcc4b73b024f11a95b7 b/test/core/security/corpus/alts_credentials_corpus/50839d5c8bf33f0970986dcc4b73b024f11a95b7 new file mode 100644 index 0000000000..9673f73c62 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/50839d5c8bf33f0970986dcc4b73b024f11a95b7 @@ -0,0 +1 @@ +t_ &
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/523d964986d8ad966ae07e540a608681098813f9 b/test/core/security/corpus/alts_credentials_corpus/523d964986d8ad966ae07e540a608681098813f9 Binary files differnew file mode 100644 index 0000000000..06e05df73e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/523d964986d8ad966ae07e540a608681098813f9 diff --git a/test/core/security/corpus/alts_credentials_corpus/5410b8190c95dacd36d6e6ec75b7538a630e08de b/test/core/security/corpus/alts_credentials_corpus/5410b8190c95dacd36d6e6ec75b7538a630e08de Binary files differnew file mode 100644 index 0000000000..4579c6fff2 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5410b8190c95dacd36d6e6ec75b7538a630e08de diff --git a/test/core/security/corpus/alts_credentials_corpus/549b2891ac79f504a7c9ea00f6d7527c34ce04e6 b/test/core/security/corpus/alts_credentials_corpus/549b2891ac79f504a7c9ea00f6d7527c34ce04e6 Binary files differnew file mode 100644 index 0000000000..6f1a9ed509 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/549b2891ac79f504a7c9ea00f6d7527c34ce04e6 diff --git a/test/core/security/corpus/alts_credentials_corpus/55321649e7b7f1b5664ae20724e683c930643fc4 b/test/core/security/corpus/alts_credentials_corpus/55321649e7b7f1b5664ae20724e683c930643fc4 new file mode 100644 index 0000000000..e38fd28e17 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/55321649e7b7f1b5664ae20724e683c930643fc4 @@ -0,0 +1 @@ +)
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/55cc52f25865baee3e6e52c3110a9723caa2b3cb b/test/core/security/corpus/alts_credentials_corpus/55cc52f25865baee3e6e52c3110a9723caa2b3cb new file mode 100644 index 0000000000..aae2fe5fe0 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/55cc52f25865baee3e6e52c3110a9723caa2b3cb @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/56c22410e3295ad03aa31552ab888f581756cc17 b/test/core/security/corpus/alts_credentials_corpus/56c22410e3295ad03aa31552ab888f581756cc17 Binary files differnew file mode 100644 index 0000000000..e5d7cf9d5d --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/56c22410e3295ad03aa31552ab888f581756cc17 diff --git a/test/core/security/corpus/alts_credentials_corpus/5724a705b62a7548ba2df1abe4ef0c970c4e1bd2 b/test/core/security/corpus/alts_credentials_corpus/5724a705b62a7548ba2df1abe4ef0c970c4e1bd2 Binary files differnew file mode 100644 index 0000000000..b0875c947b --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5724a705b62a7548ba2df1abe4ef0c970c4e1bd2 diff --git a/test/core/security/corpus/alts_credentials_corpus/576a148c107d56861d1611641a6f7c7921061c5c b/test/core/security/corpus/alts_credentials_corpus/576a148c107d56861d1611641a6f7c7921061c5c Binary files differnew file mode 100644 index 0000000000..6d91b58071 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/576a148c107d56861d1611641a6f7c7921061c5c diff --git a/test/core/security/corpus/alts_credentials_corpus/5a6b8263e8939f851cf5b1e347a33d97253b7b3d b/test/core/security/corpus/alts_credentials_corpus/5a6b8263e8939f851cf5b1e347a33d97253b7b3d Binary files differnew file mode 100644 index 0000000000..add56cac16 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5a6b8263e8939f851cf5b1e347a33d97253b7b3d diff --git a/test/core/security/corpus/alts_credentials_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f b/test/core/security/corpus/alts_credentials_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f Binary files differnew file mode 100644 index 0000000000..f76dd238ad --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f diff --git a/test/core/security/corpus/alts_credentials_corpus/5bd02a339fd7705449388580c75bfcc597aba954 b/test/core/security/corpus/alts_credentials_corpus/5bd02a339fd7705449388580c75bfcc597aba954 Binary files differnew file mode 100644 index 0000000000..f450932939 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5bd02a339fd7705449388580c75bfcc597aba954 diff --git a/test/core/security/corpus/alts_credentials_corpus/5bd6fb6fc4163bf3a9db6ddaf509dce8df8a5000 b/test/core/security/corpus/alts_credentials_corpus/5bd6fb6fc4163bf3a9db6ddaf509dce8df8a5000 new file mode 100644 index 0000000000..aea3da6970 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5bd6fb6fc4163bf3a9db6ddaf509dce8df8a5000 @@ -0,0 +1 @@ +)applea...
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/5d06fc38005503af3d084721c60e574fb9d2f370 b/test/core/security/corpus/alts_credentials_corpus/5d06fc38005503af3d084721c60e574fb9d2f370 new file mode 100644 index 0000000000..42eb673e51 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5d06fc38005503af3d084721c60e574fb9d2f370 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/5ddc10489ff3269bdaa3051b70fb7af455ee1104 b/test/core/security/corpus/alts_credentials_corpus/5ddc10489ff3269bdaa3051b70fb7af455ee1104 Binary files differnew file mode 100644 index 0000000000..79db88a7b3 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5ddc10489ff3269bdaa3051b70fb7af455ee1104 diff --git a/test/core/security/corpus/alts_credentials_corpus/5ea9d515f0d10b04f1356b9463139bfe121a6e4a b/test/core/security/corpus/alts_credentials_corpus/5ea9d515f0d10b04f1356b9463139bfe121a6e4a Binary files differnew file mode 100644 index 0000000000..7efb47e7c8 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/5ea9d515f0d10b04f1356b9463139bfe121a6e4a diff --git a/test/core/security/corpus/alts_credentials_corpus/61c449793347cf2e1ed0c38d54d23c63dfaabeb8 b/test/core/security/corpus/alts_credentials_corpus/61c449793347cf2e1ed0c38d54d23c63dfaabeb8 new file mode 100644 index 0000000000..96031be7fc --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/61c449793347cf2e1ed0c38d54d23c63dfaabeb8 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/6287389c373e9788dcc04f9747b4be1fd1ef3028 b/test/core/security/corpus/alts_credentials_corpus/6287389c373e9788dcc04f9747b4be1fd1ef3028 Binary files differnew file mode 100644 index 0000000000..799bd0e6b0 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/6287389c373e9788dcc04f9747b4be1fd1ef3028 diff --git a/test/core/security/corpus/alts_credentials_corpus/64d4de4d5aafab7ec388a7fe83066c1a4d1d9d68 b/test/core/security/corpus/alts_credentials_corpus/64d4de4d5aafab7ec388a7fe83066c1a4d1d9d68 Binary files differnew file mode 100644 index 0000000000..2e91965059 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/64d4de4d5aafab7ec388a7fe83066c1a4d1d9d68 diff --git a/test/core/security/corpus/alts_credentials_corpus/651c37806d2ac579dcfc97643c3c1ea74dbb8774 b/test/core/security/corpus/alts_credentials_corpus/651c37806d2ac579dcfc97643c3c1ea74dbb8774 Binary files differnew file mode 100644 index 0000000000..618e514ec3 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/651c37806d2ac579dcfc97643c3c1ea74dbb8774 diff --git a/test/core/security/corpus/alts_credentials_corpus/6551d02d20573cfa2944ec1f12b0c01f264a1326 b/test/core/security/corpus/alts_credentials_corpus/6551d02d20573cfa2944ec1f12b0c01f264a1326 new file mode 100644 index 0000000000..98056c073e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/6551d02d20573cfa2944ec1f12b0c01f264a1326 @@ -0,0 +1 @@ +s
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/65f029414ee10e45ff4b9f305f7b472364cea538 b/test/core/security/corpus/alts_credentials_corpus/65f029414ee10e45ff4b9f305f7b472364cea538 Binary files differnew file mode 100644 index 0000000000..1c3a1a0d28 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/65f029414ee10e45ff4b9f305f7b472364cea538 diff --git a/test/core/security/corpus/alts_credentials_corpus/68b75a17fe2db060df3e61a597650ba99079abbf b/test/core/security/corpus/alts_credentials_corpus/68b75a17fe2db060df3e61a597650ba99079abbf Binary files differnew file mode 100644 index 0000000000..327dd390b9 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/68b75a17fe2db060df3e61a597650ba99079abbf diff --git a/test/core/security/corpus/alts_credentials_corpus/69e80594dbc5c4c648e39883a650b1760f20ab63 b/test/core/security/corpus/alts_credentials_corpus/69e80594dbc5c4c648e39883a650b1760f20ab63 Binary files differnew file mode 100644 index 0000000000..740b987b48 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/69e80594dbc5c4c648e39883a650b1760f20ab63 diff --git a/test/core/security/corpus/alts_credentials_corpus/6cb47d0e640b4c41e32f13c0d64ee46eae1b80b5 b/test/core/security/corpus/alts_credentials_corpus/6cb47d0e640b4c41e32f13c0d64ee46eae1b80b5 Binary files differnew file mode 100644 index 0000000000..b22a010648 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/6cb47d0e640b4c41e32f13c0d64ee46eae1b80b5 diff --git a/test/core/security/corpus/alts_credentials_corpus/6da5fe063432cb9094c7c083efdbbe5ba4246d18 b/test/core/security/corpus/alts_credentials_corpus/6da5fe063432cb9094c7c083efdbbe5ba4246d18 Binary files differnew file mode 100644 index 0000000000..993620ed92 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/6da5fe063432cb9094c7c083efdbbe5ba4246d18 diff --git a/test/core/security/corpus/alts_credentials_corpus/6dd140da774d85f272fb587dc1b2a85d881a7c21 b/test/core/security/corpus/alts_credentials_corpus/6dd140da774d85f272fb587dc1b2a85d881a7c21 Binary files differnew file mode 100644 index 0000000000..d838739e6c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/6dd140da774d85f272fb587dc1b2a85d881a7c21 diff --git a/test/core/security/corpus/alts_credentials_corpus/6ddab273597d73be49e2307d68e00fa18bba4765 b/test/core/security/corpus/alts_credentials_corpus/6ddab273597d73be49e2307d68e00fa18bba4765 Binary files differnew file mode 100644 index 0000000000..3e74467a38 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/6ddab273597d73be49e2307d68e00fa18bba4765 diff --git a/test/core/security/corpus/alts_credentials_corpus/6eaf85d84fbf47ea0619d0dba8d366f4e3ff0be6 b/test/core/security/corpus/alts_credentials_corpus/6eaf85d84fbf47ea0619d0dba8d366f4e3ff0be6 Binary files differnew file mode 100644 index 0000000000..42cddf7419 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/6eaf85d84fbf47ea0619d0dba8d366f4e3ff0be6 diff --git a/test/core/security/corpus/alts_credentials_corpus/6f751cc09af8113f6ecd491b1830bd8454c4738d b/test/core/security/corpus/alts_credentials_corpus/6f751cc09af8113f6ecd491b1830bd8454c4738d Binary files differnew file mode 100644 index 0000000000..a51a3d0f6c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/6f751cc09af8113f6ecd491b1830bd8454c4738d diff --git a/test/core/security/corpus/alts_credentials_corpus/70d9eb29a70d483d07e2faca6b00098af78d1fff b/test/core/security/corpus/alts_credentials_corpus/70d9eb29a70d483d07e2faca6b00098af78d1fff Binary files differnew file mode 100644 index 0000000000..e9fb9b9317 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/70d9eb29a70d483d07e2faca6b00098af78d1fff diff --git a/test/core/security/corpus/alts_credentials_corpus/7192effa1058382b379fb7b87f1acad5ac554d05 b/test/core/security/corpus/alts_credentials_corpus/7192effa1058382b379fb7b87f1acad5ac554d05 Binary files differnew file mode 100644 index 0000000000..23a3819ebe --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/7192effa1058382b379fb7b87f1acad5ac554d05 diff --git a/test/core/security/corpus/alts_credentials_corpus/730e85d6a62e70cb6721009b903782ade4ff73a2 b/test/core/security/corpus/alts_credentials_corpus/730e85d6a62e70cb6721009b903782ade4ff73a2 Binary files differnew file mode 100644 index 0000000000..9c1e71c549 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/730e85d6a62e70cb6721009b903782ade4ff73a2 diff --git a/test/core/security/corpus/alts_credentials_corpus/74002471a854059cb29de7cad8f9fb7adc3c5ec2 b/test/core/security/corpus/alts_credentials_corpus/74002471a854059cb29de7cad8f9fb7adc3c5ec2 new file mode 100644 index 0000000000..bb832313c7 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/74002471a854059cb29de7cad8f9fb7adc3c5ec2 @@ -0,0 +1,2 @@ + +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/747f2330cd1fc4a06d54b376a9a6528d0364f0ac b/test/core/security/corpus/alts_credentials_corpus/747f2330cd1fc4a06d54b376a9a6528d0364f0ac Binary files differnew file mode 100644 index 0000000000..332ac4b672 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/747f2330cd1fc4a06d54b376a9a6528d0364f0ac diff --git a/test/core/security/corpus/alts_credentials_corpus/749d5d7a9e0b1545b297117e834462af32b3e230 b/test/core/security/corpus/alts_credentials_corpus/749d5d7a9e0b1545b297117e834462af32b3e230 new file mode 100644 index 0000000000..a00db592b0 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/749d5d7a9e0b1545b297117e834462af32b3e230 @@ -0,0 +1 @@ +a+
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/77de0b1de120ac702ca45868b1008a48626daf12 b/test/core/security/corpus/alts_credentials_corpus/77de0b1de120ac702ca45868b1008a48626daf12 new file mode 100644 index 0000000000..352762cf75 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/77de0b1de120ac702ca45868b1008a48626daf12 @@ -0,0 +1 @@ +^
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/792c67398bce19a4eeda32653c994436e79456e5 b/test/core/security/corpus/alts_credentials_corpus/792c67398bce19a4eeda32653c994436e79456e5 new file mode 100644 index 0000000000..08342871da --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/792c67398bce19a4eeda32653c994436e79456e5 @@ -0,0 +1 @@ +j
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/7a3022b248c8960289e4c80c7cc8df409499e5da b/test/core/security/corpus/alts_credentials_corpus/7a3022b248c8960289e4c80c7cc8df409499e5da Binary files differnew file mode 100644 index 0000000000..f9ef6a4631 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/7a3022b248c8960289e4c80c7cc8df409499e5da diff --git a/test/core/security/corpus/alts_credentials_corpus/7a9372081294a6fbd3fecdd91b99589c98d4948e b/test/core/security/corpus/alts_credentials_corpus/7a9372081294a6fbd3fecdd91b99589c98d4948e Binary files differnew file mode 100644 index 0000000000..7100f32821 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/7a9372081294a6fbd3fecdd91b99589c98d4948e diff --git a/test/core/security/corpus/alts_credentials_corpus/7bbe4ba828947550f4ad089d5989cb695ecbdb1b b/test/core/security/corpus/alts_credentials_corpus/7bbe4ba828947550f4ad089d5989cb695ecbdb1b Binary files differnew file mode 100644 index 0000000000..44e3963031 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/7bbe4ba828947550f4ad089d5989cb695ecbdb1b diff --git a/test/core/security/corpus/alts_credentials_corpus/7f1ad514a96f0c3d5ca5d6f7880b929a65eeae96 b/test/core/security/corpus/alts_credentials_corpus/7f1ad514a96f0c3d5ca5d6f7880b929a65eeae96 Binary files differnew file mode 100644 index 0000000000..700c079449 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/7f1ad514a96f0c3d5ca5d6f7880b929a65eeae96 diff --git a/test/core/security/corpus/alts_credentials_corpus/7f2b075f0b6707c38db851747e2578343eeab286 b/test/core/security/corpus/alts_credentials_corpus/7f2b075f0b6707c38db851747e2578343eeab286 Binary files differnew file mode 100644 index 0000000000..1f7b5d72ac --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/7f2b075f0b6707c38db851747e2578343eeab286 diff --git a/test/core/security/corpus/alts_credentials_corpus/81ebc64bfde3fad37af5a58ef7f1c5c3c54c4b5d b/test/core/security/corpus/alts_credentials_corpus/81ebc64bfde3fad37af5a58ef7f1c5c3c54c4b5d Binary files differnew file mode 100644 index 0000000000..d89f30fd4c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/81ebc64bfde3fad37af5a58ef7f1c5c3c54c4b5d diff --git a/test/core/security/corpus/alts_credentials_corpus/82fae081afaea13831404024d39658344d56e1c6 b/test/core/security/corpus/alts_credentials_corpus/82fae081afaea13831404024d39658344d56e1c6 Binary files differnew file mode 100644 index 0000000000..bc3cfc241f --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/82fae081afaea13831404024d39658344d56e1c6 diff --git a/test/core/security/corpus/alts_credentials_corpus/83ba41cea1adab707f7f213af5e2ed734bdddc25 b/test/core/security/corpus/alts_credentials_corpus/83ba41cea1adab707f7f213af5e2ed734bdddc25 Binary files differnew file mode 100644 index 0000000000..d465fb4977 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/83ba41cea1adab707f7f213af5e2ed734bdddc25 diff --git a/test/core/security/corpus/alts_credentials_corpus/841a3f66c94e5acd836a44cd5a8514d4ad45d83e b/test/core/security/corpus/alts_credentials_corpus/841a3f66c94e5acd836a44cd5a8514d4ad45d83e Binary files differnew file mode 100644 index 0000000000..cbb7bdcaf8 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/841a3f66c94e5acd836a44cd5a8514d4ad45d83e diff --git a/test/core/security/corpus/alts_credentials_corpus/841ef94ee0f1b0b45983d95b75aba25421d73f2c b/test/core/security/corpus/alts_credentials_corpus/841ef94ee0f1b0b45983d95b75aba25421d73f2c Binary files differnew file mode 100644 index 0000000000..ba85d1d67e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/841ef94ee0f1b0b45983d95b75aba25421d73f2c diff --git a/test/core/security/corpus/alts_credentials_corpus/843b0aad4a9707c5dcc92d12d876b78675cfcb65 b/test/core/security/corpus/alts_credentials_corpus/843b0aad4a9707c5dcc92d12d876b78675cfcb65 Binary files differnew file mode 100644 index 0000000000..02d61c52aa --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/843b0aad4a9707c5dcc92d12d876b78675cfcb65 diff --git a/test/core/security/corpus/alts_credentials_corpus/8483e3d92eda8df504b1d1d0d012f4bcd778cd33 b/test/core/security/corpus/alts_credentials_corpus/8483e3d92eda8df504b1d1d0d012f4bcd778cd33 Binary files differnew file mode 100644 index 0000000000..3795466779 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/8483e3d92eda8df504b1d1d0d012f4bcd778cd33 diff --git a/test/core/security/corpus/alts_credentials_corpus/876830fdff4e59038fa2173b700faef5bffe61de b/test/core/security/corpus/alts_credentials_corpus/876830fdff4e59038fa2173b700faef5bffe61de new file mode 100644 index 0000000000..26048bd593 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/876830fdff4e59038fa2173b700faef5bffe61de @@ -0,0 +1 @@ +A
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/87ca3342fdce0c1f678a3f1b62428032ef51442d b/test/core/security/corpus/alts_credentials_corpus/87ca3342fdce0c1f678a3f1b62428032ef51442d Binary files differnew file mode 100644 index 0000000000..ea35b452ca --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/87ca3342fdce0c1f678a3f1b62428032ef51442d diff --git a/test/core/security/corpus/alts_credentials_corpus/87d044027cdb7d35fadb56532f497764246946a6 b/test/core/security/corpus/alts_credentials_corpus/87d044027cdb7d35fadb56532f497764246946a6 Binary files differnew file mode 100644 index 0000000000..1e474c9134 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/87d044027cdb7d35fadb56532f497764246946a6 diff --git a/test/core/security/corpus/alts_credentials_corpus/88ce75ba18bdb7e93a81197d850f4e792f6a8155 b/test/core/security/corpus/alts_credentials_corpus/88ce75ba18bdb7e93a81197d850f4e792f6a8155 Binary files differnew file mode 100644 index 0000000000..70c9ab1fc5 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/88ce75ba18bdb7e93a81197d850f4e792f6a8155 diff --git a/test/core/security/corpus/alts_credentials_corpus/89dc55e8e20e811e78c952c8bd2c16f55fe72f57 b/test/core/security/corpus/alts_credentials_corpus/89dc55e8e20e811e78c952c8bd2c16f55fe72f57 new file mode 100644 index 0000000000..00961fdf9e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/89dc55e8e20e811e78c952c8bd2c16f55fe72f57 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/8a215a58908f44bdced595ceb01a81977f1d72f0 b/test/core/security/corpus/alts_credentials_corpus/8a215a58908f44bdced595ceb01a81977f1d72f0 new file mode 100644 index 0000000000..296f8b7a24 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/8a215a58908f44bdced595ceb01a81977f1d72f0 @@ -0,0 +1 @@ +==)
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/8ac7459e918304ca40b1cf29a3ac0f555eada678 b/test/core/security/corpus/alts_credentials_corpus/8ac7459e918304ca40b1cf29a3ac0f555eada678 Binary files differnew file mode 100644 index 0000000000..629a6f95a2 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/8ac7459e918304ca40b1cf29a3ac0f555eada678 diff --git a/test/core/security/corpus/alts_credentials_corpus/8b93e50a911f3ea0e0b0377ba4636574f2ee9a5e b/test/core/security/corpus/alts_credentials_corpus/8b93e50a911f3ea0e0b0377ba4636574f2ee9a5e Binary files differnew file mode 100644 index 0000000000..280aecfb9a --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/8b93e50a911f3ea0e0b0377ba4636574f2ee9a5e diff --git a/test/core/security/corpus/alts_credentials_corpus/8c9ec0ffd803505772693833d56e7a02110645b3 b/test/core/security/corpus/alts_credentials_corpus/8c9ec0ffd803505772693833d56e7a02110645b3 new file mode 100644 index 0000000000..3bd046b7f9 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/8c9ec0ffd803505772693833d56e7a02110645b3 @@ -0,0 +1 @@ +K]//(
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/8e4b361a530dc6825afcfb4106bd482c3fd010fa b/test/core/security/corpus/alts_credentials_corpus/8e4b361a530dc6825afcfb4106bd482c3fd010fa new file mode 100644 index 0000000000..3733df9e3c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/8e4b361a530dc6825afcfb4106bd482c3fd010fa @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/8f6690d97bcda890f2a5b2930a2b7a4d7b56c6e7 b/test/core/security/corpus/alts_credentials_corpus/8f6690d97bcda890f2a5b2930a2b7a4d7b56c6e7 new file mode 100644 index 0000000000..7885e1effb --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/8f6690d97bcda890f2a5b2930a2b7a4d7b56c6e7 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/917636de2c14dce2580d4308249a94d61d62c305 b/test/core/security/corpus/alts_credentials_corpus/917636de2c14dce2580d4308249a94d61d62c305 Binary files differnew file mode 100644 index 0000000000..cccb20d847 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/917636de2c14dce2580d4308249a94d61d62c305 diff --git a/test/core/security/corpus/alts_credentials_corpus/91f11008defda918951bda868cc68c6373fb0e6a b/test/core/security/corpus/alts_credentials_corpus/91f11008defda918951bda868cc68c6373fb0e6a Binary files differnew file mode 100644 index 0000000000..bf10853bfb --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/91f11008defda918951bda868cc68c6373fb0e6a diff --git a/test/core/security/corpus/alts_credentials_corpus/92e01a34047b660a798086d55a3d8d7100a01939 b/test/core/security/corpus/alts_credentials_corpus/92e01a34047b660a798086d55a3d8d7100a01939 Binary files differnew file mode 100644 index 0000000000..e86bc1d589 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/92e01a34047b660a798086d55a3d8d7100a01939 diff --git a/test/core/security/corpus/alts_credentials_corpus/963fafadb4de09dee0e6a852bd61b1740039a465 b/test/core/security/corpus/alts_credentials_corpus/963fafadb4de09dee0e6a852bd61b1740039a465 new file mode 100644 index 0000000000..8933b18c72 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/963fafadb4de09dee0e6a852bd61b1740039a465 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/97bf33ec97b93fcc2449431915911a55b906e3b6 b/test/core/security/corpus/alts_credentials_corpus/97bf33ec97b93fcc2449431915911a55b906e3b6 new file mode 100644 index 0000000000..8101e3720d --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/97bf33ec97b93fcc2449431915911a55b906e3b6 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/99e31e12b02b02479d10b2c08426906bd93a0840 b/test/core/security/corpus/alts_credentials_corpus/99e31e12b02b02479d10b2c08426906bd93a0840 new file mode 100644 index 0000000000..9fe2a6a137 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/99e31e12b02b02479d10b2c08426906bd93a0840 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/9a75ce693e7259d4d3bb9203dfc0a65f8bbaa466 b/test/core/security/corpus/alts_credentials_corpus/9a75ce693e7259d4d3bb9203dfc0a65f8bbaa466 Binary files differnew file mode 100644 index 0000000000..5366cdd4a6 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/9a75ce693e7259d4d3bb9203dfc0a65f8bbaa466 diff --git a/test/core/security/corpus/alts_credentials_corpus/9ac0d956f9743e026baad7319ba2a75d9f1a534f b/test/core/security/corpus/alts_credentials_corpus/9ac0d956f9743e026baad7319ba2a75d9f1a534f Binary files differnew file mode 100644 index 0000000000..adb0583eb6 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/9ac0d956f9743e026baad7319ba2a75d9f1a534f diff --git a/test/core/security/corpus/alts_credentials_corpus/9ae56d4451dd3e1b66ddc250d84dbf6d8cae0dbd b/test/core/security/corpus/alts_credentials_corpus/9ae56d4451dd3e1b66ddc250d84dbf6d8cae0dbd Binary files differnew file mode 100644 index 0000000000..121d0cb5d6 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/9ae56d4451dd3e1b66ddc250d84dbf6d8cae0dbd diff --git a/test/core/security/corpus/alts_credentials_corpus/9b9a3a1e4023c9b172060249752a482a3437ef2a b/test/core/security/corpus/alts_credentials_corpus/9b9a3a1e4023c9b172060249752a482a3437ef2a Binary files differnew file mode 100644 index 0000000000..0b19f19a43 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/9b9a3a1e4023c9b172060249752a482a3437ef2a diff --git a/test/core/security/corpus/alts_credentials_corpus/9c81164e10bf612c352dca3ecabf57743b451d42 b/test/core/security/corpus/alts_credentials_corpus/9c81164e10bf612c352dca3ecabf57743b451d42 new file mode 100644 index 0000000000..1cae116cff --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/9c81164e10bf612c352dca3ecabf57743b451d42 @@ -0,0 +1,2 @@ + +z
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/9d8b420b5d32deb0140ab91eeebba58ca6163722 b/test/core/security/corpus/alts_credentials_corpus/9d8b420b5d32deb0140ab91eeebba58ca6163722 Binary files differnew file mode 100644 index 0000000000..6d0f80948e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/9d8b420b5d32deb0140ab91eeebba58ca6163722 diff --git a/test/core/security/corpus/alts_credentials_corpus/9de687bf1e2cfac54c3b2e2eb85b53014a460ff7 b/test/core/security/corpus/alts_credentials_corpus/9de687bf1e2cfac54c3b2e2eb85b53014a460ff7 Binary files differnew file mode 100644 index 0000000000..789f59cd27 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/9de687bf1e2cfac54c3b2e2eb85b53014a460ff7 diff --git a/test/core/security/corpus/alts_credentials_corpus/9f3cda19a186bd11bfac361b464f92daa129a33b b/test/core/security/corpus/alts_credentials_corpus/9f3cda19a186bd11bfac361b464f92daa129a33b Binary files differnew file mode 100644 index 0000000000..61347c386e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/9f3cda19a186bd11bfac361b464f92daa129a33b diff --git a/test/core/security/corpus/alts_credentials_corpus/a14fc6a608121f8abf0fe25cf466720f00f25653 b/test/core/security/corpus/alts_credentials_corpus/a14fc6a608121f8abf0fe25cf466720f00f25653 Binary files differnew file mode 100644 index 0000000000..58af76210a --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/a14fc6a608121f8abf0fe25cf466720f00f25653 diff --git a/test/core/security/corpus/alts_credentials_corpus/a39906074669a6b76a35b0adf2bf36ad751f3b35 b/test/core/security/corpus/alts_credentials_corpus/a39906074669a6b76a35b0adf2bf36ad751f3b35 Binary files differnew file mode 100644 index 0000000000..e10cdb997e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/a39906074669a6b76a35b0adf2bf36ad751f3b35 diff --git a/test/core/security/corpus/alts_credentials_corpus/a454ca483b4a66b83826d061be2859dd79ff0d6c b/test/core/security/corpus/alts_credentials_corpus/a454ca483b4a66b83826d061be2859dd79ff0d6c Binary files differnew file mode 100644 index 0000000000..38424fc7a2 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/a454ca483b4a66b83826d061be2859dd79ff0d6c diff --git a/test/core/security/corpus/alts_credentials_corpus/a52df5607370ff0f56d821000f3d5e386a01d489 b/test/core/security/corpus/alts_credentials_corpus/a52df5607370ff0f56d821000f3d5e386a01d489 new file mode 100644 index 0000000000..f16da079ed --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/a52df5607370ff0f56d821000f3d5e386a01d489 @@ -0,0 +1 @@ +;
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/a56eaf47f7c7263e53efdc55ec39063dbb4ae71c b/test/core/security/corpus/alts_credentials_corpus/a56eaf47f7c7263e53efdc55ec39063dbb4ae71c Binary files differnew file mode 100644 index 0000000000..3664ce0f99 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/a56eaf47f7c7263e53efdc55ec39063dbb4ae71c diff --git a/test/core/security/corpus/alts_credentials_corpus/a79249fb8f7d53f0a280359d2d9df31594adbdfc b/test/core/security/corpus/alts_credentials_corpus/a79249fb8f7d53f0a280359d2d9df31594adbdfc Binary files differnew file mode 100644 index 0000000000..d7f1f455b1 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/a79249fb8f7d53f0a280359d2d9df31594adbdfc diff --git a/test/core/security/corpus/alts_credentials_corpus/aa98a46f25004f7436aadb36ff8b7f07ed7bfce1 b/test/core/security/corpus/alts_credentials_corpus/aa98a46f25004f7436aadb36ff8b7f07ed7bfce1 new file mode 100644 index 0000000000..f1db8d9f2c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/aa98a46f25004f7436aadb36ff8b7f07ed7bfce1 @@ -0,0 +1 @@ +ap/+
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc b/test/core/security/corpus/alts_credentials_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc @@ -0,0 +1 @@ + diff --git a/test/core/security/corpus/alts_credentials_corpus/afd8e19f7bfd6c963f1856be59b75627864821dc b/test/core/security/corpus/alts_credentials_corpus/afd8e19f7bfd6c963f1856be59b75627864821dc new file mode 100644 index 0000000000..385405e116 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/afd8e19f7bfd6c963f1856be59b75627864821dc @@ -0,0 +1,2 @@ ++ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/b3966239b8568442baecbeb0f8a1aa29dcdfd7ed b/test/core/security/corpus/alts_credentials_corpus/b3966239b8568442baecbeb0f8a1aa29dcdfd7ed Binary files differnew file mode 100644 index 0000000000..3d9fb86775 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/b3966239b8568442baecbeb0f8a1aa29dcdfd7ed diff --git a/test/core/security/corpus/alts_credentials_corpus/b430d41ef65493b3e917182c23ce90df983e01ab b/test/core/security/corpus/alts_credentials_corpus/b430d41ef65493b3e917182c23ce90df983e01ab new file mode 100644 index 0000000000..cbb8cebbb9 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/b430d41ef65493b3e917182c23ce90df983e01ab @@ -0,0 +1,2 @@ + + diff --git a/test/core/security/corpus/alts_credentials_corpus/b44e715e0cfe05f0c92a9e000ac3c36aae17df9d b/test/core/security/corpus/alts_credentials_corpus/b44e715e0cfe05f0c92a9e000ac3c36aae17df9d new file mode 100644 index 0000000000..f0b1381e2c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/b44e715e0cfe05f0c92a9e000ac3c36aae17df9d @@ -0,0 +1 @@ +]]
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/b4cf4ef7b3f64eff76cf99091fddc04411774708 b/test/core/security/corpus/alts_credentials_corpus/b4cf4ef7b3f64eff76cf99091fddc04411774708 Binary files differnew file mode 100644 index 0000000000..65d4adbeb4 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/b4cf4ef7b3f64eff76cf99091fddc04411774708 diff --git a/test/core/security/corpus/alts_credentials_corpus/b53d84468ea93620a9824ca65acf1179f431e763 b/test/core/security/corpus/alts_credentials_corpus/b53d84468ea93620a9824ca65acf1179f431e763 Binary files differnew file mode 100644 index 0000000000..5844d31855 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/b53d84468ea93620a9824ca65acf1179f431e763 diff --git a/test/core/security/corpus/alts_credentials_corpus/b6ac4831cc5baabee9c8ab9af9ca3923f91097a0 b/test/core/security/corpus/alts_credentials_corpus/b6ac4831cc5baabee9c8ab9af9ca3923f91097a0 new file mode 100644 index 0000000000..3d54a26e1c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/b6ac4831cc5baabee9c8ab9af9ca3923f91097a0 @@ -0,0 +1,2 @@ +A +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/b7f4a484866a8050dbc63bc905c9803c6964eda5 b/test/core/security/corpus/alts_credentials_corpus/b7f4a484866a8050dbc63bc905c9803c6964eda5 Binary files differnew file mode 100644 index 0000000000..e17c966032 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/b7f4a484866a8050dbc63bc905c9803c6964eda5 diff --git a/test/core/security/corpus/alts_credentials_corpus/b8f21e59f90431c982d5ec3fb54ae4605f102252 b/test/core/security/corpus/alts_credentials_corpus/b8f21e59f90431c982d5ec3fb54ae4605f102252 Binary files differnew file mode 100644 index 0000000000..79e3486245 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/b8f21e59f90431c982d5ec3fb54ae4605f102252 diff --git a/test/core/security/corpus/alts_credentials_corpus/bad10b6581cdead8e7cb96e4f544dcf0ea650fbc b/test/core/security/corpus/alts_credentials_corpus/bad10b6581cdead8e7cb96e4f544dcf0ea650fbc Binary files differnew file mode 100644 index 0000000000..9deb7606c7 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/bad10b6581cdead8e7cb96e4f544dcf0ea650fbc diff --git a/test/core/security/corpus/alts_credentials_corpus/bb01bed86b43257be9f527388e1183f52438c473 b/test/core/security/corpus/alts_credentials_corpus/bb01bed86b43257be9f527388e1183f52438c473 new file mode 100644 index 0000000000..ad47d46dc2 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/bb01bed86b43257be9f527388e1183f52438c473 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/bb7497b00f0d999ef39dbf81c6bd0441e32723b6 b/test/core/security/corpus/alts_credentials_corpus/bb7497b00f0d999ef39dbf81c6bd0441e32723b6 Binary files differnew file mode 100644 index 0000000000..3b2f10845c --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/bb7497b00f0d999ef39dbf81c6bd0441e32723b6 diff --git a/test/core/security/corpus/alts_credentials_corpus/bf01b72e635deda1b4a8468f1cc36f01a54e1338 b/test/core/security/corpus/alts_credentials_corpus/bf01b72e635deda1b4a8468f1cc36f01a54e1338 Binary files differnew file mode 100644 index 0000000000..7fa6cf8df9 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/bf01b72e635deda1b4a8468f1cc36f01a54e1338 diff --git a/test/core/security/corpus/alts_credentials_corpus/bf8b4530d8d246dd74ac53a13471bba17941dff7 b/test/core/security/corpus/alts_credentials_corpus/bf8b4530d8d246dd74ac53a13471bba17941dff7 new file mode 100644 index 0000000000..6b2aaa7640 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/bf8b4530d8d246dd74ac53a13471bba17941dff7 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/c08bc84ab6a512b901bb730beb05c8394e4f1c5d b/test/core/security/corpus/alts_credentials_corpus/c08bc84ab6a512b901bb730beb05c8394e4f1c5d Binary files differnew file mode 100644 index 0000000000..8d753685ca --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c08bc84ab6a512b901bb730beb05c8394e4f1c5d diff --git a/test/core/security/corpus/alts_credentials_corpus/c244b635d94e6f5d6b344887434be3e001a04b41 b/test/core/security/corpus/alts_credentials_corpus/c244b635d94e6f5d6b344887434be3e001a04b41 Binary files differnew file mode 100644 index 0000000000..92e73a2356 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c244b635d94e6f5d6b344887434be3e001a04b41 diff --git a/test/core/security/corpus/alts_credentials_corpus/c281efe9620da999a637ff6e9b3279ec613fb992 b/test/core/security/corpus/alts_credentials_corpus/c281efe9620da999a637ff6e9b3279ec613fb992 Binary files differnew file mode 100644 index 0000000000..c17a77e0da --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c281efe9620da999a637ff6e9b3279ec613fb992 diff --git a/test/core/security/corpus/alts_credentials_corpus/c30a212824ee71e215f475f453de17c65a200101 b/test/core/security/corpus/alts_credentials_corpus/c30a212824ee71e215f475f453de17c65a200101 Binary files differnew file mode 100644 index 0000000000..86ac99e288 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c30a212824ee71e215f475f453de17c65a200101 diff --git a/test/core/security/corpus/alts_credentials_corpus/c449427f35b7ecdf5641073629f7723df52c4cb0 b/test/core/security/corpus/alts_credentials_corpus/c449427f35b7ecdf5641073629f7723df52c4cb0 new file mode 100644 index 0000000000..87d1a322d7 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c449427f35b7ecdf5641073629f7723df52c4cb0 @@ -0,0 +1 @@ +Տ-
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/c60240cd3b02eb71e2bf5ebd59afa3a5dc9b5e4d b/test/core/security/corpus/alts_credentials_corpus/c60240cd3b02eb71e2bf5ebd59afa3a5dc9b5e4d Binary files differnew file mode 100644 index 0000000000..f8804b84e4 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c60240cd3b02eb71e2bf5ebd59afa3a5dc9b5e4d diff --git a/test/core/security/corpus/alts_credentials_corpus/c60cdf9c3fb9060838f445b3bc3852b6f81e1e4c b/test/core/security/corpus/alts_credentials_corpus/c60cdf9c3fb9060838f445b3bc3852b6f81e1e4c Binary files differnew file mode 100644 index 0000000000..327246f1c9 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c60cdf9c3fb9060838f445b3bc3852b6f81e1e4c diff --git a/test/core/security/corpus/alts_credentials_corpus/c72d0501bacadb45242c553ba292591302f12a6a b/test/core/security/corpus/alts_credentials_corpus/c72d0501bacadb45242c553ba292591302f12a6a Binary files differnew file mode 100644 index 0000000000..ca02bafb78 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c72d0501bacadb45242c553ba292591302f12a6a diff --git a/test/core/security/corpus/alts_credentials_corpus/c739e7b5ad999edbdeffdab672dbc30deb3959a0 b/test/core/security/corpus/alts_credentials_corpus/c739e7b5ad999edbdeffdab672dbc30deb3959a0 Binary files differnew file mode 100644 index 0000000000..d7f2d22aa8 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c739e7b5ad999edbdeffdab672dbc30deb3959a0 diff --git a/test/core/security/corpus/alts_credentials_corpus/c7d73b12a7108d82f8dac6d8a6a34f838601aca6 b/test/core/security/corpus/alts_credentials_corpus/c7d73b12a7108d82f8dac6d8a6a34f838601aca6 Binary files differnew file mode 100644 index 0000000000..b38437a65e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/c7d73b12a7108d82f8dac6d8a6a34f838601aca6 diff --git a/test/core/security/corpus/alts_credentials_corpus/ca781e1add632433293e847ae9e71649c217ee5f b/test/core/security/corpus/alts_credentials_corpus/ca781e1add632433293e847ae9e71649c217ee5f Binary files differnew file mode 100644 index 0000000000..5c79dd1c52 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/ca781e1add632433293e847ae9e71649c217ee5f diff --git a/test/core/security/corpus/alts_credentials_corpus/cc48e916f40e8d69c2d07cfda42c7d3b7fe3447a b/test/core/security/corpus/alts_credentials_corpus/cc48e916f40e8d69c2d07cfda42c7d3b7fe3447a Binary files differnew file mode 100644 index 0000000000..11ccb07de1 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/cc48e916f40e8d69c2d07cfda42c7d3b7fe3447a diff --git a/test/core/security/corpus/alts_credentials_corpus/cca1aff4c08ee4ccbcb6f80e1cd1480a0a093cfd b/test/core/security/corpus/alts_credentials_corpus/cca1aff4c08ee4ccbcb6f80e1cd1480a0a093cfd Binary files differnew file mode 100644 index 0000000000..b7bebbe8e9 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/cca1aff4c08ee4ccbcb6f80e1cd1480a0a093cfd diff --git a/test/core/security/corpus/alts_credentials_corpus/cf6ae8bf1d08d25e235b7bee0839984bbc04edf6 b/test/core/security/corpus/alts_credentials_corpus/cf6ae8bf1d08d25e235b7bee0839984bbc04edf6 Binary files differnew file mode 100644 index 0000000000..32eb656fbf --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/cf6ae8bf1d08d25e235b7bee0839984bbc04edf6 diff --git a/test/core/security/corpus/alts_credentials_corpus/cfc52fa086292c699efd7bf41d2fae3deb449536 b/test/core/security/corpus/alts_credentials_corpus/cfc52fa086292c699efd7bf41d2fae3deb449536 Binary files differnew file mode 100644 index 0000000000..285e35d40f --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/cfc52fa086292c699efd7bf41d2fae3deb449536 diff --git a/test/core/security/corpus/alts_credentials_corpus/cfe13ef3c6c713a059f231f0001ecec97e2a932d b/test/core/security/corpus/alts_credentials_corpus/cfe13ef3c6c713a059f231f0001ecec97e2a932d Binary files differnew file mode 100644 index 0000000000..1059f60cec --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/cfe13ef3c6c713a059f231f0001ecec97e2a932d diff --git a/test/core/security/corpus/alts_credentials_corpus/d14026ac6421bca7161024f4e735cb80a1068d01 b/test/core/security/corpus/alts_credentials_corpus/d14026ac6421bca7161024f4e735cb80a1068d01 new file mode 100644 index 0000000000..68b7682c71 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/d14026ac6421bca7161024f4e735cb80a1068d01 @@ -0,0 +1,2 @@ + ++
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/d2fb6e8f7867fc1e2ebe723da2b5246dc9cc6b14 b/test/core/security/corpus/alts_credentials_corpus/d2fb6e8f7867fc1e2ebe723da2b5246dc9cc6b14 Binary files differnew file mode 100644 index 0000000000..9854260459 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/d2fb6e8f7867fc1e2ebe723da2b5246dc9cc6b14 diff --git a/test/core/security/corpus/alts_credentials_corpus/d4db7d51bdaa4781cf12c3b59914bad414d2a41e b/test/core/security/corpus/alts_credentials_corpus/d4db7d51bdaa4781cf12c3b59914bad414d2a41e Binary files differnew file mode 100644 index 0000000000..0979d45bca --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/d4db7d51bdaa4781cf12c3b59914bad414d2a41e diff --git a/test/core/security/corpus/alts_credentials_corpus/d533da0e7f8c1e39bb025b4d7a89613142a6f54e b/test/core/security/corpus/alts_credentials_corpus/d533da0e7f8c1e39bb025b4d7a89613142a6f54e Binary files differnew file mode 100644 index 0000000000..89ef0d2307 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/d533da0e7f8c1e39bb025b4d7a89613142a6f54e diff --git a/test/core/security/corpus/alts_credentials_corpus/d5cf489d01a1b847a7aac5dddabff23fdc218e1e b/test/core/security/corpus/alts_credentials_corpus/d5cf489d01a1b847a7aac5dddabff23fdc218e1e Binary files differnew file mode 100644 index 0000000000..c544b2793e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/d5cf489d01a1b847a7aac5dddabff23fdc218e1e diff --git a/test/core/security/corpus/alts_credentials_corpus/d686f8561a249c7c15c78f76a5fceb884286e070 b/test/core/security/corpus/alts_credentials_corpus/d686f8561a249c7c15c78f76a5fceb884286e070 Binary files differnew file mode 100644 index 0000000000..b96c459973 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/d686f8561a249c7c15c78f76a5fceb884286e070 diff --git a/test/core/security/corpus/alts_credentials_corpus/d92424daad9d96a40e5ab177e3824c36ef51dc0f b/test/core/security/corpus/alts_credentials_corpus/d92424daad9d96a40e5ab177e3824c36ef51dc0f Binary files differnew file mode 100644 index 0000000000..509eb39065 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/d92424daad9d96a40e5ab177e3824c36ef51dc0f diff --git a/test/core/security/corpus/alts_credentials_corpus/db242a11ed88b2b26af46770dd1927d9f35301fb b/test/core/security/corpus/alts_credentials_corpus/db242a11ed88b2b26af46770dd1927d9f35301fb Binary files differnew file mode 100644 index 0000000000..bd5d04676a --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/db242a11ed88b2b26af46770dd1927d9f35301fb diff --git a/test/core/security/corpus/alts_credentials_corpus/db32eb04db13d58f65f46d262608bd088987c063 b/test/core/security/corpus/alts_credentials_corpus/db32eb04db13d58f65f46d262608bd088987c063 Binary files differnew file mode 100644 index 0000000000..5c526d8a28 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/db32eb04db13d58f65f46d262608bd088987c063 diff --git a/test/core/security/corpus/alts_credentials_corpus/db39a953317951759e40734de6607a0b4457728e b/test/core/security/corpus/alts_credentials_corpus/db39a953317951759e40734de6607a0b4457728e Binary files differnew file mode 100644 index 0000000000..d794576b59 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/db39a953317951759e40734de6607a0b4457728e diff --git a/test/core/security/corpus/alts_credentials_corpus/dc5e8f3102456bed90d17303bc4cff1a7e076d5d b/test/core/security/corpus/alts_credentials_corpus/dc5e8f3102456bed90d17303bc4cff1a7e076d5d new file mode 100644 index 0000000000..53e1bbce92 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/dc5e8f3102456bed90d17303bc4cff1a7e076d5d @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/dd9542bbed8e5dc58da2789edbfb9c38d578d3b4 b/test/core/security/corpus/alts_credentials_corpus/dd9542bbed8e5dc58da2789edbfb9c38d578d3b4 Binary files differnew file mode 100644 index 0000000000..95fd950be8 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/dd9542bbed8e5dc58da2789edbfb9c38d578d3b4 diff --git a/test/core/security/corpus/alts_credentials_corpus/de2ebb1ed324385de500a1a3308846239857c3c7 b/test/core/security/corpus/alts_credentials_corpus/de2ebb1ed324385de500a1a3308846239857c3c7 new file mode 100644 index 0000000000..d0cee5f847 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/de2ebb1ed324385de500a1a3308846239857c3c7 @@ -0,0 +1 @@ ++
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/de8ba9158254c1cd84b53df1e4cdf1757b1392f1 b/test/core/security/corpus/alts_credentials_corpus/de8ba9158254c1cd84b53df1e4cdf1757b1392f1 Binary files differnew file mode 100644 index 0000000000..1cbbe5b8cb --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/de8ba9158254c1cd84b53df1e4cdf1757b1392f1 diff --git a/test/core/security/corpus/alts_credentials_corpus/e1dd260746f50024822a8b729b89545d26decfb8 b/test/core/security/corpus/alts_credentials_corpus/e1dd260746f50024822a8b729b89545d26decfb8 Binary files differnew file mode 100644 index 0000000000..c44854edf7 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/e1dd260746f50024822a8b729b89545d26decfb8 diff --git a/test/core/security/corpus/alts_credentials_corpus/e29add81b20dc570fdc885782689f6dccb1c5fad b/test/core/security/corpus/alts_credentials_corpus/e29add81b20dc570fdc885782689f6dccb1c5fad Binary files differnew file mode 100644 index 0000000000..5c50fe7539 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/e29add81b20dc570fdc885782689f6dccb1c5fad diff --git a/test/core/security/corpus/alts_credentials_corpus/e2e99af62843cd3b29d50daeb118e58830784da9 b/test/core/security/corpus/alts_credentials_corpus/e2e99af62843cd3b29d50daeb118e58830784da9 Binary files differnew file mode 100644 index 0000000000..04da1314d9 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/e2e99af62843cd3b29d50daeb118e58830784da9 diff --git a/test/core/security/corpus/alts_credentials_corpus/e46611c5daf99662e1576147c1623409752a1f39 b/test/core/security/corpus/alts_credentials_corpus/e46611c5daf99662e1576147c1623409752a1f39 new file mode 100644 index 0000000000..0334d31def --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/e46611c5daf99662e1576147c1623409752a1f39 @@ -0,0 +1 @@ +##
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/e5a1ba11af830e9d2db201c5164f75747a85fe9b b/test/core/security/corpus/alts_credentials_corpus/e5a1ba11af830e9d2db201c5164f75747a85fe9b Binary files differnew file mode 100644 index 0000000000..8e8b1e2001 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/e5a1ba11af830e9d2db201c5164f75747a85fe9b diff --git a/test/core/security/corpus/alts_credentials_corpus/e6026ee0badf216b326443a5f708446b2f2e579f b/test/core/security/corpus/alts_credentials_corpus/e6026ee0badf216b326443a5f708446b2f2e579f Binary files differnew file mode 100644 index 0000000000..a99014fa41 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/e6026ee0badf216b326443a5f708446b2f2e579f diff --git a/test/core/security/corpus/alts_credentials_corpus/e6c7d2c0038fa1f03fc6590a726abc98f4c641f3 b/test/core/security/corpus/alts_credentials_corpus/e6c7d2c0038fa1f03fc6590a726abc98f4c641f3 new file mode 100644 index 0000000000..8f5a9f5b33 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/e6c7d2c0038fa1f03fc6590a726abc98f4c641f3 @@ -0,0 +1 @@ +i
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/eafdef6a630bed71bd0e4f3d4a16b5fa0c920651 b/test/core/security/corpus/alts_credentials_corpus/eafdef6a630bed71bd0e4f3d4a16b5fa0c920651 Binary files differnew file mode 100644 index 0000000000..6fbe750e01 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/eafdef6a630bed71bd0e4f3d4a16b5fa0c920651 diff --git a/test/core/security/corpus/alts_credentials_corpus/ece985b9b82e27281514d460709d7edf8203ded7 b/test/core/security/corpus/alts_credentials_corpus/ece985b9b82e27281514d460709d7edf8203ded7 Binary files differnew file mode 100644 index 0000000000..c1243022a0 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/ece985b9b82e27281514d460709d7edf8203ded7 diff --git a/test/core/security/corpus/alts_credentials_corpus/edb8f4259f756c2c4bc731f05beaa36f992cf079 b/test/core/security/corpus/alts_credentials_corpus/edb8f4259f756c2c4bc731f05beaa36f992cf079 Binary files differnew file mode 100644 index 0000000000..1cc08a4d39 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/edb8f4259f756c2c4bc731f05beaa36f992cf079 diff --git a/test/core/security/corpus/alts_credentials_corpus/edce7778c2e1adb81dda3d057a6536759a7cb293 b/test/core/security/corpus/alts_credentials_corpus/edce7778c2e1adb81dda3d057a6536759a7cb293 new file mode 100644 index 0000000000..39b52cf971 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/edce7778c2e1adb81dda3d057a6536759a7cb293 @@ -0,0 +1 @@ ++
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/ee4040c0dd406dd616c49ed2c37b40478dabfe0f b/test/core/security/corpus/alts_credentials_corpus/ee4040c0dd406dd616c49ed2c37b40478dabfe0f Binary files differnew file mode 100644 index 0000000000..48325e312e --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/ee4040c0dd406dd616c49ed2c37b40478dabfe0f diff --git a/test/core/security/corpus/alts_credentials_corpus/ee69f2b380663d051a70f30fcfce9f79f5341e5a b/test/core/security/corpus/alts_credentials_corpus/ee69f2b380663d051a70f30fcfce9f79f5341e5a Binary files differnew file mode 100644 index 0000000000..7e0ad2a61a --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/ee69f2b380663d051a70f30fcfce9f79f5341e5a diff --git a/test/core/security/corpus/alts_credentials_corpus/efc6743e47274058771bb6eda1fefa017bde4a95 b/test/core/security/corpus/alts_credentials_corpus/efc6743e47274058771bb6eda1fefa017bde4a95 Binary files differnew file mode 100644 index 0000000000..4418e8ab73 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/efc6743e47274058771bb6eda1fefa017bde4a95 diff --git a/test/core/security/corpus/alts_credentials_corpus/f0038e54162000694d882b1acb80930c807b41d2 b/test/core/security/corpus/alts_credentials_corpus/f0038e54162000694d882b1acb80930c807b41d2 Binary files differnew file mode 100644 index 0000000000..292a5e4bd3 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/f0038e54162000694d882b1acb80930c807b41d2 diff --git a/test/core/security/corpus/alts_credentials_corpus/f1deb9e388c877337dabe92f31b01e2a019a10f4 b/test/core/security/corpus/alts_credentials_corpus/f1deb9e388c877337dabe92f31b01e2a019a10f4 Binary files differnew file mode 100644 index 0000000000..46464ee9c2 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/f1deb9e388c877337dabe92f31b01e2a019a10f4 diff --git a/test/core/security/corpus/alts_credentials_corpus/f3a09373e4d3c7310d372089e6deb15d6b22c198 b/test/core/security/corpus/alts_credentials_corpus/f3a09373e4d3c7310d372089e6deb15d6b22c198 new file mode 100644 index 0000000000..a974996100 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/f3a09373e4d3c7310d372089e6deb15d6b22c198 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/f3db7ef6495fa1ac5bb4db293fb38dd59122bb7c b/test/core/security/corpus/alts_credentials_corpus/f3db7ef6495fa1ac5bb4db293fb38dd59122bb7c new file mode 100644 index 0000000000..8afc32bf9d --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/f3db7ef6495fa1ac5bb4db293fb38dd59122bb7c @@ -0,0 +1,2 @@ +[[ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/f434bb4ceecc573e085d4c3ef453ef01e93d9c89 b/test/core/security/corpus/alts_credentials_corpus/f434bb4ceecc573e085d4c3ef453ef01e93d9c89 Binary files differnew file mode 100644 index 0000000000..2b66a00cd8 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/f434bb4ceecc573e085d4c3ef453ef01e93d9c89 diff --git a/test/core/security/corpus/alts_credentials_corpus/f55bceaad42ddf9d2b37fdfca68255d29a696109 b/test/core/security/corpus/alts_credentials_corpus/f55bceaad42ddf9d2b37fdfca68255d29a696109 new file mode 100644 index 0000000000..a8eef8f96a --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/f55bceaad42ddf9d2b37fdfca68255d29a696109 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/f62ca5321428a5d23f3c804fb51eb4e65bc58716 b/test/core/security/corpus/alts_credentials_corpus/f62ca5321428a5d23f3c804fb51eb4e65bc58716 Binary files differnew file mode 100644 index 0000000000..0d80f7be69 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/f62ca5321428a5d23f3c804fb51eb4e65bc58716 diff --git a/test/core/security/corpus/alts_credentials_corpus/f7c6a558b8d0af64db2b139371a7af7068b01b92 b/test/core/security/corpus/alts_credentials_corpus/f7c6a558b8d0af64db2b139371a7af7068b01b92 Binary files differnew file mode 100644 index 0000000000..d46ea45bc4 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/f7c6a558b8d0af64db2b139371a7af7068b01b92 diff --git a/test/core/security/corpus/alts_credentials_corpus/faa1781e1444bba5b8c677bc5e2a38d023a1ec65 b/test/core/security/corpus/alts_credentials_corpus/faa1781e1444bba5b8c677bc5e2a38d023a1ec65 new file mode 100644 index 0000000000..013d565bb4 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/faa1781e1444bba5b8c677bc5e2a38d023a1ec65 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/fceba33ada1dda05fccedfefd331c9a201f1a2e5 b/test/core/security/corpus/alts_credentials_corpus/fceba33ada1dda05fccedfefd331c9a201f1a2e5 new file mode 100644 index 0000000000..f3db26dc2f --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/fceba33ada1dda05fccedfefd331c9a201f1a2e5 @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/core/security/corpus/alts_credentials_corpus/fd668bef6fdaf7f3ffd58d8c60ce550476652e60 b/test/core/security/corpus/alts_credentials_corpus/fd668bef6fdaf7f3ffd58d8c60ce550476652e60 Binary files differnew file mode 100644 index 0000000000..dcefd99985 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/fd668bef6fdaf7f3ffd58d8c60ce550476652e60 diff --git a/test/core/security/corpus/alts_credentials_corpus/fdf06b928e37e7c4ae59a568b5723ad98bbed6e5 b/test/core/security/corpus/alts_credentials_corpus/fdf06b928e37e7c4ae59a568b5723ad98bbed6e5 Binary files differnew file mode 100644 index 0000000000..fe28d69b5f --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/fdf06b928e37e7c4ae59a568b5723ad98bbed6e5 diff --git a/test/core/security/corpus/alts_credentials_corpus/fe2fc5d499aeb2762387ef2e3ce939280813dec0 b/test/core/security/corpus/alts_credentials_corpus/fe2fc5d499aeb2762387ef2e3ce939280813dec0 Binary files differnew file mode 100644 index 0000000000..cb035e7101 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/fe2fc5d499aeb2762387ef2e3ce939280813dec0 diff --git a/test/core/security/corpus/alts_credentials_corpus/ff548d368b090409a138e5cc4afc7f43b4a3fbbd b/test/core/security/corpus/alts_credentials_corpus/ff548d368b090409a138e5cc4afc7f43b4a3fbbd Binary files differnew file mode 100644 index 0000000000..caadbc0309 --- /dev/null +++ b/test/core/security/corpus/alts_credentials_corpus/ff548d368b090409a138e5cc4afc7f43b4a3fbbd diff --git a/test/core/security/create_jwt.cc b/test/core/security/create_jwt.cc index 867a8ba575..2ea640b605 100644 --- a/test/core/security/create_jwt.cc +++ b/test/core/security/create_jwt.cc @@ -24,9 +24,10 @@ #include <grpc/slice.h> #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> +#include "test/core/util/cmdline.h" + void create_jwt(const char* json_key_file_path, const char* service_url, const char* scope) { grpc_auth_json_key key; @@ -35,10 +36,11 @@ void create_jwt(const char* json_key_file_path, const char* service_url, GPR_ASSERT(GRPC_LOG_IF_ERROR( "load_file", grpc_load_file(json_key_file_path, 1, &json_key_data))); key = grpc_auth_json_key_create_from_string( - (const char*)GRPC_SLICE_START_PTR(json_key_data)); + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(json_key_data)); grpc_slice_unref(json_key_data); if (!grpc_auth_json_key_is_valid(&key)) { fprintf(stderr, "Could not parse json key.\n"); + fflush(stderr); exit(1); } jwt = grpc_jwt_encode_and_sign( @@ -47,6 +49,7 @@ void create_jwt(const char* json_key_file_path, const char* service_url, grpc_auth_json_key_destruct(&key); if (jwt == nullptr) { fprintf(stderr, "Could not create JWT.\n"); + fflush(stderr); exit(1); } fprintf(stdout, "%s\n", jwt); @@ -72,16 +75,19 @@ int main(int argc, char** argv) { if (json_key_file_path == nullptr) { fprintf(stderr, "Missing --json_key option.\n"); + fflush(stderr); exit(1); } if (scope != nullptr) { if (service_url != nullptr) { fprintf(stderr, "Options --scope and --service_url are mutually exclusive.\n"); + fflush(stderr); exit(1); } } else if (service_url == nullptr) { fprintf(stderr, "Need one of --service_url or --scope options.\n"); + fflush(stderr); exit(1); } diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index ecc61928f5..8a793e4bb2 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -31,6 +31,9 @@ #include <grpc/support/string_util.h> #include <grpc/support/time.h> +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/security/credentials/composite/composite_credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" @@ -38,11 +41,10 @@ #include "src/core/lib/security/credentials/jwt/jwt_credentials.h" #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h" #include "src/core/lib/security/transport/auth_filters.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" #include "test/core/util/test_config.h" +using grpc_core::internal::set_gce_tenancy_checker_for_testing; + /* -- Mock channel credentials. -- */ static grpc_channel_credentials* grpc_mock_channel_credentials_create( @@ -120,6 +122,12 @@ static const char other_test_service_url[] = "https://bar.com/bar.v1"; static const char test_method[] = "ThisIsNotAMethod"; +/* -- Global state flags. -- */ + +static bool g_test_is_on_gce = false; + +static bool g_test_gce_tenancy_checker_called = false; + /* -- Utils. -- */ static char* test_json_key_str(void) { @@ -140,7 +148,7 @@ static grpc_httpcli_response http_response(int status, const char* body) { grpc_httpcli_response response; memset(&response, 0, sizeof(grpc_httpcli_response)); response.status = status; - response.body = gpr_strdup((char*)body); + response.body = gpr_strdup(const_cast<char*>(body)); response.body_length = strlen(body); return response; } @@ -324,7 +332,7 @@ static void check_metadata(const expected_md* expected, } static void check_request_metadata(void* arg, grpc_error* error) { - request_metadata_state* state = (request_metadata_state*)arg; + request_metadata_state* state = static_cast<request_metadata_state*>(arg); gpr_log(GPR_INFO, "expected_error: %s", grpc_error_string(state->expected_error)); gpr_log(GPR_INFO, "actual_error: %s", grpc_error_string(error)); @@ -754,7 +762,7 @@ static grpc_service_account_jwt_access_credentials* creds_as_jwt( grpc_call_credentials* creds) { GPR_ASSERT(creds != nullptr); GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0); - return (grpc_service_account_jwt_access_credentials*)creds; + return reinterpret_cast<grpc_service_account_jwt_access_credentials*>(creds); } static void test_jwt_creds_lifetime(void) { @@ -867,16 +875,20 @@ static void set_google_default_creds_env_var_with_file_contents( static void test_google_default_creds_auth_key(void) { grpc_core::ExecCtx exec_ctx; grpc_service_account_jwt_access_credentials* jwt; + grpc_google_default_channel_credentials* default_creds; grpc_composite_channel_credentials* creds; char* json_key = test_json_key_str(); grpc_flush_cached_google_default_credentials(); set_google_default_creds_env_var_with_file_contents( "json_key_google_default_creds", json_key); gpr_free(json_key); - creds = (grpc_composite_channel_credentials*) - grpc_google_default_credentials_create(); - GPR_ASSERT(creds != nullptr); - jwt = (grpc_service_account_jwt_access_credentials*)creds->call_creds; + creds = reinterpret_cast<grpc_composite_channel_credentials*>( + grpc_google_default_credentials_create()); + default_creds = reinterpret_cast<grpc_google_default_channel_credentials*>( + creds->inner_creds); + GPR_ASSERT(default_creds->ssl_creds != nullptr); + jwt = reinterpret_cast<grpc_service_account_jwt_access_credentials*>( + creds->call_creds); GPR_ASSERT( strcmp(jwt->key.client_id, "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") == @@ -888,38 +900,31 @@ static void test_google_default_creds_auth_key(void) { static void test_google_default_creds_refresh_token(void) { grpc_core::ExecCtx exec_ctx; grpc_google_refresh_token_credentials* refresh; + grpc_google_default_channel_credentials* default_creds; grpc_composite_channel_credentials* creds; grpc_flush_cached_google_default_credentials(); set_google_default_creds_env_var_with_file_contents( "refresh_token_google_default_creds", test_refresh_token_str); - creds = (grpc_composite_channel_credentials*) - grpc_google_default_credentials_create(); - GPR_ASSERT(creds != nullptr); - refresh = (grpc_google_refresh_token_credentials*)creds->call_creds; + creds = reinterpret_cast<grpc_composite_channel_credentials*>( + grpc_google_default_credentials_create()); + default_creds = reinterpret_cast<grpc_google_default_channel_credentials*>( + creds->inner_creds); + GPR_ASSERT(default_creds->ssl_creds != nullptr); + refresh = reinterpret_cast<grpc_google_refresh_token_credentials*>( + creds->call_creds); GPR_ASSERT(strcmp(refresh->refresh_token.client_id, "32555999999.apps.googleusercontent.com") == 0); grpc_channel_credentials_unref(&creds->base); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } -static int default_creds_gce_detection_httpcli_get_success_override( - const grpc_httpcli_request* request, grpc_millis deadline, - grpc_closure* on_done, grpc_httpcli_response* response) { - *response = http_response(200, ""); - grpc_http_header* headers = - static_cast<grpc_http_header*>(gpr_malloc(sizeof(*headers) * 1)); - headers[0].key = gpr_strdup("Metadata-Flavor"); - headers[0].value = gpr_strdup("Google"); - response->hdr_count = 1; - response->hdrs = headers; - GPR_ASSERT(strcmp(request->http.path, "/") == 0); - GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); - GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); - return 1; -} - static char* null_well_known_creds_path_getter(void) { return nullptr; } +static bool test_gce_tenancy_checker(void) { + g_test_gce_tenancy_checker_called = true; + return g_test_is_on_gce; +} + static void test_google_default_creds_gce(void) { grpc_core::ExecCtx exec_ctx; expected_md emd[] = { @@ -932,14 +937,14 @@ static void test_google_default_creds_gce(void) { gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ grpc_override_well_known_credentials_path_getter( null_well_known_creds_path_getter); + set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); + g_test_gce_tenancy_checker_called = false; + g_test_is_on_gce = true; /* Simulate a successful detection of GCE. */ - grpc_httpcli_set_override( - default_creds_gce_detection_httpcli_get_success_override, - httpcli_post_should_not_be_called); grpc_composite_channel_credentials* creds = - (grpc_composite_channel_credentials*) - grpc_google_default_credentials_create(); + reinterpret_cast<grpc_composite_channel_credentials*>( + grpc_google_default_credentials_create()); /* Verify that the default creds actually embeds a GCE creds. */ GPR_ASSERT(creds != nullptr); @@ -952,11 +957,11 @@ static void test_google_default_creds_gce(void) { /* Check that we get a cached creds if we call grpc_google_default_credentials_create again. GCE detection should not occur anymore either. */ - grpc_httpcli_set_override(httpcli_get_should_not_be_called, - httpcli_post_should_not_be_called); + g_test_gce_tenancy_checker_called = false; grpc_channel_credentials* cached_creds = grpc_google_default_credentials_create(); GPR_ASSERT(cached_creds == &creds->base); + GPR_ASSERT(g_test_gce_tenancy_checker_called == false); /* Cleanup. */ grpc_channel_credentials_unref(cached_creds); @@ -965,36 +970,25 @@ static void test_google_default_creds_gce(void) { grpc_override_well_known_credentials_path_getter(nullptr); } -static int default_creds_gce_detection_httpcli_get_failure_override( - const grpc_httpcli_request* request, grpc_millis deadline, - grpc_closure* on_done, grpc_httpcli_response* response) { - /* No magic header. */ - GPR_ASSERT(strcmp(request->http.path, "/") == 0); - GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); - *response = http_response(200, ""); - GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); - return 1; -} - static void test_no_google_default_creds(void) { grpc_flush_cached_google_default_credentials(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ grpc_override_well_known_credentials_path_getter( null_well_known_creds_path_getter); + set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); + g_test_gce_tenancy_checker_called = false; + g_test_is_on_gce = false; + /* Simulate a successful detection of GCE. */ - grpc_httpcli_set_override( - default_creds_gce_detection_httpcli_get_failure_override, - httpcli_post_should_not_be_called); GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); /* Try a cached one. GCE detection should not occur anymore. */ - grpc_httpcli_set_override(httpcli_get_should_not_be_called, - httpcli_post_should_not_be_called); + g_test_gce_tenancy_checker_called = false; GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); + GPR_ASSERT(g_test_gce_tenancy_checker_called == false); /* Cleanup. */ - grpc_httpcli_set_override(nullptr, nullptr); grpc_override_well_known_credentials_path_getter(nullptr); } @@ -1018,7 +1012,7 @@ static int plugin_get_metadata_success( GPR_ASSERT(context.reserved == nullptr); GPR_ASSERT(GPR_ARRAY_SIZE(plugin_md) < GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX); - plugin_state* s = (plugin_state*)state; + plugin_state* s = static_cast<plugin_state*>(state); *s = PLUGIN_GET_METADATA_CALLED_STATE; for (size_t i = 0; i < GPR_ARRAY_SIZE(plugin_md); ++i) { memset(&creds_md[i], 0, sizeof(grpc_metadata)); @@ -1041,7 +1035,7 @@ static int plugin_get_metadata_failure( GPR_ASSERT(strcmp(context.method_name, test_method) == 0); GPR_ASSERT(context.channel_auth_context == nullptr); GPR_ASSERT(context.reserved == nullptr); - plugin_state* s = (plugin_state*)state; + plugin_state* s = static_cast<plugin_state*>(state); *s = PLUGIN_GET_METADATA_CALLED_STATE; *status = GRPC_STATUS_UNAUTHENTICATED; *error_details = gpr_strdup(plugin_error_details); @@ -1049,7 +1043,7 @@ static int plugin_get_metadata_failure( } static void plugin_destroy(void* state) { - plugin_state* s = (plugin_state*)state; + plugin_state* s = static_cast<plugin_state*>(state); *s = PLUGIN_DESTROY_CALLED_STATE; } diff --git a/test/core/security/fetch_oauth2.cc b/test/core/security/fetch_oauth2.cc index cb28a0487c..82efe682be 100644 --- a/test/core/security/fetch_oauth2.cc +++ b/test/core/security/fetch_oauth2.cc @@ -23,13 +23,13 @@ #include <grpc/grpc_security.h> #include <grpc/slice.h> #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/credentials/credentials.h" #include "test/core/security/oauth2_utils.h" +#include "test/core/util/cmdline.h" static grpc_call_credentials* create_refresh_token_creds( const char* json_refresh_token_file_path) { @@ -38,7 +38,8 @@ static grpc_call_credentials* create_refresh_token_creds( "load_file", grpc_load_file(json_refresh_token_file_path, 1, &refresh_token))); return grpc_google_refresh_token_credentials_create( - (const char*)GRPC_SLICE_START_PTR(refresh_token), nullptr); + reinterpret_cast<const char*> GRPC_SLICE_START_PTR(refresh_token), + nullptr); } int main(int argc, char** argv) { diff --git a/test/core/security/grpc_alts_credentials_options_test.cc b/test/core/security/grpc_alts_credentials_options_test.cc new file mode 100644 index 0000000000..623db48ebc --- /dev/null +++ b/test/core/security/grpc_alts_credentials_options_test.cc @@ -0,0 +1,95 @@ +/* + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <grpc/grpc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" + +#define ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1 "abc@google.com" +#define ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_2 "def@google.com" + +const size_t kTargetServiceAccountNum = 2; + +static void test_copy_client_options_failure() { + /* Initialization. */ + grpc_alts_credentials_options* options = + grpc_alts_credentials_client_options_create(); + /* Test. */ + GPR_ASSERT(grpc_alts_credentials_options_copy(nullptr) == nullptr); + /* Cleanup. */ + grpc_alts_credentials_options_destroy(options); +} + +static size_t get_target_service_account_num( + grpc_alts_credentials_options* options) { + auto client_options = + reinterpret_cast<grpc_alts_credentials_client_options*>(options); + size_t num = 0; + target_service_account* node = client_options->target_account_list_head; + while (node != nullptr) { + num++; + node = node->next; + } + return num; +} + +static void test_client_options_api_success() { + /* Initialization. */ + grpc_alts_credentials_options* options = + grpc_alts_credentials_client_options_create(); + /* Set client options fields. */ + grpc_alts_credentials_client_options_add_target_service_account( + options, ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1); + grpc_alts_credentials_client_options_add_target_service_account( + options, ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_2); + /* Validate client option fields. */ + GPR_ASSERT(get_target_service_account_num(options) == + kTargetServiceAccountNum); + auto client_options = + reinterpret_cast<grpc_alts_credentials_client_options*>(options); + GPR_ASSERT(strcmp(client_options->target_account_list_head->data, + ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_2) == 0); + GPR_ASSERT(strcmp(client_options->target_account_list_head->next->data, + ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1) == 0); + /* Perform a copy operation and validate its correctness. */ + grpc_alts_credentials_options* new_options = + grpc_alts_credentials_options_copy(options); + GPR_ASSERT(get_target_service_account_num(new_options) == + kTargetServiceAccountNum); + auto new_client_options = + reinterpret_cast<grpc_alts_credentials_client_options*>(new_options); + GPR_ASSERT(strcmp(new_client_options->target_account_list_head->data, + ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_2) == 0); + GPR_ASSERT(strcmp(new_client_options->target_account_list_head->next->data, + ALTS_CLIENT_OPTIONS_TEST_TARGET_SERVICE_ACCOUNT_1) == 0); + /* Cleanup.*/ + grpc_alts_credentials_options_destroy(options); + grpc_alts_credentials_options_destroy(new_options); +} + +int main(int argc, char** argv) { + /* Test. */ + test_copy_client_options_failure(); + test_client_options_api_success(); + return 0; +} diff --git a/test/core/security/json_token_test.cc b/test/core/security/json_token_test.cc index aac9cc0029..7a5b3355fe 100644 --- a/test/core/security/json_token_test.cc +++ b/test/core/security/json_token_test.cc @@ -218,7 +218,7 @@ static grpc_json* parse_json_part_from_jwt(const char* str, size_t len, slice = grpc_base64_decode(b64, 1); GPR_ASSERT(!GRPC_SLICE_IS_EMPTY(slice)); decoded = static_cast<char*>(gpr_malloc(GRPC_SLICE_LENGTH(slice) + 1)); - strncpy(decoded, (const char*)GRPC_SLICE_START_PTR(slice), + strncpy(decoded, reinterpret_cast<const char*> GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice)); decoded[GRPC_SLICE_LENGTH(slice)] = '\0'; json = grpc_json_parse_string(decoded); @@ -385,21 +385,21 @@ static void test_jwt_encode_and_sign( char* jwt = jwt_encode_and_sign_func(&json_key); const char* dot = strchr(jwt, '.'); GPR_ASSERT(dot != nullptr); - parsed_header = - parse_json_part_from_jwt(jwt, (size_t)(dot - jwt), &scratchpad); + parsed_header = parse_json_part_from_jwt(jwt, static_cast<size_t>(dot - jwt), + &scratchpad); GPR_ASSERT(parsed_header != nullptr); check_jwt_header(parsed_header); - offset = (size_t)(dot - jwt) + 1; + offset = static_cast<size_t>(dot - jwt) + 1; grpc_json_destroy(parsed_header); gpr_free(scratchpad); dot = strchr(jwt + offset, '.'); GPR_ASSERT(dot != nullptr); parsed_claim = parse_json_part_from_jwt( - jwt + offset, (size_t)(dot - (jwt + offset)), &scratchpad); + jwt + offset, static_cast<size_t>(dot - (jwt + offset)), &scratchpad); GPR_ASSERT(parsed_claim != nullptr); check_jwt_claim_func(parsed_claim); - offset = (size_t)(dot - jwt) + 1; + offset = static_cast<size_t>(dot - jwt) + 1; grpc_json_destroy(parsed_claim); gpr_free(scratchpad); diff --git a/test/core/security/jwt_verifier_test.cc b/test/core/security/jwt_verifier_test.cc index e219260b1d..9718580a08 100644 --- a/test/core/security/jwt_verifier_test.cc +++ b/test/core/security/jwt_verifier_test.cc @@ -207,7 +207,7 @@ static void test_claims_success(void) { grpc_jwt_claims* claims; grpc_slice s = grpc_slice_from_copied_string(claims_without_time_constraint); grpc_json* json = grpc_json_parse_string_with_len( - (char*)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); + reinterpret_cast<char*> GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); GPR_ASSERT(json != nullptr); grpc_core::ExecCtx exec_ctx; claims = grpc_jwt_claims_from_json(json, s); @@ -226,7 +226,7 @@ static void test_expired_claims_failure(void) { grpc_jwt_claims* claims; grpc_slice s = grpc_slice_from_copied_string(expired_claims); grpc_json* json = grpc_json_parse_string_with_len( - (char*)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); + reinterpret_cast<char*> GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); gpr_timespec exp_iat = {100, 0, GPR_CLOCK_REALTIME}; gpr_timespec exp_exp = {120, 0, GPR_CLOCK_REALTIME}; gpr_timespec exp_nbf = {60, 0, GPR_CLOCK_REALTIME}; @@ -251,7 +251,7 @@ static void test_expired_claims_failure(void) { static void test_invalid_claims_failure(void) { grpc_slice s = grpc_slice_from_copied_string(invalid_claims); grpc_json* json = grpc_json_parse_string_with_len( - (char*)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); + reinterpret_cast<char*> GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); grpc_core::ExecCtx exec_ctx; GPR_ASSERT(grpc_jwt_claims_from_json(json, s) == nullptr); } @@ -260,7 +260,7 @@ static void test_bad_audience_claims_failure(void) { grpc_jwt_claims* claims; grpc_slice s = grpc_slice_from_copied_string(claims_without_time_constraint); grpc_json* json = grpc_json_parse_string_with_len( - (char*)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); + reinterpret_cast<char*> GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); GPR_ASSERT(json != nullptr); grpc_core::ExecCtx exec_ctx; claims = grpc_jwt_claims_from_json(json, s); @@ -274,7 +274,7 @@ static void test_bad_subject_claims_failure(void) { grpc_jwt_claims* claims; grpc_slice s = grpc_slice_from_copied_string(claims_with_bad_subject); grpc_json* json = grpc_json_parse_string_with_len( - (char*)GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); + reinterpret_cast<char*> GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s)); GPR_ASSERT(json != nullptr); grpc_core::ExecCtx exec_ctx; claims = grpc_jwt_claims_from_json(json, s); diff --git a/test/core/security/oauth2_utils.cc b/test/core/security/oauth2_utils.cc index 0d3a1279af..469129a6d0 100644 --- a/test/core/security/oauth2_utils.cc +++ b/test/core/security/oauth2_utils.cc @@ -40,7 +40,7 @@ typedef struct { } oauth2_request; static void on_oauth2_response(void* arg, grpc_error* error) { - oauth2_request* request = (oauth2_request*)arg; + oauth2_request* request = static_cast<oauth2_request*>(arg); char* token = nullptr; grpc_slice token_slice; if (error != GRPC_ERROR_NONE) { @@ -48,7 +48,7 @@ static void on_oauth2_response(void* arg, grpc_error* error) { } else { GPR_ASSERT(request->md_array.size == 1); token_slice = GRPC_MDVALUE(request->md_array.md[0]); - token = (char*)gpr_malloc(GRPC_SLICE_LENGTH(token_slice) + 1); + token = static_cast<char*>(gpr_malloc(GRPC_SLICE_LENGTH(token_slice) + 1)); memcpy(token, GRPC_SLICE_START_PTR(token_slice), GRPC_SLICE_LENGTH(token_slice)); token[GRPC_SLICE_LENGTH(token_slice)] = '\0'; @@ -73,7 +73,8 @@ char* grpc_test_fetch_oauth2_token_with_credentials( grpc_closure do_nothing_closure; grpc_auth_metadata_context null_ctx = {"", "", nullptr, nullptr}; - grpc_pollset* pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); + grpc_pollset* pollset = + static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(pollset, &request.mu); request.pops = grpc_polling_entity_create_from_pollset(pollset); request.is_done = false; diff --git a/test/core/security/print_google_default_creds_token.cc b/test/core/security/print_google_default_creds_token.cc index b3742f58a8..4d251391ff 100644 --- a/test/core/security/print_google_default_creds_token.cc +++ b/test/core/security/print_google_default_creds_token.cc @@ -23,14 +23,14 @@ #include <grpc/grpc_security.h> #include <grpc/slice.h> #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> +#include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/composite/composite_credentials.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/string.h" +#include "test/core/util/cmdline.h" typedef struct { gpr_mu* mu; @@ -45,6 +45,7 @@ static void on_metadata_response(void* arg, grpc_error* error) { synchronizer* sync = static_cast<synchronizer*>(arg); if (error != GRPC_ERROR_NONE) { fprintf(stderr, "Fetching token failed: %s\n", grpc_error_string(error)); + fflush(stderr); } else { char* token; GPR_ASSERT(sync->md_array.size == 1); @@ -81,12 +82,13 @@ int main(int argc, char** argv) { creds = grpc_google_default_credentials_create(); if (creds == nullptr) { fprintf(stderr, "\nCould not find default credentials.\n\n"); + fflush(stderr); result = 1; goto end; } memset(&sync, 0, sizeof(sync)); - pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); + pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(pollset, &sync.mu); sync.pops = grpc_polling_entity_create_from_pollset(pollset); sync.is_done = false; @@ -95,8 +97,10 @@ int main(int argc, char** argv) { error = GRPC_ERROR_NONE; if (grpc_call_credentials_get_request_metadata( - ((grpc_composite_channel_credentials*)creds)->call_creds, &sync.pops, - context, &sync.md_array, &sync.on_request_metadata, &error)) { + (reinterpret_cast<grpc_composite_channel_credentials*>(creds)) + ->call_creds, + &sync.pops, context, &sync.md_array, &sync.on_request_metadata, + &error)) { // Synchronous response. Invoke callback directly. on_metadata_response(&sync, error); GRPC_ERROR_UNREF(error); diff --git a/test/core/security/secure_endpoint_test.cc b/test/core/security/secure_endpoint_test.cc index 38c78fed42..23cef99dfa 100644 --- a/test/core/security/secure_endpoint_test.cc +++ b/test/core/security/secure_endpoint_test.cc @@ -24,7 +24,7 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/transport/secure_endpoint.h" @@ -57,7 +57,7 @@ static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair( grpc_arg a[1]; a[0].key = const_cast<char*>(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER; - a[0].value.integer = (int)slice_size; + a[0].value.integer = static_cast<int>(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; tcp = grpc_iomgr_create_endpoint_pair("fixture", &args); grpc_endpoint_add_to_pollset(tcp.client, g_pollset); @@ -73,7 +73,7 @@ static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair( size_t still_pending_size; size_t total_buffer_size = 8192; size_t buffer_size = total_buffer_size; - uint8_t* encrypted_buffer = (uint8_t*)gpr_malloc(buffer_size); + uint8_t* encrypted_buffer = static_cast<uint8_t*>(gpr_malloc(buffer_size)); uint8_t* cur = encrypted_buffer; grpc_slice encrypted_leftover; for (i = 0; i < leftover_nslices; i++) { @@ -106,7 +106,8 @@ static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair( buffer_size -= protected_buffer_size_to_send; } while (still_pending_size > 0); encrypted_leftover = grpc_slice_from_copied_buffer( - (const char*)encrypted_buffer, total_buffer_size - buffer_size); + reinterpret_cast<const char*>(encrypted_buffer), + total_buffer_size - buffer_size); f.client_ep = grpc_secure_endpoint_create( fake_read_protector, fake_read_zero_copy_protector, tcp.client, &encrypted_leftover, 1); @@ -165,7 +166,9 @@ static grpc_endpoint_test_config configs[] = { clean_up}, }; -static void inc_call_ctr(void* arg, grpc_error* error) { ++*(int*)arg; } +static void inc_call_ctr(void* arg, grpc_error* error) { + ++*static_cast<int*>(arg); +} static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) { grpc_endpoint_test_fixture f = config.create_fixture(slice_size); @@ -200,7 +203,7 @@ static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) { } static void destroy_pollset(void* p, grpc_error* error) { - grpc_pollset_destroy((grpc_pollset*)p); + grpc_pollset_destroy(static_cast<grpc_pollset*>(p)); } int main(int argc, char** argv) { @@ -210,7 +213,7 @@ int main(int argc, char** argv) { { grpc_core::ExecCtx exec_ctx; - g_pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); + g_pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(g_pollset, &g_mu); grpc_endpoint_tests(configs[0], g_pollset, g_mu); grpc_endpoint_tests(configs[1], g_pollset, g_mu); diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index 9a68e176db..e4c3ace6b4 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -23,14 +23,13 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/context/security_context.h" -#include "src/core/lib/security/transport/security_connector.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" #include "test/core/util/test_config.h" @@ -88,15 +87,15 @@ static void test_unauthenticated_ssl_peer(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); - ctx = tsi_ssl_peer_to_auth_context(&peer); + ctx = grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx)); GPR_ASSERT(check_transport_security_type(ctx)); - rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); - tsi_shallow_peer_destruct(&rpeer); + grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); } @@ -188,7 +187,7 @@ static void test_cn_only_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[2]) == TSI_OK); - ctx = tsi_ssl_peer_to_auth_context(&peer); + ctx = grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1)); @@ -196,10 +195,10 @@ static void test_cn_only_ssl_peer_to_auth_context(void) { GPR_ASSERT(check_x509_cn(ctx, expected_cn)); GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); - rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); - tsi_shallow_peer_destruct(&rpeer); + grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); } @@ -224,7 +223,7 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[3]) == TSI_OK); - ctx = tsi_ssl_peer_to_auth_context(&peer); + ctx = grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); GPR_ASSERT( @@ -233,10 +232,10 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { GPR_ASSERT(check_x509_cn(ctx, expected_cn)); GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); - rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); - tsi_shallow_peer_destruct(&rpeer); + grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); } @@ -265,7 +264,7 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_sans[i], &peer.properties[3 + i]) == TSI_OK); } - ctx = tsi_ssl_peer_to_auth_context(&peer); + ctx = grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans, @@ -274,10 +273,10 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { GPR_ASSERT(check_x509_cn(ctx, expected_cn)); GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); - rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); - tsi_shallow_peer_destruct(&rpeer); + grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); } @@ -311,7 +310,7 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_sans[i], &peer.properties[5 + i]) == TSI_OK); } - ctx = tsi_ssl_peer_to_auth_context(&peer); + ctx = grpc_ssl_peer_to_auth_context(&peer); GPR_ASSERT(ctx != nullptr); GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx)); GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans, @@ -320,10 +319,10 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( GPR_ASSERT(check_x509_cn(ctx, expected_cn)); GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); - rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); - tsi_shallow_peer_destruct(&rpeer); + grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); } @@ -341,6 +340,41 @@ static grpc_ssl_roots_override_result override_roots_permanent_failure( return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY; } +static void test_ipv6_address_san(void) { + const char* addresses[] = { + "2001:db8::1", "fe80::abcd:ef65:4321%em0", "fd11:feed:beef:0:cafe::4", + "128.10.0.1:8888", "[2001:db8::1]:8080", "[2001:db8::1%em1]:8080", + }; + const char* san_ips[] = { + "2001:db8::1", "fe80::abcd:ef65:4321", "fd11:feed:beef:0:cafe::4", + "128.10.0.1", "2001:db8::1", "2001:db8::1", + }; + tsi_peer peer; + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + for (size_t i = 0; i < GPR_ARRAY_SIZE(addresses); i++) { + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, san_ips[i], + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(grpc_ssl_host_matches_name(&peer, addresses[i])); + tsi_peer_property_destruct(&peer.properties[0]); + } + tsi_peer_destruct(&peer); +} +namespace grpc_core { +namespace { + +class TestDefafaultSllRootStore : public DefaultSslRootStore { + public: + static grpc_slice ComputePemRootCertsForTesting() { + return ComputePemRootCerts(); + } +}; + +} // namespace +} // namespace grpc_core + +// TODO: Convert this test to C++ test when security_connector implementation +// is converted to C++. static void test_default_ssl_roots(void) { const char* roots_for_env_var = "roots for env var"; @@ -354,7 +388,8 @@ static void test_default_ssl_roots(void) { value. */ gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); grpc_set_ssl_roots_override_callback(override_roots_success); - grpc_slice roots = grpc_get_default_ssl_roots_for_testing(); + grpc_slice roots = + grpc_core::TestDefafaultSllRootStore::ComputePemRootCertsForTesting(); char* roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); GPR_ASSERT(strcmp(roots_contents, roots_for_override_api) == 0); @@ -363,7 +398,7 @@ static void test_default_ssl_roots(void) { /* Now let's set the env var: We should get the contents pointed value instead. */ gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_env_var_file_path); - roots = grpc_get_default_ssl_roots_for_testing(); + roots = grpc_core::TestDefafaultSllRootStore::ComputePemRootCertsForTesting(); roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); GPR_ASSERT(strcmp(roots_contents, roots_for_env_var) == 0); @@ -372,7 +407,7 @@ static void test_default_ssl_roots(void) { /* Now reset the env var. We should fall back to the value overridden using the api. */ gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); - roots = grpc_get_default_ssl_roots_for_testing(); + roots = grpc_core::TestDefafaultSllRootStore::ComputePemRootCertsForTesting(); roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); GPR_ASSERT(strcmp(roots_contents, roots_for_override_api) == 0); @@ -381,8 +416,11 @@ static void test_default_ssl_roots(void) { /* Now setup a permanent failure for the overridden roots and we should get an empty slice. */ grpc_set_ssl_roots_override_callback(override_roots_permanent_failure); - roots = grpc_get_default_ssl_roots_for_testing(); + roots = grpc_core::TestDefafaultSllRootStore::ComputePemRootCertsForTesting(); GPR_ASSERT(GRPC_SLICE_IS_EMPTY(roots)); + const tsi_ssl_root_certs_store* root_store = + grpc_core::TestDefafaultSllRootStore::GetRootStore(); + GPR_ASSERT(root_store == nullptr); /* Cleanup. */ remove(roots_env_var_file_path); @@ -398,6 +436,7 @@ int main(int argc, char** argv) { test_cn_and_one_san_ssl_peer_to_auth_context(); test_cn_and_multiple_sans_ssl_peer_to_auth_context(); test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(); + test_ipv6_address_san(); test_default_ssl_roots(); grpc_shutdown(); diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index 6e30698562..cb74e3bae1 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -22,7 +22,7 @@ #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/security/transport/security_connector.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/memory_counters.h" #include "test/core/util/mock_endpoint.h" diff --git a/test/core/security/verify_jwt.cc b/test/core/security/verify_jwt.cc index e039970c67..61dde0e7d9 100644 --- a/test/core/security/verify_jwt.cc +++ b/test/core/security/verify_jwt.cc @@ -23,11 +23,11 @@ #include <grpc/grpc_security.h> #include <grpc/slice.h> #include <grpc/support/alloc.h> -#include <grpc/support/cmdline.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> #include "src/core/lib/security/credentials/jwt/jwt_verifier.h" +#include "test/core/util/cmdline.h" typedef struct { grpc_pollset* pollset; @@ -39,6 +39,7 @@ typedef struct { static void print_usage_and_exit(gpr_cmdline* cl, const char* argv0) { char* usage = gpr_cmdline_usage_string(cl, argv0); fprintf(stderr, "%s", usage); + fflush(stderr); gpr_free(usage); gpr_cmdline_destroy(cl); exit(1); @@ -53,8 +54,8 @@ static void on_jwt_verification_done(void* user_data, if (sync->success) { char* claims_str; GPR_ASSERT(claims != nullptr); - claims_str = - grpc_json_dump_to_string((grpc_json*)grpc_jwt_claims_json(claims), 2); + claims_str = grpc_json_dump_to_string( + const_cast<grpc_json*>(grpc_jwt_claims_json(claims)), 2); printf("Claims: \n\n%s\n", claims_str); gpr_free(claims_str); grpc_jwt_claims_destroy(claims); @@ -62,6 +63,7 @@ static void on_jwt_verification_done(void* user_data, GPR_ASSERT(claims == nullptr); fprintf(stderr, "Verification failed with error %s\n", grpc_jwt_verifier_status_to_string(status)); + fflush(stderr); } gpr_mu_lock(sync->mu); diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD index ba2b553e0b..9a1a506a43 100644 --- a/test/core/slice/BUILD +++ b/test/core/slice/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "percent_encode_fuzzer", srcs = ["percent_encode_fuzzer.cc"], - language = "C++", corpus = "percent_encode_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -35,8 +35,8 @@ grpc_fuzzer( grpc_fuzzer( name = "percent_decode_fuzzer", srcs = ["percent_decode_fuzzer.cc"], - language = "C++", corpus = "percent_decode_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -59,8 +59,13 @@ grpc_cc_test( grpc_cc_test( name = "slice_test", srcs = ["slice_test.cc"], - deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"], language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( @@ -78,15 +83,43 @@ grpc_cc_test( grpc_cc_test( name = "slice_buffer_test", srcs = ["slice_buffer_test.cc"], - deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"], language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "slice_hash_table_test", srcs = ["slice_hash_table_test.cc"], - deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"], + external_deps = [ + "gtest", + ], language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "slice_weak_hash_table_test", + srcs = ["slice_weak_hash_table_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( diff --git a/test/core/slice/b64_test.cc b/test/core/slice/b64_test.cc index 94785fd1e2..6b29443ba1 100644 --- a/test/core/slice/b64_test.cc +++ b/test/core/slice/b64_test.cc @@ -34,7 +34,7 @@ static int buffers_are_equal(const unsigned char* buf1, for (i = 0; i < size; i++) { if (buf1[i] != buf2[i]) { gpr_log(GPR_ERROR, "buf1 and buf2 differ: buf1[%d] = %x vs buf2[%d] = %x", - (int)i, buf1[i], (int)i, buf2[i]); + static_cast<int>(i), buf1[i], static_cast<int>(i), buf2[i]); return 0; } } @@ -61,7 +61,7 @@ static void test_full_range_encode_decode_b64(int url_safe, int multiline) { size_t i; char* b64; grpc_slice orig_decoded; - for (i = 0; i < sizeof(orig); i++) orig[i] = (uint8_t)i; + for (i = 0; i < sizeof(orig); i++) orig[i] = static_cast<uint8_t>(i); /* Try all the different paddings. */ for (i = 0; i < 3; i++) { @@ -114,7 +114,7 @@ static void test_url_safe_unsafe_mismatch_failure(void) { char* b64; grpc_slice orig_decoded; int url_safe = 1; - for (i = 0; i < sizeof(orig); i++) orig[i] = (uint8_t)i; + for (i = 0; i < sizeof(orig); i++) orig[i] = static_cast<uint8_t>(i); grpc_core::ExecCtx exec_ctx; b64 = grpc_base64_encode(orig, sizeof(orig), url_safe, 0); diff --git a/test/core/slice/percent_encode_fuzzer.cc b/test/core/slice/percent_encode_fuzzer.cc index 201ae2790e..1fd197e180 100644 --- a/test/core/slice/percent_encode_fuzzer.cc +++ b/test/core/slice/percent_encode_fuzzer.cc @@ -34,7 +34,8 @@ static void test(const uint8_t* data, size_t size, const uint8_t* dict) { struct grpc_memory_counters counters; grpc_init(); grpc_memory_counters_init(); - grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); + grpc_slice input = + grpc_slice_from_copied_buffer(reinterpret_cast<const char*>(data), size); grpc_slice output = grpc_percent_encode_slice(input, dict); grpc_slice decoded_output; // encoder must always produce decodable output diff --git a/test/core/slice/percent_encoding_test.cc b/test/core/slice/percent_encoding_test.cc index 11f3995f98..e8d04fcc83 100644 --- a/test/core/slice/percent_encoding_test.cc +++ b/test/core/slice/percent_encoding_test.cc @@ -22,8 +22,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include "src/core/lib/gpr/string.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" #define TEST_VECTOR(raw, encoded, dict) \ diff --git a/test/core/slice/slice_hash_table_test.cc b/test/core/slice/slice_hash_table_test.cc index 9fad9a614e..43ddfe9bf2 100644 --- a/test/core/slice/slice_hash_table_test.cc +++ b/test/core/slice/slice_hash_table_test.cc @@ -20,63 +20,67 @@ #include <string.h> +#include <vector> + +#include <gtest/gtest.h> + #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/util/test_config.h" -typedef struct { - const char* key; - const char* value; -} test_entry; +namespace grpc_core { +namespace { -static void populate_entries(const test_entry* input, size_t num_entries, - grpc_slice_hash_table_entry* output) { - for (size_t i = 0; i < num_entries; ++i) { - output[i].key = grpc_slice_from_copied_string(input[i].key); - output[i].value = gpr_strdup(input[i].value); - } -} +typedef SliceHashTable<UniquePtr<char>> TestHashTable; -static void check_values(const test_entry* input, size_t num_entries, - grpc_slice_hash_table* table) { - for (size_t i = 0; i < num_entries; ++i) { - grpc_slice key = grpc_slice_from_static_string(input[i].key); - const char* actual = - static_cast<const char*>(grpc_slice_hash_table_get(table, key)); - GPR_ASSERT(actual != nullptr); - GPR_ASSERT(strcmp(actual, input[i].value) == 0); +struct TestEntry { + const char* key; + const char* value; +}; + +void CheckValues(const std::vector<TestEntry>& input, + const TestHashTable& table) { + for (const TestEntry& expected : input) { + grpc_slice key = grpc_slice_from_static_string(expected.key); + const UniquePtr<char>* actual = table.Get(key); + ASSERT_NE(actual, nullptr); + EXPECT_STREQ(expected.value, actual->get()); grpc_slice_unref(key); } } -static void check_non_existent_value(const char* key_string, - grpc_slice_hash_table* table) { +void CheckNonExistentValue(const char* key_string, const TestHashTable& table) { grpc_slice key = grpc_slice_from_static_string(key_string); - GPR_ASSERT(grpc_slice_hash_table_get(table, key) == nullptr); + ASSERT_EQ(nullptr, table.Get(key)); grpc_slice_unref(key); } -static void destroy_string(void* value) { gpr_free(value); } - -static grpc_slice_hash_table* create_table_from_entries( - const test_entry* test_entries, size_t num_test_entries, - int (*value_cmp_fn)(void*, void*)) { - // Construct table. - grpc_slice_hash_table_entry* entries = - static_cast<grpc_slice_hash_table_entry*>( - gpr_zalloc(sizeof(*entries) * num_test_entries)); - populate_entries(test_entries, num_test_entries, entries); - grpc_slice_hash_table* table = grpc_slice_hash_table_create( - num_test_entries, entries, destroy_string, value_cmp_fn); +void PopulateEntries(const std::vector<TestEntry>& input, + TestHashTable::Entry* output) { + for (size_t i = 0; i < input.size(); ++i) { + output[i].key = grpc_slice_from_copied_string(input[i].key); + output[i].value = UniquePtr<char>(gpr_strdup(input[i].value)); + } +} + +RefCountedPtr<TestHashTable> CreateTableFromEntries( + const std::vector<TestEntry>& test_entries, + TestHashTable::ValueCmp value_cmp) { + TestHashTable::Entry* entries = static_cast<TestHashTable::Entry*>( + gpr_zalloc(sizeof(*entries) * test_entries.size())); + PopulateEntries(test_entries, entries); + RefCountedPtr<TestHashTable> table = + TestHashTable::Create(test_entries.size(), entries, value_cmp); gpr_free(entries); return table; } -static void test_slice_hash_table() { - const test_entry test_entries[] = { +TEST(SliceHashTable, Basic) { + const std::vector<TestEntry> test_entries = { {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}, {"key_3", "value_3"}, {"key_4", "value_4"}, {"key_5", "value_5"}, {"key_6", "value_6"}, {"key_7", "value_7"}, {"key_8", "value_8"}, @@ -112,129 +116,110 @@ static void test_slice_hash_table() { {"key_96", "value_96"}, {"key_97", "value_97"}, {"key_98", "value_98"}, {"key_99", "value_99"}, }; - const size_t num_entries = GPR_ARRAY_SIZE(test_entries); - grpc_slice_hash_table* table = - create_table_from_entries(test_entries, num_entries, nullptr); + RefCountedPtr<TestHashTable> table = + CreateTableFromEntries(test_entries, nullptr); // Check contents of table. - check_values(test_entries, num_entries, table); - check_non_existent_value("XX", table); - // Clean up. - grpc_core::ExecCtx exec_ctx; - grpc_slice_hash_table_unref(table); + CheckValues(test_entries, *table); + CheckNonExistentValue("XX", *table); } -static int value_cmp_fn(void* a, void* b) { - const char* a_str = static_cast<const char*>(a); - const char* b_str = static_cast<const char*>(b); - return strcmp(a_str, b_str); +int StringCmp(const UniquePtr<char>& a, const UniquePtr<char>& b) { + return strcmp(a.get(), b.get()); } -static int pointer_cmp_fn(void* a, void* b) { return GPR_ICMP(a, b); } +int PointerCmp(const UniquePtr<char>& a, const UniquePtr<char>& b) { + return GPR_ICMP(a.get(), b.get()); +} -static void test_slice_hash_table_eq() { - const test_entry test_entries_a[] = { +TEST(SliceHashTable, CmpEqual) { + const std::vector<TestEntry> test_entries_a = { {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; - const size_t num_entries_a = GPR_ARRAY_SIZE(test_entries_a); - grpc_slice_hash_table* table_a = - create_table_from_entries(test_entries_a, num_entries_a, value_cmp_fn); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_a) == 0); - - const test_entry test_entries_b[] = { + RefCountedPtr<TestHashTable> table_a = + CreateTableFromEntries(test_entries_a, StringCmp); + const std::vector<TestEntry> test_entries_b = { {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; - const size_t num_entries_b = GPR_ARRAY_SIZE(test_entries_b); - grpc_slice_hash_table* table_b = - create_table_from_entries(test_entries_b, num_entries_b, value_cmp_fn); - - GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b) == 0); - grpc_core::ExecCtx exec_ctx; - grpc_slice_hash_table_unref(table_a); - grpc_slice_hash_table_unref(table_b); + RefCountedPtr<TestHashTable> table_b = + CreateTableFromEntries(test_entries_b, StringCmp); + // table_a equals itself. + EXPECT_EQ(0, TestHashTable::Cmp(*table_a, *table_a)); + // table_a equals table_b. + EXPECT_EQ(0, TestHashTable::Cmp(*table_a, *table_b)); } -static void test_slice_hash_table_not_eq() { - const test_entry test_entries_a[] = { +TEST(SliceHashTable, CmpDifferentSizes) { + // table_a has 3 entries, table_b has only 2. + const std::vector<TestEntry> test_entries_a = { {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; - const size_t num_entries_a = GPR_ARRAY_SIZE(test_entries_a); - grpc_slice_hash_table* table_a = - create_table_from_entries(test_entries_a, num_entries_a, value_cmp_fn); - - // Different sizes. - const test_entry test_entries_b_smaller[] = {{"key_0", "value_0"}, - {"key_1", "value_1"}}; - const size_t num_entries_b_smaller = GPR_ARRAY_SIZE(test_entries_b_smaller); - grpc_slice_hash_table* table_b_smaller = create_table_from_entries( - test_entries_b_smaller, num_entries_b_smaller, value_cmp_fn); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b_smaller) > 0); - - const test_entry test_entries_b_larger[] = {{"key_0", "value_0"}, - {"key_1", "value_1"}, - {"key_2", "value_2"}, - {"key_3", "value_3"}}; - const size_t num_entries_b_larger = GPR_ARRAY_SIZE(test_entries_b_larger); - grpc_slice_hash_table* table_b_larger = create_table_from_entries( - test_entries_b_larger, num_entries_b_larger, value_cmp_fn); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b_larger) < 0); + RefCountedPtr<TestHashTable> table_a = + CreateTableFromEntries(test_entries_a, StringCmp); + const std::vector<TestEntry> test_entries_b = {{"key_0", "value_0"}, + {"key_1", "value_1"}}; + RefCountedPtr<TestHashTable> table_b = + CreateTableFromEntries(test_entries_b, StringCmp); + EXPECT_GT(TestHashTable::Cmp(*table_a, *table_b), 0); + EXPECT_LT(TestHashTable::Cmp(*table_b, *table_a), 0); +} +TEST(SliceHashTable, CmpDifferentKey) { // One key doesn't match and is lexicographically "smaller". - const test_entry test_entries_c[] = { + const std::vector<TestEntry> test_entries_a = { + {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; + RefCountedPtr<TestHashTable> table_a = + CreateTableFromEntries(test_entries_a, StringCmp); + const std::vector<TestEntry> test_entries_b = { {"key_zz", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; - const size_t num_entries_c = GPR_ARRAY_SIZE(test_entries_c); - grpc_slice_hash_table* table_c = - create_table_from_entries(test_entries_c, num_entries_c, value_cmp_fn); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_c) > 0); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_c, table_a) < 0); + RefCountedPtr<TestHashTable> table_b = + CreateTableFromEntries(test_entries_b, StringCmp); + EXPECT_GT(TestHashTable::Cmp(*table_a, *table_b), 0); + EXPECT_LT(TestHashTable::Cmp(*table_b, *table_a), 0); +} +TEST(SliceHashTable, CmpDifferentValue) { // One value doesn't match. - const test_entry test_entries_d[] = { + const std::vector<TestEntry> test_entries_a = { + {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; + RefCountedPtr<TestHashTable> table_a = + CreateTableFromEntries(test_entries_a, StringCmp); + const std::vector<TestEntry> test_entries_b = { {"key_0", "value_z"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; - const size_t num_entries_d = GPR_ARRAY_SIZE(test_entries_d); - grpc_slice_hash_table* table_d = - create_table_from_entries(test_entries_d, num_entries_d, value_cmp_fn); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_d) < 0); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_d, table_a) > 0); + RefCountedPtr<TestHashTable> table_b = + CreateTableFromEntries(test_entries_b, StringCmp); + EXPECT_LT(TestHashTable::Cmp(*table_a, *table_b), 0); + EXPECT_GT(TestHashTable::Cmp(*table_b, *table_a), 0); +} +TEST(SliceHashTable, CmpDifferentCmpFunctions) { // Same values but different "equals" functions. - const test_entry test_entries_e[] = { + const std::vector<TestEntry> test_entries_a = { {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; - const size_t num_entries_e = GPR_ARRAY_SIZE(test_entries_e); - grpc_slice_hash_table* table_e = - create_table_from_entries(test_entries_e, num_entries_e, value_cmp_fn); - const test_entry test_entries_f[] = { + RefCountedPtr<TestHashTable> table_a = + CreateTableFromEntries(test_entries_a, StringCmp); + const std::vector<TestEntry> test_entries_b = { {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}}; - const size_t num_entries_f = GPR_ARRAY_SIZE(test_entries_f); - grpc_slice_hash_table* table_f = - create_table_from_entries(test_entries_f, num_entries_f, pointer_cmp_fn); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_e, table_f) != 0); + RefCountedPtr<TestHashTable> table_b = + CreateTableFromEntries(test_entries_b, PointerCmp); + EXPECT_NE(TestHashTable::Cmp(*table_a, *table_b), 0); +} +TEST(SliceHashTable, CmpEmptyKeysDifferentValue) { // Same (empty) key, different values. - const test_entry test_entries_g[] = {{"", "value_0"}}; - const size_t num_entries_g = GPR_ARRAY_SIZE(test_entries_g); - grpc_slice_hash_table* table_g = - create_table_from_entries(test_entries_g, num_entries_g, value_cmp_fn); - const test_entry test_entries_h[] = {{"", "value_1"}}; - const size_t num_entries_h = GPR_ARRAY_SIZE(test_entries_h); - grpc_slice_hash_table* table_h = - create_table_from_entries(test_entries_h, num_entries_h, pointer_cmp_fn); - GPR_ASSERT(grpc_slice_hash_table_cmp(table_g, table_h) != 0); - - grpc_core::ExecCtx exec_ctx; - grpc_slice_hash_table_unref(table_a); - grpc_slice_hash_table_unref(table_b_larger); - grpc_slice_hash_table_unref(table_b_smaller); - grpc_slice_hash_table_unref(table_c); - grpc_slice_hash_table_unref(table_d); - grpc_slice_hash_table_unref(table_e); - grpc_slice_hash_table_unref(table_f); - grpc_slice_hash_table_unref(table_g); - grpc_slice_hash_table_unref(table_h); + const std::vector<TestEntry> test_entries_a = {{"", "value_0"}}; + RefCountedPtr<TestHashTable> table_a = + CreateTableFromEntries(test_entries_a, StringCmp); + const std::vector<TestEntry> test_entries_b = {{"", "value_1"}}; + RefCountedPtr<TestHashTable> table_b = + CreateTableFromEntries(test_entries_b, PointerCmp); + EXPECT_NE(TestHashTable::Cmp(*table_a, *table_b), 0); } +} // namespace +} // namespace grpc_core + int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); grpc_test_init(argc, argv); grpc_core::ExecCtx::GlobalInit(); - test_slice_hash_table(); - test_slice_hash_table_eq(); - test_slice_hash_table_not_eq(); + int result = RUN_ALL_TESTS(); grpc_core::ExecCtx::GlobalShutdown(); - return 0; + return result; } diff --git a/test/core/slice/slice_string_helpers_test.cc b/test/core/slice/slice_string_helpers_test.cc index f1d470461a..860a1bfe03 100644 --- a/test/core/slice/slice_string_helpers_test.cc +++ b/test/core/slice/slice_string_helpers_test.cc @@ -23,13 +23,11 @@ #include <stdlib.h> #include <string.h> -#include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/util/test_config.h" #define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) @@ -129,11 +127,77 @@ static void test_strsplit(void) { gpr_free(parts); } +static void test_strsplit_nospace(void) { + grpc_slice_buffer* parts; + grpc_slice str; + + LOG_TEST_NAME("test_strsplit_nospace"); + + parts = + static_cast<grpc_slice_buffer*>(gpr_malloc(sizeof(grpc_slice_buffer))); + grpc_slice_buffer_init(parts); + + str = grpc_slice_from_copied_string("one ,two, three , four"); + grpc_slice_split_without_space(str, ",", parts); + GPR_ASSERT(4 == parts->count); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one")); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "two")); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[2], "three")); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[3], "four")); + grpc_slice_buffer_reset_and_unref(parts); + grpc_slice_unref(str); + + /* separator not present in string */ + str = grpc_slice_from_copied_string("one two three four "); + grpc_slice_split_without_space(str, ",", parts); + GPR_ASSERT(1 == parts->count); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one two three four")); + grpc_slice_buffer_reset_and_unref(parts); + grpc_slice_unref(str); + + /* separator at the end */ + str = grpc_slice_from_copied_string("foo,"); + grpc_slice_split_without_space(str, ",", parts); + GPR_ASSERT(2 == parts->count); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "foo")); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "")); + grpc_slice_buffer_reset_and_unref(parts); + grpc_slice_unref(str); + + /* separator at the beginning */ + str = grpc_slice_from_copied_string(" , foo"); + grpc_slice_split_without_space(str, ",", parts); + GPR_ASSERT(2 == parts->count); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "")); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "foo")); + grpc_slice_buffer_reset_and_unref(parts); + grpc_slice_unref(str); + + /* standalone separator */ + str = grpc_slice_from_copied_string(", "); + grpc_slice_split_without_space(str, ", ", parts); + GPR_ASSERT(2 == parts->count); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "")); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "")); + grpc_slice_buffer_reset_and_unref(parts); + grpc_slice_unref(str); + + /* empty input */ + str = grpc_slice_from_copied_string(""); + grpc_slice_split_without_space(str, ",", parts); + GPR_ASSERT(1 == parts->count); + GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "")); + grpc_slice_buffer_reset_and_unref(parts); + grpc_slice_unref(str); + + grpc_slice_buffer_destroy(parts); + gpr_free(parts); +} + int main(int argc, char** argv) { grpc_test_init(argc, argv); - grpc_init(); test_dump_slice(); test_strsplit(); - grpc_shutdown(); + test_strsplit_nospace(); return 0; } diff --git a/test/core/slice/slice_test.cc b/test/core/slice/slice_test.cc index e40154dd0e..e683c41f31 100644 --- a/test/core/slice/slice_test.cc +++ b/test/core/slice/slice_test.cc @@ -16,8 +16,11 @@ * */ +#include <grpc/support/port_platform.h> + #include <grpc/slice.h> +#include <inttypes.h> #include <string.h> #include <grpc/grpc.h> @@ -57,7 +60,7 @@ static void test_slice_malloc_returns_something_sensible(void) { } /* We must be able to write to every byte of the data */ for (i = 0; i < length; i++) { - GRPC_SLICE_START_PTR(slice)[i] = (uint8_t)i; + GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i); } /* And finally we must succeed in destroying the slice */ grpc_slice_unref(slice); @@ -77,7 +80,7 @@ static void test_slice_new_returns_something_sensible(void) { } /* destroy function that sets a mark to indicate it was called. */ -static void set_mark(void* p) { *((int*)p) = 1; } +static void set_mark(void* p) { *(static_cast<int*>(p)) = 1; } static void test_slice_new_with_user_data(void) { int marker = 0; @@ -143,7 +146,7 @@ static void test_slice_sub_works(unsigned length) { beginning of the slice. */ slice = grpc_slice_malloc(length); for (i = 0; i < length; i++) { - GRPC_SLICE_START_PTR(slice)[i] = (uint8_t)i; + GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i); } /* Ensure that for all subsets length is correct and that we start on the @@ -183,7 +186,7 @@ static void test_slice_split_head_works(size_t length) { beginning of the slice. */ slice = grpc_slice_malloc(length); for (i = 0; i < length; i++) { - GRPC_SLICE_START_PTR(slice)[i] = (uint8_t)i; + GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i); } /* Ensure that for all subsets length is correct and that we start on the @@ -211,7 +214,7 @@ static void test_slice_split_tail_works(size_t length) { beginning of the slice. */ slice = grpc_slice_malloc(length); for (i = 0; i < length; i++) { - GRPC_SLICE_START_PTR(slice)[i] = (uint8_t)i; + GRPC_SLICE_START_PTR(slice)[i] = static_cast<uint8_t>(i); } /* Ensure that for all subsets length is correct and that we start on the diff --git a/test/core/slice/slice_weak_hash_table_test.cc b/test/core/slice/slice_weak_hash_table_test.cc new file mode 100644 index 0000000000..b0a243d572 --- /dev/null +++ b/test/core/slice/slice_weak_hash_table_test.cc @@ -0,0 +1,106 @@ +/* + * + * 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 "src/core/lib/slice/slice_weak_hash_table.h" + +#include <cstring> +#include <sstream> + +#include <gtest/gtest.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/slice/slice_internal.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace { + +grpc_slice BuildRefCountedKey(const char* key_str) { + const size_t key_length = strlen(key_str); + grpc_slice key = grpc_slice_malloc_large(key_length); + memcpy(GRPC_SLICE_START_PTR(key), key_str, key_length); + return key; +} + +TEST(SliceWeakHashTable, Basic) { + auto table = SliceWeakHashTable<UniquePtr<char>, 10>::Create(); + // Single key-value insertion. + grpc_slice key = BuildRefCountedKey("key"); + grpc_slice_ref(key); // Get doesn't own. + table->Add(key, UniquePtr<char>(gpr_strdup("value"))); + ASSERT_NE(table->Get(key), nullptr); + ASSERT_STREQ(table->Get(key)->get(), "value"); + grpc_slice_unref(key); + // Unknown key. + ASSERT_EQ(table->Get(grpc_slice_from_static_string("unknown_key")), nullptr); +} + +TEST(SliceWeakHashTable, ValueTypeConstructor) { + struct Value { + Value() : a(123) {} + int a; + }; + auto table = SliceWeakHashTable<Value, 1>::Create(); + grpc_slice key = BuildRefCountedKey("key"); + grpc_slice_ref(key); // Get doesn't own. + table->Add(key, Value()); + ASSERT_EQ(table->Get(key)->a, 123); + grpc_slice_unref(key); +} + +TEST(SliceWeakHashTable, ForceOverload) { + constexpr int kTableSize = 10; + auto table = SliceWeakHashTable<UniquePtr<char>, kTableSize>::Create(); + // Insert a multiple of the maximum size table. + for (int i = 0; i < kTableSize * 2; ++i) { + std::ostringstream oss; + oss << "key-" << i; + grpc_slice key = BuildRefCountedKey(oss.str().c_str()); + oss.clear(); + oss << "value-" << i; + table->Add(key, UniquePtr<char>(gpr_strdup(oss.str().c_str()))); + } + // Verify that some will have been replaced. + int num_missing = 0; + for (int i = 0; i < kTableSize * 2; ++i) { + std::ostringstream oss; + oss << "key-" << i; + grpc_slice key = BuildRefCountedKey(oss.str().c_str()); + if (table->Get(key) == nullptr) num_missing++; + grpc_slice_unref(key); + } + // At least kTableSize elements will be missing. + ASSERT_GE(num_missing, kTableSize); +} + +} // namespace +} // namespace grpc_core + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + grpc_core::ExecCtx::GlobalInit(); + int result = RUN_ALL_TESTS(); + grpc_core::ExecCtx::GlobalShutdown(); + return result; +} diff --git a/test/core/statistics/rpc_stats_test.cc b/test/core/statistics/rpc_stats_test.cc index aead5cfdca..a2a648e2ad 100644 --- a/test/core/statistics/rpc_stats_test.cc +++ b/test/core/statistics/rpc_stats_test.cc @@ -22,8 +22,8 @@ #include <grpc/support/log.h> #include <grpc/support/port_platform.h> #include <grpc/support/string.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> + #include "src/core/ext/census/census_interface.h" #include "src/core/ext/census/census_rpc_stats.h" #include "src/core/ext/census/census_tracing.h" diff --git a/test/core/support/avl_test.cc b/test/core/support/avl_test.cc deleted file mode 100644 index 345db557b9..0000000000 --- a/test/core/support/avl_test.cc +++ /dev/null @@ -1,3659 +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/avl.h> - -#include <stdio.h> -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/useful.h> - -#include "test/core/util/test_config.h" - -static int* box(int x) { - int* b = static_cast<int*>(gpr_malloc(sizeof(*b))); - *b = x; - return b; -} - -static long int_compare(void* int1, void* int2, void* unused) { - return (*(int*)int1) - (*(int*)int2); -} -static void* int_copy(void* p, void* unused) { return box(*(int*)p); } - -static void destroy(void* p, void* unused) { gpr_free(p); } - -static const gpr_avl_vtable int_int_vtable = {destroy, int_copy, int_compare, - destroy, int_copy}; - -static void check_get(gpr_avl avl, int key, int value) { - int* k = box(key); - GPR_ASSERT(*(int*)gpr_avl_get(avl, k, nullptr) == value); - gpr_free(k); -} - -static void check_negget(gpr_avl avl, int key) { - int* k = box(key); - GPR_ASSERT(gpr_avl_get(avl, k, nullptr) == nullptr); - gpr_free(k); -} - -static gpr_avl remove_int(gpr_avl avl, int key) { - int* k = box(key); - avl = gpr_avl_remove(avl, k, nullptr); - gpr_free(k); - return avl; -} - -static void test_get(void) { - gpr_avl avl; - gpr_log(GPR_DEBUG, "test_get"); - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(1), box(11), nullptr); - avl = gpr_avl_add(avl, box(2), box(22), nullptr); - avl = gpr_avl_add(avl, box(3), box(33), nullptr); - check_get(avl, 1, 11); - check_get(avl, 2, 22); - check_get(avl, 3, 33); - check_negget(avl, 4); - gpr_avl_unref(avl, nullptr); -} - -static void test_ll(void) { - gpr_avl avl; - gpr_log(GPR_DEBUG, "test_ll"); - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(5), box(1), nullptr); - avl = gpr_avl_add(avl, box(4), box(2), nullptr); - avl = gpr_avl_add(avl, box(3), box(3), nullptr); - GPR_ASSERT(*(int*)avl.root->key == 4); - GPR_ASSERT(*(int*)avl.root->left->key == 3); - GPR_ASSERT(*(int*)avl.root->right->key == 5); - gpr_avl_unref(avl, nullptr); -} - -static void test_lr(void) { - gpr_avl avl; - gpr_log(GPR_DEBUG, "test_lr"); - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(5), box(1), nullptr); - avl = gpr_avl_add(avl, box(3), box(2), nullptr); - avl = gpr_avl_add(avl, box(4), box(3), nullptr); - GPR_ASSERT(*(int*)avl.root->key == 4); - GPR_ASSERT(*(int*)avl.root->left->key == 3); - GPR_ASSERT(*(int*)avl.root->right->key == 5); - gpr_avl_unref(avl, nullptr); -} - -static void test_rr(void) { - gpr_avl avl; - gpr_log(GPR_DEBUG, "test_rr"); - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(3), box(1), nullptr); - avl = gpr_avl_add(avl, box(4), box(2), nullptr); - avl = gpr_avl_add(avl, box(5), box(3), nullptr); - GPR_ASSERT(*(int*)avl.root->key == 4); - GPR_ASSERT(*(int*)avl.root->left->key == 3); - GPR_ASSERT(*(int*)avl.root->right->key == 5); - gpr_avl_unref(avl, nullptr); -} - -static void test_rl(void) { - gpr_avl avl; - gpr_log(GPR_DEBUG, "test_rl"); - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(3), box(1), nullptr); - avl = gpr_avl_add(avl, box(5), box(2), nullptr); - avl = gpr_avl_add(avl, box(4), box(3), nullptr); - GPR_ASSERT(*(int*)avl.root->key == 4); - GPR_ASSERT(*(int*)avl.root->left->key == 3); - GPR_ASSERT(*(int*)avl.root->right->key == 5); - gpr_avl_unref(avl, nullptr); -} - -static void test_unbalanced(void) { - gpr_avl avl; - gpr_log(GPR_DEBUG, "test_unbalanced"); - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(5), box(1), nullptr); - avl = gpr_avl_add(avl, box(4), box(2), nullptr); - avl = gpr_avl_add(avl, box(3), box(3), nullptr); - avl = gpr_avl_add(avl, box(2), box(4), nullptr); - avl = gpr_avl_add(avl, box(1), box(5), nullptr); - GPR_ASSERT(*(int*)avl.root->key == 4); - GPR_ASSERT(*(int*)avl.root->left->key == 2); - GPR_ASSERT(*(int*)avl.root->left->left->key == 1); - GPR_ASSERT(*(int*)avl.root->left->right->key == 3); - GPR_ASSERT(*(int*)avl.root->right->key == 5); - gpr_avl_unref(avl, nullptr); -} - -static void test_replace(void) { - gpr_avl avl; - gpr_log(GPR_DEBUG, "test_replace"); - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(1), box(1), nullptr); - avl = gpr_avl_add(avl, box(1), box(2), nullptr); - check_get(avl, 1, 2); - check_negget(avl, 2); - gpr_avl_unref(avl, nullptr); -} - -static void test_remove(void) { - gpr_avl avl; - gpr_avl avl3, avl4, avl5, avln; - gpr_log(GPR_DEBUG, "test_remove"); - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(3), box(1), nullptr); - avl = gpr_avl_add(avl, box(4), box(2), nullptr); - avl = gpr_avl_add(avl, box(5), box(3), nullptr); - - avl3 = remove_int(gpr_avl_ref(avl, nullptr), 3); - avl4 = remove_int(gpr_avl_ref(avl, nullptr), 4); - avl5 = remove_int(gpr_avl_ref(avl, nullptr), 5); - avln = remove_int(gpr_avl_ref(avl, nullptr), 1); - - gpr_avl_unref(avl, nullptr); - - check_negget(avl3, 3); - check_get(avl3, 4, 2); - check_get(avl3, 5, 3); - gpr_avl_unref(avl3, nullptr); - - check_get(avl4, 3, 1); - check_negget(avl4, 4); - check_get(avl4, 5, 3); - gpr_avl_unref(avl4, nullptr); - - check_get(avl5, 3, 1); - check_get(avl5, 4, 2); - check_negget(avl5, 5); - gpr_avl_unref(avl5, nullptr); - - check_get(avln, 3, 1); - check_get(avln, 4, 2); - check_get(avln, 5, 3); - gpr_avl_unref(avln, nullptr); -} - -static void test_badcase1(void) { - gpr_avl avl; - - gpr_log(GPR_DEBUG, "test_badcase1"); - - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(88), box(1), nullptr); - avl = remove_int(avl, 643); - avl = remove_int(avl, 983); - avl = gpr_avl_add(avl, box(985), box(4), nullptr); - avl = gpr_avl_add(avl, box(640), box(5), nullptr); - avl = gpr_avl_add(avl, box(41), box(6), nullptr); - avl = gpr_avl_add(avl, box(112), box(7), nullptr); - avl = gpr_avl_add(avl, box(342), box(8), nullptr); - avl = remove_int(avl, 1013); - avl = gpr_avl_add(avl, box(434), box(10), nullptr); - avl = gpr_avl_add(avl, box(520), box(11), nullptr); - avl = gpr_avl_add(avl, box(231), box(12), nullptr); - avl = gpr_avl_add(avl, box(852), box(13), nullptr); - avl = remove_int(avl, 461); - avl = gpr_avl_add(avl, box(108), box(15), nullptr); - avl = gpr_avl_add(avl, box(806), box(16), nullptr); - avl = gpr_avl_add(avl, box(827), box(17), nullptr); - avl = remove_int(avl, 796); - avl = gpr_avl_add(avl, box(340), box(19), nullptr); - avl = gpr_avl_add(avl, box(498), box(20), nullptr); - avl = gpr_avl_add(avl, box(203), box(21), nullptr); - avl = gpr_avl_add(avl, box(751), box(22), nullptr); - avl = gpr_avl_add(avl, box(150), box(23), nullptr); - avl = remove_int(avl, 237); - avl = gpr_avl_add(avl, box(830), box(25), nullptr); - avl = remove_int(avl, 1007); - avl = remove_int(avl, 394); - avl = gpr_avl_add(avl, box(65), box(28), nullptr); - avl = remove_int(avl, 904); - avl = remove_int(avl, 123); - avl = gpr_avl_add(avl, box(238), box(31), nullptr); - avl = gpr_avl_add(avl, box(184), box(32), nullptr); - avl = remove_int(avl, 331); - avl = gpr_avl_add(avl, box(827), box(34), nullptr); - - check_get(avl, 830, 25); - - gpr_avl_unref(avl, nullptr); -} - -static void test_badcase2(void) { - gpr_avl avl; - - gpr_log(GPR_DEBUG, "test_badcase2"); - - avl = gpr_avl_create(&int_int_vtable); - avl = gpr_avl_add(avl, box(288), box(1), nullptr); - avl = remove_int(avl, 415); - avl = gpr_avl_add(avl, box(953), box(3), nullptr); - avl = gpr_avl_add(avl, box(101), box(4), nullptr); - avl = gpr_avl_add(avl, box(516), box(5), nullptr); - avl = gpr_avl_add(avl, box(547), box(6), nullptr); - avl = gpr_avl_add(avl, box(467), box(7), nullptr); - avl = gpr_avl_add(avl, box(793), box(8), nullptr); - avl = remove_int(avl, 190); - avl = gpr_avl_add(avl, box(687), box(10), nullptr); - avl = gpr_avl_add(avl, box(242), box(11), nullptr); - avl = gpr_avl_add(avl, box(142), box(12), nullptr); - avl = remove_int(avl, 705); - avl = remove_int(avl, 578); - avl = remove_int(avl, 767); - avl = remove_int(avl, 183); - avl = gpr_avl_add(avl, box(950), box(17), nullptr); - avl = gpr_avl_add(avl, box(622), box(18), nullptr); - avl = remove_int(avl, 513); - avl = remove_int(avl, 429); - avl = gpr_avl_add(avl, box(205), box(21), nullptr); - avl = remove_int(avl, 663); - avl = remove_int(avl, 953); - avl = remove_int(avl, 892); - avl = gpr_avl_add(avl, box(236), box(25), nullptr); - avl = remove_int(avl, 982); - avl = remove_int(avl, 201); - avl = remove_int(avl, 684); - avl = gpr_avl_add(avl, box(572), box(29), nullptr); - avl = remove_int(avl, 817); - avl = gpr_avl_add(avl, box(970), box(31), nullptr); - avl = remove_int(avl, 347); - avl = remove_int(avl, 574); - avl = gpr_avl_add(avl, box(752), box(34), nullptr); - avl = gpr_avl_add(avl, box(670), box(35), nullptr); - avl = gpr_avl_add(avl, box(69), box(36), nullptr); - avl = remove_int(avl, 111); - avl = remove_int(avl, 523); - avl = gpr_avl_add(avl, box(141), box(39), nullptr); - avl = remove_int(avl, 159); - avl = gpr_avl_add(avl, box(947), box(41), nullptr); - avl = gpr_avl_add(avl, box(855), box(42), nullptr); - avl = remove_int(avl, 218); - avl = remove_int(avl, 6); - avl = gpr_avl_add(avl, box(753), box(45), nullptr); - avl = remove_int(avl, 82); - avl = remove_int(avl, 799); - avl = gpr_avl_add(avl, box(572), box(48), nullptr); - avl = remove_int(avl, 376); - avl = remove_int(avl, 413); - avl = gpr_avl_add(avl, box(458), box(51), nullptr); - avl = remove_int(avl, 897); - avl = gpr_avl_add(avl, box(191), box(53), nullptr); - avl = gpr_avl_add(avl, box(609), box(54), nullptr); - avl = remove_int(avl, 787); - avl = remove_int(avl, 710); - avl = remove_int(avl, 886); - avl = remove_int(avl, 835); - avl = remove_int(avl, 33); - avl = gpr_avl_add(avl, box(871), box(60), nullptr); - avl = remove_int(avl, 641); - avl = gpr_avl_add(avl, box(462), box(62), nullptr); - avl = remove_int(avl, 359); - avl = remove_int(avl, 767); - avl = gpr_avl_add(avl, box(310), box(65), nullptr); - avl = remove_int(avl, 757); - avl = remove_int(avl, 639); - avl = remove_int(avl, 314); - avl = gpr_avl_add(avl, box(2), box(69), nullptr); - avl = remove_int(avl, 138); - avl = gpr_avl_add(avl, box(669), box(71), nullptr); - avl = remove_int(avl, 477); - avl = gpr_avl_add(avl, box(366), box(73), nullptr); - avl = gpr_avl_add(avl, box(612), box(74), nullptr); - avl = gpr_avl_add(avl, box(106), box(75), nullptr); - avl = remove_int(avl, 161); - avl = gpr_avl_add(avl, box(388), box(77), nullptr); - avl = gpr_avl_add(avl, box(141), box(78), nullptr); - avl = remove_int(avl, 633); - avl = remove_int(avl, 459); - avl = gpr_avl_add(avl, box(40), box(81), nullptr); - avl = remove_int(avl, 689); - avl = gpr_avl_add(avl, box(823), box(83), nullptr); - avl = remove_int(avl, 485); - avl = gpr_avl_add(avl, box(903), box(85), nullptr); - avl = gpr_avl_add(avl, box(592), box(86), nullptr); - avl = remove_int(avl, 448); - avl = gpr_avl_add(avl, box(56), box(88), nullptr); - avl = remove_int(avl, 333); - avl = gpr_avl_add(avl, box(189), box(90), nullptr); - avl = gpr_avl_add(avl, box(103), box(91), nullptr); - avl = remove_int(avl, 164); - avl = remove_int(avl, 974); - avl = gpr_avl_add(avl, box(215), box(94), nullptr); - avl = remove_int(avl, 189); - avl = remove_int(avl, 504); - avl = gpr_avl_add(avl, box(868), box(97), nullptr); - avl = remove_int(avl, 909); - avl = remove_int(avl, 148); - avl = remove_int(avl, 469); - avl = gpr_avl_add(avl, box(994), box(101), nullptr); - avl = gpr_avl_add(avl, box(576), box(102), nullptr); - avl = remove_int(avl, 82); - avl = remove_int(avl, 209); - avl = gpr_avl_add(avl, box(276), box(105), nullptr); - avl = remove_int(avl, 856); - avl = gpr_avl_add(avl, box(750), box(107), nullptr); - avl = remove_int(avl, 871); - avl = gpr_avl_add(avl, box(301), box(109), nullptr); - avl = remove_int(avl, 260); - avl = remove_int(avl, 737); - avl = remove_int(avl, 719); - avl = gpr_avl_add(avl, box(933), box(113), nullptr); - avl = gpr_avl_add(avl, box(225), box(114), nullptr); - avl = gpr_avl_add(avl, box(975), box(115), nullptr); - avl = gpr_avl_add(avl, box(86), box(116), nullptr); - avl = remove_int(avl, 732); - avl = gpr_avl_add(avl, box(340), box(118), nullptr); - avl = gpr_avl_add(avl, box(271), box(119), nullptr); - avl = remove_int(avl, 206); - avl = gpr_avl_add(avl, box(949), box(121), nullptr); - avl = gpr_avl_add(avl, box(927), box(122), nullptr); - avl = gpr_avl_add(avl, box(34), box(123), nullptr); - avl = gpr_avl_add(avl, box(351), box(124), nullptr); - avl = remove_int(avl, 836); - avl = gpr_avl_add(avl, box(825), box(126), nullptr); - avl = gpr_avl_add(avl, box(352), box(127), nullptr); - avl = remove_int(avl, 107); - avl = remove_int(avl, 101); - avl = gpr_avl_add(avl, box(320), box(130), nullptr); - avl = gpr_avl_add(avl, box(3), box(131), nullptr); - avl = remove_int(avl, 998); - avl = remove_int(avl, 44); - avl = gpr_avl_add(avl, box(525), box(134), nullptr); - avl = gpr_avl_add(avl, box(864), box(135), nullptr); - avl = gpr_avl_add(avl, box(863), box(136), nullptr); - avl = remove_int(avl, 770); - avl = gpr_avl_add(avl, box(440), box(138), nullptr); - avl = remove_int(avl, 516); - avl = gpr_avl_add(avl, box(116), box(140), nullptr); - avl = remove_int(avl, 380); - avl = gpr_avl_add(avl, box(878), box(142), nullptr); - avl = remove_int(avl, 439); - avl = gpr_avl_add(avl, box(994), box(144), nullptr); - avl = remove_int(avl, 294); - avl = remove_int(avl, 593); - avl = gpr_avl_add(avl, box(696), box(147), nullptr); - avl = remove_int(avl, 8); - avl = gpr_avl_add(avl, box(881), box(149), nullptr); - avl = remove_int(avl, 32); - avl = remove_int(avl, 242); - avl = gpr_avl_add(avl, box(487), box(152), nullptr); - avl = gpr_avl_add(avl, box(637), box(153), nullptr); - avl = gpr_avl_add(avl, box(793), box(154), nullptr); - avl = gpr_avl_add(avl, box(696), box(155), nullptr); - avl = remove_int(avl, 458); - avl = gpr_avl_add(avl, box(828), box(157), nullptr); - avl = remove_int(avl, 784); - avl = remove_int(avl, 274); - avl = gpr_avl_add(avl, box(783), box(160), nullptr); - avl = remove_int(avl, 21); - avl = gpr_avl_add(avl, box(866), box(162), nullptr); - avl = remove_int(avl, 919); - avl = gpr_avl_add(avl, box(435), box(164), nullptr); - avl = remove_int(avl, 385); - avl = gpr_avl_add(avl, box(475), box(166), nullptr); - avl = remove_int(avl, 339); - avl = gpr_avl_add(avl, box(615), box(168), nullptr); - avl = remove_int(avl, 866); - avl = remove_int(avl, 82); - avl = remove_int(avl, 271); - avl = gpr_avl_add(avl, box(590), box(172), nullptr); - avl = gpr_avl_add(avl, box(852), box(173), nullptr); - avl = remove_int(avl, 318); - avl = remove_int(avl, 82); - avl = gpr_avl_add(avl, box(672), box(176), nullptr); - avl = remove_int(avl, 430); - avl = gpr_avl_add(avl, box(821), box(178), nullptr); - avl = gpr_avl_add(avl, box(365), box(179), nullptr); - avl = remove_int(avl, 78); - avl = gpr_avl_add(avl, box(700), box(181), nullptr); - avl = gpr_avl_add(avl, box(353), box(182), nullptr); - avl = remove_int(avl, 492); - avl = gpr_avl_add(avl, box(991), box(184), nullptr); - avl = remove_int(avl, 330); - avl = gpr_avl_add(avl, box(873), box(186), nullptr); - avl = remove_int(avl, 589); - avl = gpr_avl_add(avl, box(676), box(188), nullptr); - avl = gpr_avl_add(avl, box(790), box(189), nullptr); - avl = remove_int(avl, 521); - avl = remove_int(avl, 47); - avl = gpr_avl_add(avl, box(976), box(192), nullptr); - avl = gpr_avl_add(avl, box(683), box(193), nullptr); - avl = remove_int(avl, 803); - avl = remove_int(avl, 1006); - avl = gpr_avl_add(avl, box(775), box(196), nullptr); - avl = gpr_avl_add(avl, box(411), box(197), nullptr); - avl = gpr_avl_add(avl, box(697), box(198), nullptr); - avl = remove_int(avl, 50); - avl = gpr_avl_add(avl, box(213), box(200), nullptr); - avl = remove_int(avl, 714); - avl = gpr_avl_add(avl, box(981), box(202), nullptr); - avl = gpr_avl_add(avl, box(502), box(203), nullptr); - avl = gpr_avl_add(avl, box(697), box(204), nullptr); - avl = gpr_avl_add(avl, box(603), box(205), nullptr); - avl = gpr_avl_add(avl, box(117), box(206), nullptr); - avl = remove_int(avl, 363); - avl = gpr_avl_add(avl, box(104), box(208), nullptr); - avl = remove_int(avl, 842); - avl = gpr_avl_add(avl, box(48), box(210), nullptr); - avl = remove_int(avl, 764); - avl = gpr_avl_add(avl, box(482), box(212), nullptr); - avl = gpr_avl_add(avl, box(928), box(213), nullptr); - avl = gpr_avl_add(avl, box(30), box(214), nullptr); - avl = gpr_avl_add(avl, box(820), box(215), nullptr); - avl = gpr_avl_add(avl, box(334), box(216), nullptr); - avl = remove_int(avl, 306); - avl = gpr_avl_add(avl, box(789), box(218), nullptr); - avl = remove_int(avl, 924); - avl = gpr_avl_add(avl, box(53), box(220), nullptr); - avl = remove_int(avl, 657); - avl = gpr_avl_add(avl, box(130), box(222), nullptr); - avl = gpr_avl_add(avl, box(239), box(223), nullptr); - avl = remove_int(avl, 20); - avl = gpr_avl_add(avl, box(117), box(225), nullptr); - avl = remove_int(avl, 882); - avl = remove_int(avl, 891); - avl = gpr_avl_add(avl, box(9), box(228), nullptr); - avl = gpr_avl_add(avl, box(496), box(229), nullptr); - avl = gpr_avl_add(avl, box(750), box(230), nullptr); - avl = gpr_avl_add(avl, box(283), box(231), nullptr); - avl = gpr_avl_add(avl, box(802), box(232), nullptr); - avl = remove_int(avl, 352); - avl = gpr_avl_add(avl, box(374), box(234), nullptr); - avl = gpr_avl_add(avl, box(6), box(235), nullptr); - avl = gpr_avl_add(avl, box(756), box(236), nullptr); - avl = gpr_avl_add(avl, box(597), box(237), nullptr); - avl = gpr_avl_add(avl, box(661), box(238), nullptr); - avl = remove_int(avl, 96); - avl = gpr_avl_add(avl, box(894), box(240), nullptr); - avl = remove_int(avl, 749); - avl = gpr_avl_add(avl, box(71), box(242), nullptr); - avl = remove_int(avl, 68); - avl = gpr_avl_add(avl, box(388), box(244), nullptr); - avl = remove_int(avl, 119); - avl = remove_int(avl, 856); - avl = gpr_avl_add(avl, box(176), box(247), nullptr); - avl = gpr_avl_add(avl, box(993), box(248), nullptr); - avl = remove_int(avl, 178); - avl = remove_int(avl, 781); - avl = remove_int(avl, 771); - avl = remove_int(avl, 848); - avl = remove_int(avl, 376); - avl = remove_int(avl, 157); - avl = remove_int(avl, 142); - avl = remove_int(avl, 686); - avl = gpr_avl_add(avl, box(779), box(257), nullptr); - avl = gpr_avl_add(avl, box(484), box(258), nullptr); - avl = remove_int(avl, 837); - avl = gpr_avl_add(avl, box(388), box(260), nullptr); - avl = remove_int(avl, 987); - avl = gpr_avl_add(avl, box(336), box(262), nullptr); - avl = remove_int(avl, 855); - avl = gpr_avl_add(avl, box(668), box(264), nullptr); - avl = remove_int(avl, 648); - avl = gpr_avl_add(avl, box(193), box(266), nullptr); - avl = remove_int(avl, 939); - avl = gpr_avl_add(avl, box(740), box(268), nullptr); - avl = gpr_avl_add(avl, box(503), box(269), nullptr); - avl = gpr_avl_add(avl, box(765), box(270), nullptr); - avl = remove_int(avl, 924); - avl = remove_int(avl, 513); - avl = gpr_avl_add(avl, box(161), box(273), nullptr); - avl = gpr_avl_add(avl, box(502), box(274), nullptr); - avl = gpr_avl_add(avl, box(846), box(275), nullptr); - avl = remove_int(avl, 931); - avl = gpr_avl_add(avl, box(87), box(277), nullptr); - avl = gpr_avl_add(avl, box(949), box(278), nullptr); - avl = gpr_avl_add(avl, box(548), box(279), nullptr); - avl = gpr_avl_add(avl, box(951), box(280), nullptr); - avl = remove_int(avl, 1018); - avl = remove_int(avl, 568); - avl = gpr_avl_add(avl, box(138), box(283), nullptr); - avl = gpr_avl_add(avl, box(202), box(284), nullptr); - avl = gpr_avl_add(avl, box(157), box(285), nullptr); - avl = gpr_avl_add(avl, box(264), box(286), nullptr); - avl = gpr_avl_add(avl, box(370), box(287), nullptr); - avl = remove_int(avl, 736); - avl = remove_int(avl, 751); - avl = remove_int(avl, 506); - avl = remove_int(avl, 81); - avl = remove_int(avl, 358); - avl = remove_int(avl, 657); - avl = remove_int(avl, 86); - avl = gpr_avl_add(avl, box(876), box(295), nullptr); - avl = remove_int(avl, 354); - avl = gpr_avl_add(avl, box(134), box(297), nullptr); - avl = remove_int(avl, 781); - avl = remove_int(avl, 183); - avl = gpr_avl_add(avl, box(914), box(300), nullptr); - avl = remove_int(avl, 926); - avl = remove_int(avl, 398); - avl = remove_int(avl, 932); - avl = remove_int(avl, 804); - avl = remove_int(avl, 326); - avl = gpr_avl_add(avl, box(208), box(306), nullptr); - avl = gpr_avl_add(avl, box(699), box(307), nullptr); - avl = remove_int(avl, 576); - avl = remove_int(avl, 850); - avl = remove_int(avl, 514); - avl = remove_int(avl, 676); - avl = remove_int(avl, 549); - avl = remove_int(avl, 767); - avl = gpr_avl_add(avl, box(58), box(314), nullptr); - avl = gpr_avl_add(avl, box(265), box(315), nullptr); - avl = gpr_avl_add(avl, box(268), box(316), nullptr); - avl = gpr_avl_add(avl, box(103), box(317), nullptr); - avl = gpr_avl_add(avl, box(440), box(318), nullptr); - avl = remove_int(avl, 777); - avl = gpr_avl_add(avl, box(670), box(320), nullptr); - avl = remove_int(avl, 506); - avl = remove_int(avl, 487); - avl = gpr_avl_add(avl, box(421), box(323), nullptr); - avl = remove_int(avl, 514); - avl = gpr_avl_add(avl, box(701), box(325), nullptr); - avl = remove_int(avl, 949); - avl = remove_int(avl, 872); - avl = remove_int(avl, 139); - avl = gpr_avl_add(avl, box(781), box(329), nullptr); - avl = gpr_avl_add(avl, box(543), box(330), nullptr); - avl = gpr_avl_add(avl, box(147), box(331), nullptr); - avl = remove_int(avl, 190); - avl = gpr_avl_add(avl, box(453), box(333), nullptr); - avl = remove_int(avl, 262); - avl = remove_int(avl, 850); - avl = remove_int(avl, 286); - avl = remove_int(avl, 787); - avl = gpr_avl_add(avl, box(514), box(338), nullptr); - avl = remove_int(avl, 812); - avl = gpr_avl_add(avl, box(431), box(340), nullptr); - avl = gpr_avl_add(avl, box(8), box(341), nullptr); - avl = remove_int(avl, 843); - avl = gpr_avl_add(avl, box(831), box(343), nullptr); - avl = remove_int(avl, 472); - avl = remove_int(avl, 157); - avl = gpr_avl_add(avl, box(612), box(346), nullptr); - avl = gpr_avl_add(avl, box(802), box(347), nullptr); - avl = remove_int(avl, 554); - avl = gpr_avl_add(avl, box(409), box(349), nullptr); - avl = gpr_avl_add(avl, box(439), box(350), nullptr); - avl = gpr_avl_add(avl, box(725), box(351), nullptr); - avl = gpr_avl_add(avl, box(568), box(352), nullptr); - avl = remove_int(avl, 475); - avl = remove_int(avl, 672); - avl = remove_int(avl, 62); - avl = remove_int(avl, 753); - avl = gpr_avl_add(avl, box(435), box(357), nullptr); - avl = gpr_avl_add(avl, box(950), box(358), nullptr); - avl = gpr_avl_add(avl, box(532), box(359), nullptr); - avl = gpr_avl_add(avl, box(832), box(360), nullptr); - avl = remove_int(avl, 390); - avl = gpr_avl_add(avl, box(993), box(362), nullptr); - avl = remove_int(avl, 198); - avl = remove_int(avl, 401); - avl = gpr_avl_add(avl, box(316), box(365), nullptr); - avl = remove_int(avl, 843); - avl = gpr_avl_add(avl, box(541), box(367), nullptr); - avl = gpr_avl_add(avl, box(505), box(368), nullptr); - avl = remove_int(avl, 445); - avl = remove_int(avl, 256); - avl = gpr_avl_add(avl, box(232), box(371), nullptr); - avl = remove_int(avl, 577); - avl = remove_int(avl, 558); - avl = gpr_avl_add(avl, box(910), box(374), nullptr); - avl = remove_int(avl, 902); - avl = remove_int(avl, 755); - avl = remove_int(avl, 114); - avl = remove_int(avl, 438); - avl = remove_int(avl, 224); - avl = gpr_avl_add(avl, box(920), box(380), nullptr); - avl = gpr_avl_add(avl, box(655), box(381), nullptr); - avl = remove_int(avl, 557); - avl = remove_int(avl, 102); - avl = remove_int(avl, 165); - avl = gpr_avl_add(avl, box(191), box(385), nullptr); - avl = remove_int(avl, 30); - avl = gpr_avl_add(avl, box(406), box(387), nullptr); - avl = gpr_avl_add(avl, box(66), box(388), nullptr); - avl = gpr_avl_add(avl, box(87), box(389), nullptr); - avl = remove_int(avl, 7); - avl = remove_int(avl, 671); - avl = gpr_avl_add(avl, box(234), box(392), nullptr); - avl = remove_int(avl, 463); - avl = gpr_avl_add(avl, box(75), box(394), nullptr); - avl = gpr_avl_add(avl, box(487), box(395), nullptr); - avl = remove_int(avl, 203); - avl = gpr_avl_add(avl, box(711), box(397), nullptr); - avl = remove_int(avl, 291); - avl = remove_int(avl, 798); - avl = remove_int(avl, 337); - avl = gpr_avl_add(avl, box(877), box(401), nullptr); - avl = gpr_avl_add(avl, box(388), box(402), nullptr); - avl = remove_int(avl, 975); - avl = gpr_avl_add(avl, box(200), box(404), nullptr); - avl = gpr_avl_add(avl, box(408), box(405), nullptr); - avl = gpr_avl_add(avl, box(3), box(406), nullptr); - avl = gpr_avl_add(avl, box(971), box(407), nullptr); - avl = remove_int(avl, 841); - avl = remove_int(avl, 910); - avl = remove_int(avl, 74); - avl = remove_int(avl, 888); - avl = gpr_avl_add(avl, box(492), box(412), nullptr); - avl = remove_int(avl, 14); - avl = remove_int(avl, 364); - avl = gpr_avl_add(avl, box(215), box(415), nullptr); - avl = remove_int(avl, 778); - avl = remove_int(avl, 45); - avl = gpr_avl_add(avl, box(328), box(418), nullptr); - avl = gpr_avl_add(avl, box(597), box(419), nullptr); - avl = remove_int(avl, 34); - avl = gpr_avl_add(avl, box(736), box(421), nullptr); - avl = remove_int(avl, 37); - avl = gpr_avl_add(avl, box(275), box(423), nullptr); - avl = gpr_avl_add(avl, box(70), box(424), nullptr); - avl = gpr_avl_add(avl, box(771), box(425), nullptr); - avl = remove_int(avl, 536); - avl = remove_int(avl, 421); - avl = gpr_avl_add(avl, box(186), box(428), nullptr); - avl = gpr_avl_add(avl, box(788), box(429), nullptr); - avl = gpr_avl_add(avl, box(224), box(430), nullptr); - avl = remove_int(avl, 228); - avl = gpr_avl_add(avl, box(48), box(432), nullptr); - avl = gpr_avl_add(avl, box(120), box(433), nullptr); - avl = gpr_avl_add(avl, box(269), box(434), nullptr); - avl = gpr_avl_add(avl, box(904), box(435), nullptr); - avl = remove_int(avl, 699); - avl = gpr_avl_add(avl, box(340), box(437), nullptr); - avl = remove_int(avl, 276); - avl = gpr_avl_add(avl, box(591), box(439), nullptr); - avl = gpr_avl_add(avl, box(778), box(440), nullptr); - avl = remove_int(avl, 490); - avl = remove_int(avl, 973); - avl = gpr_avl_add(avl, box(294), box(443), nullptr); - avl = gpr_avl_add(avl, box(323), box(444), nullptr); - avl = remove_int(avl, 685); - avl = gpr_avl_add(avl, box(38), box(446), nullptr); - avl = gpr_avl_add(avl, box(525), box(447), nullptr); - avl = remove_int(avl, 162); - avl = gpr_avl_add(avl, box(462), box(449), nullptr); - avl = gpr_avl_add(avl, box(340), box(450), nullptr); - avl = remove_int(avl, 734); - avl = remove_int(avl, 959); - avl = gpr_avl_add(avl, box(752), box(453), nullptr); - avl = gpr_avl_add(avl, box(667), box(454), nullptr); - avl = remove_int(avl, 558); - avl = remove_int(avl, 657); - avl = gpr_avl_add(avl, box(711), box(457), nullptr); - avl = remove_int(avl, 937); - avl = gpr_avl_add(avl, box(741), box(459), nullptr); - avl = gpr_avl_add(avl, box(40), box(460), nullptr); - avl = remove_int(avl, 784); - avl = gpr_avl_add(avl, box(292), box(462), nullptr); - avl = remove_int(avl, 164); - avl = remove_int(avl, 931); - avl = remove_int(avl, 886); - avl = gpr_avl_add(avl, box(968), box(466), nullptr); - avl = remove_int(avl, 263); - avl = gpr_avl_add(avl, box(647), box(468), nullptr); - avl = gpr_avl_add(avl, box(92), box(469), nullptr); - avl = remove_int(avl, 310); - avl = gpr_avl_add(avl, box(711), box(471), nullptr); - avl = gpr_avl_add(avl, box(675), box(472), nullptr); - avl = remove_int(avl, 549); - avl = gpr_avl_add(avl, box(380), box(474), nullptr); - avl = remove_int(avl, 825); - avl = gpr_avl_add(avl, box(668), box(476), nullptr); - avl = remove_int(avl, 498); - avl = gpr_avl_add(avl, box(870), box(478), nullptr); - avl = gpr_avl_add(avl, box(391), box(479), nullptr); - avl = gpr_avl_add(avl, box(264), box(480), nullptr); - avl = remove_int(avl, 1); - avl = remove_int(avl, 849); - avl = remove_int(avl, 88); - avl = remove_int(avl, 255); - avl = remove_int(avl, 763); - avl = remove_int(avl, 831); - avl = gpr_avl_add(avl, box(508), box(487), nullptr); - avl = remove_int(avl, 849); - avl = remove_int(avl, 47); - avl = gpr_avl_add(avl, box(299), box(490), nullptr); - avl = remove_int(avl, 625); - avl = remove_int(avl, 433); - avl = remove_int(avl, 904); - avl = remove_int(avl, 761); - avl = gpr_avl_add(avl, box(33), box(495), nullptr); - avl = gpr_avl_add(avl, box(524), box(496), nullptr); - avl = remove_int(avl, 210); - avl = remove_int(avl, 299); - avl = gpr_avl_add(avl, box(823), box(499), nullptr); - avl = remove_int(avl, 479); - avl = remove_int(avl, 96); - avl = remove_int(avl, 1013); - avl = gpr_avl_add(avl, box(768), box(503), nullptr); - avl = remove_int(avl, 638); - avl = remove_int(avl, 20); - avl = gpr_avl_add(avl, box(663), box(506), nullptr); - avl = remove_int(avl, 882); - avl = gpr_avl_add(avl, box(745), box(508), nullptr); - avl = remove_int(avl, 352); - avl = gpr_avl_add(avl, box(10), box(510), nullptr); - avl = remove_int(avl, 484); - avl = gpr_avl_add(avl, box(420), box(512), nullptr); - avl = gpr_avl_add(avl, box(884), box(513), nullptr); - avl = gpr_avl_add(avl, box(993), box(514), nullptr); - avl = gpr_avl_add(avl, box(251), box(515), nullptr); - avl = remove_int(avl, 222); - avl = gpr_avl_add(avl, box(734), box(517), nullptr); - avl = gpr_avl_add(avl, box(952), box(518), nullptr); - avl = remove_int(avl, 26); - avl = remove_int(avl, 270); - avl = remove_int(avl, 481); - avl = remove_int(avl, 693); - avl = remove_int(avl, 1006); - avl = gpr_avl_add(avl, box(77), box(524), nullptr); - avl = remove_int(avl, 897); - avl = gpr_avl_add(avl, box(719), box(526), nullptr); - avl = gpr_avl_add(avl, box(622), box(527), nullptr); - avl = remove_int(avl, 28); - avl = remove_int(avl, 836); - avl = remove_int(avl, 142); - avl = gpr_avl_add(avl, box(445), box(531), nullptr); - avl = gpr_avl_add(avl, box(410), box(532), nullptr); - avl = remove_int(avl, 575); - avl = gpr_avl_add(avl, box(634), box(534), nullptr); - avl = gpr_avl_add(avl, box(906), box(535), nullptr); - avl = remove_int(avl, 649); - avl = gpr_avl_add(avl, box(813), box(537), nullptr); - avl = remove_int(avl, 702); - avl = remove_int(avl, 732); - avl = gpr_avl_add(avl, box(105), box(540), nullptr); - avl = gpr_avl_add(avl, box(867), box(541), nullptr); - avl = remove_int(avl, 964); - avl = remove_int(avl, 941); - avl = gpr_avl_add(avl, box(947), box(544), nullptr); - avl = remove_int(avl, 990); - avl = gpr_avl_add(avl, box(816), box(546), nullptr); - avl = remove_int(avl, 429); - avl = remove_int(avl, 567); - avl = remove_int(avl, 541); - avl = remove_int(avl, 583); - avl = gpr_avl_add(avl, box(57), box(551), nullptr); - avl = gpr_avl_add(avl, box(786), box(552), nullptr); - avl = gpr_avl_add(avl, box(526), box(553), nullptr); - avl = remove_int(avl, 642); - avl = remove_int(avl, 220); - avl = remove_int(avl, 840); - avl = remove_int(avl, 548); - avl = gpr_avl_add(avl, box(528), box(558), nullptr); - avl = gpr_avl_add(avl, box(749), box(559), nullptr); - avl = gpr_avl_add(avl, box(194), box(560), nullptr); - avl = remove_int(avl, 517); - avl = gpr_avl_add(avl, box(102), box(562), nullptr); - avl = remove_int(avl, 189); - avl = gpr_avl_add(avl, box(927), box(564), nullptr); - avl = remove_int(avl, 846); - avl = remove_int(avl, 130); - avl = gpr_avl_add(avl, box(694), box(567), nullptr); - avl = remove_int(avl, 750); - avl = gpr_avl_add(avl, box(357), box(569), nullptr); - avl = remove_int(avl, 431); - avl = remove_int(avl, 91); - avl = gpr_avl_add(avl, box(640), box(572), nullptr); - avl = remove_int(avl, 4); - avl = gpr_avl_add(avl, box(81), box(574), nullptr); - avl = gpr_avl_add(avl, box(595), box(575), nullptr); - avl = remove_int(avl, 444); - avl = remove_int(avl, 262); - avl = remove_int(avl, 11); - avl = gpr_avl_add(avl, box(192), box(579), nullptr); - avl = gpr_avl_add(avl, box(158), box(580), nullptr); - avl = remove_int(avl, 401); - avl = remove_int(avl, 918); - avl = gpr_avl_add(avl, box(180), box(583), nullptr); - avl = remove_int(avl, 268); - avl = gpr_avl_add(avl, box(1012), box(585), nullptr); - avl = gpr_avl_add(avl, box(90), box(586), nullptr); - avl = gpr_avl_add(avl, box(946), box(587), nullptr); - avl = remove_int(avl, 719); - avl = gpr_avl_add(avl, box(874), box(589), nullptr); - avl = gpr_avl_add(avl, box(679), box(590), nullptr); - avl = remove_int(avl, 53); - avl = remove_int(avl, 534); - avl = gpr_avl_add(avl, box(646), box(593), nullptr); - avl = gpr_avl_add(avl, box(767), box(594), nullptr); - avl = gpr_avl_add(avl, box(460), box(595), nullptr); - avl = gpr_avl_add(avl, box(852), box(596), nullptr); - avl = gpr_avl_add(avl, box(189), box(597), nullptr); - avl = remove_int(avl, 932); - avl = remove_int(avl, 366); - avl = remove_int(avl, 907); - avl = gpr_avl_add(avl, box(875), box(601), nullptr); - avl = gpr_avl_add(avl, box(434), box(602), nullptr); - avl = gpr_avl_add(avl, box(704), box(603), nullptr); - avl = gpr_avl_add(avl, box(724), box(604), nullptr); - avl = gpr_avl_add(avl, box(930), box(605), nullptr); - avl = gpr_avl_add(avl, box(1000), box(606), nullptr); - avl = remove_int(avl, 479); - avl = gpr_avl_add(avl, box(275), box(608), nullptr); - avl = remove_int(avl, 32); - avl = gpr_avl_add(avl, box(939), box(610), nullptr); - avl = remove_int(avl, 943); - avl = remove_int(avl, 329); - avl = gpr_avl_add(avl, box(490), box(613), nullptr); - avl = remove_int(avl, 477); - avl = remove_int(avl, 414); - avl = remove_int(avl, 187); - avl = remove_int(avl, 334); - avl = gpr_avl_add(avl, box(40), box(618), nullptr); - avl = remove_int(avl, 751); - avl = gpr_avl_add(avl, box(568), box(620), nullptr); - avl = gpr_avl_add(avl, box(120), box(621), nullptr); - avl = gpr_avl_add(avl, box(617), box(622), nullptr); - avl = gpr_avl_add(avl, box(32), box(623), nullptr); - avl = remove_int(avl, 701); - avl = gpr_avl_add(avl, box(910), box(625), nullptr); - avl = remove_int(avl, 557); - avl = remove_int(avl, 361); - avl = remove_int(avl, 937); - avl = remove_int(avl, 100); - avl = remove_int(avl, 684); - avl = gpr_avl_add(avl, box(751), box(631), nullptr); - avl = remove_int(avl, 781); - avl = remove_int(avl, 469); - avl = remove_int(avl, 75); - avl = remove_int(avl, 561); - avl = gpr_avl_add(avl, box(854), box(636), nullptr); - avl = remove_int(avl, 164); - avl = remove_int(avl, 258); - avl = remove_int(avl, 315); - avl = remove_int(avl, 261); - avl = gpr_avl_add(avl, box(552), box(641), nullptr); - avl = gpr_avl_add(avl, box(6), box(642), nullptr); - avl = gpr_avl_add(avl, box(680), box(643), nullptr); - avl = remove_int(avl, 741); - avl = remove_int(avl, 309); - avl = remove_int(avl, 272); - avl = gpr_avl_add(avl, box(249), box(647), nullptr); - avl = remove_int(avl, 97); - avl = remove_int(avl, 850); - avl = gpr_avl_add(avl, box(915), box(650), nullptr); - avl = gpr_avl_add(avl, box(816), box(651), nullptr); - avl = gpr_avl_add(avl, box(45), box(652), nullptr); - avl = gpr_avl_add(avl, box(168), box(653), nullptr); - avl = remove_int(avl, 153); - avl = remove_int(avl, 239); - avl = gpr_avl_add(avl, box(684), box(656), nullptr); - avl = gpr_avl_add(avl, box(208), box(657), nullptr); - avl = gpr_avl_add(avl, box(681), box(658), nullptr); - avl = gpr_avl_add(avl, box(609), box(659), nullptr); - avl = gpr_avl_add(avl, box(645), box(660), nullptr); - avl = remove_int(avl, 799); - avl = gpr_avl_add(avl, box(955), box(662), nullptr); - avl = gpr_avl_add(avl, box(946), box(663), nullptr); - avl = gpr_avl_add(avl, box(744), box(664), nullptr); - avl = gpr_avl_add(avl, box(201), box(665), nullptr); - avl = gpr_avl_add(avl, box(136), box(666), nullptr); - avl = remove_int(avl, 357); - avl = gpr_avl_add(avl, box(974), box(668), nullptr); - avl = remove_int(avl, 485); - avl = gpr_avl_add(avl, box(1009), box(670), nullptr); - avl = gpr_avl_add(avl, box(517), box(671), nullptr); - avl = remove_int(avl, 491); - avl = gpr_avl_add(avl, box(336), box(673), nullptr); - avl = gpr_avl_add(avl, box(589), box(674), nullptr); - avl = remove_int(avl, 546); - avl = remove_int(avl, 840); - avl = remove_int(avl, 104); - avl = remove_int(avl, 347); - avl = gpr_avl_add(avl, box(801), box(679), nullptr); - avl = remove_int(avl, 799); - avl = remove_int(avl, 702); - avl = remove_int(avl, 996); - avl = remove_int(avl, 93); - avl = gpr_avl_add(avl, box(561), box(684), nullptr); - avl = gpr_avl_add(avl, box(25), box(685), nullptr); - avl = remove_int(avl, 278); - avl = gpr_avl_add(avl, box(191), box(687), nullptr); - avl = remove_int(avl, 243); - avl = remove_int(avl, 918); - avl = remove_int(avl, 449); - avl = gpr_avl_add(avl, box(19), box(691), nullptr); - avl = gpr_avl_add(avl, box(762), box(692), nullptr); - avl = gpr_avl_add(avl, box(13), box(693), nullptr); - avl = gpr_avl_add(avl, box(151), box(694), nullptr); - avl = gpr_avl_add(avl, box(152), box(695), nullptr); - avl = gpr_avl_add(avl, box(793), box(696), nullptr); - avl = remove_int(avl, 862); - avl = remove_int(avl, 890); - avl = gpr_avl_add(avl, box(687), box(699), nullptr); - avl = gpr_avl_add(avl, box(509), box(700), nullptr); - avl = gpr_avl_add(avl, box(973), box(701), nullptr); - avl = remove_int(avl, 230); - avl = gpr_avl_add(avl, box(532), box(703), nullptr); - avl = remove_int(avl, 668); - avl = gpr_avl_add(avl, box(281), box(705), nullptr); - avl = gpr_avl_add(avl, box(867), box(706), nullptr); - avl = gpr_avl_add(avl, box(359), box(707), nullptr); - avl = remove_int(avl, 425); - avl = gpr_avl_add(avl, box(691), box(709), nullptr); - avl = gpr_avl_add(avl, box(163), box(710), nullptr); - avl = gpr_avl_add(avl, box(502), box(711), nullptr); - avl = remove_int(avl, 674); - avl = gpr_avl_add(avl, box(697), box(713), nullptr); - avl = remove_int(avl, 271); - avl = gpr_avl_add(avl, box(968), box(715), nullptr); - avl = gpr_avl_add(avl, box(48), box(716), nullptr); - avl = remove_int(avl, 543); - avl = gpr_avl_add(avl, box(35), box(718), nullptr); - avl = gpr_avl_add(avl, box(751), box(719), nullptr); - avl = gpr_avl_add(avl, box(478), box(720), nullptr); - avl = remove_int(avl, 797); - avl = remove_int(avl, 309); - avl = gpr_avl_add(avl, box(927), box(723), nullptr); - avl = remove_int(avl, 504); - avl = gpr_avl_add(avl, box(286), box(725), nullptr); - avl = gpr_avl_add(avl, box(413), box(726), nullptr); - avl = gpr_avl_add(avl, box(599), box(727), nullptr); - avl = remove_int(avl, 105); - avl = remove_int(avl, 605); - avl = gpr_avl_add(avl, box(632), box(730), nullptr); - avl = gpr_avl_add(avl, box(133), box(731), nullptr); - avl = remove_int(avl, 443); - avl = gpr_avl_add(avl, box(958), box(733), nullptr); - avl = gpr_avl_add(avl, box(729), box(734), nullptr); - avl = remove_int(avl, 158); - avl = gpr_avl_add(avl, box(694), box(736), nullptr); - avl = gpr_avl_add(avl, box(505), box(737), nullptr); - avl = remove_int(avl, 63); - avl = remove_int(avl, 714); - avl = gpr_avl_add(avl, box(1002), box(740), nullptr); - avl = remove_int(avl, 211); - avl = gpr_avl_add(avl, box(765), box(742), nullptr); - avl = gpr_avl_add(avl, box(455), box(743), nullptr); - avl = remove_int(avl, 59); - avl = remove_int(avl, 224); - avl = gpr_avl_add(avl, box(586), box(746), nullptr); - avl = gpr_avl_add(avl, box(348), box(747), nullptr); - avl = remove_int(avl, 10); - avl = remove_int(avl, 484); - avl = gpr_avl_add(avl, box(968), box(750), nullptr); - avl = gpr_avl_add(avl, box(923), box(751), nullptr); - avl = remove_int(avl, 573); - avl = remove_int(avl, 617); - avl = gpr_avl_add(avl, box(812), box(754), nullptr); - avl = gpr_avl_add(avl, box(179), box(755), nullptr); - avl = remove_int(avl, 284); - avl = remove_int(avl, 157); - avl = remove_int(avl, 177); - avl = remove_int(avl, 896); - avl = gpr_avl_add(avl, box(649), box(760), nullptr); - avl = gpr_avl_add(avl, box(927), box(761), nullptr); - avl = gpr_avl_add(avl, box(454), box(762), nullptr); - avl = gpr_avl_add(avl, box(217), box(763), nullptr); - avl = remove_int(avl, 534); - avl = gpr_avl_add(avl, box(180), box(765), nullptr); - avl = gpr_avl_add(avl, box(319), box(766), nullptr); - avl = remove_int(avl, 92); - avl = gpr_avl_add(avl, box(483), box(768), nullptr); - avl = remove_int(avl, 504); - avl = remove_int(avl, 1017); - avl = remove_int(avl, 37); - avl = remove_int(avl, 50); - avl = gpr_avl_add(avl, box(302), box(773), nullptr); - avl = remove_int(avl, 807); - avl = gpr_avl_add(avl, box(463), box(775), nullptr); - avl = gpr_avl_add(avl, box(271), box(776), nullptr); - avl = gpr_avl_add(avl, box(644), box(777), nullptr); - avl = remove_int(avl, 618); - avl = gpr_avl_add(avl, box(166), box(779), nullptr); - avl = gpr_avl_add(avl, box(538), box(780), nullptr); - avl = remove_int(avl, 606); - avl = gpr_avl_add(avl, box(425), box(782), nullptr); - avl = remove_int(avl, 725); - avl = remove_int(avl, 383); - avl = gpr_avl_add(avl, box(155), box(785), nullptr); - avl = remove_int(avl, 889); - avl = gpr_avl_add(avl, box(653), box(787), nullptr); - avl = remove_int(avl, 386); - avl = gpr_avl_add(avl, box(142), box(789), nullptr); - avl = remove_int(avl, 107); - avl = remove_int(avl, 603); - avl = remove_int(avl, 971); - avl = gpr_avl_add(avl, box(80), box(793), nullptr); - avl = gpr_avl_add(avl, box(61), box(794), nullptr); - avl = gpr_avl_add(avl, box(693), box(795), nullptr); - avl = gpr_avl_add(avl, box(592), box(796), nullptr); - avl = gpr_avl_add(avl, box(433), box(797), nullptr); - avl = gpr_avl_add(avl, box(973), box(798), nullptr); - avl = remove_int(avl, 901); - avl = remove_int(avl, 340); - avl = remove_int(avl, 709); - avl = gpr_avl_add(avl, box(224), box(802), nullptr); - avl = remove_int(avl, 120); - avl = remove_int(avl, 271); - avl = gpr_avl_add(avl, box(780), box(805), nullptr); - avl = gpr_avl_add(avl, box(867), box(806), nullptr); - avl = gpr_avl_add(avl, box(756), box(807), nullptr); - avl = gpr_avl_add(avl, box(583), box(808), nullptr); - avl = gpr_avl_add(avl, box(356), box(809), nullptr); - avl = gpr_avl_add(avl, box(58), box(810), nullptr); - avl = remove_int(avl, 219); - avl = gpr_avl_add(avl, box(301), box(812), nullptr); - avl = remove_int(avl, 643); - avl = remove_int(avl, 787); - avl = remove_int(avl, 583); - avl = remove_int(avl, 552); - avl = remove_int(avl, 308); - avl = remove_int(avl, 608); - avl = remove_int(avl, 363); - avl = remove_int(avl, 690); - avl = gpr_avl_add(avl, box(233), box(821), nullptr); - avl = gpr_avl_add(avl, box(479), box(822), nullptr); - avl = gpr_avl_add(avl, box(323), box(823), nullptr); - avl = gpr_avl_add(avl, box(802), box(824), nullptr); - avl = remove_int(avl, 682); - avl = remove_int(avl, 705); - avl = remove_int(avl, 487); - avl = gpr_avl_add(avl, box(530), box(828), nullptr); - avl = gpr_avl_add(avl, box(232), box(829), nullptr); - avl = remove_int(avl, 627); - avl = gpr_avl_add(avl, box(396), box(831), nullptr); - avl = gpr_avl_add(avl, box(61), box(832), nullptr); - avl = gpr_avl_add(avl, box(932), box(833), nullptr); - avl = gpr_avl_add(avl, box(108), box(834), nullptr); - avl = gpr_avl_add(avl, box(524), box(835), nullptr); - avl = remove_int(avl, 390); - avl = remove_int(avl, 307); - avl = gpr_avl_add(avl, box(722), box(838), nullptr); - avl = gpr_avl_add(avl, box(907), box(839), nullptr); - avl = remove_int(avl, 286); - avl = remove_int(avl, 337); - avl = remove_int(avl, 443); - avl = gpr_avl_add(avl, box(973), box(843), nullptr); - avl = remove_int(avl, 930); - avl = remove_int(avl, 242); - avl = gpr_avl_add(avl, box(997), box(846), nullptr); - avl = gpr_avl_add(avl, box(689), box(847), nullptr); - avl = remove_int(avl, 318); - avl = gpr_avl_add(avl, box(703), box(849), nullptr); - avl = gpr_avl_add(avl, box(868), box(850), nullptr); - avl = gpr_avl_add(avl, box(200), box(851), nullptr); - avl = gpr_avl_add(avl, box(960), box(852), nullptr); - avl = gpr_avl_add(avl, box(80), box(853), nullptr); - avl = remove_int(avl, 113); - avl = gpr_avl_add(avl, box(135), box(855), nullptr); - avl = remove_int(avl, 529); - avl = gpr_avl_add(avl, box(366), box(857), nullptr); - avl = remove_int(avl, 272); - avl = gpr_avl_add(avl, box(921), box(859), nullptr); - avl = remove_int(avl, 497); - avl = gpr_avl_add(avl, box(712), box(861), nullptr); - avl = remove_int(avl, 777); - avl = remove_int(avl, 505); - avl = remove_int(avl, 974); - avl = remove_int(avl, 497); - avl = gpr_avl_add(avl, box(388), box(866), nullptr); - avl = gpr_avl_add(avl, box(29), box(867), nullptr); - avl = gpr_avl_add(avl, box(180), box(868), nullptr); - avl = gpr_avl_add(avl, box(983), box(869), nullptr); - avl = gpr_avl_add(avl, box(72), box(870), nullptr); - avl = gpr_avl_add(avl, box(693), box(871), nullptr); - avl = gpr_avl_add(avl, box(567), box(872), nullptr); - avl = remove_int(avl, 549); - avl = remove_int(avl, 351); - avl = gpr_avl_add(avl, box(1019), box(875), nullptr); - avl = remove_int(avl, 585); - avl = remove_int(avl, 294); - avl = remove_int(avl, 61); - avl = gpr_avl_add(avl, box(409), box(879), nullptr); - avl = gpr_avl_add(avl, box(984), box(880), nullptr); - avl = gpr_avl_add(avl, box(830), box(881), nullptr); - avl = remove_int(avl, 579); - avl = gpr_avl_add(avl, box(672), box(883), nullptr); - avl = remove_int(avl, 968); - - gpr_avl_unref(avl, nullptr); -} - -static void test_badcase3(void) { - gpr_avl avl; - - gpr_log(GPR_DEBUG, "test_badcase3"); - - avl = gpr_avl_create(&int_int_vtable); - avl = remove_int(avl, 624); - avl = gpr_avl_add(avl, box(59), box(2), nullptr); - avl = gpr_avl_add(avl, box(494), box(3), nullptr); - avl = gpr_avl_add(avl, box(226), box(4), nullptr); - avl = remove_int(avl, 524); - avl = gpr_avl_add(avl, box(540), box(6), nullptr); - avl = remove_int(avl, 1008); - avl = gpr_avl_add(avl, box(502), box(8), nullptr); - avl = remove_int(avl, 267); - avl = remove_int(avl, 764); - avl = remove_int(avl, 443); - avl = gpr_avl_add(avl, box(8), box(12), nullptr); - avl = remove_int(avl, 291); - avl = remove_int(avl, 796); - avl = remove_int(avl, 1002); - avl = gpr_avl_add(avl, box(778), box(16), nullptr); - avl = remove_int(avl, 621); - avl = remove_int(avl, 891); - avl = remove_int(avl, 880); - avl = gpr_avl_add(avl, box(197), box(20), nullptr); - avl = gpr_avl_add(avl, box(441), box(21), nullptr); - avl = gpr_avl_add(avl, box(719), box(22), nullptr); - avl = remove_int(avl, 109); - avl = gpr_avl_add(avl, box(458), box(24), nullptr); - avl = remove_int(avl, 86); - avl = gpr_avl_add(avl, box(897), box(26), nullptr); - avl = gpr_avl_add(avl, box(997), box(27), nullptr); - avl = remove_int(avl, 235); - avl = remove_int(avl, 425); - avl = remove_int(avl, 186); - avl = gpr_avl_add(avl, box(887), box(31), nullptr); - avl = gpr_avl_add(avl, box(1005), box(32), nullptr); - avl = gpr_avl_add(avl, box(778), box(33), nullptr); - avl = gpr_avl_add(avl, box(575), box(34), nullptr); - avl = remove_int(avl, 966); - avl = remove_int(avl, 1015); - avl = gpr_avl_add(avl, box(486), box(37), nullptr); - avl = gpr_avl_add(avl, box(809), box(38), nullptr); - avl = gpr_avl_add(avl, box(907), box(39), nullptr); - avl = gpr_avl_add(avl, box(971), box(40), nullptr); - avl = remove_int(avl, 441); - avl = remove_int(avl, 498); - avl = gpr_avl_add(avl, box(727), box(43), nullptr); - avl = remove_int(avl, 679); - avl = remove_int(avl, 740); - avl = remove_int(avl, 532); - avl = gpr_avl_add(avl, box(805), box(47), nullptr); - avl = remove_int(avl, 64); - avl = gpr_avl_add(avl, box(362), box(49), nullptr); - avl = gpr_avl_add(avl, box(170), box(50), nullptr); - avl = gpr_avl_add(avl, box(389), box(51), nullptr); - avl = gpr_avl_add(avl, box(689), box(52), nullptr); - avl = remove_int(avl, 871); - avl = gpr_avl_add(avl, box(447), box(54), nullptr); - avl = remove_int(avl, 718); - avl = gpr_avl_add(avl, box(724), box(56), nullptr); - avl = remove_int(avl, 215); - avl = gpr_avl_add(avl, box(550), box(58), nullptr); - avl = remove_int(avl, 932); - avl = gpr_avl_add(avl, box(47), box(60), nullptr); - avl = remove_int(avl, 46); - avl = remove_int(avl, 229); - avl = gpr_avl_add(avl, box(68), box(63), nullptr); - avl = gpr_avl_add(avl, box(387), box(64), nullptr); - avl = remove_int(avl, 933); - avl = remove_int(avl, 736); - avl = remove_int(avl, 719); - avl = gpr_avl_add(avl, box(150), box(68), nullptr); - avl = remove_int(avl, 875); - avl = remove_int(avl, 298); - avl = gpr_avl_add(avl, box(991), box(71), nullptr); - avl = remove_int(avl, 705); - avl = gpr_avl_add(avl, box(197), box(73), nullptr); - avl = gpr_avl_add(avl, box(101), box(74), nullptr); - avl = remove_int(avl, 436); - avl = gpr_avl_add(avl, box(755), box(76), nullptr); - avl = gpr_avl_add(avl, box(727), box(77), nullptr); - avl = remove_int(avl, 309); - avl = remove_int(avl, 253); - avl = gpr_avl_add(avl, box(203), box(80), nullptr); - avl = remove_int(avl, 231); - avl = gpr_avl_add(avl, box(461), box(82), nullptr); - avl = remove_int(avl, 316); - avl = remove_int(avl, 493); - avl = gpr_avl_add(avl, box(184), box(85), nullptr); - avl = remove_int(avl, 737); - avl = gpr_avl_add(avl, box(790), box(87), nullptr); - avl = gpr_avl_add(avl, box(335), box(88), nullptr); - avl = remove_int(avl, 649); - avl = gpr_avl_add(avl, box(69), box(90), nullptr); - avl = remove_int(avl, 585); - avl = remove_int(avl, 543); - avl = gpr_avl_add(avl, box(784), box(93), nullptr); - avl = gpr_avl_add(avl, box(60), box(94), nullptr); - avl = gpr_avl_add(avl, box(525), box(95), nullptr); - avl = gpr_avl_add(avl, box(177), box(96), nullptr); - avl = gpr_avl_add(avl, box(178), box(97), nullptr); - avl = gpr_avl_add(avl, box(683), box(98), nullptr); - avl = gpr_avl_add(avl, box(226), box(99), nullptr); - avl = gpr_avl_add(avl, box(662), box(100), nullptr); - avl = remove_int(avl, 944); - avl = gpr_avl_add(avl, box(562), box(102), nullptr); - avl = gpr_avl_add(avl, box(793), box(103), nullptr); - avl = remove_int(avl, 673); - avl = gpr_avl_add(avl, box(310), box(105), nullptr); - avl = remove_int(avl, 479); - avl = remove_int(avl, 543); - avl = remove_int(avl, 159); - avl = remove_int(avl, 850); - avl = gpr_avl_add(avl, box(318), box(110), nullptr); - avl = gpr_avl_add(avl, box(483), box(111), nullptr); - avl = gpr_avl_add(avl, box(84), box(112), nullptr); - avl = remove_int(avl, 109); - avl = gpr_avl_add(avl, box(132), box(114), nullptr); - avl = gpr_avl_add(avl, box(920), box(115), nullptr); - avl = remove_int(avl, 746); - avl = gpr_avl_add(avl, box(145), box(117), nullptr); - avl = gpr_avl_add(avl, box(526), box(118), nullptr); - avl = remove_int(avl, 158); - avl = gpr_avl_add(avl, box(332), box(120), nullptr); - avl = gpr_avl_add(avl, box(918), box(121), nullptr); - avl = remove_int(avl, 339); - avl = gpr_avl_add(avl, box(809), box(123), nullptr); - avl = gpr_avl_add(avl, box(742), box(124), nullptr); - avl = gpr_avl_add(avl, box(718), box(125), nullptr); - avl = remove_int(avl, 988); - avl = remove_int(avl, 531); - avl = remove_int(avl, 840); - avl = gpr_avl_add(avl, box(816), box(129), nullptr); - avl = gpr_avl_add(avl, box(976), box(130), nullptr); - avl = remove_int(avl, 743); - avl = remove_int(avl, 528); - avl = remove_int(avl, 982); - avl = gpr_avl_add(avl, box(803), box(134), nullptr); - avl = gpr_avl_add(avl, box(205), box(135), nullptr); - avl = gpr_avl_add(avl, box(584), box(136), nullptr); - avl = remove_int(avl, 923); - avl = remove_int(avl, 538); - avl = remove_int(avl, 398); - avl = remove_int(avl, 320); - avl = remove_int(avl, 292); - avl = gpr_avl_add(avl, box(270), box(142), nullptr); - avl = gpr_avl_add(avl, box(333), box(143), nullptr); - avl = remove_int(avl, 439); - avl = gpr_avl_add(avl, box(35), box(145), nullptr); - avl = gpr_avl_add(avl, box(837), box(146), nullptr); - avl = remove_int(avl, 65); - avl = remove_int(avl, 642); - avl = remove_int(avl, 371); - avl = remove_int(avl, 140); - avl = remove_int(avl, 533); - avl = remove_int(avl, 676); - avl = gpr_avl_add(avl, box(624), box(153), nullptr); - avl = gpr_avl_add(avl, box(116), box(154), nullptr); - avl = gpr_avl_add(avl, box(446), box(155), nullptr); - avl = remove_int(avl, 91); - avl = remove_int(avl, 721); - avl = remove_int(avl, 537); - avl = gpr_avl_add(avl, box(448), box(159), nullptr); - avl = remove_int(avl, 155); - avl = remove_int(avl, 344); - avl = remove_int(avl, 237); - avl = gpr_avl_add(avl, box(309), box(163), nullptr); - avl = gpr_avl_add(avl, box(434), box(164), nullptr); - avl = gpr_avl_add(avl, box(277), box(165), nullptr); - avl = remove_int(avl, 233); - avl = gpr_avl_add(avl, box(275), box(167), nullptr); - avl = gpr_avl_add(avl, box(218), box(168), nullptr); - avl = gpr_avl_add(avl, box(76), box(169), nullptr); - avl = gpr_avl_add(avl, box(898), box(170), nullptr); - avl = remove_int(avl, 771); - avl = gpr_avl_add(avl, box(237), box(172), nullptr); - avl = remove_int(avl, 327); - avl = gpr_avl_add(avl, box(499), box(174), nullptr); - avl = remove_int(avl, 727); - avl = remove_int(avl, 234); - avl = remove_int(avl, 623); - avl = remove_int(avl, 458); - avl = remove_int(avl, 326); - avl = remove_int(avl, 589); - avl = gpr_avl_add(avl, box(442), box(181), nullptr); - avl = remove_int(avl, 389); - avl = gpr_avl_add(avl, box(708), box(183), nullptr); - avl = gpr_avl_add(avl, box(594), box(184), nullptr); - avl = gpr_avl_add(avl, box(942), box(185), nullptr); - avl = gpr_avl_add(avl, box(282), box(186), nullptr); - avl = remove_int(avl, 434); - avl = remove_int(avl, 134); - avl = remove_int(avl, 270); - avl = remove_int(avl, 512); - avl = remove_int(avl, 265); - avl = remove_int(avl, 21); - avl = remove_int(avl, 193); - avl = remove_int(avl, 797); - avl = remove_int(avl, 347); - avl = gpr_avl_add(avl, box(99), box(196), nullptr); - avl = gpr_avl_add(avl, box(161), box(197), nullptr); - avl = remove_int(avl, 484); - avl = gpr_avl_add(avl, box(72), box(199), nullptr); - avl = remove_int(avl, 629); - avl = gpr_avl_add(avl, box(522), box(201), nullptr); - avl = remove_int(avl, 679); - avl = gpr_avl_add(avl, box(407), box(203), nullptr); - avl = remove_int(avl, 693); - avl = gpr_avl_add(avl, box(424), box(205), nullptr); - avl = gpr_avl_add(avl, box(651), box(206), nullptr); - avl = gpr_avl_add(avl, box(927), box(207), nullptr); - avl = remove_int(avl, 553); - avl = gpr_avl_add(avl, box(128), box(209), nullptr); - avl = gpr_avl_add(avl, box(616), box(210), nullptr); - avl = gpr_avl_add(avl, box(690), box(211), nullptr); - avl = remove_int(avl, 241); - avl = remove_int(avl, 179); - avl = gpr_avl_add(avl, box(697), box(214), nullptr); - avl = remove_int(avl, 779); - avl = gpr_avl_add(avl, box(241), box(216), nullptr); - avl = remove_int(avl, 190); - avl = remove_int(avl, 210); - avl = gpr_avl_add(avl, box(711), box(219), nullptr); - avl = remove_int(avl, 251); - avl = remove_int(avl, 61); - avl = gpr_avl_add(avl, box(800), box(222), nullptr); - avl = remove_int(avl, 551); - avl = gpr_avl_add(avl, box(61), box(224), nullptr); - avl = gpr_avl_add(avl, box(656), box(225), nullptr); - avl = remove_int(avl, 130); - avl = remove_int(avl, 368); - avl = remove_int(avl, 150); - avl = remove_int(avl, 73); - avl = gpr_avl_add(avl, box(799), box(230), nullptr); - avl = gpr_avl_add(avl, box(125), box(231), nullptr); - avl = remove_int(avl, 107); - avl = gpr_avl_add(avl, box(938), box(233), nullptr); - avl = gpr_avl_add(avl, box(914), box(234), nullptr); - avl = gpr_avl_add(avl, box(197), box(235), nullptr); - avl = remove_int(avl, 736); - avl = gpr_avl_add(avl, box(20), box(237), nullptr); - avl = remove_int(avl, 224); - avl = remove_int(avl, 841); - avl = gpr_avl_add(avl, box(226), box(240), nullptr); - avl = remove_int(avl, 963); - avl = remove_int(avl, 796); - avl = remove_int(avl, 728); - avl = gpr_avl_add(avl, box(855), box(244), nullptr); - avl = gpr_avl_add(avl, box(769), box(245), nullptr); - avl = gpr_avl_add(avl, box(631), box(246), nullptr); - avl = remove_int(avl, 648); - avl = gpr_avl_add(avl, box(187), box(248), nullptr); - avl = gpr_avl_add(avl, box(31), box(249), nullptr); - avl = remove_int(avl, 163); - avl = gpr_avl_add(avl, box(218), box(251), nullptr); - avl = gpr_avl_add(avl, box(488), box(252), nullptr); - avl = gpr_avl_add(avl, box(387), box(253), nullptr); - avl = gpr_avl_add(avl, box(809), box(254), nullptr); - avl = gpr_avl_add(avl, box(997), box(255), nullptr); - avl = remove_int(avl, 678); - avl = gpr_avl_add(avl, box(368), box(257), nullptr); - avl = gpr_avl_add(avl, box(220), box(258), nullptr); - avl = gpr_avl_add(avl, box(373), box(259), nullptr); - avl = remove_int(avl, 874); - avl = remove_int(avl, 682); - avl = remove_int(avl, 1014); - avl = remove_int(avl, 195); - avl = gpr_avl_add(avl, box(868), box(264), nullptr); - avl = remove_int(avl, 254); - avl = remove_int(avl, 456); - avl = gpr_avl_add(avl, box(906), box(267), nullptr); - avl = remove_int(avl, 711); - avl = gpr_avl_add(avl, box(632), box(269), nullptr); - avl = remove_int(avl, 474); - avl = gpr_avl_add(avl, box(508), box(271), nullptr); - avl = gpr_avl_add(avl, box(518), box(272), nullptr); - avl = remove_int(avl, 579); - avl = remove_int(avl, 948); - avl = gpr_avl_add(avl, box(789), box(275), nullptr); - avl = gpr_avl_add(avl, box(48), box(276), nullptr); - avl = gpr_avl_add(avl, box(256), box(277), nullptr); - avl = gpr_avl_add(avl, box(754), box(278), nullptr); - avl = remove_int(avl, 215); - avl = gpr_avl_add(avl, box(679), box(280), nullptr); - avl = gpr_avl_add(avl, box(606), box(281), nullptr); - avl = remove_int(avl, 941); - avl = remove_int(avl, 31); - avl = gpr_avl_add(avl, box(758), box(284), nullptr); - avl = remove_int(avl, 101); - avl = gpr_avl_add(avl, box(244), box(286), nullptr); - avl = gpr_avl_add(avl, box(337), box(287), nullptr); - avl = gpr_avl_add(avl, box(461), box(288), nullptr); - avl = remove_int(avl, 476); - avl = gpr_avl_add(avl, box(845), box(290), nullptr); - avl = remove_int(avl, 160); - avl = gpr_avl_add(avl, box(690), box(292), nullptr); - avl = remove_int(avl, 931); - avl = gpr_avl_add(avl, box(869), box(294), nullptr); - avl = gpr_avl_add(avl, box(1019), box(295), nullptr); - avl = remove_int(avl, 591); - avl = remove_int(avl, 635); - avl = remove_int(avl, 67); - avl = gpr_avl_add(avl, box(113), box(299), nullptr); - avl = remove_int(avl, 305); - avl = gpr_avl_add(avl, box(10), box(301), nullptr); - avl = remove_int(avl, 823); - avl = remove_int(avl, 288); - avl = remove_int(avl, 239); - avl = gpr_avl_add(avl, box(646), box(305), nullptr); - avl = gpr_avl_add(avl, box(1006), box(306), nullptr); - avl = gpr_avl_add(avl, box(954), box(307), nullptr); - avl = gpr_avl_add(avl, box(199), box(308), nullptr); - avl = gpr_avl_add(avl, box(69), box(309), nullptr); - avl = gpr_avl_add(avl, box(984), box(310), nullptr); - avl = remove_int(avl, 568); - avl = remove_int(avl, 666); - avl = remove_int(avl, 37); - avl = gpr_avl_add(avl, box(845), box(314), nullptr); - avl = remove_int(avl, 535); - avl = remove_int(avl, 365); - avl = remove_int(avl, 676); - avl = remove_int(avl, 892); - avl = remove_int(avl, 425); - avl = remove_int(avl, 704); - avl = remove_int(avl, 168); - avl = gpr_avl_add(avl, box(853), box(322), nullptr); - avl = gpr_avl_add(avl, box(335), box(323), nullptr); - avl = gpr_avl_add(avl, box(961), box(324), nullptr); - avl = gpr_avl_add(avl, box(73), box(325), nullptr); - avl = remove_int(avl, 469); - avl = gpr_avl_add(avl, box(449), box(327), nullptr); - avl = remove_int(avl, 821); - avl = gpr_avl_add(avl, box(845), box(329), nullptr); - avl = remove_int(avl, 637); - avl = gpr_avl_add(avl, box(769), box(331), nullptr); - avl = gpr_avl_add(avl, box(901), box(332), nullptr); - avl = remove_int(avl, 142); - avl = remove_int(avl, 361); - avl = remove_int(avl, 876); - avl = gpr_avl_add(avl, box(614), box(336), nullptr); - avl = gpr_avl_add(avl, box(729), box(337), nullptr); - avl = remove_int(avl, 120); - avl = remove_int(avl, 473); - avl = remove_int(avl, 445); - avl = gpr_avl_add(avl, box(978), box(341), nullptr); - avl = gpr_avl_add(avl, box(164), box(342), nullptr); - avl = gpr_avl_add(avl, box(1), box(343), nullptr); - avl = remove_int(avl, 890); - avl = gpr_avl_add(avl, box(605), box(345), nullptr); - avl = gpr_avl_add(avl, box(178), box(346), nullptr); - avl = gpr_avl_add(avl, box(481), box(347), nullptr); - avl = gpr_avl_add(avl, box(772), box(348), nullptr); - avl = remove_int(avl, 824); - avl = remove_int(avl, 167); - avl = remove_int(avl, 151); - avl = gpr_avl_add(avl, box(698), box(352), nullptr); - avl = gpr_avl_add(avl, box(202), box(353), nullptr); - avl = gpr_avl_add(avl, box(921), box(354), nullptr); - avl = gpr_avl_add(avl, box(875), box(355), nullptr); - avl = remove_int(avl, 197); - avl = remove_int(avl, 232); - avl = gpr_avl_add(avl, box(209), box(358), nullptr); - avl = remove_int(avl, 324); - avl = remove_int(avl, 56); - avl = remove_int(avl, 579); - avl = remove_int(avl, 255); - avl = remove_int(avl, 290); - avl = gpr_avl_add(avl, box(661), box(364), nullptr); - avl = gpr_avl_add(avl, box(113), box(365), nullptr); - avl = remove_int(avl, 767); - avl = gpr_avl_add(avl, box(586), box(367), nullptr); - avl = gpr_avl_add(avl, box(121), box(368), nullptr); - avl = remove_int(avl, 235); - avl = remove_int(avl, 439); - avl = remove_int(avl, 360); - avl = gpr_avl_add(avl, box(916), box(372), nullptr); - avl = remove_int(avl, 999); - avl = gpr_avl_add(avl, box(825), box(374), nullptr); - avl = gpr_avl_add(avl, box(177), box(375), nullptr); - avl = remove_int(avl, 204); - avl = remove_int(avl, 92); - avl = gpr_avl_add(avl, box(794), box(378), nullptr); - avl = gpr_avl_add(avl, box(463), box(379), nullptr); - avl = gpr_avl_add(avl, box(472), box(380), nullptr); - avl = remove_int(avl, 235); - avl = gpr_avl_add(avl, box(840), box(382), nullptr); - avl = remove_int(avl, 657); - avl = gpr_avl_add(avl, box(586), box(384), nullptr); - avl = gpr_avl_add(avl, box(979), box(385), nullptr); - avl = remove_int(avl, 979); - avl = gpr_avl_add(avl, box(639), box(387), nullptr); - avl = remove_int(avl, 907); - avl = remove_int(avl, 973); - avl = gpr_avl_add(avl, box(913), box(390), nullptr); - avl = gpr_avl_add(avl, box(566), box(391), nullptr); - avl = gpr_avl_add(avl, box(883), box(392), nullptr); - avl = gpr_avl_add(avl, box(552), box(393), nullptr); - avl = gpr_avl_add(avl, box(16), box(394), nullptr); - avl = remove_int(avl, 60); - avl = gpr_avl_add(avl, box(567), box(396), nullptr); - avl = gpr_avl_add(avl, box(705), box(397), nullptr); - avl = gpr_avl_add(avl, box(94), box(398), nullptr); - avl = remove_int(avl, 321); - avl = gpr_avl_add(avl, box(207), box(400), nullptr); - avl = gpr_avl_add(avl, box(682), box(401), nullptr); - avl = gpr_avl_add(avl, box(592), box(402), nullptr); - avl = gpr_avl_add(avl, box(10), box(403), nullptr); - avl = remove_int(avl, 911); - avl = remove_int(avl, 161); - avl = gpr_avl_add(avl, box(86), box(406), nullptr); - avl = remove_int(avl, 893); - avl = remove_int(avl, 362); - avl = gpr_avl_add(avl, box(599), box(409), nullptr); - avl = remove_int(avl, 413); - avl = gpr_avl_add(avl, box(867), box(411), nullptr); - avl = remove_int(avl, 955); - avl = gpr_avl_add(avl, box(341), box(413), nullptr); - avl = gpr_avl_add(avl, box(887), box(414), nullptr); - avl = remove_int(avl, 706); - avl = gpr_avl_add(avl, box(939), box(416), nullptr); - avl = remove_int(avl, 233); - avl = remove_int(avl, 662); - avl = remove_int(avl, 984); - avl = remove_int(avl, 203); - avl = gpr_avl_add(avl, box(326), box(421), nullptr); - avl = remove_int(avl, 848); - avl = gpr_avl_add(avl, box(235), box(423), nullptr); - avl = remove_int(avl, 617); - avl = gpr_avl_add(avl, box(565), box(425), nullptr); - avl = remove_int(avl, 469); - avl = gpr_avl_add(avl, box(988), box(427), nullptr); - avl = remove_int(avl, 957); - avl = gpr_avl_add(avl, box(426), box(429), nullptr); - avl = remove_int(avl, 967); - avl = gpr_avl_add(avl, box(890), box(431), nullptr); - avl = gpr_avl_add(avl, box(473), box(432), nullptr); - avl = remove_int(avl, 367); - avl = remove_int(avl, 344); - avl = remove_int(avl, 660); - avl = remove_int(avl, 448); - avl = remove_int(avl, 837); - avl = remove_int(avl, 158); - avl = gpr_avl_add(avl, box(459), box(439), nullptr); - avl = remove_int(avl, 882); - avl = remove_int(avl, 782); - avl = gpr_avl_add(avl, box(408), box(442), nullptr); - avl = gpr_avl_add(avl, box(728), box(443), nullptr); - avl = remove_int(avl, 27); - avl = gpr_avl_add(avl, box(137), box(445), nullptr); - avl = gpr_avl_add(avl, box(239), box(446), nullptr); - avl = remove_int(avl, 854); - avl = gpr_avl_add(avl, box(104), box(448), nullptr); - avl = gpr_avl_add(avl, box(823), box(449), nullptr); - avl = gpr_avl_add(avl, box(524), box(450), nullptr); - avl = gpr_avl_add(avl, box(995), box(451), nullptr); - avl = remove_int(avl, 422); - avl = remove_int(avl, 220); - avl = gpr_avl_add(avl, box(856), box(454), nullptr); - avl = remove_int(avl, 332); - avl = gpr_avl_add(avl, box(679), box(456), nullptr); - avl = remove_int(avl, 18); - avl = gpr_avl_add(avl, box(837), box(458), nullptr); - avl = remove_int(avl, 405); - avl = remove_int(avl, 877); - avl = remove_int(avl, 835); - avl = gpr_avl_add(avl, box(547), box(462), nullptr); - avl = remove_int(avl, 805); - avl = remove_int(avl, 862); - avl = gpr_avl_add(avl, box(75), box(465), nullptr); - avl = remove_int(avl, 41); - avl = gpr_avl_add(avl, box(310), box(467), nullptr); - avl = remove_int(avl, 855); - avl = gpr_avl_add(avl, box(20), box(469), nullptr); - avl = remove_int(avl, 186); - avl = remove_int(avl, 378); - avl = remove_int(avl, 442); - avl = remove_int(avl, 930); - avl = gpr_avl_add(avl, box(118), box(474), nullptr); - avl = gpr_avl_add(avl, box(96), box(475), nullptr); - avl = remove_int(avl, 854); - avl = gpr_avl_add(avl, box(65), box(477), nullptr); - avl = gpr_avl_add(avl, box(573), box(478), nullptr); - avl = gpr_avl_add(avl, box(4), box(479), nullptr); - avl = gpr_avl_add(avl, box(451), box(480), nullptr); - avl = gpr_avl_add(avl, box(774), box(481), nullptr); - avl = gpr_avl_add(avl, box(126), box(482), nullptr); - avl = remove_int(avl, 956); - avl = remove_int(avl, 591); - avl = remove_int(avl, 644); - avl = gpr_avl_add(avl, box(304), box(486), nullptr); - avl = remove_int(avl, 620); - avl = remove_int(avl, 394); - avl = gpr_avl_add(avl, box(1002), box(489), nullptr); - avl = gpr_avl_add(avl, box(837), box(490), nullptr); - avl = remove_int(avl, 485); - avl = gpr_avl_add(avl, box(1005), box(492), nullptr); - avl = remove_int(avl, 21); - avl = gpr_avl_add(avl, box(396), box(494), nullptr); - avl = remove_int(avl, 966); - avl = gpr_avl_add(avl, box(105), box(496), nullptr); - avl = gpr_avl_add(avl, box(316), box(497), nullptr); - avl = remove_int(avl, 776); - avl = gpr_avl_add(avl, box(188), box(499), nullptr); - avl = remove_int(avl, 200); - avl = gpr_avl_add(avl, box(98), box(501), nullptr); - avl = gpr_avl_add(avl, box(831), box(502), nullptr); - avl = gpr_avl_add(avl, box(227), box(503), nullptr); - avl = gpr_avl_add(avl, box(220), box(504), nullptr); - avl = remove_int(avl, 715); - avl = remove_int(avl, 279); - avl = gpr_avl_add(avl, box(701), box(507), nullptr); - avl = gpr_avl_add(avl, box(726), box(508), nullptr); - avl = gpr_avl_add(avl, box(815), box(509), nullptr); - avl = gpr_avl_add(avl, box(749), box(510), nullptr); - avl = remove_int(avl, 946); - avl = remove_int(avl, 449); - avl = remove_int(avl, 62); - avl = remove_int(avl, 487); - avl = gpr_avl_add(avl, box(545), box(515), nullptr); - avl = remove_int(avl, 59); - avl = gpr_avl_add(avl, box(168), box(517), nullptr); - avl = remove_int(avl, 337); - avl = gpr_avl_add(avl, box(69), box(519), nullptr); - avl = remove_int(avl, 600); - avl = gpr_avl_add(avl, box(591), box(521), nullptr); - avl = gpr_avl_add(avl, box(960), box(522), nullptr); - avl = gpr_avl_add(avl, box(116), box(523), nullptr); - avl = remove_int(avl, 991); - avl = gpr_avl_add(avl, box(760), box(525), nullptr); - avl = gpr_avl_add(avl, box(664), box(526), nullptr); - avl = gpr_avl_add(avl, box(547), box(527), nullptr); - avl = remove_int(avl, 922); - avl = gpr_avl_add(avl, box(290), box(529), nullptr); - avl = gpr_avl_add(avl, box(859), box(530), nullptr); - avl = gpr_avl_add(avl, box(49), box(531), nullptr); - avl = remove_int(avl, 455); - avl = remove_int(avl, 786); - avl = gpr_avl_add(avl, box(613), box(534), nullptr); - avl = gpr_avl_add(avl, box(326), box(535), nullptr); - avl = remove_int(avl, 615); - avl = gpr_avl_add(avl, box(45), box(537), nullptr); - avl = gpr_avl_add(avl, box(162), box(538), nullptr); - avl = gpr_avl_add(avl, box(189), box(539), nullptr); - avl = remove_int(avl, 68); - avl = remove_int(avl, 846); - avl = gpr_avl_add(avl, box(608), box(542), nullptr); - avl = remove_int(avl, 821); - avl = gpr_avl_add(avl, box(978), box(544), nullptr); - avl = gpr_avl_add(avl, box(892), box(545), nullptr); - avl = remove_int(avl, 924); - avl = gpr_avl_add(avl, box(708), box(547), nullptr); - avl = remove_int(avl, 135); - avl = remove_int(avl, 124); - avl = gpr_avl_add(avl, box(301), box(550), nullptr); - avl = gpr_avl_add(avl, box(939), box(551), nullptr); - avl = gpr_avl_add(avl, box(344), box(552), nullptr); - avl = remove_int(avl, 443); - avl = remove_int(avl, 122); - avl = gpr_avl_add(avl, box(636), box(555), nullptr); - avl = remove_int(avl, 558); - avl = gpr_avl_add(avl, box(923), box(557), nullptr); - avl = remove_int(avl, 827); - avl = gpr_avl_add(avl, box(649), box(559), nullptr); - avl = gpr_avl_add(avl, box(808), box(560), nullptr); - avl = remove_int(avl, 570); - avl = remove_int(avl, 434); - avl = gpr_avl_add(avl, box(40), box(563), nullptr); - avl = gpr_avl_add(avl, box(725), box(564), nullptr); - avl = remove_int(avl, 295); - avl = remove_int(avl, 615); - avl = remove_int(avl, 919); - avl = remove_int(avl, 170); - avl = remove_int(avl, 442); - avl = remove_int(avl, 971); - avl = gpr_avl_add(avl, box(483), box(571), nullptr); - avl = gpr_avl_add(avl, box(512), box(572), nullptr); - avl = remove_int(avl, 648); - avl = remove_int(avl, 78); - avl = remove_int(avl, 72); - avl = remove_int(avl, 790); - avl = remove_int(avl, 571); - avl = gpr_avl_add(avl, box(898), box(578), nullptr); - avl = remove_int(avl, 770); - avl = remove_int(avl, 776); - avl = gpr_avl_add(avl, box(602), box(581), nullptr); - avl = remove_int(avl, 251); - avl = gpr_avl_add(avl, box(303), box(583), nullptr); - avl = remove_int(avl, 837); - avl = gpr_avl_add(avl, box(714), box(585), nullptr); - avl = remove_int(avl, 800); - avl = gpr_avl_add(avl, box(266), box(587), nullptr); - avl = gpr_avl_add(avl, box(555), box(588), nullptr); - avl = remove_int(avl, 604); - avl = remove_int(avl, 163); - avl = remove_int(avl, 497); - avl = gpr_avl_add(avl, box(296), box(592), nullptr); - avl = remove_int(avl, 129); - avl = gpr_avl_add(avl, box(656), box(594), nullptr); - avl = remove_int(avl, 769); - avl = remove_int(avl, 941); - avl = gpr_avl_add(avl, box(775), box(597), nullptr); - avl = gpr_avl_add(avl, box(846), box(598), nullptr); - avl = remove_int(avl, 591); - avl = remove_int(avl, 801); - avl = remove_int(avl, 419); - avl = remove_int(avl, 455); - avl = gpr_avl_add(avl, box(866), box(603), nullptr); - avl = gpr_avl_add(avl, box(575), box(604), nullptr); - avl = gpr_avl_add(avl, box(620), box(605), nullptr); - avl = remove_int(avl, 100); - avl = remove_int(avl, 667); - avl = gpr_avl_add(avl, box(138), box(608), nullptr); - avl = gpr_avl_add(avl, box(566), box(609), nullptr); - avl = gpr_avl_add(avl, box(673), box(610), nullptr); - avl = gpr_avl_add(avl, box(178), box(611), nullptr); - avl = remove_int(avl, 659); - avl = gpr_avl_add(avl, box(759), box(613), nullptr); - avl = gpr_avl_add(avl, box(1008), box(614), nullptr); - avl = remove_int(avl, 116); - avl = gpr_avl_add(avl, box(608), box(616), nullptr); - avl = gpr_avl_add(avl, box(339), box(617), nullptr); - avl = gpr_avl_add(avl, box(197), box(618), nullptr); - avl = remove_int(avl, 25); - avl = remove_int(avl, 628); - avl = gpr_avl_add(avl, box(487), box(621), nullptr); - avl = remove_int(avl, 739); - avl = remove_int(avl, 100); - avl = remove_int(avl, 928); - avl = gpr_avl_add(avl, box(647), box(625), nullptr); - avl = remove_int(avl, 978); - avl = remove_int(avl, 143); - avl = remove_int(avl, 755); - avl = gpr_avl_add(avl, box(71), box(629), nullptr); - avl = remove_int(avl, 205); - avl = gpr_avl_add(avl, box(501), box(631), nullptr); - avl = remove_int(avl, 723); - avl = remove_int(avl, 852); - avl = remove_int(avl, 1021); - avl = remove_int(avl, 670); - avl = remove_int(avl, 500); - avl = gpr_avl_add(avl, box(330), box(637), nullptr); - avl = remove_int(avl, 264); - avl = gpr_avl_add(avl, box(69), box(639), nullptr); - avl = remove_int(avl, 73); - avl = gpr_avl_add(avl, box(745), box(641), nullptr); - avl = remove_int(avl, 518); - avl = remove_int(avl, 641); - avl = remove_int(avl, 768); - avl = gpr_avl_add(avl, box(988), box(645), nullptr); - avl = gpr_avl_add(avl, box(899), box(646), nullptr); - avl = remove_int(avl, 763); - avl = remove_int(avl, 281); - avl = remove_int(avl, 496); - avl = gpr_avl_add(avl, box(445), box(650), nullptr); - avl = remove_int(avl, 905); - avl = gpr_avl_add(avl, box(275), box(652), nullptr); - avl = gpr_avl_add(avl, box(137), box(653), nullptr); - avl = remove_int(avl, 642); - avl = gpr_avl_add(avl, box(708), box(655), nullptr); - avl = remove_int(avl, 922); - avl = gpr_avl_add(avl, box(743), box(657), nullptr); - avl = remove_int(avl, 295); - avl = remove_int(avl, 665); - avl = remove_int(avl, 48); - avl = gpr_avl_add(avl, box(1012), box(661), nullptr); - avl = remove_int(avl, 71); - avl = remove_int(avl, 523); - avl = gpr_avl_add(avl, box(319), box(664), nullptr); - avl = remove_int(avl, 632); - avl = gpr_avl_add(avl, box(137), box(666), nullptr); - avl = gpr_avl_add(avl, box(686), box(667), nullptr); - avl = gpr_avl_add(avl, box(724), box(668), nullptr); - avl = gpr_avl_add(avl, box(952), box(669), nullptr); - avl = gpr_avl_add(avl, box(5), box(670), nullptr); - avl = remove_int(avl, 35); - avl = gpr_avl_add(avl, box(43), box(672), nullptr); - avl = gpr_avl_add(avl, box(320), box(673), nullptr); - avl = gpr_avl_add(avl, box(115), box(674), nullptr); - avl = remove_int(avl, 377); - avl = remove_int(avl, 591); - avl = remove_int(avl, 87); - avl = remove_int(avl, 93); - avl = gpr_avl_add(avl, box(1016), box(679), nullptr); - avl = gpr_avl_add(avl, box(605), box(680), nullptr); - avl = gpr_avl_add(avl, box(152), box(681), nullptr); - avl = gpr_avl_add(avl, box(113), box(682), nullptr); - avl = remove_int(avl, 131); - avl = remove_int(avl, 637); - avl = gpr_avl_add(avl, box(156), box(685), nullptr); - avl = remove_int(avl, 696); - avl = gpr_avl_add(avl, box(546), box(687), nullptr); - avl = remove_int(avl, 970); - avl = remove_int(avl, 53); - avl = remove_int(avl, 827); - avl = remove_int(avl, 224); - avl = remove_int(avl, 796); - avl = remove_int(avl, 34); - avl = remove_int(avl, 922); - avl = remove_int(avl, 277); - avl = remove_int(avl, 650); - avl = remove_int(avl, 222); - avl = remove_int(avl, 244); - avl = remove_int(avl, 576); - avl = remove_int(avl, 413); - avl = gpr_avl_add(avl, box(500), box(701), nullptr); - avl = remove_int(avl, 924); - avl = gpr_avl_add(avl, box(825), box(703), nullptr); - avl = remove_int(avl, 888); - avl = remove_int(avl, 931); - avl = gpr_avl_add(avl, box(285), box(706), nullptr); - avl = remove_int(avl, 62); - avl = remove_int(avl, 444); - avl = remove_int(avl, 946); - avl = gpr_avl_add(avl, box(122), box(710), nullptr); - avl = gpr_avl_add(avl, box(846), box(711), nullptr); - avl = remove_int(avl, 628); - avl = gpr_avl_add(avl, box(511), box(713), nullptr); - avl = gpr_avl_add(avl, box(398), box(714), nullptr); - avl = remove_int(avl, 730); - avl = gpr_avl_add(avl, box(797), box(716), nullptr); - avl = remove_int(avl, 897); - avl = remove_int(avl, 228); - avl = remove_int(avl, 544); - avl = remove_int(avl, 552); - avl = remove_int(avl, 783); - avl = remove_int(avl, 583); - avl = remove_int(avl, 894); - avl = remove_int(avl, 942); - avl = gpr_avl_add(avl, box(346), box(725), nullptr); - avl = gpr_avl_add(avl, box(1015), box(726), nullptr); - avl = remove_int(avl, 813); - avl = gpr_avl_add(avl, box(213), box(728), nullptr); - avl = remove_int(avl, 468); - avl = remove_int(avl, 365); - avl = remove_int(avl, 399); - avl = gpr_avl_add(avl, box(380), box(732), nullptr); - avl = remove_int(avl, 835); - avl = remove_int(avl, 970); - avl = gpr_avl_add(avl, box(700), box(735), nullptr); - avl = gpr_avl_add(avl, box(807), box(736), nullptr); - avl = remove_int(avl, 312); - avl = remove_int(avl, 282); - avl = remove_int(avl, 370); - avl = remove_int(avl, 999); - avl = remove_int(avl, 241); - avl = remove_int(avl, 884); - avl = gpr_avl_add(avl, box(587), box(743), nullptr); - avl = gpr_avl_add(avl, box(332), box(744), nullptr); - avl = remove_int(avl, 686); - avl = remove_int(avl, 206); - avl = remove_int(avl, 835); - avl = gpr_avl_add(avl, box(334), box(748), nullptr); - avl = remove_int(avl, 171); - avl = gpr_avl_add(avl, box(1002), box(750), nullptr); - avl = gpr_avl_add(avl, box(779), box(751), nullptr); - avl = gpr_avl_add(avl, box(307), box(752), nullptr); - avl = gpr_avl_add(avl, box(127), box(753), nullptr); - avl = gpr_avl_add(avl, box(251), box(754), nullptr); - avl = remove_int(avl, 790); - avl = remove_int(avl, 189); - avl = remove_int(avl, 193); - avl = remove_int(avl, 38); - avl = remove_int(avl, 124); - avl = gpr_avl_add(avl, box(812), box(760), nullptr); - avl = remove_int(avl, 43); - avl = gpr_avl_add(avl, box(871), box(762), nullptr); - avl = gpr_avl_add(avl, box(580), box(763), nullptr); - avl = remove_int(avl, 501); - avl = remove_int(avl, 462); - avl = remove_int(avl, 599); - avl = gpr_avl_add(avl, box(240), box(767), nullptr); - avl = gpr_avl_add(avl, box(285), box(768), nullptr); - avl = gpr_avl_add(avl, box(472), box(769), nullptr); - avl = remove_int(avl, 865); - avl = remove_int(avl, 763); - avl = remove_int(avl, 245); - avl = remove_int(avl, 80); - avl = remove_int(avl, 713); - avl = remove_int(avl, 654); - avl = remove_int(avl, 1014); - avl = gpr_avl_add(avl, box(495), box(777), nullptr); - avl = gpr_avl_add(avl, box(552), box(778), nullptr); - avl = remove_int(avl, 19); - avl = remove_int(avl, 803); - avl = gpr_avl_add(avl, box(508), box(781), nullptr); - avl = remove_int(avl, 699); - avl = remove_int(avl, 260); - avl = remove_int(avl, 92); - avl = remove_int(avl, 497); - avl = gpr_avl_add(avl, box(970), box(786), nullptr); - avl = remove_int(avl, 987); - avl = remove_int(avl, 168); - avl = remove_int(avl, 476); - avl = remove_int(avl, 248); - avl = gpr_avl_add(avl, box(358), box(791), nullptr); - avl = remove_int(avl, 804); - avl = remove_int(avl, 77); - avl = remove_int(avl, 905); - avl = remove_int(avl, 362); - avl = gpr_avl_add(avl, box(578), box(796), nullptr); - avl = remove_int(avl, 38); - avl = remove_int(avl, 595); - avl = gpr_avl_add(avl, box(213), box(799), nullptr); - avl = remove_int(avl, 7); - avl = remove_int(avl, 620); - avl = gpr_avl_add(avl, box(946), box(802), nullptr); - avl = remove_int(avl, 145); - avl = gpr_avl_add(avl, box(628), box(804), nullptr); - avl = remove_int(avl, 972); - avl = gpr_avl_add(avl, box(728), box(806), nullptr); - avl = remove_int(avl, 91); - avl = gpr_avl_add(avl, box(136), box(808), nullptr); - avl = gpr_avl_add(avl, box(841), box(809), nullptr); - avl = gpr_avl_add(avl, box(265), box(810), nullptr); - avl = gpr_avl_add(avl, box(701), box(811), nullptr); - avl = gpr_avl_add(avl, box(27), box(812), nullptr); - avl = remove_int(avl, 72); - avl = remove_int(avl, 14); - avl = gpr_avl_add(avl, box(286), box(815), nullptr); - avl = remove_int(avl, 996); - avl = remove_int(avl, 998); - avl = gpr_avl_add(avl, box(466), box(818), nullptr); - avl = remove_int(avl, 1009); - avl = remove_int(avl, 741); - avl = remove_int(avl, 947); - avl = remove_int(avl, 241); - avl = remove_int(avl, 954); - avl = remove_int(avl, 183); - avl = remove_int(avl, 395); - avl = remove_int(avl, 951); - avl = gpr_avl_add(avl, box(267), box(827), nullptr); - avl = remove_int(avl, 812); - avl = gpr_avl_add(avl, box(577), box(829), nullptr); - avl = remove_int(avl, 624); - avl = remove_int(avl, 847); - avl = remove_int(avl, 745); - avl = gpr_avl_add(avl, box(491), box(833), nullptr); - avl = gpr_avl_add(avl, box(941), box(834), nullptr); - avl = remove_int(avl, 258); - avl = gpr_avl_add(avl, box(410), box(836), nullptr); - avl = gpr_avl_add(avl, box(80), box(837), nullptr); - avl = gpr_avl_add(avl, box(196), box(838), nullptr); - avl = gpr_avl_add(avl, box(5), box(839), nullptr); - avl = remove_int(avl, 782); - avl = gpr_avl_add(avl, box(827), box(841), nullptr); - avl = remove_int(avl, 472); - avl = remove_int(avl, 664); - avl = gpr_avl_add(avl, box(409), box(844), nullptr); - avl = gpr_avl_add(avl, box(62), box(845), nullptr); - avl = remove_int(avl, 56); - avl = remove_int(avl, 606); - avl = remove_int(avl, 707); - avl = remove_int(avl, 989); - avl = remove_int(avl, 549); - avl = remove_int(avl, 259); - avl = gpr_avl_add(avl, box(405), box(852), nullptr); - avl = remove_int(avl, 587); - avl = remove_int(avl, 350); - avl = gpr_avl_add(avl, box(980), box(855), nullptr); - avl = gpr_avl_add(avl, box(992), box(856), nullptr); - avl = gpr_avl_add(avl, box(818), box(857), nullptr); - avl = remove_int(avl, 853); - avl = remove_int(avl, 701); - avl = gpr_avl_add(avl, box(675), box(860), nullptr); - avl = remove_int(avl, 248); - avl = remove_int(avl, 649); - avl = gpr_avl_add(avl, box(508), box(863), nullptr); - avl = remove_int(avl, 927); - avl = gpr_avl_add(avl, box(957), box(865), nullptr); - avl = gpr_avl_add(avl, box(698), box(866), nullptr); - avl = gpr_avl_add(avl, box(388), box(867), nullptr); - avl = gpr_avl_add(avl, box(532), box(868), nullptr); - avl = gpr_avl_add(avl, box(681), box(869), nullptr); - avl = remove_int(avl, 544); - avl = remove_int(avl, 991); - avl = remove_int(avl, 397); - avl = gpr_avl_add(avl, box(954), box(873), nullptr); - avl = gpr_avl_add(avl, box(219), box(874), nullptr); - avl = gpr_avl_add(avl, box(465), box(875), nullptr); - avl = remove_int(avl, 371); - avl = gpr_avl_add(avl, box(601), box(877), nullptr); - avl = gpr_avl_add(avl, box(543), box(878), nullptr); - avl = remove_int(avl, 329); - avl = gpr_avl_add(avl, box(560), box(880), nullptr); - avl = remove_int(avl, 898); - avl = gpr_avl_add(avl, box(455), box(882), nullptr); - avl = remove_int(avl, 313); - avl = gpr_avl_add(avl, box(215), box(884), nullptr); - avl = remove_int(avl, 846); - avl = gpr_avl_add(avl, box(608), box(886), nullptr); - avl = remove_int(avl, 248); - avl = gpr_avl_add(avl, box(575), box(888), nullptr); - avl = remove_int(avl, 207); - avl = remove_int(avl, 810); - avl = remove_int(avl, 665); - avl = remove_int(avl, 361); - avl = gpr_avl_add(avl, box(154), box(893), nullptr); - avl = gpr_avl_add(avl, box(329), box(894), nullptr); - avl = gpr_avl_add(avl, box(326), box(895), nullptr); - avl = remove_int(avl, 746); - avl = remove_int(avl, 99); - avl = gpr_avl_add(avl, box(464), box(898), nullptr); - avl = gpr_avl_add(avl, box(141), box(899), nullptr); - avl = remove_int(avl, 383); - avl = gpr_avl_add(avl, box(414), box(901), nullptr); - avl = gpr_avl_add(avl, box(777), box(902), nullptr); - avl = remove_int(avl, 972); - avl = remove_int(avl, 841); - avl = remove_int(avl, 100); - avl = gpr_avl_add(avl, box(828), box(906), nullptr); - avl = remove_int(avl, 785); - avl = gpr_avl_add(avl, box(1008), box(908), nullptr); - avl = gpr_avl_add(avl, box(46), box(909), nullptr); - avl = remove_int(avl, 399); - avl = gpr_avl_add(avl, box(178), box(911), nullptr); - avl = gpr_avl_add(avl, box(573), box(912), nullptr); - avl = remove_int(avl, 299); - avl = gpr_avl_add(avl, box(690), box(914), nullptr); - avl = gpr_avl_add(avl, box(692), box(915), nullptr); - avl = remove_int(avl, 404); - avl = remove_int(avl, 16); - avl = remove_int(avl, 746); - avl = remove_int(avl, 486); - avl = remove_int(avl, 119); - avl = gpr_avl_add(avl, box(167), box(921), nullptr); - avl = remove_int(avl, 328); - avl = gpr_avl_add(avl, box(89), box(923), nullptr); - avl = remove_int(avl, 867); - avl = remove_int(avl, 626); - avl = remove_int(avl, 507); - avl = gpr_avl_add(avl, box(365), box(927), nullptr); - avl = gpr_avl_add(avl, box(58), box(928), nullptr); - avl = gpr_avl_add(avl, box(70), box(929), nullptr); - avl = remove_int(avl, 81); - avl = remove_int(avl, 797); - avl = gpr_avl_add(avl, box(846), box(932), nullptr); - avl = remove_int(avl, 642); - avl = gpr_avl_add(avl, box(777), box(934), nullptr); - avl = remove_int(avl, 107); - avl = gpr_avl_add(avl, box(691), box(936), nullptr); - avl = gpr_avl_add(avl, box(820), box(937), nullptr); - avl = gpr_avl_add(avl, box(202), box(938), nullptr); - avl = gpr_avl_add(avl, box(308), box(939), nullptr); - avl = gpr_avl_add(avl, box(20), box(940), nullptr); - avl = remove_int(avl, 289); - avl = gpr_avl_add(avl, box(714), box(942), nullptr); - avl = gpr_avl_add(avl, box(584), box(943), nullptr); - avl = remove_int(avl, 294); - avl = gpr_avl_add(avl, box(496), box(945), nullptr); - avl = gpr_avl_add(avl, box(394), box(946), nullptr); - avl = gpr_avl_add(avl, box(860), box(947), nullptr); - avl = gpr_avl_add(avl, box(58), box(948), nullptr); - avl = remove_int(avl, 784); - avl = remove_int(avl, 584); - avl = remove_int(avl, 708); - avl = gpr_avl_add(avl, box(142), box(952), nullptr); - avl = gpr_avl_add(avl, box(247), box(953), nullptr); - avl = gpr_avl_add(avl, box(389), box(954), nullptr); - avl = remove_int(avl, 390); - avl = gpr_avl_add(avl, box(465), box(956), nullptr); - avl = gpr_avl_add(avl, box(936), box(957), nullptr); - avl = gpr_avl_add(avl, box(309), box(958), nullptr); - avl = remove_int(avl, 928); - avl = remove_int(avl, 128); - avl = remove_int(avl, 979); - avl = remove_int(avl, 670); - avl = remove_int(avl, 738); - avl = remove_int(avl, 271); - avl = remove_int(avl, 540); - avl = gpr_avl_add(avl, box(365), box(966), nullptr); - avl = remove_int(avl, 82); - avl = gpr_avl_add(avl, box(728), box(968), nullptr); - avl = remove_int(avl, 852); - avl = gpr_avl_add(avl, box(884), box(970), nullptr); - avl = gpr_avl_add(avl, box(502), box(971), nullptr); - avl = remove_int(avl, 898); - avl = remove_int(avl, 481); - avl = gpr_avl_add(avl, box(911), box(974), nullptr); - avl = remove_int(avl, 787); - avl = remove_int(avl, 785); - avl = remove_int(avl, 537); - avl = remove_int(avl, 535); - avl = remove_int(avl, 136); - avl = remove_int(avl, 749); - avl = remove_int(avl, 637); - avl = remove_int(avl, 900); - avl = gpr_avl_add(avl, box(598), box(983), nullptr); - avl = remove_int(avl, 25); - avl = remove_int(avl, 697); - avl = gpr_avl_add(avl, box(645), box(986), nullptr); - avl = gpr_avl_add(avl, box(211), box(987), nullptr); - avl = gpr_avl_add(avl, box(589), box(988), nullptr); - avl = remove_int(avl, 702); - avl = gpr_avl_add(avl, box(53), box(990), nullptr); - avl = remove_int(avl, 492); - avl = remove_int(avl, 185); - avl = remove_int(avl, 246); - avl = remove_int(avl, 257); - avl = remove_int(avl, 502); - avl = remove_int(avl, 34); - avl = gpr_avl_add(avl, box(74), box(997), nullptr); - avl = gpr_avl_add(avl, box(834), box(998), nullptr); - avl = gpr_avl_add(avl, box(514), box(999), nullptr); - avl = gpr_avl_add(avl, box(75), box(1000), nullptr); - avl = remove_int(avl, 745); - avl = gpr_avl_add(avl, box(362), box(1002), nullptr); - avl = remove_int(avl, 215); - avl = gpr_avl_add(avl, box(624), box(1004), nullptr); - avl = remove_int(avl, 404); - avl = remove_int(avl, 359); - avl = remove_int(avl, 491); - avl = gpr_avl_add(avl, box(903), box(1008), nullptr); - avl = gpr_avl_add(avl, box(240), box(1009), nullptr); - avl = remove_int(avl, 95); - avl = gpr_avl_add(avl, box(119), box(1011), nullptr); - avl = gpr_avl_add(avl, box(857), box(1012), nullptr); - avl = remove_int(avl, 39); - avl = remove_int(avl, 866); - avl = gpr_avl_add(avl, box(503), box(1015), nullptr); - avl = gpr_avl_add(avl, box(740), box(1016), nullptr); - avl = remove_int(avl, 637); - avl = remove_int(avl, 156); - avl = remove_int(avl, 6); - avl = remove_int(avl, 745); - avl = remove_int(avl, 433); - avl = remove_int(avl, 283); - avl = gpr_avl_add(avl, box(625), box(1023), nullptr); - avl = remove_int(avl, 638); - avl = gpr_avl_add(avl, box(299), box(1025), nullptr); - avl = gpr_avl_add(avl, box(584), box(1026), nullptr); - avl = remove_int(avl, 863); - avl = gpr_avl_add(avl, box(612), box(1028), nullptr); - avl = gpr_avl_add(avl, box(62), box(1029), nullptr); - avl = gpr_avl_add(avl, box(432), box(1030), nullptr); - avl = remove_int(avl, 371); - avl = remove_int(avl, 790); - avl = remove_int(avl, 227); - avl = remove_int(avl, 836); - avl = gpr_avl_add(avl, box(703), box(1035), nullptr); - avl = gpr_avl_add(avl, box(644), box(1036), nullptr); - avl = remove_int(avl, 638); - avl = gpr_avl_add(avl, box(13), box(1038), nullptr); - avl = remove_int(avl, 66); - avl = remove_int(avl, 82); - avl = gpr_avl_add(avl, box(362), box(1041), nullptr); - avl = gpr_avl_add(avl, box(783), box(1042), nullptr); - avl = remove_int(avl, 60); - avl = gpr_avl_add(avl, box(80), box(1044), nullptr); - avl = gpr_avl_add(avl, box(825), box(1045), nullptr); - avl = gpr_avl_add(avl, box(688), box(1046), nullptr); - avl = gpr_avl_add(avl, box(662), box(1047), nullptr); - avl = remove_int(avl, 156); - avl = remove_int(avl, 376); - avl = remove_int(avl, 99); - avl = gpr_avl_add(avl, box(526), box(1051), nullptr); - avl = gpr_avl_add(avl, box(168), box(1052), nullptr); - avl = remove_int(avl, 646); - avl = remove_int(avl, 380); - avl = remove_int(avl, 833); - avl = gpr_avl_add(avl, box(53), box(1056), nullptr); - avl = remove_int(avl, 105); - avl = gpr_avl_add(avl, box(373), box(1058), nullptr); - avl = gpr_avl_add(avl, box(184), box(1059), nullptr); - avl = remove_int(avl, 288); - avl = gpr_avl_add(avl, box(966), box(1061), nullptr); - avl = remove_int(avl, 158); - avl = gpr_avl_add(avl, box(406), box(1063), nullptr); - avl = remove_int(avl, 470); - avl = gpr_avl_add(avl, box(283), box(1065), nullptr); - avl = gpr_avl_add(avl, box(838), box(1066), nullptr); - avl = gpr_avl_add(avl, box(288), box(1067), nullptr); - avl = gpr_avl_add(avl, box(950), box(1068), nullptr); - avl = gpr_avl_add(avl, box(163), box(1069), nullptr); - avl = remove_int(avl, 623); - avl = remove_int(avl, 769); - avl = gpr_avl_add(avl, box(144), box(1072), nullptr); - avl = gpr_avl_add(avl, box(489), box(1073), nullptr); - avl = remove_int(avl, 15); - avl = gpr_avl_add(avl, box(971), box(1075), nullptr); - avl = remove_int(avl, 660); - avl = gpr_avl_add(avl, box(255), box(1077), nullptr); - avl = remove_int(avl, 494); - avl = gpr_avl_add(avl, box(109), box(1079), nullptr); - avl = gpr_avl_add(avl, box(420), box(1080), nullptr); - avl = gpr_avl_add(avl, box(509), box(1081), nullptr); - avl = remove_int(avl, 178); - avl = gpr_avl_add(avl, box(216), box(1083), nullptr); - avl = gpr_avl_add(avl, box(707), box(1084), nullptr); - avl = gpr_avl_add(avl, box(411), box(1085), nullptr); - avl = gpr_avl_add(avl, box(352), box(1086), nullptr); - avl = remove_int(avl, 983); - avl = gpr_avl_add(avl, box(6), box(1088), nullptr); - avl = gpr_avl_add(avl, box(1014), box(1089), nullptr); - avl = remove_int(avl, 98); - avl = remove_int(avl, 325); - avl = gpr_avl_add(avl, box(851), box(1092), nullptr); - avl = remove_int(avl, 553); - avl = gpr_avl_add(avl, box(218), box(1094), nullptr); - avl = gpr_avl_add(avl, box(261), box(1095), nullptr); - avl = remove_int(avl, 31); - avl = gpr_avl_add(avl, box(872), box(1097), nullptr); - avl = remove_int(avl, 543); - avl = remove_int(avl, 314); - avl = remove_int(avl, 443); - avl = gpr_avl_add(avl, box(533), box(1101), nullptr); - avl = remove_int(avl, 881); - avl = remove_int(avl, 269); - avl = remove_int(avl, 940); - avl = remove_int(avl, 909); - avl = remove_int(avl, 197); - avl = remove_int(avl, 773); - avl = remove_int(avl, 790); - avl = remove_int(avl, 345); - avl = gpr_avl_add(avl, box(965), box(1110), nullptr); - avl = remove_int(avl, 622); - avl = gpr_avl_add(avl, box(352), box(1112), nullptr); - avl = remove_int(avl, 182); - avl = gpr_avl_add(avl, box(534), box(1114), nullptr); - avl = gpr_avl_add(avl, box(97), box(1115), nullptr); - avl = gpr_avl_add(avl, box(198), box(1116), nullptr); - avl = remove_int(avl, 750); - avl = gpr_avl_add(avl, box(98), box(1118), nullptr); - avl = remove_int(avl, 943); - avl = gpr_avl_add(avl, box(254), box(1120), nullptr); - avl = gpr_avl_add(avl, box(30), box(1121), nullptr); - avl = remove_int(avl, 14); - avl = remove_int(avl, 475); - avl = remove_int(avl, 82); - avl = gpr_avl_add(avl, box(789), box(1125), nullptr); - avl = gpr_avl_add(avl, box(402), box(1126), nullptr); - avl = remove_int(avl, 1019); - avl = gpr_avl_add(avl, box(858), box(1128), nullptr); - avl = gpr_avl_add(avl, box(625), box(1129), nullptr); - avl = remove_int(avl, 675); - avl = remove_int(avl, 323); - avl = gpr_avl_add(avl, box(329), box(1132), nullptr); - avl = remove_int(avl, 929); - avl = remove_int(avl, 44); - avl = gpr_avl_add(avl, box(443), box(1135), nullptr); - avl = gpr_avl_add(avl, box(653), box(1136), nullptr); - avl = gpr_avl_add(avl, box(750), box(1137), nullptr); - avl = gpr_avl_add(avl, box(252), box(1138), nullptr); - avl = gpr_avl_add(avl, box(449), box(1139), nullptr); - avl = remove_int(avl, 1022); - avl = remove_int(avl, 357); - avl = remove_int(avl, 602); - avl = remove_int(avl, 131); - avl = gpr_avl_add(avl, box(531), box(1144), nullptr); - avl = remove_int(avl, 806); - avl = gpr_avl_add(avl, box(455), box(1146), nullptr); - avl = remove_int(avl, 31); - avl = gpr_avl_add(avl, box(154), box(1148), nullptr); - avl = gpr_avl_add(avl, box(189), box(1149), nullptr); - avl = remove_int(avl, 786); - avl = gpr_avl_add(avl, box(496), box(1151), nullptr); - avl = gpr_avl_add(avl, box(81), box(1152), nullptr); - avl = gpr_avl_add(avl, box(59), box(1153), nullptr); - avl = remove_int(avl, 424); - avl = remove_int(avl, 668); - avl = gpr_avl_add(avl, box(723), box(1156), nullptr); - avl = gpr_avl_add(avl, box(822), box(1157), nullptr); - avl = gpr_avl_add(avl, box(354), box(1158), nullptr); - avl = remove_int(avl, 738); - avl = gpr_avl_add(avl, box(686), box(1160), nullptr); - avl = gpr_avl_add(avl, box(43), box(1161), nullptr); - avl = gpr_avl_add(avl, box(625), box(1162), nullptr); - avl = gpr_avl_add(avl, box(902), box(1163), nullptr); - avl = gpr_avl_add(avl, box(12), box(1164), nullptr); - avl = gpr_avl_add(avl, box(977), box(1165), nullptr); - avl = gpr_avl_add(avl, box(699), box(1166), nullptr); - avl = gpr_avl_add(avl, box(189), box(1167), nullptr); - avl = remove_int(avl, 672); - avl = remove_int(avl, 90); - avl = remove_int(avl, 757); - avl = remove_int(avl, 494); - avl = gpr_avl_add(avl, box(759), box(1172), nullptr); - avl = remove_int(avl, 758); - avl = remove_int(avl, 222); - avl = gpr_avl_add(avl, box(975), box(1175), nullptr); - avl = remove_int(avl, 993); - avl = gpr_avl_add(avl, box(2), box(1177), nullptr); - avl = gpr_avl_add(avl, box(70), box(1178), nullptr); - avl = remove_int(avl, 350); - avl = remove_int(avl, 972); - avl = remove_int(avl, 880); - avl = gpr_avl_add(avl, box(753), box(1182), nullptr); - avl = remove_int(avl, 404); - avl = gpr_avl_add(avl, box(294), box(1184), nullptr); - avl = remove_int(avl, 474); - avl = gpr_avl_add(avl, box(228), box(1186), nullptr); - avl = gpr_avl_add(avl, box(484), box(1187), nullptr); - avl = remove_int(avl, 238); - avl = remove_int(avl, 53); - avl = remove_int(avl, 691); - avl = gpr_avl_add(avl, box(345), box(1191), nullptr); - avl = remove_int(avl, 0); - avl = gpr_avl_add(avl, box(230), box(1193), nullptr); - avl = remove_int(avl, 227); - avl = remove_int(avl, 152); - avl = gpr_avl_add(avl, box(884), box(1196), nullptr); - avl = remove_int(avl, 823); - avl = remove_int(avl, 53); - avl = gpr_avl_add(avl, box(1015), box(1199), nullptr); - avl = gpr_avl_add(avl, box(697), box(1200), nullptr); - avl = gpr_avl_add(avl, box(376), box(1201), nullptr); - avl = remove_int(avl, 411); - avl = gpr_avl_add(avl, box(888), box(1203), nullptr); - avl = remove_int(avl, 55); - avl = gpr_avl_add(avl, box(85), box(1205), nullptr); - avl = remove_int(avl, 947); - avl = remove_int(avl, 382); - avl = remove_int(avl, 777); - avl = gpr_avl_add(avl, box(1017), box(1209), nullptr); - avl = gpr_avl_add(avl, box(169), box(1210), nullptr); - avl = gpr_avl_add(avl, box(156), box(1211), nullptr); - avl = remove_int(avl, 153); - avl = remove_int(avl, 642); - avl = remove_int(avl, 158); - avl = gpr_avl_add(avl, box(554), box(1215), nullptr); - avl = gpr_avl_add(avl, box(76), box(1216), nullptr); - avl = gpr_avl_add(avl, box(756), box(1217), nullptr); - avl = remove_int(avl, 767); - avl = remove_int(avl, 112); - avl = remove_int(avl, 539); - avl = remove_int(avl, 544); - avl = remove_int(avl, 628); - avl = remove_int(avl, 385); - avl = remove_int(avl, 514); - avl = remove_int(avl, 362); - avl = gpr_avl_add(avl, box(523), box(1226), nullptr); - avl = gpr_avl_add(avl, box(712), box(1227), nullptr); - avl = gpr_avl_add(avl, box(474), box(1228), nullptr); - avl = gpr_avl_add(avl, box(882), box(1229), nullptr); - avl = gpr_avl_add(avl, box(965), box(1230), nullptr); - avl = remove_int(avl, 464); - avl = gpr_avl_add(avl, box(319), box(1232), nullptr); - avl = gpr_avl_add(avl, box(504), box(1233), nullptr); - avl = remove_int(avl, 818); - avl = gpr_avl_add(avl, box(884), box(1235), nullptr); - avl = gpr_avl_add(avl, box(813), box(1236), nullptr); - avl = gpr_avl_add(avl, box(795), box(1237), nullptr); - avl = remove_int(avl, 306); - avl = gpr_avl_add(avl, box(799), box(1239), nullptr); - avl = remove_int(avl, 534); - avl = gpr_avl_add(avl, box(480), box(1241), nullptr); - avl = gpr_avl_add(avl, box(656), box(1242), nullptr); - avl = gpr_avl_add(avl, box(709), box(1243), nullptr); - avl = gpr_avl_add(avl, box(500), box(1244), nullptr); - avl = remove_int(avl, 740); - avl = gpr_avl_add(avl, box(980), box(1246), nullptr); - avl = gpr_avl_add(avl, box(458), box(1247), nullptr); - avl = remove_int(avl, 377); - avl = remove_int(avl, 338); - avl = gpr_avl_add(avl, box(554), box(1250), nullptr); - avl = gpr_avl_add(avl, box(504), box(1251), nullptr); - avl = gpr_avl_add(avl, box(603), box(1252), nullptr); - avl = gpr_avl_add(avl, box(761), box(1253), nullptr); - avl = remove_int(avl, 431); - avl = gpr_avl_add(avl, box(707), box(1255), nullptr); - avl = gpr_avl_add(avl, box(673), box(1256), nullptr); - avl = remove_int(avl, 998); - avl = remove_int(avl, 332); - avl = remove_int(avl, 413); - avl = remove_int(avl, 227); - avl = remove_int(avl, 249); - avl = remove_int(avl, 309); - avl = remove_int(avl, 459); - avl = gpr_avl_add(avl, box(645), box(1264), nullptr); - avl = remove_int(avl, 858); - avl = remove_int(avl, 997); - avl = gpr_avl_add(avl, box(519), box(1267), nullptr); - avl = remove_int(avl, 614); - avl = remove_int(avl, 462); - avl = remove_int(avl, 792); - avl = gpr_avl_add(avl, box(987), box(1271), nullptr); - avl = gpr_avl_add(avl, box(309), box(1272), nullptr); - avl = remove_int(avl, 747); - avl = gpr_avl_add(avl, box(621), box(1274), nullptr); - avl = gpr_avl_add(avl, box(450), box(1275), nullptr); - avl = remove_int(avl, 265); - avl = remove_int(avl, 8); - avl = remove_int(avl, 383); - avl = gpr_avl_add(avl, box(238), box(1279), nullptr); - avl = remove_int(avl, 241); - avl = gpr_avl_add(avl, box(180), box(1281), nullptr); - avl = gpr_avl_add(avl, box(411), box(1282), nullptr); - avl = gpr_avl_add(avl, box(791), box(1283), nullptr); - avl = gpr_avl_add(avl, box(955), box(1284), nullptr); - avl = remove_int(avl, 24); - avl = remove_int(avl, 375); - avl = gpr_avl_add(avl, box(140), box(1287), nullptr); - avl = remove_int(avl, 949); - avl = gpr_avl_add(avl, box(301), box(1289), nullptr); - avl = gpr_avl_add(avl, box(0), box(1290), nullptr); - avl = remove_int(avl, 371); - avl = remove_int(avl, 427); - avl = remove_int(avl, 841); - avl = remove_int(avl, 847); - avl = gpr_avl_add(avl, box(814), box(1295), nullptr); - avl = gpr_avl_add(avl, box(127), box(1296), nullptr); - avl = gpr_avl_add(avl, box(279), box(1297), nullptr); - avl = remove_int(avl, 669); - avl = remove_int(avl, 541); - avl = remove_int(avl, 275); - avl = remove_int(avl, 299); - avl = remove_int(avl, 552); - avl = gpr_avl_add(avl, box(310), box(1303), nullptr); - avl = gpr_avl_add(avl, box(304), box(1304), nullptr); - avl = gpr_avl_add(avl, box(1), box(1305), nullptr); - avl = gpr_avl_add(avl, box(339), box(1306), nullptr); - avl = remove_int(avl, 570); - avl = remove_int(avl, 752); - avl = remove_int(avl, 552); - avl = remove_int(avl, 442); - avl = remove_int(avl, 639); - avl = gpr_avl_add(avl, box(313), box(1312), nullptr); - avl = remove_int(avl, 85); - avl = gpr_avl_add(avl, box(964), box(1314), nullptr); - avl = gpr_avl_add(avl, box(559), box(1315), nullptr); - avl = remove_int(avl, 167); - avl = gpr_avl_add(avl, box(866), box(1317), nullptr); - avl = remove_int(avl, 275); - avl = gpr_avl_add(avl, box(173), box(1319), nullptr); - avl = gpr_avl_add(avl, box(765), box(1320), nullptr); - avl = remove_int(avl, 883); - avl = gpr_avl_add(avl, box(547), box(1322), nullptr); - avl = gpr_avl_add(avl, box(847), box(1323), nullptr); - avl = remove_int(avl, 817); - avl = remove_int(avl, 850); - avl = remove_int(avl, 718); - avl = gpr_avl_add(avl, box(806), box(1327), nullptr); - avl = gpr_avl_add(avl, box(360), box(1328), nullptr); - avl = remove_int(avl, 991); - avl = gpr_avl_add(avl, box(493), box(1330), nullptr); - avl = remove_int(avl, 516); - avl = gpr_avl_add(avl, box(361), box(1332), nullptr); - avl = remove_int(avl, 355); - avl = gpr_avl_add(avl, box(512), box(1334), nullptr); - avl = gpr_avl_add(avl, box(191), box(1335), nullptr); - avl = remove_int(avl, 703); - avl = gpr_avl_add(avl, box(333), box(1337), nullptr); - avl = remove_int(avl, 481); - avl = gpr_avl_add(avl, box(501), box(1339), nullptr); - avl = remove_int(avl, 532); - avl = remove_int(avl, 510); - avl = gpr_avl_add(avl, box(793), box(1342), nullptr); - avl = gpr_avl_add(avl, box(234), box(1343), nullptr); - avl = remove_int(avl, 159); - avl = remove_int(avl, 429); - avl = remove_int(avl, 728); - avl = remove_int(avl, 288); - avl = gpr_avl_add(avl, box(281), box(1348), nullptr); - avl = gpr_avl_add(avl, box(702), box(1349), nullptr); - avl = gpr_avl_add(avl, box(149), box(1350), nullptr); - avl = remove_int(avl, 22); - avl = remove_int(avl, 944); - avl = remove_int(avl, 55); - avl = remove_int(avl, 512); - avl = remove_int(avl, 676); - avl = remove_int(avl, 884); - avl = gpr_avl_add(avl, box(246), box(1357), nullptr); - avl = gpr_avl_add(avl, box(455), box(1358), nullptr); - avl = remove_int(avl, 782); - avl = remove_int(avl, 682); - avl = gpr_avl_add(avl, box(243), box(1361), nullptr); - avl = gpr_avl_add(avl, box(109), box(1362), nullptr); - avl = gpr_avl_add(avl, box(452), box(1363), nullptr); - avl = remove_int(avl, 151); - avl = gpr_avl_add(avl, box(159), box(1365), nullptr); - avl = remove_int(avl, 1023); - avl = gpr_avl_add(avl, box(129), box(1367), nullptr); - avl = gpr_avl_add(avl, box(537), box(1368), nullptr); - avl = remove_int(avl, 321); - avl = gpr_avl_add(avl, box(740), box(1370), nullptr); - avl = remove_int(avl, 45); - avl = remove_int(avl, 136); - avl = gpr_avl_add(avl, box(229), box(1373), nullptr); - avl = remove_int(avl, 772); - avl = gpr_avl_add(avl, box(181), box(1375), nullptr); - avl = remove_int(avl, 175); - avl = gpr_avl_add(avl, box(817), box(1377), nullptr); - avl = remove_int(avl, 956); - avl = gpr_avl_add(avl, box(675), box(1379), nullptr); - avl = gpr_avl_add(avl, box(375), box(1380), nullptr); - avl = remove_int(avl, 384); - avl = gpr_avl_add(avl, box(1016), box(1382), nullptr); - avl = remove_int(avl, 295); - avl = remove_int(avl, 697); - avl = remove_int(avl, 554); - avl = remove_int(avl, 590); - avl = remove_int(avl, 1014); - avl = gpr_avl_add(avl, box(890), box(1388), nullptr); - avl = gpr_avl_add(avl, box(293), box(1389), nullptr); - avl = remove_int(avl, 207); - avl = remove_int(avl, 46); - avl = gpr_avl_add(avl, box(899), box(1392), nullptr); - avl = gpr_avl_add(avl, box(666), box(1393), nullptr); - avl = gpr_avl_add(avl, box(85), box(1394), nullptr); - avl = gpr_avl_add(avl, box(914), box(1395), nullptr); - avl = gpr_avl_add(avl, box(128), box(1396), nullptr); - avl = gpr_avl_add(avl, box(835), box(1397), nullptr); - avl = gpr_avl_add(avl, box(787), box(1398), nullptr); - avl = gpr_avl_add(avl, box(649), box(1399), nullptr); - avl = gpr_avl_add(avl, box(723), box(1400), nullptr); - avl = remove_int(avl, 874); - avl = gpr_avl_add(avl, box(778), box(1402), nullptr); - avl = gpr_avl_add(avl, box(1015), box(1403), nullptr); - avl = gpr_avl_add(avl, box(59), box(1404), nullptr); - avl = gpr_avl_add(avl, box(259), box(1405), nullptr); - avl = gpr_avl_add(avl, box(758), box(1406), nullptr); - avl = remove_int(avl, 648); - avl = gpr_avl_add(avl, box(145), box(1408), nullptr); - avl = gpr_avl_add(avl, box(440), box(1409), nullptr); - avl = remove_int(avl, 608); - avl = remove_int(avl, 690); - avl = gpr_avl_add(avl, box(605), box(1412), nullptr); - avl = remove_int(avl, 856); - avl = remove_int(avl, 608); - avl = gpr_avl_add(avl, box(829), box(1415), nullptr); - avl = gpr_avl_add(avl, box(660), box(1416), nullptr); - avl = remove_int(avl, 596); - avl = gpr_avl_add(avl, box(519), box(1418), nullptr); - avl = gpr_avl_add(avl, box(35), box(1419), nullptr); - avl = gpr_avl_add(avl, box(871), box(1420), nullptr); - avl = remove_int(avl, 845); - avl = gpr_avl_add(avl, box(600), box(1422), nullptr); - avl = gpr_avl_add(avl, box(215), box(1423), nullptr); - avl = remove_int(avl, 761); - avl = gpr_avl_add(avl, box(975), box(1425), nullptr); - avl = remove_int(avl, 987); - avl = gpr_avl_add(avl, box(58), box(1427), nullptr); - avl = remove_int(avl, 119); - avl = gpr_avl_add(avl, box(937), box(1429), nullptr); - avl = gpr_avl_add(avl, box(372), box(1430), nullptr); - avl = gpr_avl_add(avl, box(11), box(1431), nullptr); - avl = gpr_avl_add(avl, box(398), box(1432), nullptr); - avl = gpr_avl_add(avl, box(423), box(1433), nullptr); - avl = remove_int(avl, 171); - avl = gpr_avl_add(avl, box(473), box(1435), nullptr); - avl = remove_int(avl, 752); - avl = remove_int(avl, 625); - avl = remove_int(avl, 764); - avl = remove_int(avl, 49); - avl = gpr_avl_add(avl, box(472), box(1440), nullptr); - avl = remove_int(avl, 847); - avl = remove_int(avl, 642); - avl = remove_int(avl, 1004); - avl = remove_int(avl, 795); - avl = remove_int(avl, 465); - avl = gpr_avl_add(avl, box(636), box(1446), nullptr); - avl = remove_int(avl, 152); - avl = gpr_avl_add(avl, box(61), box(1448), nullptr); - avl = remove_int(avl, 929); - avl = remove_int(avl, 9); - avl = gpr_avl_add(avl, box(251), box(1451), nullptr); - avl = gpr_avl_add(avl, box(672), box(1452), nullptr); - avl = gpr_avl_add(avl, box(66), box(1453), nullptr); - avl = remove_int(avl, 693); - avl = remove_int(avl, 914); - avl = remove_int(avl, 116); - avl = remove_int(avl, 577); - avl = gpr_avl_add(avl, box(618), box(1458), nullptr); - avl = gpr_avl_add(avl, box(495), box(1459), nullptr); - avl = remove_int(avl, 450); - avl = gpr_avl_add(avl, box(533), box(1461), nullptr); - avl = gpr_avl_add(avl, box(414), box(1462), nullptr); - avl = remove_int(avl, 74); - avl = remove_int(avl, 236); - avl = gpr_avl_add(avl, box(707), box(1465), nullptr); - avl = gpr_avl_add(avl, box(357), box(1466), nullptr); - avl = gpr_avl_add(avl, box(1007), box(1467), nullptr); - avl = gpr_avl_add(avl, box(811), box(1468), nullptr); - avl = gpr_avl_add(avl, box(418), box(1469), nullptr); - avl = gpr_avl_add(avl, box(164), box(1470), nullptr); - avl = gpr_avl_add(avl, box(622), box(1471), nullptr); - avl = remove_int(avl, 22); - avl = remove_int(avl, 14); - avl = remove_int(avl, 732); - avl = remove_int(avl, 7); - avl = remove_int(avl, 447); - avl = gpr_avl_add(avl, box(221), box(1477), nullptr); - avl = gpr_avl_add(avl, box(202), box(1478), nullptr); - avl = gpr_avl_add(avl, box(312), box(1479), nullptr); - avl = remove_int(avl, 274); - avl = gpr_avl_add(avl, box(684), box(1481), nullptr); - avl = gpr_avl_add(avl, box(954), box(1482), nullptr); - avl = gpr_avl_add(avl, box(637), box(1483), nullptr); - avl = remove_int(avl, 716); - avl = gpr_avl_add(avl, box(198), box(1485), nullptr); - avl = remove_int(avl, 340); - avl = remove_int(avl, 137); - avl = remove_int(avl, 995); - avl = remove_int(avl, 1004); - avl = gpr_avl_add(avl, box(661), box(1490), nullptr); - avl = gpr_avl_add(avl, box(862), box(1491), nullptr); - avl = remove_int(avl, 527); - avl = gpr_avl_add(avl, box(945), box(1493), nullptr); - avl = remove_int(avl, 355); - avl = remove_int(avl, 144); - avl = gpr_avl_add(avl, box(229), box(1496), nullptr); - avl = gpr_avl_add(avl, box(237), box(1497), nullptr); - avl = remove_int(avl, 471); - avl = remove_int(avl, 901); - avl = gpr_avl_add(avl, box(905), box(1500), nullptr); - avl = remove_int(avl, 19); - avl = remove_int(avl, 896); - avl = remove_int(avl, 585); - avl = remove_int(avl, 308); - avl = gpr_avl_add(avl, box(547), box(1505), nullptr); - avl = gpr_avl_add(avl, box(552), box(1506), nullptr); - avl = gpr_avl_add(avl, box(30), box(1507), nullptr); - avl = gpr_avl_add(avl, box(445), box(1508), nullptr); - avl = remove_int(avl, 785); - avl = remove_int(avl, 185); - avl = gpr_avl_add(avl, box(405), box(1511), nullptr); - avl = gpr_avl_add(avl, box(733), box(1512), nullptr); - avl = gpr_avl_add(avl, box(573), box(1513), nullptr); - avl = gpr_avl_add(avl, box(492), box(1514), nullptr); - avl = gpr_avl_add(avl, box(343), box(1515), nullptr); - avl = gpr_avl_add(avl, box(527), box(1516), nullptr); - avl = gpr_avl_add(avl, box(596), box(1517), nullptr); - avl = gpr_avl_add(avl, box(519), box(1518), nullptr); - avl = remove_int(avl, 243); - avl = remove_int(avl, 722); - avl = gpr_avl_add(avl, box(772), box(1521), nullptr); - avl = remove_int(avl, 152); - avl = remove_int(avl, 305); - avl = gpr_avl_add(avl, box(754), box(1524), nullptr); - avl = gpr_avl_add(avl, box(373), box(1525), nullptr); - avl = remove_int(avl, 995); - avl = gpr_avl_add(avl, box(329), box(1527), nullptr); - avl = remove_int(avl, 397); - avl = gpr_avl_add(avl, box(884), box(1529), nullptr); - avl = remove_int(avl, 329); - avl = remove_int(avl, 240); - avl = gpr_avl_add(avl, box(566), box(1532), nullptr); - avl = gpr_avl_add(avl, box(232), box(1533), nullptr); - avl = remove_int(avl, 993); - avl = gpr_avl_add(avl, box(888), box(1535), nullptr); - avl = remove_int(avl, 242); - avl = gpr_avl_add(avl, box(941), box(1537), nullptr); - avl = remove_int(avl, 415); - avl = gpr_avl_add(avl, box(992), box(1539), nullptr); - avl = remove_int(avl, 289); - avl = gpr_avl_add(avl, box(60), box(1541), nullptr); - avl = gpr_avl_add(avl, box(97), box(1542), nullptr); - avl = remove_int(avl, 965); - avl = remove_int(avl, 267); - avl = remove_int(avl, 360); - avl = gpr_avl_add(avl, box(5), box(1546), nullptr); - avl = remove_int(avl, 429); - avl = gpr_avl_add(avl, box(412), box(1548), nullptr); - avl = remove_int(avl, 632); - avl = remove_int(avl, 113); - avl = gpr_avl_add(avl, box(48), box(1551), nullptr); - avl = gpr_avl_add(avl, box(108), box(1552), nullptr); - avl = gpr_avl_add(avl, box(750), box(1553), nullptr); - avl = remove_int(avl, 188); - avl = gpr_avl_add(avl, box(668), box(1555), nullptr); - avl = remove_int(avl, 37); - avl = remove_int(avl, 737); - avl = gpr_avl_add(avl, box(93), box(1558), nullptr); - avl = gpr_avl_add(avl, box(628), box(1559), nullptr); - avl = gpr_avl_add(avl, box(480), box(1560), nullptr); - avl = remove_int(avl, 958); - avl = remove_int(avl, 565); - avl = remove_int(avl, 32); - avl = remove_int(avl, 1); - avl = remove_int(avl, 335); - avl = gpr_avl_add(avl, box(136), box(1566), nullptr); - avl = gpr_avl_add(avl, box(469), box(1567), nullptr); - avl = remove_int(avl, 349); - avl = gpr_avl_add(avl, box(768), box(1569), nullptr); - avl = gpr_avl_add(avl, box(915), box(1570), nullptr); - avl = remove_int(avl, 1014); - avl = gpr_avl_add(avl, box(117), box(1572), nullptr); - avl = remove_int(avl, 62); - avl = gpr_avl_add(avl, box(382), box(1574), nullptr); - avl = remove_int(avl, 571); - avl = gpr_avl_add(avl, box(655), box(1576), nullptr); - avl = gpr_avl_add(avl, box(323), box(1577), nullptr); - avl = remove_int(avl, 869); - avl = remove_int(avl, 151); - avl = gpr_avl_add(avl, box(1019), box(1580), nullptr); - avl = gpr_avl_add(avl, box(984), box(1581), nullptr); - avl = gpr_avl_add(avl, box(870), box(1582), nullptr); - avl = gpr_avl_add(avl, box(376), box(1583), nullptr); - avl = remove_int(avl, 625); - avl = gpr_avl_add(avl, box(733), box(1585), nullptr); - avl = remove_int(avl, 532); - avl = remove_int(avl, 444); - avl = gpr_avl_add(avl, box(428), box(1588), nullptr); - avl = gpr_avl_add(avl, box(860), box(1589), nullptr); - avl = gpr_avl_add(avl, box(173), box(1590), nullptr); - avl = remove_int(avl, 649); - avl = remove_int(avl, 913); - avl = remove_int(avl, 1); - avl = remove_int(avl, 304); - avl = gpr_avl_add(avl, box(604), box(1595), nullptr); - avl = gpr_avl_add(avl, box(639), box(1596), nullptr); - avl = remove_int(avl, 431); - avl = gpr_avl_add(avl, box(993), box(1598), nullptr); - avl = remove_int(avl, 681); - avl = remove_int(avl, 927); - avl = gpr_avl_add(avl, box(87), box(1601), nullptr); - avl = gpr_avl_add(avl, box(91), box(1602), nullptr); - avl = remove_int(avl, 61); - avl = remove_int(avl, 14); - avl = remove_int(avl, 305); - avl = remove_int(avl, 304); - avl = remove_int(avl, 1016); - avl = gpr_avl_add(avl, box(903), box(1608), nullptr); - avl = gpr_avl_add(avl, box(951), box(1609), nullptr); - avl = gpr_avl_add(avl, box(146), box(1610), nullptr); - avl = gpr_avl_add(avl, box(482), box(1611), nullptr); - avl = gpr_avl_add(avl, box(71), box(1612), nullptr); - avl = remove_int(avl, 246); - avl = remove_int(avl, 696); - avl = gpr_avl_add(avl, box(636), box(1615), nullptr); - avl = gpr_avl_add(avl, box(295), box(1616), nullptr); - avl = remove_int(avl, 11); - avl = remove_int(avl, 231); - avl = gpr_avl_add(avl, box(905), box(1619), nullptr); - avl = gpr_avl_add(avl, box(993), box(1620), nullptr); - avl = gpr_avl_add(avl, box(433), box(1621), nullptr); - avl = gpr_avl_add(avl, box(117), box(1622), nullptr); - avl = gpr_avl_add(avl, box(467), box(1623), nullptr); - avl = remove_int(avl, 419); - avl = gpr_avl_add(avl, box(179), box(1625), nullptr); - avl = remove_int(avl, 926); - avl = remove_int(avl, 326); - avl = gpr_avl_add(avl, box(551), box(1628), nullptr); - avl = remove_int(avl, 14); - avl = remove_int(avl, 476); - avl = remove_int(avl, 823); - avl = gpr_avl_add(avl, box(350), box(1632), nullptr); - avl = gpr_avl_add(avl, box(133), box(1633), nullptr); - avl = remove_int(avl, 906); - avl = gpr_avl_add(avl, box(827), box(1635), nullptr); - avl = gpr_avl_add(avl, box(201), box(1636), nullptr); - avl = remove_int(avl, 124); - avl = remove_int(avl, 662); - avl = gpr_avl_add(avl, box(314), box(1639), nullptr); - avl = gpr_avl_add(avl, box(986), box(1640), nullptr); - avl = gpr_avl_add(avl, box(622), box(1641), nullptr); - avl = remove_int(avl, 130); - avl = gpr_avl_add(avl, box(861), box(1643), nullptr); - avl = remove_int(avl, 497); - avl = remove_int(avl, 905); - avl = gpr_avl_add(avl, box(502), box(1646), nullptr); - avl = remove_int(avl, 721); - avl = gpr_avl_add(avl, box(514), box(1648), nullptr); - avl = gpr_avl_add(avl, box(410), box(1649), nullptr); - avl = remove_int(avl, 869); - avl = remove_int(avl, 247); - avl = gpr_avl_add(avl, box(450), box(1652), nullptr); - avl = remove_int(avl, 364); - avl = gpr_avl_add(avl, box(963), box(1654), nullptr); - avl = gpr_avl_add(avl, box(146), box(1655), nullptr); - avl = remove_int(avl, 147); - avl = remove_int(avl, 789); - avl = gpr_avl_add(avl, box(693), box(1658), nullptr); - avl = gpr_avl_add(avl, box(959), box(1659), nullptr); - avl = remove_int(avl, 478); - avl = gpr_avl_add(avl, box(116), box(1661), nullptr); - avl = gpr_avl_add(avl, box(520), box(1662), nullptr); - avl = gpr_avl_add(avl, box(809), box(1663), nullptr); - avl = gpr_avl_add(avl, box(667), box(1664), nullptr); - avl = gpr_avl_add(avl, box(406), box(1665), nullptr); - avl = remove_int(avl, 409); - avl = gpr_avl_add(avl, box(558), box(1667), nullptr); - avl = gpr_avl_add(avl, box(0), box(1668), nullptr); - avl = gpr_avl_add(avl, box(948), box(1669), nullptr); - avl = gpr_avl_add(avl, box(576), box(1670), nullptr); - avl = remove_int(avl, 864); - avl = remove_int(avl, 840); - avl = remove_int(avl, 1001); - avl = gpr_avl_add(avl, box(232), box(1674), nullptr); - avl = remove_int(avl, 676); - avl = remove_int(avl, 752); - avl = remove_int(avl, 667); - avl = remove_int(avl, 605); - avl = gpr_avl_add(avl, box(258), box(1679), nullptr); - avl = gpr_avl_add(avl, box(648), box(1680), nullptr); - avl = gpr_avl_add(avl, box(761), box(1681), nullptr); - avl = remove_int(avl, 293); - avl = remove_int(avl, 893); - avl = gpr_avl_add(avl, box(194), box(1684), nullptr); - avl = remove_int(avl, 233); - avl = gpr_avl_add(avl, box(888), box(1686), nullptr); - avl = remove_int(avl, 470); - avl = remove_int(avl, 703); - avl = remove_int(avl, 190); - avl = remove_int(avl, 359); - avl = gpr_avl_add(avl, box(621), box(1691), nullptr); - avl = remove_int(avl, 634); - avl = remove_int(avl, 335); - avl = gpr_avl_add(avl, box(718), box(1694), nullptr); - avl = gpr_avl_add(avl, box(463), box(1695), nullptr); - avl = gpr_avl_add(avl, box(233), box(1696), nullptr); - avl = remove_int(avl, 376); - avl = remove_int(avl, 496); - avl = remove_int(avl, 819); - avl = remove_int(avl, 38); - avl = remove_int(avl, 436); - avl = remove_int(avl, 102); - avl = gpr_avl_add(avl, box(607), box(1703), nullptr); - avl = remove_int(avl, 329); - avl = gpr_avl_add(avl, box(716), box(1705), nullptr); - avl = remove_int(avl, 639); - avl = remove_int(avl, 775); - avl = remove_int(avl, 578); - avl = remove_int(avl, 464); - avl = remove_int(avl, 679); - avl = remove_int(avl, 615); - avl = remove_int(avl, 104); - avl = gpr_avl_add(avl, box(414), box(1713), nullptr); - avl = gpr_avl_add(avl, box(212), box(1714), nullptr); - avl = gpr_avl_add(avl, box(266), box(1715), nullptr); - avl = gpr_avl_add(avl, box(238), box(1716), nullptr); - avl = remove_int(avl, 153); - avl = gpr_avl_add(avl, box(585), box(1718), nullptr); - avl = remove_int(avl, 121); - avl = gpr_avl_add(avl, box(534), box(1720), nullptr); - avl = remove_int(avl, 579); - avl = gpr_avl_add(avl, box(127), box(1722), nullptr); - avl = gpr_avl_add(avl, box(399), box(1723), nullptr); - avl = remove_int(avl, 417); - avl = gpr_avl_add(avl, box(978), box(1725), nullptr); - avl = gpr_avl_add(avl, box(768), box(1726), nullptr); - avl = remove_int(avl, 985); - avl = gpr_avl_add(avl, box(536), box(1728), nullptr); - avl = gpr_avl_add(avl, box(449), box(1729), nullptr); - avl = gpr_avl_add(avl, box(586), box(1730), nullptr); - avl = remove_int(avl, 998); - avl = remove_int(avl, 394); - avl = remove_int(avl, 141); - avl = gpr_avl_add(avl, box(889), box(1734), nullptr); - avl = gpr_avl_add(avl, box(871), box(1735), nullptr); - avl = gpr_avl_add(avl, box(76), box(1736), nullptr); - avl = gpr_avl_add(avl, box(549), box(1737), nullptr); - avl = gpr_avl_add(avl, box(757), box(1738), nullptr); - avl = remove_int(avl, 908); - avl = gpr_avl_add(avl, box(789), box(1740), nullptr); - avl = remove_int(avl, 224); - avl = gpr_avl_add(avl, box(407), box(1742), nullptr); - avl = gpr_avl_add(avl, box(381), box(1743), nullptr); - avl = gpr_avl_add(avl, box(561), box(1744), nullptr); - avl = gpr_avl_add(avl, box(667), box(1745), nullptr); - avl = gpr_avl_add(avl, box(522), box(1746), nullptr); - avl = gpr_avl_add(avl, box(948), box(1747), nullptr); - avl = remove_int(avl, 770); - avl = gpr_avl_add(avl, box(872), box(1749), nullptr); - avl = gpr_avl_add(avl, box(327), box(1750), nullptr); - avl = remove_int(avl, 10); - avl = gpr_avl_add(avl, box(122), box(1752), nullptr); - avl = remove_int(avl, 606); - avl = gpr_avl_add(avl, box(485), box(1754), nullptr); - avl = remove_int(avl, 6); - avl = gpr_avl_add(avl, box(329), box(1756), nullptr); - avl = gpr_avl_add(avl, box(783), box(1757), nullptr); - avl = remove_int(avl, 416); - avl = gpr_avl_add(avl, box(656), box(1759), nullptr); - avl = gpr_avl_add(avl, box(971), box(1760), nullptr); - avl = gpr_avl_add(avl, box(77), box(1761), nullptr); - avl = gpr_avl_add(avl, box(942), box(1762), nullptr); - avl = remove_int(avl, 361); - avl = gpr_avl_add(avl, box(66), box(1764), nullptr); - avl = gpr_avl_add(avl, box(299), box(1765), nullptr); - avl = gpr_avl_add(avl, box(929), box(1766), nullptr); - avl = gpr_avl_add(avl, box(797), box(1767), nullptr); - avl = remove_int(avl, 869); - avl = remove_int(avl, 907); - avl = gpr_avl_add(avl, box(870), box(1770), nullptr); - avl = remove_int(avl, 580); - avl = remove_int(avl, 120); - avl = gpr_avl_add(avl, box(913), box(1773), nullptr); - avl = remove_int(avl, 480); - avl = gpr_avl_add(avl, box(489), box(1775), nullptr); - avl = remove_int(avl, 845); - avl = gpr_avl_add(avl, box(896), box(1777), nullptr); - avl = remove_int(avl, 567); - avl = remove_int(avl, 427); - avl = gpr_avl_add(avl, box(443), box(1780), nullptr); - avl = gpr_avl_add(avl, box(3), box(1781), nullptr); - avl = remove_int(avl, 12); - avl = gpr_avl_add(avl, box(376), box(1783), nullptr); - avl = gpr_avl_add(avl, box(155), box(1784), nullptr); - avl = gpr_avl_add(avl, box(188), box(1785), nullptr); - avl = gpr_avl_add(avl, box(149), box(1786), nullptr); - avl = gpr_avl_add(avl, box(178), box(1787), nullptr); - avl = remove_int(avl, 84); - avl = gpr_avl_add(avl, box(805), box(1789), nullptr); - avl = gpr_avl_add(avl, box(612), box(1790), nullptr); - avl = remove_int(avl, 991); - avl = gpr_avl_add(avl, box(837), box(1792), nullptr); - avl = remove_int(avl, 173); - avl = remove_int(avl, 72); - avl = gpr_avl_add(avl, box(1014), box(1795), nullptr); - avl = remove_int(avl, 303); - avl = gpr_avl_add(avl, box(865), box(1797), nullptr); - avl = gpr_avl_add(avl, box(793), box(1798), nullptr); - avl = remove_int(avl, 173); - avl = remove_int(avl, 477); - avl = gpr_avl_add(avl, box(950), box(1801), nullptr); - avl = gpr_avl_add(avl, box(105), box(1802), nullptr); - avl = gpr_avl_add(avl, box(895), box(1803), nullptr); - avl = gpr_avl_add(avl, box(171), box(1804), nullptr); - avl = gpr_avl_add(avl, box(753), box(1805), nullptr); - avl = gpr_avl_add(avl, box(946), box(1806), nullptr); - avl = remove_int(avl, 194); - avl = remove_int(avl, 559); - avl = remove_int(avl, 116); - avl = gpr_avl_add(avl, box(968), box(1810), nullptr); - avl = remove_int(avl, 124); - avl = remove_int(avl, 99); - avl = gpr_avl_add(avl, box(563), box(1813), nullptr); - avl = remove_int(avl, 182); - avl = gpr_avl_add(avl, box(816), box(1815), nullptr); - avl = remove_int(avl, 73); - avl = remove_int(avl, 261); - avl = gpr_avl_add(avl, box(847), box(1818), nullptr); - avl = gpr_avl_add(avl, box(368), box(1819), nullptr); - avl = gpr_avl_add(avl, box(808), box(1820), nullptr); - avl = gpr_avl_add(avl, box(779), box(1821), nullptr); - avl = remove_int(avl, 818); - avl = gpr_avl_add(avl, box(466), box(1823), nullptr); - avl = remove_int(avl, 316); - avl = gpr_avl_add(avl, box(986), box(1825), nullptr); - avl = gpr_avl_add(avl, box(688), box(1826), nullptr); - avl = gpr_avl_add(avl, box(509), box(1827), nullptr); - avl = gpr_avl_add(avl, box(51), box(1828), nullptr); - avl = remove_int(avl, 655); - avl = remove_int(avl, 785); - avl = remove_int(avl, 893); - avl = gpr_avl_add(avl, box(167), box(1832), nullptr); - avl = remove_int(avl, 13); - avl = remove_int(avl, 263); - avl = gpr_avl_add(avl, box(1009), box(1835), nullptr); - avl = remove_int(avl, 480); - avl = remove_int(avl, 778); - avl = remove_int(avl, 713); - avl = remove_int(avl, 628); - avl = gpr_avl_add(avl, box(803), box(1840), nullptr); - avl = remove_int(avl, 267); - avl = gpr_avl_add(avl, box(676), box(1842), nullptr); - avl = gpr_avl_add(avl, box(231), box(1843), nullptr); - avl = gpr_avl_add(avl, box(824), box(1844), nullptr); - avl = remove_int(avl, 961); - avl = gpr_avl_add(avl, box(311), box(1846), nullptr); - avl = gpr_avl_add(avl, box(420), box(1847), nullptr); - avl = gpr_avl_add(avl, box(960), box(1848), nullptr); - avl = gpr_avl_add(avl, box(468), box(1849), nullptr); - avl = gpr_avl_add(avl, box(815), box(1850), nullptr); - avl = remove_int(avl, 247); - avl = remove_int(avl, 194); - avl = gpr_avl_add(avl, box(546), box(1853), nullptr); - avl = remove_int(avl, 222); - avl = remove_int(avl, 914); - avl = remove_int(avl, 741); - avl = gpr_avl_add(avl, box(470), box(1857), nullptr); - avl = gpr_avl_add(avl, box(933), box(1858), nullptr); - avl = gpr_avl_add(avl, box(97), box(1859), nullptr); - avl = remove_int(avl, 564); - avl = remove_int(avl, 295); - avl = gpr_avl_add(avl, box(864), box(1862), nullptr); - avl = remove_int(avl, 329); - avl = gpr_avl_add(avl, box(124), box(1864), nullptr); - avl = gpr_avl_add(avl, box(1000), box(1865), nullptr); - avl = gpr_avl_add(avl, box(228), box(1866), nullptr); - avl = gpr_avl_add(avl, box(187), box(1867), nullptr); - avl = remove_int(avl, 224); - avl = remove_int(avl, 306); - avl = remove_int(avl, 884); - avl = gpr_avl_add(avl, box(449), box(1871), nullptr); - avl = gpr_avl_add(avl, box(353), box(1872), nullptr); - avl = gpr_avl_add(avl, box(994), box(1873), nullptr); - avl = gpr_avl_add(avl, box(596), box(1874), nullptr); - avl = gpr_avl_add(avl, box(996), box(1875), nullptr); - avl = gpr_avl_add(avl, box(101), box(1876), nullptr); - avl = gpr_avl_add(avl, box(1012), box(1877), nullptr); - avl = gpr_avl_add(avl, box(982), box(1878), nullptr); - avl = gpr_avl_add(avl, box(742), box(1879), nullptr); - avl = remove_int(avl, 92); - avl = remove_int(avl, 1022); - avl = gpr_avl_add(avl, box(941), box(1882), nullptr); - avl = remove_int(avl, 742); - avl = remove_int(avl, 919); - avl = gpr_avl_add(avl, box(588), box(1885), nullptr); - avl = remove_int(avl, 221); - avl = gpr_avl_add(avl, box(356), box(1887), nullptr); - avl = gpr_avl_add(avl, box(932), box(1888), nullptr); - avl = remove_int(avl, 837); - avl = gpr_avl_add(avl, box(394), box(1890), nullptr); - avl = gpr_avl_add(avl, box(642), box(1891), nullptr); - avl = gpr_avl_add(avl, box(52), box(1892), nullptr); - avl = gpr_avl_add(avl, box(437), box(1893), nullptr); - avl = gpr_avl_add(avl, box(948), box(1894), nullptr); - avl = gpr_avl_add(avl, box(93), box(1895), nullptr); - avl = remove_int(avl, 873); - avl = remove_int(avl, 336); - avl = remove_int(avl, 277); - avl = remove_int(avl, 932); - avl = gpr_avl_add(avl, box(80), box(1900), nullptr); - avl = gpr_avl_add(avl, box(952), box(1901), nullptr); - avl = gpr_avl_add(avl, box(510), box(1902), nullptr); - avl = remove_int(avl, 876); - avl = remove_int(avl, 612); - avl = gpr_avl_add(avl, box(923), box(1905), nullptr); - avl = gpr_avl_add(avl, box(475), box(1906), nullptr); - avl = remove_int(avl, 478); - avl = remove_int(avl, 148); - avl = gpr_avl_add(avl, box(538), box(1909), nullptr); - avl = remove_int(avl, 47); - avl = gpr_avl_add(avl, box(89), box(1911), nullptr); - avl = remove_int(avl, 723); - avl = gpr_avl_add(avl, box(687), box(1913), nullptr); - avl = gpr_avl_add(avl, box(480), box(1914), nullptr); - avl = gpr_avl_add(avl, box(149), box(1915), nullptr); - avl = remove_int(avl, 68); - avl = remove_int(avl, 862); - avl = remove_int(avl, 363); - avl = gpr_avl_add(avl, box(996), box(1919), nullptr); - avl = remove_int(avl, 380); - avl = gpr_avl_add(avl, box(957), box(1921), nullptr); - avl = remove_int(avl, 413); - avl = gpr_avl_add(avl, box(360), box(1923), nullptr); - avl = gpr_avl_add(avl, box(304), box(1924), nullptr); - avl = gpr_avl_add(avl, box(634), box(1925), nullptr); - avl = gpr_avl_add(avl, box(506), box(1926), nullptr); - avl = remove_int(avl, 248); - avl = gpr_avl_add(avl, box(124), box(1928), nullptr); - avl = gpr_avl_add(avl, box(181), box(1929), nullptr); - avl = remove_int(avl, 507); - avl = gpr_avl_add(avl, box(141), box(1931), nullptr); - avl = remove_int(avl, 409); - avl = remove_int(avl, 129); - avl = remove_int(avl, 694); - avl = remove_int(avl, 723); - avl = gpr_avl_add(avl, box(998), box(1936), nullptr); - avl = gpr_avl_add(avl, box(906), box(1937), nullptr); - avl = gpr_avl_add(avl, box(44), box(1938), nullptr); - avl = remove_int(avl, 949); - avl = remove_int(avl, 117); - avl = gpr_avl_add(avl, box(700), box(1941), nullptr); - avl = gpr_avl_add(avl, box(258), box(1942), nullptr); - avl = remove_int(avl, 828); - avl = gpr_avl_add(avl, box(860), box(1944), nullptr); - avl = gpr_avl_add(avl, box(987), box(1945), nullptr); - avl = gpr_avl_add(avl, box(316), box(1946), nullptr); - avl = gpr_avl_add(avl, box(919), box(1947), nullptr); - avl = remove_int(avl, 84); - avl = gpr_avl_add(avl, box(473), box(1949), nullptr); - avl = remove_int(avl, 127); - avl = remove_int(avl, 829); - avl = remove_int(avl, 829); - avl = gpr_avl_add(avl, box(488), box(1953), nullptr); - avl = gpr_avl_add(avl, box(954), box(1954), nullptr); - avl = remove_int(avl, 198); - avl = remove_int(avl, 972); - avl = remove_int(avl, 670); - avl = gpr_avl_add(avl, box(822), box(1958), nullptr); - avl = remove_int(avl, 589); - avl = remove_int(avl, 459); - avl = gpr_avl_add(avl, box(1003), box(1961), nullptr); - avl = gpr_avl_add(avl, box(657), box(1962), nullptr); - avl = gpr_avl_add(avl, box(477), box(1963), nullptr); - avl = gpr_avl_add(avl, box(923), box(1964), nullptr); - avl = remove_int(avl, 496); - avl = remove_int(avl, 99); - avl = gpr_avl_add(avl, box(127), box(1967), nullptr); - avl = gpr_avl_add(avl, box(1013), box(1968), nullptr); - avl = gpr_avl_add(avl, box(778), box(1969), nullptr); - avl = remove_int(avl, 5); - avl = remove_int(avl, 990); - avl = remove_int(avl, 850); - avl = remove_int(avl, 160); - avl = remove_int(avl, 86); - avl = gpr_avl_add(avl, box(283), box(1975), nullptr); - avl = remove_int(avl, 278); - avl = remove_int(avl, 297); - avl = remove_int(avl, 137); - avl = remove_int(avl, 653); - avl = gpr_avl_add(avl, box(702), box(1980), nullptr); - avl = remove_int(avl, 63); - avl = remove_int(avl, 427); - avl = remove_int(avl, 706); - avl = remove_int(avl, 806); - avl = gpr_avl_add(avl, box(335), box(1985), nullptr); - avl = gpr_avl_add(avl, box(412), box(1986), nullptr); - avl = remove_int(avl, 766); - avl = remove_int(avl, 937); - avl = remove_int(avl, 886); - avl = remove_int(avl, 652); - avl = gpr_avl_add(avl, box(545), box(1991), nullptr); - avl = gpr_avl_add(avl, box(408), box(1992), nullptr); - avl = gpr_avl_add(avl, box(841), box(1993), nullptr); - avl = remove_int(avl, 593); - avl = gpr_avl_add(avl, box(582), box(1995), nullptr); - avl = gpr_avl_add(avl, box(597), box(1996), nullptr); - avl = remove_int(avl, 49); - avl = remove_int(avl, 835); - avl = gpr_avl_add(avl, box(417), box(1999), nullptr); - avl = gpr_avl_add(avl, box(191), box(2000), nullptr); - avl = remove_int(avl, 406); - avl = gpr_avl_add(avl, box(30), box(2002), nullptr); - avl = remove_int(avl, 841); - avl = remove_int(avl, 50); - avl = gpr_avl_add(avl, box(967), box(2005), nullptr); - avl = gpr_avl_add(avl, box(849), box(2006), nullptr); - avl = remove_int(avl, 608); - avl = gpr_avl_add(avl, box(306), box(2008), nullptr); - avl = remove_int(avl, 779); - avl = gpr_avl_add(avl, box(897), box(2010), nullptr); - avl = gpr_avl_add(avl, box(147), box(2011), nullptr); - avl = remove_int(avl, 982); - avl = gpr_avl_add(avl, box(470), box(2013), nullptr); - avl = remove_int(avl, 951); - avl = gpr_avl_add(avl, box(388), box(2015), nullptr); - avl = remove_int(avl, 616); - avl = remove_int(avl, 721); - avl = remove_int(avl, 942); - avl = remove_int(avl, 589); - avl = gpr_avl_add(avl, box(218), box(2020), nullptr); - avl = remove_int(avl, 671); - avl = gpr_avl_add(avl, box(1020), box(2022), nullptr); - avl = remove_int(avl, 277); - avl = gpr_avl_add(avl, box(681), box(2024), nullptr); - avl = gpr_avl_add(avl, box(179), box(2025), nullptr); - avl = gpr_avl_add(avl, box(370), box(2026), nullptr); - avl = gpr_avl_add(avl, box(0), box(2027), nullptr); - avl = remove_int(avl, 523); - avl = gpr_avl_add(avl, box(99), box(2029), nullptr); - avl = gpr_avl_add(avl, box(334), box(2030), nullptr); - avl = gpr_avl_add(avl, box(569), box(2031), nullptr); - avl = gpr_avl_add(avl, box(257), box(2032), nullptr); - avl = remove_int(avl, 572); - avl = gpr_avl_add(avl, box(805), box(2034), nullptr); - avl = gpr_avl_add(avl, box(143), box(2035), nullptr); - avl = gpr_avl_add(avl, box(670), box(2036), nullptr); - avl = remove_int(avl, 42); - avl = gpr_avl_add(avl, box(46), box(2038), nullptr); - avl = remove_int(avl, 970); - avl = gpr_avl_add(avl, box(353), box(2040), nullptr); - avl = remove_int(avl, 258); - avl = gpr_avl_add(avl, box(451), box(2042), nullptr); - avl = gpr_avl_add(avl, box(28), box(2043), nullptr); - avl = gpr_avl_add(avl, box(729), box(2044), nullptr); - avl = gpr_avl_add(avl, box(401), box(2045), nullptr); - avl = gpr_avl_add(avl, box(614), box(2046), nullptr); - avl = remove_int(avl, 990); - avl = remove_int(avl, 212); - avl = remove_int(avl, 22); - avl = remove_int(avl, 677); - avl = gpr_avl_add(avl, box(1016), box(2051), nullptr); - avl = gpr_avl_add(avl, box(980), box(2052), nullptr); - avl = gpr_avl_add(avl, box(990), box(2053), nullptr); - avl = gpr_avl_add(avl, box(355), box(2054), nullptr); - avl = remove_int(avl, 730); - avl = remove_int(avl, 37); - avl = gpr_avl_add(avl, box(407), box(2057), nullptr); - avl = gpr_avl_add(avl, box(222), box(2058), nullptr); - avl = gpr_avl_add(avl, box(439), box(2059), nullptr); - avl = gpr_avl_add(avl, box(563), box(2060), nullptr); - avl = remove_int(avl, 992); - avl = remove_int(avl, 786); - avl = gpr_avl_add(avl, box(1), box(2063), nullptr); - avl = gpr_avl_add(avl, box(473), box(2064), nullptr); - avl = gpr_avl_add(avl, box(992), box(2065), nullptr); - avl = remove_int(avl, 190); - avl = remove_int(avl, 450); - avl = remove_int(avl, 1020); - avl = remove_int(avl, 149); - avl = gpr_avl_add(avl, box(329), box(2070), nullptr); - avl = gpr_avl_add(avl, box(35), box(2071), nullptr); - avl = remove_int(avl, 843); - avl = gpr_avl_add(avl, box(855), box(2073), nullptr); - avl = remove_int(avl, 878); - avl = gpr_avl_add(avl, box(993), box(2075), nullptr); - avl = gpr_avl_add(avl, box(87), box(2076), nullptr); - avl = gpr_avl_add(avl, box(572), box(2077), nullptr); - avl = remove_int(avl, 896); - avl = gpr_avl_add(avl, box(849), box(2079), nullptr); - avl = remove_int(avl, 597); - avl = gpr_avl_add(avl, box(472), box(2081), nullptr); - avl = remove_int(avl, 778); - avl = remove_int(avl, 934); - avl = remove_int(avl, 314); - avl = gpr_avl_add(avl, box(101), box(2085), nullptr); - avl = remove_int(avl, 938); - avl = remove_int(avl, 1010); - avl = gpr_avl_add(avl, box(579), box(2088), nullptr); - avl = remove_int(avl, 798); - avl = remove_int(avl, 88); - avl = gpr_avl_add(avl, box(851), box(2091), nullptr); - avl = remove_int(avl, 705); - avl = gpr_avl_add(avl, box(26), box(2093), nullptr); - avl = remove_int(avl, 973); - avl = gpr_avl_add(avl, box(923), box(2095), nullptr); - avl = remove_int(avl, 668); - avl = gpr_avl_add(avl, box(310), box(2097), nullptr); - avl = gpr_avl_add(avl, box(269), box(2098), nullptr); - avl = remove_int(avl, 173); - avl = gpr_avl_add(avl, box(279), box(2100), nullptr); - avl = remove_int(avl, 203); - avl = gpr_avl_add(avl, box(411), box(2102), nullptr); - avl = remove_int(avl, 950); - avl = gpr_avl_add(avl, box(6), box(2104), nullptr); - avl = remove_int(avl, 400); - avl = remove_int(avl, 468); - avl = remove_int(avl, 271); - avl = gpr_avl_add(avl, box(627), box(2108), nullptr); - avl = remove_int(avl, 727); - avl = remove_int(avl, 148); - avl = remove_int(avl, 98); - avl = remove_int(avl, 997); - avl = remove_int(avl, 215); - avl = remove_int(avl, 628); - avl = remove_int(avl, 826); - avl = remove_int(avl, 664); - avl = gpr_avl_add(avl, box(76), box(2117), nullptr); - avl = remove_int(avl, 194); - avl = remove_int(avl, 18); - avl = gpr_avl_add(avl, box(727), box(2120), nullptr); - avl = remove_int(avl, 295); - avl = gpr_avl_add(avl, box(645), box(2122), nullptr); - avl = remove_int(avl, 321); - avl = remove_int(avl, 863); - avl = gpr_avl_add(avl, box(824), box(2125), nullptr); - avl = gpr_avl_add(avl, box(651), box(2126), nullptr); - avl = gpr_avl_add(avl, box(804), box(2127), nullptr); - avl = remove_int(avl, 307); - avl = gpr_avl_add(avl, box(867), box(2129), nullptr); - avl = remove_int(avl, 384); - avl = gpr_avl_add(avl, box(819), box(2131), nullptr); - avl = remove_int(avl, 674); - avl = gpr_avl_add(avl, box(76), box(2133), nullptr); - avl = remove_int(avl, 898); - avl = gpr_avl_add(avl, box(45), box(2135), nullptr); - avl = gpr_avl_add(avl, box(512), box(2136), nullptr); - avl = remove_int(avl, 773); - avl = remove_int(avl, 907); - avl = remove_int(avl, 382); - avl = remove_int(avl, 95); - avl = remove_int(avl, 734); - avl = remove_int(avl, 81); - avl = gpr_avl_add(avl, box(348), box(2143), nullptr); - avl = remove_int(avl, 509); - avl = remove_int(avl, 301); - avl = gpr_avl_add(avl, box(861), box(2146), nullptr); - avl = gpr_avl_add(avl, box(918), box(2147), nullptr); - avl = remove_int(avl, 992); - avl = gpr_avl_add(avl, box(356), box(2149), nullptr); - avl = remove_int(avl, 64); - avl = remove_int(avl, 444); - avl = remove_int(avl, 741); - avl = gpr_avl_add(avl, box(710), box(2153), nullptr); - avl = gpr_avl_add(avl, box(264), box(2154), nullptr); - avl = remove_int(avl, 347); - avl = remove_int(avl, 250); - avl = gpr_avl_add(avl, box(82), box(2157), nullptr); - avl = gpr_avl_add(avl, box(571), box(2158), nullptr); - avl = remove_int(avl, 721); - avl = remove_int(avl, 622); - avl = gpr_avl_add(avl, box(950), box(2161), nullptr); - avl = gpr_avl_add(avl, box(94), box(2162), nullptr); - avl = remove_int(avl, 970); - avl = gpr_avl_add(avl, box(815), box(2164), nullptr); - avl = remove_int(avl, 930); - avl = remove_int(avl, 703); - avl = gpr_avl_add(avl, box(432), box(2167), nullptr); - avl = remove_int(avl, 544); - avl = gpr_avl_add(avl, box(21), box(2169), nullptr); - avl = gpr_avl_add(avl, box(186), box(2170), nullptr); - avl = remove_int(avl, 143); - avl = gpr_avl_add(avl, box(425), box(2172), nullptr); - avl = remove_int(avl, 769); - avl = gpr_avl_add(avl, box(656), box(2174), nullptr); - avl = remove_int(avl, 29); - avl = gpr_avl_add(avl, box(464), box(2176), nullptr); - avl = remove_int(avl, 713); - avl = gpr_avl_add(avl, box(800), box(2178), nullptr); - avl = remove_int(avl, 621); - avl = gpr_avl_add(avl, box(962), box(2180), nullptr); - avl = remove_int(avl, 448); - avl = gpr_avl_add(avl, box(878), box(2182), nullptr); - avl = remove_int(avl, 39); - avl = remove_int(avl, 999); - avl = gpr_avl_add(avl, box(182), box(2185), nullptr); - avl = gpr_avl_add(avl, box(429), box(2186), nullptr); - avl = gpr_avl_add(avl, box(598), box(2187), nullptr); - avl = remove_int(avl, 551); - avl = gpr_avl_add(avl, box(827), box(2189), nullptr); - avl = gpr_avl_add(avl, box(809), box(2190), nullptr); - avl = remove_int(avl, 438); - avl = remove_int(avl, 811); - avl = gpr_avl_add(avl, box(808), box(2193), nullptr); - avl = gpr_avl_add(avl, box(788), box(2194), nullptr); - avl = remove_int(avl, 156); - avl = gpr_avl_add(avl, box(933), box(2196), nullptr); - avl = gpr_avl_add(avl, box(344), box(2197), nullptr); - avl = remove_int(avl, 460); - avl = gpr_avl_add(avl, box(161), box(2199), nullptr); - avl = gpr_avl_add(avl, box(444), box(2200), nullptr); - avl = remove_int(avl, 597); - avl = remove_int(avl, 668); - avl = gpr_avl_add(avl, box(703), box(2203), nullptr); - avl = remove_int(avl, 515); - avl = gpr_avl_add(avl, box(380), box(2205), nullptr); - avl = gpr_avl_add(avl, box(338), box(2206), nullptr); - avl = remove_int(avl, 550); - avl = remove_int(avl, 946); - avl = remove_int(avl, 714); - avl = remove_int(avl, 739); - avl = gpr_avl_add(avl, box(413), box(2211), nullptr); - avl = remove_int(avl, 450); - avl = gpr_avl_add(avl, box(411), box(2213), nullptr); - avl = gpr_avl_add(avl, box(117), box(2214), nullptr); - avl = gpr_avl_add(avl, box(322), box(2215), nullptr); - avl = gpr_avl_add(avl, box(915), box(2216), nullptr); - avl = gpr_avl_add(avl, box(410), box(2217), nullptr); - avl = gpr_avl_add(avl, box(66), box(2218), nullptr); - avl = remove_int(avl, 756); - avl = remove_int(avl, 596); - avl = gpr_avl_add(avl, box(882), box(2221), nullptr); - avl = gpr_avl_add(avl, box(930), box(2222), nullptr); - avl = gpr_avl_add(avl, box(36), box(2223), nullptr); - avl = remove_int(avl, 742); - avl = gpr_avl_add(avl, box(539), box(2225), nullptr); - avl = gpr_avl_add(avl, box(596), box(2226), nullptr); - avl = remove_int(avl, 82); - avl = remove_int(avl, 686); - avl = remove_int(avl, 933); - avl = remove_int(avl, 42); - avl = remove_int(avl, 340); - avl = gpr_avl_add(avl, box(126), box(2232), nullptr); - avl = gpr_avl_add(avl, box(493), box(2233), nullptr); - avl = gpr_avl_add(avl, box(839), box(2234), nullptr); - avl = remove_int(avl, 774); - avl = gpr_avl_add(avl, box(337), box(2236), nullptr); - avl = remove_int(avl, 322); - avl = gpr_avl_add(avl, box(16), box(2238), nullptr); - avl = remove_int(avl, 73); - avl = remove_int(avl, 85); - avl = remove_int(avl, 191); - avl = remove_int(avl, 541); - avl = gpr_avl_add(avl, box(704), box(2243), nullptr); - avl = remove_int(avl, 767); - avl = remove_int(avl, 1006); - avl = remove_int(avl, 844); - avl = remove_int(avl, 742); - avl = gpr_avl_add(avl, box(48), box(2248), nullptr); - avl = gpr_avl_add(avl, box(138), box(2249), nullptr); - avl = gpr_avl_add(avl, box(437), box(2250), nullptr); - avl = gpr_avl_add(avl, box(275), box(2251), nullptr); - avl = remove_int(avl, 520); - avl = gpr_avl_add(avl, box(1019), box(2253), nullptr); - avl = remove_int(avl, 955); - avl = gpr_avl_add(avl, box(270), box(2255), nullptr); - avl = remove_int(avl, 680); - avl = remove_int(avl, 698); - avl = gpr_avl_add(avl, box(735), box(2258), nullptr); - avl = gpr_avl_add(avl, box(400), box(2259), nullptr); - avl = remove_int(avl, 991); - avl = gpr_avl_add(avl, box(263), box(2261), nullptr); - avl = remove_int(avl, 704); - avl = gpr_avl_add(avl, box(757), box(2263), nullptr); - avl = remove_int(avl, 194); - avl = remove_int(avl, 616); - avl = remove_int(avl, 784); - avl = gpr_avl_add(avl, box(382), box(2267), nullptr); - avl = gpr_avl_add(avl, box(464), box(2268), nullptr); - avl = gpr_avl_add(avl, box(817), box(2269), nullptr); - avl = remove_int(avl, 445); - avl = gpr_avl_add(avl, box(412), box(2271), nullptr); - avl = remove_int(avl, 525); - avl = gpr_avl_add(avl, box(299), box(2273), nullptr); - avl = gpr_avl_add(avl, box(464), box(2274), nullptr); - avl = gpr_avl_add(avl, box(715), box(2275), nullptr); - avl = remove_int(avl, 58); - avl = remove_int(avl, 218); - avl = gpr_avl_add(avl, box(961), box(2278), nullptr); - avl = gpr_avl_add(avl, box(491), box(2279), nullptr); - avl = remove_int(avl, 846); - avl = gpr_avl_add(avl, box(762), box(2281), nullptr); - avl = remove_int(avl, 974); - avl = remove_int(avl, 887); - avl = gpr_avl_add(avl, box(498), box(2284), nullptr); - avl = remove_int(avl, 810); - avl = remove_int(avl, 743); - avl = remove_int(avl, 22); - avl = remove_int(avl, 284); - avl = gpr_avl_add(avl, box(482), box(2289), nullptr); - avl = gpr_avl_add(avl, box(1021), box(2290), nullptr); - avl = remove_int(avl, 155); - avl = remove_int(avl, 128); - avl = gpr_avl_add(avl, box(819), box(2293), nullptr); - avl = gpr_avl_add(avl, box(324), box(2294), nullptr); - avl = remove_int(avl, 196); - avl = remove_int(avl, 370); - avl = remove_int(avl, 753); - avl = remove_int(avl, 56); - avl = remove_int(avl, 735); - avl = gpr_avl_add(avl, box(272), box(2300), nullptr); - avl = gpr_avl_add(avl, box(474), box(2301), nullptr); - avl = gpr_avl_add(avl, box(719), box(2302), nullptr); - avl = gpr_avl_add(avl, box(236), box(2303), nullptr); - avl = remove_int(avl, 818); - avl = gpr_avl_add(avl, box(727), box(2305), nullptr); - avl = remove_int(avl, 892); - avl = remove_int(avl, 871); - avl = remove_int(avl, 231); - avl = gpr_avl_add(avl, box(62), box(2309), nullptr); - avl = gpr_avl_add(avl, box(953), box(2310), nullptr); - avl = remove_int(avl, 701); - avl = gpr_avl_add(avl, box(193), box(2312), nullptr); - avl = remove_int(avl, 619); - avl = remove_int(avl, 22); - avl = remove_int(avl, 804); - avl = remove_int(avl, 851); - avl = gpr_avl_add(avl, box(286), box(2317), nullptr); - avl = gpr_avl_add(avl, box(751), box(2318), nullptr); - avl = remove_int(avl, 525); - avl = gpr_avl_add(avl, box(217), box(2320), nullptr); - avl = remove_int(avl, 336); - avl = gpr_avl_add(avl, box(86), box(2322), nullptr); - avl = gpr_avl_add(avl, box(81), box(2323), nullptr); - avl = gpr_avl_add(avl, box(850), box(2324), nullptr); - avl = remove_int(avl, 872); - avl = gpr_avl_add(avl, box(402), box(2326), nullptr); - avl = gpr_avl_add(avl, box(54), box(2327), nullptr); - avl = gpr_avl_add(avl, box(980), box(2328), nullptr); - avl = gpr_avl_add(avl, box(845), box(2329), nullptr); - avl = remove_int(avl, 1004); - avl = remove_int(avl, 273); - avl = remove_int(avl, 879); - avl = gpr_avl_add(avl, box(354), box(2333), nullptr); - avl = gpr_avl_add(avl, box(58), box(2334), nullptr); - avl = gpr_avl_add(avl, box(127), box(2335), nullptr); - avl = remove_int(avl, 84); - avl = gpr_avl_add(avl, box(360), box(2337), nullptr); - avl = remove_int(avl, 648); - avl = remove_int(avl, 488); - avl = remove_int(avl, 585); - avl = remove_int(avl, 230); - avl = gpr_avl_add(avl, box(887), box(2342), nullptr); - avl = remove_int(avl, 558); - avl = remove_int(avl, 958); - avl = gpr_avl_add(avl, box(822), box(2345), nullptr); - avl = remove_int(avl, 1004); - avl = remove_int(avl, 747); - avl = gpr_avl_add(avl, box(631), box(2348), nullptr); - avl = gpr_avl_add(avl, box(442), box(2349), nullptr); - avl = remove_int(avl, 957); - avl = remove_int(avl, 964); - avl = gpr_avl_add(avl, box(10), box(2352), nullptr); - avl = remove_int(avl, 189); - avl = gpr_avl_add(avl, box(742), box(2354), nullptr); - avl = remove_int(avl, 108); - avl = gpr_avl_add(avl, box(1014), box(2356), nullptr); - avl = remove_int(avl, 266); - avl = remove_int(avl, 623); - avl = remove_int(avl, 697); - avl = gpr_avl_add(avl, box(180), box(2360), nullptr); - avl = remove_int(avl, 472); - avl = gpr_avl_add(avl, box(567), box(2362), nullptr); - avl = remove_int(avl, 1020); - avl = remove_int(avl, 273); - avl = gpr_avl_add(avl, box(864), box(2365), nullptr); - avl = gpr_avl_add(avl, box(1009), box(2366), nullptr); - avl = remove_int(avl, 224); - avl = remove_int(avl, 81); - avl = gpr_avl_add(avl, box(653), box(2369), nullptr); - avl = remove_int(avl, 67); - avl = remove_int(avl, 102); - avl = remove_int(avl, 76); - avl = remove_int(avl, 935); - avl = remove_int(avl, 169); - avl = remove_int(avl, 232); - avl = remove_int(avl, 79); - avl = gpr_avl_add(avl, box(509), box(2377), nullptr); - avl = remove_int(avl, 900); - avl = remove_int(avl, 822); - avl = remove_int(avl, 945); - avl = remove_int(avl, 356); - avl = gpr_avl_add(avl, box(443), box(2382), nullptr); - avl = gpr_avl_add(avl, box(925), box(2383), nullptr); - avl = remove_int(avl, 994); - avl = remove_int(avl, 324); - avl = gpr_avl_add(avl, box(291), box(2386), nullptr); - avl = remove_int(avl, 94); - avl = remove_int(avl, 795); - avl = remove_int(avl, 42); - avl = gpr_avl_add(avl, box(613), box(2390), nullptr); - avl = remove_int(avl, 289); - avl = gpr_avl_add(avl, box(980), box(2392), nullptr); - avl = remove_int(avl, 316); - avl = gpr_avl_add(avl, box(281), box(2394), nullptr); - avl = gpr_avl_add(avl, box(1006), box(2395), nullptr); - avl = remove_int(avl, 776); - avl = gpr_avl_add(avl, box(108), box(2397), nullptr); - avl = gpr_avl_add(avl, box(918), box(2398), nullptr); - avl = remove_int(avl, 721); - avl = remove_int(avl, 563); - avl = gpr_avl_add(avl, box(925), box(2401), nullptr); - avl = remove_int(avl, 448); - avl = remove_int(avl, 198); - avl = remove_int(avl, 1); - avl = gpr_avl_add(avl, box(160), box(2405), nullptr); - avl = remove_int(avl, 515); - avl = gpr_avl_add(avl, box(284), box(2407), nullptr); - avl = gpr_avl_add(avl, box(225), box(2408), nullptr); - avl = remove_int(avl, 304); - avl = gpr_avl_add(avl, box(714), box(2410), nullptr); - avl = gpr_avl_add(avl, box(708), box(2411), nullptr); - avl = gpr_avl_add(avl, box(624), box(2412), nullptr); - avl = remove_int(avl, 662); - avl = remove_int(avl, 825); - avl = remove_int(avl, 383); - avl = remove_int(avl, 381); - avl = gpr_avl_add(avl, box(194), box(2417), nullptr); - avl = remove_int(avl, 280); - avl = remove_int(avl, 25); - avl = remove_int(avl, 633); - avl = gpr_avl_add(avl, box(897), box(2421), nullptr); - avl = remove_int(avl, 636); - avl = remove_int(avl, 596); - avl = remove_int(avl, 757); - avl = remove_int(avl, 343); - avl = remove_int(avl, 162); - avl = remove_int(avl, 913); - avl = remove_int(avl, 843); - avl = remove_int(avl, 280); - avl = remove_int(avl, 911); - avl = gpr_avl_add(avl, box(1008), box(2431), nullptr); - avl = remove_int(avl, 948); - avl = remove_int(avl, 74); - avl = remove_int(avl, 571); - avl = gpr_avl_add(avl, box(486), box(2435), nullptr); - avl = gpr_avl_add(avl, box(285), box(2436), nullptr); - avl = remove_int(avl, 304); - avl = remove_int(avl, 516); - avl = gpr_avl_add(avl, box(758), box(2439), nullptr); - avl = gpr_avl_add(avl, box(776), box(2440), nullptr); - avl = remove_int(avl, 696); - avl = gpr_avl_add(avl, box(104), box(2442), nullptr); - avl = gpr_avl_add(avl, box(700), box(2443), nullptr); - avl = gpr_avl_add(avl, box(114), box(2444), nullptr); - avl = gpr_avl_add(avl, box(567), box(2445), nullptr); - avl = remove_int(avl, 620); - avl = gpr_avl_add(avl, box(270), box(2447), nullptr); - avl = remove_int(avl, 730); - avl = gpr_avl_add(avl, box(749), box(2449), nullptr); - avl = gpr_avl_add(avl, box(443), box(2450), nullptr); - avl = remove_int(avl, 457); - avl = gpr_avl_add(avl, box(571), box(2452), nullptr); - avl = gpr_avl_add(avl, box(626), box(2453), nullptr); - avl = remove_int(avl, 638); - avl = remove_int(avl, 313); - - gpr_avl_unref(avl, nullptr); -} - -static void test_stress(int amount_of_stress) { - int added[1024]; - int i, j; - int deletions = 0; - gpr_avl avl; - - unsigned seed = (unsigned)time(nullptr); - - gpr_log(GPR_DEBUG, "test_stress amount=%d seed=%u", amount_of_stress, seed); - - srand((unsigned)time(nullptr)); - avl = gpr_avl_create(&int_int_vtable); - - memset(added, 0, sizeof(added)); - - for (i = 1; deletions < amount_of_stress; i++) { - int idx = rand() % (int)GPR_ARRAY_SIZE(added); - GPR_ASSERT(i); - if (rand() < RAND_MAX / 2) { - added[idx] = i; - printf("avl = gpr_avl_add(avl, box(%d), box(%d), NULL); /* d=%d */\n", - idx, i, deletions); - avl = gpr_avl_add(avl, box(idx), box(i), nullptr); - } else { - deletions += (added[idx] != 0); - added[idx] = 0; - printf("avl = remove_int(avl, %d); /* d=%d */\n", idx, deletions); - avl = remove_int(avl, idx); - } - for (j = 0; j < (int)GPR_ARRAY_SIZE(added); j++) { - if (added[j] != 0) { - check_get(avl, j, added[j]); - } else { - check_negget(avl, j); - } - } - } - - gpr_avl_unref(avl, nullptr); -} - -int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); - - test_get(); - test_ll(); - test_lr(); - test_rr(); - test_rl(); - test_unbalanced(); - test_replace(); - test_remove(); - test_badcase1(); - test_badcase2(); - test_badcase3(); - test_stress(10); - - return 0; -} diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD index 6cec7feabc..77df1cc989 100644 --- a/test/core/surface/BUILD +++ b/test/core/surface/BUILD @@ -19,8 +19,8 @@ licenses(["notice"]) # Apache v2 grpc_package(name = "test/core/surface") grpc_cc_test( - name = "alarm_test", - srcs = ["alarm_test.cc"], + name = "grpc_byte_buffer_reader_test", + srcs = ["byte_buffer_reader_test.cc"], language = "C++", deps = [ "//:gpr", @@ -31,8 +31,8 @@ grpc_cc_test( ) grpc_cc_test( - name = "grpc_byte_buffer_reader_test", - srcs = ["byte_buffer_reader_test.cc"], + name = "channel_create_test", + srcs = ["channel_create_test.cc"], language = "C++", deps = [ "//:gpr", @@ -43,8 +43,8 @@ grpc_cc_test( ) grpc_cc_test( - name = "channel_create_test", - srcs = ["channel_create_test.cc"], + name = "grpc_completion_queue_test", + srcs = ["completion_queue_test.cc"], language = "C++", deps = [ "//:gpr", @@ -55,8 +55,8 @@ grpc_cc_test( ) grpc_cc_test( - name = "grpc_completion_queue_test", - srcs = ["completion_queue_test.cc"], + name = "completion_queue_threading_test", + srcs = ["completion_queue_threading_test.cc"], language = "C++", deps = [ "//:gpr", @@ -91,25 +91,26 @@ grpc_cc_test( ) grpc_cc_test( - name = "grpc_invalid_channel_args_test", - srcs = ["invalid_channel_args_test.cc"], + name = "lame_client_test", + srcs = ["lame_client_test.cc"], language = "C++", deps = [ "//:gpr", "//:grpc", + "//test/core/end2end:cq_verifier", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) grpc_cc_test( - name = "lame_client_test", - srcs = ["lame_client_test.cc"], + name = "num_external_connectivity_watchers_test", + srcs = ["num_external_connectivity_watchers_test.cc"], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/end2end:cq_verifier", + "//test/core/end2end:ssl_test_data", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], diff --git a/test/core/surface/alarm_test.cc b/test/core/surface/alarm_test.cc deleted file mode 100644 index 8950603b41..0000000000 --- a/test/core/surface/alarm_test.cc +++ /dev/null @@ -1,109 +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/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpc/support/useful.h> -#include "test/core/util/test_config.h" - -#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) - -static void* create_test_tag(void) { - static intptr_t i = 0; - return (void*)(++i); -} - -/* helper for tests to shutdown correctly and tersely */ -static void shutdown_and_destroy(grpc_completion_queue* cc) { - grpc_event ev; - grpc_completion_queue_shutdown(cc); - ev = - grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), nullptr); - GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN); - grpc_completion_queue_destroy(cc); -} - -static void test_alarm(void) { - grpc_completion_queue* cc; - - LOG_TEST("test_alarm"); - cc = grpc_completion_queue_create_for_next(nullptr); - { - /* regular expiry */ - grpc_event ev; - void* tag = create_test_tag(); - grpc_alarm* alarm = grpc_alarm_create(nullptr); - grpc_alarm_set(alarm, cc, grpc_timeout_seconds_to_deadline(1), tag, - nullptr); - - ev = grpc_completion_queue_next(cc, grpc_timeout_seconds_to_deadline(2), - nullptr); - GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); - GPR_ASSERT(ev.tag == tag); - GPR_ASSERT(ev.success); - grpc_alarm_destroy(alarm, nullptr); - } - { - /* cancellation */ - grpc_event ev; - void* tag = create_test_tag(); - grpc_alarm* alarm = grpc_alarm_create(nullptr); - grpc_alarm_set(alarm, cc, grpc_timeout_seconds_to_deadline(2), tag, - nullptr); - - grpc_alarm_cancel(alarm, nullptr); - ev = grpc_completion_queue_next(cc, grpc_timeout_seconds_to_deadline(1), - nullptr); - GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); - GPR_ASSERT(ev.tag == tag); - GPR_ASSERT(ev.success == 0); - grpc_alarm_destroy(alarm, nullptr); - } - { - /* alarm_destroy before cq_next */ - grpc_event ev; - void* tag = create_test_tag(); - grpc_alarm* alarm = grpc_alarm_create(nullptr); - grpc_alarm_set(alarm, cc, grpc_timeout_seconds_to_deadline(2), tag, - nullptr); - - grpc_alarm_destroy(alarm, nullptr); - ev = grpc_completion_queue_next(cc, grpc_timeout_seconds_to_deadline(1), - nullptr); - GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); - GPR_ASSERT(ev.tag == tag); - GPR_ASSERT(ev.success == 0); - } - { - /* alarm_destroy before set */ - grpc_alarm* alarm = grpc_alarm_create(nullptr); - grpc_alarm_destroy(alarm, nullptr); - } - - shutdown_and_destroy(cc); -} - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - grpc_init(); - test_alarm(); - grpc_shutdown(); - return 0; -} diff --git a/test/core/surface/byte_buffer_reader_test.cc b/test/core/surface/byte_buffer_reader_test.cc index 94a8615b3c..cff05caec1 100644 --- a/test/core/surface/byte_buffer_reader_test.cc +++ b/test/core/surface/byte_buffer_reader_test.cc @@ -23,10 +23,10 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> #include "src/core/lib/compression/message_compress.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" @@ -133,7 +133,10 @@ static void read_compressed_slice(grpc_compression_algorithm algorithm, grpc_slice_buffer_add(&sliceb_in, input_slice); /* takes ownership */ { grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(grpc_msg_compress(algorithm, &sliceb_in, &sliceb_out)); + GPR_ASSERT(grpc_msg_compress( + + grpc_compression_algorithm_to_message_compression_algorithm(algorithm), + &sliceb_in, &sliceb_out)); } buffer = grpc_raw_compressed_byte_buffer_create(sliceb_out.slices, @@ -202,8 +205,8 @@ static void test_readall(void) { LOG_TEST("test_readall"); - memset(lotsa_as, 'a', 512); - memset(lotsa_bs, 'b', 1024); + memset(lotsa_as, 'a', 512 * sizeof(lotsa_as[0])); + memset(lotsa_bs, 'b', 1024 * sizeof(lotsa_bs[0])); /* use slices large enough to overflow inlining */ slices[0] = grpc_slice_malloc(512); memcpy(GRPC_SLICE_START_PTR(slices[0]), lotsa_as, 512); @@ -237,8 +240,8 @@ static void test_byte_buffer_copy(void) { LOG_TEST("test_byte_buffer_copy"); - memset(lotsa_as, 'a', 512); - memset(lotsa_bs, 'b', 1024); + memset(lotsa_as, 'a', 512 * sizeof(lotsa_as[0])); + memset(lotsa_bs, 'b', 1024 * sizeof(lotsa_bs[0])); /* use slices large enough to overflow inlining */ slices[0] = grpc_slice_malloc(512); memcpy(GRPC_SLICE_START_PTR(slices[0]), lotsa_as, 512); @@ -265,7 +268,6 @@ static void test_byte_buffer_copy(void) { int main(int argc, char** argv) { grpc_test_init(argc, argv); - grpc_init(); test_read_one_slice(); test_read_one_slice_malloc(); test_read_none_compressed_slice(); @@ -275,6 +277,5 @@ int main(int argc, char** argv) { test_byte_buffer_from_reader(); test_byte_buffer_copy(); test_readall(); - grpc_shutdown(); return 0; } diff --git a/test/core/surface/channel_create_test.cc b/test/core/surface/channel_create_test.cc index 37247f89d0..56f4f602e8 100644 --- a/test/core/surface/channel_create_test.cc +++ b/test/core/surface/channel_create_test.cc @@ -29,8 +29,8 @@ void test_unknown_scheme_target(void) { grpc_channel* chan; /* avoid default prefix */ - grpc_resolver_registry_shutdown(); - grpc_resolver_registry_init(); + grpc_core::ResolverRegistry::Builder::ShutdownRegistry(); + grpc_core::ResolverRegistry::Builder::InitRegistry(); chan = grpc_insecure_channel_create("blah://blah", nullptr, nullptr); GPR_ASSERT(chan != nullptr); diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index fefbb3c185..68129146cc 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -21,7 +21,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" diff --git a/test/core/surface/completion_queue_threading_test.cc b/test/core/surface/completion_queue_threading_test.cc index 4a9e818b45..0b82803af6 100644 --- a/test/core/surface/completion_queue_threading_test.cc +++ b/test/core/surface/completion_queue_threading_test.cc @@ -20,9 +20,10 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" @@ -77,16 +78,14 @@ static void test_too_many_plucks(void) { grpc_completion_queue* cc; void* tags[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS]; grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; - gpr_thd_id thread_ids[GPR_ARRAY_SIZE(tags)]; + grpc_core::Thread threads[GPR_ARRAY_SIZE(tags)]; struct thread_state thread_states[GPR_ARRAY_SIZE(tags)]; - gpr_thd_options thread_options = gpr_thd_options_default(); grpc_core::ExecCtx exec_ctx; unsigned i, j; LOG_TEST("test_too_many_plucks"); cc = grpc_completion_queue_create_for_pluck(nullptr); - gpr_thd_options_set_joinable(&thread_options); for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { tags[i] = create_test_tag(); @@ -95,8 +94,9 @@ static void test_too_many_plucks(void) { } thread_states[i].cc = cc; thread_states[i].tag = tags[i]; - gpr_thd_new(thread_ids + i, "grpc_pluck_test", pluck_one, thread_states + i, - &thread_options); + threads[i] = + grpc_core::Thread("grpc_pluck_test", pluck_one, thread_states + i); + threads[i].Start(); } /* wait until all other threads are plucking */ @@ -112,8 +112,8 @@ static void test_too_many_plucks(void) { nullptr, &completions[i]); } - for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { - gpr_thd_join(thread_ids[i]); + for (auto& th : threads) { + th.Join(); } shutdown_and_destroy(cc); @@ -145,7 +145,7 @@ static void producer_thread(void* arg) { int i; gpr_log(GPR_INFO, "producer %d started", opt->id); - gpr_event_set(&opt->on_started, (void*)(intptr_t)1); + gpr_event_set(&opt->on_started, (void*)static_cast<intptr_t>(1)); GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time())); gpr_log(GPR_INFO, "producer %d phase 1", opt->id); @@ -154,13 +154,13 @@ static void producer_thread(void* arg) { } gpr_log(GPR_INFO, "producer %d phase 1 done", opt->id); - gpr_event_set(&opt->on_phase1_done, (void*)(intptr_t)1); + gpr_event_set(&opt->on_phase1_done, (void*)static_cast<intptr_t>(1)); GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time())); gpr_log(GPR_INFO, "producer %d phase 2", opt->id); for (i = 0; i < TEST_THREAD_EVENTS; i++) { grpc_core::ExecCtx exec_ctx; - grpc_cq_end_op(opt->cc, (void*)(intptr_t)1, GRPC_ERROR_NONE, + grpc_cq_end_op(opt->cc, (void*)static_cast<intptr_t>(1), GRPC_ERROR_NONE, free_completion, nullptr, static_cast<grpc_cq_completion*>( gpr_malloc(sizeof(grpc_cq_completion)))); @@ -168,7 +168,7 @@ static void producer_thread(void* arg) { } gpr_log(GPR_INFO, "producer %d phase 2 done", opt->id); - gpr_event_set(&opt->on_finished, (void*)(intptr_t)1); + gpr_event_set(&opt->on_finished, (void*)static_cast<intptr_t>(1)); } static void consumer_thread(void* arg) { @@ -176,13 +176,13 @@ static void consumer_thread(void* arg) { grpc_event ev; gpr_log(GPR_INFO, "consumer %d started", opt->id); - gpr_event_set(&opt->on_started, (void*)(intptr_t)1); + gpr_event_set(&opt->on_started, (void*)static_cast<intptr_t>(1)); GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time())); gpr_log(GPR_INFO, "consumer %d phase 1", opt->id); gpr_log(GPR_INFO, "consumer %d phase 1 done", opt->id); - gpr_event_set(&opt->on_phase1_done, (void*)(intptr_t)1); + gpr_event_set(&opt->on_phase1_done, (void*)static_cast<intptr_t>(1)); GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time())); gpr_log(GPR_INFO, "consumer %d phase 2", opt->id); @@ -196,7 +196,7 @@ static void consumer_thread(void* arg) { break; case GRPC_QUEUE_SHUTDOWN: gpr_log(GPR_INFO, "consumer %d phase 2 done", opt->id); - gpr_event_set(&opt->on_finished, (void*)(intptr_t)1); + gpr_event_set(&opt->on_finished, (void*)static_cast<intptr_t>(1)); return; case GRPC_QUEUE_TIMEOUT: gpr_log(GPR_ERROR, "Invalid timeout received"); @@ -219,8 +219,9 @@ static void test_threading(size_t producers, size_t consumers) { "test_threading", producers, consumers); /* start all threads: they will wait for phase1 */ + grpc_core::Thread* threads = static_cast<grpc_core::Thread*>( + gpr_malloc(sizeof(*threads) * (producers + consumers))); for (i = 0; i < producers + consumers; i++) { - gpr_thd_id id; gpr_event_init(&options[i].on_started); gpr_event_init(&options[i].on_phase1_done); gpr_event_init(&options[i].on_finished); @@ -229,17 +230,20 @@ static void test_threading(size_t producers, size_t consumers) { options[i].events_triggered = 0; options[i].cc = cc; options[i].id = optid++; - GPR_ASSERT(gpr_thd_new(&id, - i < producers ? "grpc_producer" : "grpc_consumer", - i < producers ? producer_thread : consumer_thread, - options + i, nullptr)); + + bool ok; + threads[i] = grpc_core::Thread( + i < producers ? "grpc_producer" : "grpc_consumer", + i < producers ? producer_thread : consumer_thread, options + i, &ok); + GPR_ASSERT(ok); + threads[i].Start(); gpr_event_wait(&options[i].on_started, ten_seconds_time()); } /* start phase1: producers will pre-declare all operations they will complete */ gpr_log(GPR_INFO, "start phase 1"); - gpr_event_set(&phase1, (void*)(intptr_t)1); + gpr_event_set(&phase1, (void*)static_cast<intptr_t>(1)); gpr_log(GPR_INFO, "wait phase 1"); for (i = 0; i < producers + consumers; i++) { @@ -249,7 +253,7 @@ static void test_threading(size_t producers, size_t consumers) { /* start phase2: operations will complete, and consumers will consume them */ gpr_log(GPR_INFO, "start phase 2"); - gpr_event_set(&phase2, (void*)(intptr_t)1); + gpr_event_set(&phase2, (void*)static_cast<intptr_t>(1)); /* in parallel, we shutdown the completion channel - all events should still be consumed */ @@ -265,6 +269,11 @@ static void test_threading(size_t producers, size_t consumers) { /* destroy the completion channel */ grpc_completion_queue_destroy(cc); + for (i = 0; i < producers + consumers; i++) { + threads[i].Join(); + } + gpr_free(threads); + /* verify that everything was produced and consumed */ for (i = 0; i < producers + consumers; i++) { if (i < producers) { diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc index 235d136376..fbc5ec4c54 100644 --- a/test/core/surface/concurrent_connectivity_test.cc +++ b/test/core/surface/concurrent_connectivity_test.cc @@ -29,8 +29,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/thd.h> +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -55,14 +55,14 @@ // it should never take longer that this to shutdown the server #define SERVER_SHUTDOWN_TIMEOUT 30000 -static void* tag(int n) { return (void*)(uintptr_t)n; } -static int detag(void* p) { return (int)(uintptr_t)p; } +static void* tag(int n) { return (void*)static_cast<uintptr_t>(n); } +static int detag(void* p) { return static_cast<int>((uintptr_t)p); } void create_loop_destroy(void* addr) { for (int i = 0; i < NUM_OUTER_LOOPS; ++i) { grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); - grpc_channel* chan = - grpc_insecure_channel_create((char*)addr, nullptr, nullptr); + grpc_channel* chan = grpc_insecure_channel_create(static_cast<char*>(addr), + nullptr, nullptr); for (int j = 0; j < NUM_INNER_LOOPS; ++j) { gpr_timespec later_time = @@ -94,7 +94,8 @@ struct server_thread_args { }; void server_thread(void* vargs) { - struct server_thread_args* args = (struct server_thread_args*)vargs; + struct server_thread_args* args = + static_cast<struct server_thread_args*>(vargs); grpc_event ev; gpr_timespec deadline = grpc_timeout_milliseconds_to_deadline(SERVER_SHUTDOWN_TIMEOUT); @@ -107,7 +108,8 @@ static void on_connect(void* vargs, grpc_endpoint* tcp, grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor) { gpr_free(acceptor); - struct server_thread_args* args = (struct server_thread_args*)vargs; + struct server_thread_args* args = + static_cast<struct server_thread_args*>(vargs); grpc_endpoint_shutdown(tcp, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connected")); grpc_endpoint_destroy(tcp); @@ -117,17 +119,18 @@ static void on_connect(void* vargs, grpc_endpoint* tcp, } void bad_server_thread(void* vargs) { - struct server_thread_args* args = (struct server_thread_args*)vargs; + struct server_thread_args* args = + static_cast<struct server_thread_args*>(vargs); grpc_core::ExecCtx exec_ctx; grpc_resolved_address resolved_addr; - struct sockaddr_storage* addr = (struct sockaddr_storage*)resolved_addr.addr; + grpc_sockaddr* addr = reinterpret_cast<grpc_sockaddr*>(resolved_addr.addr); int port; grpc_tcp_server* s; grpc_error* error = grpc_tcp_server_create(nullptr, nullptr, &s); GPR_ASSERT(error == GRPC_ERROR_NONE); memset(&resolved_addr, 0, sizeof(resolved_addr)); - addr->ss_family = AF_INET; + addr->sa_family = GRPC_AF_INET; error = grpc_tcp_server_add_port(s, &resolved_addr, &port); GPR_ASSERT(GRPC_LOG_IF_ERROR("grpc_tcp_server_add_port", error)); GPR_ASSERT(port > 0); @@ -168,73 +171,77 @@ int run_concurrent_connectivity_test() { grpc_init(); - gpr_thd_id threads[NUM_THREADS]; - gpr_thd_id server; - - char* localhost = gpr_strdup("localhost:54321"); - gpr_thd_options options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&options); - /* First round, no server */ - gpr_log(GPR_DEBUG, "Wave 1"); - for (size_t i = 0; i < NUM_THREADS; ++i) { - gpr_thd_new(&threads[i], "grpc_wave_1", create_loop_destroy, localhost, - &options); - } - for (size_t i = 0; i < NUM_THREADS; ++i) { - gpr_thd_join(threads[i]); + { + gpr_log(GPR_DEBUG, "Wave 1"); + char* localhost = gpr_strdup("localhost:54321"); + grpc_core::Thread threads[NUM_THREADS]; + for (auto& th : threads) { + th = grpc_core::Thread("grpc_wave_1", create_loop_destroy, localhost); + th.Start(); + } + for (auto& th : threads) { + th.Join(); + } + gpr_free(localhost); } - gpr_free(localhost); - /* Second round, actual grpc server */ - gpr_log(GPR_DEBUG, "Wave 2"); - int port = grpc_pick_unused_port_or_die(); - gpr_asprintf(&args.addr, "localhost:%d", port); - args.server = grpc_server_create(nullptr, nullptr); - grpc_server_add_insecure_http2_port(args.server, args.addr); - args.cq = grpc_completion_queue_create_for_next(nullptr); - grpc_server_register_completion_queue(args.server, args.cq, nullptr); - grpc_server_start(args.server); - gpr_thd_new(&server, "grpc_wave_2_server", server_thread, &args, &options); - - for (size_t i = 0; i < NUM_THREADS; ++i) { - gpr_thd_new(&threads[i], "grpc_wave_2", create_loop_destroy, args.addr, - &options); - } - for (size_t i = 0; i < NUM_THREADS; ++i) { - gpr_thd_join(threads[i]); - } - grpc_server_shutdown_and_notify(args.server, args.cq, tag(0xd1e)); - - gpr_thd_join(server); - grpc_server_destroy(args.server); - grpc_completion_queue_destroy(args.cq); - gpr_free(args.addr); - - /* Third round, bogus tcp server */ - gpr_log(GPR_DEBUG, "Wave 3"); - args.pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); - grpc_pollset_init(args.pollset, &args.mu); - gpr_event_init(&args.ready); - gpr_thd_new(&server, "grpc_wave_3_server", bad_server_thread, &args, - &options); - gpr_event_wait(&args.ready, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - - for (size_t i = 0; i < NUM_THREADS; ++i) { - gpr_thd_new(&threads[i], "grpc_wave_3", create_loop_destroy, args.addr, - &options); - } - for (size_t i = 0; i < NUM_THREADS; ++i) { - gpr_thd_join(threads[i]); + { + /* Second round, actual grpc server */ + gpr_log(GPR_DEBUG, "Wave 2"); + int port = grpc_pick_unused_port_or_die(); + gpr_asprintf(&args.addr, "localhost:%d", port); + args.server = grpc_server_create(nullptr, nullptr); + grpc_server_add_insecure_http2_port(args.server, args.addr); + args.cq = grpc_completion_queue_create_for_next(nullptr); + grpc_server_register_completion_queue(args.server, args.cq, nullptr); + grpc_server_start(args.server); + grpc_core::Thread server2("grpc_wave_2_server", server_thread, &args); + server2.Start(); + + grpc_core::Thread threads[NUM_THREADS]; + for (auto& th : threads) { + th = grpc_core::Thread("grpc_wave_2", create_loop_destroy, args.addr); + th.Start(); + } + for (auto& th : threads) { + th.Join(); + } + grpc_server_shutdown_and_notify(args.server, args.cq, tag(0xd1e)); + + server2.Join(); + grpc_server_destroy(args.server); + grpc_completion_queue_destroy(args.cq); + gpr_free(args.addr); } - gpr_atm_rel_store(&args.stop, 1); - gpr_thd_join(server); { - grpc_core::ExecCtx exec_ctx; - grpc_pollset_shutdown( - args.pollset, GRPC_CLOSURE_CREATE(done_pollset_shutdown, args.pollset, - grpc_schedule_on_exec_ctx)); + /* Third round, bogus tcp server */ + gpr_log(GPR_DEBUG, "Wave 3"); + args.pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); + grpc_pollset_init(args.pollset, &args.mu); + gpr_event_init(&args.ready); + grpc_core::Thread server3("grpc_wave_3_server", bad_server_thread, &args); + server3.Start(); + gpr_event_wait(&args.ready, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + + grpc_core::Thread threads[NUM_THREADS]; + for (auto& th : threads) { + th = grpc_core::Thread("grpc_wave_3", create_loop_destroy, args.addr); + th.Start(); + } + for (auto& th : threads) { + th.Join(); + } + + gpr_atm_rel_store(&args.stop, 1); + server3.Join(); + { + grpc_core::ExecCtx exec_ctx; + grpc_pollset_shutdown( + args.pollset, GRPC_CLOSURE_CREATE(done_pollset_shutdown, args.pollset, + grpc_schedule_on_exec_ctx)); + } } grpc_shutdown(); @@ -244,8 +251,8 @@ int run_concurrent_connectivity_test() { void watches_with_short_timeouts(void* addr) { for (int i = 0; i < NUM_OUTER_LOOPS_SHORT_TIMEOUTS; ++i) { grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); - grpc_channel* chan = - grpc_insecure_channel_create((char*)addr, nullptr, nullptr); + grpc_channel* chan = grpc_insecure_channel_create(static_cast<char*>(addr), + nullptr, nullptr); for (int j = 0; j < NUM_INNER_LOOPS_SHORT_TIMEOUTS; ++j) { gpr_timespec later_time = @@ -274,18 +281,17 @@ void watches_with_short_timeouts(void* addr) { int run_concurrent_watches_with_short_timeouts_test() { grpc_init(); - gpr_thd_id threads[NUM_THREADS]; + grpc_core::Thread threads[NUM_THREADS]; char* localhost = gpr_strdup("localhost:54321"); - gpr_thd_options options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&options); - for (size_t i = 0; i < NUM_THREADS; ++i) { - gpr_thd_new(&threads[i], "grpc_short_watches", watches_with_short_timeouts, - localhost, &options); + for (auto& th : threads) { + th = grpc_core::Thread("grpc_short_watches", watches_with_short_timeouts, + localhost); + th.Start(); } - for (size_t i = 0; i < NUM_THREADS; ++i) { - gpr_thd_join(threads[i]); + for (auto& th : threads) { + th.Join(); } gpr_free(localhost); diff --git a/test/core/surface/invalid_channel_args_test.cc b/test/core/surface/invalid_channel_args_test.cc deleted file mode 100644 index 7c5f1f0352..0000000000 --- a/test/core/surface/invalid_channel_args_test.cc +++ /dev/null @@ -1,137 +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/grpc.h> -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include "test/core/util/test_config.h" - -static char* g_last_log_error_message = nullptr; -static const char* g_file_name = "channel.cc"; - -static int ends_with(const char* src, const char* suffix) { - size_t src_len = strlen(src); - size_t suffix_len = strlen(suffix); - if (src_len < suffix_len) { - return 0; - } - return strcmp(src + src_len - suffix_len, suffix) == 0; -} - -static void log_error_sink(gpr_log_func_args* args) { - if (args->severity == GPR_LOG_SEVERITY_ERROR && - ends_with(args->file, g_file_name)) { - g_last_log_error_message = gpr_strdup(args->message); - } -} - -static void verify_last_error(const char* message) { - if (message == nullptr) { - GPR_ASSERT(g_last_log_error_message == nullptr); - return; - } - GPR_ASSERT(strcmp(message, g_last_log_error_message) == 0); - gpr_free(g_last_log_error_message); - g_last_log_error_message = nullptr; -} - -static char* compose_error_string(const char* key, const char* message) { - char* ret; - gpr_asprintf(&ret, "%s%s", key, message); - return ret; -} - -static void one_test(grpc_channel_args* args, char* expected_error_message) { - grpc_channel* chan = - grpc_insecure_channel_create("nonexistant:54321", args, nullptr); - verify_last_error(expected_error_message); - gpr_free(expected_error_message); - grpc_channel_destroy(chan); -} - -static void test_no_error_message(void) { one_test(nullptr, nullptr); } - -static void test_default_authority_type(void) { - grpc_arg client_arg; - grpc_channel_args client_args; - char* expected_error_message; - - client_arg.type = GRPC_ARG_INTEGER; - client_arg.key = const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY); - client_arg.value.integer = 0; - - client_args.num_args = 1; - client_args.args = &client_arg; - expected_error_message = compose_error_string( - GRPC_ARG_DEFAULT_AUTHORITY, " ignored: it must be a string"); - one_test(&client_args, expected_error_message); -} - -static void test_ssl_name_override_type(void) { - grpc_arg client_arg; - grpc_channel_args client_args; - char* expected_error_message; - - client_arg.type = GRPC_ARG_INTEGER; - client_arg.key = const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); - client_arg.value.integer = 0; - - client_args.num_args = 1; - client_args.args = &client_arg; - expected_error_message = compose_error_string( - GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, " ignored: it must be a string"); - one_test(&client_args, expected_error_message); -} - -static void test_ssl_name_override_failed(void) { - grpc_arg client_arg[2]; - grpc_channel_args client_args; - char* expected_error_message; - - client_arg[0].type = GRPC_ARG_STRING; - client_arg[0].key = const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY); - client_arg[0].value.string = const_cast<char*>("default"); - client_arg[1].type = GRPC_ARG_STRING; - client_arg[1].key = const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); - client_arg[1].value.string = const_cast<char*>("ssl"); - - client_args.num_args = 2; - client_args.args = client_arg; - expected_error_message = - compose_error_string(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, - " ignored: default host already set some other way"); - one_test(&client_args, expected_error_message); -} - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - grpc_init(); - gpr_set_log_function(log_error_sink); - - test_no_error_message(); - test_default_authority_type(); - test_ssl_name_override_type(); - test_ssl_name_override_failed(); - - grpc_shutdown(); - - return 0; -} diff --git a/test/core/surface/lame_client_test.cc b/test/core/surface/lame_client_test.cc index 4bf40569e6..fac5ca8f7f 100644 --- a/test/core/surface/lame_client_test.cc +++ b/test/core/surface/lame_client_test.cc @@ -112,7 +112,8 @@ int main(int argc, char** argv) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(1), nullptr); + error = grpc_call_start_batch(call, ops, static_cast<size_t>(op - ops), + tag(1), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); /* the call should immediately fail */ @@ -128,7 +129,8 @@ int main(int argc, char** argv) { op->flags = 0; op->reserved = nullptr; op++; - error = grpc_call_start_batch(call, ops, (size_t)(op - ops), tag(2), nullptr); + error = grpc_call_start_batch(call, ops, static_cast<size_t>(op - ops), + tag(2), nullptr); GPR_ASSERT(GRPC_CALL_OK == error); /* the call should immediately fail */ diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc index 9cdd299ae3..467deeeaec 100644 --- a/test/core/surface/num_external_connectivity_watchers_test.cc +++ b/test/core/surface/num_external_connectivity_watchers_test.cc @@ -19,11 +19,11 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 8d2384ba61..52a1b03998 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -29,7 +29,6 @@ #include <grpc/impl/codegen/byte_buffer_reader.h> #include <grpc/impl/codegen/compression_types.h> #include <grpc/impl/codegen/connectivity_state.h> -#include <grpc/impl/codegen/exec_ctx_fwd.h> #include <grpc/impl/codegen/fork.h> #include <grpc/impl/codegen/gpr_slice.h> #include <grpc/impl/codegen/gpr_types.h> @@ -47,36 +46,29 @@ #include <grpc/status.h> #include <grpc/support/alloc.h> #include <grpc/support/atm.h> -#include <grpc/support/avl.h> -#include <grpc/support/cmdline.h> #include <grpc/support/cpu.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/port_platform.h> #include <grpc/support/string_util.h> -#include <grpc/support/subprocess.h> #include <grpc/support/sync.h> #include <grpc/support/sync_custom.h> #include <grpc/support/sync_generic.h> -#include <grpc/support/thd.h> +#include <grpc/support/thd_id.h> #include <grpc/support/time.h> -#include <grpc/support/tls.h> -#include <grpc/support/useful.h> #include <grpc/support/workaround_list.h> #include <stdio.h> int main(int argc, char **argv) { + printf("%lx", (unsigned long) grpc_compression_algorithm_is_message); + printf("%lx", (unsigned long) grpc_compression_algorithm_is_stream); printf("%lx", (unsigned long) grpc_compression_algorithm_parse); printf("%lx", (unsigned long) grpc_compression_algorithm_name); - printf("%lx", (unsigned long) grpc_stream_compression_algorithm_name); printf("%lx", (unsigned long) grpc_compression_algorithm_for_level); - printf("%lx", (unsigned long) grpc_stream_compression_algorithm_for_level); printf("%lx", (unsigned long) grpc_compression_options_init); printf("%lx", (unsigned long) grpc_compression_options_enable_algorithm); printf("%lx", (unsigned long) grpc_compression_options_disable_algorithm); printf("%lx", (unsigned long) grpc_compression_options_is_algorithm_enabled); - printf("%lx", (unsigned long) grpc_compression_options_is_stream_compression_algorithm_enabled); printf("%lx", (unsigned long) grpc_metadata_array_init); printf("%lx", (unsigned long) grpc_metadata_array_destroy); printf("%lx", (unsigned long) grpc_call_details_init); @@ -96,10 +88,6 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_completion_queue_destroy); printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_init); printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_flush); - printf("%lx", (unsigned long) grpc_alarm_create); - printf("%lx", (unsigned long) grpc_alarm_set); - printf("%lx", (unsigned long) grpc_alarm_cancel); - printf("%lx", (unsigned long) grpc_alarm_destroy); printf("%lx", (unsigned long) grpc_channel_check_connectivity_state); printf("%lx", (unsigned long) grpc_channel_num_external_connectivity_watchers); printf("%lx", (unsigned long) grpc_channel_watch_connectivity_state); @@ -118,6 +106,8 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_insecure_channel_create); printf("%lx", (unsigned long) grpc_lame_client_channel_create); printf("%lx", (unsigned long) grpc_channel_destroy); + printf("%lx", (unsigned long) grpc_channel_get_trace); + printf("%lx", (unsigned long) grpc_channel_get_uuid); printf("%lx", (unsigned long) grpc_call_cancel); printf("%lx", (unsigned long) grpc_call_cancel_with_status); printf("%lx", (unsigned long) grpc_call_ref); @@ -153,6 +143,9 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_auth_context_add_property); printf("%lx", (unsigned long) grpc_auth_context_add_cstring_property); printf("%lx", (unsigned long) grpc_auth_context_set_peer_identity_property_name); + printf("%lx", (unsigned long) grpc_ssl_session_cache_create_lru); + printf("%lx", (unsigned long) grpc_ssl_session_cache_destroy); + printf("%lx", (unsigned long) grpc_ssl_session_cache_create_channel_arg); printf("%lx", (unsigned long) grpc_channel_credentials_release); printf("%lx", (unsigned long) grpc_google_default_credentials_create); printf("%lx", (unsigned long) grpc_set_ssl_roots_override_callback); @@ -180,6 +173,12 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_server_add_secure_http2_port); printf("%lx", (unsigned long) grpc_call_set_credentials); printf("%lx", (unsigned long) grpc_server_credentials_set_auth_metadata_processor); + printf("%lx", (unsigned long) grpc_alts_credentials_client_options_create); + printf("%lx", (unsigned long) grpc_alts_credentials_server_options_create); + printf("%lx", (unsigned long) grpc_alts_credentials_client_options_add_target_service_account); + printf("%lx", (unsigned long) grpc_alts_credentials_options_destroy); + printf("%lx", (unsigned long) grpc_alts_credentials_create); + printf("%lx", (unsigned long) grpc_alts_server_credentials_create); printf("%lx", (unsigned long) grpc_raw_byte_buffer_create); printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create); printf("%lx", (unsigned long) grpc_byte_buffer_copy); @@ -246,40 +245,17 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) gpr_free_aligned); printf("%lx", (unsigned long) gpr_set_allocation_functions); printf("%lx", (unsigned long) gpr_get_allocation_functions); - printf("%lx", (unsigned long) gpr_avl_create); - printf("%lx", (unsigned long) gpr_avl_ref); - printf("%lx", (unsigned long) gpr_avl_unref); - printf("%lx", (unsigned long) gpr_avl_add); - printf("%lx", (unsigned long) gpr_avl_remove); - printf("%lx", (unsigned long) gpr_avl_get); - printf("%lx", (unsigned long) gpr_avl_maybe_get); - printf("%lx", (unsigned long) gpr_avl_is_empty); - printf("%lx", (unsigned long) gpr_cmdline_create); - printf("%lx", (unsigned long) gpr_cmdline_add_int); - printf("%lx", (unsigned long) gpr_cmdline_add_flag); - printf("%lx", (unsigned long) gpr_cmdline_add_string); - printf("%lx", (unsigned long) gpr_cmdline_on_extra_arg); - printf("%lx", (unsigned long) gpr_cmdline_set_survive_failure); - printf("%lx", (unsigned long) gpr_cmdline_parse); - printf("%lx", (unsigned long) gpr_cmdline_destroy); - printf("%lx", (unsigned long) gpr_cmdline_usage_string); printf("%lx", (unsigned long) gpr_cpu_num_cores); printf("%lx", (unsigned long) gpr_cpu_current_cpu); - printf("%lx", (unsigned long) gpr_join_host_port); - printf("%lx", (unsigned long) gpr_split_host_port); printf("%lx", (unsigned long) gpr_log_severity_string); printf("%lx", (unsigned long) gpr_log); + printf("%lx", (unsigned long) gpr_should_log); printf("%lx", (unsigned long) gpr_log_message); printf("%lx", (unsigned long) gpr_set_log_verbosity); printf("%lx", (unsigned long) gpr_log_verbosity_init); printf("%lx", (unsigned long) gpr_set_log_function); printf("%lx", (unsigned long) gpr_strdup); printf("%lx", (unsigned long) gpr_asprintf); - printf("%lx", (unsigned long) gpr_subprocess_binary_extension); - printf("%lx", (unsigned long) gpr_subprocess_create); - printf("%lx", (unsigned long) gpr_subprocess_destroy); - printf("%lx", (unsigned long) gpr_subprocess_join); - printf("%lx", (unsigned long) gpr_subprocess_interrupt); printf("%lx", (unsigned long) gpr_mu_init); printf("%lx", (unsigned long) gpr_mu_destroy); printf("%lx", (unsigned long) gpr_mu_lock); @@ -304,14 +280,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) gpr_stats_init); printf("%lx", (unsigned long) gpr_stats_inc); printf("%lx", (unsigned long) gpr_stats_read); - printf("%lx", (unsigned long) gpr_thd_new); - printf("%lx", (unsigned long) gpr_thd_options_default); - printf("%lx", (unsigned long) gpr_thd_options_set_detached); - printf("%lx", (unsigned long) gpr_thd_options_set_joinable); - printf("%lx", (unsigned long) gpr_thd_options_is_detached); - printf("%lx", (unsigned long) gpr_thd_options_is_joinable); printf("%lx", (unsigned long) gpr_thd_currentid); - printf("%lx", (unsigned long) gpr_thd_join); printf("%lx", (unsigned long) gpr_time_0); printf("%lx", (unsigned long) gpr_inf_future); printf("%lx", (unsigned long) gpr_inf_past); diff --git a/test/core/surface/secure_channel_create_test.cc b/test/core/surface/secure_channel_create_test.cc index fa22cd6873..06962179a2 100644 --- a/test/core/surface/secure_channel_create_test.cc +++ b/test/core/surface/secure_channel_create_test.cc @@ -23,13 +23,13 @@ #include <grpc/support/log.h> #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/core/lib/security/transport/security_connector.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/surface/channel.h" #include "test/core/util/test_config.h" void test_unknown_scheme_target(void) { - grpc_resolver_registry_shutdown(); - grpc_resolver_registry_init(); + grpc_core::ResolverRegistry::Builder::ShutdownRegistry(); + grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_channel_credentials* creds = grpc_fake_transport_security_credentials_create(); grpc_channel* chan = diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc index ac49bd9823..9aba4c499e 100644 --- a/test/core/surface/sequential_connectivity_test.cc +++ b/test/core/surface/sequential_connectivity_test.cc @@ -19,11 +19,11 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -67,10 +67,8 @@ static void run_test(const test_fixture* fixture) { grpc_server_start(server); server_thread_args sta = {server, server_cq}; - gpr_thd_id server_thread; - gpr_thd_options thdopt = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&thdopt); - gpr_thd_new(&server_thread, "grpc_server", server_thread_func, &sta, &thdopt); + grpc_core::Thread server_thread("grpc_server", server_thread_func, &sta); + server_thread.Start(); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_channel* channels[NUM_CONNECTIONS]; @@ -95,7 +93,7 @@ static void run_test(const test_fixture* fixture) { } grpc_server_shutdown_and_notify(server, server_cq, nullptr); - gpr_thd_join(server_thread); + server_thread.Join(); grpc_completion_queue_shutdown(server_cq); grpc_completion_queue_shutdown(cq); diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc index 96eaa6a7a9..fd8ab9cd3d 100644 --- a/test/core/surface/server_chttp2_test.cc +++ b/test/core/surface/server_chttp2_test.cc @@ -19,9 +19,10 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/time.h> + +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/tsi/fake_transport_security.h" @@ -36,6 +37,8 @@ void test_unparsable_target(void) { grpc_server_destroy(server); } +// GRPC_ARG_ALLOW_REUSEPORT isn't supported for custom servers +#ifndef GRPC_UV void test_add_same_port_twice() { grpc_arg a; a.type = GRPC_ARG_INTEGER; @@ -61,12 +64,15 @@ void test_add_same_port_twice() { grpc_server_destroy(server); grpc_completion_queue_destroy(cq); } +#endif int main(int argc, char** argv) { grpc_test_init(argc, argv); grpc_init(); test_unparsable_target(); +#ifndef GRPC_UV test_add_same_port_twice(); +#endif grpc_shutdown(); return 0; } diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc index 969b8cb11b..b4eabd8d4d 100644 --- a/test/core/surface/server_test.cc +++ b/test/core/surface/server_test.cc @@ -19,9 +19,10 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> + +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/util/port.h" @@ -68,6 +69,8 @@ void test_request_call_on_no_server_cq(void) { grpc_server_destroy(server); } +// GRPC_ARG_ALLOW_REUSEPORT isn't supported for custom servers +#ifndef GRPC_UV void test_bind_server_twice(void) { grpc_arg a; a.type = GRPC_ARG_INTEGER; @@ -99,6 +102,7 @@ void test_bind_server_twice(void) { grpc_completion_queue_destroy(cq); gpr_free(addr); } +#endif void test_bind_server_to_addr(const char* host, bool secure) { int port = grpc_pick_unused_port_or_die(); @@ -148,7 +152,9 @@ int main(int argc, char** argv) { grpc_init(); test_register_method_fail(); test_request_call_on_no_server_cq(); +#ifndef GRPC_UV test_bind_server_twice(); +#endif static const char* addrs[] = { "::1", "127.0.0.1", "::ffff:127.0.0.1", "localhost", "0.0.0.0", "::", diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD index b31d4ff899..84fb3a1421 100644 --- a/test/core/transport/BUILD +++ b/test/core/transport/BUILD @@ -43,6 +43,9 @@ grpc_cc_test( "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + external_deps = [ + "gtest", + ], ) grpc_cc_test( @@ -119,3 +122,15 @@ grpc_cc_test( "//test/core/util:grpc_test_util", ], ) + +grpc_cc_test( + name = "status_metadata_test", + srcs = ["status_metadata_test.cc"], + language = "C++", + deps = [ + "//:grpc", + ], + external_deps = [ + "gtest", + ], +) diff --git a/test/core/transport/bdp_estimator_test.cc b/test/core/transport/bdp_estimator_test.cc index 445823b628..c7e6b2bd84 100644 --- a/test/core/transport/bdp_estimator_test.cc +++ b/test/core/transport/bdp_estimator_test.cc @@ -22,11 +22,13 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> + #include <gtest/gtest.h> #include <limits.h> + +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/timer_manager.h" -#include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); diff --git a/test/core/transport/byte_stream_test.cc b/test/core/transport/byte_stream_test.cc index 2aab6e9262..df09637249 100644 --- a/test/core/transport/byte_stream_test.cc +++ b/test/core/transport/byte_stream_test.cc @@ -21,22 +21,25 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/util/test_config.h" +#include <gtest/gtest.h> + +namespace grpc_core { +namespace { + // -// grpc_slice_buffer_stream tests +// SliceBufferByteStream tests // -static void not_called_closure(void* arg, grpc_error* error) { - GPR_ASSERT(false); -} +void NotCalledClosure(void* arg, grpc_error* error) { GPR_ASSERT(false); } -static void test_slice_buffer_stream_basic(void) { - gpr_log(GPR_DEBUG, "test_slice_buffer_stream_basic"); +TEST(SliceBufferByteStream, Basic) { grpc_core::ExecCtx exec_ctx; // Create and populate slice buffer. grpc_slice_buffer buffer; @@ -49,28 +52,26 @@ static void test_slice_buffer_stream_basic(void) { grpc_slice_buffer_add(&buffer, input[i]); } // Create byte stream. - grpc_slice_buffer_stream stream; - grpc_slice_buffer_stream_init(&stream, &buffer, 0); - GPR_ASSERT(stream.base.length == 6); + SliceBufferByteStream stream(&buffer, 0); + grpc_slice_buffer_destroy_internal(&buffer); + EXPECT_EQ(6U, stream.length()); grpc_closure closure; - GRPC_CLOSURE_INIT(&closure, not_called_closure, nullptr, + GRPC_CLOSURE_INIT(&closure, NotCalledClosure, nullptr, grpc_schedule_on_exec_ctx); - // Read each slice. Note that next() always returns synchronously. + // Read each slice. Note that Next() always returns synchronously. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) { - GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure)); + ASSERT_TRUE(stream.Next(~(size_t)0, &closure)); grpc_slice output; - grpc_error* error = grpc_byte_stream_pull(&stream.base, &output); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_slice_eq(input[i], output)); + grpc_error* error = stream.Pull(&output); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE(grpc_slice_eq(input[i], output)); grpc_slice_unref_internal(output); } // Clean up. - grpc_byte_stream_destroy(&stream.base); - grpc_slice_buffer_destroy_internal(&buffer); + stream.Orphan(); } -static void test_slice_buffer_stream_shutdown(void) { - gpr_log(GPR_DEBUG, "test_slice_buffer_stream_shutdown"); +TEST(SliceBufferByteStream, Shutdown) { grpc_core::ExecCtx exec_ctx; // Create and populate slice buffer. grpc_slice_buffer buffer; @@ -83,40 +84,38 @@ static void test_slice_buffer_stream_shutdown(void) { grpc_slice_buffer_add(&buffer, input[i]); } // Create byte stream. - grpc_slice_buffer_stream stream; - grpc_slice_buffer_stream_init(&stream, &buffer, 0); - GPR_ASSERT(stream.base.length == 6); + SliceBufferByteStream stream(&buffer, 0); + grpc_slice_buffer_destroy_internal(&buffer); + EXPECT_EQ(6U, stream.length()); grpc_closure closure; - GRPC_CLOSURE_INIT(&closure, not_called_closure, nullptr, + GRPC_CLOSURE_INIT(&closure, NotCalledClosure, nullptr, grpc_schedule_on_exec_ctx); // Read the first slice. - GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure)); + ASSERT_TRUE(stream.Next(~(size_t)0, &closure)); grpc_slice output; - grpc_error* error = grpc_byte_stream_pull(&stream.base, &output); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_slice_eq(input[0], output)); + grpc_error* error = stream.Pull(&output); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE(grpc_slice_eq(input[0], output)); grpc_slice_unref_internal(output); // Now shutdown. grpc_error* shutdown_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("shutdown error"); - grpc_byte_stream_shutdown(&stream.base, GRPC_ERROR_REF(shutdown_error)); + stream.Shutdown(GRPC_ERROR_REF(shutdown_error)); // After shutdown, the next pull() should return the error. - GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure)); - error = grpc_byte_stream_pull(&stream.base, &output); - GPR_ASSERT(error == shutdown_error); + ASSERT_TRUE(stream.Next(~(size_t)0, &closure)); + error = stream.Pull(&output); + EXPECT_TRUE(error == shutdown_error); GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(shutdown_error); // Clean up. - grpc_byte_stream_destroy(&stream.base); - grpc_slice_buffer_destroy_internal(&buffer); + stream.Orphan(); } // -// grpc_caching_byte_stream tests +// CachingByteStream tests // -static void test_caching_byte_stream_basic(void) { - gpr_log(GPR_DEBUG, "test_caching_byte_stream_basic"); +TEST(CachingByteStream, Basic) { grpc_core::ExecCtx exec_ctx; // Create and populate slice buffer byte stream. grpc_slice_buffer buffer; @@ -128,34 +127,30 @@ static void test_caching_byte_stream_basic(void) { for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) { grpc_slice_buffer_add(&buffer, input[i]); } - grpc_slice_buffer_stream underlying_stream; - grpc_slice_buffer_stream_init(&underlying_stream, &buffer, 0); + SliceBufferByteStream underlying_stream(&buffer, 0); + grpc_slice_buffer_destroy_internal(&buffer); // Create cache and caching stream. - grpc_byte_stream_cache cache; - grpc_byte_stream_cache_init(&cache, &underlying_stream.base); - grpc_caching_byte_stream stream; - grpc_caching_byte_stream_init(&stream, &cache); + ByteStreamCache cache((OrphanablePtr<ByteStream>(&underlying_stream))); + ByteStreamCache::CachingByteStream stream(&cache); grpc_closure closure; - GRPC_CLOSURE_INIT(&closure, not_called_closure, nullptr, + GRPC_CLOSURE_INIT(&closure, NotCalledClosure, nullptr, grpc_schedule_on_exec_ctx); // Read each slice. Note that next() always returns synchronously, // because the underlying byte stream always does. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) { - GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure)); + ASSERT_TRUE(stream.Next(~(size_t)0, &closure)); grpc_slice output; - grpc_error* error = grpc_byte_stream_pull(&stream.base, &output); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_slice_eq(input[i], output)); + grpc_error* error = stream.Pull(&output); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE(grpc_slice_eq(input[i], output)); grpc_slice_unref_internal(output); } // Clean up. - grpc_byte_stream_destroy(&stream.base); - grpc_byte_stream_cache_destroy(&cache); - grpc_slice_buffer_destroy_internal(&buffer); + stream.Orphan(); + cache.Destroy(); } -static void test_caching_byte_stream_reset(void) { - gpr_log(GPR_DEBUG, "test_caching_byte_stream_reset"); +TEST(CachingByteStream, Reset) { grpc_core::ExecCtx exec_ctx; // Create and populate slice buffer byte stream. grpc_slice_buffer buffer; @@ -167,41 +162,37 @@ static void test_caching_byte_stream_reset(void) { for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) { grpc_slice_buffer_add(&buffer, input[i]); } - grpc_slice_buffer_stream underlying_stream; - grpc_slice_buffer_stream_init(&underlying_stream, &buffer, 0); + SliceBufferByteStream underlying_stream(&buffer, 0); + grpc_slice_buffer_destroy_internal(&buffer); // Create cache and caching stream. - grpc_byte_stream_cache cache; - grpc_byte_stream_cache_init(&cache, &underlying_stream.base); - grpc_caching_byte_stream stream; - grpc_caching_byte_stream_init(&stream, &cache); + ByteStreamCache cache((OrphanablePtr<ByteStream>(&underlying_stream))); + ByteStreamCache::CachingByteStream stream(&cache); grpc_closure closure; - GRPC_CLOSURE_INIT(&closure, not_called_closure, nullptr, + GRPC_CLOSURE_INIT(&closure, NotCalledClosure, nullptr, grpc_schedule_on_exec_ctx); // Read one slice. - GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure)); + ASSERT_TRUE(stream.Next(~(size_t)0, &closure)); grpc_slice output; - grpc_error* error = grpc_byte_stream_pull(&stream.base, &output); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_slice_eq(input[0], output)); + grpc_error* error = stream.Pull(&output); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE(grpc_slice_eq(input[0], output)); grpc_slice_unref_internal(output); // Reset the caching stream. The reads should start over from the // first slice. - grpc_caching_byte_stream_reset(&stream); + stream.Reset(); for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) { - GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure)); - error = grpc_byte_stream_pull(&stream.base, &output); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_slice_eq(input[i], output)); + ASSERT_TRUE(stream.Next(~(size_t)0, &closure)); + error = stream.Pull(&output); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE(grpc_slice_eq(input[i], output)); grpc_slice_unref_internal(output); } // Clean up. - grpc_byte_stream_destroy(&stream.base); - grpc_byte_stream_cache_destroy(&cache); - grpc_slice_buffer_destroy_internal(&buffer); + stream.Orphan(); + cache.Destroy(); } -static void test_caching_byte_stream_shared_cache(void) { - gpr_log(GPR_DEBUG, "test_caching_byte_stream_shared_cache"); +TEST(CachingByteStream, SharedCache) { grpc_core::ExecCtx exec_ctx; // Create and populate slice buffer byte stream. grpc_slice_buffer buffer; @@ -213,54 +204,50 @@ static void test_caching_byte_stream_shared_cache(void) { for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) { grpc_slice_buffer_add(&buffer, input[i]); } - grpc_slice_buffer_stream underlying_stream; - grpc_slice_buffer_stream_init(&underlying_stream, &buffer, 0); + SliceBufferByteStream underlying_stream(&buffer, 0); + grpc_slice_buffer_destroy_internal(&buffer); // Create cache and two caching streams. - grpc_byte_stream_cache cache; - grpc_byte_stream_cache_init(&cache, &underlying_stream.base); - grpc_caching_byte_stream stream1; - grpc_caching_byte_stream_init(&stream1, &cache); - grpc_caching_byte_stream stream2; - grpc_caching_byte_stream_init(&stream2, &cache); + ByteStreamCache cache((OrphanablePtr<ByteStream>(&underlying_stream))); + ByteStreamCache::CachingByteStream stream1(&cache); + ByteStreamCache::CachingByteStream stream2(&cache); grpc_closure closure; - GRPC_CLOSURE_INIT(&closure, not_called_closure, nullptr, + GRPC_CLOSURE_INIT(&closure, NotCalledClosure, nullptr, grpc_schedule_on_exec_ctx); // Read one slice from stream1. - GPR_ASSERT(grpc_byte_stream_next(&stream1.base, ~(size_t)0, &closure)); + EXPECT_TRUE(stream1.Next(~(size_t)0, &closure)); grpc_slice output; - grpc_error* error = grpc_byte_stream_pull(&stream1.base, &output); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_slice_eq(input[0], output)); + grpc_error* error = stream1.Pull(&output); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE(grpc_slice_eq(input[0], output)); grpc_slice_unref_internal(output); // Read all slices from stream2. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) { - GPR_ASSERT(grpc_byte_stream_next(&stream2.base, ~(size_t)0, &closure)); - error = grpc_byte_stream_pull(&stream2.base, &output); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_slice_eq(input[i], output)); + EXPECT_TRUE(stream2.Next(~(size_t)0, &closure)); + error = stream2.Pull(&output); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE(grpc_slice_eq(input[i], output)); grpc_slice_unref_internal(output); } // Now read the second slice from stream1. - GPR_ASSERT(grpc_byte_stream_next(&stream1.base, ~(size_t)0, &closure)); - error = grpc_byte_stream_pull(&stream1.base, &output); - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_slice_eq(input[1], output)); + EXPECT_TRUE(stream1.Next(~(size_t)0, &closure)); + error = stream1.Pull(&output); + EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE(grpc_slice_eq(input[1], output)); grpc_slice_unref_internal(output); // Clean up. - grpc_byte_stream_destroy(&stream1.base); - grpc_byte_stream_destroy(&stream2.base); - grpc_byte_stream_cache_destroy(&cache); - grpc_slice_buffer_destroy_internal(&buffer); + stream1.Orphan(); + stream2.Orphan(); + cache.Destroy(); } +} // namespace +} // namespace grpc_core + int main(int argc, char** argv) { grpc_init(); grpc_test_init(argc, argv); - test_slice_buffer_stream_basic(); - test_slice_buffer_stream_shutdown(); - test_caching_byte_stream_basic(); - test_caching_byte_stream_reset(); - test_caching_byte_stream_shared_cache(); + ::testing::InitGoogleTest(&argc, argv); + int retval = RUN_ALL_TESTS(); grpc_shutdown(); - return 0; + return retval; } diff --git a/test/core/transport/chttp2/bin_decoder_test.cc b/test/core/transport/chttp2/bin_decoder_test.cc index 6d70a4261b..b4b07986a3 100644 --- a/test/core/transport/chttp2/bin_decoder_test.cc +++ b/test/core/transport/chttp2/bin_decoder_test.cc @@ -24,9 +24,10 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include "src/core/ext/transport/chttp2/transport/bin_encoder.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/string.h" static int all_ok = 1; @@ -67,6 +68,16 @@ static grpc_slice base64_decode_with_length(const char* s, return out; } +static size_t base64_infer_length(const char* s) { + grpc_slice ss = grpc_slice_from_copied_string(s); + size_t out = grpc_chttp2_base64_infer_length_after_decode(ss); + grpc_slice_unref_internal(ss); + return out; +} + +#define EXPECT_DECODED_LENGTH(s, expected) \ + GPR_ASSERT((expected) == base64_infer_length((s))); + #define EXPECT_SLICE_EQ(expected, slice) \ expect_slice_eq( \ grpc_slice_from_copied_buffer(expected, sizeof(expected) - 1), slice, \ @@ -131,6 +142,26 @@ int main(int argc, char** argv) { // Test illegal charactors in grpc_chttp2_base64_decode_with_length EXPECT_SLICE_EQ("", base64_decode_with_length("Zm:v", 3)); EXPECT_SLICE_EQ("", base64_decode_with_length("Zm=v", 3)); + + EXPECT_DECODED_LENGTH("", 0); + EXPECT_DECODED_LENGTH("ab", 1); + EXPECT_DECODED_LENGTH("abc", 2); + EXPECT_DECODED_LENGTH("abcd", 3); + EXPECT_DECODED_LENGTH("abcdef", 4); + EXPECT_DECODED_LENGTH("abcdefg", 5); + EXPECT_DECODED_LENGTH("abcdefgh", 6); + + EXPECT_DECODED_LENGTH("ab==", 1); + EXPECT_DECODED_LENGTH("abc=", 2); + EXPECT_DECODED_LENGTH("abcd", 3); + EXPECT_DECODED_LENGTH("abcdef==", 4); + EXPECT_DECODED_LENGTH("abcdefg=", 5); + EXPECT_DECODED_LENGTH("abcdefgh", 6); + + EXPECT_DECODED_LENGTH("a", 0); + EXPECT_DECODED_LENGTH("a===", 0); + EXPECT_DECODED_LENGTH("abcde", 0); + EXPECT_DECODED_LENGTH("abcde===", 0); } grpc_shutdown(); return all_ok ? 0 : 1; diff --git a/test/core/transport/chttp2/bin_encoder_test.cc b/test/core/transport/chttp2/bin_encoder_test.cc index 44f5de8a50..bd62b0e479 100644 --- a/test/core/transport/chttp2/bin_encoder_test.cc +++ b/test/core/transport/chttp2/bin_encoder_test.cc @@ -26,8 +26,8 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include "src/core/lib/gpr/string.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/string.h" static int all_ok = 1; diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc index d2dbd4a798..2a57198ab6 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.cc +++ b/test/core/transport/chttp2/hpack_encoder_test.cc @@ -26,9 +26,9 @@ #include <grpc/support/string_util.h> #include "src/core/ext/transport/chttp2/transport/hpack_parser.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/support/string.h" #include "src/core/lib/transport/metadata.h" #include "test/core/util/parse_hexstring.h" #include "test/core/util/slice_splitter.h" @@ -152,14 +152,16 @@ static void test_basic_headers() { } static void encode_int_to_str(int i, char* p) { - p[0] = (char)('a' + i % 26); + p[0] = static_cast<char>('a' + i % 26); i /= 26; GPR_ASSERT(i < 26); - p[1] = (char)('a' + i); + p[1] = static_cast<char>('a' + i); p[2] = 0; } static void test_decode_table_overflow() { + // Decrease the default table size to make decode table overflow easier. + grpc_chttp2_hpack_compressor_set_max_table_size(&g_compressor, 1024); int i; char key[3], value[3]; char* expect; @@ -170,27 +172,20 @@ static void test_decode_table_overflow() { false, }; - for (i = 0; i < 114; i++) { + for (i = 0; i < 29; i++) { encode_int_to_str(i, key); encode_int_to_str(i + 1, value); - - if (i + 61 >= 127) { + if (i == 0) { + // 3fe107 corresponds to the table size update. gpr_asprintf(&expect, - "000009 0104 deadbeef ff%02x 40 02%02x%02x 02%02x%02x", - i + 61 - 127, key[0], key[1], value[0], value[1]); - } else if (i > 0) { + "00000a 0104 deadbeef 3fe107 40 02%02x%02x 02%02x%02x", + key[0], key[1], value[0], value[1]); + verify(params, expect, 1, key, value); + } else { gpr_asprintf(&expect, "000008 0104 deadbeef %02x 40 02%02x%02x 02%02x%02x", 0x80 + 61 + i, key[0], key[1], value[0], value[1]); - } else { - gpr_asprintf(&expect, "000007 0104 deadbeef 40 02%02x%02x 02%02x%02x", - key[0], key[1], value[0], value[1]); - } - - if (i > 0) { verify(params, expect, 2, "aa", "ba", key, value); - } else { - verify(params, expect, 1, key, value); } gpr_free(expect); } diff --git a/test/core/transport/chttp2/hpack_parser_fuzzer_test.cc b/test/core/transport/chttp2/hpack_parser_fuzzer_test.cc index 9a195daee0..a8eec1eefd 100644 --- a/test/core/transport/chttp2/hpack_parser_fuzzer_test.cc +++ b/test/core/transport/chttp2/hpack_parser_fuzzer_test.cc @@ -24,6 +24,7 @@ #include <grpc/support/log.h> #include "src/core/ext/transport/chttp2/transport/hpack_parser.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" bool squelch = true; diff --git a/test/core/transport/chttp2/hpack_parser_test.cc b/test/core/transport/chttp2/hpack_parser_test.cc index 9d3456a873..43b6c79e8a 100644 --- a/test/core/transport/chttp2/hpack_parser_test.cc +++ b/test/core/transport/chttp2/hpack_parser_test.cc @@ -24,6 +24,8 @@ #include <grpc/slice.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> + +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/parse_hexstring.h" #include "test/core/util/slice_splitter.h" #include "test/core/util/test_config.h" diff --git a/test/core/transport/chttp2/hpack_table_test.cc b/test/core/transport/chttp2/hpack_table_test.cc index 3f3cb2ee9d..3ab463b631 100644 --- a/test/core/transport/chttp2/hpack_table_test.cc +++ b/test/core/transport/chttp2/hpack_table_test.cc @@ -26,7 +26,8 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) diff --git a/test/core/transport/chttp2/settings_timeout_test.cc b/test/core/transport/chttp2/settings_timeout_test.cc index 08473c72b6..39ae587bae 100644 --- a/test/core/transport/chttp2/settings_timeout_test.cc +++ b/test/core/transport/chttp2/settings_timeout_test.cc @@ -21,6 +21,7 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> +#include <functional> #include <memory> #include <thread> @@ -103,7 +104,7 @@ class Client { grpc_blocking_resolve_address(server_address_, "80", &server_addresses); ASSERT_EQ(GRPC_ERROR_NONE, error) << grpc_error_string(error); ASSERT_GE(server_addresses->naddrs, 1UL); - pollset_ = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); + pollset_ = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(pollset_, &mu_); grpc_pollset_set* pollset_set = grpc_pollset_set_create(); grpc_pollset_set_add_pollset(pollset_set, pollset_); @@ -168,7 +169,7 @@ class Client { grpc_closure* closure() { return &closure_; } - bool done() const { return done_; } + bool done() const { return gpr_atm_acq_load(&done_atm_) != 0; } // Caller does NOT take ownership of the error. grpc_error* error() const { return error_; } @@ -176,13 +177,13 @@ class Client { private: static void OnEventDone(void* arg, grpc_error* error) { gpr_log(GPR_INFO, "OnEventDone(): %s", grpc_error_string(error)); - EventState* state = (EventState*)arg; + EventState* state = static_cast<EventState*>(arg); state->error_ = GRPC_ERROR_REF(error); - state->done_ = true; + gpr_atm_rel_store(&state->done_atm_, 1); } grpc_closure closure_; - bool done_ = false; + gpr_atm done_atm_ = 0; grpc_error* error_ = GRPC_ERROR_NONE; }; @@ -202,7 +203,7 @@ class Client { } static void PollsetDestroy(void* arg, grpc_error* error) { - grpc_pollset* pollset = (grpc_pollset*)arg; + grpc_pollset* pollset = static_cast<grpc_pollset*>(arg); grpc_pollset_destroy(pollset); gpr_free(pollset); } diff --git a/test/core/transport/chttp2/stream_map_test.cc b/test/core/transport/chttp2/stream_map_test.cc index 9b21cb2364..773eb3a35f 100644 --- a/test/core/transport/chttp2/stream_map_test.cc +++ b/test/core/transport/chttp2/stream_map_test.cc @@ -78,7 +78,7 @@ static void test_basic_add_find(uint32_t n) { grpc_chttp2_stream_map_init(&map, 8); GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map)); for (i = 1; i <= n; i++) { - grpc_chttp2_stream_map_add(&map, i, (void*)(uintptr_t)i); + grpc_chttp2_stream_map_add(&map, i, (void*)static_cast<uintptr_t>(i)); } GPR_ASSERT(n == grpc_chttp2_stream_map_size(&map)); GPR_ASSERT(nullptr == grpc_chttp2_stream_map_find(&map, 0)); @@ -133,7 +133,7 @@ static void test_delete_evens_sweep(uint32_t n) { grpc_chttp2_stream_map_init(&map, 8); for (i = 1; i <= n; i++) { - grpc_chttp2_stream_map_add(&map, i, (void*)(uintptr_t)i); + grpc_chttp2_stream_map_add(&map, i, (void*)static_cast<uintptr_t>(i)); } for (i = 1; i <= n; i++) { if ((i & 1) == 0) { @@ -155,7 +155,7 @@ static void test_delete_evens_incremental(uint32_t n) { grpc_chttp2_stream_map_init(&map, 8); for (i = 1; i <= n; i++) { - grpc_chttp2_stream_map_add(&map, i, (void*)(uintptr_t)i); + grpc_chttp2_stream_map_add(&map, i, (void*)static_cast<uintptr_t>(i)); if ((i & 1) == 0) { grpc_chttp2_stream_map_delete(&map, i); } @@ -177,7 +177,7 @@ static void test_periodic_compaction(uint32_t n) { grpc_chttp2_stream_map_init(&map, 16); GPR_ASSERT(map.capacity == 16); for (i = 1; i <= n; i++) { - grpc_chttp2_stream_map_add(&map, i, (void*)(uintptr_t)i); + grpc_chttp2_stream_map_add(&map, i, (void*)static_cast<uintptr_t>(i)); if (i > 8) { del = i - 8; GPR_ASSERT((void*)(uintptr_t)del == diff --git a/test/core/transport/connectivity_state_test.cc b/test/core/transport/connectivity_state_test.cc index f5894599e5..cbd6318f52 100644 --- a/test/core/transport/connectivity_state_test.cc +++ b/test/core/transport/connectivity_state_test.cc @@ -22,6 +22,7 @@ #include <grpc/support/log.h> +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" #include "test/core/util/tracer_util.h" diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc index 5c52ae8d5f..4be34f72d9 100644 --- a/test/core/transport/metadata_test.cc +++ b/test/core/transport/metadata_test.cc @@ -27,8 +27,9 @@ #include <grpc/support/string_util.h> #include "src/core/ext/transport/chttp2/transport/bin_encoder.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/support/string.h" #include "src/core/lib/transport/static_metadata.h" #include "test/core/util/test_config.h" @@ -240,8 +241,8 @@ static void test_things_stick_around(void) { } for (i = 0; i < nstrs; i++) { - size_t p = (size_t)rand() % nstrs; - size_t q = (size_t)rand() % nstrs; + size_t p = static_cast<size_t>(rand()) % nstrs; + size_t q = static_cast<size_t>(rand()) % nstrs; size_t temp = shuf[p]; shuf[p] = shuf[q]; shuf[q] = temp; @@ -307,8 +308,8 @@ static void verify_binary_header_size(const char* key, const uint8_t* value, intern_value)); GPR_ASSERT(grpc_is_binary_header(GRPC_MDKEY(elem))); size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, false); - grpc_slice value_slice = - grpc_slice_from_copied_buffer((const char*)value, value_len); + grpc_slice value_slice = grpc_slice_from_copied_buffer( + reinterpret_cast<const char*>(value), value_len); grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice); size_t expected_size = 32 + strlen(key) + GRPC_SLICE_LENGTH(base64_encoded); GPR_ASSERT(expected_size == elem_size); diff --git a/test/core/transport/pid_controller_test.cc b/test/core/transport/pid_controller_test.cc index 081d03472a..8d2cec4042 100644 --- a/test/core/transport/pid_controller_test.cc +++ b/test/core/transport/pid_controller_test.cc @@ -24,9 +24,9 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> + #include <gtest/gtest.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/core/util/test_config.h" namespace grpc_core { diff --git a/test/core/transport/status_metadata_test.cc b/test/core/transport/status_metadata_test.cc new file mode 100644 index 0000000000..a96f11c1ea --- /dev/null +++ b/test/core/transport/status_metadata_test.cc @@ -0,0 +1,61 @@ +/* + * + * 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 "src/core/lib/transport/status_metadata.h" + +#include <gtest/gtest.h> + +#include "src/core/lib/transport/static_metadata.h" + +namespace { + +TEST(GetStatusCodeFromMetadata, OK) { + EXPECT_EQ(GRPC_STATUS_OK, + grpc_get_status_code_from_metadata(GRPC_MDELEM_GRPC_STATUS_0)); +} + +TEST(GetStatusCodeFromMetadata, CANCELLED) { + EXPECT_EQ(GRPC_STATUS_CANCELLED, + grpc_get_status_code_from_metadata(GRPC_MDELEM_GRPC_STATUS_1)); +} + +TEST(GetStatusCodeFromMetadata, UNKNOWN) { + EXPECT_EQ(GRPC_STATUS_UNKNOWN, + grpc_get_status_code_from_metadata(GRPC_MDELEM_GRPC_STATUS_2)); +} + +TEST(GetStatusCodeFromMetadata, Other) { + grpc_mdelem status_md = grpc_mdelem_from_slices( + GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_static_string("10")); + EXPECT_EQ(GRPC_STATUS_ABORTED, grpc_get_status_code_from_metadata(status_md)); + GRPC_MDELEM_UNREF(status_md); +} + +TEST(GetStatusCodeFromMetadata, Unparseable) { + grpc_mdelem status_md = grpc_mdelem_from_slices( + GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_static_string("NaN")); + EXPECT_EQ(GRPC_STATUS_UNKNOWN, grpc_get_status_code_from_metadata(status_md)); + GRPC_MDELEM_UNREF(status_md); +} + +} // namespace + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/transport/timeout_encoding_test.cc b/test/core/transport/timeout_encoding_test.cc index 0930bc836d..b7044b5b41 100644 --- a/test/core/transport/timeout_encoding_test.cc +++ b/test/core/transport/timeout_encoding_test.cc @@ -24,9 +24,10 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> -#include "src/core/lib/support/murmur_hash.h" -#include "src/core/lib/support/string.h" + +#include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) @@ -70,7 +71,7 @@ static void assert_decodes_as(const char* buffer, grpc_millis expected) { GPR_ASSERT(1 == grpc_http2_decode_timeout( grpc_slice_from_static_string(buffer), &got)); if (got != expected) { - gpr_log(GPR_ERROR, "got:'%" PRIdPTR "' != expected:'%" PRIdPTR "'", got, + gpr_log(GPR_ERROR, "got:'%" PRId64 "' != expected:'%" PRId64 "'", got, expected); abort(); } @@ -102,20 +103,22 @@ void decode_suite(char ext, grpc_millis (*answer)(int64_t x)) { } static grpc_millis millis_from_nanos(int64_t x) { - return (grpc_millis)(x / GPR_NS_PER_MS + (x % GPR_NS_PER_MS != 0)); + return static_cast<grpc_millis>(x / GPR_NS_PER_MS + (x % GPR_NS_PER_MS != 0)); } static grpc_millis millis_from_micros(int64_t x) { - return (grpc_millis)(x / GPR_US_PER_MS + (x % GPR_US_PER_MS != 0)); + return static_cast<grpc_millis>(x / GPR_US_PER_MS + (x % GPR_US_PER_MS != 0)); +} +static grpc_millis millis_from_millis(int64_t x) { + return static_cast<grpc_millis>(x); } -static grpc_millis millis_from_millis(int64_t x) { return (grpc_millis)x; } static grpc_millis millis_from_seconds(int64_t x) { - return (grpc_millis)(x * GPR_MS_PER_SEC); + return static_cast<grpc_millis>(x * GPR_MS_PER_SEC); } static grpc_millis millis_from_minutes(int64_t x) { - return (grpc_millis)(x * 60 * GPR_MS_PER_SEC); + return static_cast<grpc_millis>(x * 60 * GPR_MS_PER_SEC); } static grpc_millis millis_from_hours(int64_t x) { - return (grpc_millis)(x * 3600 * GPR_MS_PER_SEC); + return static_cast<grpc_millis>(x * 3600 * GPR_MS_PER_SEC); } void test_decoding(void) { diff --git a/test/core/tsi/BUILD b/test/core/tsi/BUILD index e28c0b5f84..ae6e8fdc32 100644 --- a/test/core/tsi/BUILD +++ b/test/core/tsi/BUILD @@ -16,7 +16,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_c licenses(["notice"]) # Apache v2 -grpc_package(name = "test/core/tsi") +grpc_package(name = "test/core/tsi", visibility = "public") grpc_cc_library( name = "transport_security_test_lib", @@ -41,6 +41,20 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "ssl_session_cache_test", + srcs = ["ssl_session_cache_test.cc"], + language = "C++", + external_deps = [ + "gtest", + ], + deps = [ + "//:grpc", + "//:gpr", + "//:tsi", + "//test/core/util:gpr_test_util", + ], +) grpc_cc_test( name = "ssl_transport_security_test", diff --git a/test/core/tsi/alts/crypt/BUILD b/test/core/tsi/alts/crypt/BUILD new file mode 100644 index 0000000000..cf9dbca316 --- /dev/null +++ b/test/core/tsi/alts/crypt/BUILD @@ -0,0 +1,42 @@ +# 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. +# +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") + +licenses(["notice"]) # Apache v2 + +grpc_package(name = "test/core/tsi/alts/crypt", visibility = "public") + +grpc_cc_test( + name = "alts_crypt_test", + srcs = ["aes_gcm_test.cc"], + language = "C++", + deps = [ + ":alts_crypt_test_util", + "//:alts_frame_protector", + "//:gpr", + "//:grpc", + ], +) + +grpc_cc_library( + name = "alts_crypt_test_util", + srcs = ["gsec_test_util.cc"], + hdrs = ["gsec_test_util.h"], + deps = [ + "//:gpr", + "//:grpc", + ], +) + diff --git a/test/core/tsi/alts/crypt/aes_gcm_test.cc b/test/core/tsi/alts/crypt/aes_gcm_test.cc new file mode 100644 index 0000000000..576dd8f27b --- /dev/null +++ b/test/core/tsi/alts/crypt/aes_gcm_test.cc @@ -0,0 +1,2105 @@ +/* + * + * 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 "src/core/tsi/alts/crypt/gsec.h" +#include "test/core/tsi/alts/crypt/gsec_test_util.h" + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +const size_t kTestMinTagLengthForCorruption = 8; +const size_t kTestNumCrypters = 3; +const size_t kTestMaxSlices = 5; +const size_t kTestMaxLength = 1024; +const size_t kTestNumEncryptions = 100; + +/* Struct for pre-generated test vector */ +typedef struct gsec_aead_test_vector { + uint8_t* nonce; + uint8_t* aad; + uint8_t* key; + uint8_t* plaintext; + uint8_t* ciphertext_and_tag; + size_t nonce_length; + size_t aad_length; + size_t key_length; + size_t plaintext_length; + size_t ciphertext_and_tag_length; +} gsec_aead_test_vector; + +static void gsec_randomly_slice(uint8_t* input, size_t input_length, + struct iovec** output, size_t* output_length) { + if (input_length == 0) { + *output = nullptr; + *output_length = 0; + return; + } + *output_length = gsec_test_bias_random_uint32(kTestMaxSlices) + 1; + *output = + static_cast<struct iovec*>(malloc(*output_length * sizeof(**output))); + size_t i; + for (i = 0; i < *output_length - 1; i++) { + size_t slice_length = + gsec_test_bias_random_uint32(static_cast<uint32_t>(input_length)); + struct iovec slice = {input, slice_length}; + (*output)[i] = slice; + input += slice_length; + input_length -= slice_length; + } + struct iovec slice = {input, input_length}; + (*output)[*output_length - 1] = slice; +} + +static void gsec_assert_ok(grpc_status_code status, const char* error_detail) { + char empty_string[] = ""; + if (error_detail == nullptr) { + error_detail = empty_string; + } + if (status != GRPC_STATUS_OK) { + fprintf(stderr, "Status is not ok: %s\n", error_detail); + } + GPR_ASSERT(status == GRPC_STATUS_OK); +} + +static void gsec_test_random_encrypt_decrypt(gsec_aead_crypter* crypter, + size_t aad_length, + size_t message_length) { + GPR_ASSERT(crypter != nullptr); + size_t nonce_length, tag_length; + uint8_t *nonce, *aad, *message; + gsec_aead_crypter_nonce_length(crypter, &nonce_length, nullptr); + gsec_aead_crypter_tag_length(crypter, &tag_length, nullptr); + + gsec_test_random_array(&nonce, nonce_length); + gsec_test_random_array(&aad, aad_length); + gsec_test_random_array(&message, message_length); + + /* Test encryption */ + size_t ciphertext_and_tag_length, ciphertext_bytes_written = 0; + gsec_aead_crypter_max_ciphertext_and_tag_length( + crypter, message_length, &ciphertext_and_tag_length, nullptr); + + uint8_t* ciphertext_and_tag = + static_cast<uint8_t*>(gpr_malloc(ciphertext_and_tag_length)); + + char* error_buffer = nullptr; + gsec_assert_ok( + gsec_aead_crypter_encrypt(crypter, nonce, nonce_length, aad, aad_length, + message, message_length, ciphertext_and_tag, + ciphertext_and_tag_length, + &ciphertext_bytes_written, &error_buffer), + error_buffer); + GPR_ASSERT(message_length + tag_length == ciphertext_and_tag_length); + GPR_ASSERT(ciphertext_bytes_written == ciphertext_and_tag_length); + + /* Test decryption */ + size_t plaintext_length, plaintext_bytes_written = 0; + gsec_aead_crypter_max_plaintext_length(crypter, ciphertext_bytes_written, + &plaintext_length, nullptr); + uint8_t* plaintext = static_cast<uint8_t*>(gpr_malloc(plaintext_length)); + grpc_status_code status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, aad, aad_length, ciphertext_and_tag, + ciphertext_bytes_written, plaintext, plaintext_length, + &plaintext_bytes_written, nullptr); + + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(message_length == plaintext_bytes_written); + GPR_ASSERT(memcmp(message, plaintext, message_length) == 0); + + /** + * The returned plaintext will be zeroed if there was an authentication error. + */ + uint8_t* zero_message = static_cast<uint8_t*>(gpr_zalloc(plaintext_length)); + if (tag_length >= kTestMinTagLengthForCorruption) { + char* error_message; + /* Corrupt nonce */ + if (nonce_length > 0) { + plaintext_bytes_written = 0; + uint8_t* corrupt_nonce; + gsec_test_copy_and_alter_random_byte(nonce, &corrupt_nonce, nonce_length); + status = gsec_aead_crypter_decrypt( + crypter, corrupt_nonce, nonce_length, aad, aad_length, + ciphertext_and_tag, ciphertext_bytes_written, plaintext, + plaintext_length, &plaintext_bytes_written, &error_message); + + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, "Checking tag failed.", + error_message)); + GPR_ASSERT(plaintext_bytes_written == 0); + GPR_ASSERT(memcmp(zero_message, plaintext, plaintext_length) == 0); + gpr_free(corrupt_nonce); + gpr_free(error_message); + } + + /* Corrupt ciphertext_and_tag */ + plaintext_bytes_written = 0; + uint8_t* corrupt_ciphertext_and_tag; + gsec_test_copy_and_alter_random_byte(ciphertext_and_tag, + &corrupt_ciphertext_and_tag, + ciphertext_and_tag_length); + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, aad, aad_length, + corrupt_ciphertext_and_tag, ciphertext_bytes_written, plaintext, + plaintext_length, &plaintext_bytes_written, &error_message); + + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Checking tag failed")); + GPR_ASSERT(plaintext_bytes_written == 0); + GPR_ASSERT(memcmp(zero_message, plaintext, plaintext_length) == 0); + gpr_free(error_message); + gpr_free(corrupt_ciphertext_and_tag); + + /* Corrupt start of ciphertext_and_tag */ + plaintext_bytes_written = 0; + gsec_test_copy(ciphertext_and_tag, &corrupt_ciphertext_and_tag, + ciphertext_and_tag_length); + (*corrupt_ciphertext_and_tag)++; + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, aad, aad_length, + corrupt_ciphertext_and_tag, ciphertext_bytes_written, plaintext, + plaintext_length, &plaintext_bytes_written, &error_message); + GPR_ASSERT(plaintext_bytes_written == 0); + GPR_ASSERT(memcmp(zero_message, plaintext, plaintext_length) == 0); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Checking tag failed")); + gpr_free(error_message); + gpr_free(corrupt_ciphertext_and_tag); + + /* Corrupt end of ciphertext_and_tag */ + plaintext_bytes_written = 0; + gsec_test_copy(ciphertext_and_tag, &corrupt_ciphertext_and_tag, + ciphertext_and_tag_length); + (*(corrupt_ciphertext_and_tag + ciphertext_and_tag_length - 1))++; + + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, aad, aad_length, + corrupt_ciphertext_and_tag, ciphertext_bytes_written, plaintext, + plaintext_length, &plaintext_bytes_written, &error_message); + + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Checking tag failed")); + GPR_ASSERT(plaintext_bytes_written == 0); + GPR_ASSERT(memcmp(zero_message, plaintext, plaintext_length) == 0); + gpr_free(error_message); + gpr_free(corrupt_ciphertext_and_tag); + } + + gpr_free(zero_message); + gpr_free(nonce); + gpr_free(aad); + gpr_free(message); + gpr_free(plaintext); + gpr_free(ciphertext_and_tag); +} + +static void gsec_test_encrypt_decrypt(gsec_aead_crypter* crypter) { + GPR_ASSERT(crypter != nullptr); + size_t aad_length, message_length; + aad_length = gsec_test_bias_random_uint32(kTestMaxLength); + message_length = gsec_test_bias_random_uint32(kTestMaxLength); + gsec_test_random_encrypt_decrypt(crypter, aad_length, message_length); + gsec_test_random_encrypt_decrypt(crypter, 0, message_length); + gsec_test_random_encrypt_decrypt(crypter, aad_length, 0); +} + +static void gsec_test_multiple_random_encrypt_decrypt( + gsec_aead_crypter* crypter, size_t* aad_lengths, size_t* message_lengths, + size_t count) { + GPR_ASSERT(crypter != nullptr); + size_t nonce_length, tag_length; + uint8_t **nonces, **aads, **messages; + nonces = static_cast<uint8_t**>(gpr_malloc(sizeof(uint8_t*) * count)); + aads = static_cast<uint8_t**>(gpr_malloc(sizeof(uint8_t*) * count)); + messages = static_cast<uint8_t**>(gpr_malloc(sizeof(uint8_t*) * count)); + + gsec_aead_crypter_nonce_length(crypter, &nonce_length, nullptr); + gsec_aead_crypter_tag_length(crypter, &tag_length, nullptr); + + size_t ind; + for (ind = 0; ind < count; ind++) { + size_t aad_length = (aad_lengths == nullptr) ? 0 : aad_lengths[ind]; + size_t message_length = + (message_lengths == nullptr) ? 0 : message_lengths[ind]; + gsec_test_random_array(&(nonces[ind]), nonce_length); + gsec_test_random_array(&(aads[ind]), aad_length); + gsec_test_random_array(&(messages[ind]), message_length); + } + + size_t* ciphertext_and_tag_lengths = + static_cast<size_t*>(gpr_malloc(sizeof(size_t) * count)); + size_t* ciphertext_bytes_writtens = + static_cast<size_t*>(gpr_malloc(sizeof(size_t) * count)); + size_t* plaintext_lengths = + static_cast<size_t*>(gpr_malloc(sizeof(size_t) * count)); + size_t* plaintext_bytes_writtens = + static_cast<size_t*>(gpr_malloc(sizeof(size_t) * count)); + uint8_t** ciphertext_and_tags = + static_cast<uint8_t**>(gpr_malloc(sizeof(uint8_t*) * count)); + uint8_t** plaintexts = + static_cast<uint8_t**>(gpr_malloc(sizeof(uint8_t*) * count)); + + /* Do encryption */ + for (ind = 0; ind < count; ind++) { + size_t aad_length = (aad_lengths == nullptr) ? 0 : aad_lengths[ind]; + size_t message_length = + (message_lengths == nullptr) ? 0 : message_lengths[ind]; + gsec_aead_crypter_max_ciphertext_and_tag_length( + crypter, message_length, &(ciphertext_and_tag_lengths[ind]), nullptr); + ciphertext_and_tags[ind] = + static_cast<uint8_t*>(gpr_malloc(ciphertext_and_tag_lengths[ind])); + grpc_status_code status = gsec_aead_crypter_encrypt( + crypter, nonces[ind], nonce_length, aads[ind], aad_length, + messages[ind], message_length, ciphertext_and_tags[ind], + ciphertext_and_tag_lengths[ind], &(ciphertext_bytes_writtens[ind]), + nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(message_length + tag_length == ciphertext_and_tag_lengths[ind]); + GPR_ASSERT(ciphertext_bytes_writtens[ind] == + ciphertext_and_tag_lengths[ind]); + } + /* Do Decryption */ + for (ind = 0; ind < count; ind++) { + size_t aad_length = (aad_lengths == nullptr) ? 0 : aad_lengths[ind]; + size_t message_length = + (message_lengths == nullptr) ? 0 : message_lengths[ind]; + gsec_aead_crypter_max_plaintext_length(crypter, + ciphertext_bytes_writtens[ind], + &(plaintext_lengths[ind]), nullptr); + plaintexts[ind] = static_cast<uint8_t*>(gpr_malloc(plaintext_lengths[ind])); + grpc_status_code status = gsec_aead_crypter_decrypt( + crypter, nonces[ind], nonce_length, aads[ind], aad_length, + ciphertext_and_tags[ind], ciphertext_bytes_writtens[ind], + plaintexts[ind], plaintext_lengths[ind], + &(plaintext_bytes_writtens[ind]), nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(message_length == plaintext_bytes_writtens[ind]); + GPR_ASSERT(memcmp(messages[ind], plaintexts[ind], message_length) == 0); + } + + /* Slice the plaintext and encrypt with iovecs */ + for (ind = 0; ind < count; ind++) { + size_t aad_length = (aad_lengths == nullptr) ? 0 : aad_lengths[ind]; + struct iovec* aad_vecs = nullptr; + size_t aad_vecs_length = 0; + gsec_randomly_slice(aads[ind], aad_length, &aad_vecs, &aad_vecs_length); + size_t message_length = + (message_lengths == nullptr) ? 0 : message_lengths[ind]; + struct iovec* message_vecs = nullptr; + size_t message_vecs_length = 0; + gsec_randomly_slice(messages[ind], message_length, &message_vecs, + &message_vecs_length); + + size_t ciphertext_length = ciphertext_and_tag_lengths[ind]; + uint8_t* another_ciphertext = + static_cast<uint8_t*>(malloc(ciphertext_length)); + struct iovec another_ciphertext_vec = {another_ciphertext, + ciphertext_length}; + + char* error_details = nullptr; + size_t ciphertext_bytes_written = 0; + gsec_assert_ok( + gsec_aead_crypter_encrypt_iovec( + crypter, nonces[ind], nonce_length, aad_vecs, aad_vecs_length, + message_vecs, message_vecs_length, another_ciphertext_vec, + &ciphertext_bytes_written, &error_details), + error_details); + GPR_ASSERT(memcmp(ciphertext_and_tags[ind], another_ciphertext_vec.iov_base, + ciphertext_length) == 0); + free(another_ciphertext); + free(aad_vecs); + free(message_vecs); + } + + /* Slice the ciphertext and decrypt with iovecs */ + for (ind = 0; ind < count; ind++) { + size_t message_length = + (message_lengths == nullptr) ? 0 : message_lengths[ind]; + message_length = message_length + 0; + + size_t aad_length = (aad_lengths == nullptr) ? 0 : aad_lengths[ind]; + + struct iovec* aad_vecs = nullptr; + size_t aad_vecs_length = 0; + gsec_randomly_slice(aads[ind], aad_length, &aad_vecs, &aad_vecs_length); + + struct iovec* ciphertext_vecs = nullptr; + size_t ciphertext_vecs_length = 0; + gsec_randomly_slice(ciphertext_and_tags[ind], + ciphertext_bytes_writtens[ind], &ciphertext_vecs, + &ciphertext_vecs_length); + + size_t decrypted_length = plaintext_lengths[ind]; + uint8_t* decrypted = static_cast<uint8_t*>(malloc(decrypted_length)); + struct iovec decrypted_vec = {decrypted, decrypted_length}; + + char* error_details = nullptr; + gsec_assert_ok(gsec_aead_crypter_decrypt_iovec( + crypter, nonces[ind], nonce_length, aad_vecs, + aad_vecs_length, ciphertext_vecs, ciphertext_vecs_length, + decrypted_vec, &decrypted_length, &error_details), + error_details); + GPR_ASSERT(decrypted_vec.iov_len == message_length); + GPR_ASSERT(memcmp(decrypted_vec.iov_base, messages[ind], message_length) == + 0); + free(decrypted); + free(aad_vecs); + free(ciphertext_vecs); + } + + for (ind = 0; ind < count; ind++) { + gpr_free(nonces[ind]); + gpr_free(aads[ind]); + gpr_free(messages[ind]); + gpr_free(ciphertext_and_tags[ind]); + gpr_free(plaintexts[ind]); + } + gpr_free(nonces); + gpr_free(aads); + gpr_free(messages); + gpr_free(ciphertext_and_tag_lengths); + gpr_free(ciphertext_bytes_writtens); + gpr_free(plaintext_lengths); + gpr_free(plaintext_bytes_writtens); + gpr_free(ciphertext_and_tags); + gpr_free(plaintexts); +} + +static void gsec_test_multiple_encrypt_decrypt(gsec_aead_crypter* crypter) { + GPR_ASSERT(crypter != nullptr); + size_t count = kTestNumEncryptions; + size_t* aad_lengths = + static_cast<size_t*>(gpr_malloc(sizeof(size_t) * count)); + size_t* message_lengths = + static_cast<size_t*>(gpr_malloc(sizeof(size_t) * count)); + size_t ind; + for (ind = 0; ind < count; ind++) { + aad_lengths[ind] = gsec_test_bias_random_uint32(kTestMaxLength); + message_lengths[ind] = gsec_test_bias_random_uint32(kTestMaxLength); + } + gsec_test_multiple_random_encrypt_decrypt(crypter, aad_lengths, + message_lengths, count); + gsec_test_multiple_random_encrypt_decrypt(crypter, aad_lengths, nullptr, + count); + gsec_test_multiple_random_encrypt_decrypt(crypter, nullptr, message_lengths, + count); + gpr_free(aad_lengths); + gpr_free(message_lengths); +} + +static void gsec_test_encryption_failure(gsec_aead_crypter* crypter) { + GPR_ASSERT(crypter != nullptr); + size_t aad_length = kTestMaxLength; + size_t message_length = kTestMaxLength; + size_t nonce_length; + + char* error_message; + uint8_t *nonce, *aad, *message; + + gsec_aead_crypter_nonce_length(crypter, &nonce_length, nullptr); + gsec_test_random_array(&nonce, nonce_length); + gsec_test_random_array(&aad, aad_length); + gsec_test_random_array(&message, message_length); + + size_t ciphertext_and_tag_length, ciphertext_bytes_written = 0; + gsec_aead_crypter_max_ciphertext_and_tag_length( + crypter, message_length, &ciphertext_and_tag_length, nullptr); + uint8_t* ciphertext_and_tag = + static_cast<uint8_t*>(gpr_malloc(ciphertext_and_tag_length)); + + /* nullptr nonce */ + grpc_status_code status = gsec_aead_crypter_encrypt( + crypter, nullptr, nonce_length, aad, aad_length, message, message_length, + ciphertext_and_tag, ciphertext_and_tag_length, &ciphertext_bytes_written, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Nonce buffer is nullptr.")); + gpr_free(error_message); + + /* Big nonce */ + status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length + 1, aad, aad_length, message, + message_length, ciphertext_and_tag, ciphertext_and_tag_length, + &ciphertext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Nonce buffer has the wrong length.")); + gpr_free(error_message); + + /* Small nonce */ + status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length - 1, aad, aad_length, message, + message_length, ciphertext_and_tag, ciphertext_and_tag_length, + &ciphertext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Nonce buffer has the wrong length.")); + gpr_free(error_message); + + /* nullptr aad */ + status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length, nullptr, aad_length, message, + message_length, ciphertext_and_tag, ciphertext_and_tag_length, + &ciphertext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, "aad is nullptr.")); + gpr_free(error_message); + + /* nullptr aad with zero length */ + gsec_assert_ok( + gsec_aead_crypter_encrypt(crypter, nonce, nonce_length, nullptr, 0, + message, message_length, ciphertext_and_tag, + ciphertext_and_tag_length, + &ciphertext_bytes_written, &error_message), + error_message); + + /* nullptr plaintext */ + status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length, aad, aad_length, nullptr, message_length, + ciphertext_and_tag, ciphertext_and_tag_length, &ciphertext_bytes_written, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "plaintext is nullptr.")); + gpr_free(error_message); + + /* nullptr ciphertext */ + status = gsec_aead_crypter_encrypt(crypter, nonce, nonce_length, aad, + aad_length, message, message_length, + nullptr, ciphertext_and_tag_length, + &ciphertext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "ciphertext is nullptr.")); + gpr_free(error_message); + + /* Short ciphertext */ + status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length, aad, aad_length, message, message_length, + ciphertext_and_tag, ciphertext_and_tag_length - 1, + &ciphertext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "ciphertext is too small to hold a tag.")); + gpr_free(error_message); + + /* nullptr ciphertext_bytes_written */ + status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length, aad, aad_length, message, message_length, + ciphertext_and_tag, ciphertext_and_tag_length, nullptr, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "bytes_written is nullptr.")); + gpr_free(error_message); + + /* nullptr plaintext/ciphertext encrypt with zero length */ + gsec_assert_ok(gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length, aad, aad_length, nullptr, 0, + ciphertext_and_tag, ciphertext_and_tag_length, + &ciphertext_bytes_written, &error_message), + error_message); + + /* Success */ + status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length, aad, aad_length, message, message_length, + ciphertext_and_tag, ciphertext_and_tag_length, &ciphertext_bytes_written, + &error_message); + GPR_ASSERT(status == GRPC_STATUS_OK); + + gpr_free(message); + gpr_free(aad); + gpr_free(nonce); + gpr_free(ciphertext_and_tag); +} + +static void gsec_test_decryption_failure(gsec_aead_crypter* crypter) { + GPR_ASSERT(crypter != nullptr); + size_t aad_length = kTestMaxLength; + size_t message_length = kTestMaxLength; + size_t nonce_length, tag_length; + uint8_t *nonce, *aad, *message; + + gsec_aead_crypter_nonce_length(crypter, &nonce_length, nullptr); + gsec_aead_crypter_tag_length(crypter, &tag_length, nullptr); + gsec_test_random_array(&nonce, nonce_length); + gsec_test_random_array(&aad, aad_length); + gsec_test_random_array(&message, message_length); + + /* Test encryption */ + size_t ciphertext_and_tag_length, ciphertext_bytes_written = 0; + gsec_aead_crypter_max_ciphertext_and_tag_length( + crypter, message_length, &ciphertext_and_tag_length, nullptr); + uint8_t* ciphertext_and_tag = + static_cast<uint8_t*>(gpr_malloc(ciphertext_and_tag_length)); + + grpc_status_code status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length, aad, aad_length, message, message_length, + ciphertext_and_tag, ciphertext_and_tag_length, &ciphertext_bytes_written, + nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(ciphertext_bytes_written == ciphertext_and_tag_length); + + size_t plaintext_length, plaintext_bytes_written = 0; + gsec_aead_crypter_max_plaintext_length(crypter, ciphertext_bytes_written, + &plaintext_length, nullptr); + uint8_t* plaintext = static_cast<uint8_t*>(gpr_malloc(plaintext_length)); + + char* error_message; + /* nullptr nonce */ + status = gsec_aead_crypter_decrypt( + crypter, nullptr, nonce_length, aad, aad_length, ciphertext_and_tag, + ciphertext_and_tag_length, plaintext, plaintext_length, + &plaintext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Nonce buffer is nullptr.")); + gpr_free(error_message); + + /* Big nonce */ + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length + 1, aad, aad_length, ciphertext_and_tag, + ciphertext_and_tag_length, plaintext, plaintext_length, + &plaintext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Nonce buffer has the wrong length.")); + gpr_free(error_message); + + /* Small nonce */ + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length - 1, aad, aad_length, ciphertext_and_tag, + ciphertext_and_tag_length, plaintext, plaintext_length, + &plaintext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Nonce buffer has the wrong length.")); + gpr_free(error_message); + + /* nullptr aad */ + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, nullptr, aad_length, ciphertext_and_tag, + ciphertext_and_tag_length, plaintext, plaintext_length, + &plaintext_bytes_written, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, "aad is nullptr.")); + gpr_free(error_message); + + /* nullptr aad with zero length */ + status = gsec_aead_crypter_encrypt( + crypter, nonce, nonce_length, nullptr, 0, message, message_length, + ciphertext_and_tag, ciphertext_and_tag_length, &ciphertext_bytes_written, + &error_message); + GPR_ASSERT(status == GRPC_STATUS_OK); + + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, nullptr, 0, ciphertext_and_tag, + ciphertext_and_tag_length, plaintext, plaintext_length, + &plaintext_bytes_written, &error_message); + GPR_ASSERT(status == GRPC_STATUS_OK); + + /* Small ciphertext */ + if (tag_length > 0) { + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, aad, aad_length, ciphertext_and_tag, + tag_length - 1, plaintext, plaintext_length, &plaintext_bytes_written, + &error_message); + + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "ciphertext is too small to hold a tag.")); + gpr_free(error_message); + } + + /* nullptr ciphertext */ + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, aad, aad_length, nullptr, + ciphertext_and_tag_length, plaintext, plaintext_length, + &plaintext_bytes_written, &error_message); + + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "ciphertext is nullptr.")); + gpr_free(error_message); + + /* nullptr plaintext */ + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, aad, aad_length, ciphertext_and_tag, + ciphertext_and_tag_length, nullptr, plaintext_length, + &plaintext_bytes_written, &error_message); + + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "plaintext is nullptr, but plaintext_length is positive.")); + gpr_free(error_message); + + /* Short plaintext */ + status = gsec_aead_crypter_decrypt( + crypter, nonce, nonce_length, aad, aad_length, ciphertext_and_tag, + ciphertext_and_tag_length, plaintext, plaintext_length - 1, + &plaintext_bytes_written, &error_message); + + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Not enough plaintext buffer to hold encrypted ciphertext.")); + gpr_free(error_message); + + /* nullptr plaintext_bytes_written */ + status = gsec_aead_crypter_decrypt(crypter, nonce, nonce_length, aad, + aad_length, ciphertext_and_tag, + ciphertext_and_tag_length, plaintext, + plaintext_length, nullptr, &error_message); + + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "bytes_written is nullptr.")); + gpr_free(error_message); + + gpr_free(message); + gpr_free(plaintext); + gpr_free(ciphertext_and_tag); + gpr_free(aad); + gpr_free(nonce); +} + +static void gsec_test_encrypt_decrypt_test_vector( + gsec_aead_crypter* crypter, gsec_aead_test_vector* test_vector) { + GPR_ASSERT(crypter != nullptr); + /* Test byte-based encryption interface. */ + size_t ciphertext_and_tag_length, ciphertext_bytes_written = 0; + gsec_aead_crypter_max_ciphertext_and_tag_length( + crypter, test_vector->plaintext_length, &ciphertext_and_tag_length, + nullptr); + uint8_t* ciphertext_and_tag_bytes = + static_cast<uint8_t*>(gpr_malloc(ciphertext_and_tag_length)); + grpc_status_code status = gsec_aead_crypter_encrypt( + crypter, test_vector->nonce, test_vector->nonce_length, test_vector->aad, + test_vector->aad_length, test_vector->plaintext, + test_vector->plaintext_length, ciphertext_and_tag_bytes, + ciphertext_and_tag_length, &ciphertext_bytes_written, nullptr); + + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(ciphertext_bytes_written == ciphertext_and_tag_length); + GPR_ASSERT(memcmp(test_vector->ciphertext_and_tag, ciphertext_and_tag_bytes, + ciphertext_and_tag_length) == 0); + + /* Test byte-based decryption interface */ + size_t plaintext_length, plaintext_bytes_written = 0; + gsec_aead_crypter_max_plaintext_length(crypter, ciphertext_and_tag_length, + &plaintext_length, nullptr); + uint8_t* plaintext_bytes = + static_cast<uint8_t*>(gpr_malloc(plaintext_length)); + status = gsec_aead_crypter_decrypt( + crypter, test_vector->nonce, test_vector->nonce_length, test_vector->aad, + test_vector->aad_length, test_vector->ciphertext_and_tag, + test_vector->ciphertext_and_tag_length, plaintext_bytes, plaintext_length, + &plaintext_bytes_written, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(test_vector->plaintext, plaintext_bytes, + plaintext_bytes_written) == 0); + + gpr_free(ciphertext_and_tag_bytes); + gpr_free(plaintext_bytes); +} + +static void gsec_test_get_crypter_from_test_vector( + gsec_aead_crypter** crypter, gsec_aead_test_vector* test_vector, + bool rekey = false) { + size_t key_length = test_vector->key_length; + GPR_ASSERT(key_length == kAes128GcmKeyLength || + key_length == kAes256GcmKeyLength || + key_length == kAes128GcmRekeyKeyLength); + size_t nonce_length = test_vector->nonce_length; + GPR_ASSERT(nonce_length == kAesGcmNonceLength); + size_t plaintext_length = test_vector->plaintext_length; + size_t ciphertext_and_tag_length = test_vector->ciphertext_and_tag_length; + GPR_ASSERT(ciphertext_and_tag_length == plaintext_length + kAesGcmTagLength); + size_t tag_length = ciphertext_and_tag_length - plaintext_length; + gsec_aes_gcm_aead_crypter_create(test_vector->key, key_length, nonce_length, + tag_length, rekey, crypter, nullptr); +} + +static void gsec_test_verify_crypter_on_test_vector( + gsec_aead_test_vector* test_vector, bool rekey = false) { + gsec_aead_crypter* crypter; + gsec_test_get_crypter_from_test_vector(&crypter, test_vector, rekey); + gsec_test_encrypt_decrypt_test_vector(crypter, test_vector); + gsec_aead_crypter_destroy(crypter); +} + +static void gsec_aead_malloc_test_vector( + gsec_aead_test_vector** test_vector, const uint8_t* key, size_t key_length, + const uint8_t* nonce, size_t nonce_length, const uint8_t* aad, + size_t aad_length, const uint8_t* plaintext, size_t plaintext_length, + const uint8_t* ciphertext_and_tag, size_t ciphertext_and_tag_length) { + *test_vector = static_cast<gsec_aead_test_vector*>( + gpr_malloc(sizeof(gsec_aead_test_vector))); + (*test_vector)->key_length = key_length; + (*test_vector)->nonce_length = nonce_length; + (*test_vector)->aad_length = aad_length; + (*test_vector)->plaintext_length = plaintext_length; + (*test_vector)->ciphertext_and_tag_length = ciphertext_and_tag_length; + gsec_test_copy(key, &((*test_vector)->key), key_length); + gsec_test_copy(nonce, &((*test_vector)->nonce), nonce_length); + gsec_test_copy(aad, &((*test_vector)->aad), aad_length); + gsec_test_copy(plaintext, &((*test_vector)->plaintext), plaintext_length); + gsec_test_copy(ciphertext_and_tag, &((*test_vector)->ciphertext_and_tag), + ciphertext_and_tag_length); +} + +static void gsec_aead_free_test_vector(gsec_aead_test_vector* test_vector) { + gpr_free(test_vector->key); + gpr_free(test_vector->nonce); + gpr_free(test_vector->aad); + gpr_free(test_vector->plaintext); + gpr_free(test_vector->ciphertext_and_tag); + gpr_free(test_vector); +} + +static void gsec_test_create_random_aes_gcm_crypter(gsec_aead_crypter** crypter, + size_t key_length, + size_t nonce_length, + size_t tag_length, + bool rekey) { + uint8_t* key; + gsec_test_random_array(&key, key_length); + gsec_aes_gcm_aead_crypter_create(key, key_length, nonce_length, tag_length, + rekey, crypter, nullptr); + gpr_free(key); +} + +static void gsec_test_get_random_aes_gcm_crypters( + gsec_aead_crypter*** crypters) { + *crypters = static_cast<gsec_aead_crypter**>( + gpr_malloc(sizeof(gsec_aead_crypter*) * kTestNumCrypters)); + gsec_test_create_random_aes_gcm_crypter( + &((*crypters)[0]), kAes128GcmKeyLength, kAesGcmNonceLength, + kAesGcmTagLength, /*rekey=*/false); + gsec_test_create_random_aes_gcm_crypter( + &((*crypters)[1]), kAes256GcmKeyLength, kAesGcmNonceLength, + kAesGcmTagLength, /*rekey=*/false); + gsec_test_create_random_aes_gcm_crypter( + &((*crypters)[2]), kAes128GcmRekeyKeyLength, kAesGcmNonceLength, + kAesGcmTagLength, /*rekey=*/true); +} + +static void gsec_test_do_generic_crypter_tests() { + gsec_aead_crypter** crypters; + gsec_test_get_random_aes_gcm_crypters(&crypters); + size_t ind; + for (ind = 0; ind < kTestNumCrypters; ind++) { + gsec_test_encrypt_decrypt(crypters[ind]); + gsec_test_multiple_encrypt_decrypt(crypters[ind]); + gsec_test_encryption_failure(crypters[ind]); + gsec_test_decryption_failure(crypters[ind]); + } + for (ind = 0; ind < kTestNumCrypters; ind++) { + gsec_aead_crypter_destroy(crypters[ind]); + } + gpr_free(crypters); +} + +static void gsec_test_do_vector_tests_rekey_nist() { + // NIST vectors from: + // http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf + // + // IEEE vectors from: + // http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf + // + // Key expanded by setting expandedKey = (key||(key ^ {0x01, .., 0x01})||key ^ + // {0x02,..,0x02}))[0:44]. + + gsec_aead_test_vector vec; + + // Derived from NIST test vector 1 + uint8_t nonce_0[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + uint8_t aad_0[1] = {}; + uint8_t key_0[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2}; + uint8_t plaintext_0[1] = {}; + uint8_t ciphertext_0[] = {0x85, 0xE8, 0x73, 0xE0, 0x2, 0xF6, 0xEB, 0xDC, + 0x40, 0x60, 0x95, 0x4E, 0xB8, 0x67, 0x55, 0x8}; + vec = {nonce_0, aad_0, key_0, plaintext_0, ciphertext_0, 12, 0, 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from NIST test vector 2 + uint8_t nonce_1[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + uint8_t aad_1[1] = {}; + uint8_t key_1[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2}; + uint8_t plaintext_1[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + uint8_t ciphertext_1[] = {0x51, 0xE9, 0xA8, 0xCB, 0x23, 0xCA, 0x25, 0x12, + 0xC8, 0x25, 0x6A, 0xFF, 0xF8, 0xE7, 0x2D, 0x68, + 0x1A, 0xCA, 0x19, 0xA1, 0x14, 0x8A, 0xC1, 0x15, + 0xE8, 0x3D, 0xF4, 0x88, 0x8C, 0xC0, 0xD, 0x11}; + vec = {nonce_1, aad_1, key_1, plaintext_1, ciphertext_1, 12, 0, 44, 16, 32}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from NIST test vector 3 + uint8_t nonce_2[] = {0xCA, 0xFE, 0xBA, 0xBE, 0xFA, 0xCE, + 0xDB, 0xAD, 0xDE, 0xCA, 0xF8, 0x88}; + uint8_t aad_2[1] = {}; + uint8_t key_2[] = {0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, + 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x8, 0xFF, 0xFE, + 0xE8, 0x93, 0x87, 0x64, 0x72, 0x1D, 0x6C, 0x6B, 0x8E, + 0x95, 0x66, 0x31, 0x82, 0x9, 0xFC, 0xFD, 0xEB, 0x90, + 0x84, 0x67, 0x71, 0x1E, 0x6F, 0x68, 0x8D, 0x96}; + uint8_t plaintext_2[] = { + 0xD9, 0x31, 0x32, 0x25, 0xF8, 0x84, 0x6, 0xE5, 0xA5, 0x59, 0x9, + 0xC5, 0xAF, 0xF5, 0x26, 0x9A, 0x86, 0xA7, 0xA9, 0x53, 0x15, 0x34, + 0xF7, 0xDA, 0x2E, 0x4C, 0x30, 0x3D, 0x8A, 0x31, 0x8A, 0x72, 0x1C, + 0x3C, 0xC, 0x95, 0x95, 0x68, 0x9, 0x53, 0x2F, 0xCF, 0xE, 0x24, + 0x49, 0xA6, 0xB5, 0x25, 0xB1, 0x6A, 0xED, 0xF5, 0xAA, 0xD, 0xE6, + 0x57, 0xBA, 0x63, 0x7B, 0x39, 0x1A, 0xAF, 0xD2, 0x55}; + uint8_t ciphertext_2[] = { + 0x10, 0x18, 0xED, 0x5A, 0x14, 0x2, 0xA8, 0x65, 0x16, 0xD6, 0x57, 0x6D, + 0x70, 0xB2, 0xFF, 0xCC, 0xCA, 0x26, 0x1B, 0x94, 0xDF, 0x88, 0xB5, 0x8F, + 0x53, 0xB6, 0x4D, 0xFB, 0xA4, 0x35, 0xD1, 0x8B, 0x2F, 0x6E, 0x3B, 0x78, + 0x69, 0xF9, 0x35, 0x3D, 0x4A, 0xC8, 0xCF, 0x9, 0xAF, 0xB1, 0x66, 0x3D, + 0xAA, 0x7B, 0x40, 0x17, 0xE6, 0xFC, 0x2C, 0x17, 0x7C, 0xC, 0x8, 0x7C, + 0xD, 0xF1, 0x16, 0x21, 0x29, 0x95, 0x22, 0x13, 0xCE, 0xE1, 0xBC, 0x6E, + 0x9C, 0x84, 0x95, 0xDD, 0x70, 0x5E, 0x1F, 0x3D}; + vec = {nonce_2, aad_2, key_2, plaintext_2, ciphertext_2, 12, 0, 44, 64, 80}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from NIST test vector 4 + uint8_t nonce_3[] = {0xCA, 0xFE, 0xBA, 0xBE, 0xFA, 0xCE, + 0xDB, 0xAD, 0xDE, 0xCA, 0xF8, 0x88}; + uint8_t aad_3[] = {0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, + 0xEF, 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, + 0xBE, 0xEF, 0xAB, 0xAD, 0xDA, 0xD2}; + uint8_t key_3[] = {0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, + 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x8, 0xFF, 0xFE, + 0xE8, 0x93, 0x87, 0x64, 0x72, 0x1D, 0x6C, 0x6B, 0x8E, + 0x95, 0x66, 0x31, 0x82, 0x9, 0xFC, 0xFD, 0xEB, 0x90, + 0x84, 0x67, 0x71, 0x1E, 0x6F, 0x68, 0x8D, 0x96}; + uint8_t plaintext_3[] = { + 0xD9, 0x31, 0x32, 0x25, 0xF8, 0x84, 0x6, 0xE5, 0xA5, 0x59, 0x9, 0xC5, + 0xAF, 0xF5, 0x26, 0x9A, 0x86, 0xA7, 0xA9, 0x53, 0x15, 0x34, 0xF7, 0xDA, + 0x2E, 0x4C, 0x30, 0x3D, 0x8A, 0x31, 0x8A, 0x72, 0x1C, 0x3C, 0xC, 0x95, + 0x95, 0x68, 0x9, 0x53, 0x2F, 0xCF, 0xE, 0x24, 0x49, 0xA6, 0xB5, 0x25, + 0xB1, 0x6A, 0xED, 0xF5, 0xAA, 0xD, 0xE6, 0x57, 0xBA, 0x63, 0x7B, 0x39}; + uint8_t ciphertext_3[] = { + 0x10, 0x18, 0xED, 0x5A, 0x14, 0x2, 0xA8, 0x65, 0x16, 0xD6, 0x57, + 0x6D, 0x70, 0xB2, 0xFF, 0xCC, 0xCA, 0x26, 0x1B, 0x94, 0xDF, 0x88, + 0xB5, 0x8F, 0x53, 0xB6, 0x4D, 0xFB, 0xA4, 0x35, 0xD1, 0x8B, 0x2F, + 0x6E, 0x3B, 0x78, 0x69, 0xF9, 0x35, 0x3D, 0x4A, 0xC8, 0xCF, 0x9, + 0xAF, 0xB1, 0x66, 0x3D, 0xAA, 0x7B, 0x40, 0x17, 0xE6, 0xFC, 0x2C, + 0x17, 0x7C, 0xC, 0x8, 0x7C, 0x47, 0x64, 0x56, 0x5D, 0x7, 0x7E, + 0x91, 0x24, 0x0, 0x1D, 0xDB, 0x27, 0xFC, 0x8, 0x48, 0xC5}; + vec = {nonce_3, aad_3, key_3, plaintext_3, ciphertext_3, 12, 20, 44, 60, 76}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from adapted NIST test vector 4 for KDF counter boundary (flip + // nonce bit 15) + uint8_t nonce_4[] = {0xCA, 0x7E, 0xBA, 0xBE, 0xFA, 0xCE, + 0xDB, 0xAD, 0xDE, 0xCA, 0xF8, 0x88}; + uint8_t aad_4[] = {0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, + 0xEF, 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, + 0xBE, 0xEF, 0xAB, 0xAD, 0xDA, 0xD2}; + uint8_t key_4[] = {0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, + 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x8, 0xFF, 0xFE, + 0xE8, 0x93, 0x87, 0x64, 0x72, 0x1D, 0x6C, 0x6B, 0x8E, + 0x95, 0x66, 0x31, 0x82, 0x9, 0xFC, 0xFD, 0xEB, 0x90, + 0x84, 0x67, 0x71, 0x1E, 0x6F, 0x68, 0x8D, 0x96}; + uint8_t plaintext_4[] = { + 0xD9, 0x31, 0x32, 0x25, 0xF8, 0x84, 0x6, 0xE5, 0xA5, 0x59, 0x9, 0xC5, + 0xAF, 0xF5, 0x26, 0x9A, 0x86, 0xA7, 0xA9, 0x53, 0x15, 0x34, 0xF7, 0xDA, + 0x2E, 0x4C, 0x30, 0x3D, 0x8A, 0x31, 0x8A, 0x72, 0x1C, 0x3C, 0xC, 0x95, + 0x95, 0x68, 0x9, 0x53, 0x2F, 0xCF, 0xE, 0x24, 0x49, 0xA6, 0xB5, 0x25, + 0xB1, 0x6A, 0xED, 0xF5, 0xAA, 0xD, 0xE6, 0x57, 0xBA, 0x63, 0x7B, 0x39}; + uint8_t ciphertext_4[] = { + 0xE6, 0x50, 0xD3, 0xC0, 0xFB, 0x87, 0x93, 0x27, 0xF2, 0xD0, 0x32, + 0x87, 0xFA, 0x93, 0xCD, 0x7, 0x34, 0x2B, 0x13, 0x62, 0x15, 0xAD, + 0xBC, 0xA0, 0xC, 0x3B, 0xD5, 0x9, 0x9E, 0xC4, 0x18, 0x32, 0xB1, + 0xD1, 0x8E, 0x4, 0x23, 0xED, 0x26, 0xBB, 0x12, 0xC6, 0xCD, 0x9, + 0xDE, 0xBB, 0x29, 0x23, 0xA, 0x94, 0xC0, 0xCE, 0xE1, 0x59, 0x3, + 0x65, 0x6F, 0x85, 0xED, 0xB6, 0xFC, 0x50, 0x9B, 0x1B, 0x28, 0x21, + 0x63, 0x82, 0x17, 0x2E, 0xCB, 0xCC, 0x31, 0xE1, 0xE9, 0xB1}; + vec = {nonce_4, aad_4, key_4, plaintext_4, ciphertext_4, 12, 20, 44, 60, 76}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from adapted NIST test vector 4 for KDF counter boundary (flip + // nonce bit 16) + uint8_t nonce_5[] = {0xCA, 0xFE, 0xBB, 0xBE, 0xFA, 0xCE, + 0xDB, 0xAD, 0xDE, 0xCA, 0xF8, 0x88}; + uint8_t aad_5[] = {0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, + 0xEF, 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, + 0xBE, 0xEF, 0xAB, 0xAD, 0xDA, 0xD2}; + uint8_t key_5[] = {0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, + 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x8, 0xFF, 0xFE, + 0xE8, 0x93, 0x87, 0x64, 0x72, 0x1D, 0x6C, 0x6B, 0x8E, + 0x95, 0x66, 0x31, 0x82, 0x9, 0xFC, 0xFD, 0xEB, 0x90, + 0x84, 0x67, 0x71, 0x1E, 0x6F, 0x68, 0x8D, 0x96}; + uint8_t plaintext_5[] = { + 0xD9, 0x31, 0x32, 0x25, 0xF8, 0x84, 0x6, 0xE5, 0xA5, 0x59, 0x9, 0xC5, + 0xAF, 0xF5, 0x26, 0x9A, 0x86, 0xA7, 0xA9, 0x53, 0x15, 0x34, 0xF7, 0xDA, + 0x2E, 0x4C, 0x30, 0x3D, 0x8A, 0x31, 0x8A, 0x72, 0x1C, 0x3C, 0xC, 0x95, + 0x95, 0x68, 0x9, 0x53, 0x2F, 0xCF, 0xE, 0x24, 0x49, 0xA6, 0xB5, 0x25, + 0xB1, 0x6A, 0xED, 0xF5, 0xAA, 0xD, 0xE6, 0x57, 0xBA, 0x63, 0x7B, 0x39}; + uint8_t ciphertext_5[] = { + 0xC0, 0x12, 0x1E, 0x6C, 0x95, 0x4D, 0x7, 0x67, 0xF9, 0x66, 0x30, + 0xC3, 0x34, 0x50, 0x99, 0x97, 0x91, 0xB2, 0xDA, 0x2A, 0xD0, 0x5C, + 0x41, 0x90, 0x16, 0x9C, 0xCA, 0xD9, 0xAC, 0x86, 0xFF, 0x1C, 0x72, + 0x1E, 0x3D, 0x82, 0xF2, 0xAD, 0x22, 0xAB, 0x46, 0x3B, 0xAB, 0x4A, + 0x7, 0x54, 0xB7, 0xDD, 0x68, 0xCA, 0x4D, 0xE7, 0xEA, 0x25, 0x31, + 0xB6, 0x25, 0xED, 0xA0, 0x1F, 0x89, 0x31, 0x2B, 0x2A, 0xB9, 0x57, + 0xD5, 0xC7, 0xF8, 0x56, 0x8D, 0xD9, 0x5F, 0xCD, 0xCD, 0x1F}; + vec = {nonce_5, aad_5, key_5, plaintext_5, ciphertext_5, 12, 20, 44, 60, 76}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from adapted NIST test vector 4 for KDF counter boundary (flip + // nonce bit 63) + uint8_t nonce_6[] = {0xCA, 0xFE, 0xBA, 0xBE, 0xFA, 0xCE, + 0xDB, 0x2D, 0xDE, 0xCA, 0xF8, 0x88}; + uint8_t aad_6[] = {0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, + 0xEF, 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, + 0xBE, 0xEF, 0xAB, 0xAD, 0xDA, 0xD2}; + uint8_t key_6[] = {0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, + 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x8, 0xFF, 0xFE, + 0xE8, 0x93, 0x87, 0x64, 0x72, 0x1D, 0x6C, 0x6B, 0x8E, + 0x95, 0x66, 0x31, 0x82, 0x9, 0xFC, 0xFD, 0xEB, 0x90, + 0x84, 0x67, 0x71, 0x1E, 0x6F, 0x68, 0x8D, 0x96}; + uint8_t plaintext_6[] = { + 0xD9, 0x31, 0x32, 0x25, 0xF8, 0x84, 0x6, 0xE5, 0xA5, 0x59, 0x9, 0xC5, + 0xAF, 0xF5, 0x26, 0x9A, 0x86, 0xA7, 0xA9, 0x53, 0x15, 0x34, 0xF7, 0xDA, + 0x2E, 0x4C, 0x30, 0x3D, 0x8A, 0x31, 0x8A, 0x72, 0x1C, 0x3C, 0xC, 0x95, + 0x95, 0x68, 0x9, 0x53, 0x2F, 0xCF, 0xE, 0x24, 0x49, 0xA6, 0xB5, 0x25, + 0xB1, 0x6A, 0xED, 0xF5, 0xAA, 0xD, 0xE6, 0x57, 0xBA, 0x63, 0x7B, 0x39}; + uint8_t ciphertext_6[] = { + 0x8A, 0xF3, 0x7E, 0xA5, 0x68, 0x4A, 0x4D, 0x81, 0xD4, 0xFD, 0x81, + 0x72, 0x61, 0xFD, 0x97, 0x43, 0x9, 0x9E, 0x7E, 0x6A, 0x2, 0x5E, + 0xAA, 0xCF, 0x8E, 0x54, 0xB1, 0x24, 0xFB, 0x57, 0x43, 0x14, 0x9E, + 0x5, 0xCB, 0x89, 0xF4, 0xA4, 0x94, 0x67, 0xFE, 0x2E, 0x5E, 0x59, + 0x65, 0xF2, 0x9A, 0x19, 0xF9, 0x94, 0x16, 0xB0, 0x1, 0x6B, 0x54, + 0x58, 0x5D, 0x12, 0x55, 0x37, 0x83, 0xBA, 0x59, 0xE9, 0xF7, 0x82, + 0xE8, 0x2E, 0x9, 0x7C, 0x33, 0x6B, 0xF7, 0x98, 0x9F, 0x8}; + vec = {nonce_6, aad_6, key_6, plaintext_6, ciphertext_6, 12, 20, 44, 60, 76}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from adapted NIST test vector 4 for KDF counter boundary (flip + // nonce bit 64) + uint8_t nonce_7[] = {0xCA, 0xFE, 0xBA, 0xBE, 0xFA, 0xCE, + 0xDB, 0xAD, 0xDF, 0xCA, 0xF8, 0x88}; + uint8_t aad_7[] = {0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, + 0xEF, 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, + 0xBE, 0xEF, 0xAB, 0xAD, 0xDA, 0xD2}; + uint8_t key_7[] = {0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, + 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x8, 0xFF, 0xFE, + 0xE8, 0x93, 0x87, 0x64, 0x72, 0x1D, 0x6C, 0x6B, 0x8E, + 0x95, 0x66, 0x31, 0x82, 0x9, 0xFC, 0xFD, 0xEB, 0x90, + 0x84, 0x67, 0x71, 0x1E, 0x6F, 0x68, 0x8D, 0x96}; + uint8_t plaintext_7[] = { + 0xD9, 0x31, 0x32, 0x25, 0xF8, 0x84, 0x6, 0xE5, 0xA5, 0x59, 0x9, 0xC5, + 0xAF, 0xF5, 0x26, 0x9A, 0x86, 0xA7, 0xA9, 0x53, 0x15, 0x34, 0xF7, 0xDA, + 0x2E, 0x4C, 0x30, 0x3D, 0x8A, 0x31, 0x8A, 0x72, 0x1C, 0x3C, 0xC, 0x95, + 0x95, 0x68, 0x9, 0x53, 0x2F, 0xCF, 0xE, 0x24, 0x49, 0xA6, 0xB5, 0x25, + 0xB1, 0x6A, 0xED, 0xF5, 0xAA, 0xD, 0xE6, 0x57, 0xBA, 0x63, 0x7B, 0x39}; + uint8_t ciphertext_7[] = { + 0xFB, 0xD5, 0x28, 0x44, 0x8D, 0x3, 0x46, 0xBF, 0xA8, 0x78, 0x63, + 0x48, 0x64, 0xD4, 0x7, 0xA3, 0x5A, 0x3, 0x9D, 0xE9, 0xDB, 0x2F, + 0x1F, 0xEB, 0x8E, 0x96, 0x5B, 0x3A, 0xE9, 0x35, 0x6C, 0xE6, 0x28, + 0x94, 0x41, 0xD7, 0x7F, 0x8F, 0xD, 0xF2, 0x94, 0x89, 0x1F, 0x37, + 0xEA, 0x43, 0x8B, 0x22, 0x3E, 0x3B, 0xF2, 0xBD, 0xC5, 0x3D, 0x4C, + 0x5A, 0x74, 0xFB, 0x68, 0xB, 0xB3, 0x12, 0xA8, 0xDE, 0xC6, 0xF7, + 0x25, 0x2C, 0xBC, 0xD7, 0xF5, 0x79, 0x97, 0x50, 0xAD, 0x78}; + vec = {nonce_7, aad_7, key_7, plaintext_7, ciphertext_7, 12, 20, 44, 60, 76}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); +} + +static void gsec_test_do_vector_tests_rekey_ieee() { + // IEEE vectors from: + // http://www.ieee802.org/1/files/public/docs2011/bn-randall-test-vectors-0511-v1.pdf + // + // Key expanded by setting expandedKey = (key||(key ^ {0x01, .., 0x01})||key ^ + // {0x02,..,0x02}))[0:44]. + + gsec_aead_test_vector vec; + + // Derived from IEEE 2.1.1 54-byte auth + uint8_t nonce_8[] = {0x12, 0x15, 0x35, 0x24, 0xC0, 0x89, + 0x5E, 0x81, 0xB2, 0xC2, 0x84, 0x65}; + uint8_t aad_8[] = {0xD6, 0x9, 0xB1, 0xF0, 0x56, 0x63, 0x7A, 0xD, 0x46, 0xDF, + 0x99, 0x8D, 0x88, 0xE5, 0x22, 0x2A, 0xB2, 0xC2, 0x84, 0x65, + 0x12, 0x15, 0x35, 0x24, 0xC0, 0x89, 0x5E, 0x81, 0x8, 0x0, + 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x0, 0x1}; + uint8_t key_8[] = {0xAD, 0x7A, 0x2B, 0xD0, 0x3E, 0xAC, 0x83, 0x5A, 0x6F, + 0x62, 0xF, 0xDC, 0xB5, 0x6, 0xB3, 0x45, 0xAC, 0x7B, + 0x2A, 0xD1, 0x3F, 0xAD, 0x82, 0x5B, 0x6E, 0x63, 0xE, + 0xDD, 0xB4, 0x7, 0xB2, 0x44, 0xAF, 0x78, 0x29, 0xD2, + 0x3C, 0xAE, 0x81, 0x58, 0x6D, 0x60, 0xD, 0xDE}; + uint8_t plaintext_8[1] = {}; + uint8_t ciphertext_8[] = {0x3E, 0xA0, 0xB5, 0x84, 0xF3, 0xC8, 0x5E, 0x93, + 0xF9, 0x32, 0xE, 0xA5, 0x91, 0x69, 0x9E, 0xFB}; + vec = {nonce_8, aad_8, key_8, plaintext_8, ciphertext_8, 12, 70, 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.1.2 54-byte auth + uint8_t nonce_9[] = {0x12, 0x15, 0x35, 0x24, 0xC0, 0x89, + 0x5E, 0x81, 0xB2, 0xC2, 0x84, 0x65}; + uint8_t aad_9[] = {0xD6, 0x9, 0xB1, 0xF0, 0x56, 0x63, 0x7A, 0xD, 0x46, 0xDF, + 0x99, 0x8D, 0x88, 0xE5, 0x22, 0x2A, 0xB2, 0xC2, 0x84, 0x65, + 0x12, 0x15, 0x35, 0x24, 0xC0, 0x89, 0x5E, 0x81, 0x8, 0x0, + 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x0, 0x1}; + uint8_t key_9[] = {0xE3, 0xC0, 0x8A, 0x8F, 0x6, 0xC6, 0xE3, 0xAD, 0x95, + 0xA7, 0x5, 0x57, 0xB2, 0x3F, 0x75, 0x48, 0x3C, 0xE3, + 0x30, 0x21, 0xA9, 0xC7, 0x2B, 0x70, 0x25, 0x66, 0x62, + 0x4, 0xC6, 0x9C, 0xB, 0x72, 0xE1, 0xC2, 0x88, 0x8D, + 0x4, 0xC4, 0xE1, 0xAF, 0x97, 0xA5, 0x7, 0x55}; + uint8_t plaintext_9[1] = {}; + uint8_t ciphertext_9[] = {0x29, 0x4E, 0x2, 0x8B, 0xF1, 0xFE, 0x6F, 0x14, + 0xC4, 0xE8, 0xF7, 0x30, 0x5C, 0x93, 0x3E, 0xB5}; + vec = {nonce_9, aad_9, key_9, plaintext_9, ciphertext_9, 12, 70, 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.2.1 60-byte crypt + uint8_t nonce_10[] = {0x12, 0x15, 0x35, 0x24, 0xC0, 0x89, + 0x5E, 0x81, 0xB2, 0xC2, 0x84, 0x65}; + uint8_t aad_10[] = {0xD6, 0x9, 0xB1, 0xF0, 0x56, 0x63, 0x7A, + 0xD, 0x46, 0xDF, 0x99, 0x8D, 0x88, 0xE5, + 0x2E, 0x0, 0xB2, 0xC2, 0x84, 0x65, 0x12, + 0x15, 0x35, 0x24, 0xC0, 0x89, 0x5E, 0x81}; + uint8_t key_10[] = {0xAD, 0x7A, 0x2B, 0xD0, 0x3E, 0xAC, 0x83, 0x5A, 0x6F, + 0x62, 0xF, 0xDC, 0xB5, 0x6, 0xB3, 0x45, 0xAC, 0x7B, + 0x2A, 0xD1, 0x3F, 0xAD, 0x82, 0x5B, 0x6E, 0x63, 0xE, + 0xDD, 0xB4, 0x7, 0xB2, 0x44, 0xAF, 0x78, 0x29, 0xD2, + 0x3C, 0xAE, 0x81, 0x58, 0x6D, 0x60, 0xD, 0xDE}; + uint8_t plaintext_10[] = { + 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x0, 0x2}; + uint8_t ciphertext_10[] = { + 0xDB, 0x3D, 0x25, 0x71, 0x9C, 0x6B, 0xA, 0x3C, 0xA6, 0x14, 0x5C, + 0x15, 0x9D, 0x5C, 0x6E, 0xD9, 0xAF, 0xF9, 0xC6, 0xE0, 0xB7, 0x9F, + 0x17, 0x1, 0x9E, 0xA9, 0x23, 0xB8, 0x66, 0x5D, 0xDF, 0x52, 0x13, + 0x7A, 0xD6, 0x11, 0xF0, 0xD1, 0xBF, 0x41, 0x7A, 0x7C, 0xA8, 0x5E, + 0x45, 0xAF, 0xE1, 0x6, 0xFF, 0x9C, 0x75, 0x69, 0xD3, 0x35, 0xD0, + 0x86, 0xAE, 0x6C, 0x3, 0xF0, 0x9, 0x87, 0xCC, 0xD6}; + vec = {nonce_10, aad_10, key_10, plaintext_10, ciphertext_10, + 12, 28, 44, 48, 64}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.2.2 60-byte crypt + uint8_t nonce_11[] = {0x12, 0x15, 0x35, 0x24, 0xC0, 0x89, + 0x5E, 0x81, 0xB2, 0xC2, 0x84, 0x65}; + uint8_t aad_11[] = {0xD6, 0x9, 0xB1, 0xF0, 0x56, 0x63, 0x7A, + 0xD, 0x46, 0xDF, 0x99, 0x8D, 0x88, 0xE5, + 0x2E, 0x0, 0xB2, 0xC2, 0x84, 0x65, 0x12, + 0x15, 0x35, 0x24, 0xC0, 0x89, 0x5E, 0x81}; + uint8_t key_11[] = {0xE3, 0xC0, 0x8A, 0x8F, 0x6, 0xC6, 0xE3, 0xAD, 0x95, + 0xA7, 0x5, 0x57, 0xB2, 0x3F, 0x75, 0x48, 0x3C, 0xE3, + 0x30, 0x21, 0xA9, 0xC7, 0x2B, 0x70, 0x25, 0x66, 0x62, + 0x4, 0xC6, 0x9C, 0xB, 0x72, 0xE1, 0xC2, 0x88, 0x8D, + 0x4, 0xC4, 0xE1, 0xAF, 0x97, 0xA5, 0x7, 0x55}; + uint8_t plaintext_11[] = { + 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x0, 0x2}; + uint8_t ciphertext_11[] = { + 0x16, 0x41, 0xF2, 0x8E, 0xC1, 0x3A, 0xFC, 0xC8, 0xF7, 0x90, 0x33, + 0x89, 0x78, 0x72, 0x1, 0x5, 0x16, 0x44, 0x91, 0x49, 0x33, 0xE9, + 0x20, 0x2B, 0xB9, 0xD0, 0x6A, 0xA0, 0x20, 0xC2, 0xA6, 0x7E, 0xF5, + 0x1D, 0xFE, 0x7B, 0xC0, 0xA, 0x85, 0x6C, 0x55, 0xB8, 0xF8, 0x13, + 0x3E, 0x77, 0xF6, 0x59, 0x13, 0x25, 0x2, 0xBA, 0xD6, 0x3F, 0x57, + 0x13, 0xD5, 0x7D, 0xC, 0x11, 0xE0, 0xF8, 0x71, 0xED}; + vec = {nonce_11, aad_11, key_11, plaintext_11, ciphertext_11, + 12, 28, 44, 48, 64}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.3.1 60-byte auth + uint8_t nonce_12[] = {0xF0, 0x76, 0x1E, 0x8D, 0xCD, 0x3D, + 0x0, 0x1, 0x76, 0xD4, 0x57, 0xED}; + uint8_t aad_12[] = { + 0xE2, 0x1, 0x6, 0xD7, 0xCD, 0xD, 0xF0, 0x76, 0x1E, 0x8D, 0xCD, 0x3D, + 0x88, 0xE5, 0x40, 0x0, 0x76, 0xD4, 0x57, 0xED, 0x8, 0x0, 0xF, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, + 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x0, 0x3}; + uint8_t key_12[] = {0x7, 0x1B, 0x11, 0x3B, 0xC, 0xA7, 0x43, 0xFE, 0xCC, + 0xCF, 0x3D, 0x5, 0x1F, 0x73, 0x73, 0x82, 0x6, 0x1A, + 0x10, 0x3A, 0xD, 0xA6, 0x42, 0xFF, 0xCD, 0xCE, 0x3C, + 0x4, 0x1E, 0x72, 0x72, 0x83, 0x5, 0x19, 0x13, 0x39, + 0xE, 0xA5, 0x41, 0xFC, 0xCE, 0xCD, 0x3F, 0x7}; + uint8_t plaintext_12[1] = {}; + uint8_t ciphertext_12[] = {0x58, 0x83, 0x7A, 0x10, 0x56, 0x2B, 0xF, 0x1F, + 0x8E, 0xDB, 0xE5, 0x8C, 0xA5, 0x58, 0x11, 0xD3}; + vec = {nonce_12, aad_12, key_12, plaintext_12, ciphertext_12, 12, 68, + 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.3.2 60-byte auth + uint8_t nonce_13[] = {0xF0, 0x76, 0x1E, 0x8D, 0xCD, 0x3D, + 0x0, 0x1, 0x76, 0xD4, 0x57, 0xED}; + uint8_t aad_13[] = { + 0xE2, 0x1, 0x6, 0xD7, 0xCD, 0xD, 0xF0, 0x76, 0x1E, 0x8D, 0xCD, 0x3D, + 0x88, 0xE5, 0x40, 0x0, 0x76, 0xD4, 0x57, 0xED, 0x8, 0x0, 0xF, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, + 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x0, 0x3}; + uint8_t key_13[] = {0x69, 0x1D, 0x3E, 0xE9, 0x9, 0xD7, 0xF5, 0x41, 0x67, + 0xFD, 0x1C, 0xA0, 0xB5, 0xD7, 0x69, 0x8, 0x1F, 0x2B, + 0xDE, 0x1A, 0xEE, 0x65, 0x5F, 0xDB, 0xAB, 0x80, 0xBD, + 0x52, 0x95, 0xAE, 0x6B, 0xE7, 0x6B, 0x1F, 0x3C, 0xEB, + 0xB, 0xD5, 0xF7, 0x43, 0x65, 0xFF, 0x1E, 0xA2}; + uint8_t plaintext_13[1] = {}; + uint8_t ciphertext_13[] = {0xC2, 0x72, 0x2F, 0xF6, 0xCA, 0x29, 0xA2, 0x57, + 0x71, 0x8A, 0x52, 0x9D, 0x1F, 0xC, 0x6A, 0x3B}; + vec = {nonce_13, aad_13, key_13, plaintext_13, ciphertext_13, 12, 68, + 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.4.1 54-byte crypt + uint8_t nonce_14[] = {0xF0, 0x76, 0x1E, 0x8D, 0xCD, 0x3D, + 0x0, 0x1, 0x76, 0xD4, 0x57, 0xED}; + uint8_t aad_14[] = {0xE2, 0x1, 0x6, 0xD7, 0xCD, 0xD, 0xF0, + 0x76, 0x1E, 0x8D, 0xCD, 0x3D, 0x88, 0xE5, + 0x4C, 0x2A, 0x76, 0xD4, 0x57, 0xED}; + uint8_t key_14[] = {0x7, 0x1B, 0x11, 0x3B, 0xC, 0xA7, 0x43, 0xFE, 0xCC, + 0xCF, 0x3D, 0x5, 0x1F, 0x73, 0x73, 0x82, 0x6, 0x1A, + 0x10, 0x3A, 0xD, 0xA6, 0x42, 0xFF, 0xCD, 0xCE, 0x3C, + 0x4, 0x1E, 0x72, 0x72, 0x83, 0x5, 0x19, 0x13, 0x39, + 0xE, 0xA5, 0x41, 0xFC, 0xCE, 0xCD, 0x3F, 0x7}; + uint8_t plaintext_14[] = { + 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x0, 0x4}; + uint8_t ciphertext_14[] = { + 0xFD, 0x96, 0xB7, 0x15, 0xB9, 0x3A, 0x13, 0x34, 0x6A, 0xF5, 0x1E, 0x8A, + 0xCD, 0xF7, 0x92, 0xCD, 0xC7, 0xB2, 0x68, 0x6F, 0x85, 0x74, 0xC7, 0xE, + 0x6B, 0xC, 0xBF, 0x16, 0x29, 0x1D, 0xED, 0x42, 0x7A, 0xD7, 0x3F, 0xEC, + 0x48, 0xCD, 0x29, 0x8E, 0x5, 0x28, 0xA1, 0xF4, 0xC6, 0x44, 0xA9, 0x49, + 0xFC, 0x31, 0xDC, 0x92, 0x79, 0x70, 0x6D, 0xDB, 0xA3, 0x3F}; + vec = {nonce_14, aad_14, key_14, plaintext_14, ciphertext_14, + 12, 20, 44, 42, 58}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.4.2 54-byte crypt + uint8_t nonce_15[] = {0xF0, 0x76, 0x1E, 0x8D, 0xCD, 0x3D, + 0x0, 0x1, 0x76, 0xD4, 0x57, 0xED}; + uint8_t aad_15[] = {0xE2, 0x1, 0x6, 0xD7, 0xCD, 0xD, 0xF0, + 0x76, 0x1E, 0x8D, 0xCD, 0x3D, 0x88, 0xE5, + 0x4C, 0x2A, 0x76, 0xD4, 0x57, 0xED}; + uint8_t key_15[] = {0x69, 0x1D, 0x3E, 0xE9, 0x9, 0xD7, 0xF5, 0x41, 0x67, + 0xFD, 0x1C, 0xA0, 0xB5, 0xD7, 0x69, 0x8, 0x1F, 0x2B, + 0xDE, 0x1A, 0xEE, 0x65, 0x5F, 0xDB, 0xAB, 0x80, 0xBD, + 0x52, 0x95, 0xAE, 0x6B, 0xE7, 0x6B, 0x1F, 0x3C, 0xEB, + 0xB, 0xD5, 0xF7, 0x43, 0x65, 0xFF, 0x1E, 0xA2}; + uint8_t plaintext_15[] = { + 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x0, 0x4}; + uint8_t ciphertext_15[] = { + 0xB6, 0x8F, 0x63, 0x0, 0xC2, 0xE9, 0xAE, 0x83, 0x3B, 0xDC, 0x7, 0xE, + 0x24, 0x2, 0x1A, 0x34, 0x77, 0x11, 0x8E, 0x78, 0xCC, 0xF8, 0x4E, 0x11, + 0xA4, 0x85, 0xD8, 0x61, 0x47, 0x6C, 0x30, 0xF, 0x17, 0x53, 0x53, 0xD5, + 0xCD, 0xF9, 0x20, 0x8, 0xA4, 0xF8, 0x78, 0xE6, 0xCC, 0x35, 0x77, 0x76, + 0x80, 0x85, 0xC5, 0xA, 0xE, 0x98, 0xFD, 0xA6, 0xCB, 0xB8}; + vec = {nonce_15, aad_15, key_15, plaintext_15, ciphertext_15, + 12, 20, 44, 42, 58}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.5.1 65-byte auth + uint8_t nonce_16[] = {0x7C, 0xFD, 0xE9, 0xF9, 0xE3, 0x37, + 0x24, 0xC6, 0x89, 0x32, 0xD6, 0x12}; + uint8_t aad_16[] = { + 0x84, 0xC5, 0xD5, 0x13, 0xD2, 0xAA, 0xF6, 0xE5, 0xBB, 0xD2, 0x72, 0x77, + 0x88, 0xE5, 0x23, 0x0, 0x89, 0x32, 0xD6, 0x12, 0x7C, 0xFD, 0xE9, 0xF9, + 0xE3, 0x37, 0x24, 0xC6, 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x0, 0x5}; + uint8_t key_16[] = {0x1, 0x3F, 0xE0, 0xB, 0x5F, 0x11, 0xBE, 0x7F, 0x86, + 0x6D, 0xC, 0xBB, 0xC5, 0x5A, 0x7A, 0x90, 0x0, 0x3E, + 0xE1, 0xA, 0x5E, 0x10, 0xBF, 0x7E, 0x87, 0x6C, 0xD, + 0xBA, 0xC4, 0x5B, 0x7B, 0x91, 0x3, 0x3D, 0xE2, 0x9, + 0x5D, 0x13, 0xBC, 0x7D, 0x84, 0x6F, 0xE, 0xB9}; + uint8_t plaintext_16[1] = {}; + uint8_t ciphertext_16[] = {0xCC, 0xA2, 0xE, 0xEC, 0xDA, 0x62, 0x83, 0xF0, + 0x9B, 0xB3, 0x54, 0x3D, 0xD9, 0x9E, 0xDB, 0x9B}; + vec = {nonce_16, aad_16, key_16, plaintext_16, ciphertext_16, 12, 81, + 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.5.2 65-byte auth + uint8_t nonce_17[] = {0x7C, 0xFD, 0xE9, 0xF9, 0xE3, 0x37, + 0x24, 0xC6, 0x89, 0x32, 0xD6, 0x12}; + uint8_t aad_17[] = { + 0x84, 0xC5, 0xD5, 0x13, 0xD2, 0xAA, 0xF6, 0xE5, 0xBB, 0xD2, 0x72, 0x77, + 0x88, 0xE5, 0x23, 0x0, 0x89, 0x32, 0xD6, 0x12, 0x7C, 0xFD, 0xE9, 0xF9, + 0xE3, 0x37, 0x24, 0xC6, 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x0, 0x5}; + uint8_t key_17[] = {0x83, 0xC0, 0x93, 0xB5, 0x8D, 0xE7, 0xFF, 0xE1, 0xC0, + 0xDA, 0x92, 0x6A, 0xC4, 0x3F, 0xB3, 0x60, 0x9A, 0xC1, + 0xC8, 0xF, 0xEE, 0x1B, 0x62, 0x44, 0x97, 0xEF, 0x94, + 0x2E, 0x2F, 0x79, 0xA8, 0x23, 0x81, 0xC2, 0x91, 0xB7, + 0x8F, 0xE5, 0xFD, 0xE3, 0xC2, 0xD8, 0x90, 0x68}; + uint8_t plaintext_17[1] = {}; + uint8_t ciphertext_17[] = {0xB2, 0x32, 0xCC, 0x1D, 0xA5, 0x11, 0x7B, 0xF1, + 0x50, 0x3, 0x73, 0x4F, 0xA5, 0x99, 0xD2, 0x71}; + vec = {nonce_17, aad_17, key_17, plaintext_17, ciphertext_17, 12, 81, + 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.6.1 61-byte crypt + uint8_t nonce_18[] = {0x7C, 0xFD, 0xE9, 0xF9, 0xE3, 0x37, + 0x24, 0xC6, 0x89, 0x32, 0xD6, 0x12}; + uint8_t aad_18[] = {0x84, 0xC5, 0xD5, 0x13, 0xD2, 0xAA, 0xF6, + 0xE5, 0xBB, 0xD2, 0x72, 0x77, 0x88, 0xE5, + 0x2F, 0x0, 0x89, 0x32, 0xD6, 0x12, 0x7C, + 0xFD, 0xE9, 0xF9, 0xE3, 0x37, 0x24, 0xC6}; + uint8_t key_18[] = {0x1, 0x3F, 0xE0, 0xB, 0x5F, 0x11, 0xBE, 0x7F, 0x86, + 0x6D, 0xC, 0xBB, 0xC5, 0x5A, 0x7A, 0x90, 0x0, 0x3E, + 0xE1, 0xA, 0x5E, 0x10, 0xBF, 0x7E, 0x87, 0x6C, 0xD, + 0xBA, 0xC4, 0x5B, 0x7B, 0x91, 0x3, 0x3D, 0xE2, 0x9, + 0x5D, 0x13, 0xBC, 0x7D, 0x84, 0x6F, 0xE, 0xB9}; + uint8_t plaintext_18[] = { + 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, + 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x0, 0x6}; + uint8_t ciphertext_18[] = { + 0xFF, 0x19, 0x10, 0xD3, 0x5A, 0xD7, 0xE5, 0x65, 0x78, 0x90, 0xC7, + 0xC5, 0x60, 0x14, 0x6F, 0xD0, 0x38, 0x70, 0x7F, 0x20, 0x4B, 0x66, + 0xED, 0xBC, 0x3D, 0x16, 0x1F, 0x8A, 0xCE, 0x24, 0x4B, 0x98, 0x59, + 0x21, 0x2, 0x3C, 0x43, 0x6E, 0x3A, 0x1C, 0x35, 0x32, 0xEC, 0xD5, + 0xD0, 0x9A, 0x5, 0x6D, 0x70, 0xBE, 0x58, 0x3F, 0xD, 0x10, 0x82, + 0x9D, 0x93, 0x87, 0xD0, 0x7D, 0x33, 0xD8, 0x72, 0xE4, 0x90}; + vec = {nonce_18, aad_18, key_18, plaintext_18, ciphertext_18, + 12, 28, 44, 49, 65}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.6.2 61-byte crypt + uint8_t nonce_19[] = {0x7C, 0xFD, 0xE9, 0xF9, 0xE3, 0x37, + 0x24, 0xC6, 0x89, 0x32, 0xD6, 0x12}; + uint8_t aad_19[] = {0x84, 0xC5, 0xD5, 0x13, 0xD2, 0xAA, 0xF6, + 0xE5, 0xBB, 0xD2, 0x72, 0x77, 0x88, 0xE5, + 0x2F, 0x0, 0x89, 0x32, 0xD6, 0x12, 0x7C, + 0xFD, 0xE9, 0xF9, 0xE3, 0x37, 0x24, 0xC6}; + uint8_t key_19[] = {0x83, 0xC0, 0x93, 0xB5, 0x8D, 0xE7, 0xFF, 0xE1, 0xC0, + 0xDA, 0x92, 0x6A, 0xC4, 0x3F, 0xB3, 0x60, 0x9A, 0xC1, + 0xC8, 0xF, 0xEE, 0x1B, 0x62, 0x44, 0x97, 0xEF, 0x94, + 0x2E, 0x2F, 0x79, 0xA8, 0x23, 0x81, 0xC2, 0x91, 0xB7, + 0x8F, 0xE5, 0xFD, 0xE3, 0xC2, 0xD8, 0x90, 0x68}; + uint8_t plaintext_19[] = { + 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, + 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x0, 0x6}; + uint8_t ciphertext_19[] = { + 0xD, 0xB4, 0xCF, 0x95, 0x6B, 0x5F, 0x97, 0xEC, 0xA4, 0xEA, 0xB8, + 0x2A, 0x69, 0x55, 0x30, 0x7F, 0x9A, 0xE0, 0x2A, 0x32, 0xDD, 0x7D, + 0x93, 0xF8, 0x3D, 0x66, 0xAD, 0x4, 0xE1, 0xCF, 0xDC, 0x51, 0x82, + 0xAD, 0x12, 0xAB, 0xDE, 0xA5, 0xBB, 0xB6, 0x19, 0xA1, 0xBD, 0x5F, + 0xB9, 0xA5, 0x73, 0x59, 0xF, 0xBA, 0x90, 0x8E, 0x9C, 0x7A, 0x46, + 0xC1, 0xF7, 0xBA, 0x9, 0x5, 0xD1, 0xB5, 0x5F, 0xFD, 0xA4}; + vec = {nonce_19, aad_19, key_19, plaintext_19, ciphertext_19, + 12, 28, 44, 49, 65}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.7.1 79-byte crypt + uint8_t nonce_20[] = {0x7A, 0xE8, 0xE2, 0xCA, 0x4E, 0xC5, + 0x0, 0x1, 0x2E, 0x58, 0x49, 0x5C}; + uint8_t aad_20[] = { + 0x68, 0xF2, 0xE7, 0x76, 0x96, 0xCE, 0x7A, 0xE8, 0xE2, 0xCA, 0x4E, + 0xC5, 0x88, 0xE5, 0x41, 0x0, 0x2E, 0x58, 0x49, 0x5C, 0x8, 0x0, + 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, + 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x0, 0x7}; + uint8_t key_20[] = {0x88, 0xEE, 0x8, 0x7F, 0xD9, 0x5D, 0xA9, 0xFB, 0xF6, + 0x72, 0x5A, 0xA9, 0xD7, 0x57, 0xB0, 0xCD, 0x89, 0xEF, + 0x9, 0x7E, 0xD8, 0x5C, 0xA8, 0xFA, 0xF7, 0x73, 0x5B, + 0xA8, 0xD6, 0x56, 0xB1, 0xCC, 0x8A, 0xEC, 0xA, 0x7D, + 0xDB, 0x5F, 0xAB, 0xF9, 0xF4, 0x70, 0x58, 0xAB}; + uint8_t plaintext_20[1] = {}; + uint8_t ciphertext_20[] = {0x81, 0x3F, 0xE, 0x63, 0xF, 0x96, 0xFB, 0x2D, + 0x3, 0xF, 0x58, 0xD8, 0x3F, 0x5C, 0xDF, 0xD0}; + vec = {nonce_20, aad_20, key_20, plaintext_20, ciphertext_20, 12, 87, + 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.7.2 79-byte crypt + uint8_t nonce_21[] = {0x7A, 0xE8, 0xE2, 0xCA, 0x4E, 0xC5, + 0x0, 0x1, 0x2E, 0x58, 0x49, 0x5C}; + uint8_t aad_21[] = { + 0x68, 0xF2, 0xE7, 0x76, 0x96, 0xCE, 0x7A, 0xE8, 0xE2, 0xCA, 0x4E, + 0xC5, 0x88, 0xE5, 0x41, 0x0, 0x2E, 0x58, 0x49, 0x5C, 0x8, 0x0, + 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, + 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x0, 0x7}; + uint8_t key_21[] = {0x4C, 0x97, 0x3D, 0xBC, 0x73, 0x64, 0x62, 0x16, 0x74, + 0xF8, 0xB5, 0xB8, 0x9E, 0x5C, 0x15, 0x51, 0x1F, 0xCE, + 0xD9, 0x21, 0x64, 0x90, 0xFB, 0x1C, 0x1A, 0x2C, 0xAA, + 0xF, 0xFE, 0x4, 0x7, 0xE5, 0x4E, 0x95, 0x3F, 0xBE, + 0x71, 0x66, 0x60, 0x14, 0x76, 0xFA, 0xB7, 0xBA}; + uint8_t plaintext_21[1] = {}; + uint8_t ciphertext_21[] = {0x77, 0xE5, 0xA4, 0x4C, 0x21, 0xEB, 0x7, 0x18, + 0x8A, 0xAC, 0xBD, 0x74, 0xD1, 0x98, 0xE, 0x97}; + vec = {nonce_21, aad_21, key_21, plaintext_21, ciphertext_21, 12, 87, + 44, 0, 16}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.8.1 61-byte crypt + uint8_t nonce_22[] = {0x7A, 0xE8, 0xE2, 0xCA, 0x4E, 0xC5, + 0x0, 0x1, 0x2E, 0x58, 0x49, 0x5C}; + uint8_t aad_22[] = {0x68, 0xF2, 0xE7, 0x76, 0x96, 0xCE, 0x7A, + 0xE8, 0xE2, 0xCA, 0x4E, 0xC5, 0x88, 0xE5, + 0x4D, 0x0, 0x2E, 0x58, 0x49, 0x5C}; + uint8_t key_22[] = {0x88, 0xEE, 0x8, 0x7F, 0xD9, 0x5D, 0xA9, 0xFB, 0xF6, + 0x72, 0x5A, 0xA9, 0xD7, 0x57, 0xB0, 0xCD, 0x89, 0xEF, + 0x9, 0x7E, 0xD8, 0x5C, 0xA8, 0xFA, 0xF7, 0x73, 0x5B, + 0xA8, 0xD6, 0x56, 0xB1, 0xCC, 0x8A, 0xEC, 0xA, 0x7D, + 0xDB, 0x5F, 0xAB, 0xF9, 0xF4, 0x70, 0x58, 0xAB}; + uint8_t plaintext_22[] = { + 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x0, 0x8}; + uint8_t ciphertext_22[] = { + 0x95, 0x8E, 0xC3, 0xF6, 0xD6, 0xA, 0xFE, 0xDA, 0x99, 0xEF, 0xD8, 0x88, + 0xF1, 0x75, 0xE5, 0xFC, 0xD4, 0xC8, 0x7B, 0x9B, 0xCC, 0x5C, 0x2F, 0x54, + 0x26, 0x25, 0x3A, 0x8B, 0x50, 0x62, 0x96, 0xC8, 0xC4, 0x33, 0x9, 0xAB, + 0x2A, 0xDB, 0x59, 0x39, 0x46, 0x25, 0x41, 0xD9, 0x5E, 0x80, 0x81, 0x1E, + 0x4, 0xE7, 0x6, 0xB1, 0x49, 0x8F, 0x2C, 0x40, 0x7C, 0x7F, 0xB2, 0x34, + 0xF8, 0xCC, 0x1, 0xA6, 0x47, 0x55, 0xE, 0xE6, 0xB5, 0x57, 0xB3, 0x5A, + 0x7E, 0x39, 0x45, 0x38, 0x18, 0x21, 0xF4}; + vec = {nonce_22, aad_22, key_22, plaintext_22, ciphertext_22, + 12, 20, 44, 63, 79}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); + + // Derived from IEEE 2.8.2 61-byte crypt + uint8_t nonce_23[] = {0x7A, 0xE8, 0xE2, 0xCA, 0x4E, 0xC5, + 0x0, 0x1, 0x2E, 0x58, 0x49, 0x5C}; + uint8_t aad_23[] = {0x68, 0xF2, 0xE7, 0x76, 0x96, 0xCE, 0x7A, + 0xE8, 0xE2, 0xCA, 0x4E, 0xC5, 0x88, 0xE5, + 0x4D, 0x0, 0x2E, 0x58, 0x49, 0x5C}; + uint8_t key_23[] = {0x4C, 0x97, 0x3D, 0xBC, 0x73, 0x64, 0x62, 0x16, 0x74, + 0xF8, 0xB5, 0xB8, 0x9E, 0x5C, 0x15, 0x51, 0x1F, 0xCE, + 0xD9, 0x21, 0x64, 0x90, 0xFB, 0x1C, 0x1A, 0x2C, 0xAA, + 0xF, 0xFE, 0x4, 0x7, 0xE5, 0x4E, 0x95, 0x3F, 0xBE, + 0x71, 0x66, 0x60, 0x14, 0x76, 0xFA, 0xB7, 0xBA}; + uint8_t plaintext_23[] = { + 0x8, 0x0, 0xF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x0, 0x8}; + uint8_t ciphertext_23[] = { + 0xB4, 0x4D, 0x7, 0x20, 0x11, 0xCD, 0x36, 0xD2, 0x72, 0xA9, 0xB7, 0xA9, + 0x8D, 0xB9, 0xAA, 0x90, 0xCB, 0xC5, 0xC6, 0x7B, 0x93, 0xDD, 0xCE, 0x67, + 0xC8, 0x54, 0x50, 0x32, 0x14, 0xE2, 0xE8, 0x96, 0xEC, 0x7E, 0x9D, 0xB6, + 0x49, 0xED, 0x4B, 0xCF, 0x6F, 0x85, 0xA, 0xAC, 0x2, 0x23, 0xD0, 0xCF, + 0x92, 0xC8, 0x3D, 0xB8, 0x7, 0x95, 0xC3, 0xA1, 0x7E, 0xCC, 0x12, 0x48, + 0xBB, 0x0, 0x59, 0x17, 0x12, 0xB1, 0xAE, 0x71, 0xE2, 0x68, 0x16, 0x41, + 0x96, 0x25, 0x21, 0x62, 0x81, 0xB, 0x0}; + vec = {nonce_23, aad_23, key_23, plaintext_23, ciphertext_23, + 12, 20, 44, 63, 79}; + gsec_test_verify_crypter_on_test_vector(&vec, /*rekey=*/true); +} + +static void gsec_test_do_vector_tests_nist() { + /** + * From: + * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/ + * gcm-revised-spec.pdf + */ + + /* Test vector 1 */ + gsec_aead_test_vector* test_vector_1; + const uint8_t test_vector_1_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + const uint8_t test_vector_1_nonce[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + const uint8_t test_vector_1_aad[1] = {}; + const uint8_t test_vector_1_plaintext[1] = {}; + const uint8_t test_vector_1_ciphertext_and_tag[] = { + 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a}; + gsec_aead_malloc_test_vector( + &test_vector_1, test_vector_1_key, + sizeof(test_vector_1_key) / sizeof(uint8_t), test_vector_1_nonce, + sizeof(test_vector_1_nonce) / sizeof(uint8_t), test_vector_1_aad, 0, + test_vector_1_plaintext, 0, test_vector_1_ciphertext_and_tag, + sizeof(test_vector_1_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_1); + gsec_aead_free_test_vector(test_vector_1); + + /* Test vector 2 */ + gsec_aead_test_vector* test_vector_2; + const uint8_t test_vector_2_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + const uint8_t test_vector_2_nonce[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + const uint8_t test_vector_2_aad[1] = {}; + const uint8_t test_vector_2_plaintext[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + const uint8_t test_vector_2_ciphertext_and_tag[] = { + 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 0xf3, 0x28, 0xc2, + 0xb9, 0x71, 0xb2, 0xfe, 0x78, 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, + 0x13, 0xbd, 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf}; + gsec_aead_malloc_test_vector( + &test_vector_2, test_vector_2_key, + sizeof(test_vector_2_key) / sizeof(uint8_t), test_vector_2_nonce, + sizeof(test_vector_2_nonce) / sizeof(uint8_t), test_vector_2_aad, 0, + test_vector_2_plaintext, + sizeof(test_vector_2_plaintext) / sizeof(uint8_t), + test_vector_2_ciphertext_and_tag, + sizeof(test_vector_2_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_2); + gsec_aead_free_test_vector(test_vector_2); + + /* Test vector 3 */ + gsec_aead_test_vector* test_vector_3; + const uint8_t test_vector_3_key[] = {0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, + 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, + 0x67, 0x30, 0x83, 0x08}; + const uint8_t test_vector_3_nonce[] = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, + 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88}; + const uint8_t test_vector_3_aad[1] = {}; + const uint8_t test_vector_3_plaintext[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, + 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, + 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, + 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, + 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, + 0x57, 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55}; + const uint8_t test_vector_3_ciphertext_and_tag[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, + 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, + 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91, + 0x47, 0x3f, 0x59, 0x85, 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4}; + gsec_aead_malloc_test_vector( + &test_vector_3, test_vector_3_key, + sizeof(test_vector_3_key) / sizeof(uint8_t), test_vector_3_nonce, + sizeof(test_vector_3_nonce) / sizeof(uint8_t), test_vector_3_aad, 0, + test_vector_3_plaintext, + sizeof(test_vector_3_plaintext) / sizeof(uint8_t), + test_vector_3_ciphertext_and_tag, + sizeof(test_vector_3_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_3); + gsec_aead_free_test_vector(test_vector_3); + + /* Test vector 4 */ + gsec_aead_test_vector* test_vector_4; + const uint8_t test_vector_4_key[] = {0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, + 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, + 0x67, 0x30, 0x83, 0x08}; + const uint8_t test_vector_4_nonce[] = {0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, + 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88}; + const uint8_t test_vector_4_aad[] = {0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, + 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, + 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2}; + const uint8_t test_vector_4_plaintext[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, + 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, + 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39}; + const uint8_t test_vector_4_ciphertext_and_tag[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, + 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, + 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, + 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, + 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, + 0x97, 0x3d, 0x58, 0xe0, 0x91, 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, + 0xa5, 0xdb, 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47}; + gsec_aead_malloc_test_vector( + &test_vector_4, test_vector_4_key, + sizeof(test_vector_4_key) / sizeof(uint8_t), test_vector_4_nonce, + sizeof(test_vector_4_nonce) / sizeof(uint8_t), test_vector_4_aad, + sizeof(test_vector_4_aad) / sizeof(uint8_t), test_vector_4_plaintext, + sizeof(test_vector_4_plaintext) / sizeof(uint8_t), + test_vector_4_ciphertext_and_tag, + sizeof(test_vector_4_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_4); + gsec_aead_free_test_vector(test_vector_4); +} + +static void gsec_test_do_vector_tests_ieee() { + /** + * From: + * http://www.ieee802.org/1/files/public/docs2011/ + * bn-randall-test-vectors-0511-v1.pdf + */ + + /* 2.1.1 54-byte auth */ + gsec_aead_test_vector* test_vector_5; + const uint8_t test_vector_5_key[] = {0xad, 0x7a, 0x2b, 0xd0, 0x3e, 0xac, + 0x83, 0x5a, 0x6f, 0x62, 0x0f, 0xdc, + 0xb5, 0x06, 0xb3, 0x45}; + const uint8_t test_vector_5_nonce[] = {0x12, 0x15, 0x35, 0x24, 0xc0, 0x89, + 0x5e, 0x81, 0xb2, 0xc2, 0x84, 0x65}; + const uint8_t test_vector_5_aad[] = { + 0xd6, 0x09, 0xb1, 0xf0, 0x56, 0x63, 0x7a, 0x0d, 0x46, 0xdf, 0x99, 0x8d, + 0x88, 0xe5, 0x22, 0x2a, 0xb2, 0xc2, 0x84, 0x65, 0x12, 0x15, 0x35, 0x24, + 0xc0, 0x89, 0x5e, 0x81, 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x00, 0x01}; + const uint8_t test_vector_5_plaintext[1] = {}; + const uint8_t test_vector_5_ciphertext_and_tag[] = { + 0xf0, 0x94, 0x78, 0xa9, 0xb0, 0x90, 0x07, 0xd0, + 0x6f, 0x46, 0xe9, 0xb6, 0xa1, 0xda, 0x25, 0xdd}; + gsec_aead_malloc_test_vector( + &test_vector_5, test_vector_5_key, + sizeof(test_vector_5_key) / sizeof(uint8_t), test_vector_5_nonce, + sizeof(test_vector_5_nonce) / sizeof(uint8_t), test_vector_5_aad, + sizeof(test_vector_5_aad) / sizeof(uint8_t), test_vector_5_plaintext, 0, + test_vector_5_ciphertext_and_tag, + sizeof(test_vector_5_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_5); + gsec_aead_free_test_vector(test_vector_5); + + /* 2.1.2 54-byte auth */ + gsec_aead_test_vector* test_vector_6; + const uint8_t test_vector_6_key[] = { + 0xe3, 0xc0, 0x8a, 0x8f, 0x06, 0xc6, 0xe3, 0xad, 0x95, 0xa7, 0x05, + 0x57, 0xb2, 0x3f, 0x75, 0x48, 0x3c, 0xe3, 0x30, 0x21, 0xa9, 0xc7, + 0x2b, 0x70, 0x25, 0x66, 0x62, 0x04, 0xc6, 0x9c, 0x0b, 0x72}; + + const uint8_t test_vector_6_nonce[] = {0x12, 0x15, 0x35, 0x24, 0xc0, 0x89, + 0x5e, 0x81, 0xb2, 0xc2, 0x84, 0x65}; + const uint8_t test_vector_6_aad[] = { + 0xd6, 0x09, 0xb1, 0xf0, 0x56, 0x63, 0x7a, 0x0d, 0x46, 0xdf, 0x99, 0x8d, + 0x88, 0xe5, 0x22, 0x2a, 0xb2, 0xc2, 0x84, 0x65, 0x12, 0x15, 0x35, 0x24, + 0xc0, 0x89, 0x5e, 0x81, 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x00, 0x01}; + const uint8_t test_vector_6_plaintext[1] = {}; + const uint8_t test_vector_6_ciphertext_and_tag[] = { + 0x2f, 0x0b, 0xc5, 0xaf, 0x40, 0x9e, 0x06, 0xd6, + 0x09, 0xea, 0x8b, 0x7d, 0x0f, 0xa5, 0xea, 0x50}; + gsec_aead_malloc_test_vector( + &test_vector_6, test_vector_6_key, + sizeof(test_vector_6_key) / sizeof(uint8_t), test_vector_6_nonce, + sizeof(test_vector_6_nonce) / sizeof(uint8_t), test_vector_6_aad, + sizeof(test_vector_6_aad) / sizeof(uint8_t), test_vector_6_plaintext, 0, + test_vector_6_ciphertext_and_tag, + sizeof(test_vector_6_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_6); + gsec_aead_free_test_vector(test_vector_6); + + /* 2.2.1 60-byte crypt */ + gsec_aead_test_vector* test_vector_7; + const uint8_t test_vector_7_key[] = {0xad, 0x7a, 0x2b, 0xd0, 0x3e, 0xac, + 0x83, 0x5a, 0x6f, 0x62, 0x0f, 0xdc, + 0xb5, 0x06, 0xb3, 0x45}; + + const uint8_t test_vector_7_nonce[] = {0x12, 0x15, 0x35, 0x24, 0xc0, 0x89, + 0x5e, 0x81, 0xb2, 0xc2, 0x84, 0x65}; + const uint8_t test_vector_7_aad[] = { + 0xd6, 0x09, 0xb1, 0xf0, 0x56, 0x63, 0x7a, 0x0d, 0x46, 0xdf, + 0x99, 0x8d, 0x88, 0xe5, 0x2e, 0x00, 0xb2, 0xc2, 0x84, 0x65, + 0x12, 0x15, 0x35, 0x24, 0xc0, 0x89, 0x5e, 0x81}; + const uint8_t test_vector_7_plaintext[] = { + 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x00, 0x02}; + const uint8_t test_vector_7_ciphertext_and_tag[] = { + 0x70, 0x1a, 0xfa, 0x1c, 0xc0, 0x39, 0xc0, 0xd7, 0x65, 0x12, 0x8a, + 0x66, 0x5d, 0xab, 0x69, 0x24, 0x38, 0x99, 0xbf, 0x73, 0x18, 0xcc, + 0xdc, 0x81, 0xc9, 0x93, 0x1d, 0xa1, 0x7f, 0xbe, 0x8e, 0xdd, 0x7d, + 0x17, 0xcb, 0x8b, 0x4c, 0x26, 0xfc, 0x81, 0xe3, 0x28, 0x4f, 0x2b, + 0x7f, 0xba, 0x71, 0x3d, 0x4f, 0x8d, 0x55, 0xe7, 0xd3, 0xf0, 0x6f, + 0xd5, 0xa1, 0x3c, 0x0c, 0x29, 0xb9, 0xd5, 0xb8, 0x80}; + gsec_aead_malloc_test_vector( + &test_vector_7, test_vector_7_key, + sizeof(test_vector_7_key) / sizeof(uint8_t), test_vector_7_nonce, + sizeof(test_vector_7_nonce) / sizeof(uint8_t), test_vector_7_aad, + sizeof(test_vector_7_aad) / sizeof(uint8_t), test_vector_7_plaintext, + sizeof(test_vector_7_plaintext) / sizeof(uint8_t), + test_vector_7_ciphertext_and_tag, + sizeof(test_vector_7_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_7); + gsec_aead_free_test_vector(test_vector_7); + + /* 2.2.2 60-byte crypt */ + gsec_aead_test_vector* test_vector_8; + const uint8_t test_vector_8_key[] = { + 0xe3, 0xc0, 0x8a, 0x8f, 0x06, 0xc6, 0xe3, 0xad, 0x95, 0xa7, 0x05, + 0x57, 0xb2, 0x3f, 0x75, 0x48, 0x3c, 0xe3, 0x30, 0x21, 0xa9, 0xc7, + 0x2b, 0x70, 0x25, 0x66, 0x62, 0x04, 0xc6, 0x9c, 0x0b, 0x72}; + const uint8_t test_vector_8_nonce[] = {0x12, 0x15, 0x35, 0x24, 0xc0, 0x89, + 0x5e, 0x81, 0xb2, 0xc2, 0x84, 0x65}; + const uint8_t test_vector_8_aad[] = { + 0xd6, 0x09, 0xb1, 0xf0, 0x56, 0x63, 0x7a, 0x0d, 0x46, 0xdf, + 0x99, 0x8d, 0x88, 0xe5, 0x2e, 0x00, 0xb2, 0xc2, 0x84, 0x65, + 0x12, 0x15, 0x35, 0x24, 0xc0, 0x89, 0x5e, 0x81}; + const uint8_t test_vector_8_plaintext[] = { + 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x00, 0x02}; + const uint8_t test_vector_8_ciphertext_and_tag[] = { + 0xe2, 0x00, 0x6e, 0xb4, 0x2f, 0x52, 0x77, 0x02, 0x2d, 0x9b, 0x19, + 0x92, 0x5b, 0xc4, 0x19, 0xd7, 0xa5, 0x92, 0x66, 0x6c, 0x92, 0x5f, + 0xe2, 0xef, 0x71, 0x8e, 0xb4, 0xe3, 0x08, 0xef, 0xea, 0xa7, 0xc5, + 0x27, 0x3b, 0x39, 0x41, 0x18, 0x86, 0x0a, 0x5b, 0xe2, 0xa9, 0x7f, + 0x56, 0xab, 0x78, 0x36, 0x5c, 0xa5, 0x97, 0xcd, 0xbb, 0x3e, 0xdb, + 0x8d, 0x1a, 0x11, 0x51, 0xea, 0x0a, 0xf7, 0xb4, 0x36}; + gsec_aead_malloc_test_vector( + &test_vector_8, test_vector_8_key, + sizeof(test_vector_8_key) / sizeof(uint8_t), test_vector_8_nonce, + sizeof(test_vector_8_nonce) / sizeof(uint8_t), test_vector_8_aad, + sizeof(test_vector_8_aad) / sizeof(uint8_t), test_vector_8_plaintext, + sizeof(test_vector_8_plaintext) / sizeof(uint8_t), + test_vector_8_ciphertext_and_tag, + sizeof(test_vector_8_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_8); + gsec_aead_free_test_vector(test_vector_8); + + /* 2.3.1 60-byte auth */ + gsec_aead_test_vector* test_vector_9; + const uint8_t test_vector_9_key[] = {0x07, 0x1b, 0x11, 0x3b, 0x0c, 0xa7, + 0x43, 0xfe, 0xcc, 0xcf, 0x3d, 0x05, + 0x1f, 0x73, 0x73, 0x82}; + const uint8_t test_vector_9_nonce[] = {0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d, + 0x00, 0x01, 0x76, 0xd4, 0x57, 0xed}; + const uint8_t test_vector_9_aad[] = { + 0xe2, 0x01, 0x06, 0xd7, 0xcd, 0x0d, 0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d, + 0x88, 0xe5, 0x40, 0x00, 0x76, 0xd4, 0x57, 0xed, 0x08, 0x00, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x00, 0x03}; + const uint8_t test_vector_9_plaintext[1] = {}; + const uint8_t test_vector_9_ciphertext_and_tag[] = { + 0x0c, 0x01, 0x7b, 0xc7, 0x3b, 0x22, 0x7d, 0xfc, + 0xc9, 0xba, 0xfa, 0x1c, 0x41, 0xac, 0xc3, 0x53}; + gsec_aead_malloc_test_vector( + &test_vector_9, test_vector_9_key, + sizeof(test_vector_9_key) / sizeof(uint8_t), test_vector_9_nonce, + sizeof(test_vector_9_nonce) / sizeof(uint8_t), test_vector_9_aad, + sizeof(test_vector_9_aad) / sizeof(uint8_t), test_vector_9_plaintext, 0, + test_vector_9_ciphertext_and_tag, + sizeof(test_vector_9_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_9); + gsec_aead_free_test_vector(test_vector_9); + + /* 2.3.2 60-byte auth */ + gsec_aead_test_vector* test_vector_10; + const uint8_t test_vector_10_key[] = { + 0x69, 0x1d, 0x3e, 0xe9, 0x09, 0xd7, 0xf5, 0x41, 0x67, 0xfd, 0x1c, + 0xa0, 0xb5, 0xd7, 0x69, 0x08, 0x1f, 0x2b, 0xde, 0x1a, 0xee, 0x65, + 0x5f, 0xdb, 0xab, 0x80, 0xbd, 0x52, 0x95, 0xae, 0x6b, 0xe7}; + const uint8_t test_vector_10_nonce[] = {0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d, + 0x00, 0x01, 0x76, 0xd4, 0x57, 0xed}; + const uint8_t test_vector_10_aad[] = { + 0xe2, 0x01, 0x06, 0xd7, 0xcd, 0x0d, 0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d, + 0x88, 0xe5, 0x40, 0x00, 0x76, 0xd4, 0x57, 0xed, 0x08, 0x00, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x00, 0x03}; + const uint8_t test_vector_10_plaintext[1] = {}; + const uint8_t test_vector_10_ciphertext_and_tag[] = { + 0x35, 0x21, 0x7c, 0x77, 0x4b, 0xbc, 0x31, 0xb6, + 0x31, 0x66, 0xbc, 0xf9, 0xd4, 0xab, 0xed, 0x07}; + gsec_aead_malloc_test_vector( + &test_vector_10, test_vector_10_key, + sizeof(test_vector_10_key) / sizeof(uint8_t), test_vector_10_nonce, + sizeof(test_vector_10_nonce) / sizeof(uint8_t), test_vector_10_aad, + sizeof(test_vector_10_aad) / sizeof(uint8_t), test_vector_10_plaintext, 0, + test_vector_10_ciphertext_and_tag, + sizeof(test_vector_10_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_10); + gsec_aead_free_test_vector(test_vector_10); + + /* 2.4.1 54-byte crypt */ + gsec_aead_test_vector* test_vector_11; + const uint8_t test_vector_11_key[] = {0x07, 0x1b, 0x11, 0x3b, 0x0c, 0xa7, + 0x43, 0xfe, 0xcc, 0xcf, 0x3d, 0x05, + 0x1f, 0x73, 0x73, 0x82}; + const uint8_t test_vector_11_nonce[] = {0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d, + 0x00, 0x01, 0x76, 0xd4, 0x57, 0xed}; + const uint8_t test_vector_11_aad[] = { + 0xe2, 0x01, 0x06, 0xd7, 0xcd, 0x0d, 0xf0, 0x76, 0x1e, 0x8d, + 0xcd, 0x3d, 0x88, 0xe5, 0x4c, 0x2a, 0x76, 0xd4, 0x57, 0xed}; + const uint8_t test_vector_11_plaintext[] = { + 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x00, 0x04}; + const uint8_t test_vector_11_ciphertext_and_tag[] = { + 0x13, 0xb4, 0xc7, 0x2b, 0x38, 0x9d, 0xc5, 0x01, 0x8e, 0x72, 0xa1, 0x71, + 0xdd, 0x85, 0xa5, 0xd3, 0x75, 0x22, 0x74, 0xd3, 0xa0, 0x19, 0xfb, 0xca, + 0xed, 0x09, 0xa4, 0x25, 0xcd, 0x9b, 0x2e, 0x1c, 0x9b, 0x72, 0xee, 0xe7, + 0xc9, 0xde, 0x7d, 0x52, 0xb3, 0xf3, 0xd6, 0xa5, 0x28, 0x4f, 0x4a, 0x6d, + 0x3f, 0xe2, 0x2a, 0x5d, 0x6c, 0x2b, 0x96, 0x04, 0x94, 0xc3}; + gsec_aead_malloc_test_vector( + &test_vector_11, test_vector_11_key, + sizeof(test_vector_11_key) / sizeof(uint8_t), test_vector_11_nonce, + sizeof(test_vector_11_nonce) / sizeof(uint8_t), test_vector_11_aad, + sizeof(test_vector_11_aad) / sizeof(uint8_t), test_vector_11_plaintext, + sizeof(test_vector_11_plaintext) / sizeof(uint8_t), + test_vector_11_ciphertext_and_tag, + sizeof(test_vector_11_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_11); + gsec_aead_free_test_vector(test_vector_11); + + /* 2.4.2 54-byte crypt */ + gsec_aead_test_vector* test_vector_12; + const uint8_t test_vector_12_key[] = { + 0x69, 0x1d, 0x3e, 0xe9, 0x09, 0xd7, 0xf5, 0x41, 0x67, 0xfd, 0x1c, + 0xa0, 0xb5, 0xd7, 0x69, 0x08, 0x1f, 0x2b, 0xde, 0x1a, 0xee, 0x65, + 0x5f, 0xdb, 0xab, 0x80, 0xbd, 0x52, 0x95, 0xae, 0x6b, 0xe7}; + const uint8_t test_vector_12_nonce[] = {0xf0, 0x76, 0x1e, 0x8d, 0xcd, 0x3d, + 0x00, 0x01, 0x76, 0xd4, 0x57, 0xed}; + const uint8_t test_vector_12_aad[] = { + 0xe2, 0x01, 0x06, 0xd7, 0xcd, 0x0d, 0xf0, 0x76, 0x1e, 0x8d, + 0xcd, 0x3d, 0x88, 0xe5, 0x4c, 0x2a, 0x76, 0xd4, 0x57, 0xed}; + const uint8_t test_vector_12_plaintext[] = { + 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x00, 0x04}; + const uint8_t test_vector_12_ciphertext_and_tag[] = { + 0xc1, 0x62, 0x3f, 0x55, 0x73, 0x0c, 0x93, 0x53, 0x30, 0x97, 0xad, 0xda, + 0xd2, 0x56, 0x64, 0x96, 0x61, 0x25, 0x35, 0x2b, 0x43, 0xad, 0xac, 0xbd, + 0x61, 0xc5, 0xef, 0x3a, 0xc9, 0x0b, 0x5b, 0xee, 0x92, 0x9c, 0xe4, 0x63, + 0x0e, 0xa7, 0x9f, 0x6c, 0xe5, 0x19, 0x12, 0xaf, 0x39, 0xc2, 0xd1, 0xfd, + 0xc2, 0x05, 0x1f, 0x8b, 0x7b, 0x3c, 0x9d, 0x39, 0x7e, 0xf2}; + gsec_aead_malloc_test_vector( + &test_vector_12, test_vector_12_key, + sizeof(test_vector_12_key) / sizeof(uint8_t), test_vector_12_nonce, + sizeof(test_vector_12_nonce) / sizeof(uint8_t), test_vector_12_aad, + sizeof(test_vector_12_aad) / sizeof(uint8_t), test_vector_12_plaintext, + sizeof(test_vector_12_plaintext) / sizeof(uint8_t), + test_vector_12_ciphertext_and_tag, + sizeof(test_vector_12_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_12); + gsec_aead_free_test_vector(test_vector_12); + + /* 2.5.1 65-byte auth */ + gsec_aead_test_vector* test_vector_13; + const uint8_t test_vector_13_key[] = {0x01, 0x3f, 0xe0, 0x0b, 0x5f, 0x11, + 0xbe, 0x7f, 0x86, 0x6d, 0x0c, 0xbb, + 0xc5, 0x5a, 0x7a, 0x90}; + const uint8_t test_vector_13_nonce[] = {0x7c, 0xfd, 0xe9, 0xf9, 0xe3, 0x37, + 0x24, 0xc6, 0x89, 0x32, 0xd6, 0x12}; + const uint8_t test_vector_13_aad[] = { + 0x84, 0xc5, 0xd5, 0x13, 0xd2, 0xaa, 0xf6, 0xe5, 0xbb, 0xd2, 0x72, 0x77, + 0x88, 0xe5, 0x23, 0x00, 0x89, 0x32, 0xd6, 0x12, 0x7c, 0xfd, 0xe9, 0xf9, + 0xe3, 0x37, 0x24, 0xc6, 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x05}; + const uint8_t test_vector_13_plaintext[1] = {}; + const uint8_t test_vector_13_ciphertext_and_tag[] = { + 0x21, 0x78, 0x67, 0xe5, 0x0c, 0x2d, 0xad, 0x74, + 0xc2, 0x8c, 0x3b, 0x50, 0xab, 0xdf, 0x69, 0x5a}; + gsec_aead_malloc_test_vector( + &test_vector_13, test_vector_13_key, + sizeof(test_vector_13_key) / sizeof(uint8_t), test_vector_13_nonce, + sizeof(test_vector_13_nonce) / sizeof(uint8_t), test_vector_13_aad, + sizeof(test_vector_13_aad) / sizeof(uint8_t), test_vector_13_plaintext, 0, + test_vector_13_ciphertext_and_tag, + sizeof(test_vector_13_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_13); + gsec_aead_free_test_vector(test_vector_13); + + /* 2.5.2 65-byte auth */ + gsec_aead_test_vector* test_vector_14; + const uint8_t test_vector_14_key[] = { + 0x83, 0xc0, 0x93, 0xb5, 0x8d, 0xe7, 0xff, 0xe1, 0xc0, 0xda, 0x92, + 0x6a, 0xc4, 0x3f, 0xb3, 0x60, 0x9a, 0xc1, 0xc8, 0x0f, 0xee, 0x1b, + 0x62, 0x44, 0x97, 0xef, 0x94, 0x2e, 0x2f, 0x79, 0xa8, 0x23}; + const uint8_t test_vector_14_nonce[] = {0x7c, 0xfd, 0xe9, 0xf9, 0xe3, 0x37, + 0x24, 0xc6, 0x89, 0x32, 0xd6, 0x12}; + const uint8_t test_vector_14_aad[] = { + 0x84, 0xc5, 0xd5, 0x13, 0xd2, 0xaa, 0xf6, 0xe5, 0xbb, 0xd2, 0x72, 0x77, + 0x88, 0xe5, 0x23, 0x00, 0x89, 0x32, 0xd6, 0x12, 0x7c, 0xfd, 0xe9, 0xf9, + 0xe3, 0x37, 0x24, 0xc6, 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x05}; + const uint8_t test_vector_14_plaintext[1] = {}; + const uint8_t test_vector_14_ciphertext_and_tag[] = { + 0x6e, 0xe1, 0x60, 0xe8, 0xfa, 0xec, 0xa4, 0xb3, + 0x6c, 0x86, 0xb2, 0x34, 0x92, 0x0c, 0xa9, 0x75}; + gsec_aead_malloc_test_vector( + &test_vector_14, test_vector_14_key, + sizeof(test_vector_14_key) / sizeof(uint8_t), test_vector_14_nonce, + sizeof(test_vector_14_nonce) / sizeof(uint8_t), test_vector_14_aad, + sizeof(test_vector_14_aad) / sizeof(uint8_t), test_vector_14_plaintext, 0, + test_vector_14_ciphertext_and_tag, + sizeof(test_vector_14_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_14); + gsec_aead_free_test_vector(test_vector_14); + + /* 2.6.1 61-byte crypt */ + gsec_aead_test_vector* test_vector_15; + const uint8_t test_vector_15_key[] = {0x01, 0x3f, 0xe0, 0x0b, 0x5f, 0x11, + 0xbe, 0x7f, 0x86, 0x6d, 0x0c, 0xbb, + 0xc5, 0x5a, 0x7a, 0x90}; + const uint8_t test_vector_15_nonce[] = {0x7c, 0xfd, 0xe9, 0xf9, 0xe3, 0x37, + 0x24, 0xc6, 0x89, 0x32, 0xd6, 0x12}; + const uint8_t test_vector_15_aad[] = { + 0x84, 0xc5, 0xd5, 0x13, 0xd2, 0xaa, 0xf6, 0xe5, 0xbb, 0xd2, + 0x72, 0x77, 0x88, 0xe5, 0x2f, 0x00, 0x89, 0x32, 0xd6, 0x12, + 0x7c, 0xfd, 0xe9, 0xf9, 0xe3, 0x37, 0x24, 0xc6}; + const uint8_t test_vector_15_plaintext[] = { + 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x00, 0x06}; + const uint8_t test_vector_15_ciphertext_and_tag[] = { + 0x3a, 0x4d, 0xe6, 0xfa, 0x32, 0x19, 0x10, 0x14, 0xdb, 0xb3, 0x03, + 0xd9, 0x2e, 0xe3, 0xa9, 0xe8, 0xa1, 0xb5, 0x99, 0xc1, 0x4d, 0x22, + 0xfb, 0x08, 0x00, 0x96, 0xe1, 0x38, 0x11, 0x81, 0x6a, 0x3c, 0x9c, + 0x9b, 0xcf, 0x7c, 0x1b, 0x9b, 0x96, 0xda, 0x80, 0x92, 0x04, 0xe2, + 0x9d, 0x0e, 0x2a, 0x76, 0x42, 0xbf, 0xd3, 0x10, 0xa4, 0x83, 0x7c, + 0x81, 0x6c, 0xcf, 0xa5, 0xac, 0x23, 0xab, 0x00, 0x39, 0x88}; + gsec_aead_malloc_test_vector( + &test_vector_15, test_vector_15_key, + sizeof(test_vector_15_key) / sizeof(uint8_t), test_vector_15_nonce, + sizeof(test_vector_15_nonce) / sizeof(uint8_t), test_vector_15_aad, + sizeof(test_vector_15_aad) / sizeof(uint8_t), test_vector_15_plaintext, + sizeof(test_vector_15_plaintext) / sizeof(uint8_t), + test_vector_15_ciphertext_and_tag, + sizeof(test_vector_15_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_15); + gsec_aead_free_test_vector(test_vector_15); + + /* 2.6.2 61-byte crypt */ + gsec_aead_test_vector* test_vector_16; + const uint8_t test_vector_16_key[] = { + 0x83, 0xc0, 0x93, 0xb5, 0x8d, 0xe7, 0xff, 0xe1, 0xc0, 0xda, 0x92, + 0x6a, 0xc4, 0x3f, 0xb3, 0x60, 0x9a, 0xc1, 0xc8, 0x0f, 0xee, 0x1b, + 0x62, 0x44, 0x97, 0xef, 0x94, 0x2e, 0x2f, 0x79, 0xa8, 0x23}; + const uint8_t test_vector_16_nonce[] = {0x7c, 0xfd, 0xe9, 0xf9, 0xe3, 0x37, + 0x24, 0xc6, 0x89, 0x32, 0xd6, 0x12}; + const uint8_t test_vector_16_aad[] = { + 0x84, 0xc5, 0xd5, 0x13, 0xd2, 0xaa, 0xf6, 0xe5, 0xbb, 0xd2, + 0x72, 0x77, 0x88, 0xe5, 0x2f, 0x00, 0x89, 0x32, 0xd6, 0x12, + 0x7c, 0xfd, 0xe9, 0xf9, 0xe3, 0x37, 0x24, 0xc6}; + const uint8_t test_vector_16_plaintext[] = { + 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x00, 0x06}; + const uint8_t test_vector_16_ciphertext_and_tag[] = { + 0x11, 0x02, 0x22, 0xff, 0x80, 0x50, 0xcb, 0xec, 0xe6, 0x6a, 0x81, + 0x3a, 0xd0, 0x9a, 0x73, 0xed, 0x7a, 0x9a, 0x08, 0x9c, 0x10, 0x6b, + 0x95, 0x93, 0x89, 0x16, 0x8e, 0xd6, 0xe8, 0x69, 0x8e, 0xa9, 0x02, + 0xeb, 0x12, 0x77, 0xdb, 0xec, 0x2e, 0x68, 0xe4, 0x73, 0x15, 0x5a, + 0x15, 0xa7, 0xda, 0xee, 0xd4, 0xa1, 0x0f, 0x4e, 0x05, 0x13, 0x9c, + 0x23, 0xdf, 0x00, 0xb3, 0xaa, 0xdc, 0x71, 0xf0, 0x59, 0x6a}; + gsec_aead_malloc_test_vector( + &test_vector_16, test_vector_16_key, + sizeof(test_vector_16_key) / sizeof(uint8_t), test_vector_16_nonce, + sizeof(test_vector_16_nonce) / sizeof(uint8_t), test_vector_16_aad, + sizeof(test_vector_16_aad) / sizeof(uint8_t), test_vector_16_plaintext, + sizeof(test_vector_16_plaintext) / sizeof(uint8_t), + test_vector_16_ciphertext_and_tag, + sizeof(test_vector_16_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_16); + gsec_aead_free_test_vector(test_vector_16); + + /* 2.7.1 79-byte crypt */ + gsec_aead_test_vector* test_vector_17; + const uint8_t test_vector_17_key[] = {0x88, 0xee, 0x08, 0x7f, 0xd9, 0x5d, + 0xa9, 0xfb, 0xf6, 0x72, 0x5a, 0xa9, + 0xd7, 0x57, 0xb0, 0xcd}; + const uint8_t test_vector_17_nonce[] = {0x7a, 0xe8, 0xe2, 0xca, 0x4e, 0xc5, + 0x00, 0x01, 0x2e, 0x58, 0x49, 0x5c}; + const uint8_t test_vector_17_aad[] = { + 0x68, 0xf2, 0xe7, 0x76, 0x96, 0xce, 0x7a, 0xe8, 0xe2, 0xca, 0x4e, + 0xc5, 0x88, 0xe5, 0x41, 0x00, 0x2e, 0x58, 0x49, 0x5c, 0x08, 0x00, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x00, 0x07}; + const uint8_t test_vector_17_plaintext[1] = {}; + const uint8_t test_vector_17_ciphertext_and_tag[] = { + 0x07, 0x92, 0x2b, 0x8e, 0xbc, 0xf1, 0x0b, 0xb2, + 0x29, 0x75, 0x88, 0xca, 0x4c, 0x61, 0x45, 0x23}; + gsec_aead_malloc_test_vector( + &test_vector_17, test_vector_17_key, + sizeof(test_vector_17_key) / sizeof(uint8_t), test_vector_17_nonce, + sizeof(test_vector_17_nonce) / sizeof(uint8_t), test_vector_17_aad, + sizeof(test_vector_17_aad) / sizeof(uint8_t), test_vector_17_plaintext, 0, + test_vector_17_ciphertext_and_tag, + sizeof(test_vector_17_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_17); + gsec_aead_free_test_vector(test_vector_17); + + /* 2.7.2 79-byte crypt */ + gsec_aead_test_vector* test_vector_18; + const uint8_t test_vector_18_key[] = { + 0x4c, 0x97, 0x3d, 0xbc, 0x73, 0x64, 0x62, 0x16, 0x74, 0xf8, 0xb5, + 0xb8, 0x9e, 0x5c, 0x15, 0x51, 0x1f, 0xce, 0xd9, 0x21, 0x64, 0x90, + 0xfb, 0x1c, 0x1a, 0x2c, 0xaa, 0x0f, 0xfe, 0x04, 0x07, 0xe5}; + const uint8_t test_vector_18_nonce[] = {0x7a, 0xe8, 0xe2, 0xca, 0x4e, 0xc5, + 0x00, 0x01, 0x2e, 0x58, 0x49, 0x5c}; + const uint8_t test_vector_18_aad[] = { + 0x68, 0xf2, 0xe7, 0x76, 0x96, 0xce, 0x7a, 0xe8, 0xe2, 0xca, 0x4e, + 0xc5, 0x88, 0xe5, 0x41, 0x00, 0x2e, 0x58, 0x49, 0x5c, 0x08, 0x00, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x00, 0x07}; + const uint8_t test_vector_18_plaintext[1] = {}; + const uint8_t test_vector_18_ciphertext_and_tag[] = { + 0x00, 0xbd, 0xa1, 0xb7, 0xe8, 0x76, 0x08, 0xbc, + 0xbf, 0x47, 0x0f, 0x12, 0x15, 0x7f, 0x4c, 0x07}; + gsec_aead_malloc_test_vector( + &test_vector_18, test_vector_18_key, + sizeof(test_vector_18_key) / sizeof(uint8_t), test_vector_18_nonce, + sizeof(test_vector_18_nonce) / sizeof(uint8_t), test_vector_18_aad, + sizeof(test_vector_18_aad) / sizeof(uint8_t), test_vector_18_plaintext, 0, + test_vector_18_ciphertext_and_tag, + sizeof(test_vector_18_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_18); + gsec_aead_free_test_vector(test_vector_18); + + /* 2.8.1 61-byte crypt */ + gsec_aead_test_vector* test_vector_19; + const uint8_t test_vector_19_key[] = {0x88, 0xee, 0x08, 0x7f, 0xd9, 0x5d, + 0xa9, 0xfb, 0xf6, 0x72, 0x5a, 0xa9, + 0xd7, 0x57, 0xb0, 0xcd}; + const uint8_t test_vector_19_nonce[] = {0x7a, 0xe8, 0xe2, 0xca, 0x4e, 0xc5, + 0x00, 0x01, 0x2e, 0x58, 0x49, 0x5c}; + const uint8_t test_vector_19_aad[] = { + 0x68, 0xf2, 0xe7, 0x76, 0x96, 0xce, 0x7a, 0xe8, 0xe2, 0xca, + 0x4e, 0xc5, 0x88, 0xe5, 0x4d, 0x00, 0x2e, 0x58, 0x49, 0x5c}; + const uint8_t test_vector_19_plaintext[] = { + 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x00, 0x08}; + const uint8_t test_vector_19_ciphertext_and_tag[] = { + 0xc3, 0x1f, 0x53, 0xd9, 0x9e, 0x56, 0x87, 0xf7, 0x36, 0x51, 0x19, 0xb8, + 0x32, 0xd2, 0xaa, 0xe7, 0x07, 0x41, 0xd5, 0x93, 0xf1, 0xf9, 0xe2, 0xab, + 0x34, 0x55, 0x77, 0x9b, 0x07, 0x8e, 0xb8, 0xfe, 0xac, 0xdf, 0xec, 0x1f, + 0x8e, 0x3e, 0x52, 0x77, 0xf8, 0x18, 0x0b, 0x43, 0x36, 0x1f, 0x65, 0x12, + 0xad, 0xb1, 0x6d, 0x2e, 0x38, 0x54, 0x8a, 0x2c, 0x71, 0x9d, 0xba, 0x72, + 0x28, 0xd8, 0x40, 0x88, 0xf8, 0x75, 0x7a, 0xdb, 0x8a, 0xa7, 0x88, 0xd8, + 0xf6, 0x5a, 0xd6, 0x68, 0xbe, 0x70, 0xe7}; + gsec_aead_malloc_test_vector( + &test_vector_19, test_vector_19_key, + sizeof(test_vector_19_key) / sizeof(uint8_t), test_vector_19_nonce, + sizeof(test_vector_19_nonce) / sizeof(uint8_t), test_vector_19_aad, + sizeof(test_vector_19_aad) / sizeof(uint8_t), test_vector_19_plaintext, + sizeof(test_vector_19_plaintext) / sizeof(uint8_t), + test_vector_19_ciphertext_and_tag, + sizeof(test_vector_19_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_19); + gsec_aead_free_test_vector(test_vector_19); + + /* 2.8.2 61-byte crypt */ + gsec_aead_test_vector* test_vector_20; + const uint8_t test_vector_20_key[] = { + 0x4c, 0x97, 0x3d, 0xbc, 0x73, 0x64, 0x62, 0x16, 0x74, 0xf8, 0xb5, + 0xb8, 0x9e, 0x5c, 0x15, 0x51, 0x1f, 0xce, 0xd9, 0x21, 0x64, 0x90, + 0xfb, 0x1c, 0x1a, 0x2c, 0xaa, 0x0f, 0xfe, 0x04, 0x07, 0xe5}; + const uint8_t test_vector_20_nonce[] = {0x7a, 0xe8, 0xe2, 0xca, 0x4e, 0xc5, + 0x00, 0x01, 0x2e, 0x58, 0x49, 0x5c}; + const uint8_t test_vector_20_aad[] = { + 0x68, 0xf2, 0xe7, 0x76, 0x96, 0xce, 0x7a, 0xe8, 0xe2, 0xca, + 0x4e, 0xc5, 0x88, 0xe5, 0x4d, 0x00, 0x2e, 0x58, 0x49, 0x5c}; + const uint8_t test_vector_20_plaintext[] = { + 0x08, 0x00, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x00, 0x08}; + const uint8_t test_vector_20_ciphertext_and_tag[] = { + 0xba, 0x8a, 0xe3, 0x1b, 0xc5, 0x06, 0x48, 0x6d, 0x68, 0x73, 0xe4, 0xfc, + 0xe4, 0x60, 0xe7, 0xdc, 0x57, 0x59, 0x1f, 0xf0, 0x06, 0x11, 0xf3, 0x1c, + 0x38, 0x34, 0xfe, 0x1c, 0x04, 0xad, 0x80, 0xb6, 0x68, 0x03, 0xaf, 0xcf, + 0x5b, 0x27, 0xe6, 0x33, 0x3f, 0xa6, 0x7c, 0x99, 0xda, 0x47, 0xc2, 0xf0, + 0xce, 0xd6, 0x8d, 0x53, 0x1b, 0xd7, 0x41, 0xa9, 0x43, 0xcf, 0xf7, 0xa6, + 0x71, 0x3b, 0xd0, 0x26, 0x11, 0xcd, 0x7d, 0xaa, 0x01, 0xd6, 0x1c, 0x5c, + 0x88, 0x6d, 0xc1, 0xa8, 0x17, 0x01, 0x07}; + gsec_aead_malloc_test_vector( + &test_vector_20, test_vector_20_key, + sizeof(test_vector_20_key) / sizeof(uint8_t), test_vector_20_nonce, + sizeof(test_vector_20_nonce) / sizeof(uint8_t), test_vector_20_aad, + sizeof(test_vector_20_aad) / sizeof(uint8_t), test_vector_20_plaintext, + sizeof(test_vector_20_plaintext) / sizeof(uint8_t), + test_vector_20_ciphertext_and_tag, + sizeof(test_vector_20_ciphertext_and_tag) / sizeof(uint8_t)); + gsec_test_verify_crypter_on_test_vector(test_vector_20); + gsec_aead_free_test_vector(test_vector_20); +} + +int main(int argc, char** argv) { + grpc_init(); + gsec_test_do_generic_crypter_tests(); + gsec_test_do_vector_tests_nist(); + gsec_test_do_vector_tests_ieee(); + gsec_test_do_vector_tests_rekey_nist(); + gsec_test_do_vector_tests_rekey_ieee(); + grpc_shutdown(); + return 0; +} diff --git a/test/core/tsi/alts/crypt/gsec_test_util.cc b/test/core/tsi/alts/crypt/gsec_test_util.cc new file mode 100644 index 0000000000..c682fb8e4d --- /dev/null +++ b/test/core/tsi/alts/crypt/gsec_test_util.cc @@ -0,0 +1,89 @@ +/* + * + * 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/tsi/alts/crypt/gsec_test_util.h" + +#include <time.h> + +#include <grpc/support/alloc.h> + +void gsec_test_random_bytes(uint8_t* bytes, size_t length) { + srand(time(nullptr)); + size_t ind; + for (ind = 0; ind < length; ind++) { + bytes[ind] = static_cast<uint8_t>(rand() % 255 + 1); + } +} + +void gsec_test_random_array(uint8_t** bytes, size_t length) { + if (bytes != nullptr) { + *bytes = static_cast<uint8_t*>(gpr_malloc(length)); + gsec_test_random_bytes(*bytes, length); + } else { + fprintf(stderr, "bytes buffer is nullptr in gsec_test_random_array()."); + abort(); + } +} + +uint32_t gsec_test_bias_random_uint32(uint32_t max_length) { + uint32_t value; + gsec_test_random_bytes((uint8_t*)(&value), sizeof(value)); + return value % max_length; +} + +void gsec_test_copy(const uint8_t* src, uint8_t** des, size_t source_len) { + if (src != nullptr && des != nullptr) { + *des = static_cast<uint8_t*>(gpr_malloc(source_len)); + memcpy(*des, src, source_len); + } else { + fprintf(stderr, "Either src or des buffer is nullptr in gsec_test_copy()."); + abort(); + } +} + +void gsec_test_copy_and_alter_random_byte(const uint8_t* src, uint8_t** des, + size_t source_len) { + if (src != nullptr && des != nullptr) { + *des = static_cast<uint8_t*>(gpr_malloc(source_len)); + memcpy(*des, src, source_len); + uint32_t offset; + offset = gsec_test_bias_random_uint32(static_cast<uint32_t>(source_len)); + (*(*des + offset))++; + } else { + fprintf(stderr, + "Either src or des is nullptr in " + "gsec_test_copy_and_alter_random_byte()."); + abort(); + } +} + +int gsec_test_expect_compare_code_and_substr(grpc_status_code status1, + grpc_status_code status2, + const char* msg1, + const char* msg2) { + int failure = 1; + if (status1 != status2) { + fprintf(stderr, "Status %d does not equal %d.\n", status1, status2); + failure = 0; + } + if (strstr(msg1, msg2) == nullptr) { + fprintf(stderr, "Status message <%s> does not contain <%s>.\n", msg1, msg2); + failure = 0; + } + return failure; +} diff --git a/test/core/tsi/alts/crypt/gsec_test_util.h b/test/core/tsi/alts/crypt/gsec_test_util.h new file mode 100644 index 0000000000..1bd780000f --- /dev/null +++ b/test/core/tsi/alts/crypt/gsec_test_util.h @@ -0,0 +1,89 @@ +/* + * + * 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_TSI_ALTS_CRYPT_GSEC_TEST_UTIL_H_ +#define GRPC_TEST_CORE_TSI_ALTS_CRYPT_GSEC_TEST_UTIL_H_ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <grpc/grpc.h> + +/** + * This method returns random bytes of certain length. + * + * - bytes: buffer to hold random bytes. + * - length: length of buffer to be populated. + */ +void gsec_test_random_bytes(uint8_t* bytes, size_t length); + +/** + * This method returns an array of random bytes. + * + * - bytes: array to hold random bytes. + * - length: length of array to be populated. + */ +void gsec_test_random_array(uint8_t** bytes, size_t length); + +/** + * This method returns a uint32 that's not quite uniformly random, but good + * enough for tests. + * + * - max_length: a max value the returned random number can choose. + */ +uint32_t gsec_test_bias_random_uint32(uint32_t max_length); + +/** + * This method copies data from a source to a destination buffer. + * + * - src: a source buffer. + * - des: a destination buffer. + * - length: the length of source buffer to be copied from its beginning. + */ +void gsec_test_copy(const uint8_t* src, uint8_t** des, size_t length); + +/** + * This method copies data from a source to a destination buffer, and flips one + * byte in the destination buffer randomly. + * + * - src: a source buffer. + * - des: a destination buffer. + * - length: the length of source buffer to be copied from its beginning. + */ +void gsec_test_copy_and_alter_random_byte(const uint8_t* src, uint8_t** des, + size_t source_len); + +/** + * This method compares two grpc_status_code values, and verifies if one string + * is a substring of the other. + * + * - status1: the first grpc_status_code to be compared. + * - status2: the second grpc_status_code to be compared. + * - msg1: a string to be scanned. + * - msg2: a small string to be searched within msg1. + * + * If both checks succeed, the method returns 1 and otherwise, it returns 0. + */ +int gsec_test_expect_compare_code_and_substr(grpc_status_code status1, + grpc_status_code status2, + const char* msg1, + const char* msg2); + +#endif // GRPC_TEST_CORE_TSI_ALTS_CRYPT_GSEC_TEST_UTIL_H_ */ diff --git a/test/core/tsi/alts/fake_handshaker/BUILD b/test/core/tsi/alts/fake_handshaker/BUILD new file mode 100644 index 0000000000..a09a046d27 --- /dev/null +++ b/test/core/tsi/alts/fake_handshaker/BUILD @@ -0,0 +1,57 @@ +# 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. + +licenses(["notice"]) # Apache v2 + +load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_cc_library", "grpc_cc_binary", "grpc_package") + +grpc_package(name = "test/core/tsi/alts/fake_handshaker", visibility = "public") + +grpc_proto_library( + name = "transport_security_common_proto", + srcs = ["transport_security_common.proto"], + has_services = False, +) + +grpc_proto_library( + name = "handshaker_proto", + srcs = ["handshaker.proto"], + has_services = True, + deps = [ + "transport_security_common_proto", + ], +) + +grpc_cc_library( + name = "fake_handshaker_lib", + testonly = True, + srcs = ["fake_handshaker_server.cc"], + language = "C++", + deps = [ + "handshaker_proto", + "transport_security_common_proto", + "//:grpc++", + "//test/cpp/util:test_config", + ], +) + +grpc_cc_binary( + name = "fake_handshaker_server", + testonly = True, + srcs = ["fake_handshaker_server.cc"], + language = "C++", + deps = [ + "fake_handshaker_lib", + ], +) diff --git a/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc new file mode 100644 index 0000000000..f6a4791b49 --- /dev/null +++ b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc @@ -0,0 +1,268 @@ +/* + * + * 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 <sstream> +#include <string> + +#include <gflags/gflags.h> +#include <grpc/grpc.h> +#include <grpc/support/log.h> +#include <grpcpp/impl/codegen/async_stream.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> + +#include "test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.h" +#include "test/core/tsi/alts/fake_handshaker/handshaker.pb.h" +#include "test/core/tsi/alts/fake_handshaker/transport_security_common.pb.h" +#include "test/cpp/util/test_config.h" + +DEFINE_int32(handshaker_port, 55056, + "TCP port on which the fake handshaker server listens to."); + +// Fake handshake messages. +constexpr char kClientInitFrame[] = "ClientInit"; +constexpr char kServerFrame[] = "ServerInitAndFinished"; +constexpr char kClientFinishFrame[] = "ClientFinished"; +// Error messages. +constexpr char kInvalidFrameError[] = "Invalid input frame."; +constexpr char kWrongStateError[] = "Wrong handshake state."; + +namespace grpc { +namespace gcp { + +// FakeHandshakeService implements a fake handshaker service using a fake key +// exchange protocol. The fake key exchange protocol is a 3-message protocol: +// - Client first sends ClientInit message to Server. +// - Server then sends ServerInitAndFinished message back to Client. +// - Client finally sends ClientFinished message to Server. +// This fake handshaker service is intended for ALTS integration testing without +// relying on real ALTS handshaker service inside GCE. +// It is thread-safe. +class FakeHandshakerService : public HandshakerService::Service { + public: + Status DoHandshake( + ServerContext* server_context, + ServerReaderWriter<HandshakerResp, HandshakerReq>* stream) override { + Status status; + HandshakerContext context; + HandshakerReq request; + HandshakerResp response; + gpr_log(GPR_DEBUG, "Start a new handshake."); + while (stream->Read(&request)) { + status = ProcessRequest(&context, request, &response); + if (!status.ok()) return WriteErrorResponse(stream, status); + stream->Write(response); + if (context.state == COMPLETED) return Status::OK; + request.Clear(); + } + return Status::OK; + } + + private: + // HandshakeState is used by fake handshaker server to keep track of client's + // handshake status. In the beginning of a handshake, the state is INITIAL. + // If start_client or start_server request is called, the state becomes at + // least STARTED. When the handshaker server produces the first fame, the + // state becomes SENT. After the handshaker server processes the final frame + // from the peer, the state becomes COMPLETED. + enum HandshakeState { INITIAL, STARTED, SENT, COMPLETED }; + + struct HandshakerContext { + bool is_client = true; + HandshakeState state = INITIAL; + }; + + Status ProcessRequest(HandshakerContext* context, + const HandshakerReq& request, + HandshakerResp* response) { + GPR_ASSERT(context != nullptr && response != nullptr); + response->Clear(); + if (request.has_client_start()) { + gpr_log(GPR_DEBUG, "Process client start request."); + return ProcessClientStart(context, request.client_start(), response); + } else if (request.has_server_start()) { + gpr_log(GPR_DEBUG, "Process server start request."); + return ProcessServerStart(context, request.server_start(), response); + } else if (request.has_next()) { + gpr_log(GPR_DEBUG, "Process next request."); + return ProcessNext(context, request.next(), response); + } + return Status(StatusCode::INVALID_ARGUMENT, "Request is empty."); + } + + Status ProcessClientStart(HandshakerContext* context, + const StartClientHandshakeReq& request, + HandshakerResp* response) { + GPR_ASSERT(context != nullptr && response != nullptr); + // Checks request. + if (context->state != INITIAL) { + return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError); + } + if (request.application_protocols_size() == 0) { + return Status(StatusCode::INVALID_ARGUMENT, + "At least one application protocol needed."); + } + if (request.record_protocols_size() == 0) { + return Status(StatusCode::INVALID_ARGUMENT, + "At least one record protocol needed."); + } + // Sets response. + response->set_out_frames(kClientInitFrame); + response->set_bytes_consumed(0); + response->mutable_status()->set_code(StatusCode::OK); + // Updates handshaker context. + context->is_client = true; + context->state = SENT; + return Status::OK; + } + + Status ProcessServerStart(HandshakerContext* context, + const StartServerHandshakeReq& request, + HandshakerResp* response) { + GPR_ASSERT(context != nullptr && response != nullptr); + // Checks request. + if (context->state != INITIAL) { + return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError); + } + if (request.application_protocols_size() == 0) { + return Status(StatusCode::INVALID_ARGUMENT, + "At least one application protocol needed."); + } + if (request.handshake_parameters().empty()) { + return Status(StatusCode::INVALID_ARGUMENT, + "At least one set of handshake parameters needed."); + } + // Sets response. + if (request.in_bytes().empty()) { + // start_server request does not have in_bytes. + response->set_bytes_consumed(0); + context->state = STARTED; + } else { + // start_server request has in_bytes. + if (request.in_bytes() == kClientInitFrame) { + response->set_out_frames(kServerFrame); + response->set_bytes_consumed(strlen(kClientInitFrame)); + context->state = SENT; + } else { + return Status(StatusCode::UNKNOWN, kInvalidFrameError); + } + } + response->mutable_status()->set_code(StatusCode::OK); + context->is_client = false; + return Status::OK; + } + + Status ProcessNext(HandshakerContext* context, + const NextHandshakeMessageReq& request, + HandshakerResp* response) { + GPR_ASSERT(context != nullptr && response != nullptr); + if (context->is_client) { + // Processes next request on client side. + if (context->state != SENT) { + return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError); + } + if (request.in_bytes() != kServerFrame) { + return Status(StatusCode::UNKNOWN, kInvalidFrameError); + } + response->set_out_frames(kClientFinishFrame); + response->set_bytes_consumed(strlen(kServerFrame)); + context->state = COMPLETED; + } else { + // Processes next request on server side. + HandshakeState current_state = context->state; + if (current_state == STARTED) { + if (request.in_bytes() != kClientInitFrame) { + return Status(StatusCode::UNKNOWN, kInvalidFrameError); + } + response->set_out_frames(kServerFrame); + response->set_bytes_consumed(strlen(kClientInitFrame)); + context->state = SENT; + } else if (current_state == SENT) { + // Client finish frame may be sent along with the first payload from the + // client, handshaker only consumes the client finish frame. + if (request.in_bytes().substr(0, strlen(kClientFinishFrame)) != + kClientFinishFrame) { + return Status(StatusCode::UNKNOWN, kInvalidFrameError); + } + response->set_bytes_consumed(strlen(kClientFinishFrame)); + context->state = COMPLETED; + } else { + return Status(StatusCode::FAILED_PRECONDITION, kWrongStateError); + } + } + // At this point, processing next request succeeded. + response->mutable_status()->set_code(StatusCode::OK); + if (context->state == COMPLETED) { + *response->mutable_result() = GetHandshakerResult(); + } + return Status::OK; + } + + Status WriteErrorResponse( + ServerReaderWriter<HandshakerResp, HandshakerReq>* stream, + const Status& status) { + GPR_ASSERT(!status.ok()); + HandshakerResp response; + response.mutable_status()->set_code(status.error_code()); + response.mutable_status()->set_details(status.error_message()); + stream->Write(response); + return status; + } + + HandshakerResult GetHandshakerResult() { + HandshakerResult result; + result.set_application_protocol("grpc"); + result.set_record_protocol("ALTSRP_GCM_AES128_REKEY"); + result.mutable_peer_identity()->set_service_account("peer_identity"); + result.mutable_local_identity()->set_service_account("local_identity"); + string key(1024, '\0'); + result.set_key_data(key); + result.mutable_peer_rpc_versions()->mutable_max_rpc_version()->set_major(2); + result.mutable_peer_rpc_versions()->mutable_max_rpc_version()->set_minor(1); + result.mutable_peer_rpc_versions()->mutable_min_rpc_version()->set_major(2); + result.mutable_peer_rpc_versions()->mutable_min_rpc_version()->set_minor(1); + return result; + } +}; + +} // namespace gcp +} // namespace grpc + +void RunServer() { + GPR_ASSERT(FLAGS_handshaker_port != 0); + std::ostringstream server_address; + server_address << "[::1]:" << FLAGS_handshaker_port; + grpc::gcp::FakeHandshakerService service; + grpc::ServerBuilder builder; + builder.AddListeningPort(server_address.str(), + grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); + gpr_log(GPR_INFO, "Fake handshaker server listening on %s", + server_address.str().c_str()); + server->Wait(); +} + +int main(int argc, char** argv) { + grpc::testing::InitTest(&argc, &argv, true); + RunServer(); + return 0; +} diff --git a/test/core/tsi/alts/fake_handshaker/handshaker.proto b/test/core/tsi/alts/fake_handshaker/handshaker.proto new file mode 100644 index 0000000000..8af9abfbf5 --- /dev/null +++ b/test/core/tsi/alts/fake_handshaker/handshaker.proto @@ -0,0 +1,224 @@ +// 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. + +syntax = "proto3"; + +import "test/core/tsi/alts/fake_handshaker/transport_security_common.proto"; + +package grpc.gcp; + +option java_package = "io.grpc.alts.internal"; + +enum HandshakeProtocol { + // Default value. + HANDSHAKE_PROTOCOL_UNSPECIFIED = 0; + + // TLS handshake protocol. + TLS = 1; + + // Application Layer Transport Security handshake protocol. + ALTS = 2; +} + +enum NetworkProtocol { + NETWORK_PROTOCOL_UNSPECIFIED = 0; + TCP = 1; + UDP = 2; +} + +message Endpoint { + // IP address. It should contain an IPv4 or IPv6 string literal, e.g. + // "192.168.0.1" or "2001:db8::1". + string ip_address = 1; + + // Port number. + int32 port = 2; + + // Network protocol (e.g., TCP, UDP) associated with this endpoint. + NetworkProtocol protocol = 3; +} + +message Identity { + oneof identity_oneof { + // Service account of a connection endpoint. + string service_account = 1; + + // Hostname of a connection endpoint. + string hostname = 2; + } +} + +message StartClientHandshakeReq { + // Handshake security protocol requested by the client. + HandshakeProtocol handshake_security_protocol = 1; + + // The application protocols supported by the client, e.g., "h2" (for http2), + // "grpc". + repeated string application_protocols = 2; + + // The record protocols supported by the client, e.g., + // "ALTSRP_GCM_AES128". + repeated string record_protocols = 3; + + // (Optional) Describes which server identities are acceptable by the client. + // If target identities are provided and none of them matches the peer + // identity of the server, handshake will fail. + repeated Identity target_identities = 4; + + // (Optional) Application may specify a local identity. Otherwise, the + // handshaker chooses a default local identity. + Identity local_identity = 5; + + // (Optional) Local endpoint information of the connection to the server, + // such as local IP address, port number, and network protocol. + Endpoint local_endpoint = 6; + + // (Optional) Endpoint information of the remote server, such as IP address, + // port number, and network protocol. + Endpoint remote_endpoint = 7; + + // (Optional) If target name is provided, a secure naming check is performed + // to verify that the peer authenticated identity is indeed authorized to run + // the target name. + string target_name = 8; + + // (Optional) RPC protocol versions supported by the client. + RpcProtocolVersions rpc_versions = 9; +} + +message ServerHandshakeParameters { + // The record protocols supported by the server, e.g., + // "ALTSRP_GCM_AES128". + repeated string record_protocols = 1; + + // (Optional) A list of local identities supported by the server, if + // specified. Otherwise, the handshaker chooses a default local identity. + repeated Identity local_identities = 2; +} + +message StartServerHandshakeReq { + // The application protocols supported by the server, e.g., "h2" (for http2), + // "grpc". + repeated string application_protocols = 1; + + // Handshake parameters (record protocols and local identities supported by + // the server) mapped by the handshake protocol. Each handshake security + // protocol (e.g., TLS or ALTS) has its own set of record protocols and local + // identities. Since protobuf does not support enum as key to the map, the key + // to handshake_parameters is the integer value of HandshakeProtocol enum. + map<int32, ServerHandshakeParameters> handshake_parameters = 2; + + // Bytes in out_frames returned from the peer's HandshakerResp. It is possible + // that the peer's out_frames are split into multiple HandshakReq messages. + bytes in_bytes = 3; + + // (Optional) Local endpoint information of the connection to the client, + // such as local IP address, port number, and network protocol. + Endpoint local_endpoint = 4; + + // (Optional) Endpoint information of the remote client, such as IP address, + // port number, and network protocol. + Endpoint remote_endpoint = 5; + + // (Optional) RPC protocol versions supported by the server. + RpcProtocolVersions rpc_versions = 6; +} + +message NextHandshakeMessageReq { + // Bytes in out_frames returned from the peer's HandshakerResp. It is possible + // that the peer's out_frames are split into multiple NextHandshakerMessageReq + // messages. + bytes in_bytes = 1; +} + +message HandshakerReq { + oneof req_oneof { + // The start client handshake request message. + StartClientHandshakeReq client_start = 1; + + // The start server handshake request message. + StartServerHandshakeReq server_start = 2; + + // The next handshake request message. + NextHandshakeMessageReq next = 3; + } +} + +message HandshakerResult { + // The application protocol negotiated for this connection. + string application_protocol = 1; + + // The record protocol negotiated for this connection. + string record_protocol = 2; + + // Cryptographic key data. The key data may be more than the key length + // required for the record protocol, thus the client of the handshaker + // service needs to truncate the key data into the right key length. + bytes key_data = 3; + + // The authenticated identity of the peer. + Identity peer_identity = 4; + + // The local identity used in the handshake. + Identity local_identity = 5; + + // Indicate whether the handshaker service client should keep the channel + // between the handshaker service open, e.g., in order to handle + // post-handshake messages in the future. + bool keep_channel_open = 6; + + // The RPC protocol versions supported by the peer. + RpcProtocolVersions peer_rpc_versions = 7; +} + +message HandshakerStatus { + // The status code. This could be the gRPC status code. + uint32 code = 1; + + // The status details. + string details = 2; +} + +message HandshakerResp { + // Frames to be given to the peer for the NextHandshakeMessageReq. May be + // empty if no out_frames have to be sent to the peer or if in_bytes in the + // HandshakerReq are incomplete. All the non-empty out frames must be sent to + // the peer even if the handshaker status is not OK as these frames may + // contain the alert frames. + bytes out_frames = 1; + + // Number of bytes in the in_bytes consumed by the handshaker. It is possible + // that part of in_bytes in HandshakerReq was unrelated to the handshake + // process. + uint32 bytes_consumed = 2; + + // This is set iff the handshake was successful. out_frames may still be set + // to frames that needs to be forwarded to the peer. + HandshakerResult result = 3; + + // Status of the handshaker. + HandshakerStatus status = 4; +} + +service HandshakerService { + // Handshaker service accepts a stream of handshaker request, returning a + // stream of handshaker response. Client is expected to send exactly one + // message with either client_start or server_start followed by one or more + // messages with next. Each time client sends a request, the handshaker + // service expects to respond. Client does not have to wait for service's + // response before sending next request. + rpc DoHandshake(stream HandshakerReq) + returns (stream HandshakerResp) { + } +} diff --git a/test/core/tsi/alts/fake_handshaker/transport_security_common.proto b/test/core/tsi/alts/fake_handshaker/transport_security_common.proto new file mode 100644 index 0000000000..d0f861e644 --- /dev/null +++ b/test/core/tsi/alts/fake_handshaker/transport_security_common.proto @@ -0,0 +1,40 @@ +// 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. + +syntax = "proto3"; + +package grpc.gcp; + +option java_package = "io.grpc.alts.internal"; + +// The security level of the created channel. The list is sorted in increasing +// level of security. This order must always be maintained. +enum SecurityLevel { + SECURITY_NONE = 0; + INTEGRITY_ONLY = 1; + INTEGRITY_AND_PRIVACY = 2; +} + +// Max and min supported RPC protocol versions. +message RpcProtocolVersions { + // RPC version contains a major version and a minor version. + message Version { + uint32 major = 1; + uint32 minor = 2; + } + // Maximum supported RPC version. + Version max_rpc_version = 1; + // Minimum supported RPC version. + Version min_rpc_version = 2; +} diff --git a/test/core/tsi/alts/frame_protector/BUILD b/test/core/tsi/alts/frame_protector/BUILD new file mode 100644 index 0000000000..dd1966b379 --- /dev/null +++ b/test/core/tsi/alts/frame_protector/BUILD @@ -0,0 +1,71 @@ +# 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. + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") + +licenses(["notice"]) # Apache v2 + +grpc_package(name = "test/core/tsi/alts/frame_protector") + +grpc_cc_test( + name = "alts_counter_test", + srcs = ["alts_counter_test.cc"], + language = "C++", + deps = [ + "//:alts_frame_protector", + "//:gpr", + "//:grpc", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + ], +) + +grpc_cc_test( + name = "alts_crypter_test", + srcs = ["alts_crypter_test.cc"], + language = "C++", + deps = [ + "//:alts_frame_protector", + "//:gpr", + "//:grpc", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + ], +) + +grpc_cc_test( + name = "alts_frame_protector_test", + srcs = ["alts_frame_protector_test.cc"], + language = "C++", + deps = [ + "//:alts_frame_protector", + "//:gpr", + "//:grpc", + "//:tsi", + "//:tsi_interface", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/tsi:transport_security_test_lib", + ], +) + +grpc_cc_test( + name = "frame_handler_test", + srcs = ["frame_handler_test.cc"], + language = "C++", + deps = [ + "//:alts_frame_protector", + "//:gpr", + "//:gpr_base", + "//:grpc", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + ], +) diff --git a/test/core/tsi/alts/frame_protector/alts_counter_test.cc b/test/core/tsi/alts/frame_protector/alts_counter_test.cc new file mode 100644 index 0000000000..49ff82108b --- /dev/null +++ b/test/core/tsi/alts/frame_protector/alts_counter_test.cc @@ -0,0 +1,180 @@ +/* + * + * 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/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/tsi/alts/frame_protector/alts_counter.h" +#include "test/core/tsi/alts/crypt/gsec_test_util.h" + +const size_t kSmallCounterSize = 4; +const size_t kSmallOverflowSize = 1; +const size_t kGcmCounterSize = 12; +const size_t kGcmOverflowSize = 5; + +static bool do_bytes_represent_client(alts_counter* ctr, unsigned char* counter, + size_t size) { + return (ctr->counter[size - 1] & 0x80) == 0x80; +} + +static void alts_counter_test_input_sanity_check(size_t counter_size, + size_t overflow_size) { + alts_counter* ctr = nullptr; + char* error_details = nullptr; + + /* Input sanity check on alts_counter_create(). */ + /* Invalid counter size. */ + grpc_status_code status = + alts_counter_create(true, 0, overflow_size, &ctr, &error_details); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_details, + "counter_size is invalid.")); + gpr_free(error_details); + + /* Invalid overflow size. */ + status = alts_counter_create(true, counter_size, 0, &ctr, &error_details); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_details, + "overflow_size is invalid.")); + gpr_free(error_details); + + /* alts_counter is nullptr. */ + status = alts_counter_create(true, counter_size, overflow_size, nullptr, + &error_details); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_details, + "crypter_counter is nullptr.")); + gpr_free(error_details); + + status = alts_counter_create(true, counter_size, overflow_size, &ctr, + &error_details); + GPR_ASSERT(status == GRPC_STATUS_OK); + + /* Input sanity check on alts_counter_increment(). */ + /* crypter_counter is nullptr. */ + bool is_overflow = false; + status = alts_counter_increment(nullptr, &is_overflow, &error_details); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_details, + "crypter_counter is nullptr.")); + gpr_free(error_details); + /* is_overflow is nullptr. */ + status = alts_counter_increment(ctr, nullptr, &error_details); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_details, + "is_overflow is nullptr.")); + gpr_free(error_details); + alts_counter_destroy(ctr); +} + +static void alts_counter_test_overflow_full_range(bool is_client, + size_t counter_size, + size_t overflow_size) { + alts_counter* ctr = nullptr; + char* error_details = nullptr; + grpc_status_code status = alts_counter_create( + is_client, counter_size, overflow_size, &ctr, &error_details); + GPR_ASSERT(status == GRPC_STATUS_OK); + unsigned char* expected = + static_cast<unsigned char*>(gpr_zalloc(counter_size)); + if (is_client) { + expected[counter_size - 1] = 0x80; + } + /* Do a single iteration to ensure the counter is initialized as expected. */ + GPR_ASSERT(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr), + counter_size) == is_client); + GPR_ASSERT(memcmp(alts_counter_get_counter(ctr), expected, counter_size) == + 0); + bool is_overflow = false; + GPR_ASSERT(alts_counter_increment(ctr, &is_overflow, &error_details) == + GRPC_STATUS_OK); + GPR_ASSERT(!is_overflow); + /** + * The counter can return 2^{overflow_size * 8} counters. The + * high-order bit is fixed to the client/server. The last call will yield a + * useable counter, but overflow the counter object. + */ + int iterations = 1 << (overflow_size * 8); + int ind = 1; + for (ind = 1; ind < iterations - 1; ind++) { + GPR_ASSERT(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr), + counter_size) == is_client); + GPR_ASSERT(alts_counter_increment(ctr, &is_overflow, &error_details) == + GRPC_STATUS_OK); + GPR_ASSERT(!is_overflow); + } + GPR_ASSERT(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr), + counter_size) == is_client); + GPR_ASSERT(alts_counter_increment(ctr, &is_overflow, &error_details) == + GRPC_STATUS_FAILED_PRECONDITION); + GPR_ASSERT(is_overflow); + gpr_free(expected); + alts_counter_destroy(ctr); +} + +/* Set the counter manually and make sure it overflows as expected. */ +static void alts_counter_test_overflow_single_increment(bool is_client, + size_t counter_size, + size_t overflow_size) { + alts_counter* ctr = nullptr; + char* error_details = nullptr; + grpc_status_code status = alts_counter_create( + is_client, counter_size, overflow_size, &ctr, &error_details); + GPR_ASSERT(status == GRPC_STATUS_OK); + unsigned char* expected = + static_cast<unsigned char*>(gpr_zalloc(counter_size)); + memset(expected, 0xFF, overflow_size); + expected[0] = 0xFE; + + if (is_client) { + expected[counter_size - 1] = 0x80; + } + memcpy(ctr->counter, expected, counter_size); + GPR_ASSERT(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr), + counter_size) == is_client); + GPR_ASSERT(memcmp(expected, alts_counter_get_counter(ctr), counter_size) == + 0); + bool is_overflow = false; + GPR_ASSERT(alts_counter_increment(ctr, &is_overflow, &error_details) == + GRPC_STATUS_OK); + GPR_ASSERT(!is_overflow); + GPR_ASSERT(do_bytes_represent_client(ctr, alts_counter_get_counter(ctr), + counter_size) == is_client); + expected[0] = static_cast<unsigned char>(expected[0] + 1); + GPR_ASSERT(memcmp(expected, alts_counter_get_counter(ctr), counter_size) == + 0); + GPR_ASSERT(alts_counter_increment(ctr, &is_overflow, &error_details) == + GRPC_STATUS_FAILED_PRECONDITION); + GPR_ASSERT(is_overflow); + gpr_free(expected); + alts_counter_destroy(ctr); +} + +int main(int argc, char** argv) { + alts_counter_test_input_sanity_check(kGcmCounterSize, kGcmOverflowSize); + alts_counter_test_overflow_full_range(true, kSmallCounterSize, + kSmallOverflowSize); + alts_counter_test_overflow_full_range(false, kSmallCounterSize, + kSmallOverflowSize); + alts_counter_test_overflow_single_increment(true, kGcmCounterSize, + kGcmOverflowSize); + alts_counter_test_overflow_single_increment(false, kGcmCounterSize, + kGcmOverflowSize); + + return 0; +} diff --git a/test/core/tsi/alts/frame_protector/alts_crypter_test.cc b/test/core/tsi/alts/frame_protector/alts_crypter_test.cc new file mode 100644 index 0000000000..0ad616bcd6 --- /dev/null +++ b/test/core/tsi/alts/frame_protector/alts_crypter_test.cc @@ -0,0 +1,493 @@ +/* + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/tsi/alts/frame_protector/alts_crypter.h" +#include "test/core/tsi/alts/crypt/gsec_test_util.h" + +static void alts_crypter_test_random_seal_unseal(alts_crypter* server_seal, + alts_crypter* server_unseal, + alts_crypter* client_seal, + alts_crypter* client_unseal) { + size_t data_size = gsec_test_bias_random_uint32(1024) + 1; + size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(server_seal); + size_t protected_data_size = data_size + num_overhead_bytes; + uint8_t* data_buffer = static_cast<uint8_t*>(gpr_malloc(protected_data_size)); + gsec_test_random_bytes(data_buffer, data_size); + uint8_t* duplicate_buffer = nullptr; + gsec_test_copy(data_buffer, &duplicate_buffer, data_size); + + /* Client seal and server unseal */ + size_t size = data_size; + grpc_status_code status = alts_crypter_process_in_place( + client_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + status = alts_crypter_process_in_place( + server_unseal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(data_buffer, duplicate_buffer, data_size) == 0); + GPR_ASSERT(size == data_size); + /* Server seal and client unseal */ + status = alts_crypter_process_in_place( + server_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + status = alts_crypter_process_in_place( + client_unseal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(data_buffer, duplicate_buffer, data_size) == 0); + GPR_ASSERT(size == data_size); + gpr_free(data_buffer); + gpr_free(duplicate_buffer); +} + +static void alts_crypter_test_multiple_random_seal_unseal( + alts_crypter* server_seal, alts_crypter* server_unseal, + alts_crypter* client_seal, alts_crypter* client_unseal) { + size_t data_size = gsec_test_bias_random_uint32(1024) + 1; + size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(server_seal); + size_t protected_data_size = data_size + num_overhead_bytes; + + uint8_t* data_buffer1 = + static_cast<uint8_t*>(gpr_malloc(protected_data_size)); + uint8_t* data_buffer2 = + static_cast<uint8_t*>(gpr_malloc(protected_data_size)); + uint8_t* duplicate_buffer1 = nullptr; + uint8_t* duplicate_buffer2 = nullptr; + gsec_test_random_bytes(data_buffer1, data_size); + gsec_test_random_bytes(data_buffer2, data_size); + gsec_test_copy(data_buffer1, &duplicate_buffer1, data_size); + gsec_test_copy(data_buffer2, &duplicate_buffer2, data_size); + + /* Client seal and server unseal */ + size_t size1 = data_size, size2 = data_size; + grpc_status_code status = alts_crypter_process_in_place( + client_seal, data_buffer1, protected_data_size, size1, &size1, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size1 == protected_data_size); + status = alts_crypter_process_in_place( + client_seal, data_buffer2, protected_data_size, size2, &size2, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size2 == protected_data_size); + status = alts_crypter_process_in_place( + server_unseal, data_buffer1, protected_data_size, size1, &size1, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(data_buffer1, duplicate_buffer1, data_size) == 0); + GPR_ASSERT(size1 == data_size); + status = alts_crypter_process_in_place( + server_unseal, data_buffer2, protected_data_size, size2, &size2, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(data_buffer2, duplicate_buffer2, data_size) == 0); + GPR_ASSERT(size2 == data_size); + + /* Server seal and client unseal */ + status = alts_crypter_process_in_place( + server_seal, data_buffer1, protected_data_size, size1, &size1, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size1 == protected_data_size); + status = alts_crypter_process_in_place( + server_seal, data_buffer2, protected_data_size, size2, &size2, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size2 == protected_data_size); + status = alts_crypter_process_in_place( + client_unseal, data_buffer1, protected_data_size, size1, &size1, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(data_buffer1, duplicate_buffer1, data_size) == 0); + GPR_ASSERT(size1 == data_size); + status = alts_crypter_process_in_place( + client_unseal, data_buffer2, protected_data_size, size2, &size2, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(data_buffer2, duplicate_buffer2, data_size) == 0); + GPR_ASSERT(size2 == data_size); + + gpr_free(data_buffer1); + gpr_free(data_buffer2); + gpr_free(duplicate_buffer1); + gpr_free(duplicate_buffer2); +} + +static void alts_crypter_test_corrupted_unseal(alts_crypter* server_seal, + alts_crypter* server_unseal, + alts_crypter* client_seal, + alts_crypter* client_unseal) { + size_t data_size = gsec_test_bias_random_uint32(1024) + 1; + size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(server_seal); + size_t protected_data_size = data_size + num_overhead_bytes; + auto* data_buffer = static_cast<uint8_t*>(gpr_malloc(protected_data_size)); + auto* zero_buffer = static_cast<uint8_t*>(gpr_zalloc(data_size)); + + /* Corrupt a random byte in protected data. */ + size_t size = data_size; + gsec_test_random_bytes(data_buffer, data_size); + grpc_status_code status = alts_crypter_process_in_place( + client_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + uint8_t* corrupted_data_buffer; + char* error_message = nullptr; + gsec_test_copy_and_alter_random_byte(data_buffer, &corrupted_data_buffer, + protected_data_size); + status = alts_crypter_process_in_place(server_unseal, corrupted_data_buffer, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Checking tag failed")); + GPR_ASSERT(memcmp(corrupted_data_buffer, zero_buffer, data_size) == 0); + gpr_free(corrupted_data_buffer); + gpr_free(error_message); + + /* Corrupt the beginning of protected data. */ + size = data_size; + gsec_test_random_bytes(data_buffer, data_size); + status = alts_crypter_process_in_place( + client_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + gsec_test_copy(data_buffer, &corrupted_data_buffer, protected_data_size); + (*corrupted_data_buffer)++; + status = alts_crypter_process_in_place(server_unseal, corrupted_data_buffer, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Checking tag failed")); + GPR_ASSERT(memcmp(corrupted_data_buffer, zero_buffer, data_size) == 0); + gpr_free(corrupted_data_buffer); + gpr_free(error_message); + + /* Corrupt the end of protected data. */ + size = data_size; + gsec_test_random_bytes(data_buffer, data_size); + status = alts_crypter_process_in_place( + client_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + gsec_test_copy(data_buffer, &corrupted_data_buffer, protected_data_size); + (*(corrupted_data_buffer + protected_data_size - 1))++; + status = alts_crypter_process_in_place(server_unseal, corrupted_data_buffer, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Checking tag failed")); + GPR_ASSERT(memcmp(corrupted_data_buffer, zero_buffer, data_size) == 0); + gpr_free(corrupted_data_buffer); + gpr_free(error_message); + + gpr_free(data_buffer); + gpr_free(zero_buffer); +} + +static void alts_crypter_test_unsync_seal_unseal(alts_crypter* server_seal, + alts_crypter* server_unseal, + alts_crypter* client_seal, + alts_crypter* client_unseal) { + size_t data_size = gsec_test_bias_random_uint32(1024) + 1; + size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(server_seal); + size_t protected_data_size = data_size + num_overhead_bytes; + auto* data_buffer = static_cast<uint8_t*>(gpr_malloc(protected_data_size)); + auto* zero_buffer = static_cast<uint8_t*>(gpr_zalloc(data_size)); + + /* Perform two seals at client, one unseal at server. */ + size_t size = data_size; + gsec_test_random_bytes(data_buffer, data_size); + grpc_status_code status = alts_crypter_process_in_place( + client_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + + size = data_size; + gsec_test_random_bytes(data_buffer, data_size); + status = alts_crypter_process_in_place( + client_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + + char* error_message = nullptr; + status = alts_crypter_process_in_place(server_unseal, data_buffer, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Checking tag failed")); + GPR_ASSERT(memcmp(data_buffer, zero_buffer, data_size) == 0); + gpr_free(error_message); + + /* Perform two seals at server, one unseal at client. */ + size = data_size; + gsec_test_random_bytes(data_buffer, data_size); + status = alts_crypter_process_in_place( + server_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + + size = data_size; + gsec_test_random_bytes(data_buffer, data_size); + status = alts_crypter_process_in_place( + server_seal, data_buffer, protected_data_size, size, &size, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(size == protected_data_size); + + status = alts_crypter_process_in_place(client_unseal, data_buffer, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Checking tag failed")); + GPR_ASSERT(memcmp(data_buffer, zero_buffer, data_size) == 0); + gpr_free(error_message); + gpr_free(data_buffer); + gpr_free(zero_buffer); +} + +static void alts_crypter_test_input_sanity_check(alts_crypter* crypter_seal, + alts_crypter* crypter_unseal) { + size_t data_size = gsec_test_bias_random_uint32(1024) + 1; + size_t num_overhead_bytes = alts_crypter_num_overhead_bytes(crypter_seal); + size_t protected_data_size = data_size + num_overhead_bytes; + auto* data_buffer = static_cast<uint8_t*>(gpr_malloc(protected_data_size)); + gsec_test_random_bytes(data_buffer, data_size); + char* error_message = nullptr; + size_t size = data_size; + + /* Crypter is nullptr. */ + grpc_status_code status = alts_crypter_process_in_place( + nullptr, data_buffer, protected_data_size, size, &size, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "crypter or crypter->vtable has not been initialized properly.")); + gpr_free(error_message); + + /* Seal data is nullptr. */ + size = data_size; + status = alts_crypter_process_in_place( + crypter_seal, nullptr, protected_data_size, size, &size, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, "data is nullptr.")); + gpr_free(error_message); + + /* Seal data size is 0. */ + size = 0; + status = alts_crypter_process_in_place(crypter_seal, data_buffer, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "data_size is zero.")); + gpr_free(error_message); + + /* Seal data buffer has a size smaller than the required. */ + size = data_size; + status = alts_crypter_process_in_place(crypter_seal, data_buffer, + protected_data_size - 1, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "data_allocated_size is smaller than sum of data_size and " + "num_overhead_bytes.")); + gpr_free(error_message); + + /* Unseal data is nullptr. */ + size = data_size; + status = alts_crypter_process_in_place(crypter_unseal, nullptr, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, "data is nullptr.")); + gpr_free(error_message); + + /* Unseal data size is 0. */ + size = 0; + status = alts_crypter_process_in_place(crypter_unseal, data_buffer, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "data_size is smaller than num_overhead_bytes.")); + gpr_free(error_message); + + /* Unseal data size is smaller than number of overhead bytes. */ + size = num_overhead_bytes - 1; + status = alts_crypter_process_in_place(crypter_unseal, data_buffer, + protected_data_size, size, &size, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "data_size is smaller than num_overhead_bytes.")); + gpr_free(error_message); + gpr_free(data_buffer); +} + +static void create_random_alts_seal_crypter( + alts_crypter** server_seal, alts_crypter** server_unseal, + alts_crypter** client_seal, alts_crypter** client_unseal, + gsec_aead_crypter** server_crypter_seal, + gsec_aead_crypter** server_crypter_unseal, + gsec_aead_crypter** client_crypter_seal, + gsec_aead_crypter** client_crypter_unseal, bool rekey) { + size_t key_length = rekey ? kAes128GcmRekeyKeyLength : kAes128GcmKeyLength; + uint8_t* key; + gsec_test_random_array(&key, key_length); + gsec_aes_gcm_aead_crypter_create(key, key_length, kAesGcmNonceLength, + kAesGcmTagLength, rekey, server_crypter_seal, + nullptr); + gsec_aes_gcm_aead_crypter_create(key, key_length, kAesGcmNonceLength, + kAesGcmTagLength, rekey, + server_crypter_unseal, nullptr); + gsec_aes_gcm_aead_crypter_create(key, key_length, kAesGcmNonceLength, + kAesGcmTagLength, rekey, client_crypter_seal, + nullptr); + gsec_aes_gcm_aead_crypter_create(key, key_length, kAesGcmNonceLength, + kAesGcmTagLength, rekey, + client_crypter_unseal, nullptr); + + size_t overflow_size = rekey ? 8 : 5; + alts_seal_crypter_create(*client_crypter_seal, /*is_client=*/true, + overflow_size, client_seal, nullptr); + alts_unseal_crypter_create(*client_crypter_unseal, /*is_client=*/true, + overflow_size, client_unseal, nullptr); + alts_seal_crypter_create(*server_crypter_seal, /*is_client=*/false, + overflow_size, server_seal, nullptr); + alts_unseal_crypter_create(*server_crypter_unseal, /*is_client=*/false, + overflow_size, server_unseal, nullptr); + gpr_free(key); +} + +static void destroy_random_alts_seal_crypter(alts_crypter* server_seal, + alts_crypter* server_unseal, + alts_crypter* client_seal, + alts_crypter* client_unseal) { + alts_crypter_destroy(server_seal); + alts_crypter_destroy(server_unseal); + alts_crypter_destroy(client_seal); + alts_crypter_destroy(client_unseal); +} + +static void alts_crypter_do_generic_tests() { + alts_crypter *server_seal = nullptr, *server_unseal = nullptr, + *client_seal = nullptr, *client_unseal = nullptr; + gsec_aead_crypter *server_crypter_seal = nullptr, + *server_crypter_unseal = nullptr, + *client_crypter_seal = nullptr, + *client_crypter_unseal = nullptr; + /* Random seal and unseal tests */ + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/false); + alts_crypter_test_random_seal_unseal(server_seal, server_unseal, client_seal, + client_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/true); + alts_crypter_test_random_seal_unseal(server_seal, server_unseal, client_seal, + client_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + /* Multiple random seal and unseal tests */ + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/false); + alts_crypter_test_multiple_random_seal_unseal(server_seal, server_unseal, + client_seal, client_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/true); + alts_crypter_test_multiple_random_seal_unseal(server_seal, server_unseal, + client_seal, client_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + /* Corrupted unseal tests */ + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/false); + alts_crypter_test_corrupted_unseal(server_seal, server_unseal, client_seal, + client_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/true); + alts_crypter_test_corrupted_unseal(server_seal, server_unseal, client_seal, + client_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + /* Unsync seal and unseal tests */ + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/false); + alts_crypter_test_unsync_seal_unseal(server_seal, server_unseal, client_seal, + client_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/true); + alts_crypter_test_unsync_seal_unseal(server_seal, server_unseal, client_seal, + client_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + /* Input sanity check tests */ + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/false); + alts_crypter_test_input_sanity_check(server_seal, server_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); + + create_random_alts_seal_crypter(&server_seal, &server_unseal, &client_seal, + &client_unseal, &server_crypter_seal, + &server_crypter_unseal, &client_crypter_seal, + &client_crypter_unseal, /*rekey=*/true); + alts_crypter_test_input_sanity_check(server_seal, server_unseal); + destroy_random_alts_seal_crypter(server_seal, server_unseal, client_seal, + client_unseal); +} + +int main(int argc, char** argv) { + alts_crypter_do_generic_tests(); + return 0; +} diff --git a/test/core/tsi/alts/frame_protector/alts_frame_protector_test.cc b/test/core/tsi/alts/frame_protector/alts_frame_protector_test.cc new file mode 100644 index 0000000000..2bd4958763 --- /dev/null +++ b/test/core/tsi/alts/frame_protector/alts_frame_protector_test.cc @@ -0,0 +1,394 @@ +/* + * + * 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/alloc.h> +#include <grpc/support/log.h> + +#include <stdbool.h> + +#include "src/core/tsi/alts/crypt/gsec.h" +#include "src/core/tsi/alts/frame_protector/alts_frame_protector.h" +#include "src/core/tsi/transport_security_interface.h" +#include "test/core/tsi/alts/crypt/gsec_test_util.h" +#include "test/core/tsi/transport_security_test_lib.h" + +const size_t kChannelSize = 32768; + +static void alts_test_do_round_trip_check_frames( + tsi_test_frame_protector_fixture* fixture, const uint8_t* key, + const size_t key_size, bool rekey, const uint8_t* client_message, + const size_t client_message_size, const uint8_t* client_expected_frames, + const size_t client_frame_size, const uint8_t* server_message, + const size_t server_message_size, const uint8_t* server_expected_frames, + const size_t server_frame_size) { + GPR_ASSERT(fixture != nullptr); + GPR_ASSERT(fixture->config != nullptr); + tsi_frame_protector* client_frame_protector = nullptr; + tsi_frame_protector* server_frame_protector = nullptr; + tsi_test_frame_protector_config* config = fixture->config; + tsi_test_channel* channel = fixture->channel; + /* Create a client frame protector. */ + size_t client_max_output_protected_frame_size = + config->client_max_output_protected_frame_size; + GPR_ASSERT( + alts_create_frame_protector(key, key_size, /*is_client=*/true, rekey, + client_max_output_protected_frame_size == 0 + ? nullptr + : &client_max_output_protected_frame_size, + &client_frame_protector) == TSI_OK); + /* Create a server frame protector. */ + size_t server_max_output_protected_frame_size = + config->server_max_output_protected_frame_size; + GPR_ASSERT( + alts_create_frame_protector(key, key_size, /*is_client=*/false, rekey, + server_max_output_protected_frame_size == 0 + ? nullptr + : &server_max_output_protected_frame_size, + &server_frame_protector) == TSI_OK); + tsi_test_frame_protector_fixture_init(fixture, client_frame_protector, + server_frame_protector); + /* Client sends a message to server. */ + uint8_t* saved_client_message = config->client_message; + config->client_message = const_cast<uint8_t*>(client_message); + config->client_message_size = client_message_size; + tsi_test_frame_protector_send_message_to_peer(config, channel, + client_frame_protector, + /*is_client=*/true); + /* Verify if the generated frame is the same as the expected. */ + GPR_ASSERT(channel->bytes_written_to_server_channel == client_frame_size); + GPR_ASSERT(memcmp(client_expected_frames, channel->server_channel, + client_frame_size) == 0); + unsigned char* server_received_message = + static_cast<unsigned char*>(gpr_malloc(kChannelSize)); + size_t server_received_message_size = 0; + tsi_test_frame_protector_receive_message_from_peer( + config, channel, server_frame_protector, server_received_message, + &server_received_message_size, /*is_client=*/false); + GPR_ASSERT(config->client_message_size == server_received_message_size); + GPR_ASSERT(memcmp(config->client_message, server_received_message, + server_received_message_size) == 0); + /* Server sends a message to client. */ + uint8_t* saved_server_message = config->server_message; + config->server_message = const_cast<uint8_t*>(server_message); + config->server_message_size = server_message_size; + tsi_test_frame_protector_send_message_to_peer(config, channel, + server_frame_protector, + /*is_client=*/false); + /* Verify if the generated frame is the same as the expected. */ + GPR_ASSERT(channel->bytes_written_to_client_channel == server_frame_size); + GPR_ASSERT(memcmp(server_expected_frames, channel->client_channel, + server_frame_size) == 0); + unsigned char* client_received_message = + static_cast<unsigned char*>(gpr_malloc(kChannelSize)); + size_t client_received_message_size = 0; + tsi_test_frame_protector_receive_message_from_peer( + config, channel, client_frame_protector, client_received_message, + &client_received_message_size, + /*is_client=*/true); + GPR_ASSERT(config->server_message_size == client_received_message_size); + GPR_ASSERT(memcmp(config->server_message, client_received_message, + client_received_message_size) == 0); + config->client_message = saved_client_message; + config->server_message = saved_server_message; + /* Destroy server and client frame protectors. */ + gpr_free(server_received_message); + gpr_free(client_received_message); +} + +static void alts_test_do_round_trip_vector_tests() { + const uint8_t key[] = {0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08}; + const char small_message[] = {'C', 'h', 'a', 'p', 'i', ' ', + 'C', 'h', 'a', 'p', 'o'}; + const uint8_t large_message[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, + 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, + 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, + 0x1a, 0xaf, 0xd2, 0x55, 0xd6, 0x09, 0xb1, 0xf0, 0x56, 0x63, 0x7a, 0x0d, + 0x46, 0xdf, 0x99, 0x8d, 0x88, 0xe5, 0x22, 0x2a, 0xb2, 0xc2, 0x84, 0x65, + 0x12, 0x15, 0x35, 0x24, 0xc0, 0x89, 0x5e, 0x81, 0x08, 0x06, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30}; + const size_t small_message_size = sizeof(small_message) / sizeof(uint8_t); + const size_t large_message_size = sizeof(large_message) / sizeof(uint8_t); + /* Test small client message and large server message. */ + const uint8_t client_expected_frame1[] = { + 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09, 0xd8, 0xd5, 0x92, + 0x4d, 0x50, 0x32, 0xb7, 0x1f, 0xb8, 0xf2, 0xbb, 0x43, 0xc7, 0xe2, 0x94, + 0x3d, 0x3e, 0x9a, 0x78, 0x76, 0xaa, 0x0a, 0x6b, 0xfa, 0x98, 0x3a}; + const uint8_t server_expected_frame1[] = { + 0x94, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4b, 0xf8, 0xc8, + 0xe7, 0x8f, 0x1a, 0x26, 0x37, 0x44, 0xa2, 0x5c, 0x55, 0x94, 0x30, 0x4e, + 0x3e, 0x16, 0xe7, 0x9e, 0x96, 0xe8, 0x1b, 0xc0, 0xdd, 0x52, 0x30, 0x06, + 0xc2, 0x72, 0x9a, 0xa1, 0x0b, 0xdb, 0xdc, 0x19, 0x8c, 0x93, 0x5e, 0x84, + 0x1f, 0x4b, 0x97, 0x26, 0xf0, 0x73, 0x85, 0x59, 0x00, 0x95, 0xc1, 0xc5, + 0x22, 0x2f, 0x70, 0x85, 0x68, 0x2c, 0x4f, 0xfe, 0x30, 0x26, 0x91, 0xde, + 0x62, 0x55, 0x1d, 0x35, 0x01, 0x96, 0x1c, 0xe7, 0xa2, 0x8b, 0x14, 0x8a, + 0x5e, 0x1b, 0x4a, 0x3b, 0x4f, 0x65, 0x0f, 0xca, 0x79, 0x10, 0xb4, 0xdd, + 0xf7, 0xa4, 0x8b, 0x64, 0x2f, 0x00, 0x39, 0x60, 0x03, 0xfc, 0xe1, 0x8b, + 0x5c, 0x19, 0xba, 0xcc, 0x46, 0xba, 0x88, 0xdd, 0x40, 0x42, 0x27, 0x4f, + 0xe4, 0x1a, 0x6a, 0x31, 0x6c, 0x1c, 0xb0, 0xb6, 0x5c, 0x3e, 0xca, 0x84, + 0x9b, 0x5f, 0x04, 0x84, 0x11, 0xa9, 0xf8, 0x39, 0xe7, 0xe7, 0xc5, 0xc4, + 0x33, 0x9f, 0x63, 0x21, 0x9a, 0x7c, 0x9c, 0x64}; + const size_t client_frame_size1 = + sizeof(client_expected_frame1) / sizeof(uint8_t); + const size_t server_frame_size1 = + sizeof(server_expected_frame1) / sizeof(uint8_t); + tsi_test_frame_protector_fixture* fixture = + tsi_test_frame_protector_fixture_create(); + alts_test_do_round_trip_check_frames( + fixture, key, kAes128GcmKeyLength, /*rekey=*/false, + reinterpret_cast<const uint8_t*>(small_message), small_message_size, + client_expected_frame1, client_frame_size1, large_message, + large_message_size, server_expected_frame1, server_frame_size1); + tsi_test_frame_protector_fixture_destroy(fixture); + /** + * Test large client message, small server message, and small + * message_buffer_allocated_size. + */ + const uint8_t client_expected_frame2[] = { + 0x94, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x93, 0x81, 0x86, 0xc7, + 0xdc, 0xf4, 0x77, 0x3a, 0xdb, 0x91, 0x94, 0x61, 0xba, 0xed, 0xd5, 0x37, + 0x47, 0x53, 0x0c, 0xe1, 0xbf, 0x59, 0x23, 0x20, 0xde, 0x8b, 0x25, 0x13, + 0x72, 0xe7, 0x8a, 0x4f, 0x32, 0x61, 0xc6, 0xda, 0xc3, 0xe9, 0xff, 0x31, + 0x33, 0x53, 0x4a, 0xf8, 0xc9, 0x98, 0xe4, 0x19, 0x71, 0x9c, 0x5e, 0x72, + 0xc7, 0x35, 0x97, 0x78, 0x30, 0xf2, 0xc4, 0xd1, 0x53, 0xd5, 0x6e, 0x8f, + 0x4f, 0xd9, 0x28, 0x5a, 0xfd, 0x22, 0x57, 0x7f, 0x95, 0xb4, 0x8a, 0x5e, + 0x7c, 0x47, 0xa8, 0xcf, 0x64, 0x3d, 0x83, 0xa5, 0xcf, 0xc3, 0xfe, 0x54, + 0xc2, 0x6a, 0x40, 0xc4, 0xfb, 0x8e, 0x07, 0x77, 0x70, 0x8f, 0x99, 0x94, + 0xb1, 0xd5, 0xa7, 0xf9, 0x0d, 0xc7, 0x11, 0xc5, 0x6f, 0x4a, 0x4f, 0x56, + 0xd5, 0xe2, 0x9c, 0xbb, 0x95, 0x7a, 0xd0, 0x9f, 0x30, 0x54, 0xca, 0x6d, + 0x5c, 0x8e, 0x83, 0xa0, 0x04, 0x5e, 0xd0, 0x22, 0x8c, 0x2a, 0x7f, 0xdb, + 0xfe, 0xb3, 0x2e, 0xae, 0x22, 0xe6, 0xf4, 0xb7}; + const uint8_t server_expected_frame2[] = { + 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x33, 0x12, 0xab, 0x9d, + 0x76, 0x2b, 0x5f, 0xab, 0xf3, 0x6d, 0xc4, 0xaa, 0xe5, 0x1e, 0x63, 0xc1, + 0x7b, 0x7b, 0x10, 0xd5, 0x63, 0x0f, 0x29, 0xad, 0x17, 0x33, 0x73}; + const size_t client_frame_size2 = + sizeof(client_expected_frame2) / sizeof(uint8_t); + const size_t server_frame_size2 = + sizeof(server_expected_frame2) / sizeof(uint8_t); + fixture = tsi_test_frame_protector_fixture_create(); + alts_test_do_round_trip_check_frames( + fixture, key, kAes128GcmKeyLength, /*rekey=*/false, large_message, + large_message_size, client_expected_frame2, client_frame_size2, + reinterpret_cast<const uint8_t*>(small_message), small_message_size, + server_expected_frame2, server_frame_size2); + tsi_test_frame_protector_fixture_destroy(fixture); + /** + * Test large client message, small server message, and small + * protected_buffer_size. + */ + const uint8_t client_expected_frame3[] = { + 0x94, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x93, 0x81, 0x86, 0xc7, + 0xdc, 0xf4, 0x77, 0x3a, 0xdb, 0x91, 0x94, 0x61, 0xba, 0xed, 0xd5, 0x37, + 0x47, 0x53, 0x0c, 0xe1, 0xbf, 0x59, 0x23, 0x20, 0xde, 0x8b, 0x25, 0x13, + 0x72, 0xe7, 0x8a, 0x4f, 0x32, 0x61, 0xc6, 0xda, 0xc3, 0xe9, 0xff, 0x31, + 0x33, 0x53, 0x4a, 0xf8, 0xc9, 0x98, 0xe4, 0x19, 0x71, 0x9c, 0x5e, 0x72, + 0xc7, 0x35, 0x97, 0x78, 0x30, 0xf2, 0xc4, 0xd1, 0x53, 0xd5, 0x6e, 0x8f, + 0x4f, 0xd9, 0x28, 0x5a, 0xfd, 0x22, 0x57, 0x7f, 0x95, 0xb4, 0x8a, 0x5e, + 0x7c, 0x47, 0xa8, 0xcf, 0x64, 0x3d, 0x83, 0xa5, 0xcf, 0xc3, 0xfe, 0x54, + 0xc2, 0x6a, 0x40, 0xc4, 0xfb, 0x8e, 0x07, 0x77, 0x70, 0x8f, 0x99, 0x94, + 0xb1, 0xd5, 0xa7, 0xf9, 0x0d, 0xc7, 0x11, 0xc5, 0x6f, 0x4a, 0x4f, 0x56, + 0xd5, 0xe2, 0x9c, 0xbb, 0x95, 0x7a, 0xd0, 0x9f, 0x30, 0x54, 0xca, 0x6d, + 0x5c, 0x8e, 0x83, 0xa0, 0x04, 0x5e, 0xd0, 0x22, 0x8c, 0x2a, 0x7f, 0xdb, + 0xfe, 0xb3, 0x2e, 0xae, 0x22, 0xe6, 0xf4, 0xb7}; + const uint8_t server_expected_frame3[] = { + 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x33, 0x12, 0xab, 0x9d, + 0x76, 0x2b, 0x5f, 0xab, 0xf3, 0x6d, 0xc4, 0xaa, 0xe5, 0x1e, 0x63, 0xc1, + 0x7b, 0x7b, 0x10, 0xd5, 0x63, 0x0f, 0x29, 0xad, 0x17, 0x33, 0x73}; + const size_t client_frame_size3 = + sizeof(client_expected_frame3) / sizeof(uint8_t); + const size_t server_frame_size3 = + sizeof(server_expected_frame3) / sizeof(uint8_t); + fixture = tsi_test_frame_protector_fixture_create(); + alts_test_do_round_trip_check_frames( + fixture, key, kAes128GcmKeyLength, /*rekey=*/false, large_message, + large_message_size, client_expected_frame3, client_frame_size3, + reinterpret_cast<const uint8_t*>(small_message), small_message_size, + server_expected_frame3, server_frame_size3); + tsi_test_frame_protector_fixture_destroy(fixture); + /** + * Test large client message, small server message, and small + * read_buffer_allocated_size. + */ + const uint8_t client_expected_frame4[] = { + 0x94, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x93, 0x81, 0x86, 0xc7, + 0xdc, 0xf4, 0x77, 0x3a, 0xdb, 0x91, 0x94, 0x61, 0xba, 0xed, 0xd5, 0x37, + 0x47, 0x53, 0x0c, 0xe1, 0xbf, 0x59, 0x23, 0x20, 0xde, 0x8b, 0x25, 0x13, + 0x72, 0xe7, 0x8a, 0x4f, 0x32, 0x61, 0xc6, 0xda, 0xc3, 0xe9, 0xff, 0x31, + 0x33, 0x53, 0x4a, 0xf8, 0xc9, 0x98, 0xe4, 0x19, 0x71, 0x9c, 0x5e, 0x72, + 0xc7, 0x35, 0x97, 0x78, 0x30, 0xf2, 0xc4, 0xd1, 0x53, 0xd5, 0x6e, 0x8f, + 0x4f, 0xd9, 0x28, 0x5a, 0xfd, 0x22, 0x57, 0x7f, 0x95, 0xb4, 0x8a, 0x5e, + 0x7c, 0x47, 0xa8, 0xcf, 0x64, 0x3d, 0x83, 0xa5, 0xcf, 0xc3, 0xfe, 0x54, + 0xc2, 0x6a, 0x40, 0xc4, 0xfb, 0x8e, 0x07, 0x77, 0x70, 0x8f, 0x99, 0x94, + 0xb1, 0xd5, 0xa7, 0xf9, 0x0d, 0xc7, 0x11, 0xc5, 0x6f, 0x4a, 0x4f, 0x56, + 0xd5, 0xe2, 0x9c, 0xbb, 0x95, 0x7a, 0xd0, 0x9f, 0x30, 0x54, 0xca, 0x6d, + 0x5c, 0x8e, 0x83, 0xa0, 0x04, 0x5e, 0xd0, 0x22, 0x8c, 0x2a, 0x7f, 0xdb, + 0xfe, 0xb3, 0x2e, 0xae, 0x22, 0xe6, 0xf4, 0xb7}; + const uint8_t server_expected_frame4[] = { + 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x33, 0x12, 0xab, 0x9d, + 0x76, 0x2b, 0x5f, 0xab, 0xf3, 0x6d, 0xc4, 0xaa, 0xe5, 0x1e, 0x63, 0xc1, + 0x7b, 0x7b, 0x10, 0xd5, 0x63, 0x0f, 0x29, 0xad, 0x17, 0x33, 0x73}; + const size_t client_frame_size4 = + sizeof(client_expected_frame4) / sizeof(uint8_t); + const size_t server_frame_size4 = + sizeof(server_expected_frame4) / sizeof(uint8_t); + fixture = tsi_test_frame_protector_fixture_create(); + alts_test_do_round_trip_check_frames( + fixture, key, kAes128GcmKeyLength, /*rekey=*/false, large_message, + large_message_size, client_expected_frame4, client_frame_size4, + reinterpret_cast<const uint8_t*>(small_message), small_message_size, + server_expected_frame4, server_frame_size4); + tsi_test_frame_protector_fixture_destroy(fixture); + /** + * Test large client message, small server message, and small + * client_max_output_protected_frame_size. + */ + const uint8_t client_expected_frame5[] = { + 0x94, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x93, 0x81, 0x86, 0xc7, + 0xdc, 0xf4, 0x77, 0x3a, 0xdb, 0x91, 0x94, 0x61, 0xba, 0xed, 0xd5, 0x37, + 0x47, 0x53, 0x0c, 0xe1, 0xbf, 0x59, 0x23, 0x20, 0xde, 0x8b, 0x25, 0x13, + 0x72, 0xe7, 0x8a, 0x4f, 0x32, 0x61, 0xc6, 0xda, 0xc3, 0xe9, 0xff, 0x31, + 0x33, 0x53, 0x4a, 0xf8, 0xc9, 0x98, 0xe4, 0x19, 0x71, 0x9c, 0x5e, 0x72, + 0xc7, 0x35, 0x97, 0x78, 0x30, 0xf2, 0xc4, 0xd1, 0x53, 0xd5, 0x6e, 0x8f, + 0x4f, 0xd9, 0x28, 0x5a, 0xfd, 0x22, 0x57, 0x7f, 0x95, 0xb4, 0x8a, 0x5e, + 0x7c, 0x47, 0xa8, 0xcf, 0x64, 0x3d, 0x83, 0xa5, 0xcf, 0xc3, 0xfe, 0x54, + 0xc2, 0x6a, 0x40, 0xc4, 0xfb, 0x8e, 0x07, 0x77, 0x70, 0x8f, 0x99, 0x94, + 0xb1, 0xd5, 0xa7, 0xf9, 0x0d, 0xc7, 0x11, 0xc5, 0x6f, 0x4a, 0x4f, 0x56, + 0xd5, 0xe2, 0x9c, 0xbb, 0x95, 0x7a, 0xd0, 0x9f, 0x30, 0x54, 0xca, 0x6d, + 0x5c, 0x8e, 0x83, 0xa0, 0x04, 0x5e, 0xd0, 0x22, 0x8c, 0x2a, 0x7f, 0xdb, + 0xfe, 0xb3, 0x2e, 0xae, 0x22, 0xe6, 0xf4, 0xb7}; + const uint8_t server_expected_frame5[] = { + 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x33, 0x12, 0xab, 0x9d, + 0x76, 0x2b, 0x5f, 0xab, 0xf3, 0x6d, 0xc4, 0xaa, 0xe5, 0x1e, 0x63, 0xc1, + 0x7b, 0x7b, 0x10, 0xd5, 0x63, 0x0f, 0x29, 0xad, 0x17, 0x33, 0x73}; + const size_t client_frame_size5 = + sizeof(client_expected_frame5) / sizeof(uint8_t); + const size_t server_frame_size5 = + sizeof(server_expected_frame5) / sizeof(uint8_t); + fixture = tsi_test_frame_protector_fixture_create(); + alts_test_do_round_trip_check_frames( + fixture, key, kAes128GcmKeyLength, /*rekey=*/false, large_message, + large_message_size, client_expected_frame5, client_frame_size5, + reinterpret_cast<const uint8_t*>(small_message), small_message_size, + server_expected_frame5, server_frame_size5); + tsi_test_frame_protector_fixture_destroy(fixture); + /** + * Test small client message, large server message, and small + * server_max_output_protected_frame_size. + */ + const uint8_t client_expected_frame6[] = { + 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09, 0xd8, 0xd5, 0x92, + 0x4d, 0x50, 0x32, 0xb7, 0x1f, 0xb8, 0xf2, 0xbb, 0x43, 0xc7, 0xe2, 0x94, + 0x3d, 0x3e, 0x9a, 0x78, 0x76, 0xaa, 0x0a, 0x6b, 0xfa, 0x98, 0x3a}; + const uint8_t server_expected_frame6[] = { + 0x94, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4b, 0xf8, 0xc8, + 0xe7, 0x8f, 0x1a, 0x26, 0x37, 0x44, 0xa2, 0x5c, 0x55, 0x94, 0x30, 0x4e, + 0x3e, 0x16, 0xe7, 0x9e, 0x96, 0xe8, 0x1b, 0xc0, 0xdd, 0x52, 0x30, 0x06, + 0xc2, 0x72, 0x9a, 0xa1, 0x0b, 0xdb, 0xdc, 0x19, 0x8c, 0x93, 0x5e, 0x84, + 0x1f, 0x4b, 0x97, 0x26, 0xf0, 0x73, 0x85, 0x59, 0x00, 0x95, 0xc1, 0xc5, + 0x22, 0x2f, 0x70, 0x85, 0x68, 0x2c, 0x4f, 0xfe, 0x30, 0x26, 0x91, 0xde, + 0x62, 0x55, 0x1d, 0x35, 0x01, 0x96, 0x1c, 0xe7, 0xa2, 0x8b, 0x14, 0x8a, + 0x5e, 0x1b, 0x4a, 0x3b, 0x4f, 0x65, 0x0f, 0xca, 0x79, 0x10, 0xb4, 0xdd, + 0xf7, 0xa4, 0x8b, 0x64, 0x2f, 0x00, 0x39, 0x60, 0x03, 0xfc, 0xe1, 0x8b, + 0x5c, 0x19, 0xba, 0xcc, 0x46, 0xba, 0x88, 0xdd, 0x40, 0x42, 0x27, 0x4f, + 0xe4, 0x1a, 0x6a, 0x31, 0x6c, 0x1c, 0xb0, 0xb6, 0x5c, 0x3e, 0xca, 0x84, + 0x9b, 0x5f, 0x04, 0x84, 0x11, 0xa9, 0xf8, 0x39, 0xe7, 0xe7, 0xc5, 0xc4, + 0x33, 0x9f, 0x63, 0x21, 0x9a, 0x7c, 0x9c, 0x64}; + const size_t client_frame_size6 = + sizeof(client_expected_frame6) / sizeof(uint8_t); + const size_t server_frame_size6 = + sizeof(server_expected_frame6) / sizeof(uint8_t); + fixture = tsi_test_frame_protector_fixture_create(); + alts_test_do_round_trip_check_frames( + fixture, key, kAes128GcmKeyLength, /*rekey=*/false, + reinterpret_cast<const uint8_t*>(small_message), small_message_size, + client_expected_frame6, client_frame_size6, large_message, + large_message_size, server_expected_frame6, server_frame_size6); + tsi_test_frame_protector_fixture_destroy(fixture); +} + +static void alts_test_do_round_trip(tsi_test_frame_protector_fixture* fixture, + bool rekey) { + GPR_ASSERT(fixture != nullptr); + GPR_ASSERT(fixture->config != nullptr); + tsi_frame_protector* client_frame_protector = nullptr; + tsi_frame_protector* server_frame_protector = nullptr; + tsi_test_frame_protector_config* config = fixture->config; + /* Create a key to be used by both client and server. */ + uint8_t* key = nullptr; + size_t key_length = rekey ? kAes128GcmRekeyKeyLength : kAes128GcmKeyLength; + gsec_test_random_array(&key, key_length); + /* Create a client frame protector. */ + size_t client_max_output_protected_frame_size = + config->client_max_output_protected_frame_size; + GPR_ASSERT( + alts_create_frame_protector(key, key_length, /*is_client=*/true, rekey, + client_max_output_protected_frame_size == 0 + ? nullptr + : &client_max_output_protected_frame_size, + &client_frame_protector) == TSI_OK); + /* Create a server frame protector. */ + size_t server_max_output_protected_frame_size = + config->server_max_output_protected_frame_size; + GPR_ASSERT( + alts_create_frame_protector(key, key_length, /*is_client=*/false, rekey, + server_max_output_protected_frame_size == 0 + ? nullptr + : &server_max_output_protected_frame_size, + &server_frame_protector) == TSI_OK); + tsi_test_frame_protector_fixture_init(fixture, client_frame_protector, + server_frame_protector); + tsi_test_frame_protector_do_round_trip_no_handshake(fixture); + gpr_free(key); +} + +/* Run all combinations of different arguments of test config. */ +static void alts_test_do_round_trip_all(bool rekey) { + unsigned int* bit_array = static_cast<unsigned int*>( + gpr_malloc(sizeof(unsigned int) * TSI_TEST_NUM_OF_ARGUMENTS)); + unsigned int mask = 1U << (TSI_TEST_NUM_OF_ARGUMENTS - 1); + unsigned int val = 0, ind = 0; + for (val = 0; val < TSI_TEST_NUM_OF_COMBINATIONS; val++) { + unsigned int v = val; + for (ind = 0; ind < TSI_TEST_NUM_OF_ARGUMENTS; ind++) { + bit_array[ind] = (v & mask) ? 1 : 0; + v <<= 1; + } + tsi_test_frame_protector_fixture* fixture = + tsi_test_frame_protector_fixture_create(); + tsi_test_frame_protector_config_destroy(fixture->config); + fixture->config = tsi_test_frame_protector_config_create( + bit_array[0], bit_array[1], bit_array[2], bit_array[3], bit_array[4], + bit_array[5], bit_array[6]); + alts_test_do_round_trip(fixture, rekey); + tsi_test_frame_protector_fixture_destroy(fixture); + } + gpr_free(bit_array); +} + +int main(int argc, char** argv) { + alts_test_do_round_trip_vector_tests(); + alts_test_do_round_trip_all(/*rekey=*/false); + alts_test_do_round_trip_all(/*rekey=*/true); + return 0; +} diff --git a/test/core/tsi/alts/frame_protector/frame_handler_test.cc b/test/core/tsi/alts/frame_protector/frame_handler_test.cc new file mode 100644 index 0000000000..6434ea1d31 --- /dev/null +++ b/test/core/tsi/alts/frame_protector/frame_handler_test.cc @@ -0,0 +1,244 @@ +/* + * + * 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 <stdint.h> +#include <stdio.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/gpr/useful.h" +#include "src/core/tsi/alts/frame_protector/frame_handler.h" +#include "test/core/tsi/alts/crypt/gsec_test_util.h" + +const size_t kFrameHandlerTestBufferSize = 1024; + +typedef struct frame_handler { + alts_frame_writer* writer; + alts_frame_reader* reader; + unsigned char* buffer; + size_t buffer_size; +} frame_handler; + +static size_t frame_length(size_t payload_length) { + return payload_length + kFrameHeaderSize; +} + +static frame_handler* create_frame_handler() { + frame_handler* handler = + static_cast<frame_handler*>(gpr_malloc(sizeof(frame_handler))); + handler->writer = alts_create_frame_writer(); + handler->reader = alts_create_frame_reader(); + handler->buffer = nullptr; + handler->buffer_size = 0; + return handler; +} + +static void destroy_frame_handler(frame_handler* handler) { + if (handler != nullptr) { + alts_destroy_frame_reader(handler->reader); + alts_destroy_frame_writer(handler->writer); + if (handler->buffer != nullptr) gpr_free(handler->buffer); + gpr_free(handler); + } +} + +static void frame(frame_handler* handler, unsigned char* payload, + size_t payload_length, size_t write_length) { + handler->buffer_size = frame_length(payload_length); + handler->buffer = + static_cast<unsigned char*>(gpr_malloc(handler->buffer_size)); + GPR_ASSERT(alts_reset_frame_writer(handler->writer, payload, payload_length)); + size_t offset = 0; + while (offset < handler->buffer_size && + !alts_is_frame_writer_done(handler->writer)) { + size_t bytes_written = GPR_MIN(write_length, handler->buffer_size - offset); + GPR_ASSERT(alts_write_frame_bytes(handler->writer, handler->buffer + offset, + &bytes_written)); + offset += bytes_written; + } + GPR_ASSERT(alts_is_frame_writer_done(handler->writer)); + GPR_ASSERT(handler->buffer_size == offset); +} + +static size_t deframe(frame_handler* handler, unsigned char* bytes, + size_t read_length) { + GPR_ASSERT(alts_reset_frame_reader(handler->reader, bytes)); + size_t offset = 0; + while (offset < handler->buffer_size && + !alts_is_frame_reader_done(handler->reader)) { + size_t bytes_read = GPR_MIN(read_length, handler->buffer_size - offset); + GPR_ASSERT(alts_read_frame_bytes(handler->reader, handler->buffer + offset, + &bytes_read)); + offset += bytes_read; + } + GPR_ASSERT(alts_is_frame_reader_done(handler->reader)); + GPR_ASSERT(handler->buffer_size == offset); + return offset - handler->reader->header_bytes_read; +} + +static void frame_n_deframe(frame_handler* handler, unsigned char* payload, + size_t payload_length, size_t write_length, + size_t read_length) { + frame(handler, payload, payload_length, write_length); + unsigned char* bytes = + static_cast<unsigned char*>(gpr_malloc(kFrameHandlerTestBufferSize)); + size_t deframed_payload_length = deframe(handler, bytes, read_length); + GPR_ASSERT(payload_length == deframed_payload_length); + GPR_ASSERT(memcmp(payload, bytes, payload_length) == 0); + gpr_free(bytes); +} + +static void frame_handler_test_frame_deframe() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen((char*)payload) + 1; + frame_handler* handler = create_frame_handler(); + frame_n_deframe(handler, payload, payload_length, + frame_length(payload_length), frame_length(payload_length)); + destroy_frame_handler(handler); +} + +static void frame_handler_test_small_buffer() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1; + frame_handler* handler = create_frame_handler(); + frame_n_deframe(handler, payload, payload_length, 1, 1); + destroy_frame_handler(handler); +} + +static void frame_handler_test_null_input_stream() { + frame_handler* handler = create_frame_handler(); + GPR_ASSERT(!alts_reset_frame_writer(handler->writer, nullptr, 0)); + destroy_frame_handler(handler); +} + +static void frame_handler_test_bad_input_length() { + unsigned char payload[] = "hello world"; + frame_handler* handler = create_frame_handler(); + GPR_ASSERT(!alts_reset_frame_writer(handler->writer, payload, SIZE_MAX)); + destroy_frame_handler(handler); +} + +static void frame_handler_test_null_writer_byte_length() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1; + frame_handler* handler = create_frame_handler(); + GPR_ASSERT(alts_reset_frame_writer(handler->writer, payload, payload_length)); + GPR_ASSERT( + !alts_write_frame_bytes(handler->writer, handler->buffer, nullptr)); + destroy_frame_handler(handler); +} + +static void frame_handler_test_null_writer_bytes() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1; + frame_handler* handler = create_frame_handler(); + GPR_ASSERT(alts_reset_frame_writer(handler->writer, payload, payload_length)); + GPR_ASSERT( + !alts_write_frame_bytes(handler->writer, nullptr, &payload_length)); + destroy_frame_handler(handler); +} + +static void frame_handler_test_bad_frame_length() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1; + frame_handler* handler = create_frame_handler(); + frame(handler, payload, payload_length, payload_length); + memset(handler->buffer, 0x00, kFrameLengthFieldSize); + unsigned char* bytes = + static_cast<unsigned char*>(gpr_malloc(kFrameHandlerTestBufferSize)); + GPR_ASSERT(alts_reset_frame_reader(handler->reader, bytes)); + size_t bytes_read = handler->buffer_size; + GPR_ASSERT( + !alts_read_frame_bytes(handler->reader, handler->buffer, &bytes_read)); + GPR_ASSERT(alts_is_frame_reader_done(handler->reader)); + GPR_ASSERT(bytes_read == 0); + gpr_free(bytes); + destroy_frame_handler(handler); +} + +static void frame_handler_test_unsupported_message_type() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1; + frame_handler* handler = create_frame_handler(); + frame(handler, payload, payload_length, payload_length); + memset(handler->buffer + kFrameLengthFieldSize, 0x00, + kFrameMessageTypeFieldSize); + unsigned char* bytes = + static_cast<unsigned char*>(gpr_malloc(kFrameHandlerTestBufferSize)); + GPR_ASSERT(alts_reset_frame_reader(handler->reader, bytes)); + size_t bytes_read = handler->buffer_size; + GPR_ASSERT( + !alts_read_frame_bytes(handler->reader, handler->buffer, &bytes_read)); + GPR_ASSERT(alts_is_frame_reader_done(handler->reader)); + GPR_ASSERT(bytes_read == 0); + gpr_free(bytes); + destroy_frame_handler(handler); +} + +static void frame_handler_test_null_output_stream() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1; + frame_handler* handler = create_frame_handler(); + frame(handler, payload, payload_length, payload_length); + GPR_ASSERT(!alts_reset_frame_reader(handler->reader, nullptr)); + destroy_frame_handler(handler); +} + +static void frame_handler_test_null_reader_byte_length() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1; + frame_handler* handler = create_frame_handler(); + frame(handler, payload, payload_length, payload_length); + unsigned char* bytes = + static_cast<unsigned char*>(gpr_malloc(kFrameHandlerTestBufferSize)); + GPR_ASSERT(alts_reset_frame_reader(handler->reader, bytes)); + GPR_ASSERT(!alts_read_frame_bytes(handler->reader, handler->buffer, nullptr)); + gpr_free(bytes); + destroy_frame_handler(handler); +} + +static void frame_handler_test_null_reader_bytes() { + unsigned char payload[] = "hello world"; + size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1; + frame_handler* handler = create_frame_handler(); + frame(handler, payload, payload_length, payload_length); + unsigned char* bytes = + static_cast<unsigned char*>(gpr_malloc(kFrameHandlerTestBufferSize)); + GPR_ASSERT(alts_reset_frame_reader(handler->reader, bytes)); + size_t bytes_read = handler->buffer_size; + GPR_ASSERT(!alts_read_frame_bytes(handler->reader, nullptr, &bytes_read)); + gpr_free(bytes); + destroy_frame_handler(handler); +} + +int main(int argc, char** argv) { + frame_handler_test_frame_deframe(); + frame_handler_test_small_buffer(); + frame_handler_test_null_input_stream(); + frame_handler_test_bad_input_length(); + frame_handler_test_null_writer_byte_length(); + frame_handler_test_null_writer_bytes(); + frame_handler_test_bad_frame_length(); + frame_handler_test_unsupported_message_type(); + frame_handler_test_null_output_stream(); + frame_handler_test_null_reader_byte_length(); + frame_handler_test_null_reader_bytes(); + return 0; +} diff --git a/test/core/tsi/alts/handshaker/BUILD b/test/core/tsi/alts/handshaker/BUILD new file mode 100644 index 0000000000..809742744c --- /dev/null +++ b/test/core/tsi/alts/handshaker/BUILD @@ -0,0 +1,86 @@ +# 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. + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") + +licenses(["notice"]) # Apache v2 + +grpc_package(name = "test/core/tsi/alts/handshaker") + +grpc_cc_library( + name = "alts_handshaker_service_api_test_lib", + srcs = ["alts_handshaker_service_api_test_lib.cc"], + hdrs = ["alts_handshaker_service_api_test_lib.h"], + deps = [ + "//:alts_util", + "//:grpc", + ], +) + +grpc_cc_test( + name = "alts_handshaker_client_test", + srcs = ["alts_handshaker_client_test.cc"], + language = "C++", + deps = [ + ":alts_handshaker_service_api_test_lib", + "//:tsi", + "//:tsi_interface", + "//:grpc", + ], +) + +grpc_cc_test( + name = "alts_handshaker_service_api_test", + srcs = ["alts_handshaker_service_api_test.cc"], + language = "C++", + deps = [ + ":alts_handshaker_service_api_test_lib", + "//:grpc", + ], +) + +grpc_cc_test( + name = "alts_tsi_handshaker_test", + srcs = ["alts_tsi_handshaker_test.cc"], + language = "C++", + deps = [ + ":alts_handshaker_service_api_test_lib", + "//:gpr", + "//:gpr_base", + "//:grpc", + "//:tsi", + ], +) + +grpc_cc_test( + name = "alts_tsi_utils_test", + srcs = ["alts_tsi_utils_test.cc"], + language = "C++", + deps = [ + ":alts_handshaker_service_api_test_lib", + "//:grpc", + "//:tsi", + ], +) + +grpc_cc_test( + name = "transport_security_common_api_test", + srcs = ["transport_security_common_api_test.cc"], + language = "C++", + deps = [ + "//:alts_util", + "//:grpc", + ], +) + diff --git a/test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc b/test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc new file mode 100644 index 0000000000..c8d88aa72c --- /dev/null +++ b/test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc @@ -0,0 +1,413 @@ +/* + * + * 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/grpc.h> + +#include "src/core/tsi/alts/handshaker/alts_handshaker_client.h" +#include "src/core/tsi/alts/handshaker/alts_tsi_event.h" +#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" +#include "src/core/tsi/transport_security.h" +#include "src/core/tsi/transport_security_interface.h" +#include "test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h" + +#define ALTS_HANDSHAKER_CLIENT_TEST_OUT_FRAME "Hello Google" +#define ALTS_HANDSHAKER_CLIENT_TEST_HANDSHAKER_SERVICE_URL "lame" +#define ALTS_HANDSHAKER_CLIENT_TEST_TARGET_NAME "bigtable.google.api.com" +#define ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT1 "A@google.com" +#define ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT2 "B@google.com" + +const size_t kHandshakerClientOpNum = 4; +const size_t kMaxRpcVersionMajor = 3; +const size_t kMaxRpcVersionMinor = 2; +const size_t kMinRpcVersionMajor = 2; +const size_t kMinRpcVersionMinor = 1; + +using grpc_core::internal::alts_handshaker_client_set_grpc_caller_for_testing; + +typedef struct alts_handshaker_client_test_config { + grpc_channel* channel; + grpc_completion_queue* cq; + alts_handshaker_client* client; + grpc_slice out_frame; +} alts_handshaker_client_test_config; + +static alts_tsi_event* alts_tsi_event_create_for_testing(bool is_client) { + alts_tsi_event* e = static_cast<alts_tsi_event*>(gpr_zalloc(sizeof(*e))); + grpc_metadata_array_init(&e->initial_metadata); + grpc_metadata_array_init(&e->trailing_metadata); + e->options = is_client ? grpc_alts_credentials_client_options_create() + : grpc_alts_credentials_server_options_create(); + if (is_client) { + grpc_alts_credentials_client_options_add_target_service_account( + e->options, ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT1); + grpc_alts_credentials_client_options_add_target_service_account( + e->options, ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT2); + } + grpc_gcp_rpc_protocol_versions* versions = &e->options->rpc_versions; + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max( + versions, kMaxRpcVersionMajor, kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min( + versions, kMinRpcVersionMajor, kMinRpcVersionMinor)); + e->target_name = + grpc_slice_from_static_string(ALTS_HANDSHAKER_CLIENT_TEST_TARGET_NAME); + return e; +} + +static void validate_rpc_protocol_versions( + grpc_gcp_rpc_protocol_versions* versions) { + GPR_ASSERT(versions != nullptr); + GPR_ASSERT(versions->max_rpc_version.major == kMaxRpcVersionMajor); + GPR_ASSERT(versions->max_rpc_version.minor == kMaxRpcVersionMinor); + GPR_ASSERT(versions->min_rpc_version.major == kMinRpcVersionMajor); + GPR_ASSERT(versions->min_rpc_version.minor == kMinRpcVersionMinor); +} + +static void validate_target_identities( + const repeated_field* target_identity_head) { + grpc_gcp_identity* target_identity1 = static_cast<grpc_gcp_identity*>( + const_cast<void*>(target_identity_head->next->data)); + grpc_gcp_identity* target_identity2 = static_cast<grpc_gcp_identity*>( + const_cast<void*>(target_identity_head->data)); + grpc_slice* service_account1 = + static_cast<grpc_slice*>(target_identity1->service_account.arg); + grpc_slice* service_account2 = + static_cast<grpc_slice*>(target_identity2->service_account.arg); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*service_account1), + ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT1, + GRPC_SLICE_LENGTH(*service_account1)) == 0); + GPR_ASSERT(strlen(ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT1) == + GRPC_SLICE_LENGTH(*service_account1)); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*service_account2), + ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT2, + GRPC_SLICE_LENGTH(*service_account2)) == 0); + GPR_ASSERT(strlen(ALTS_HANDSHAKER_CLIENT_TEST_TARGET_SERVICE_ACCOUNT2) == + GRPC_SLICE_LENGTH(*service_account2)); +} + +/** + * Validate if grpc operation data is correctly populated with the fields of + * ALTS TSI event. + */ +static bool validate_op(alts_tsi_event* event, const grpc_op* op, size_t nops, + bool is_start) { + GPR_ASSERT(event != nullptr && op != nullptr && nops != 0); + bool ok = true; + grpc_op* start_op = const_cast<grpc_op*>(op); + if (is_start) { + ok &= (op->op == GRPC_OP_SEND_INITIAL_METADATA); + ok &= (op->data.send_initial_metadata.count == 0); + op++; + GPR_ASSERT((size_t)(op - start_op) <= kHandshakerClientOpNum); + + ok &= (op->op == GRPC_OP_RECV_INITIAL_METADATA); + ok &= (op->data.recv_initial_metadata.recv_initial_metadata == + &event->initial_metadata); + op++; + GPR_ASSERT((size_t)(op - start_op) <= kHandshakerClientOpNum); + } + ok &= (op->op == GRPC_OP_SEND_MESSAGE); + ok &= (op->data.send_message.send_message == event->send_buffer); + op++; + GPR_ASSERT((size_t)(op - start_op) <= kHandshakerClientOpNum); + + ok &= (op->op == GRPC_OP_RECV_MESSAGE); + ok &= (op->data.recv_message.recv_message == &event->recv_buffer); + op++; + GPR_ASSERT((size_t)(op - start_op) <= kHandshakerClientOpNum); + + return ok; +} + +static grpc_gcp_handshaker_req* deserialize_handshaker_req( + grpc_gcp_handshaker_req_type type, grpc_byte_buffer* buffer) { + GPR_ASSERT(buffer != nullptr); + grpc_gcp_handshaker_req* req = grpc_gcp_handshaker_decoded_req_create(type); + grpc_byte_buffer_reader bbr; + GPR_ASSERT(grpc_byte_buffer_reader_init(&bbr, buffer)); + grpc_slice slice = grpc_byte_buffer_reader_readall(&bbr); + GPR_ASSERT(grpc_gcp_handshaker_req_decode(slice, req)); + grpc_slice_unref(slice); + grpc_byte_buffer_reader_destroy(&bbr); + return req; +} + +/** + * A mock grpc_caller used to check if client_start, server_start, and next + * operations correctly handle invalid arguments. It should not be called. + */ +static grpc_call_error check_must_not_be_called(grpc_call* call, + const grpc_op* ops, size_t nops, + void* tag) { + GPR_ASSERT(0); +} + +/** + * A mock grpc_caller used to check correct execution of client_start operation. + * It checks if the client_start handshaker request is populated with correct + * handshake_security_protocol, application_protocol, and record_protocol, and + * op is correctly populated. + */ +static grpc_call_error check_client_start_success(grpc_call* call, + const grpc_op* op, + size_t nops, void* tag) { + alts_tsi_event* event = static_cast<alts_tsi_event*>(tag); + grpc_gcp_handshaker_req* req = + deserialize_handshaker_req(CLIENT_START_REQ, event->send_buffer); + GPR_ASSERT(req->client_start.handshake_security_protocol == + grpc_gcp_HandshakeProtocol_ALTS); + const void* data = (static_cast<repeated_field*>( + req->client_start.application_protocols.arg)) + ->data; + GPR_ASSERT(data != nullptr); + grpc_slice* application_protocol = (grpc_slice*)data; + data = (static_cast<repeated_field*>(req->client_start.record_protocols.arg)) + ->data; + grpc_slice* record_protocol = (grpc_slice*)data; + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*application_protocol), + ALTS_APPLICATION_PROTOCOL, + GRPC_SLICE_LENGTH(*application_protocol)) == 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*record_protocol), + ALTS_RECORD_PROTOCOL, + GRPC_SLICE_LENGTH(*record_protocol)) == 0); + validate_rpc_protocol_versions(&req->client_start.rpc_versions); + validate_target_identities( + static_cast<repeated_field*>(req->client_start.target_identities.arg)); + grpc_slice* target_name = + static_cast<grpc_slice*>(req->client_start.target_name.arg); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*target_name), + ALTS_HANDSHAKER_CLIENT_TEST_TARGET_NAME, + GRPC_SLICE_LENGTH(*target_name)) == 0); + GPR_ASSERT(GRPC_SLICE_LENGTH(*target_name) == + strlen(ALTS_HANDSHAKER_CLIENT_TEST_TARGET_NAME)); + GPR_ASSERT(validate_op(event, op, nops, true /* is_start */)); + grpc_gcp_handshaker_req_destroy(req); + return GRPC_CALL_OK; +} + +/** + * A mock grpc_caller used to check correct execution of server_start operation. + * It checks if the server_start handshaker request is populated with correct + * handshake_security_protocol, application_protocol, and record_protocol, and + * op is correctly populated. + */ +static grpc_call_error check_server_start_success(grpc_call* call, + const grpc_op* op, + size_t nops, void* tag) { + alts_tsi_event* event = static_cast<alts_tsi_event*>(tag); + grpc_gcp_handshaker_req* req = + deserialize_handshaker_req(SERVER_START_REQ, event->send_buffer); + const void* data = (static_cast<repeated_field*>( + req->server_start.application_protocols.arg)) + ->data; + GPR_ASSERT(data != nullptr); + grpc_slice* application_protocol = (grpc_slice*)data; + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*application_protocol), + ALTS_APPLICATION_PROTOCOL, + GRPC_SLICE_LENGTH(*application_protocol)) == 0); + GPR_ASSERT(req->server_start.handshake_parameters_count == 1); + GPR_ASSERT(req->server_start.handshake_parameters[0].key == + grpc_gcp_HandshakeProtocol_ALTS); + data = (static_cast<repeated_field*>(req->server_start.handshake_parameters[0] + .value.record_protocols.arg)) + ->data; + GPR_ASSERT(data != nullptr); + grpc_slice* record_protocol = (grpc_slice*)data; + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*record_protocol), + ALTS_RECORD_PROTOCOL, + GRPC_SLICE_LENGTH(*record_protocol)) == 0); + validate_rpc_protocol_versions(&req->server_start.rpc_versions); + GPR_ASSERT(validate_op(event, op, nops, true /* is_start */)); + grpc_gcp_handshaker_req_destroy(req); + return GRPC_CALL_OK; +} + +/** + * A mock grpc_caller used to check correct execution of next operation. It + * checks if the next handshaker request is populated with correct information, + * and op is correctly populated. + */ +static grpc_call_error check_next_success(grpc_call* call, const grpc_op* op, + size_t nops, void* tag) { + alts_tsi_event* event = static_cast<alts_tsi_event*>(tag); + grpc_gcp_handshaker_req* req = + deserialize_handshaker_req(NEXT_REQ, event->send_buffer); + grpc_slice* in_bytes = static_cast<grpc_slice*>(req->next.in_bytes.arg); + GPR_ASSERT(in_bytes != nullptr); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*in_bytes), + ALTS_HANDSHAKER_CLIENT_TEST_OUT_FRAME, + GRPC_SLICE_LENGTH(*in_bytes)) == 0); + GPR_ASSERT(validate_op(event, op, nops, false /* is_start */)); + grpc_gcp_handshaker_req_destroy(req); + return GRPC_CALL_OK; +} +/** + * A mock grpc_caller used to check if client_start, server_start, and next + * operations correctly handle the situation when the grpc call made to the + * handshaker service fails. + */ +static grpc_call_error check_grpc_call_failure(grpc_call* call, + const grpc_op* op, size_t nops, + void* tag) { + return GRPC_CALL_ERROR; +} + +static alts_handshaker_client_test_config* create_config() { + alts_handshaker_client_test_config* config = + static_cast<alts_handshaker_client_test_config*>( + gpr_zalloc(sizeof(*config))); + config->channel = grpc_insecure_channel_create( + ALTS_HANDSHAKER_CLIENT_TEST_HANDSHAKER_SERVICE_URL, nullptr, nullptr); + config->cq = grpc_completion_queue_create_for_next(nullptr); + config->client = alts_grpc_handshaker_client_create( + config->channel, config->cq, + ALTS_HANDSHAKER_CLIENT_TEST_HANDSHAKER_SERVICE_URL); + GPR_ASSERT(config->client != nullptr); + config->out_frame = + grpc_slice_from_static_string(ALTS_HANDSHAKER_CLIENT_TEST_OUT_FRAME); + return config; +} + +static void destroy_config(alts_handshaker_client_test_config* config) { + if (config == nullptr) { + return; + } + grpc_completion_queue_destroy(config->cq); + grpc_channel_destroy(config->channel); + alts_handshaker_client_destroy(config->client); + grpc_slice_unref(config->out_frame); + gpr_free(config); +} + +static void schedule_request_invalid_arg_test() { + /* Initialization. */ + alts_handshaker_client_test_config* config = create_config(); + alts_tsi_event* event = nullptr; + + /* Tests. */ + alts_handshaker_client_set_grpc_caller_for_testing(config->client, + check_must_not_be_called); + event = alts_tsi_event_create_for_testing(true /* is_client */); + /* Check client_start. */ + GPR_ASSERT(alts_handshaker_client_start_client(nullptr, event) == + TSI_INVALID_ARGUMENT); + GPR_ASSERT(alts_handshaker_client_start_client(config->client, nullptr) == + TSI_INVALID_ARGUMENT); + + /* Check server_start. */ + GPR_ASSERT(alts_handshaker_client_start_server( + config->client, event, nullptr) == TSI_INVALID_ARGUMENT); + GPR_ASSERT(alts_handshaker_client_start_server(config->client, nullptr, + &config->out_frame) == + TSI_INVALID_ARGUMENT); + GPR_ASSERT(alts_handshaker_client_start_server( + nullptr, event, &config->out_frame) == TSI_INVALID_ARGUMENT); + + /* Check next. */ + GPR_ASSERT(alts_handshaker_client_next(config->client, event, nullptr) == + TSI_INVALID_ARGUMENT); + GPR_ASSERT(alts_handshaker_client_next(config->client, nullptr, + &config->out_frame) == + TSI_INVALID_ARGUMENT); + GPR_ASSERT(alts_handshaker_client_next(nullptr, event, &config->out_frame) == + TSI_INVALID_ARGUMENT); + + /* Check shutdown. */ + alts_handshaker_client_shutdown(nullptr); + + /* Cleanup. */ + alts_tsi_event_destroy(event); + destroy_config(config); +} + +static void schedule_request_success_test() { + /* Initialization. */ + alts_handshaker_client_test_config* config = create_config(); + alts_tsi_event* event = nullptr; + + /* Check client_start success. */ + alts_handshaker_client_set_grpc_caller_for_testing( + config->client, check_client_start_success); + event = alts_tsi_event_create_for_testing(true /* is_client. */); + GPR_ASSERT(alts_handshaker_client_start_client(config->client, event) == + TSI_OK); + alts_tsi_event_destroy(event); + + /* Check server_start success. */ + alts_handshaker_client_set_grpc_caller_for_testing( + config->client, check_server_start_success); + event = alts_tsi_event_create_for_testing(false /* is_client. */); + GPR_ASSERT(alts_handshaker_client_start_server(config->client, event, + &config->out_frame) == TSI_OK); + alts_tsi_event_destroy(event); + + /* Check next success. */ + alts_handshaker_client_set_grpc_caller_for_testing(config->client, + check_next_success); + event = alts_tsi_event_create_for_testing(true /* is_client. */); + GPR_ASSERT(alts_handshaker_client_next(config->client, event, + &config->out_frame) == TSI_OK); + alts_tsi_event_destroy(event); + + /* Cleanup. */ + destroy_config(config); +} + +static void schedule_request_grpc_call_failure_test() { + /* Initialization. */ + alts_handshaker_client_test_config* config = create_config(); + alts_tsi_event* event = nullptr; + + /* Check client_start failure. */ + alts_handshaker_client_set_grpc_caller_for_testing(config->client, + check_grpc_call_failure); + event = alts_tsi_event_create_for_testing(true /* is_client. */); + GPR_ASSERT(alts_handshaker_client_start_client(config->client, event) == + TSI_INTERNAL_ERROR); + alts_tsi_event_destroy(event); + + /* Check server_start failure. */ + event = alts_tsi_event_create_for_testing(false /* is_client. */); + GPR_ASSERT(alts_handshaker_client_start_server(config->client, event, + &config->out_frame) == + TSI_INTERNAL_ERROR); + alts_tsi_event_destroy(event); + + /* Check next failure. */ + event = alts_tsi_event_create_for_testing(true /* is_cleint. */); + GPR_ASSERT( + alts_handshaker_client_next(config->client, event, &config->out_frame) == + TSI_INTERNAL_ERROR); + alts_tsi_event_destroy(event); + + /* Cleanup. */ + destroy_config(config); +} + +int main(int argc, char** argv) { + /* Initialization. */ + grpc_init(); + + /* Tests. */ + schedule_request_invalid_arg_test(); + schedule_request_success_test(); + schedule_request_grpc_call_failure_test(); + + /* Cleanup. */ + grpc_shutdown(); + return 0; +} diff --git a/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test.cc b/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test.cc new file mode 100644 index 0000000000..3506264f52 --- /dev/null +++ b/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test.cc @@ -0,0 +1,149 @@ +/* + * + * 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 <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include "test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h" + +int main(int argc, char** argv) { + const char in_bytes[] = "HELLO GOOGLE!"; + const char out_frames[] = "HELLO WORLD!"; + const char key_data[] = "THIS IS KEY DATA."; + const char details[] = "DETAILS NEED TO BE POPULATED"; + const uint32_t max_rpc_version_major = 3; + const uint32_t max_rpc_version_minor = 2; + const uint32_t min_rpc_version_major = 2; + const uint32_t min_rpc_version_minor = 1; + + /* handshaker_req_next. */ + grpc_gcp_handshaker_req* req = grpc_gcp_handshaker_req_create(NEXT_REQ); + grpc_gcp_handshaker_req* decoded_req = + grpc_gcp_handshaker_decoded_req_create(NEXT_REQ); + GPR_ASSERT( + grpc_gcp_handshaker_req_set_in_bytes(req, in_bytes, strlen(in_bytes))); + grpc_slice encoded_req; + GPR_ASSERT(grpc_gcp_handshaker_req_encode(req, &encoded_req)); + GPR_ASSERT(grpc_gcp_handshaker_req_decode(encoded_req, decoded_req)); + GPR_ASSERT(grpc_gcp_handshaker_req_equals(req, decoded_req)); + grpc_gcp_handshaker_req_destroy(req); + grpc_gcp_handshaker_req_destroy(decoded_req); + grpc_slice_unref(encoded_req); + + /* handshaker_req_client_start. */ + req = grpc_gcp_handshaker_req_create(CLIENT_START_REQ); + decoded_req = grpc_gcp_handshaker_decoded_req_create(CLIENT_START_REQ); + GPR_ASSERT(grpc_gcp_handshaker_req_set_handshake_protocol( + req, grpc_gcp_HandshakeProtocol_TLS)); + GPR_ASSERT(grpc_gcp_handshaker_req_set_local_identity_hostname( + req, "www.google.com")); + GPR_ASSERT(grpc_gcp_handshaker_req_set_local_endpoint( + req, "2001:db8::8:800:200C:417a", 9876, grpc_gcp_NetworkProtocol_TCP)); + GPR_ASSERT(grpc_gcp_handshaker_req_set_remote_endpoint( + req, "2001:db8::bac5::fed0:84a2", 1234, grpc_gcp_NetworkProtocol_TCP)); + GPR_ASSERT(grpc_gcp_handshaker_req_add_application_protocol(req, "grpc")); + GPR_ASSERT(grpc_gcp_handshaker_req_add_application_protocol(req, "http2")); + GPR_ASSERT( + grpc_gcp_handshaker_req_add_record_protocol(req, "ALTSRP_GCM_AES256")); + GPR_ASSERT( + grpc_gcp_handshaker_req_add_record_protocol(req, "ALTSRP_GCM_AES384")); + GPR_ASSERT(grpc_gcp_handshaker_req_add_target_identity_service_account( + req, "foo@google.com")); + GPR_ASSERT(grpc_gcp_handshaker_req_set_target_name( + req, "google.example.library.service")); + GPR_ASSERT(grpc_gcp_handshaker_req_set_rpc_versions( + req, max_rpc_version_major, max_rpc_version_minor, min_rpc_version_major, + min_rpc_version_minor)); + GPR_ASSERT(grpc_gcp_handshaker_req_encode(req, &encoded_req)); + GPR_ASSERT(grpc_gcp_handshaker_req_decode(encoded_req, decoded_req)); + GPR_ASSERT(grpc_gcp_handshaker_req_equals(req, decoded_req)); + grpc_gcp_handshaker_req_destroy(req); + grpc_gcp_handshaker_req_destroy(decoded_req); + grpc_slice_unref(encoded_req); + + /* handshaker_req_server_start. */ + req = grpc_gcp_handshaker_req_create(SERVER_START_REQ); + decoded_req = grpc_gcp_handshaker_decoded_req_create(SERVER_START_REQ); + GPR_ASSERT(grpc_gcp_handshaker_req_add_application_protocol(req, "grpc")); + GPR_ASSERT(grpc_gcp_handshaker_req_add_application_protocol(req, "http2")); + GPR_ASSERT(grpc_gcp_handshaker_req_set_local_endpoint( + req, "2001:db8::8:800:200C:417a", 9876, grpc_gcp_NetworkProtocol_TCP)); + GPR_ASSERT(grpc_gcp_handshaker_req_set_remote_endpoint( + req, "2001:db8::bac5::fed0:84a2", 1234, grpc_gcp_NetworkProtocol_UDP)); + GPR_ASSERT( + grpc_gcp_handshaker_req_set_in_bytes(req, in_bytes, strlen(in_bytes))); + GPR_ASSERT(grpc_gcp_handshaker_req_param_add_record_protocol( + req, grpc_gcp_HandshakeProtocol_TLS, "ALTSRP_GCM_AES128")); + GPR_ASSERT(grpc_gcp_handshaker_req_param_add_local_identity_service_account( + req, grpc_gcp_HandshakeProtocol_TLS, "foo@google.com")); + GPR_ASSERT(grpc_gcp_handshaker_req_param_add_local_identity_hostname( + req, grpc_gcp_HandshakeProtocol_TLS, "yihuaz0.mtv.corp.google.com")); + GPR_ASSERT(grpc_gcp_handshaker_req_param_add_record_protocol( + req, grpc_gcp_HandshakeProtocol_ALTS, "ALTSRP_GCM_AES128")); + GPR_ASSERT(grpc_gcp_handshaker_req_param_add_local_identity_hostname( + req, grpc_gcp_HandshakeProtocol_ALTS, "www.amazon.com")); + GPR_ASSERT(grpc_gcp_handshaker_req_set_rpc_versions( + req, max_rpc_version_major, max_rpc_version_minor, min_rpc_version_major, + min_rpc_version_minor)); + + GPR_ASSERT(grpc_gcp_handshaker_req_encode(req, &encoded_req)); + GPR_ASSERT(grpc_gcp_handshaker_req_decode(encoded_req, decoded_req)); + GPR_ASSERT(grpc_gcp_handshaker_req_equals(req, decoded_req)); + grpc_gcp_handshaker_req_destroy(req); + grpc_gcp_handshaker_req_destroy(decoded_req); + grpc_slice_unref(encoded_req); + + /* handshaker_resp. */ + grpc_gcp_handshaker_resp* resp = grpc_gcp_handshaker_resp_create(); + grpc_gcp_handshaker_resp* decoded_resp = grpc_gcp_handshaker_resp_create(); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_out_frames(resp, out_frames, + strlen(out_frames))); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_bytes_consumed(resp, 1024)); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_application_protocol(resp, "http")); + GPR_ASSERT( + grpc_gcp_handshaker_resp_set_record_protocol(resp, "ALTSRP_GCM_AES128")); + GPR_ASSERT( + grpc_gcp_handshaker_resp_set_key_data(resp, key_data, strlen(key_data))); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_local_identity_hostname( + resp, "www.faceboook.com")); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_identity_hostname( + resp, "www.amazon.com")); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_channel_open( + resp, false /* channel_open */)); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_code(resp, 1023)); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_details(resp, details)); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_rpc_versions( + resp, max_rpc_version_major, max_rpc_version_minor, min_rpc_version_major, + min_rpc_version_minor)); + grpc_slice encoded_resp; + GPR_ASSERT(grpc_gcp_handshaker_resp_encode(resp, &encoded_resp)); + GPR_ASSERT(grpc_gcp_handshaker_resp_decode(encoded_resp, decoded_resp)); + GPR_ASSERT(grpc_gcp_handshaker_resp_equals(resp, decoded_resp)); + grpc_gcp_handshaker_resp_destroy(resp); + grpc_gcp_handshaker_resp_destroy(decoded_resp); + grpc_slice_unref(encoded_resp); + /* Test invalid arguments. */ + GPR_ASSERT(!grpc_gcp_handshaker_req_set_in_bytes(nullptr, in_bytes, + strlen(in_bytes))); + GPR_ASSERT(!grpc_gcp_handshaker_req_param_add_record_protocol( + req, grpc_gcp_HandshakeProtocol_TLS, nullptr)); + GPR_ASSERT(!grpc_gcp_handshaker_req_param_add_local_identity_service_account( + nullptr, grpc_gcp_HandshakeProtocol_TLS, nullptr)); + GPR_ASSERT(!grpc_gcp_handshaker_resp_set_record_protocol(nullptr, nullptr)); +} diff --git a/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc b/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc new file mode 100644 index 0000000000..ecca04defa --- /dev/null +++ b/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc @@ -0,0 +1,642 @@ +/* + * + * 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/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h" + +const size_t kHandshakeProtocolNum = 3; + +grpc_gcp_handshaker_req* grpc_gcp_handshaker_decoded_req_create( + grpc_gcp_handshaker_req_type type) { + grpc_gcp_handshaker_req* req = + static_cast<grpc_gcp_handshaker_req*>(gpr_zalloc(sizeof(*req))); + switch (type) { + case CLIENT_START_REQ: + req->has_client_start = true; + req->client_start.target_identities.funcs.decode = + decode_repeated_identity_cb; + req->client_start.application_protocols.funcs.decode = + decode_repeated_string_cb; + req->client_start.record_protocols.funcs.decode = + decode_repeated_string_cb; + req->client_start.local_identity.hostname.funcs.decode = + decode_string_or_bytes_cb; + req->client_start.local_identity.service_account.funcs.decode = + decode_string_or_bytes_cb; + req->client_start.local_endpoint.ip_address.funcs.decode = + decode_string_or_bytes_cb; + req->client_start.remote_endpoint.ip_address.funcs.decode = + decode_string_or_bytes_cb; + req->client_start.target_name.funcs.decode = decode_string_or_bytes_cb; + break; + case SERVER_START_REQ: + req->has_server_start = true; + req->server_start.application_protocols.funcs.decode = + &decode_repeated_string_cb; + for (size_t i = 0; i < kHandshakeProtocolNum; i++) { + req->server_start.handshake_parameters[i] + .value.local_identities.funcs.decode = &decode_repeated_identity_cb; + req->server_start.handshake_parameters[i] + .value.record_protocols.funcs.decode = &decode_repeated_string_cb; + } + req->server_start.in_bytes.funcs.decode = decode_string_or_bytes_cb; + req->server_start.local_endpoint.ip_address.funcs.decode = + decode_string_or_bytes_cb; + req->server_start.remote_endpoint.ip_address.funcs.decode = + decode_string_or_bytes_cb; + break; + case NEXT_REQ: + req->has_next = true; + break; + } + return req; +} + +bool grpc_gcp_handshaker_resp_set_application_protocol( + grpc_gcp_handshaker_resp* resp, const char* application_protocol) { + if (resp == nullptr || application_protocol == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "handshaker_resp_set_application_protocol()."); + return false; + } + resp->has_result = true; + grpc_slice* slice = + create_slice(application_protocol, strlen(application_protocol)); + resp->result.application_protocol.arg = slice; + resp->result.application_protocol.funcs.encode = encode_string_or_bytes_cb; + return true; +} + +bool grpc_gcp_handshaker_resp_set_record_protocol( + grpc_gcp_handshaker_resp* resp, const char* record_protocol) { + if (resp == nullptr || record_protocol == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "handshaker_resp_set_record_protocol()."); + return false; + } + resp->has_result = true; + grpc_slice* slice = create_slice(record_protocol, strlen(record_protocol)); + resp->result.record_protocol.arg = slice; + resp->result.record_protocol.funcs.encode = encode_string_or_bytes_cb; + return true; +} + +bool grpc_gcp_handshaker_resp_set_key_data(grpc_gcp_handshaker_resp* resp, + const char* key_data, size_t size) { + if (resp == nullptr || key_data == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to handshaker_resp_set_key_data()."); + return false; + } + resp->has_result = true; + grpc_slice* slice = create_slice(key_data, size); + resp->result.key_data.arg = slice; + resp->result.key_data.funcs.encode = encode_string_or_bytes_cb; + return true; +} + +static void set_identity_hostname(grpc_gcp_identity* identity, + const char* hostname) { + grpc_slice* slice = create_slice(hostname, strlen(hostname)); + identity->hostname.arg = slice; + identity->hostname.funcs.encode = encode_string_or_bytes_cb; +} + +static void set_identity_service_account(grpc_gcp_identity* identity, + const char* service_account) { + grpc_slice* slice = create_slice(service_account, strlen(service_account)); + identity->service_account.arg = slice; + identity->service_account.funcs.encode = encode_string_or_bytes_cb; +} + +bool grpc_gcp_handshaker_resp_set_local_identity_hostname( + grpc_gcp_handshaker_resp* resp, const char* hostname) { + if (resp == nullptr || hostname == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_gcp_handshaker_resp_set_local_identity_hostname()."); + return false; + } + resp->has_result = true; + resp->result.has_local_identity = true; + set_identity_hostname(&resp->result.local_identity, hostname); + return true; +} + +bool grpc_gcp_handshaker_resp_set_local_identity_service_account( + grpc_gcp_handshaker_resp* resp, const char* service_account) { + if (resp == nullptr || service_account == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_gcp_handshaker_resp_set_local_identity_service_account()."); + return false; + } + resp->has_result = true; + resp->result.has_local_identity = true; + set_identity_service_account(&resp->result.local_identity, service_account); + return true; +} + +bool grpc_gcp_handshaker_resp_set_peer_identity_hostname( + grpc_gcp_handshaker_resp* resp, const char* hostname) { + if (resp == nullptr || hostname == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_gcp_handshaker_resp_set_peer_identity_hostname()."); + return false; + } + resp->has_result = true; + resp->result.has_peer_identity = true; + set_identity_hostname(&resp->result.peer_identity, hostname); + return true; +} + +bool grpc_gcp_handshaker_resp_set_peer_identity_service_account( + grpc_gcp_handshaker_resp* resp, const char* service_account) { + if (resp == nullptr || service_account == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_gcp_handshaker_resp_set_peer_identity_service_account()."); + return false; + } + resp->has_result = true; + resp->result.has_peer_identity = true; + set_identity_service_account(&resp->result.peer_identity, service_account); + return true; +} + +bool grpc_gcp_handshaker_resp_set_channel_open(grpc_gcp_handshaker_resp* resp, + bool keep_channel_open) { + if (resp == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr argument to " + "grpc_gcp_handshaker_resp_set_channel_open()."); + return false; + } + resp->has_result = true; + resp->result.has_keep_channel_open = true; + resp->result.keep_channel_open = keep_channel_open; + return true; +} + +bool grpc_gcp_handshaker_resp_set_code(grpc_gcp_handshaker_resp* resp, + uint32_t code) { + if (resp == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr argument to grpc_gcp_handshaker_resp_set_code()."); + return false; + } + resp->has_status = true; + resp->status.has_code = true; + resp->status.code = code; + return true; +} + +bool grpc_gcp_handshaker_resp_set_details(grpc_gcp_handshaker_resp* resp, + const char* details) { + if (resp == nullptr || details == nullptr) { + gpr_log( + GPR_ERROR, + "Invalid nullptr arguments to grpc_gcp_handshaker_resp_set_details()."); + return false; + } + resp->has_status = true; + grpc_slice* slice = create_slice(details, strlen(details)); + resp->status.details.arg = slice; + resp->status.details.funcs.encode = encode_string_or_bytes_cb; + return true; +} + +bool grpc_gcp_handshaker_resp_set_out_frames(grpc_gcp_handshaker_resp* resp, + const char* out_frames, + size_t size) { + if (resp == nullptr || out_frames == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_gcp_handshaker_resp_set_out_frames()."); + return false; + } + grpc_slice* slice = create_slice(out_frames, size); + resp->out_frames.arg = slice; + resp->out_frames.funcs.encode = encode_string_or_bytes_cb; + return true; +} + +bool grpc_gcp_handshaker_resp_set_bytes_consumed(grpc_gcp_handshaker_resp* resp, + int32_t bytes_consumed) { + if (resp == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr argument to " + "grpc_gcp_handshaker_resp_set_bytes_consumed()."); + return false; + } + resp->has_bytes_consumed = true; + resp->bytes_consumed = bytes_consumed; + return true; +} + +bool grpc_gcp_handshaker_resp_set_peer_rpc_versions( + grpc_gcp_handshaker_resp* resp, uint32_t max_major, uint32_t max_minor, + uint32_t min_major, uint32_t min_minor) { + if (resp == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr argument to " + "grpc_gcp_handshaker_resp_set_peer_rpc_versions()."); + return false; + } + resp->has_result = true; + resp->result.has_peer_rpc_versions = true; + grpc_gcp_rpc_protocol_versions* versions = &resp->result.peer_rpc_versions; + versions->has_max_rpc_version = true; + versions->has_min_rpc_version = true; + versions->max_rpc_version.has_major = true; + versions->max_rpc_version.has_minor = true; + versions->min_rpc_version.has_major = true; + versions->min_rpc_version.has_minor = true; + versions->max_rpc_version.major = max_major; + versions->max_rpc_version.minor = max_minor; + versions->min_rpc_version.major = min_major; + versions->min_rpc_version.minor = min_minor; + return true; +} + +bool grpc_gcp_handshaker_resp_encode(grpc_gcp_handshaker_resp* resp, + grpc_slice* slice) { + if (resp == nullptr || slice == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to grpc_gcp_handshaker_resp_encode()."); + return false; + } + pb_ostream_t size_stream; + memset(&size_stream, 0, sizeof(pb_ostream_t)); + if (!pb_encode(&size_stream, grpc_gcp_HandshakerResp_fields, resp)) { + gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&size_stream)); + return false; + } + size_t encoded_length = size_stream.bytes_written; + *slice = grpc_slice_malloc(encoded_length); + pb_ostream_t output_stream = + pb_ostream_from_buffer(GRPC_SLICE_START_PTR(*slice), encoded_length); + if (!pb_encode(&output_stream, grpc_gcp_HandshakerResp_fields, resp)) { + gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&size_stream)); + return false; + } + return true; +} + +bool grpc_gcp_handshaker_req_decode(grpc_slice slice, + grpc_gcp_handshaker_req* req) { + if (req == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr argument to grpc_gcp_handshaker_req_decode()."); + return false; + } + pb_istream_t stream = pb_istream_from_buffer(GRPC_SLICE_START_PTR(slice), + GRPC_SLICE_LENGTH(slice)); + req->next.in_bytes.funcs.decode = decode_string_or_bytes_cb; + if (!pb_decode(&stream, grpc_gcp_HandshakerReq_fields, req)) { + gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream)); + return false; + } + return true; +} + +/* Check equality of a pair of grpc_slice fields. */ +static bool slice_equals(grpc_slice* l_slice, grpc_slice* r_slice) { + if (l_slice == nullptr && r_slice == nullptr) { + return true; + } + if (l_slice != nullptr && r_slice != nullptr) { + return grpc_slice_eq(*l_slice, *r_slice); + } + return false; +} + +/* Check equality of a pair of grpc_gcp_identity fields. */ +static bool handshaker_identity_equals(const grpc_gcp_identity* l_id, + const grpc_gcp_identity* r_id) { + if (!((l_id->hostname.arg != nullptr) != (r_id->hostname.arg != nullptr))) { + if (l_id->hostname.arg != nullptr) { + return slice_equals(static_cast<grpc_slice*>(l_id->hostname.arg), + static_cast<grpc_slice*>(r_id->hostname.arg)); + } + } else { + return false; + } + if (!((l_id->service_account.arg != nullptr) != + (r_id->service_account.arg != nullptr))) { + if (l_id->service_account.arg != nullptr) { + return slice_equals(static_cast<grpc_slice*>(l_id->service_account.arg), + static_cast<grpc_slice*>(r_id->service_account.arg)); + } + } else { + return false; + } + return true; +} + +static bool handshaker_rpc_versions_equals( + const grpc_gcp_rpc_protocol_versions* l_version, + const grpc_gcp_rpc_protocol_versions* r_version) { + bool result = true; + result &= + (l_version->max_rpc_version.major == r_version->max_rpc_version.major); + result &= + (l_version->max_rpc_version.minor == r_version->max_rpc_version.minor); + result &= + (l_version->min_rpc_version.major == r_version->min_rpc_version.major); + result &= + (l_version->min_rpc_version.minor == r_version->min_rpc_version.minor); + return result; +} + +/* Check equality of a pair of grpc_gcp_endpoint fields. */ +static bool handshaker_endpoint_equals(const grpc_gcp_endpoint* l_end, + const grpc_gcp_endpoint* r_end) { + bool result = true; + result &= (l_end->port == r_end->port); + result &= (l_end->protocol == r_end->protocol); + if (!((l_end->ip_address.arg != nullptr) != + (r_end->ip_address.arg != nullptr))) { + if (l_end->ip_address.arg != nullptr) { + result &= slice_equals(static_cast<grpc_slice*>(l_end->ip_address.arg), + static_cast<grpc_slice*>(r_end->ip_address.arg)); + } + } else { + return false; + } + return result; +} +/** + * Check if a specific repeated field (i.e., target) is contained in a repeated + * field list (i.e., head). + */ +static bool repeated_field_list_contains_identity( + const repeated_field* head, const repeated_field* target) { + repeated_field* field = const_cast<repeated_field*>(head); + while (field != nullptr) { + if (handshaker_identity_equals( + static_cast<const grpc_gcp_identity*>(field->data), + static_cast<const grpc_gcp_identity*>(target->data))) { + return true; + } + field = field->next; + } + return false; +} + +static bool repeated_field_list_contains_string(const repeated_field* head, + const repeated_field* target) { + repeated_field* field = const_cast<repeated_field*>(head); + while (field != nullptr) { + if (slice_equals((grpc_slice*)field->data, (grpc_slice*)target->data)) { + return true; + } + field = field->next; + } + return false; +} + +/* Return a length of repeated field list. */ +static size_t repeated_field_list_get_length(const repeated_field* head) { + repeated_field* field = const_cast<repeated_field*>(head); + size_t len = 0; + while (field != nullptr) { + len++; + field = field->next; + } + return len; +} + +/** + * Check if a pair of repeated field lists contain the same set of repeated + * fields. + */ +static bool repeated_field_list_equals_identity(const repeated_field* l_head, + const repeated_field* r_head) { + if (repeated_field_list_get_length(l_head) != + repeated_field_list_get_length(r_head)) { + return false; + } + repeated_field* field = const_cast<repeated_field*>(l_head); + repeated_field* head = const_cast<repeated_field*>(r_head); + while (field != nullptr) { + if (!repeated_field_list_contains_identity(head, field)) { + return false; + } + field = field->next; + } + return true; +} + +static bool repeated_field_list_equals_string(const repeated_field* l_head, + const repeated_field* r_head) { + if (repeated_field_list_get_length(l_head) != + repeated_field_list_get_length(r_head)) { + return false; + } + repeated_field* field = const_cast<repeated_field*>(l_head); + repeated_field* head = const_cast<repeated_field*>(r_head); + while (field != nullptr) { + if (!repeated_field_list_contains_string(head, field)) { + return false; + } + field = field->next; + } + return true; +} + +/* Check equality of a pair of ALTS client_start handshake requests. */ +bool grpc_gcp_handshaker_client_start_req_equals( + grpc_gcp_start_client_handshake_req* l_req, + grpc_gcp_start_client_handshake_req* r_req) { + bool result = true; + /* Compare handshake_security_protocol. */ + result &= + l_req->handshake_security_protocol == r_req->handshake_security_protocol; + /* Compare application_protocols, record_protocols, and target_identities. */ + result &= repeated_field_list_equals_string( + static_cast<const repeated_field*>(l_req->application_protocols.arg), + static_cast<const repeated_field*>(r_req->application_protocols.arg)); + result &= repeated_field_list_equals_string( + static_cast<const repeated_field*>(l_req->record_protocols.arg), + static_cast<const repeated_field*>(r_req->record_protocols.arg)); + result &= repeated_field_list_equals_identity( + static_cast<const repeated_field*>(l_req->target_identities.arg), + static_cast<const repeated_field*>(r_req->target_identities.arg)); + if ((l_req->has_local_identity ^ r_req->has_local_identity) | + (l_req->has_local_endpoint ^ r_req->has_local_endpoint) | + ((l_req->has_remote_endpoint ^ r_req->has_remote_endpoint)) | + (l_req->has_rpc_versions ^ r_req->has_rpc_versions)) { + return false; + } + /* Compare local_identity, local_endpoint, and remote_endpoint. */ + if (l_req->has_local_identity) { + result &= handshaker_identity_equals(&l_req->local_identity, + &r_req->local_identity); + } + if (l_req->has_local_endpoint) { + result &= handshaker_endpoint_equals(&l_req->local_endpoint, + &r_req->local_endpoint); + } + if (l_req->has_remote_endpoint) { + result &= handshaker_endpoint_equals(&l_req->remote_endpoint, + &r_req->remote_endpoint); + } + if (l_req->has_rpc_versions) { + result &= handshaker_rpc_versions_equals(&l_req->rpc_versions, + &r_req->rpc_versions); + } + return result; +} + +/* Check equality of a pair of ALTS server_start handshake requests. */ +bool grpc_gcp_handshaker_server_start_req_equals( + grpc_gcp_start_server_handshake_req* l_req, + grpc_gcp_start_server_handshake_req* r_req) { + bool result = true; + /* Compare application_protocols. */ + result &= repeated_field_list_equals_string( + static_cast<const repeated_field*>(l_req->application_protocols.arg), + static_cast<const repeated_field*>(r_req->application_protocols.arg)); + /* Compare handshake_parameters. */ + size_t i = 0, j = 0; + result &= + (l_req->handshake_parameters_count == r_req->handshake_parameters_count); + for (i = 0; i < l_req->handshake_parameters_count; i++) { + bool found = false; + for (j = 0; j < r_req->handshake_parameters_count; j++) { + if (l_req->handshake_parameters[i].key == + r_req->handshake_parameters[j].key) { + found = true; + result &= repeated_field_list_equals_string( + static_cast<const repeated_field*>( + l_req->handshake_parameters[i].value.record_protocols.arg), + static_cast<const repeated_field*>( + r_req->handshake_parameters[j].value.record_protocols.arg)); + result &= repeated_field_list_equals_identity( + static_cast<const repeated_field*>( + l_req->handshake_parameters[i].value.local_identities.arg), + static_cast<const repeated_field*>( + r_req->handshake_parameters[j].value.local_identities.arg)); + } + } + if (!found) { + return false; + } + } + /* Compare in_bytes, local_endpoint, remote_endpoint. */ + result &= slice_equals(static_cast<grpc_slice*>(l_req->in_bytes.arg), + static_cast<grpc_slice*>(r_req->in_bytes.arg)); + if ((l_req->has_local_endpoint ^ r_req->has_local_endpoint) | + (l_req->has_remote_endpoint ^ r_req->has_remote_endpoint) | + (l_req->has_rpc_versions ^ r_req->has_rpc_versions)) + return false; + if (l_req->has_local_endpoint) { + result &= handshaker_endpoint_equals(&l_req->local_endpoint, + &r_req->local_endpoint); + } + if (l_req->has_remote_endpoint) { + result &= handshaker_endpoint_equals(&l_req->remote_endpoint, + &r_req->remote_endpoint); + } + if (l_req->has_rpc_versions) { + result &= handshaker_rpc_versions_equals(&l_req->rpc_versions, + &r_req->rpc_versions); + } + return result; +} + +/* Check equality of a pair of ALTS handshake requests. */ +bool grpc_gcp_handshaker_req_equals(grpc_gcp_handshaker_req* l_req, + grpc_gcp_handshaker_req* r_req) { + if (l_req->has_next && r_req->has_next) { + return slice_equals(static_cast<grpc_slice*>(l_req->next.in_bytes.arg), + static_cast<grpc_slice*>(r_req->next.in_bytes.arg)); + } else if (l_req->has_client_start && r_req->has_client_start) { + return grpc_gcp_handshaker_client_start_req_equals(&l_req->client_start, + &r_req->client_start); + } else if (l_req->has_server_start && r_req->has_server_start) { + return grpc_gcp_handshaker_server_start_req_equals(&l_req->server_start, + &r_req->server_start); + } + return false; +} + +/* Check equality of a pair of ALTS handshake results. */ +bool grpc_gcp_handshaker_resp_result_equals( + grpc_gcp_handshaker_result* l_result, + grpc_gcp_handshaker_result* r_result) { + bool result = true; + /* Compare application_protocol, record_protocol, and key_data. */ + result &= slice_equals( + static_cast<grpc_slice*>(l_result->application_protocol.arg), + static_cast<grpc_slice*>(r_result->application_protocol.arg)); + result &= + slice_equals(static_cast<grpc_slice*>(l_result->record_protocol.arg), + static_cast<grpc_slice*>(r_result->record_protocol.arg)); + result &= slice_equals(static_cast<grpc_slice*>(l_result->key_data.arg), + static_cast<grpc_slice*>(r_result->key_data.arg)); + /* Compare local_identity, peer_identity, and keep_channel_open. */ + if ((l_result->has_local_identity ^ r_result->has_local_identity) | + (l_result->has_peer_identity ^ r_result->has_peer_identity) | + (l_result->has_peer_rpc_versions ^ r_result->has_peer_rpc_versions)) { + return false; + } + if (l_result->has_local_identity) { + result &= handshaker_identity_equals(&l_result->local_identity, + &r_result->local_identity); + } + if (l_result->has_peer_identity) { + result &= handshaker_identity_equals(&l_result->peer_identity, + &r_result->peer_identity); + } + if (l_result->has_peer_rpc_versions) { + result &= handshaker_rpc_versions_equals(&l_result->peer_rpc_versions, + &r_result->peer_rpc_versions); + } + result &= (l_result->keep_channel_open == r_result->keep_channel_open); + return result; +} + +/* Check equality of a pair of ALTS handshake responses. */ +bool grpc_gcp_handshaker_resp_equals(grpc_gcp_handshaker_resp* l_resp, + grpc_gcp_handshaker_resp* r_resp) { + bool result = true; + /* Compare out_frames and bytes_consumed. */ + result &= slice_equals(static_cast<grpc_slice*>(l_resp->out_frames.arg), + static_cast<grpc_slice*>(r_resp->out_frames.arg)); + result &= (l_resp->bytes_consumed == r_resp->bytes_consumed); + /* Compare result and status. */ + if ((l_resp->has_result ^ r_resp->has_result) | + (l_resp->has_status ^ r_resp->has_status)) { + return false; + } + if (l_resp->has_result) { + result &= grpc_gcp_handshaker_resp_result_equals(&l_resp->result, + &r_resp->result); + } + if (l_resp->has_status) { + result &= (l_resp->status.code == r_resp->status.code); + result &= + slice_equals(static_cast<grpc_slice*>(l_resp->status.details.arg), + static_cast<grpc_slice*>(r_resp->status.details.arg)); + } + return result; +} diff --git a/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h b/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h new file mode 100644 index 0000000000..2fcbb4ea99 --- /dev/null +++ b/test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h @@ -0,0 +1,143 @@ +/* + * + * 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_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_TEST_LIB_H +#define GRPC_TEST_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_TEST_LIB_H + +#include "src/core/tsi/alts/handshaker/alts_handshaker_service_api.h" +#include "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h" +#include "src/core/tsi/alts/handshaker/transport_security_common_api.h" + +/** + * The first part of this file contains function signatures for de-serializing + * ALTS handshake requests and setting/serializing ALTS handshake responses, + * which simulate the behaviour of grpc server that runs ALTS handshaker + * service. + */ + +/** + * This method creates a ALTS handshaker request that is used to hold + * de-serialized result. + */ +grpc_gcp_handshaker_req* grpc_gcp_handshaker_decoded_req_create( + grpc_gcp_handshaker_req_type type); + +/* This method de-serializes a ALTS handshaker request. */ +bool grpc_gcp_handshaker_req_decode(grpc_slice slice, + grpc_gcp_handshaker_req* req); + +/* This method serializes a ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_encode(grpc_gcp_handshaker_resp* resp, + grpc_slice* slice); + +/* This method sets application protocol of ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_application_protocol( + grpc_gcp_handshaker_resp* resp, const char* application_protocol); + +/* This method sets record protocol of ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_record_protocol( + grpc_gcp_handshaker_resp* resp, const char* record_protocol); + +/* This method sets key_data of ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_key_data(grpc_gcp_handshaker_resp* resp, + const char* key_data, size_t size); + +/* This method sets local identity's hostname for ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_local_identity_hostname( + grpc_gcp_handshaker_resp* resp, const char* hostname); + +/** + * This method sets local identity's service account for ALTS handshaker + * response. + */ +bool grpc_gcp_handshaker_resp_set_local_identity_service_account( + grpc_gcp_handshaker_resp* resp, const char* service_account); + +/* This method sets peer identity's hostname for ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_peer_identity_hostname( + grpc_gcp_handshaker_resp* resp, const char* hostname); + +/** + * This method sets peer identity's service account for ALTS handshaker + * response. + */ +bool grpc_gcp_handshaker_resp_set_peer_identity_service_account( + grpc_gcp_handshaker_resp* resp, const char* service_account); + +/* This method sets keep_channel_open for ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_channel_open(grpc_gcp_handshaker_resp* resp, + bool keep_channel_open); + +/* This method sets code for ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_code(grpc_gcp_handshaker_resp* resp, + uint32_t code); + +/* This method sets details for ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_details(grpc_gcp_handshaker_resp* resp, + const char* details); + +/* This method sets out_frames for ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_out_frames(grpc_gcp_handshaker_resp* resp, + const char* out_frames, + size_t size); + +/* This method sets peer_rpc_versions for ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_peer_rpc_versions( + grpc_gcp_handshaker_resp* resp, uint32_t max_major, uint32_t max_minor, + uint32_t min_major, uint32_t min_minor); + +/* This method sets bytes_consumed for ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_set_bytes_consumed(grpc_gcp_handshaker_resp* resp, + int32_t bytes_consumed); + +/* This method serializes ALTS handshaker response. */ +bool grpc_gcp_handshaker_resp_encode(grpc_gcp_handshaker_resp* resp, + grpc_slice* slice); + +/* This method de-serializes ALTS handshaker request. */ +bool grpc_gcp_handshaker_req_decode(grpc_slice slice, + grpc_gcp_handshaker_req* req); + +/** + * The second part contains function signatures for checking equality of a pair + * of ALTS handshake requests/responses. + */ + +/* This method checks equality of two client_start handshaker requests. */ +bool grpc_gcp_handshaker_client_start_req_equals( + grpc_gcp_start_client_handshake_req* l_req, + grpc_gcp_start_client_handshake_req* r_req); + +/* This method checks equality of two server_start handshaker requests. */ +bool grpc_gcp_handshaker_server_start_req_equals( + grpc_gcp_start_server_handshake_req* l_req, + grpc_gcp_start_server_handshake_req* r_req); + +/* This method checks equality of two ALTS handshaker requests. */ +bool grpc_gcp_handshaker_req_equals(grpc_gcp_handshaker_req* l_req, + grpc_gcp_handshaker_req* r_req); + +/* This method checks equality of two handshaker response results. */ +bool grpc_gcp_handshaker_resp_result_equals( + grpc_gcp_handshaker_result* l_result, grpc_gcp_handshaker_result* r_result); + +/* This method checks equality of two ALTS handshaker responses. */ +bool grpc_gcp_handshaker_resp_equals(grpc_gcp_handshaker_resp* l_resp, + grpc_gcp_handshaker_resp* r_resp); + +#endif // GRPC_TEST_CORE_TSI_ALTS_HANDSHAKER_ALTS_HANDSHAKER_SERVICE_API_TEST_LIB_H diff --git a/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc b/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc new file mode 100644 index 0000000000..85a58114ba --- /dev/null +++ b/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc @@ -0,0 +1,768 @@ +/* + * + * 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 <stdio.h> +#include <stdlib.h> + +#include <grpc/grpc.h> +#include <grpc/support/sync.h> + +#include "src/core/lib/gprpp/thd.h" +#include "src/core/tsi/alts/handshaker/alts_handshaker_client.h" +#include "src/core/tsi/alts/handshaker/alts_tsi_event.h" +#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" +#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h" +#include "test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h" + +#define ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES "Hello World" +#define ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME "Hello Google" +#define ALTS_TSI_HANDSHAKER_TEST_CONSUMED_BYTES "Hello " +#define ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES "Google" +#define ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY "chapi@service.google.com" +#define ALTS_TSI_HANDSHAKER_TEST_KEY_DATA \ + "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKL" +#define ALTS_TSI_HANDSHAKER_TEST_BUFFER_SIZE 100 +#define ALTS_TSI_HANDSHAKER_TEST_SLEEP_TIME_IN_SECONDS 2 +#define ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR 3 +#define ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR 2 +#define ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR 2 +#define ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR 1 + +using grpc_core::internal:: + alts_tsi_handshaker_get_has_sent_start_message_for_testing; +using grpc_core::internal::alts_tsi_handshaker_get_is_client_for_testing; +using grpc_core::internal::alts_tsi_handshaker_get_recv_bytes_for_testing; +using grpc_core::internal::alts_tsi_handshaker_set_client_for_testing; +using grpc_core::internal::alts_tsi_handshaker_set_recv_bytes_for_testing; + +/* ALTS mock notification. */ +typedef struct notification { + gpr_cv cv; + gpr_mu mu; + bool notified; +} notification; + +/* ALTS mock handshaker client. */ +typedef struct alts_mock_handshaker_client { + alts_handshaker_client base; + bool used_for_success_test; +} alts_mock_handshaker_client; + +/* Type of ALTS handshaker response. */ +typedef enum { + INVALID, + FAILED, + CLIENT_START, + SERVER_START, + CLIENT_NEXT, + SERVER_NEXT, +} alts_handshaker_response_type; + +static alts_tsi_event* client_start_event; +static alts_tsi_event* client_next_event; +static alts_tsi_event* server_start_event; +static alts_tsi_event* server_next_event; +static notification caller_to_tsi_notification; +static notification tsi_to_caller_notification; + +static void notification_init(notification* n) { + gpr_mu_init(&n->mu); + gpr_cv_init(&n->cv); + n->notified = false; +} + +static void notification_destroy(notification* n) { + gpr_mu_destroy(&n->mu); + gpr_cv_destroy(&n->cv); +} + +static void signal(notification* n) { + gpr_mu_lock(&n->mu); + n->notified = true; + gpr_cv_signal(&n->cv); + gpr_mu_unlock(&n->mu); +} + +static void wait(notification* n) { + gpr_mu_lock(&n->mu); + while (!n->notified) { + gpr_cv_wait(&n->cv, &n->mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + n->notified = false; + gpr_mu_unlock(&n->mu); +} + +/** + * This method mocks ALTS handshaker service to generate handshaker response + * for a specific request. + */ +static grpc_byte_buffer* generate_handshaker_response( + alts_handshaker_response_type type) { + grpc_gcp_handshaker_resp* resp = grpc_gcp_handshaker_resp_create(); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_code(resp, 0)); + switch (type) { + case INVALID: + break; + case CLIENT_START: + case SERVER_START: + GPR_ASSERT(grpc_gcp_handshaker_resp_set_out_frames( + resp, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME, + strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME))); + break; + case CLIENT_NEXT: + GPR_ASSERT(grpc_gcp_handshaker_resp_set_out_frames( + resp, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME, + strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME))); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_identity_service_account( + resp, ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY)); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_bytes_consumed( + resp, strlen(ALTS_TSI_HANDSHAKER_TEST_CONSUMED_BYTES))); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_key_data( + resp, ALTS_TSI_HANDSHAKER_TEST_KEY_DATA, + strlen(ALTS_TSI_HANDSHAKER_TEST_KEY_DATA))); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_rpc_versions( + resp, ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR, + ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR, + ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR, + ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR)); + break; + case SERVER_NEXT: + GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_identity_service_account( + resp, ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY)); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_bytes_consumed( + resp, strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME))); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_key_data( + resp, ALTS_TSI_HANDSHAKER_TEST_KEY_DATA, + strlen(ALTS_TSI_HANDSHAKER_TEST_KEY_DATA))); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_peer_rpc_versions( + resp, ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MAJOR, + ALTS_TSI_HANDSHAKER_TEST_MAX_RPC_VERSION_MINOR, + ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MAJOR, + ALTS_TSI_HANDSHAKER_TEST_MIN_RPC_VERSION_MINOR)); + break; + case FAILED: + GPR_ASSERT( + grpc_gcp_handshaker_resp_set_code(resp, 3 /* INVALID ARGUMENT */)); + break; + } + grpc_slice slice; + GPR_ASSERT(grpc_gcp_handshaker_resp_encode(resp, &slice)); + if (type == INVALID) { + grpc_slice bad_slice = + grpc_slice_split_head(&slice, GRPC_SLICE_LENGTH(slice) - 1); + grpc_slice_unref(slice); + slice = grpc_slice_ref(bad_slice); + grpc_slice_unref(bad_slice); + } + grpc_byte_buffer* buffer = + grpc_raw_byte_buffer_create(&slice, 1 /* number of slices */); + grpc_slice_unref(slice); + grpc_gcp_handshaker_resp_destroy(resp); + return buffer; +} + +static void check_must_not_be_called(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(0); +} + +static void on_client_start_success_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_OK); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME)); + GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME, + bytes_to_send_size) == 0); + GPR_ASSERT(result == nullptr); + /* Validate peer identity. */ + tsi_peer peer; + GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) == + TSI_INVALID_ARGUMENT); + /* Validate frame protector. */ + tsi_frame_protector* protector = nullptr; + GPR_ASSERT(tsi_handshaker_result_create_frame_protector( + result, nullptr, &protector) == TSI_INVALID_ARGUMENT); + /* Validate unused bytes. */ + const unsigned char* unused_bytes = nullptr; + size_t unused_bytes_size = 0; + GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &unused_bytes, + &unused_bytes_size) == + TSI_INVALID_ARGUMENT); + signal(&tsi_to_caller_notification); +} + +static void on_server_start_success_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_OK); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME)); + GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME, + bytes_to_send_size) == 0); + GPR_ASSERT(result == nullptr); + /* Validate peer identity. */ + tsi_peer peer; + GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) == + TSI_INVALID_ARGUMENT); + /* Validate frame protector. */ + tsi_frame_protector* protector = nullptr; + GPR_ASSERT(tsi_handshaker_result_create_frame_protector( + result, nullptr, &protector) == TSI_INVALID_ARGUMENT); + /* Validate unused bytes. */ + const unsigned char* unused_bytes = nullptr; + size_t unused_bytes_size = 0; + GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &unused_bytes, + &unused_bytes_size) == + TSI_INVALID_ARGUMENT); + signal(&tsi_to_caller_notification); +} + +static void on_client_next_success_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_OK); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send_size == strlen(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME)); + GPR_ASSERT(memcmp(bytes_to_send, ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME, + bytes_to_send_size) == 0); + GPR_ASSERT(result != nullptr); + /* Validate peer identity. */ + tsi_peer peer; + GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) == TSI_OK); + GPR_ASSERT(peer.property_count == kTsiAltsNumOfPeerProperties); + GPR_ASSERT(memcmp(TSI_ALTS_CERTIFICATE_TYPE, peer.properties[0].value.data, + peer.properties[0].value.length) == 0); + GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY, + peer.properties[1].value.data, + peer.properties[1].value.length) == 0); + tsi_peer_destruct(&peer); + /* Validate unused bytes. */ + const unsigned char* bytes = nullptr; + size_t bytes_size = 0; + GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &bytes, + &bytes_size) == TSI_OK); + GPR_ASSERT(bytes_size == strlen(ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES)); + GPR_ASSERT(memcmp(bytes, ALTS_TSI_HANDSHAKER_TEST_REMAIN_BYTES, bytes_size) == + 0); + /* Validate frame protector. */ + tsi_frame_protector* protector = nullptr; + GPR_ASSERT(tsi_handshaker_result_create_frame_protector( + result, nullptr, &protector) == TSI_OK); + GPR_ASSERT(protector != nullptr); + tsi_frame_protector_destroy(protector); + tsi_handshaker_result_destroy(result); + signal(&tsi_to_caller_notification); +} + +static void on_server_next_success_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_OK); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send_size == 0); + GPR_ASSERT(bytes_to_send == nullptr); + GPR_ASSERT(result != nullptr); + /* Validate peer identity. */ + tsi_peer peer; + GPR_ASSERT(tsi_handshaker_result_extract_peer(result, &peer) == TSI_OK); + GPR_ASSERT(peer.property_count == kTsiAltsNumOfPeerProperties); + GPR_ASSERT(memcmp(TSI_ALTS_CERTIFICATE_TYPE, peer.properties[0].value.data, + peer.properties[0].value.length) == 0); + GPR_ASSERT(memcmp(ALTS_TSI_HANDSHAKER_TEST_PEER_IDENTITY, + peer.properties[1].value.data, + peer.properties[1].value.length) == 0); + tsi_peer_destruct(&peer); + /* Validate unused bytes. */ + const unsigned char* bytes = nullptr; + size_t bytes_size = 0; + GPR_ASSERT(tsi_handshaker_result_get_unused_bytes(result, &bytes, + &bytes_size) == TSI_OK); + GPR_ASSERT(bytes_size == 0); + GPR_ASSERT(bytes == nullptr); + /* Validate frame protector. */ + tsi_frame_protector* protector = nullptr; + GPR_ASSERT(tsi_handshaker_result_create_frame_protector( + result, nullptr, &protector) == TSI_OK); + GPR_ASSERT(protector != nullptr); + tsi_frame_protector_destroy(protector); + tsi_handshaker_result_destroy(result); + signal(&tsi_to_caller_notification); +} + +static tsi_result mock_client_start(alts_handshaker_client* self, + alts_tsi_event* event) { + alts_mock_handshaker_client* client = + reinterpret_cast<alts_mock_handshaker_client*>(self); + if (!client->used_for_success_test) { + alts_tsi_event_destroy(event); + return TSI_INTERNAL_ERROR; + } + GPR_ASSERT(event->cb == on_client_start_success_cb); + GPR_ASSERT(event->user_data == nullptr); + GPR_ASSERT(!alts_tsi_handshaker_get_has_sent_start_message_for_testing( + event->handshaker)); + /* Populate handshaker response for client_start request. */ + event->recv_buffer = generate_handshaker_response(CLIENT_START); + client_start_event = event; + signal(&caller_to_tsi_notification); + return TSI_OK; +} + +static void mock_shutdown(alts_handshaker_client* self) {} + +static tsi_result mock_server_start(alts_handshaker_client* self, + alts_tsi_event* event, + grpc_slice* bytes_received) { + alts_mock_handshaker_client* client = + reinterpret_cast<alts_mock_handshaker_client*>(self); + if (!client->used_for_success_test) { + alts_tsi_event_destroy(event); + return TSI_INTERNAL_ERROR; + } + GPR_ASSERT(event->cb == on_server_start_success_cb); + GPR_ASSERT(event->user_data == nullptr); + grpc_slice slice = grpc_empty_slice(); + GPR_ASSERT(grpc_slice_cmp(*bytes_received, slice) == 0); + GPR_ASSERT(!alts_tsi_handshaker_get_has_sent_start_message_for_testing( + event->handshaker)); + /* Populate handshaker response for server_start request. */ + event->recv_buffer = generate_handshaker_response(SERVER_START); + server_start_event = event; + grpc_slice_unref(slice); + signal(&caller_to_tsi_notification); + return TSI_OK; +} + +static tsi_result mock_next(alts_handshaker_client* self, alts_tsi_event* event, + grpc_slice* bytes_received) { + alts_mock_handshaker_client* client = + reinterpret_cast<alts_mock_handshaker_client*>(self); + if (!client->used_for_success_test) { + alts_tsi_event_destroy(event); + return TSI_INTERNAL_ERROR; + } + bool is_client = + alts_tsi_handshaker_get_is_client_for_testing(event->handshaker); + if (is_client) { + GPR_ASSERT(event->cb == on_client_next_success_cb); + } else { + GPR_ASSERT(event->cb == on_server_next_success_cb); + } + GPR_ASSERT(event->user_data == nullptr); + GPR_ASSERT(bytes_received != nullptr); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*bytes_received), + ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES, + GRPC_SLICE_LENGTH(*bytes_received)) == 0); + GPR_ASSERT(grpc_slice_cmp(alts_tsi_handshaker_get_recv_bytes_for_testing( + event->handshaker), + *bytes_received) == 0); + GPR_ASSERT(alts_tsi_handshaker_get_has_sent_start_message_for_testing( + event->handshaker)); + /* Populate handshaker response for next request. */ + grpc_slice out_frame = + grpc_slice_from_static_string(ALTS_TSI_HANDSHAKER_TEST_OUT_FRAME); + if (is_client) { + event->recv_buffer = generate_handshaker_response(CLIENT_NEXT); + } else { + event->recv_buffer = generate_handshaker_response(SERVER_NEXT); + } + alts_tsi_handshaker_set_recv_bytes_for_testing(event->handshaker, &out_frame); + if (is_client) { + client_next_event = event; + } else { + server_next_event = event; + } + signal(&caller_to_tsi_notification); + grpc_slice_unref(out_frame); + return TSI_OK; +} + +static void mock_destruct(alts_handshaker_client* client) {} + +static const alts_handshaker_client_vtable vtable = { + mock_client_start, mock_server_start, mock_next, mock_shutdown, + mock_destruct}; + +static alts_handshaker_client* alts_mock_handshaker_client_create( + bool used_for_success_test) { + alts_mock_handshaker_client* client = + static_cast<alts_mock_handshaker_client*>(gpr_zalloc(sizeof(*client))); + client->base.vtable = &vtable; + client->used_for_success_test = used_for_success_test; + return &client->base; +} + +static tsi_handshaker* create_test_handshaker(bool used_for_success_test, + bool is_client) { + tsi_handshaker* handshaker = nullptr; + alts_handshaker_client* client = + alts_mock_handshaker_client_create(used_for_success_test); + grpc_alts_credentials_options* options = + grpc_alts_credentials_client_options_create(); + alts_tsi_handshaker_create(options, "target_name", "lame", is_client, + &handshaker); + alts_tsi_handshaker* alts_handshaker = + reinterpret_cast<alts_tsi_handshaker*>(handshaker); + alts_tsi_handshaker_set_client_for_testing(alts_handshaker, client); + grpc_alts_credentials_options_destroy(options); + return handshaker; +} + +static void check_handshaker_next_invalid_input() { + /* Initialization. */ + tsi_handshaker* handshaker = create_test_handshaker(true, true); + /* Check nullptr handshaker. */ + GPR_ASSERT(tsi_handshaker_next(nullptr, nullptr, 0, nullptr, nullptr, nullptr, + check_must_not_be_called, + nullptr) == TSI_INVALID_ARGUMENT); + /* Check nullptr callback. */ + GPR_ASSERT(tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, + nullptr, nullptr, + nullptr) == TSI_INVALID_ARGUMENT); + /* Cleanup. */ + tsi_handshaker_destroy(handshaker); +} + +static void check_handshaker_shutdown_invalid_input() { + /* Initialization. */ + tsi_handshaker* handshaker = create_test_handshaker( + false /* used_for_success_test */, true /* is_client */); + /* Check nullptr handshaker. */ + tsi_handshaker_shutdown(nullptr); + /* Cleanup. */ + tsi_handshaker_destroy(handshaker); +} + +static void check_handshaker_next_success() { + /** + * Create handshakers for which internal mock client is going to do + * correctness check. + */ + tsi_handshaker* client_handshaker = create_test_handshaker( + true /* used_for_success_test */, true /* is_client */); + tsi_handshaker* server_handshaker = create_test_handshaker( + true /* used_for_success_test */, false /* is_client */); + /* Client start. */ + GPR_ASSERT(tsi_handshaker_next(client_handshaker, nullptr, 0, nullptr, + nullptr, nullptr, on_client_start_success_cb, + nullptr) == TSI_ASYNC); + wait(&tsi_to_caller_notification); + /* Client next. */ + GPR_ASSERT(tsi_handshaker_next( + client_handshaker, + (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES, + strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr, + nullptr, on_client_next_success_cb, nullptr) == TSI_ASYNC); + wait(&tsi_to_caller_notification); + /* Server start. */ + GPR_ASSERT(tsi_handshaker_next(server_handshaker, nullptr, 0, nullptr, + nullptr, nullptr, on_server_start_success_cb, + nullptr) == TSI_ASYNC); + wait(&tsi_to_caller_notification); + /* Server next. */ + GPR_ASSERT(tsi_handshaker_next( + server_handshaker, + (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES, + strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr, + nullptr, on_server_next_success_cb, nullptr) == TSI_ASYNC); + wait(&tsi_to_caller_notification); + /* Cleanup. */ + tsi_handshaker_destroy(server_handshaker); + tsi_handshaker_destroy(client_handshaker); +} + +static void check_handshaker_next_with_shutdown() { + /* Initialization. */ + tsi_handshaker* handshaker = create_test_handshaker( + true /* used_for_success_test */, true /* is_client*/); + /* next(success) -- shutdown(success) -- next (fail) */ + GPR_ASSERT(tsi_handshaker_next(handshaker, nullptr, 0, nullptr, nullptr, + nullptr, on_client_start_success_cb, + nullptr) == TSI_ASYNC); + wait(&tsi_to_caller_notification); + tsi_handshaker_shutdown(handshaker); + GPR_ASSERT(tsi_handshaker_next( + handshaker, + (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES, + strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr, + nullptr, on_client_next_success_cb, + nullptr) == TSI_HANDSHAKE_SHUTDOWN); + /* Cleanup. */ + tsi_handshaker_destroy(handshaker); +} + +static void check_handle_response_with_shutdown(void* unused) { + /* Client start. */ + wait(&caller_to_tsi_notification); + alts_tsi_event_dispatch_to_handshaker(client_start_event, true /* is_ok */); + alts_tsi_event_destroy(client_start_event); +} + +static void check_handshaker_next_failure() { + /** + * Create handshakers for which internal mock client is always going to fail. + */ + tsi_handshaker* client_handshaker = create_test_handshaker( + false /* used_for_success_test */, true /* is_client */); + tsi_handshaker* server_handshaker = create_test_handshaker( + false /* used_for_success_test */, false /* is_client */); + /* Client start. */ + GPR_ASSERT(tsi_handshaker_next(client_handshaker, nullptr, 0, nullptr, + nullptr, nullptr, check_must_not_be_called, + nullptr) == TSI_INTERNAL_ERROR); + /* Server start. */ + GPR_ASSERT(tsi_handshaker_next(server_handshaker, nullptr, 0, nullptr, + nullptr, nullptr, check_must_not_be_called, + nullptr) == TSI_INTERNAL_ERROR); + /* Server next. */ + GPR_ASSERT(tsi_handshaker_next( + server_handshaker, + (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES, + strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr, + nullptr, check_must_not_be_called, + nullptr) == TSI_INTERNAL_ERROR); + /* Client next. */ + GPR_ASSERT(tsi_handshaker_next( + client_handshaker, + (const unsigned char*)ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES, + strlen(ALTS_TSI_HANDSHAKER_TEST_RECV_BYTES), nullptr, nullptr, + nullptr, check_must_not_be_called, + nullptr) == TSI_INTERNAL_ERROR); + /* Cleanup. */ + tsi_handshaker_destroy(server_handshaker); + tsi_handshaker_destroy(client_handshaker); +} + +static void on_invalid_input_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_INTERNAL_ERROR); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send == nullptr); + GPR_ASSERT(bytes_to_send_size == 0); + GPR_ASSERT(result == nullptr); +} + +static void on_failed_grpc_call_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_INTERNAL_ERROR); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send == nullptr); + GPR_ASSERT(bytes_to_send_size == 0); + GPR_ASSERT(result == nullptr); +} + +static void check_handle_response_invalid_input() { + /** + * Create a handshaker at the client side, for which internal mock client is + * always going to fail. + */ + tsi_handshaker* handshaker = create_test_handshaker( + false /* used_for_success_test */, true /* is_client */); + alts_tsi_handshaker* alts_handshaker = + reinterpret_cast<alts_tsi_handshaker*>(handshaker); + grpc_byte_buffer recv_buffer; + /* Check nullptr handshaker. */ + alts_tsi_handshaker_handle_response(nullptr, &recv_buffer, GRPC_STATUS_OK, + nullptr, on_invalid_input_cb, nullptr, + true); + /* Check nullptr recv_bytes. */ + alts_tsi_handshaker_handle_response(alts_handshaker, nullptr, GRPC_STATUS_OK, + nullptr, on_invalid_input_cb, nullptr, + true); + /* Check failed grpc call made to handshaker service. */ + alts_tsi_handshaker_handle_response(alts_handshaker, &recv_buffer, + GRPC_STATUS_UNKNOWN, nullptr, + on_failed_grpc_call_cb, nullptr, true); + + alts_tsi_handshaker_handle_response(alts_handshaker, &recv_buffer, + GRPC_STATUS_OK, nullptr, + on_failed_grpc_call_cb, nullptr, false); + + /* Cleanup. */ + tsi_handshaker_destroy(handshaker); +} + +static void on_invalid_resp_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_DATA_CORRUPTED); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send == nullptr); + GPR_ASSERT(bytes_to_send_size == 0); + GPR_ASSERT(result == nullptr); +} + +static void check_handle_response_invalid_resp() { + /** + * Create a handshaker at the client side, for which internal mock client is + * always going to fail. + */ + tsi_handshaker* handshaker = create_test_handshaker( + false /* used_for_success_test */, true /* is_client */); + alts_tsi_handshaker* alts_handshaker = + reinterpret_cast<alts_tsi_handshaker*>(handshaker); + /* Tests. */ + grpc_byte_buffer* recv_buffer = generate_handshaker_response(INVALID); + alts_tsi_handshaker_handle_response(alts_handshaker, recv_buffer, + GRPC_STATUS_OK, nullptr, + on_invalid_resp_cb, nullptr, true); + /* Cleanup. */ + grpc_byte_buffer_destroy(recv_buffer); + tsi_handshaker_destroy(handshaker); +} + +static void check_handle_response_success(void* unused) { + /* Client start. */ + wait(&caller_to_tsi_notification); + alts_tsi_event_dispatch_to_handshaker(client_start_event, true /* is_ok */); + alts_tsi_event_destroy(client_start_event); + /* Client next. */ + wait(&caller_to_tsi_notification); + alts_tsi_event_dispatch_to_handshaker(client_next_event, true /* is_ok */); + alts_tsi_event_destroy(client_next_event); + /* Server start. */ + wait(&caller_to_tsi_notification); + alts_tsi_event_dispatch_to_handshaker(server_start_event, true /* is_ok */); + alts_tsi_event_destroy(server_start_event); + /* Server next. */ + wait(&caller_to_tsi_notification); + alts_tsi_event_dispatch_to_handshaker(server_next_event, true /* is_ok */); + alts_tsi_event_destroy(server_next_event); +} + +static void on_failed_resp_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_INVALID_ARGUMENT); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send == nullptr); + GPR_ASSERT(bytes_to_send_size == 0); + GPR_ASSERT(result == nullptr); +} + +static void check_handle_response_failure() { + /** + * Create a handshaker at the client side, for which internal mock client is + * always going to fail. + */ + tsi_handshaker* handshaker = create_test_handshaker( + false /* used_for_success_test */, true /* is_client */); + alts_tsi_handshaker* alts_handshaker = + reinterpret_cast<alts_tsi_handshaker*>(handshaker); + /* Tests. */ + grpc_byte_buffer* recv_buffer = generate_handshaker_response(FAILED); + alts_tsi_handshaker_handle_response(alts_handshaker, recv_buffer, + GRPC_STATUS_OK, nullptr, + on_failed_resp_cb, nullptr, true); + grpc_byte_buffer_destroy(recv_buffer); + /* Cleanup. */ + tsi_handshaker_destroy(handshaker); +} + +static void on_shutdown_resp_cb(tsi_result status, void* user_data, + const unsigned char* bytes_to_send, + size_t bytes_to_send_size, + tsi_handshaker_result* result) { + GPR_ASSERT(status == TSI_HANDSHAKE_SHUTDOWN); + GPR_ASSERT(user_data == nullptr); + GPR_ASSERT(bytes_to_send == nullptr); + GPR_ASSERT(bytes_to_send_size == 0); + GPR_ASSERT(result == nullptr); +} + +static void check_handle_response_after_shutdown() { + tsi_handshaker* handshaker = create_test_handshaker( + true /* used_for_success_test */, true /* is_client */); + alts_tsi_handshaker* alts_handshaker = + reinterpret_cast<alts_tsi_handshaker*>(handshaker); + /* Tests. */ + tsi_handshaker_shutdown(handshaker); + grpc_byte_buffer* recv_buffer = generate_handshaker_response(CLIENT_START); + alts_tsi_handshaker_handle_response(alts_handshaker, recv_buffer, + GRPC_STATUS_OK, nullptr, + on_shutdown_resp_cb, nullptr, true); + grpc_byte_buffer_destroy(recv_buffer); + /* Cleanup. */ + tsi_handshaker_destroy(handshaker); +} + +void check_handshaker_next_fails_after_shutdown() { + /* Initialization. */ + notification_init(&caller_to_tsi_notification); + notification_init(&tsi_to_caller_notification); + client_start_event = nullptr; + /* Tests. */ + grpc_core::Thread thd("alts_tsi_handshaker_test", + &check_handle_response_with_shutdown, nullptr); + thd.Start(); + check_handshaker_next_with_shutdown(); + thd.Join(); + /* Cleanup. */ + notification_destroy(&caller_to_tsi_notification); + notification_destroy(&tsi_to_caller_notification); +} + +void check_handshaker_success() { + /* Initialization. */ + notification_init(&caller_to_tsi_notification); + notification_init(&tsi_to_caller_notification); + client_start_event = nullptr; + client_next_event = nullptr; + server_start_event = nullptr; + server_next_event = nullptr; + /* Tests. */ + grpc_core::Thread thd("alts_tsi_handshaker_test", + &check_handle_response_success, nullptr); + thd.Start(); + check_handshaker_next_success(); + thd.Join(); + /* Cleanup. */ + notification_destroy(&caller_to_tsi_notification); + notification_destroy(&tsi_to_caller_notification); +} + +int main(int argc, char** argv) { + /* Initialization. */ + grpc_init(); + /* Tests. */ + check_handshaker_success(); + check_handshaker_next_invalid_input(); + check_handshaker_shutdown_invalid_input(); + check_handshaker_next_fails_after_shutdown(); + check_handshaker_next_failure(); + check_handle_response_invalid_input(); + check_handle_response_invalid_resp(); + check_handle_response_failure(); + check_handle_response_after_shutdown(); + /* Cleanup. */ + grpc_shutdown(); + return 0; +} diff --git a/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc b/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc new file mode 100644 index 0000000000..98c5d23641 --- /dev/null +++ b/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc @@ -0,0 +1,73 @@ +/* + * + * 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 "src/core/tsi/alts/handshaker/alts_tsi_utils.h" +#include "test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.h" + +#define ALTS_TSI_UTILS_TEST_OUT_FRAME "Hello Google" + +static void convert_to_tsi_result_test() { + GPR_ASSERT(alts_tsi_utils_convert_to_tsi_result(GRPC_STATUS_OK) == TSI_OK); + GPR_ASSERT(alts_tsi_utils_convert_to_tsi_result(GRPC_STATUS_UNKNOWN) == + TSI_UNKNOWN_ERROR); + GPR_ASSERT(alts_tsi_utils_convert_to_tsi_result( + GRPC_STATUS_INVALID_ARGUMENT) == TSI_INVALID_ARGUMENT); + GPR_ASSERT(alts_tsi_utils_convert_to_tsi_result(GRPC_STATUS_OUT_OF_RANGE) == + TSI_UNKNOWN_ERROR); + GPR_ASSERT(alts_tsi_utils_convert_to_tsi_result(GRPC_STATUS_INTERNAL) == + TSI_INTERNAL_ERROR); + GPR_ASSERT(alts_tsi_utils_convert_to_tsi_result(GRPC_STATUS_NOT_FOUND) == + TSI_NOT_FOUND); +} + +static void deserialize_response_test() { + grpc_gcp_handshaker_resp* resp = grpc_gcp_handshaker_resp_create(); + GPR_ASSERT(grpc_gcp_handshaker_resp_set_out_frames( + resp, ALTS_TSI_UTILS_TEST_OUT_FRAME, + strlen(ALTS_TSI_UTILS_TEST_OUT_FRAME))); + grpc_slice slice; + GPR_ASSERT(grpc_gcp_handshaker_resp_encode(resp, &slice)); + + /* Valid serialization. */ + grpc_byte_buffer* buffer = + grpc_raw_byte_buffer_create(&slice, 1 /* number of slices */); + grpc_gcp_handshaker_resp* decoded_resp = + alts_tsi_utils_deserialize_response(buffer); + GPR_ASSERT(grpc_gcp_handshaker_resp_equals(resp, decoded_resp)); + grpc_byte_buffer_destroy(buffer); + + /* Invalid serializaiton. */ + grpc_slice bad_slice = + grpc_slice_split_head(&slice, GRPC_SLICE_LENGTH(slice) - 1); + buffer = grpc_raw_byte_buffer_create(&bad_slice, 1 /* number of slices */); + GPR_ASSERT(alts_tsi_utils_deserialize_response(buffer) == nullptr); + + /* Clean up. */ + grpc_slice_unref(slice); + grpc_slice_unref(bad_slice); + grpc_byte_buffer_destroy(buffer); + grpc_gcp_handshaker_resp_destroy(resp); + grpc_gcp_handshaker_resp_destroy(decoded_resp); +} + +int main(int argc, char** argv) { + /* Tests. */ + deserialize_response_test(); + convert_to_tsi_result_test(); + return 0; +} diff --git a/test/core/tsi/alts/handshaker/transport_security_common_api_test.cc b/test/core/tsi/alts/handshaker/transport_security_common_api_test.cc new file mode 100644 index 0000000000..6ff1357c27 --- /dev/null +++ b/test/core/tsi/alts/handshaker/transport_security_common_api_test.cc @@ -0,0 +1,196 @@ +/* + * + * 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 <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include "src/core/tsi/alts/handshaker/transport_security_common_api.h" + +const size_t kMaxRpcVersionMajor = 3; +const size_t kMaxRpcVersionMinor = 2; +const size_t kMinRpcVersionMajor = 2; +const size_t kMinRpcVersionMinor = 1; + +static bool grpc_gcp_rpc_protocol_versions_equal( + grpc_gcp_rpc_protocol_versions* l_versions, + grpc_gcp_rpc_protocol_versions* r_versions) { + GPR_ASSERT(l_versions != nullptr && r_versions != nullptr); + if ((l_versions->has_max_rpc_version ^ r_versions->has_max_rpc_version) | + (l_versions->has_min_rpc_version ^ r_versions->has_min_rpc_version)) { + return false; + } + if (l_versions->has_max_rpc_version) { + if ((l_versions->max_rpc_version.major != + r_versions->max_rpc_version.major) || + (l_versions->max_rpc_version.minor != + r_versions->max_rpc_version.minor)) { + return false; + } + } + if (l_versions->has_min_rpc_version) { + if ((l_versions->min_rpc_version.major != + r_versions->min_rpc_version.major) || + (l_versions->min_rpc_version.minor != + r_versions->min_rpc_version.minor)) { + return false; + } + } + return true; +} + +static void test_success() { + grpc_gcp_rpc_protocol_versions version; + grpc_gcp_rpc_protocol_versions decoded_version; + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max( + &version, kMaxRpcVersionMajor, kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min( + &version, kMinRpcVersionMajor, kMinRpcVersionMinor)); + /* Serializes to raw bytes. */ + size_t encoded_length = + grpc_gcp_rpc_protocol_versions_encode_length(&version); + uint8_t* encoded_bytes = static_cast<uint8_t*>(gpr_malloc(encoded_length)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes( + &version, encoded_bytes, encoded_length)); + grpc_slice encoded_slice; + /* Serializes to grpc slice. */ + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_encode(&version, &encoded_slice)); + /* Checks serialized raw bytes and serialized grpc slice have same content. */ + GPR_ASSERT(encoded_length == GRPC_SLICE_LENGTH(encoded_slice)); + GPR_ASSERT(memcmp(encoded_bytes, GRPC_SLICE_START_PTR(encoded_slice), + encoded_length) == 0); + /* Deserializes and compares with the original version. */ + GPR_ASSERT( + grpc_gcp_rpc_protocol_versions_decode(encoded_slice, &decoded_version)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_equal(&version, &decoded_version)); + grpc_slice_unref(encoded_slice); + gpr_free(encoded_bytes); +} + +static void test_failure() { + grpc_gcp_rpc_protocol_versions version, decoded_version; + grpc_slice encoded_slice; + /* Test for invalid arguments. */ + GPR_ASSERT(!grpc_gcp_rpc_protocol_versions_set_max( + nullptr, kMaxRpcVersionMajor, kMaxRpcVersionMinor)); + GPR_ASSERT(!grpc_gcp_rpc_protocol_versions_set_min( + nullptr, kMinRpcVersionMajor, kMinRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_encode_length(nullptr) == 0); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max( + &version, kMaxRpcVersionMajor, kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min( + &version, kMinRpcVersionMajor, kMinRpcVersionMinor)); + size_t encoded_length = + grpc_gcp_rpc_protocol_versions_encode_length(&version); + uint8_t* encoded_bytes = static_cast<uint8_t*>(gpr_malloc(encoded_length)); + GPR_ASSERT(!grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes( + nullptr, encoded_bytes, encoded_length)); + GPR_ASSERT(!grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes( + &version, nullptr, encoded_length)); + GPR_ASSERT(!grpc_gcp_rpc_protocol_versions_encode_to_raw_bytes( + &version, encoded_bytes, 0)); + GPR_ASSERT(!grpc_gcp_rpc_protocol_versions_encode(nullptr, &encoded_slice)); + GPR_ASSERT(!grpc_gcp_rpc_protocol_versions_encode(&version, nullptr)); + GPR_ASSERT(!grpc_gcp_rpc_protocol_versions_decode(encoded_slice, nullptr)); + /* Test for nanopb decode. */ + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_encode(&version, &encoded_slice)); + grpc_slice bad_slice = grpc_slice_split_head( + &encoded_slice, GRPC_SLICE_LENGTH(encoded_slice) - 1); + grpc_slice_unref(encoded_slice); + GPR_ASSERT( + !grpc_gcp_rpc_protocol_versions_decode(bad_slice, &decoded_version)); + grpc_slice_unref(bad_slice); + gpr_free(encoded_bytes); +} + +static void test_copy() { + grpc_gcp_rpc_protocol_versions src; + grpc_gcp_rpc_protocol_versions des; + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max(&src, kMaxRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min(&src, kMinRpcVersionMajor, + kMinRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_copy(&src, &des)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_equal(&src, &des)); +} + +static void test_check_success() { + grpc_gcp_rpc_protocol_versions v1; + grpc_gcp_rpc_protocol_versions v2; + grpc_gcp_rpc_protocol_versions_version highest_common_version; + /* test equality. */ + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max(&v1, kMaxRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min(&v1, kMaxRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max(&v2, kMaxRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min(&v2, kMaxRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_check( + (const grpc_gcp_rpc_protocol_versions*)&v1, + (const grpc_gcp_rpc_protocol_versions*)&v2, + &highest_common_version) == 1); + GPR_ASSERT(grpc_core::internal::grpc_gcp_rpc_protocol_version_compare( + &highest_common_version, &v1.max_rpc_version) == 0); + + /* test inequality. */ + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max(&v1, kMaxRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min(&v1, kMinRpcVersionMinor, + kMinRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max(&v2, kMaxRpcVersionMajor, + kMinRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min(&v2, kMinRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_check( + (const grpc_gcp_rpc_protocol_versions*)&v1, + (const grpc_gcp_rpc_protocol_versions*)&v2, + &highest_common_version) == 1); + GPR_ASSERT(grpc_core::internal::grpc_gcp_rpc_protocol_version_compare( + &highest_common_version, &v2.max_rpc_version) == 0); +} + +static void test_check_failure() { + grpc_gcp_rpc_protocol_versions v1; + grpc_gcp_rpc_protocol_versions v2; + grpc_gcp_rpc_protocol_versions_version highest_common_version; + + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max(&v1, kMinRpcVersionMajor, + kMinRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min(&v1, kMinRpcVersionMajor, + kMinRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_max(&v2, kMaxRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_set_min(&v2, kMaxRpcVersionMajor, + kMaxRpcVersionMinor)); + GPR_ASSERT(grpc_gcp_rpc_protocol_versions_check( + (const grpc_gcp_rpc_protocol_versions*)&v1, + (const grpc_gcp_rpc_protocol_versions*)&v2, + &highest_common_version) == 0); +} + +int main(int argc, char** argv) { + /* Run tests. */ + test_success(); + test_failure(); + test_copy(); + test_check_success(); + test_check_failure(); + return 0; +} diff --git a/test/core/tsi/alts/zero_copy_frame_protector/BUILD b/test/core/tsi/alts/zero_copy_frame_protector/BUILD new file mode 100644 index 0000000000..2b41dae043 --- /dev/null +++ b/test/core/tsi/alts/zero_copy_frame_protector/BUILD @@ -0,0 +1,57 @@ +# 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. + +load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_package") + +licenses(["notice"]) # Apache v2 + +grpc_package(name = "test/core/tsi/alts/zero_copy_frame_protector") + +grpc_cc_test( + name = "alts_grpc_record_protocol_test", + srcs = ["alts_grpc_record_protocol_test.cc"], + language = "C++", + deps = [ + "//:alts_frame_protector", + "//:gpr", + "//:grpc", + "//:grpc_base_c", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + ], +) + +grpc_cc_test( + name = "alts_iovec_record_protocol_test", + srcs = ["alts_iovec_record_protocol_test.cc"], + language = "C++", + deps = [ + "//:alts_frame_protector", + "//:gpr", + "//:grpc", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + ], +) + +grpc_cc_test( + name = "alts_zero_copy_grpc_protector_test", + srcs = ["alts_zero_copy_grpc_protector_test.cc"], + language = "C++", + deps = [ + "//:alts_frame_protector", + "//:gpr", + "//:grpc", + "//:grpc_base_c", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + ], +) diff --git a/test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc b/test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc new file mode 100644 index 0000000000..b763f19d50 --- /dev/null +++ b/test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc @@ -0,0 +1,450 @@ +/* + * + * 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/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h" +#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h" +#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h" +#include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h" +#include "test/core/tsi/alts/crypt/gsec_test_util.h" + +constexpr size_t kMaxSliceLength = 256; +constexpr size_t kMaxSlices = 10; +constexpr size_t kSealRepeatTimes = 5; +constexpr size_t kTagLength = 16; + +/* Test fixtures for each test cases. */ +struct alts_grpc_record_protocol_test_fixture { + alts_grpc_record_protocol* client_protect; + alts_grpc_record_protocol* client_unprotect; + alts_grpc_record_protocol* server_protect; + alts_grpc_record_protocol* server_unprotect; +}; + +/* Test input variables for protect/unprotect operations. */ +struct alts_grpc_record_protocol_test_var { + size_t header_length; + size_t tag_length; + grpc_slice_buffer original_sb; + grpc_slice_buffer duplicate_sb; + grpc_slice_buffer protected_sb; + grpc_slice_buffer unprotected_sb; +}; + +/* --- Test utility functions. --- */ + +static void create_random_slice_buffer(grpc_slice_buffer* sb) { + GPR_ASSERT(sb != nullptr); + size_t slice_count = gsec_test_bias_random_uint32(kMaxSlices) + 1; + for (size_t i = 0; i < slice_count; i++) { + size_t slice_length = gsec_test_bias_random_uint32(kMaxSliceLength) + 1; + grpc_slice slice = GRPC_SLICE_MALLOC(slice_length); + gsec_test_random_bytes(GRPC_SLICE_START_PTR(slice), slice_length); + grpc_slice_buffer_add(sb, slice); + } +} + +static uint8_t* pointer_to_nth_byte(grpc_slice_buffer* sb, size_t index) { + GPR_ASSERT(sb != nullptr); + GPR_ASSERT(index < sb->length); + for (size_t i = 0; i < sb->count; i++) { + if (index < GRPC_SLICE_LENGTH(sb->slices[i])) { + return GRPC_SLICE_START_PTR(sb->slices[i]) + index; + } else { + index -= GRPC_SLICE_LENGTH(sb->slices[i]); + } + } + return nullptr; +} + +/* Checks if two slice buffer contents are the same. It is not super efficient, + * but OK for testing. */ +static bool are_slice_buffers_equal(grpc_slice_buffer* first, + grpc_slice_buffer* second) { + GPR_ASSERT(first != nullptr); + GPR_ASSERT(second != nullptr); + if (first->length != second->length) { + return false; + } + for (size_t i = 0; i < first->length; i++) { + uint8_t* first_ptr = pointer_to_nth_byte(first, i); + uint8_t* second_ptr = pointer_to_nth_byte(second, i); + GPR_ASSERT(first_ptr != nullptr); + GPR_ASSERT(second_ptr != nullptr); + if ((*first_ptr) != (*second_ptr)) { + return false; + } + } + return true; +} + +static void alter_random_byte(grpc_slice_buffer* sb) { + GPR_ASSERT(sb != nullptr); + if (sb->length == 0) { + return; + } + uint32_t offset = + gsec_test_bias_random_uint32(static_cast<uint32_t>(sb->length)); + uint8_t* ptr = pointer_to_nth_byte(sb, offset); + (*ptr)++; +} + +static alts_grpc_record_protocol_test_fixture* +test_fixture_integrity_only_create(bool rekey) { + alts_grpc_record_protocol_test_fixture* fixture = + static_cast<alts_grpc_record_protocol_test_fixture*>( + gpr_zalloc(sizeof(alts_grpc_record_protocol_test_fixture))); + size_t key_length = rekey ? kAes128GcmRekeyKeyLength : kAes128GcmKeyLength; + uint8_t* key; + gsec_test_random_array(&key, key_length); + gsec_aead_crypter* crypter = nullptr; + + /* Create client record protocol for protect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create( + crypter, 8, /*is_client=*/true, /*is_protect=*/true, + &fixture->client_protect) == TSI_OK); + /* Create client record protocol for unprotect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create( + crypter, 8, /*is_client=*/true, /*is_protect=*/false, + &fixture->client_unprotect) == TSI_OK); + /* Create server record protocol for protect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create( + crypter, 8, /*is_client=*/false, /*is_protect=*/true, + &fixture->server_protect) == TSI_OK); + /* Create server record protocol for unprotect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create( + crypter, 8, /*is_client=*/false, /*is_protect=*/false, + &fixture->server_unprotect) == TSI_OK); + + gpr_free(key); + return fixture; +} + +static alts_grpc_record_protocol_test_fixture* +test_fixture_integrity_only_no_rekey_create() { + return test_fixture_integrity_only_create(false); +} + +static alts_grpc_record_protocol_test_fixture* +test_fixture_integrity_only_rekey_create() { + return test_fixture_integrity_only_create(true); +} + +static alts_grpc_record_protocol_test_fixture* +test_fixture_privacy_integrity_create(bool rekey) { + alts_grpc_record_protocol_test_fixture* fixture = + static_cast<alts_grpc_record_protocol_test_fixture*>( + gpr_zalloc(sizeof(alts_grpc_record_protocol_test_fixture))); + size_t key_length = rekey ? kAes128GcmRekeyKeyLength : kAes128GcmKeyLength; + uint8_t* key; + gsec_test_random_array(&key, key_length); + gsec_aead_crypter* crypter = nullptr; + + /* Create client record protocol for protect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_grpc_privacy_integrity_record_protocol_create( + crypter, 8, /*is_client=*/true, /*is_protect=*/true, + &fixture->client_protect) == TSI_OK); + /* Create client record protocol for unprotect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_grpc_privacy_integrity_record_protocol_create( + crypter, 8, /*is_client=*/true, /*is_protect=*/false, + &fixture->client_unprotect) == TSI_OK); + /* Create server record protocol for protect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_grpc_privacy_integrity_record_protocol_create( + crypter, 8, /*is_client=*/false, /*is_protect=*/true, + &fixture->server_protect) == TSI_OK); + /* Create server record protocol for unprotect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_grpc_privacy_integrity_record_protocol_create( + crypter, 8, /*is_client=*/false, /*is_protect=*/false, + &fixture->server_unprotect) == TSI_OK); + + gpr_free(key); + return fixture; +} + +static alts_grpc_record_protocol_test_fixture* +test_fixture_privacy_integrity_no_rekey_create() { + return test_fixture_privacy_integrity_create(false); +} + +static alts_grpc_record_protocol_test_fixture* +test_fixture_privacy_integrity_rekey_create() { + return test_fixture_privacy_integrity_create(true); +} + +static void alts_grpc_record_protocol_test_fixture_destroy( + alts_grpc_record_protocol_test_fixture* fixture) { + if (fixture == nullptr) { + return; + } + grpc_core::ExecCtx exec_ctx; + alts_grpc_record_protocol_destroy(fixture->client_protect); + alts_grpc_record_protocol_destroy(fixture->client_unprotect); + alts_grpc_record_protocol_destroy(fixture->server_protect); + alts_grpc_record_protocol_destroy(fixture->server_unprotect); + grpc_core::ExecCtx::Get()->Flush(); + gpr_free(fixture); +} + +static alts_grpc_record_protocol_test_var* +alts_grpc_record_protocol_test_var_create() { + alts_grpc_record_protocol_test_var* var = + static_cast<alts_grpc_record_protocol_test_var*>( + gpr_zalloc(sizeof(alts_grpc_record_protocol_test_var))); + var->header_length = alts_iovec_record_protocol_get_header_length(); + var->tag_length = kTagLength; + /* Initialized slice buffers. */ + grpc_slice_buffer_init(&var->original_sb); + grpc_slice_buffer_init(&var->duplicate_sb); + grpc_slice_buffer_init(&var->protected_sb); + grpc_slice_buffer_init(&var->unprotected_sb); + /* Randomly sets content of original_sb, and copies into duplicate_sb. */ + create_random_slice_buffer(&var->original_sb); + for (size_t i = 0; i < var->original_sb.count; i++) { + grpc_slice_buffer_add(&var->duplicate_sb, + grpc_slice_ref(var->original_sb.slices[i])); + } + return var; +} + +static void alts_grpc_record_protocol_test_var_destroy( + alts_grpc_record_protocol_test_var* var) { + if (var == nullptr) { + return; + } + grpc_slice_buffer_destroy_internal(&var->original_sb); + grpc_slice_buffer_destroy_internal(&var->duplicate_sb); + grpc_slice_buffer_destroy_internal(&var->protected_sb); + grpc_slice_buffer_destroy_internal(&var->unprotected_sb); + gpr_free(var); +} + +/* --- alts grpc record protocol tests. --- */ + +static void random_seal_unseal(alts_grpc_record_protocol* sender, + alts_grpc_record_protocol* receiver) { + grpc_core::ExecCtx exec_ctx; + for (size_t i = 0; i < kSealRepeatTimes; i++) { + alts_grpc_record_protocol_test_var* var = + alts_grpc_record_protocol_test_var_create(); + /* Seals and then unseals. */ + size_t data_length = var->original_sb.length; + tsi_result status = alts_grpc_record_protocol_protect( + sender, &var->original_sb, &var->protected_sb); + GPR_ASSERT(status == TSI_OK); + GPR_ASSERT(var->protected_sb.length == + data_length + var->header_length + var->tag_length); + status = alts_grpc_record_protocol_unprotect(receiver, &var->protected_sb, + &var->unprotected_sb); + GPR_ASSERT(status == TSI_OK); + GPR_ASSERT( + are_slice_buffers_equal(&var->unprotected_sb, &var->duplicate_sb)); + alts_grpc_record_protocol_test_var_destroy(var); + } + grpc_core::ExecCtx::Get()->Flush(); +} + +static void empty_seal_unseal(alts_grpc_record_protocol* sender, + alts_grpc_record_protocol* receiver) { + grpc_core::ExecCtx exec_ctx; + for (size_t i = 0; i < kSealRepeatTimes; i++) { + alts_grpc_record_protocol_test_var* var = + alts_grpc_record_protocol_test_var_create(); + /* Seals and then unseals empty payload. */ + grpc_slice_buffer_reset_and_unref_internal(&var->original_sb); + grpc_slice_buffer_reset_and_unref_internal(&var->duplicate_sb); + tsi_result status = alts_grpc_record_protocol_protect( + sender, &var->original_sb, &var->protected_sb); + GPR_ASSERT(status == TSI_OK); + GPR_ASSERT(var->protected_sb.length == + var->header_length + var->tag_length); + status = alts_grpc_record_protocol_unprotect(receiver, &var->protected_sb, + &var->unprotected_sb); + GPR_ASSERT(status == TSI_OK); + GPR_ASSERT( + are_slice_buffers_equal(&var->unprotected_sb, &var->duplicate_sb)); + alts_grpc_record_protocol_test_var_destroy(var); + } + grpc_core::ExecCtx::Get()->Flush(); +} + +static void unsync_seal_unseal(alts_grpc_record_protocol* sender, + alts_grpc_record_protocol* receiver) { + grpc_core::ExecCtx exec_ctx; + tsi_result status; + alts_grpc_record_protocol_test_var* var = + alts_grpc_record_protocol_test_var_create(); + /* Seals once. */ + status = alts_grpc_record_protocol_protect(sender, &var->original_sb, + &var->protected_sb); + GPR_ASSERT(status == TSI_OK); + grpc_slice_buffer_reset_and_unref_internal(&var->protected_sb); + /* Seals again. */ + status = alts_grpc_record_protocol_protect(sender, &var->duplicate_sb, + &var->protected_sb); + GPR_ASSERT(status == TSI_OK); + /* Unseals the second frame. */ + status = alts_grpc_record_protocol_unprotect(receiver, &var->protected_sb, + &var->unprotected_sb); + GPR_ASSERT(status == TSI_INTERNAL_ERROR); + alts_grpc_record_protocol_test_var_destroy(var); + grpc_core::ExecCtx::Get()->Flush(); +} + +static void corrupted_data(alts_grpc_record_protocol* sender, + alts_grpc_record_protocol* receiver) { + grpc_core::ExecCtx exec_ctx; + tsi_result status; + alts_grpc_record_protocol_test_var* var = + alts_grpc_record_protocol_test_var_create(); + /* Seals once. */ + status = alts_grpc_record_protocol_protect(sender, &var->original_sb, + &var->protected_sb); + GPR_ASSERT(status == TSI_OK); + /* Corrupts one byte in protected_sb and tries to unprotect. */ + alter_random_byte(&var->protected_sb); + status = alts_grpc_record_protocol_unprotect(receiver, &var->protected_sb, + &var->unprotected_sb); + GPR_ASSERT(status == TSI_INTERNAL_ERROR); + alts_grpc_record_protocol_test_var_destroy(var); + grpc_core::ExecCtx::Get()->Flush(); +} + +static void input_check(alts_grpc_record_protocol* rp) { + grpc_core::ExecCtx exec_ctx; + tsi_result status; + alts_grpc_record_protocol_test_var* var = + alts_grpc_record_protocol_test_var_create(); + /* Protects with nullptr input. */ + status = alts_grpc_record_protocol_protect(rp, nullptr, &var->protected_sb); + GPR_ASSERT(status == TSI_INVALID_ARGUMENT); + status = alts_grpc_record_protocol_protect(rp, &var->original_sb, nullptr); + GPR_ASSERT(status == TSI_INVALID_ARGUMENT); + /* Unprotects with nullptr input. */ + status = alts_grpc_record_protocol_protect(rp, &var->original_sb, + &var->protected_sb); + GPR_ASSERT(status == TSI_OK); + status = + alts_grpc_record_protocol_unprotect(rp, nullptr, &var->unprotected_sb); + GPR_ASSERT(status == TSI_INVALID_ARGUMENT); + status = alts_grpc_record_protocol_unprotect(rp, &var->protected_sb, nullptr); + GPR_ASSERT(status == TSI_INVALID_ARGUMENT); + /* Unprotects on a temporary slice buffer which length is smaller than header + * length plus tag length. */ + grpc_slice_buffer temp_sb; + grpc_slice_buffer_init(&temp_sb); + grpc_slice_buffer_move_first( + &var->protected_sb, var->header_length + var->tag_length - 1, &temp_sb); + status = + alts_grpc_record_protocol_unprotect(rp, &temp_sb, &var->unprotected_sb); + GPR_ASSERT(status == TSI_INVALID_ARGUMENT); + grpc_slice_buffer_destroy_internal(&temp_sb); + alts_grpc_record_protocol_test_var_destroy(var); + grpc_core::ExecCtx::Get()->Flush(); +} + +/* --- Test cases. --- */ + +static void alts_grpc_record_protocol_random_seal_unseal_tests( + alts_grpc_record_protocol_test_fixture* fixture) { + random_seal_unseal(fixture->client_protect, fixture->server_unprotect); + random_seal_unseal(fixture->server_protect, fixture->client_unprotect); +} + +static void alts_grpc_record_protocol_empty_seal_unseal_tests( + alts_grpc_record_protocol_test_fixture* fixture) { + empty_seal_unseal(fixture->client_protect, fixture->server_unprotect); + empty_seal_unseal(fixture->server_protect, fixture->client_unprotect); +} + +static void alts_grpc_record_protocol_unsync_seal_unseal_tests( + alts_grpc_record_protocol_test_fixture* fixture) { + unsync_seal_unseal(fixture->client_protect, fixture->server_unprotect); + unsync_seal_unseal(fixture->server_protect, fixture->client_unprotect); +} + +static void alts_grpc_record_protocol_corrupted_data_tests( + alts_grpc_record_protocol_test_fixture* fixture) { + corrupted_data(fixture->client_protect, fixture->server_unprotect); + corrupted_data(fixture->server_protect, fixture->client_unprotect); +} + +static void alts_grpc_record_protocol_input_check_tests( + alts_grpc_record_protocol_test_fixture* fixture) { + input_check(fixture->client_protect); +} + +static void alts_grpc_record_protocol_tests( + alts_grpc_record_protocol_test_fixture* (*fixture_create)()) { + auto* fixture_1 = fixture_create(); + alts_grpc_record_protocol_random_seal_unseal_tests(fixture_1); + alts_grpc_record_protocol_test_fixture_destroy(fixture_1); + + auto* fixture_2 = fixture_create(); + alts_grpc_record_protocol_empty_seal_unseal_tests(fixture_2); + alts_grpc_record_protocol_test_fixture_destroy(fixture_2); + + auto* fixture_3 = fixture_create(); + alts_grpc_record_protocol_unsync_seal_unseal_tests(fixture_3); + alts_grpc_record_protocol_test_fixture_destroy(fixture_3); + + auto* fixture_4 = fixture_create(); + alts_grpc_record_protocol_corrupted_data_tests(fixture_4); + alts_grpc_record_protocol_test_fixture_destroy(fixture_4); + + auto* fixture_5 = fixture_create(); + alts_grpc_record_protocol_input_check_tests(fixture_5); + alts_grpc_record_protocol_test_fixture_destroy(fixture_5); +} + +int main(int argc, char** argv) { + alts_grpc_record_protocol_tests(&test_fixture_integrity_only_no_rekey_create); + alts_grpc_record_protocol_tests(&test_fixture_integrity_only_rekey_create); + alts_grpc_record_protocol_tests( + &test_fixture_privacy_integrity_no_rekey_create); + alts_grpc_record_protocol_tests(&test_fixture_privacy_integrity_rekey_create); + + return 0; +} diff --git a/test/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol_test.cc b/test/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol_test.cc new file mode 100644 index 0000000000..db1934bbae --- /dev/null +++ b/test/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol_test.cc @@ -0,0 +1,928 @@ +/* + * + * 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/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h" +#include "test/core/tsi/alts/crypt/gsec_test_util.h" + +constexpr size_t kMaxDataSize = 1024; +constexpr size_t kMaxSlices = 10; +constexpr size_t kSealRepeatTimes = 5; +constexpr size_t kTagLength = 16; + +/* Test fixtures for each test cases. */ +struct alts_iovec_record_protocol_test_fixture { + alts_iovec_record_protocol* client_protect; + alts_iovec_record_protocol* client_unprotect; + alts_iovec_record_protocol* server_protect; + alts_iovec_record_protocol* server_unprotect; +}; + +/* Test variables for protect/unprotect operations. */ +struct alts_iovec_record_protocol_test_var { + uint8_t* header_buf; + size_t header_length; + iovec_t header_iovec; + uint8_t* tag_buf; + size_t tag_length; + iovec_t tag_iovec; + uint8_t* data_buf; + uint8_t* dup_buf; + size_t data_length; + iovec_t* data_iovec; + size_t data_iovec_length; + uint8_t* protected_buf; + iovec_t protected_iovec; + iovec_t unprotected_iovec; +}; + +/* --- Test utility functions. --- */ + +static void randomly_slice(uint8_t* input, size_t input_length, + iovec_t** output, size_t* output_length) { + if (input_length == 0) { + *output = nullptr; + *output_length = 0; + return; + } + *output_length = gsec_test_bias_random_uint32(kMaxSlices) + 1; + *output = static_cast<iovec_t*>(gpr_malloc(*output_length * sizeof(iovec_t))); + for (size_t i = 0; i < *output_length - 1; i++) { + size_t slice_length = + gsec_test_bias_random_uint32(static_cast<uint32_t>(input_length)); + iovec_t slice = {input, slice_length}; + (*output)[i] = slice; + input += slice_length; + input_length -= slice_length; + } + iovec_t slice = {input, input_length}; + (*output)[*output_length - 1] = slice; +} + +static size_t alter_random_byte(uint8_t* buf, size_t buf_length) { + GPR_ASSERT(buf != nullptr); + uint32_t offset = + gsec_test_bias_random_uint32(static_cast<uint32_t>(buf_length)); + (*(buf + offset))++; + return offset; +} + +static void revert_back_alter(uint8_t* buf, size_t offset) { + GPR_ASSERT(buf != nullptr); + (*(buf + offset))--; +} + +static alts_iovec_record_protocol_test_fixture* +alts_iovec_record_protocol_test_fixture_create(bool rekey, + bool integrity_only) { + alts_iovec_record_protocol_test_fixture* fixture = + static_cast<alts_iovec_record_protocol_test_fixture*>( + gpr_malloc(sizeof(alts_iovec_record_protocol_test_fixture))); + size_t overflow_size = 8; + size_t key_length = rekey ? kAes128GcmRekeyKeyLength : kAes128GcmKeyLength; + uint8_t* key; + gsec_test_random_array(&key, key_length); + gsec_aead_crypter* crypter = nullptr; + /* Create client record protocol for protect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_iovec_record_protocol_create( + crypter, overflow_size, /*is_client=*/true, integrity_only, + /*is_protect=*/true, &fixture->client_protect, + nullptr) == GRPC_STATUS_OK); + /* Create client record protocol for unprotect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_iovec_record_protocol_create( + crypter, overflow_size, /*is_client=*/true, integrity_only, + /*is_protect=*/false, &fixture->client_unprotect, + nullptr) == GRPC_STATUS_OK); + /* Create server record protocol for protect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_iovec_record_protocol_create( + crypter, overflow_size, /*is_client=*/false, integrity_only, + /*is_protect=*/true, &fixture->server_protect, + nullptr) == GRPC_STATUS_OK); + /* Create server record protocol for unprotect. */ + GPR_ASSERT(gsec_aes_gcm_aead_crypter_create( + key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey, + &crypter, nullptr) == GRPC_STATUS_OK); + GPR_ASSERT(alts_iovec_record_protocol_create( + crypter, overflow_size, /*is_client=*/false, integrity_only, + /*is_protect=*/false, &fixture->server_unprotect, + nullptr) == GRPC_STATUS_OK); + + gpr_free(key); + return fixture; +} + +static void alts_iovec_record_protocol_test_fixture_destroy( + alts_iovec_record_protocol_test_fixture* fixture) { + if (fixture == nullptr) { + return; + } + alts_iovec_record_protocol_destroy(fixture->client_protect); + alts_iovec_record_protocol_destroy(fixture->client_unprotect); + alts_iovec_record_protocol_destroy(fixture->server_protect); + alts_iovec_record_protocol_destroy(fixture->server_unprotect); + gpr_free(fixture); +} + +static alts_iovec_record_protocol_test_var* +alts_iovec_record_protocol_test_var_create() { + auto* var = static_cast<alts_iovec_record_protocol_test_var*>( + gpr_zalloc(sizeof(alts_iovec_record_protocol_test_var))); + /* Sets header buffer. */ + var->header_length = alts_iovec_record_protocol_get_header_length(); + var->header_buf = static_cast<uint8_t*>(gpr_malloc(var->header_length)); + var->header_iovec.iov_base = var->header_buf; + var->header_iovec.iov_len = var->header_length; + /* Sets tag buffer. */ + var->tag_length = kTagLength; + var->tag_buf = static_cast<uint8_t*>(gpr_malloc(var->tag_length)); + var->tag_iovec.iov_base = var->tag_buf; + var->tag_iovec.iov_len = var->tag_length; + /* Randomly sets data buffer and duplicates to dup_buf. */ + var->data_length = gsec_test_bias_random_uint32(kMaxDataSize) + 1; + var->data_buf = static_cast<uint8_t*>(gpr_malloc(var->data_length)); + gsec_test_random_bytes(var->data_buf, var->data_length); + gsec_test_copy(var->data_buf, &var->dup_buf, var->data_length); + var->data_iovec = nullptr; + var->data_iovec_length = 0; + randomly_slice(var->data_buf, var->data_length, &var->data_iovec, + &var->data_iovec_length); + /* Sets protected iovec. */ + size_t protected_buf_length = + var->header_length + var->data_length + var->tag_length; + var->protected_buf = static_cast<uint8_t*>(gpr_malloc(protected_buf_length)); + var->protected_iovec.iov_base = var->protected_buf; + var->protected_iovec.iov_len = protected_buf_length; + /* Unprotected iovec points to data_buf. */ + var->unprotected_iovec.iov_base = var->data_buf; + var->unprotected_iovec.iov_len = var->data_length; + return var; +} + +static void alts_iovec_record_protocol_test_var_destroy( + alts_iovec_record_protocol_test_var* var) { + if (var == nullptr) { + return; + } + gpr_free(var->header_buf); + gpr_free(var->tag_buf); + gpr_free(var->data_buf); + gpr_free(var->dup_buf); + gpr_free(var->data_iovec); + gpr_free(var->protected_buf); + gpr_free(var); +} + +/* --- Integrity-only protect/unprotect tests. --- */ + +static void integrity_only_random_seal_unseal( + alts_iovec_record_protocol* sender, alts_iovec_record_protocol* receiver) { + for (size_t i = 0; i < kSealRepeatTimes; i++) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + /* Seals and then unseals. */ + grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect( + sender, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + gpr_free(var->data_iovec); + /* Randomly slices data buffer again. */ + randomly_slice(var->data_buf, var->data_length, &var->data_iovec, + &var->data_iovec_length); + status = alts_iovec_record_protocol_integrity_only_unprotect( + receiver, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + /* Makes sure data buffer has not been modified during + * seal/unseal. */ + GPR_ASSERT(memcmp(var->data_buf, var->dup_buf, var->data_length) == 0); + alts_iovec_record_protocol_test_var_destroy(var); + } +} + +static void integrity_only_empty_seal_unseal( + alts_iovec_record_protocol* sender, alts_iovec_record_protocol* receiver) { + for (size_t i = 0; i < kSealRepeatTimes; i++) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + /* Seals and then unseals empty payload. */ + grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect( + sender, nullptr, 0, var->header_iovec, var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + status = alts_iovec_record_protocol_integrity_only_unprotect( + receiver, nullptr, 0, var->header_iovec, var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + alts_iovec_record_protocol_test_var_destroy(var); + } +} + +static void integrity_only_unsync_seal_unseal( + alts_iovec_record_protocol* sender, alts_iovec_record_protocol* receiver) { + /* Seals once. */ + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect( + sender, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + alts_iovec_record_protocol_test_var_destroy(var); + /* Seals again. */ + var = alts_iovec_record_protocol_test_var_create(); + status = alts_iovec_record_protocol_integrity_only_protect( + sender, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + /* Unseals the second frame. */ + char* error_message = nullptr; + status = alts_iovec_record_protocol_integrity_only_unprotect( + receiver, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, + "Frame tag verification failed.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void integrity_only_corrupted_data( + alts_iovec_record_protocol* sender, alts_iovec_record_protocol* receiver) { + /* Seals the data first. */ + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect( + sender, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + /* Alter frame length field. */ + char* error_message = nullptr; + size_t offset = + alter_random_byte(var->header_buf, kZeroCopyFrameLengthFieldSize); + status = alts_iovec_record_protocol_integrity_only_unprotect( + receiver, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, "Bad frame length.")); + gpr_free(error_message); + revert_back_alter(var->header_buf, offset); + /* Alter message type field. */ + offset = alter_random_byte(var->header_buf + kZeroCopyFrameLengthFieldSize, + kZeroCopyFrameMessageTypeFieldSize); + status = alts_iovec_record_protocol_integrity_only_unprotect( + receiver, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, + "Unsupported message type.")); + gpr_free(error_message); + revert_back_alter(var->header_buf + kZeroCopyFrameLengthFieldSize, offset); + /* Alter data. */ + offset = alter_random_byte(var->data_buf, var->data_length); + status = alts_iovec_record_protocol_integrity_only_unprotect( + receiver, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, + "Frame tag verification failed.")); + gpr_free(error_message); + revert_back_alter(var->data_buf, offset); + /* Alter tag. */ + offset = alter_random_byte(var->tag_buf, var->tag_length); + status = alts_iovec_record_protocol_integrity_only_unprotect( + receiver, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, + "Frame tag verification failed.")); + gpr_free(error_message); + revert_back_alter(var->tag_buf, offset); + /* Reverted protected data should be verified correctly. */ + status = alts_iovec_record_protocol_integrity_only_unprotect( + receiver, var->data_iovec, var->data_iovec_length, var->header_iovec, + var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(var->data_buf, var->dup_buf, var->data_length) == 0); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void integrity_only_protect_input_check(alts_iovec_record_protocol* rp) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + char* error_message = nullptr; + /* Header buffer is nullptr. */ + iovec_t header_iovec = {nullptr, var->header_length}; + grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect( + rp, var->data_iovec, var->data_iovec_length, header_iovec, var->tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Header is nullptr.")); + gpr_free(error_message); + /* Header buffer length is 0. */ + header_iovec.iov_base = var->header_buf; + header_iovec.iov_len = 0; + status = alts_iovec_record_protocol_integrity_only_protect( + rp, var->data_iovec, var->data_iovec_length, header_iovec, var->tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Header length is incorrect.")); + gpr_free(error_message); + /* Tag buffer is nullptr. */ + iovec_t tag_iovec = {nullptr, var->tag_length}; + status = alts_iovec_record_protocol_integrity_only_protect( + rp, var->data_iovec, var->data_iovec_length, var->header_iovec, tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, "Tag is nullptr.")); + gpr_free(error_message); + /* Tag buffer length is 0. */ + tag_iovec.iov_base = var->tag_buf; + tag_iovec.iov_len = 0; + status = alts_iovec_record_protocol_integrity_only_protect( + rp, var->data_iovec, var->data_iovec_length, var->header_iovec, tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Tag length is incorrect.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void integrity_only_unprotect_input_check( + alts_iovec_record_protocol* rp) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + char* error_message = nullptr; + /* Header buffer is nullptr. */ + iovec_t header_iovec = {nullptr, var->header_length}; + grpc_status_code status = alts_iovec_record_protocol_integrity_only_unprotect( + rp, var->data_iovec, var->data_iovec_length, header_iovec, var->tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Header is nullptr.")); + gpr_free(error_message); + /* Header buffer length is 0. */ + header_iovec.iov_base = var->header_buf; + header_iovec.iov_len = 0; + status = alts_iovec_record_protocol_integrity_only_unprotect( + rp, var->data_iovec, var->data_iovec_length, header_iovec, var->tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Header length is incorrect.")); + gpr_free(error_message); + /* Tag buffer is nullptr. */ + iovec_t tag_iovec = {nullptr, var->tag_length}; + status = alts_iovec_record_protocol_integrity_only_unprotect( + rp, var->data_iovec, var->data_iovec_length, var->header_iovec, tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, "Tag is nullptr.")); + gpr_free(error_message); + /* Tag buffer length is 0. */ + tag_iovec.iov_base = var->tag_buf; + tag_iovec.iov_len = 0; + status = alts_iovec_record_protocol_integrity_only_unprotect( + rp, var->data_iovec, var->data_iovec_length, var->header_iovec, tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Tag length is incorrect.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +/* --- Privacy-integrity protect/unprotect tests. --- */ + +static void privacy_integrity_random_seal_unseal( + alts_iovec_record_protocol* sender, alts_iovec_record_protocol* receiver) { + for (size_t i = 0; i < kSealRepeatTimes; i++) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + /* Seals and then unseals. */ + grpc_status_code status = + alts_iovec_record_protocol_privacy_integrity_protect( + sender, var->data_iovec, var->data_iovec_length, + var->protected_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + iovec_t header_iovec = {var->protected_buf, var->header_length}; + gpr_free(var->data_iovec); + /* Randomly slices protected buffer, excluding the header. */ + randomly_slice(var->protected_buf + var->header_length, + var->data_length + var->tag_length, &var->data_iovec, + &var->data_iovec_length); + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + receiver, header_iovec, var->data_iovec, var->data_iovec_length, + var->unprotected_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + /* Makes sure unprotected data are the same as the original. */ + GPR_ASSERT(memcmp(var->data_buf, var->dup_buf, var->data_length) == 0); + alts_iovec_record_protocol_test_var_destroy(var); + } +} + +static void privacy_integrity_empty_seal_unseal( + alts_iovec_record_protocol* sender, alts_iovec_record_protocol* receiver) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + size_t empty_payload_frame_size = var->header_length + var->tag_length; + auto* protected_buf = + static_cast<uint8_t*>(gpr_malloc(empty_payload_frame_size)); + for (size_t i = 0; i < kSealRepeatTimes; i++) { + iovec_t protected_iovec = {protected_buf, empty_payload_frame_size}; + iovec_t unprotected_iovec = {nullptr, 0}; + iovec_t data_iovec = {protected_buf + var->header_length, var->tag_length}; + /* Seals and then unseals empty payload. */ + grpc_status_code status = + alts_iovec_record_protocol_privacy_integrity_protect( + sender, nullptr, 0, protected_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + iovec_t header_iovec = {protected_buf, var->header_length}; + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + receiver, header_iovec, &data_iovec, 1, unprotected_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + } + gpr_free(protected_buf); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void privacy_integrity_unsync_seal_unseal( + alts_iovec_record_protocol* sender, alts_iovec_record_protocol* receiver) { + /* Seals once. */ + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + grpc_status_code status = + alts_iovec_record_protocol_privacy_integrity_protect( + sender, var->data_iovec, var->data_iovec_length, var->protected_iovec, + nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + alts_iovec_record_protocol_test_var_destroy(var); + /* Seals again. */ + var = alts_iovec_record_protocol_test_var_create(); + status = alts_iovec_record_protocol_privacy_integrity_protect( + sender, var->data_iovec, var->data_iovec_length, var->protected_iovec, + nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + /* Unseals the second frame. */ + char* error_message = nullptr; + iovec_t header_iovec = {var->protected_buf, var->header_length}; + iovec_t protected_iovec = {var->protected_buf + var->header_length, + var->data_length + var->tag_length}; + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + receiver, header_iovec, &protected_iovec, 1, var->unprotected_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, "Frame decryption failed.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void privacy_integrity_corrupted_data( + alts_iovec_record_protocol* sender, alts_iovec_record_protocol* receiver) { + /* Seals the data first. */ + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + grpc_status_code status = + alts_iovec_record_protocol_privacy_integrity_protect( + sender, var->data_iovec, var->data_iovec_length, var->protected_iovec, + nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + char* error_message = nullptr; + uint8_t* header_buf = var->protected_buf; + size_t header_length = var->header_length; + iovec_t header_iovec = {header_buf, header_length}; + /* The following protected_buf and protected_length excludes header. */ + uint8_t* protected_buf = var->protected_buf + var->header_length; + size_t protected_length = var->data_length + var->tag_length; + iovec_t protected_iovec = {protected_buf, protected_length}; + /* Alter frame length field. */ + size_t offset = alter_random_byte(header_buf, kZeroCopyFrameLengthFieldSize); + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + receiver, header_iovec, &protected_iovec, 1, var->unprotected_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, "Bad frame length.")); + gpr_free(error_message); + revert_back_alter(header_buf, offset); + /* Alter message type field. */ + offset = alter_random_byte(header_buf + kZeroCopyFrameLengthFieldSize, + kZeroCopyFrameMessageTypeFieldSize); + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + receiver, header_iovec, &protected_iovec, 1, var->unprotected_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, + "Unsupported message type.")); + gpr_free(error_message); + revert_back_alter(header_buf + kZeroCopyFrameLengthFieldSize, offset); + /* Alter protected data. */ + offset = alter_random_byte(protected_buf, protected_length); + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + receiver, header_iovec, &protected_iovec, 1, var->unprotected_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, "Frame decryption failed.")); + gpr_free(error_message); + revert_back_alter(protected_buf, offset); + /* Reverted protected data should be verified correctly. */ + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + receiver, header_iovec, &protected_iovec, 1, var->unprotected_iovec, + nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(memcmp(var->data_buf, var->dup_buf, var->data_length) == 0); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void privacy_integrity_protect_input_check( + alts_iovec_record_protocol* rp) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + char* error_message = nullptr; + /* Protected output buffer is nullptr. */ + iovec_t protected_iovec = {nullptr, var->protected_iovec.iov_len}; + grpc_status_code status = + alts_iovec_record_protocol_privacy_integrity_protect( + rp, var->data_iovec, var->data_iovec_length, protected_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Protected frame is nullptr.")); + gpr_free(error_message); + /* Protected output buffer length incorrect. */ + protected_iovec.iov_base = var->protected_buf; + protected_iovec.iov_len = var->header_length + var->data_length; + status = alts_iovec_record_protocol_privacy_integrity_protect( + rp, var->data_iovec, var->data_iovec_length, protected_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Protected frame size is incorrect.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void privacy_integrity_unprotect_input_check( + alts_iovec_record_protocol* rp) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + char* error_message = nullptr; + /* Header buffer is nullptr. */ + iovec_t header_iovec = {var->protected_buf, var->header_length}; + iovec_t protected_iovec = {var->protected_buf + var->header_length, + var->data_length + var->tag_length}; + header_iovec.iov_base = nullptr; + grpc_status_code status = + alts_iovec_record_protocol_privacy_integrity_unprotect( + rp, header_iovec, &protected_iovec, 1, var->unprotected_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Header is nullptr.")); + gpr_free(error_message); + header_iovec.iov_base = var->protected_buf; + /* Header buffer length is 0. */ + header_iovec.iov_len = 0; + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + rp, header_iovec, &protected_iovec, 1, var->unprotected_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Header length is incorrect.")); + gpr_free(error_message); + header_iovec.iov_len = var->header_length; + /* Unprotected output buffer length is incorrect. */ + iovec_t unprotected_iovec = {var->data_buf, var->data_length - 1}; + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + rp, header_iovec, &protected_iovec, 1, unprotected_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INVALID_ARGUMENT, error_message, + "Unprotected data size is incorrect.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +/* --- Integrity-only and privacy-integrity mixed. --- */ + +static void record_protocol_wrong_mode( + alts_iovec_record_protocol* integrity_only_protect_rp, + alts_iovec_record_protocol* integrity_only_unprotect_rp, + alts_iovec_record_protocol* privacy_integrity_protect_rp, + alts_iovec_record_protocol* privacy_integrity_unprotect_rp) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + grpc_status_code status; + char* error_message = nullptr; + /* Call integrity-only protect on privacy-integrity record protocol. */ + status = alts_iovec_record_protocol_integrity_only_protect( + privacy_integrity_protect_rp, var->data_iovec, var->data_iovec_length, + var->header_iovec, var->tag_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Integrity-only operations are not allowed for this object.")); + gpr_free(error_message); + /* Call integrity-only unprotect on privacy-integrity record protocol. */ + status = alts_iovec_record_protocol_integrity_only_unprotect( + privacy_integrity_unprotect_rp, var->data_iovec, var->data_iovec_length, + var->header_iovec, var->tag_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Integrity-only operations are not allowed for this object.")); + gpr_free(error_message); + /* Call privacy-integrity protect on integrity-only record protocol. */ + status = alts_iovec_record_protocol_privacy_integrity_protect( + integrity_only_protect_rp, var->data_iovec, var->data_iovec_length, + var->protected_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Privacy-integrity operations are not allowed for this object.")); + gpr_free(error_message); + /* Call privacy-integrity unprotect on integrity-only record protocol. */ + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + integrity_only_unprotect_rp, var->header_iovec, var->data_iovec, + var->data_iovec_length, var->unprotected_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_FAILED_PRECONDITION, error_message, + "Privacy-integrity operations are not allowed for this object.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void integrity_seal_privacy_unseal( + alts_iovec_record_protocol* integrity_only_sender, + alts_iovec_record_protocol* privacy_integrity_receiver) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + grpc_status_code status; + char* error_message = nullptr; + /* Seals with integrity-only protect. */ + status = alts_iovec_record_protocol_integrity_only_protect( + integrity_only_sender, var->data_iovec, var->data_iovec_length, + var->header_iovec, var->tag_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + /* Unseal with privacy-integrity unprotect. */ + memcpy(var->protected_buf, var->data_buf, var->data_length); + memcpy(var->protected_buf + var->data_length, var->tag_buf, var->tag_length); + iovec_t protected_iovec = {var->protected_buf, + var->data_length + var->tag_length}; + status = alts_iovec_record_protocol_privacy_integrity_unprotect( + privacy_integrity_receiver, var->header_iovec, &protected_iovec, 1, + var->unprotected_iovec, &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, "Frame decryption failed.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +static void privacy_seal_integrity_unseal( + alts_iovec_record_protocol* privacy_integrity_sender, + alts_iovec_record_protocol* integrity_only_receiver) { + alts_iovec_record_protocol_test_var* var = + alts_iovec_record_protocol_test_var_create(); + grpc_status_code status; + char* error_message = nullptr; + /* Seals with privacy-integrity protect. */ + status = alts_iovec_record_protocol_privacy_integrity_protect( + privacy_integrity_sender, var->data_iovec, var->data_iovec_length, + var->protected_iovec, nullptr); + GPR_ASSERT(status == GRPC_STATUS_OK); + /* Unseal with integrity-only unprotect. */ + iovec_t header_iovec = {var->protected_buf, var->header_length}; + iovec_t data_iovec = {var->protected_buf + var->header_length, + var->data_length}; + iovec_t tag_iovec = { + var->protected_buf + var->header_length + var->data_length, + var->tag_length}; + status = alts_iovec_record_protocol_integrity_only_unprotect( + integrity_only_receiver, &data_iovec, 1, header_iovec, tag_iovec, + &error_message); + GPR_ASSERT(gsec_test_expect_compare_code_and_substr( + status, GRPC_STATUS_INTERNAL, error_message, + "Frame tag verification failed.")); + gpr_free(error_message); + alts_iovec_record_protocol_test_var_destroy(var); +} + +/* --- Test cases. --- */ + +static void alts_iovec_record_protocol_random_seal_unseal_tests() { + alts_iovec_record_protocol_test_fixture* fixture = + alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/true); + integrity_only_random_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + integrity_only_random_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/true); + integrity_only_random_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + integrity_only_random_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/false); + privacy_integrity_random_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + privacy_integrity_random_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/false); + privacy_integrity_random_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + privacy_integrity_random_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); +} + +static void alts_iovec_record_protocol_empty_seal_unseal_tests() { + alts_iovec_record_protocol_test_fixture* fixture = + alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/true); + integrity_only_empty_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + integrity_only_empty_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/true); + integrity_only_empty_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + integrity_only_empty_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/false); + privacy_integrity_empty_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + privacy_integrity_empty_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/false); + privacy_integrity_empty_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + privacy_integrity_empty_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); +} + +static void alts_iovec_record_protocol_unsync_seal_unseal_tests() { + alts_iovec_record_protocol_test_fixture* fixture = + alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/true); + integrity_only_unsync_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + integrity_only_unsync_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/true); + integrity_only_unsync_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + integrity_only_unsync_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/false); + privacy_integrity_unsync_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + privacy_integrity_unsync_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/false); + privacy_integrity_unsync_seal_unseal(fixture->client_protect, + fixture->server_unprotect); + privacy_integrity_unsync_seal_unseal(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); +} + +static void alts_iovec_record_protocol_corrupted_data_tests() { + alts_iovec_record_protocol_test_fixture* fixture = + alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/true); + integrity_only_corrupted_data(fixture->client_protect, + fixture->server_unprotect); + integrity_only_corrupted_data(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/true); + integrity_only_corrupted_data(fixture->client_protect, + fixture->server_unprotect); + integrity_only_corrupted_data(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/false); + privacy_integrity_corrupted_data(fixture->client_protect, + fixture->server_unprotect); + privacy_integrity_corrupted_data(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/false); + privacy_integrity_corrupted_data(fixture->client_protect, + fixture->server_unprotect); + privacy_integrity_corrupted_data(fixture->server_protect, + fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); +} + +static void alts_iovec_record_protocol_input_check_tests() { + alts_iovec_record_protocol_test_fixture* fixture = + alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/true); + integrity_only_protect_input_check(fixture->client_protect); + integrity_only_unprotect_input_check(fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/true); + integrity_only_protect_input_check(fixture->client_protect); + integrity_only_unprotect_input_check(fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/false); + privacy_integrity_protect_input_check(fixture->client_protect); + privacy_integrity_unprotect_input_check(fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); + + fixture = alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/false); + privacy_integrity_protect_input_check(fixture->client_protect); + privacy_integrity_unprotect_input_check(fixture->client_unprotect); + alts_iovec_record_protocol_test_fixture_destroy(fixture); +} + +static void alts_iovec_record_protocol_mix_operations_tests() { + alts_iovec_record_protocol_test_fixture* fixture_1 = + alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/true); + alts_iovec_record_protocol_test_fixture* fixture_2 = + alts_iovec_record_protocol_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/false); + + record_protocol_wrong_mode( + fixture_1->client_protect, fixture_1->client_unprotect, + fixture_2->client_protect, fixture_2->client_unprotect); + integrity_seal_privacy_unseal(fixture_1->client_protect, + fixture_2->server_unprotect); + privacy_seal_integrity_unseal(fixture_2->client_protect, + fixture_1->server_unprotect); + + alts_iovec_record_protocol_test_fixture_destroy(fixture_1); + alts_iovec_record_protocol_test_fixture_destroy(fixture_2); +} + +int main(int argc, char** argv) { + alts_iovec_record_protocol_random_seal_unseal_tests(); + alts_iovec_record_protocol_empty_seal_unseal_tests(); + alts_iovec_record_protocol_unsync_seal_unseal_tests(); + alts_iovec_record_protocol_corrupted_data_tests(); + alts_iovec_record_protocol_input_check_tests(); + alts_iovec_record_protocol_mix_operations_tests(); + return 0; +} diff --git a/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc b/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc new file mode 100644 index 0000000000..32159e22f2 --- /dev/null +++ b/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc @@ -0,0 +1,290 @@ +/* + * + * 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/slice_buffer.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/tsi/alts/crypt/gsec.h" +#include "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h" +#include "src/core/tsi/transport_security_grpc.h" +#include "test/core/tsi/alts/crypt/gsec_test_util.h" + +/* TODO: tests zero_copy_grpc_protector under TSI test library, which + * has more comprehensive tests. */ + +constexpr size_t kSealRepeatTimes = 50; +constexpr size_t kSmallBufferSize = 16; +constexpr size_t kLargeBufferSize = 16384; +constexpr size_t kChannelMaxSize = 2048; +constexpr size_t kChannelMinSize = 128; + +/* Test fixtures for each test cases. */ +struct alts_zero_copy_grpc_protector_test_fixture { + tsi_zero_copy_grpc_protector* client; + tsi_zero_copy_grpc_protector* server; +}; + +/* Test input variables for protect/unprotect operations. */ +struct alts_zero_copy_grpc_protector_test_var { + grpc_slice_buffer original_sb; + grpc_slice_buffer duplicate_sb; + grpc_slice_buffer staging_sb; + grpc_slice_buffer protected_sb; + grpc_slice_buffer unprotected_sb; +}; + +/* --- Test utility functions. --- */ + +static void create_random_slice_buffer(grpc_slice_buffer* sb, + grpc_slice_buffer* dup_sb, + size_t length) { + GPR_ASSERT(sb != nullptr); + GPR_ASSERT(dup_sb != nullptr); + GPR_ASSERT(length > 0); + grpc_slice slice = GRPC_SLICE_MALLOC(length); + gsec_test_random_bytes(GRPC_SLICE_START_PTR(slice), length); + grpc_slice_buffer_add(sb, grpc_slice_ref(slice)); + grpc_slice_buffer_add(dup_sb, slice); +} + +static uint8_t* pointer_to_nth_byte(grpc_slice_buffer* sb, size_t index) { + GPR_ASSERT(sb != nullptr); + GPR_ASSERT(index < sb->length); + for (size_t i = 0; i < sb->count; i++) { + if (index < GRPC_SLICE_LENGTH(sb->slices[i])) { + return GRPC_SLICE_START_PTR(sb->slices[i]) + index; + } else { + index -= GRPC_SLICE_LENGTH(sb->slices[i]); + } + } + return nullptr; +} + +/* Checks if two slice buffer contents are the same. It is not super efficient, + * but OK for testing. */ +static bool are_slice_buffers_equal(grpc_slice_buffer* first, + grpc_slice_buffer* second) { + GPR_ASSERT(first != nullptr); + GPR_ASSERT(second != nullptr); + if (first->length != second->length) { + return false; + } + for (size_t i = 0; i < first->length; i++) { + uint8_t* first_ptr = pointer_to_nth_byte(first, i); + uint8_t* second_ptr = pointer_to_nth_byte(second, i); + GPR_ASSERT(first_ptr != nullptr && second_ptr != nullptr); + if ((*first_ptr) != (*second_ptr)) { + return false; + } + } + return true; +} + +static alts_zero_copy_grpc_protector_test_fixture* +alts_zero_copy_grpc_protector_test_fixture_create(bool rekey, + bool integrity_only) { + alts_zero_copy_grpc_protector_test_fixture* fixture = + static_cast<alts_zero_copy_grpc_protector_test_fixture*>( + gpr_zalloc(sizeof(alts_zero_copy_grpc_protector_test_fixture))); + grpc_core::ExecCtx exec_ctx; + size_t key_length = rekey ? kAes128GcmRekeyKeyLength : kAes128GcmKeyLength; + uint8_t* key; + size_t max_protected_frame_size = 1024; + gsec_test_random_array(&key, key_length); + GPR_ASSERT(alts_zero_copy_grpc_protector_create( + key, key_length, rekey, /*is_client=*/true, integrity_only, + &max_protected_frame_size, &fixture->client) == TSI_OK); + GPR_ASSERT(alts_zero_copy_grpc_protector_create( + key, key_length, rekey, /*is_client=*/false, integrity_only, + &max_protected_frame_size, &fixture->server) == TSI_OK); + gpr_free(key); + grpc_core::ExecCtx::Get()->Flush(); + return fixture; +} + +static void alts_zero_copy_grpc_protector_test_fixture_destroy( + alts_zero_copy_grpc_protector_test_fixture* fixture) { + if (fixture == nullptr) { + return; + } + grpc_core::ExecCtx exec_ctx; + tsi_zero_copy_grpc_protector_destroy(fixture->client); + tsi_zero_copy_grpc_protector_destroy(fixture->server); + grpc_core::ExecCtx::Get()->Flush(); + gpr_free(fixture); +} + +static alts_zero_copy_grpc_protector_test_var* +alts_zero_copy_grpc_protector_test_var_create() { + alts_zero_copy_grpc_protector_test_var* var = + static_cast<alts_zero_copy_grpc_protector_test_var*>( + gpr_zalloc(sizeof(alts_zero_copy_grpc_protector_test_var))); + grpc_slice_buffer_init(&var->original_sb); + grpc_slice_buffer_init(&var->duplicate_sb); + grpc_slice_buffer_init(&var->staging_sb); + grpc_slice_buffer_init(&var->protected_sb); + grpc_slice_buffer_init(&var->unprotected_sb); + return var; +} + +static void alts_zero_copy_grpc_protector_test_var_destroy( + alts_zero_copy_grpc_protector_test_var* var) { + if (var == nullptr) { + return; + } + grpc_slice_buffer_destroy_internal(&var->original_sb); + grpc_slice_buffer_destroy_internal(&var->duplicate_sb); + grpc_slice_buffer_destroy_internal(&var->staging_sb); + grpc_slice_buffer_destroy_internal(&var->protected_sb); + grpc_slice_buffer_destroy_internal(&var->unprotected_sb); + gpr_free(var); +} + +/* --- ALTS zero-copy protector tests. --- */ + +static void seal_unseal_small_buffer(tsi_zero_copy_grpc_protector* sender, + tsi_zero_copy_grpc_protector* receiver) { + grpc_core::ExecCtx exec_ctx; + for (size_t i = 0; i < kSealRepeatTimes; i++) { + alts_zero_copy_grpc_protector_test_var* var = + alts_zero_copy_grpc_protector_test_var_create(); + /* Creates a random small slice buffer and calls protect(). */ + create_random_slice_buffer(&var->original_sb, &var->duplicate_sb, + kSmallBufferSize); + GPR_ASSERT(tsi_zero_copy_grpc_protector_protect( + sender, &var->original_sb, &var->protected_sb) == TSI_OK); + /* Splits protected slice buffer into two: first one is staging_sb, and + * second one is is protected_sb. */ + uint32_t staging_sb_size = + gsec_test_bias_random_uint32( + static_cast<uint32_t>(var->protected_sb.length - 1)) + + 1; + grpc_slice_buffer_move_first(&var->protected_sb, staging_sb_size, + &var->staging_sb); + /* Unprotects one by one. */ + GPR_ASSERT(tsi_zero_copy_grpc_protector_unprotect( + receiver, &var->staging_sb, &var->unprotected_sb) == TSI_OK); + GPR_ASSERT(var->unprotected_sb.length == 0); + GPR_ASSERT(tsi_zero_copy_grpc_protector_unprotect( + receiver, &var->protected_sb, &var->unprotected_sb) == + TSI_OK); + GPR_ASSERT( + are_slice_buffers_equal(&var->unprotected_sb, &var->duplicate_sb)); + alts_zero_copy_grpc_protector_test_var_destroy(var); + } + grpc_core::ExecCtx::Get()->Flush(); +} + +static void seal_unseal_large_buffer(tsi_zero_copy_grpc_protector* sender, + tsi_zero_copy_grpc_protector* receiver) { + grpc_core::ExecCtx exec_ctx; + for (size_t i = 0; i < kSealRepeatTimes; i++) { + alts_zero_copy_grpc_protector_test_var* var = + alts_zero_copy_grpc_protector_test_var_create(); + /* Creates a random large slice buffer and calls protect(). */ + create_random_slice_buffer(&var->original_sb, &var->duplicate_sb, + kLargeBufferSize); + GPR_ASSERT(tsi_zero_copy_grpc_protector_protect( + sender, &var->original_sb, &var->protected_sb) == TSI_OK); + /* Splits protected slice buffer into multiple pieces. Receiver unprotects + * each slice buffer one by one. */ + uint32_t channel_size = gsec_test_bias_random_uint32(static_cast<uint32_t>( + kChannelMaxSize + 1 - kChannelMinSize)) + + static_cast<uint32_t>(kChannelMinSize); + while (var->protected_sb.length > channel_size) { + grpc_slice_buffer_reset_and_unref_internal(&var->staging_sb); + grpc_slice_buffer_move_first(&var->protected_sb, channel_size, + &var->staging_sb); + GPR_ASSERT(tsi_zero_copy_grpc_protector_unprotect( + receiver, &var->staging_sb, &var->unprotected_sb) == + TSI_OK); + } + GPR_ASSERT(tsi_zero_copy_grpc_protector_unprotect( + receiver, &var->protected_sb, &var->unprotected_sb) == + TSI_OK); + GPR_ASSERT( + are_slice_buffers_equal(&var->unprotected_sb, &var->duplicate_sb)); + alts_zero_copy_grpc_protector_test_var_destroy(var); + } + grpc_core::ExecCtx::Get()->Flush(); +} + +/* --- Test cases. --- */ + +static void alts_zero_copy_protector_seal_unseal_small_buffer_tests() { + alts_zero_copy_grpc_protector_test_fixture* fixture = + alts_zero_copy_grpc_protector_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/true); + seal_unseal_small_buffer(fixture->client, fixture->server); + seal_unseal_small_buffer(fixture->server, fixture->client); + alts_zero_copy_grpc_protector_test_fixture_destroy(fixture); + + fixture = alts_zero_copy_grpc_protector_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/false); + seal_unseal_small_buffer(fixture->client, fixture->server); + seal_unseal_small_buffer(fixture->server, fixture->client); + alts_zero_copy_grpc_protector_test_fixture_destroy(fixture); + + fixture = alts_zero_copy_grpc_protector_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/true); + seal_unseal_small_buffer(fixture->client, fixture->server); + seal_unseal_small_buffer(fixture->server, fixture->client); + alts_zero_copy_grpc_protector_test_fixture_destroy(fixture); + + fixture = alts_zero_copy_grpc_protector_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/false); + seal_unseal_small_buffer(fixture->client, fixture->server); + seal_unseal_small_buffer(fixture->server, fixture->client); + alts_zero_copy_grpc_protector_test_fixture_destroy(fixture); +} + +static void alts_zero_copy_protector_seal_unseal_large_buffer_tests() { + alts_zero_copy_grpc_protector_test_fixture* fixture = + alts_zero_copy_grpc_protector_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/true); + seal_unseal_large_buffer(fixture->client, fixture->server); + seal_unseal_large_buffer(fixture->server, fixture->client); + alts_zero_copy_grpc_protector_test_fixture_destroy(fixture); + + fixture = alts_zero_copy_grpc_protector_test_fixture_create( + /*rekey=*/false, /*integrity_only=*/false); + seal_unseal_large_buffer(fixture->client, fixture->server); + seal_unseal_large_buffer(fixture->server, fixture->client); + alts_zero_copy_grpc_protector_test_fixture_destroy(fixture); + + fixture = alts_zero_copy_grpc_protector_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/true); + seal_unseal_large_buffer(fixture->client, fixture->server); + seal_unseal_large_buffer(fixture->server, fixture->client); + alts_zero_copy_grpc_protector_test_fixture_destroy(fixture); + + fixture = alts_zero_copy_grpc_protector_test_fixture_create( + /*rekey=*/true, /*integrity_only=*/false); + seal_unseal_large_buffer(fixture->client, fixture->server); + seal_unseal_large_buffer(fixture->server, fixture->client); + alts_zero_copy_grpc_protector_test_fixture_destroy(fixture); +} + +int main(int argc, char** argv) { + alts_zero_copy_protector_seal_unseal_small_buffer_tests(); + alts_zero_copy_protector_seal_unseal_large_buffer_tests(); + return 0; +} diff --git a/test/core/tsi/fake_transport_security_test.cc b/test/core/tsi/fake_transport_security_test.cc index 73643fc9fd..5e6671965d 100644 --- a/test/core/tsi/fake_transport_security_test.cc +++ b/test/core/tsi/fake_transport_security_test.cc @@ -20,7 +20,7 @@ #include <stdio.h> #include <string.h> -#include "src/core/lib/security/transport/security_connector.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/fake_transport_security.h" #include "test/core/tsi/transport_security_test_lib.h" #include "test/core/util/test_config.h" @@ -102,11 +102,12 @@ void fake_tsi_test_do_round_trip_for_all_configs() { v <<= 1; } tsi_test_fixture* fixture = fake_tsi_test_fixture_create(); - fake_tsi_test_fixture* fake_fixture = (fake_tsi_test_fixture*)fixture; + fake_tsi_test_fixture* fake_fixture = + reinterpret_cast<fake_tsi_test_fixture*>(fixture); tsi_test_frame_protector_config_destroy(fake_fixture->base.config); fake_fixture->base.config = tsi_test_frame_protector_config_create( bit_array[0], bit_array[1], bit_array[2], bit_array[3], bit_array[4], - bit_array[5], bit_array[6], bit_array[7]); + bit_array[5], bit_array[6]); tsi_test_do_round_trip(&fake_fixture->base); tsi_test_fixture_destroy(fixture); } @@ -123,7 +124,7 @@ void fake_tsi_test_do_round_trip_odd_buffer_size() { for (size_t ind5 = 0; ind5 < size; ind5++) { tsi_test_fixture* fixture = fake_tsi_test_fixture_create(); fake_tsi_test_fixture* fake_fixture = - (fake_tsi_test_fixture*)fixture; + reinterpret_cast<fake_tsi_test_fixture*>(fixture); tsi_test_frame_protector_config_set_buffer_size( fake_fixture->base.config, odd_sizes[ind1], odd_sizes[ind2], odd_sizes[ind3], odd_sizes[ind4], odd_sizes[ind5]); diff --git a/test/core/tsi/ssl_session_cache_test.cc b/test/core/tsi/ssl_session_cache_test.cc new file mode 100644 index 0000000000..c86cefb3ff --- /dev/null +++ b/test/core/tsi/ssl_session_cache_test.cc @@ -0,0 +1,153 @@ +/* + * + * 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 <string> +#include <unordered_set> + +#include "src/core/tsi/ssl/session_cache/ssl_session_cache.h" +#include "test/core/util/test_config.h" + +#include <grpc/grpc.h> +#include <grpc/support/log.h> +#include <gtest/gtest.h> + +namespace grpc_core { + +namespace { + +class SessionTracker; + +struct SessionExDataId { + SessionTracker* tracker; + long id; +}; + +class SessionTracker { + public: + SessionTracker() { ssl_context_ = SSL_CTX_new(TLSv1_2_method()); } + + ~SessionTracker() { SSL_CTX_free(ssl_context_); } + + tsi::SslSessionPtr NewSession(long id) { + static int ex_data_id = SSL_SESSION_get_ex_new_index( + 0, nullptr, nullptr, nullptr, DestroyExData); + GPR_ASSERT(ex_data_id != -1); + // OpenSSL and different version of BoringSSL don't agree on API + // so try both. + tsi::SslSessionPtr session = NewSessionInternal(SSL_SESSION_new); + SessionExDataId* data = new SessionExDataId{this, id}; + int result = SSL_SESSION_set_ex_data(session.get(), ex_data_id, data); + EXPECT_EQ(result, 1); + alive_sessions_.insert(id); + return session; + } + + bool IsAlive(long id) const { + return alive_sessions_.find(id) != alive_sessions_.end(); + } + + size_t AliveCount() const { return alive_sessions_.size(); } + + private: + tsi::SslSessionPtr NewSessionInternal(SSL_SESSION* (*cb)()) { + return tsi::SslSessionPtr(cb()); + } + + tsi::SslSessionPtr NewSessionInternal(SSL_SESSION* (*cb)(const SSL_CTX*)) { + return tsi::SslSessionPtr(cb(ssl_context_)); + } + + static void DestroyExData(void* parent, void* ptr, CRYPTO_EX_DATA* ad, + int index, long argl, void* argp) { + SessionExDataId* data = static_cast<SessionExDataId*>(ptr); + data->tracker->alive_sessions_.erase(data->id); + delete data; + } + + SSL_CTX* ssl_context_; + std::unordered_set<long> alive_sessions_; +}; + +TEST(SslSessionCacheTest, InitialState) { + SessionTracker tracker; + // Verify session initial state. + { + tsi::SslSessionPtr tmp_sess = tracker.NewSession(1); + EXPECT_TRUE(tracker.IsAlive(1)); + EXPECT_EQ(tracker.AliveCount(), 1); + } + EXPECT_FALSE(tracker.IsAlive(1)); + EXPECT_EQ(tracker.AliveCount(), 0); +} + +TEST(SslSessionCacheTest, LruCache) { + SessionTracker tracker; + { + RefCountedPtr<tsi::SslSessionLRUCache> cache = + tsi::SslSessionLRUCache::Create(3); + tsi::SslSessionPtr sess2 = tracker.NewSession(2); + SSL_SESSION* sess2_ptr = sess2.get(); + cache->Put("first.dropbox.com", std::move(sess2)); + EXPECT_EQ(cache->Get("first.dropbox.com").get(), sess2_ptr); + EXPECT_TRUE(tracker.IsAlive(2)); + EXPECT_EQ(tracker.AliveCount(), 1); + // Putting element with the same key destroys old session. + tsi::SslSessionPtr sess3 = tracker.NewSession(3); + SSL_SESSION* sess3_ptr = sess3.get(); + cache->Put("first.dropbox.com", std::move(sess3)); + EXPECT_FALSE(tracker.IsAlive(2)); + EXPECT_EQ(cache->Get("first.dropbox.com").get(), sess3_ptr); + EXPECT_TRUE(tracker.IsAlive(3)); + EXPECT_EQ(tracker.AliveCount(), 1); + // Putting three more elements discards current one. + for (long id = 4; id < 7; id++) { + EXPECT_TRUE(tracker.IsAlive(3)); + std::string domain = std::to_string(id) + ".random.domain"; + cache->Put(domain.c_str(), tracker.NewSession(id)); + } + EXPECT_EQ(cache->Size(), 3); + EXPECT_FALSE(tracker.IsAlive(3)); + EXPECT_EQ(tracker.AliveCount(), 3); + // Accessing element moves it into front of the queue. + EXPECT_TRUE(cache->Get("4.random.domain")); + EXPECT_TRUE(tracker.IsAlive(4)); + EXPECT_TRUE(tracker.IsAlive(5)); + EXPECT_TRUE(tracker.IsAlive(6)); + // One element has to be evicted from cache-> + cache->Put("7.random.domain", tracker.NewSession(7)); + EXPECT_TRUE(tracker.IsAlive(4)); + EXPECT_FALSE(tracker.IsAlive(5)); + EXPECT_TRUE(tracker.IsAlive(6)); + EXPECT_TRUE(tracker.IsAlive(7)); + EXPECT_EQ(tracker.AliveCount(), 3); + } + // Cache destructor destroys all sessions. + EXPECT_EQ(tracker.AliveCount(), 0); +} + +} // namespace +} // namespace grpc_core + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + grpc_init(); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 8939c0434b..b477904d60 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -21,10 +21,9 @@ #include <string.h> #include "src/core/lib/iomgr/load_file.h" -#include "src/core/lib/security/transport/security_connector.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" -#include "src/core/tsi/transport_security_adapter.h" #include "src/core/tsi/transport_security_interface.h" #include "test/core/tsi/transport_security_test_lib.h" #include "test/core/util/test_config.h" @@ -34,6 +33,10 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> +extern "C" { +#include <openssl/crypto.h> +} + #define SSL_TSI_TEST_ALPN1 "foo" #define SSL_TSI_TEST_ALPN2 "toto" #define SSL_TSI_TEST_ALPN3 "baz" @@ -42,6 +45,14 @@ #define SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM 1 #define SSL_TSI_TEST_CREDENTIALS_DIR "src/core/tsi/test_creds/" +// OpenSSL 1.1 uses AES256 for encryption session ticket by default so specify +// different STEK size. +#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_IS_BORINGSSL) +const size_t kSessionTicketEncryptionKeySize = 80; +#else +const size_t kSessionTicketEncryptionKeySize = 48; +#endif + typedef enum AlpnMode { NO_ALPN, ALPN_CLIENT_NO_SERVER, @@ -52,8 +63,8 @@ typedef enum AlpnMode { typedef struct ssl_alpn_lib { AlpnMode alpn_mode; - char** server_alpn_protocols; - char** client_alpn_protocols; + const char** server_alpn_protocols; + const char** client_alpn_protocols; uint16_t num_server_alpn_protocols; uint16_t num_client_alpn_protocols; } ssl_alpn_lib; @@ -61,7 +72,9 @@ typedef struct ssl_alpn_lib { typedef struct ssl_key_cert_lib { bool use_bad_server_cert; bool use_bad_client_cert; + bool use_root_store; char* root_cert; + tsi_ssl_root_certs_store* root_store; tsi_ssl_pem_key_cert_pair* server_pem_key_cert_pairs; tsi_ssl_pem_key_cert_pair* bad_server_pem_key_cert_pairs; tsi_ssl_pem_key_cert_pair client_pem_key_cert_pair; @@ -76,73 +89,87 @@ typedef struct ssl_tsi_test_fixture { ssl_alpn_lib* alpn_lib; bool force_client_auth; char* server_name_indication; + tsi_ssl_session_cache* session_cache; + bool session_reused; + const char* session_ticket_key; + size_t session_ticket_key_size; tsi_ssl_server_handshaker_factory* server_handshaker_factory; tsi_ssl_client_handshaker_factory* client_handshaker_factory; } ssl_tsi_test_fixture; static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); GPR_ASSERT(ssl_fixture != nullptr); GPR_ASSERT(ssl_fixture->key_cert_lib != nullptr); GPR_ASSERT(ssl_fixture->alpn_lib != nullptr); ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib; ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; /* Create client handshaker factory. */ - tsi_ssl_pem_key_cert_pair* client_key_cert_pair = nullptr; + tsi_ssl_client_handshaker_options client_options; + memset(&client_options, 0, sizeof(client_options)); + client_options.pem_root_certs = key_cert_lib->root_cert; if (ssl_fixture->force_client_auth) { - client_key_cert_pair = key_cert_lib->use_bad_client_cert - ? &key_cert_lib->bad_client_pem_key_cert_pair - : &key_cert_lib->client_pem_key_cert_pair; + client_options.pem_key_cert_pair = + key_cert_lib->use_bad_client_cert + ? &key_cert_lib->bad_client_pem_key_cert_pair + : &key_cert_lib->client_pem_key_cert_pair; } - char** client_alpn_protocols = nullptr; - uint16_t num_client_alpn_protocols = 0; if (alpn_lib->alpn_mode == ALPN_CLIENT_NO_SERVER || alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - client_alpn_protocols = alpn_lib->client_alpn_protocols; - num_client_alpn_protocols = alpn_lib->num_client_alpn_protocols; + client_options.alpn_protocols = alpn_lib->client_alpn_protocols; + client_options.num_alpn_protocols = alpn_lib->num_client_alpn_protocols; } - GPR_ASSERT(tsi_create_ssl_client_handshaker_factory( - client_key_cert_pair, key_cert_lib->root_cert, nullptr, - (const char**)client_alpn_protocols, num_client_alpn_protocols, - &ssl_fixture->client_handshaker_factory) == TSI_OK); + client_options.root_store = + key_cert_lib->use_root_store ? key_cert_lib->root_store : nullptr; + if (ssl_fixture->session_cache != nullptr) { + client_options.session_cache = ssl_fixture->session_cache; + } + GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options( + &client_options, &ssl_fixture->client_handshaker_factory) == + TSI_OK); /* Create server handshaker factory. */ - char** server_alpn_protocols = nullptr; - uint16_t num_server_alpn_protocols = 0; + tsi_ssl_server_handshaker_options server_options; + memset(&server_options, 0, sizeof(server_options)); if (alpn_lib->alpn_mode == ALPN_SERVER_NO_CLIENT || alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - server_alpn_protocols = alpn_lib->server_alpn_protocols; - num_server_alpn_protocols = alpn_lib->num_server_alpn_protocols; + server_options.alpn_protocols = alpn_lib->server_alpn_protocols; + server_options.num_alpn_protocols = alpn_lib->num_server_alpn_protocols; if (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - num_server_alpn_protocols--; + server_options.num_alpn_protocols--; } } - GPR_ASSERT(tsi_create_ssl_server_handshaker_factory( - key_cert_lib->use_bad_server_cert - ? key_cert_lib->bad_server_pem_key_cert_pairs - : key_cert_lib->server_pem_key_cert_pairs, - key_cert_lib->use_bad_server_cert - ? key_cert_lib->bad_server_num_key_cert_pairs - : key_cert_lib->server_num_key_cert_pairs, - key_cert_lib->root_cert, ssl_fixture->force_client_auth, - nullptr, (const char**)server_alpn_protocols, - num_server_alpn_protocols, - &ssl_fixture->server_handshaker_factory) == TSI_OK); + server_options.pem_key_cert_pairs = + key_cert_lib->use_bad_server_cert + ? key_cert_lib->bad_server_pem_key_cert_pairs + : key_cert_lib->server_pem_key_cert_pairs; + server_options.num_key_cert_pairs = + key_cert_lib->use_bad_server_cert + ? key_cert_lib->bad_server_num_key_cert_pairs + : key_cert_lib->server_num_key_cert_pairs; + server_options.pem_client_root_certs = key_cert_lib->root_cert; + if (ssl_fixture->force_client_auth) { + server_options.client_certificate_request = + TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; + } else { + server_options.client_certificate_request = + TSI_DONT_REQUEST_CLIENT_CERTIFICATE; + } + server_options.session_ticket_key = ssl_fixture->session_ticket_key; + server_options.session_ticket_key_size = ssl_fixture->session_ticket_key_size; + GPR_ASSERT(tsi_create_ssl_server_handshaker_factory_with_options( + &server_options, &ssl_fixture->server_handshaker_factory) == + TSI_OK); /* Create server and client handshakers. */ - tsi_handshaker* client_handshaker = nullptr; GPR_ASSERT(tsi_ssl_client_handshaker_factory_create_handshaker( ssl_fixture->client_handshaker_factory, ssl_fixture->server_name_indication, - &client_handshaker) == TSI_OK); - ssl_fixture->base.client_handshaker = - tsi_create_adapter_handshaker(client_handshaker); - tsi_handshaker* server_handshaker = nullptr; + &ssl_fixture->base.client_handshaker) == TSI_OK); GPR_ASSERT(tsi_ssl_server_handshaker_factory_create_handshaker( - ssl_fixture->server_handshaker_factory, &server_handshaker) == - TSI_OK); - ssl_fixture->base.server_handshaker = - tsi_create_adapter_handshaker(server_handshaker); + ssl_fixture->server_handshaker_factory, + &ssl_fixture->base.server_handshaker) == TSI_OK); } static void check_alpn(ssl_tsi_test_fixture* ssl_fixture, @@ -175,6 +202,18 @@ check_basic_authenticated_peer_and_get_common_name(const tsi_peer* peer) { return property; } +static void check_session_reusage(ssl_tsi_test_fixture* ssl_fixture, + tsi_peer* peer) { + const tsi_peer_property* session_reused = + tsi_peer_get_property_by_name(peer, TSI_SSL_SESSION_REUSED_PEER_PROPERTY); + GPR_ASSERT(session_reused != nullptr); + if (ssl_fixture->session_reused) { + GPR_ASSERT(strcmp(session_reused->value.data, "true") == 0); + } else { + GPR_ASSERT(strcmp(session_reused->value.data, "false") == 0); + } +} + void check_server0_peer(tsi_peer* peer) { const tsi_peer_property* property = check_basic_authenticated_peer_and_get_common_name(peer); @@ -232,7 +271,7 @@ static void check_client_peer(ssl_tsi_test_fixture* ssl_fixture, ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; if (!ssl_fixture->force_client_auth) { GPR_ASSERT(peer->property_count == - (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ? 1 : 0)); + (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ? 2 : 1)); } else { const tsi_peer_property* property = check_basic_authenticated_peer_and_get_common_name(peer); @@ -244,7 +283,8 @@ static void check_client_peer(ssl_tsi_test_fixture* ssl_fixture, } static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); GPR_ASSERT(ssl_fixture != nullptr); GPR_ASSERT(ssl_fixture->key_cert_lib != nullptr); ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib; @@ -255,8 +295,8 @@ static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) { if (expect_success) { GPR_ASSERT(tsi_handshaker_result_extract_peer( ssl_fixture->base.client_result, &peer) == TSI_OK); + check_session_reusage(ssl_fixture, &peer); check_alpn(ssl_fixture, &peer); - if (ssl_fixture->server_name_indication != nullptr) { check_server1_peer(&peer); } else { @@ -268,6 +308,7 @@ static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) { if (expect_success) { GPR_ASSERT(tsi_handshaker_result_extract_peer( ssl_fixture->base.server_result, &peer) == TSI_OK); + check_session_reusage(ssl_fixture, &peer); check_alpn(ssl_fixture, &peer); check_client_peer(ssl_fixture, &peer); } else { @@ -281,18 +322,19 @@ static void ssl_test_pem_key_cert_pair_destroy(tsi_ssl_pem_key_cert_pair kp) { } static void ssl_test_destruct(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); if (ssl_fixture == nullptr) { return; } /* Destroy ssl_alpn_lib. */ ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; for (size_t i = 0; i < alpn_lib->num_server_alpn_protocols; i++) { - gpr_free(alpn_lib->server_alpn_protocols[i]); + gpr_free(const_cast<char*>(alpn_lib->server_alpn_protocols[i])); } gpr_free(alpn_lib->server_alpn_protocols); for (size_t i = 0; i < alpn_lib->num_client_alpn_protocols; i++) { - gpr_free(alpn_lib->client_alpn_protocols[i]); + gpr_free(const_cast<char*>(alpn_lib->client_alpn_protocols[i])); } gpr_free(alpn_lib->client_alpn_protocols); gpr_free(alpn_lib); @@ -312,7 +354,11 @@ static void ssl_test_destruct(tsi_test_fixture* fixture) { ssl_test_pem_key_cert_pair_destroy( key_cert_lib->bad_client_pem_key_cert_pair); gpr_free(key_cert_lib->root_cert); + tsi_ssl_root_certs_store_destroy(key_cert_lib->root_store); gpr_free(key_cert_lib); + if (ssl_fixture->session_cache != nullptr) { + tsi_ssl_session_cache_unref(ssl_fixture->session_cache); + } /* Unreference others. */ tsi_ssl_server_handshaker_factory_unref( ssl_fixture->server_handshaker_factory); @@ -348,6 +394,7 @@ static tsi_test_fixture* ssl_tsi_test_fixture_create() { static_cast<ssl_key_cert_lib*>(gpr_zalloc(sizeof(*key_cert_lib))); key_cert_lib->use_bad_server_cert = false; key_cert_lib->use_bad_client_cert = false; + key_cert_lib->use_root_store = false; key_cert_lib->server_num_key_cert_pairs = SSL_TSI_TEST_SERVER_KEY_CERT_PAIRS_NUM; key_cert_lib->bad_server_num_key_cert_pairs = @@ -381,14 +428,17 @@ static tsi_test_fixture* ssl_tsi_test_fixture_create() { key_cert_lib->bad_client_pem_key_cert_pair.cert_chain = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "badclient.pem"); key_cert_lib->root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "ca.pem"); + key_cert_lib->root_store = + tsi_ssl_root_certs_store_create(key_cert_lib->root_cert); + GPR_ASSERT(key_cert_lib->root_store != nullptr); ssl_fixture->key_cert_lib = key_cert_lib; /* Create ssl_alpn_lib. */ ssl_alpn_lib* alpn_lib = static_cast<ssl_alpn_lib*>(gpr_zalloc(sizeof(*alpn_lib))); - alpn_lib->server_alpn_protocols = - static_cast<char**>(gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); - alpn_lib->client_alpn_protocols = - static_cast<char**>(gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); + alpn_lib->server_alpn_protocols = static_cast<const char**>( + gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); + alpn_lib->client_alpn_protocols = static_cast<const char**>( + gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); alpn_lib->server_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN1); alpn_lib->server_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); alpn_lib->client_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN2); @@ -399,6 +449,9 @@ static tsi_test_fixture* ssl_tsi_test_fixture_create() { ssl_fixture->alpn_lib = alpn_lib; ssl_fixture->base.vtable = &vtable; ssl_fixture->server_name_indication = nullptr; + ssl_fixture->session_reused = false; + ssl_fixture->session_ticket_key = nullptr; + ssl_fixture->session_ticket_key_size = 0; ssl_fixture->force_client_auth = false; return &ssl_fixture->base; } @@ -423,18 +476,39 @@ void ssl_tsi_test_do_handshake() { tsi_test_fixture_destroy(fixture); } +void ssl_tsi_test_do_handshake_with_root_store() { + tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); + ssl_fixture->key_cert_lib->use_root_store = true; + tsi_test_do_handshake(fixture); + tsi_test_fixture_destroy(fixture); +} + void ssl_tsi_test_do_handshake_with_client_authentication() { tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->force_client_auth = true; tsi_test_do_handshake(fixture); tsi_test_fixture_destroy(fixture); } +void ssl_tsi_test_do_handshake_with_client_authentication_and_root_store() { + tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); + ssl_fixture->force_client_auth = true; + ssl_fixture->key_cert_lib->use_root_store = true; + tsi_test_do_handshake(fixture); + tsi_test_fixture_destroy(fixture); +} + void ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain() { /* server1 cert contains "waterzooi.test.google.be" in SAN. */ tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->server_name_indication = const_cast<char*>("waterzooi.test.google.be"); tsi_test_do_handshake(fixture); @@ -444,7 +518,8 @@ void ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain() { void ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain() { /* server1 cert contains "*.test.google.fr" in SAN. */ tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->server_name_indication = const_cast<char*>("juju.test.google.fr"); tsi_test_do_handshake(fixture); @@ -453,7 +528,8 @@ void ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain() { void ssl_tsi_test_do_handshake_with_bad_server_cert() { tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->key_cert_lib->use_bad_server_cert = true; tsi_test_do_handshake(fixture); tsi_test_fixture_destroy(fixture); @@ -461,7 +537,8 @@ void ssl_tsi_test_do_handshake_with_bad_server_cert() { void ssl_tsi_test_do_handshake_with_bad_client_cert() { tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->key_cert_lib->use_bad_client_cert = true; ssl_fixture->force_client_auth = true; tsi_test_do_handshake(fixture); @@ -470,7 +547,8 @@ void ssl_tsi_test_do_handshake_with_bad_client_cert() { void ssl_tsi_test_do_handshake_alpn_client_no_server() { tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_NO_SERVER; tsi_test_do_handshake(fixture); tsi_test_fixture_destroy(fixture); @@ -478,7 +556,8 @@ void ssl_tsi_test_do_handshake_alpn_client_no_server() { void ssl_tsi_test_do_handshake_alpn_server_no_client() { tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->alpn_lib->alpn_mode = ALPN_SERVER_NO_CLIENT; tsi_test_do_handshake(fixture); tsi_test_fixture_destroy(fixture); @@ -486,7 +565,8 @@ void ssl_tsi_test_do_handshake_alpn_server_no_client() { void ssl_tsi_test_do_handshake_alpn_client_server_mismatch() { tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_SERVER_MISMATCH; tsi_test_do_handshake(fixture); tsi_test_fixture_destroy(fixture); @@ -494,7 +574,8 @@ void ssl_tsi_test_do_handshake_alpn_client_server_mismatch() { void ssl_tsi_test_do_handshake_alpn_client_server_ok() { tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_SERVER_OK; tsi_test_do_handshake(fixture); tsi_test_fixture_destroy(fixture); @@ -511,11 +592,12 @@ void ssl_tsi_test_do_round_trip_for_all_configs() { v <<= 1; } tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); tsi_test_frame_protector_config_destroy(ssl_fixture->base.config); ssl_fixture->base.config = tsi_test_frame_protector_config_create( bit_array[0], bit_array[1], bit_array[2], bit_array[3], bit_array[4], - bit_array[5], bit_array[6], bit_array[7]); + bit_array[5], bit_array[6]); tsi_test_do_round_trip(&ssl_fixture->base); tsi_test_fixture_destroy(fixture); } @@ -531,7 +613,8 @@ void ssl_tsi_test_do_round_trip_odd_buffer_size() { for (size_t ind4 = 0; ind4 < size; ind4++) { for (size_t ind5 = 0; ind5 < size; ind5++) { tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = (ssl_tsi_test_fixture*)fixture; + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); tsi_test_frame_protector_config_set_buffer_size( ssl_fixture->base.config, odd_sizes[ind1], odd_sizes[ind2], odd_sizes[ind3], odd_sizes[ind4], odd_sizes[ind5]); @@ -544,6 +627,38 @@ void ssl_tsi_test_do_round_trip_odd_buffer_size() { } } +void ssl_tsi_test_do_handshake_session_cache() { + tsi_ssl_session_cache* session_cache = tsi_ssl_session_cache_create_lru(16); + char session_ticket_key[kSessionTicketEncryptionKeySize]; + auto do_handshake = [&session_ticket_key, + &session_cache](bool session_reused) { + tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast<ssl_tsi_test_fixture*>(fixture); + ssl_fixture->server_name_indication = + const_cast<char*>("waterzooi.test.google.be"); + ssl_fixture->session_ticket_key = session_ticket_key; + ssl_fixture->session_ticket_key_size = sizeof(session_ticket_key); + tsi_ssl_session_cache_ref(session_cache); + ssl_fixture->session_cache = session_cache; + ssl_fixture->session_reused = session_reused; + tsi_test_do_round_trip(&ssl_fixture->base); + tsi_test_fixture_destroy(fixture); + }; + memset(session_ticket_key, 'a', sizeof(session_ticket_key)); + do_handshake(false); + do_handshake(true); + do_handshake(true); + // Changing session_ticket_key on server invalidates ticket. + memset(session_ticket_key, 'b', sizeof(session_ticket_key)); + do_handshake(false); + do_handshake(true); + memset(session_ticket_key, 'c', sizeof(session_ticket_key)); + do_handshake(false); + do_handshake(true); + tsi_ssl_session_cache_unref(session_cache); +} + static const tsi_ssl_handshaker_factory_vtable* original_vtable; static bool handshaker_factory_destructor_called; @@ -561,17 +676,18 @@ static tsi_ssl_handshaker_factory_vtable test_handshaker_factory_vtable = { void test_tsi_ssl_client_handshaker_factory_refcounting() { int i; - const char* cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "client.pem"); + char* cert_chain = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "client.pem"); + tsi_ssl_client_handshaker_options options; + memset(&options, 0, sizeof(options)); + options.pem_root_certs = cert_chain; tsi_ssl_client_handshaker_factory* client_handshaker_factory; - GPR_ASSERT(tsi_create_ssl_client_handshaker_factory( - nullptr, cert_chain, nullptr, nullptr, 0, - &client_handshaker_factory) == TSI_OK); + GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options( + &options, &client_handshaker_factory) == TSI_OK); handshaker_factory_destructor_called = false; original_vtable = tsi_ssl_handshaker_factory_swap_vtable( - (tsi_ssl_handshaker_factory*)client_handshaker_factory, + reinterpret_cast<tsi_ssl_handshaker_factory*>(client_handshaker_factory), &test_handshaker_factory_vtable); tsi_handshaker* handshaker[3]; @@ -594,7 +710,7 @@ void test_tsi_ssl_client_handshaker_factory_refcounting() { tsi_handshaker_destroy(handshaker[2]); GPR_ASSERT(handshaker_factory_destructor_called); - gpr_free((void*)cert_chain); + gpr_free(cert_chain); } void test_tsi_ssl_server_handshaker_factory_refcounting() { @@ -615,7 +731,7 @@ void test_tsi_ssl_server_handshaker_factory_refcounting() { handshaker_factory_destructor_called = false; original_vtable = tsi_ssl_handshaker_factory_swap_vtable( - (tsi_ssl_handshaker_factory*)server_handshaker_factory, + reinterpret_cast<tsi_ssl_handshaker_factory*>(server_handshaker_factory), &test_handshaker_factory_vtable); for (i = 0; i < 3; ++i) { @@ -644,9 +760,11 @@ void test_tsi_ssl_client_handshaker_factory_bad_params() { const char* cert_chain = "This is not a valid PEM file."; tsi_ssl_client_handshaker_factory* client_handshaker_factory; - GPR_ASSERT(tsi_create_ssl_client_handshaker_factory( - nullptr, cert_chain, nullptr, nullptr, 0, - &client_handshaker_factory) == TSI_INVALID_ARGUMENT); + tsi_ssl_client_handshaker_options options; + memset(&options, 0, sizeof(options)); + options.pem_root_certs = cert_chain; + GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options( + &options, &client_handshaker_factory) == TSI_INVALID_ARGUMENT); tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory); } @@ -659,18 +777,25 @@ void ssl_tsi_test_handshaker_factory_internals() { int main(int argc, char** argv) { grpc_test_init(argc, argv); grpc_init(); + ssl_tsi_test_do_handshake_tiny_handshake_buffer(); ssl_tsi_test_do_handshake_small_handshake_buffer(); ssl_tsi_test_do_handshake(); + ssl_tsi_test_do_handshake_with_root_store(); ssl_tsi_test_do_handshake_with_client_authentication(); + ssl_tsi_test_do_handshake_with_client_authentication_and_root_store(); ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain(); ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain(); ssl_tsi_test_do_handshake_with_bad_server_cert(); ssl_tsi_test_do_handshake_with_bad_client_cert(); +#ifdef OPENSSL_IS_BORINGSSL + // BoringSSL and OpenSSL have different behaviors on mismatched ALPN. ssl_tsi_test_do_handshake_alpn_client_no_server(); - ssl_tsi_test_do_handshake_alpn_server_no_client(); ssl_tsi_test_do_handshake_alpn_client_server_mismatch(); +#endif + ssl_tsi_test_do_handshake_alpn_server_no_client(); ssl_tsi_test_do_handshake_alpn_client_server_ok(); + ssl_tsi_test_do_handshake_session_cache(); ssl_tsi_test_do_round_trip_for_all_configs(); ssl_tsi_test_do_round_trip_odd_buffer_size(); ssl_tsi_test_handshaker_factory_internals(); diff --git a/test/core/tsi/transport_security_test.cc b/test/core/tsi/transport_security_test.cc index c788ad96ad..5c92912f6f 100644 --- a/test/core/tsi/transport_security_test.cc +++ b/test/core/tsi/transport_security_test.cc @@ -23,11 +23,11 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> #include <openssl/crypto.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/tsi/fake_transport_security.h" #include "src/core/tsi/ssl_transport_security.h" #include "test/core/util/test_config.h" diff --git a/test/core/tsi/transport_security_test_lib.cc b/test/core/tsi/transport_security_test_lib.cc index 3537366de9..26349dbfca 100644 --- a/test/core/tsi/transport_security_test_lib.cc +++ b/test/core/tsi/transport_security_test_lib.cc @@ -23,7 +23,7 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> + #include "src/core/lib/security/transport/tsi_error.h" #include "test/core/tsi/transport_security_test_lib.h" @@ -110,27 +110,29 @@ static void check_handshake_results(tsi_test_fixture* fixture) { fixture->vtable->check_handshaker_peers(fixture); /* Check unused bytes. */ if (fixture->test_unused_bytes) { + tsi_test_channel* channel = fixture->channel; if (fixture->server_result != nullptr && fixture->client_result != nullptr) { check_unused_bytes(fixture); } - fixture->bytes_written_to_server_channel = 0; - fixture->bytes_written_to_client_channel = 0; - fixture->bytes_read_from_client_channel = 0; - fixture->bytes_read_from_server_channel = 0; + channel->bytes_written_to_server_channel = 0; + channel->bytes_written_to_client_channel = 0; + channel->bytes_read_from_client_channel = 0; + channel->bytes_read_from_server_channel = 0; } } -static void send_bytes_to_peer(tsi_test_fixture* fixture, +static void send_bytes_to_peer(tsi_test_channel* test_channel, const unsigned char* buf, size_t buf_size, bool is_client) { - GPR_ASSERT(fixture != nullptr); + GPR_ASSERT(test_channel != nullptr); GPR_ASSERT(buf != nullptr); uint8_t* channel = - is_client ? fixture->server_channel : fixture->client_channel; + is_client ? test_channel->server_channel : test_channel->client_channel; GPR_ASSERT(channel != nullptr); - size_t* bytes_written = is_client ? &fixture->bytes_written_to_server_channel - : &fixture->bytes_written_to_client_channel; + size_t* bytes_written = is_client + ? &test_channel->bytes_written_to_server_channel + : &test_channel->bytes_written_to_client_channel; GPR_ASSERT(bytes_written != nullptr); GPR_ASSERT(*bytes_written + buf_size <= TSI_TEST_DEFAULT_CHANNEL_SIZE); /* Write data to channel. */ @@ -144,8 +146,10 @@ static void maybe_append_unused_bytes(handshaker_args* args) { tsi_test_fixture* fixture = args->fixture; if (fixture->test_unused_bytes && !args->appended_unused_bytes) { args->appended_unused_bytes = true; - send_bytes_to_peer(fixture, (const unsigned char*)TSI_TEST_UNUSED_BYTES, - strlen(TSI_TEST_UNUSED_BYTES), args->is_client); + send_bytes_to_peer( + fixture->channel, + reinterpret_cast<const unsigned char*>(TSI_TEST_UNUSED_BYTES), + strlen(TSI_TEST_UNUSED_BYTES), args->is_client); if (fixture->client_result != nullptr && fixture->server_result == nullptr) { fixture->has_client_finished_first = true; @@ -153,19 +157,21 @@ static void maybe_append_unused_bytes(handshaker_args* args) { } } -static void receive_bytes_from_peer(tsi_test_fixture* fixture, +static void receive_bytes_from_peer(tsi_test_channel* test_channel, unsigned char** buf, size_t* buf_size, bool is_client) { - GPR_ASSERT(fixture != nullptr); + GPR_ASSERT(test_channel != nullptr); GPR_ASSERT(*buf != nullptr); GPR_ASSERT(buf_size != nullptr); uint8_t* channel = - is_client ? fixture->client_channel : fixture->server_channel; + is_client ? test_channel->client_channel : test_channel->server_channel; GPR_ASSERT(channel != nullptr); - size_t* bytes_read = is_client ? &fixture->bytes_read_from_client_channel - : &fixture->bytes_read_from_server_channel; - size_t* bytes_written = is_client ? &fixture->bytes_written_to_client_channel - : &fixture->bytes_written_to_server_channel; + size_t* bytes_read = is_client + ? &test_channel->bytes_read_from_client_channel + : &test_channel->bytes_read_from_server_channel; + size_t* bytes_written = is_client + ? &test_channel->bytes_written_to_client_channel + : &test_channel->bytes_written_to_server_channel; GPR_ASSERT(bytes_read != nullptr); GPR_ASSERT(bytes_written != nullptr); size_t to_read = *buf_size < *bytes_written - *bytes_read @@ -177,14 +183,13 @@ static void receive_bytes_from_peer(tsi_test_fixture* fixture, *bytes_read += to_read; } -static void send_message_to_peer(tsi_test_fixture* fixture, - tsi_frame_protector* protector, - bool is_client) { +void tsi_test_frame_protector_send_message_to_peer( + tsi_test_frame_protector_config* config, tsi_test_channel* channel, + tsi_frame_protector* protector, bool is_client) { /* Initialization. */ - GPR_ASSERT(fixture != nullptr); - GPR_ASSERT(fixture->config != nullptr); + GPR_ASSERT(config != nullptr); + GPR_ASSERT(channel != nullptr); GPR_ASSERT(protector != nullptr); - tsi_test_frame_protector_config* config = fixture->config; unsigned char* protected_buffer = static_cast<unsigned char*>(gpr_zalloc(config->protected_buffer_size)); size_t message_size = @@ -204,7 +209,7 @@ static void send_message_to_peer(tsi_test_fixture* fixture, &protected_buffer_size_to_send); GPR_ASSERT(result == TSI_OK); /* Send protected data to peer. */ - send_bytes_to_peer(fixture, protected_buffer, protected_buffer_size_to_send, + send_bytes_to_peer(channel, protected_buffer, protected_buffer_size_to_send, is_client); message_bytes += processed_message_size; message_size -= processed_message_size; @@ -217,7 +222,7 @@ static void send_message_to_peer(tsi_test_fixture* fixture, protector, protected_buffer, &protected_buffer_size_to_send, &still_pending_size); GPR_ASSERT(result == TSI_OK); - send_bytes_to_peer(fixture, protected_buffer, + send_bytes_to_peer(channel, protected_buffer, protected_buffer_size_to_send, is_client); } while (still_pending_size > 0 && result == TSI_OK); GPR_ASSERT(result == TSI_OK); @@ -227,17 +232,16 @@ static void send_message_to_peer(tsi_test_fixture* fixture, gpr_free(protected_buffer); } -static void receive_message_from_peer(tsi_test_fixture* fixture, - tsi_frame_protector* protector, - unsigned char* message, - size_t* bytes_received, bool is_client) { +void tsi_test_frame_protector_receive_message_from_peer( + tsi_test_frame_protector_config* config, tsi_test_channel* channel, + tsi_frame_protector* protector, unsigned char* message, + size_t* bytes_received, bool is_client) { /* Initialization. */ - GPR_ASSERT(fixture != nullptr); + GPR_ASSERT(config != nullptr); + GPR_ASSERT(channel != nullptr); GPR_ASSERT(protector != nullptr); GPR_ASSERT(message != nullptr); GPR_ASSERT(bytes_received != nullptr); - GPR_ASSERT(fixture->config != nullptr); - tsi_test_frame_protector_config* config = fixture->config; size_t read_offset = 0; size_t message_offset = 0; size_t read_from_peer_size = 0; @@ -252,7 +256,7 @@ static void receive_message_from_peer(tsi_test_fixture* fixture, /* Receive data from peer. */ if (read_from_peer_size == 0) { read_from_peer_size = config->read_buffer_allocated_size; - receive_bytes_from_peer(fixture, &read_buffer, &read_from_peer_size, + receive_bytes_from_peer(channel, &read_buffer, &read_from_peer_size, is_client); read_offset = 0; } @@ -288,7 +292,7 @@ grpc_error* on_handshake_next_done(tsi_result result, void* user_data, const unsigned char* bytes_to_send, size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result) { - handshaker_args* args = (handshaker_args*)user_data; + handshaker_args* args = static_cast<handshaker_args*>(user_data); GPR_ASSERT(args != nullptr); GPR_ASSERT(args->fixture != nullptr); tsi_test_fixture* fixture = args->fixture; @@ -313,7 +317,7 @@ grpc_error* on_handshake_next_done(tsi_result result, void* user_data, } /* Send data to peer, if needed. */ if (bytes_to_send_size > 0) { - send_bytes_to_peer(args->fixture, bytes_to_send, bytes_to_send_size, + send_bytes_to_peer(fixture->channel, bytes_to_send, bytes_to_send_size, args->is_client); args->transferred_data = true; } @@ -327,7 +331,7 @@ grpc_error* on_handshake_next_done(tsi_result result, void* user_data, static void on_handshake_next_done_wrapper( tsi_result result, void* user_data, const unsigned char* bytes_to_send, size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result) { - handshaker_args* args = (handshaker_args*)user_data; + handshaker_args* args = static_cast<handshaker_args*>(user_data); args->error = on_handshake_next_done(result, user_data, bytes_to_send, bytes_to_send_size, handshaker_result); } @@ -360,8 +364,8 @@ static void do_handshaker_next(handshaker_args* args) { /* Receive data from peer, if available. */ do { size_t buf_size = args->handshake_buffer_size; - receive_bytes_from_peer(args->fixture, &args->handshake_buffer, &buf_size, - args->is_client); + receive_bytes_from_peer(fixture->channel, &args->handshake_buffer, + &buf_size, args->is_client); if (buf_size > 0) { args->transferred_data = true; } @@ -410,6 +414,50 @@ void tsi_test_do_handshake(tsi_test_fixture* fixture) { handshaker_args_destroy(server_args); } +static void tsi_test_do_ping_pong(tsi_test_frame_protector_config* config, + tsi_test_channel* channel, + tsi_frame_protector* client_frame_protector, + tsi_frame_protector* server_frame_protector) { + GPR_ASSERT(config != nullptr); + GPR_ASSERT(channel != nullptr); + GPR_ASSERT(client_frame_protector != nullptr); + GPR_ASSERT(server_frame_protector != nullptr); + /* Client sends a message to server. */ + tsi_test_frame_protector_send_message_to_peer( + config, channel, client_frame_protector, true /* is_client */); + unsigned char* server_received_message = + static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE)); + size_t server_received_message_size = 0; + tsi_test_frame_protector_receive_message_from_peer( + config, channel, server_frame_protector, server_received_message, + &server_received_message_size, false /* is_client */); + GPR_ASSERT(config->client_message_size == server_received_message_size); + GPR_ASSERT(memcmp(config->client_message, server_received_message, + server_received_message_size) == 0); + /* Server sends a message to client. */ + tsi_test_frame_protector_send_message_to_peer( + config, channel, server_frame_protector, false /* is_client */); + unsigned char* client_received_message = + static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE)); + size_t client_received_message_size = 0; + tsi_test_frame_protector_receive_message_from_peer( + config, channel, client_frame_protector, client_received_message, + &client_received_message_size, true /* is_client */); + GPR_ASSERT(config->server_message_size == client_received_message_size); + GPR_ASSERT(memcmp(config->server_message, client_received_message, + client_received_message_size) == 0); + gpr_free(server_received_message); + gpr_free(client_received_message); +} + +void tsi_test_frame_protector_do_round_trip_no_handshake( + tsi_test_frame_protector_fixture* fixture) { + GPR_ASSERT(fixture != nullptr); + tsi_test_do_ping_pong(fixture->config, fixture->channel, + fixture->client_frame_protector, + fixture->server_frame_protector); +} + void tsi_test_do_round_trip(tsi_test_fixture* fixture) { /* Initialization. */ GPR_ASSERT(fixture != nullptr); @@ -436,33 +484,11 @@ void tsi_test_do_round_trip(tsi_test_fixture* fixture) { ? nullptr : &server_max_output_protected_frame_size, &server_frame_protector) == TSI_OK); - /* Client sends a message to server. */ - send_message_to_peer(fixture, client_frame_protector, true /* is_client */); - unsigned char* server_received_message = - static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE)); - size_t server_received_message_size = 0; - receive_message_from_peer( - fixture, server_frame_protector, server_received_message, - &server_received_message_size, false /* is_client */); - GPR_ASSERT(config->client_message_size == server_received_message_size); - GPR_ASSERT(memcmp(config->client_message, server_received_message, - server_received_message_size) == 0); - /* Server sends a message to client. */ - send_message_to_peer(fixture, server_frame_protector, false /* is_client */); - unsigned char* client_received_message = - static_cast<unsigned char*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE)); - size_t client_received_message_size = 0; - receive_message_from_peer( - fixture, client_frame_protector, client_received_message, - &client_received_message_size, true /* is_client */); - GPR_ASSERT(config->server_message_size == client_received_message_size); - GPR_ASSERT(memcmp(config->server_message, client_received_message, - client_received_message_size) == 0); + tsi_test_do_ping_pong(config, fixture->channel, client_frame_protector, + server_frame_protector); /* Destroy server and client frame protectors. */ tsi_frame_protector_destroy(client_frame_protector); tsi_frame_protector_destroy(server_frame_protector); - gpr_free(server_received_message); - gpr_free(client_received_message); } static unsigned char* generate_random_message(size_t size) { @@ -471,7 +497,7 @@ static unsigned char* generate_random_message(size_t size) { unsigned char* output = static_cast<unsigned char*>(gpr_zalloc(sizeof(unsigned char) * size)); for (i = 0; i < size - 1; ++i) { - output[i] = chars[rand() % (int)(sizeof(chars) - 1)]; + output[i] = chars[rand() % static_cast<int>(sizeof(chars) - 1)]; } return output; } @@ -482,8 +508,7 @@ tsi_test_frame_protector_config* tsi_test_frame_protector_config_create( bool use_default_protected_buffer_size, bool use_default_client_message, bool use_default_server_message, bool use_default_client_max_output_protected_frame_size, - bool use_default_server_max_output_protected_frame_size, - bool use_default_handshake_buffer_size) { + bool use_default_server_max_output_protected_frame_size) { tsi_test_frame_protector_config* config = static_cast<tsi_test_frame_protector_config*>( gpr_zalloc(sizeof(*config))); @@ -551,24 +576,42 @@ void tsi_test_frame_protector_config_set_buffer_size( void tsi_test_frame_protector_config_destroy( tsi_test_frame_protector_config* config) { - GPR_ASSERT(config != nullptr); + if (config == nullptr) { + return; + } gpr_free(config->client_message); gpr_free(config->server_message); gpr_free(config); } +static tsi_test_channel* tsi_test_channel_create() { + tsi_test_channel* channel = + static_cast<tsi_test_channel*>(gpr_zalloc(sizeof(*channel))); + channel->client_channel = + static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE)); + channel->server_channel = + static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE)); + channel->bytes_written_to_client_channel = 0; + channel->bytes_written_to_server_channel = 0; + channel->bytes_read_from_client_channel = 0; + channel->bytes_read_from_server_channel = 0; + return channel; +} + +static void tsi_test_channel_destroy(tsi_test_channel* channel) { + if (channel == nullptr) { + return; + } + gpr_free(channel->client_channel); + gpr_free(channel->server_channel); + gpr_free(channel); +} + void tsi_test_fixture_init(tsi_test_fixture* fixture) { fixture->config = tsi_test_frame_protector_config_create( - true, true, true, true, true, true, true, true); + true, true, true, true, true, true, true); fixture->handshake_buffer_size = TSI_TEST_DEFAULT_BUFFER_SIZE; - fixture->client_channel = - static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE)); - fixture->server_channel = - static_cast<uint8_t*>(gpr_zalloc(TSI_TEST_DEFAULT_CHANNEL_SIZE)); - fixture->bytes_written_to_client_channel = 0; - fixture->bytes_written_to_server_channel = 0; - fixture->bytes_read_from_client_channel = 0; - fixture->bytes_read_from_server_channel = 0; + fixture->channel = tsi_test_channel_create(); fixture->test_unused_bytes = true; fixture->has_client_finished_first = false; gpr_mu_init(&fixture->mu); @@ -577,14 +620,15 @@ void tsi_test_fixture_init(tsi_test_fixture* fixture) { } void tsi_test_fixture_destroy(tsi_test_fixture* fixture) { - GPR_ASSERT(fixture != nullptr); + if (fixture == nullptr) { + return; + } tsi_test_frame_protector_config_destroy(fixture->config); tsi_handshaker_destroy(fixture->client_handshaker); tsi_handshaker_destroy(fixture->server_handshaker); tsi_handshaker_result_destroy(fixture->client_result); tsi_handshaker_result_destroy(fixture->server_result); - gpr_free(fixture->client_channel); - gpr_free(fixture->server_channel); + tsi_test_channel_destroy(fixture->channel); GPR_ASSERT(fixture->vtable != nullptr); GPR_ASSERT(fixture->vtable->destruct != nullptr); fixture->vtable->destruct(fixture); @@ -592,3 +636,34 @@ void tsi_test_fixture_destroy(tsi_test_fixture* fixture) { gpr_cv_destroy(&fixture->cv); gpr_free(fixture); } + +tsi_test_frame_protector_fixture* tsi_test_frame_protector_fixture_create() { + tsi_test_frame_protector_fixture* fixture = + static_cast<tsi_test_frame_protector_fixture*>( + gpr_zalloc(sizeof(*fixture))); + fixture->config = tsi_test_frame_protector_config_create( + true, true, true, true, true, true, true); + fixture->channel = tsi_test_channel_create(); + return fixture; +} + +void tsi_test_frame_protector_fixture_init( + tsi_test_frame_protector_fixture* fixture, + tsi_frame_protector* client_frame_protector, + tsi_frame_protector* server_frame_protector) { + GPR_ASSERT(fixture != nullptr); + fixture->client_frame_protector = client_frame_protector; + fixture->server_frame_protector = server_frame_protector; +} + +void tsi_test_frame_protector_fixture_destroy( + tsi_test_frame_protector_fixture* fixture) { + if (fixture == nullptr) { + return; + } + tsi_test_frame_protector_config_destroy(fixture->config); + tsi_test_channel_destroy(fixture->channel); + tsi_frame_protector_destroy(fixture->client_frame_protector); + tsi_frame_protector_destroy(fixture->server_frame_protector); + gpr_free(fixture); +} diff --git a/test/core/tsi/transport_security_test_lib.h b/test/core/tsi/transport_security_test_lib.h index 9b07448cc5..b6a431f5a0 100644 --- a/test/core/tsi/transport_security_test_lib.h +++ b/test/core/tsi/transport_security_test_lib.h @@ -35,8 +35,8 @@ #define TSI_TEST_DEFAULT_CHANNEL_SIZE 32768 #define TSI_TEST_BIG_MESSAGE_SIZE 17000 #define TSI_TEST_SMALL_MESSAGE_SIZE 10 -#define TSI_TEST_NUM_OF_ARGUMENTS 8 -#define TSI_TEST_NUM_OF_COMBINATIONS 256 +#define TSI_TEST_NUM_OF_ARGUMENTS 7 +#define TSI_TEST_NUM_OF_COMBINATIONS 128 #define TSI_TEST_UNUSED_BYTES "HELLO GOOGLE" /* --- tsi_test_fixture object --- @@ -46,12 +46,22 @@ protect/unprotect operations with respect to TSI implementations. */ typedef struct tsi_test_fixture tsi_test_fixture; -/* --- tsi_test_frame_protector_config object --- +/* --- tsi_test_frame_protector_fixture object --- + The object wraps all necessary information used to test correctness of TSI + frame protector implementations. */ +typedef struct tsi_test_frame_protector_fixture + tsi_test_frame_protector_fixture; +/* --- tsi_test_frame_protector_config object --- This object is used to configure different parameters of TSI frame protector APIs. */ typedef struct tsi_test_frame_protector_config tsi_test_frame_protector_config; +/* --- tsi_test_channel object --- + This object represents simulated channels between the client and server + from/to which they could read/write the exchanged information. */ +typedef struct tsi_test_channel tsi_test_channel; + /* V-table for tsi_test_fixture operations that are implemented differently in different TSI implementations. */ typedef struct tsi_test_fixture_vtable { @@ -73,17 +83,8 @@ struct tsi_test_fixture { tsi_handshaker_result* server_result; /* size of buffer used to store data received from the peer. */ size_t handshake_buffer_size; - /* simulated channels between client and server. If the server (client) - wants to send data to the client (server), he will write data to - client_channel (server_channel), which will be read by client (server). */ - uint8_t* client_channel; - uint8_t* server_channel; - /* size of data written to the client/server channel. */ - size_t bytes_written_to_client_channel; - size_t bytes_written_to_server_channel; - /* size of data read from the client/server channel */ - size_t bytes_read_from_client_channel; - size_t bytes_read_from_server_channel; + /* tsi_test_channel instance. */ + tsi_test_channel* channel; /* tsi_test_frame_protector_config instance */ tsi_test_frame_protector_config* config; /* a flag indicating if client has finished TSI handshake first (i.e., before @@ -106,6 +107,30 @@ struct tsi_test_fixture { bool notified; }; +struct tsi_test_frame_protector_fixture { + /* client/server TSI frame protectors whose ownership are transferred. */ + tsi_frame_protector* client_frame_protector; + tsi_frame_protector* server_frame_protector; + /* tsi_test_channel instance. */ + tsi_test_channel* channel; + /* tsi_test_frame_protector_config instance */ + tsi_test_frame_protector_config* config; +}; + +struct tsi_test_channel { + /* simulated channels between client and server. If the server (client) + wants to send data to the client (server), he will write data to + client_channel (server_channel), which will be read by client (server). */ + uint8_t* client_channel; + uint8_t* server_channel; + /* size of data written to the client/server channel. */ + size_t bytes_written_to_client_channel; + size_t bytes_written_to_server_channel; + /* size of data read from the client/server channel */ + size_t bytes_read_from_client_channel; + size_t bytes_read_from_server_channel; +}; + struct tsi_test_frame_protector_config { /* size of buffer used to store protected frames to be unprotected. */ size_t read_buffer_allocated_size; @@ -135,8 +160,7 @@ tsi_test_frame_protector_config* tsi_test_frame_protector_config_create( bool use_default_protected_buffer_size, bool use_default_client_message, bool use_default_server_message, bool use_default_client_max_output_protected_frame_size, - bool use_default_server_max_output_protected_frame_size, - bool use_default_handshake_buffer_size); + bool use_default_server_max_output_protected_frame_size); /* This method sets different buffer and frame sizes of a tsi_test_frame_protector_config instance with user provided values. */ @@ -160,6 +184,35 @@ void tsi_test_fixture_init(tsi_test_fixture* fixture); this function. */ void tsi_test_fixture_destroy(tsi_test_fixture* fixture); +/* This method creates a tsi_test_frame_protector_fixture instance. */ +tsi_test_frame_protector_fixture* tsi_test_frame_protector_fixture_create(); + +/* This method initializes members of tsi_test_frame_protector_fixture instance. + Note that the struct instance should be allocated before making + this call. */ +void tsi_test_frame_protector_fixture_init( + tsi_test_frame_protector_fixture* fixture, + tsi_frame_protector* client_frame_protector, + tsi_frame_protector* server_frame_protector); + +/* This method destroys a tsi_test_frame_protector_fixture instance. Note that + the fixture intance must be dynamically allocated and will be freed by this + function. */ +void tsi_test_frame_protector_fixture_destroy( + tsi_test_frame_protector_fixture* fixture); + +/* This method performs a protect opeation on raw data and sends the result to + peer. */ +void tsi_test_frame_protector_send_message_to_peer( + tsi_test_frame_protector_config* config, tsi_test_channel* channel, + tsi_frame_protector* protector, bool is_client); + +/* This method receives message from peer and unprotects it. */ +void tsi_test_frame_protector_receive_message_from_peer( + tsi_test_frame_protector_config* config, tsi_test_channel* channel, + tsi_frame_protector* protector, unsigned char* message, + size_t* bytes_received, bool is_client); + /* This method performs a full TSI handshake between a client and a server. Note that the test library will implement the new TSI handshaker API to perform handshakes. */ @@ -171,4 +224,8 @@ void tsi_test_do_handshake(tsi_test_fixture* fixture); the client and server switching its role. */ void tsi_test_do_round_trip(tsi_test_fixture* fixture); +/* This method performs the above round trip test without doing handshakes. */ +void tsi_test_frame_protector_do_round_trip_no_handshake( + tsi_test_frame_protector_fixture* fixture); + #endif // GRPC_TEST_CORE_TSI_TRANSPORT_SECURITY_TEST_LIB_H_ diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 2237cfc173..f52570cde5 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -51,6 +51,8 @@ grpc_cc_library( grpc_cc_library( name = "grpc_test_util_base", srcs = [ + "cmdline.cc", + "fuzzer_util.cc", "grpc_profiler.cc", "histogram.cc", "mock_endpoint.cc", @@ -61,11 +63,15 @@ grpc_cc_library( "port_server_client.cc", "reconnect_server.cc", "slice_splitter.cc", + "subprocess_posix.cc", + "subprocess_windows.cc", "test_tcp_server.cc", "tracer_util.cc", "trickle_endpoint.cc", ], hdrs = [ + "cmdline.h", + "fuzzer_util.h", "grpc_profiler.h", "histogram.h", "mock_endpoint.h", @@ -74,6 +80,7 @@ grpc_cc_library( "port.h", "port_server_client.h", "reconnect_server.h", + "subprocess.h", "slice_splitter.h", "test_tcp_server.h", "tracer_util.h", @@ -109,6 +116,16 @@ grpc_cc_library( ], ) +grpc_cc_test( + name = "cmdline_test", + srcs = ["cmdline_test.cc"], + language = "C++", + deps = [ + ":grpc_test_util", + "//:gpr", + ], +) + grpc_cc_library( name = "fuzzer_corpus_test", testonly = 1, diff --git a/test/core/util/cmdline.cc b/test/core/util/cmdline.cc new file mode 100644 index 0000000000..e76acb5e2b --- /dev/null +++ b/test/core/util/cmdline.cc @@ -0,0 +1,331 @@ +/* + * + * 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 <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include "src/core/lib/gpr/string.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* arg); + +gpr_cmdline* gpr_cmdline_create(const char* description) { + gpr_cmdline* cl = static_cast<gpr_cmdline*>(gpr_zalloc(sizeof(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(gpr_strvec* s, arg* a) { + char* tmp; + + if (!a) return; + add_args_to_usage(s, a->next); + + switch (a->type) { + case ARGTYPE_BOOL: + gpr_asprintf(&tmp, " [--%s|--no-%s]", a->name, a->name); + gpr_strvec_add(s, tmp); + break; + case ARGTYPE_STRING: + gpr_asprintf(&tmp, " [--%s=string]", a->name); + gpr_strvec_add(s, tmp); + break; + case ARGTYPE_INT: + gpr_asprintf(&tmp, " [--%s=int]", a->name); + gpr_strvec_add(s, tmp); + break; + } +} + +char* gpr_cmdline_usage_string(gpr_cmdline* cl, const char* argv0) { + /* TODO(ctiller): make this prettier */ + gpr_strvec s; + char* tmp; + const char* name = strrchr(argv0, '/'); + + if (name) { + name++; + } else { + name = argv0; + } + + gpr_strvec_init(&s); + + gpr_asprintf(&tmp, "Usage: %s", name); + gpr_strvec_add(&s, tmp); + add_args_to_usage(&s, cl->args); + if (cl->extra_arg) { + gpr_asprintf(&tmp, " [%s...]", cl->extra_arg_name); + gpr_strvec_add(&s, tmp); + } + gpr_strvec_add(&s, gpr_strdup("\n")); + + tmp = gpr_strvec_flatten(&s, nullptr); + gpr_strvec_destroy(&s); + return tmp; +} + +static int print_usage_and_die(gpr_cmdline* cl) { + char* usage = gpr_cmdline_usage_string(cl, cl->argv0); + fprintf(stderr, "%s", usage); + gpr_free(usage); + 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/test/core/util/cmdline.h b/test/core/util/cmdline.h new file mode 100644 index 0000000000..3ae35d6e6a --- /dev/null +++ b/test/core/util/cmdline.h @@ -0,0 +1,80 @@ +/* + * + * 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> + +/** 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 */ +char* gpr_cmdline_usage_string(gpr_cmdline* cl, const char* argv0); + +#endif /* GRPC_TEST_CORE_UTIL_CMDLINE_H */ diff --git a/test/core/support/cmdline_test.cc b/test/core/util/cmdline_test.cc index 172efda8a0..9f5ad88d57 100644 --- a/test/core/support/cmdline_test.cc +++ b/test/core/util/cmdline_test.cc @@ -16,13 +16,13 @@ * */ -#include <grpc/support/cmdline.h> - #include <string.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" +#include "test/core/util/cmdline.h" #include "test/core/util/test_config.h" #define LOG_TEST() gpr_log(GPR_INFO, "test at %s:%d", __FILE__, __LINE__) diff --git a/test/core/util/debugger_macros.cc b/test/core/util/debugger_macros.cc index f1e4ffd3af..05fb146173 100644 --- a/test/core/util/debugger_macros.cc +++ b/test/core/util/debugger_macros.cc @@ -39,6 +39,7 @@ grpc_stream* grpc_transport_stream_from_call(grpc_call* call) { grpc_subchannel_call* scc = grpc_client_channel_get_subchannel_call(el); if (scc == nullptr) { fprintf(stderr, "No subchannel-call"); + fflush(stderr); return nullptr; } cs = grpc_subchannel_call_get_call_stack(scc); @@ -46,11 +47,13 @@ grpc_stream* grpc_transport_stream_from_call(grpc_call* call) { return grpc_connected_channel_get_stream(el); } else { fprintf(stderr, "Unrecognized filter: %s", el->filter->name); + fflush(stderr); return nullptr; } } } grpc_chttp2_stream* grpc_chttp2_stream_from_call(grpc_call* call) { - return (grpc_chttp2_stream*)grpc_transport_stream_from_call(call); + return reinterpret_cast<grpc_chttp2_stream*>( + grpc_transport_stream_from_call(call)); } diff --git a/test/core/util/fuzzer_corpus_test.cc b/test/core/util/fuzzer_corpus_test.cc index 7849321257..ebf1913137 100644 --- a/test/core/util/fuzzer_corpus_test.cc +++ b/test/core/util/fuzzer_corpus_test.cc @@ -20,11 +20,13 @@ #include <dirent.h> #include <gflags/gflags.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <gtest/gtest.h> #include <stdio.h> #include <sys/types.h> +#include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/load_file.h" #include "test/core/util/test_config.h" @@ -68,6 +70,12 @@ class ExampleGenerator if (examples_.empty()) { if (!FLAGS_file.empty()) examples_.push_back(FLAGS_file); if (!FLAGS_directory.empty()) { + char* test_srcdir = gpr_getenv("TEST_SRCDIR"); + if (test_srcdir != nullptr) { + FLAGS_directory = test_srcdir + + std::string("/com_github_grpc_grpc/") + + FLAGS_directory; + } DIR* dp; struct dirent* ep; dp = opendir(FLAGS_directory.c_str()); @@ -84,6 +92,7 @@ class ExampleGenerator perror("Couldn't open the directory"); abort(); } + gpr_free(test_srcdir); } } } diff --git a/test/core/util/fuzzer_one_entry_runner.sh b/test/core/util/fuzzer_one_entry_runner.sh index 2634a1b3a9..7c471afcc2 100755 --- a/test/core/util/fuzzer_one_entry_runner.sh +++ b/test/core/util/fuzzer_one_entry_runner.sh @@ -15,4 +15,4 @@ # 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 +"$1" "$2" diff --git a/test/core/util/fuzzer_util.cc b/test/core/util/fuzzer_util.cc new file mode 100644 index 0000000000..29c9b8875f --- /dev/null +++ b/test/core/util/fuzzer_util.cc @@ -0,0 +1,82 @@ +/* + * + * 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 <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 = GPR_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/test/core/util/fuzzer_util.h b/test/core/util/fuzzer_util.h new file mode 100644 index 0000000000..0e938399a1 --- /dev/null +++ b/test/core/util/fuzzer_util.h @@ -0,0 +1,49 @@ +/* + * + * 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/test/core/util/grpc_fuzzer.bzl b/test/core/util/grpc_fuzzer.bzl index b8b270ecd0..a6a60b0311 100644 --- a/test/core/util/grpc_fuzzer.bzl +++ b/test/core/util/grpc_fuzzer.bzl @@ -14,7 +14,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_test") -def grpc_fuzzer(name, corpus, srcs = [], deps = [], **kwargs): +def grpc_fuzzer(name, corpus, srcs = [], deps = [], size = "large", timeout = "long", **kwargs): grpc_cc_test( name = name, srcs = srcs, @@ -23,5 +23,8 @@ def grpc_fuzzer(name, corpus, srcs = [], deps = [], **kwargs): external_deps = [ 'gtest', ], + size = size, + timeout = timeout, + args = ["--directory=" + native.package_name() + "/" + corpus,], **kwargs ) diff --git a/test/core/util/histogram.cc b/test/core/util/histogram.cc index 2f916f831d..f028ac404e 100644 --- a/test/core/util/histogram.cc +++ b/test/core/util/histogram.cc @@ -16,6 +16,8 @@ * */ +#include "test/core/util/histogram.h" + #include <math.h> #include <stddef.h> #include <string.h> @@ -23,9 +25,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/port_platform.h> -#include <grpc/support/useful.h> -#include "test/core/util/histogram.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 @@ -56,7 +57,7 @@ struct grpc_histogram { /* determine a bucket index given a value - does no bounds checking */ static size_t bucket_for_unchecked(grpc_histogram* h, double x) { - return (size_t)(log(x) * h->one_on_log_multiplier); + return static_cast<size_t>(log(x) * h->one_on_log_multiplier); } /* bounds checked version of the above */ @@ -73,7 +74,8 @@ static double bucket_start(grpc_histogram* h, double x) { grpc_histogram* grpc_histogram_create(double resolution, double max_bucket_start) { - grpc_histogram* h = (grpc_histogram*)gpr_malloc(sizeof(grpc_histogram)); + 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; @@ -87,7 +89,8 @@ grpc_histogram* grpc_histogram_create(double resolution, 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 = (uint32_t*)gpr_zalloc(sizeof(uint32_t) * h->num_buckets); + h->buckets = + static_cast<uint32_t*>(gpr_zalloc(sizeof(uint32_t) * h->num_buckets)); return h; } @@ -175,14 +178,14 @@ static double threshold_for_count_below(grpc_histogram* h, double count_below) { break; } } - return (bucket_start(h, (double)lower_idx) + - bucket_start(h, (double)upper_idx)) / + 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, (double)lower_idx); - upper_bound = bucket_start(h, (double)(lower_idx + 1)); + lower_bound = bucket_start(h, static_cast<double>(lower_idx)); + upper_bound = bucket_start(h, static_cast<double>(lower_idx + 1)); return GPR_CLAMP(upper_bound - (upper_bound - lower_bound) * (count_so_far - count_below) / h->buckets[lower_idx], diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 32d7b89c9a..4960fe0757 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -48,13 +48,13 @@ static void* guard_malloc(size_t 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); - ptr = (size_t*)g_old_allocs.malloc_fn(size + sizeof(size)); + ptr = static_cast<size_t*>(g_old_allocs.malloc_fn(size + sizeof(size))); *ptr++ = size; return ptr; } static void* guard_realloc(void* vptr, size_t size) { - size_t* ptr = (size_t*)vptr; + size_t* ptr = static_cast<size_t*>(vptr); if (vptr == nullptr) { return guard_malloc(size); } @@ -67,13 +67,13 @@ static void* guard_realloc(void* vptr, size_t size) { NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); 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); - ptr = (size_t*)g_old_allocs.realloc_fn(ptr, size + sizeof(size)); + ptr = static_cast<size_t*>(g_old_allocs.realloc_fn(ptr, size + sizeof(size))); *ptr++ = size; return ptr; } static void guard_free(void* vptr) { - size_t* ptr = (size_t*)vptr; + size_t* ptr = static_cast<size_t*>(vptr); if (!vptr) return; --ptr; NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index 4b35a581b1..1156cd5fc5 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -30,7 +30,7 @@ #include <grpc/support/string_util.h> #include "src/core/lib/iomgr/sockaddr.h" -typedef struct grpc_mock_endpoint { +typedef struct mock_endpoint { grpc_endpoint base; gpr_mu mu; void (*on_write)(grpc_slice slice); @@ -38,11 +38,11 @@ typedef struct grpc_mock_endpoint { grpc_slice_buffer* on_read_out; grpc_closure* on_read; grpc_resource_user* resource_user; -} grpc_mock_endpoint; +} mock_endpoint; static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb) { - grpc_mock_endpoint* m = (grpc_mock_endpoint*)ep; + 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); @@ -56,7 +56,7 @@ static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb) { - grpc_mock_endpoint* m = (grpc_mock_endpoint*)ep; + mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); for (size_t i = 0; i < slices->count; i++) { m->on_write(slices->slices[i]); } @@ -72,7 +72,7 @@ static void me_delete_from_pollset_set(grpc_endpoint* ep, grpc_pollset_set* pollset) {} static void me_shutdown(grpc_endpoint* ep, grpc_error* why) { - grpc_mock_endpoint* m = (grpc_mock_endpoint*)ep; + mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); gpr_mu_lock(&m->mu); if (m->on_read) { GRPC_CLOSURE_SCHED(m->on_read, @@ -86,7 +86,7 @@ static void me_shutdown(grpc_endpoint* ep, grpc_error* why) { } static void me_destroy(grpc_endpoint* ep) { - grpc_mock_endpoint* m = (grpc_mock_endpoint*)ep; + mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); grpc_slice_buffer_destroy(&m->read_buffer); grpc_resource_user_unref(m->resource_user); gpr_free(m); @@ -97,7 +97,7 @@ static char* me_get_peer(grpc_endpoint* ep) { } static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) { - grpc_mock_endpoint* m = (grpc_mock_endpoint*)ep; + mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep); return m->resource_user; } @@ -118,7 +118,7 @@ static const grpc_endpoint_vtable vtable = { grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice), grpc_resource_quota* resource_quota) { - grpc_mock_endpoint* m = (grpc_mock_endpoint*)gpr_malloc(sizeof(*m)); + mock_endpoint* m = static_cast<mock_endpoint*>(gpr_malloc(sizeof(*m))); m->base.vtable = &vtable; char* name; gpr_asprintf(&name, "mock_endpoint_%" PRIxPTR, (intptr_t)m); @@ -132,7 +132,7 @@ grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice), } void grpc_mock_endpoint_put_read(grpc_endpoint* ep, grpc_slice slice) { - grpc_mock_endpoint* m = (grpc_mock_endpoint*)ep; + 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); diff --git a/test/core/util/parse_hexstring.cc b/test/core/util/parse_hexstring.cc index 622642a298..cd64843bd3 100644 --- a/test/core/util/parse_hexstring.cc +++ b/test/core/util/parse_hexstring.cc @@ -39,10 +39,11 @@ grpc_slice parse_hexstring(const char* hexstring) { temp = 0; for (p = hexstring; *p; p++) { if (*p >= '0' && *p <= '9') { - temp = (uint8_t)(temp << 4) | (uint8_t)(*p - '0'); + temp = static_cast<uint8_t>(temp << 4) | static_cast<uint8_t>(*p - '0'); nibbles++; } else if (*p >= 'a' && *p <= 'f') { - temp = (uint8_t)(temp << 4) | (uint8_t)(*p - 'a' + 10); + temp = + static_cast<uint8_t>(temp << 4) | static_cast<uint8_t>(*p - 'a' + 10); nibbles++; } if (nibbles == 2) { diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 5f127cb960..5958216747 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -48,8 +48,6 @@ struct passthru_endpoint { gpr_mu mu; int halves; grpc_passthru_endpoint_stats* stats; - grpc_passthru_endpoint_stats - dummy_stats; // used if constructor stats == nullptr bool shutdown; half client; half server; @@ -57,7 +55,7 @@ struct passthru_endpoint { static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb) { - half* m = (half*)ep; + half* m = reinterpret_cast<half*>(ep); gpr_mu_lock(&m->parent->mu); if (m->parent->shutdown) { GRPC_CLOSURE_SCHED( @@ -79,7 +77,7 @@ static half* other_half(half* h) { static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb) { - half* m = other_half((half*)ep); + half* m = other_half(reinterpret_cast<half*>(ep)); gpr_mu_lock(&m->parent->mu); grpc_error* error = GRPC_ERROR_NONE; gpr_atm_no_barrier_fetch_add(&m->parent->stats->num_writes, (gpr_atm)1); @@ -110,7 +108,7 @@ static void me_delete_from_pollset_set(grpc_endpoint* ep, grpc_pollset_set* pollset) {} static void me_shutdown(grpc_endpoint* ep, grpc_error* why) { - half* m = (half*)ep; + half* m = reinterpret_cast<half*>(ep); gpr_mu_lock(&m->parent->mu); m->parent->shutdown = true; if (m->on_read) { @@ -132,11 +130,12 @@ static void me_shutdown(grpc_endpoint* ep, grpc_error* why) { } static void me_destroy(grpc_endpoint* ep) { - passthru_endpoint* p = ((half*)ep)->parent; + passthru_endpoint* p = (reinterpret_cast<half*>(ep))->parent; gpr_mu_lock(&p->mu); if (0 == --p->halves) { gpr_mu_unlock(&p->mu); gpr_mu_destroy(&p->mu); + grpc_passthru_endpoint_stats_destroy(p->stats); grpc_slice_buffer_destroy_internal(&p->client.read_buffer); grpc_slice_buffer_destroy_internal(&p->server.read_buffer); grpc_resource_user_unref(p->client.resource_user); @@ -148,15 +147,16 @@ static void me_destroy(grpc_endpoint* ep) { } static char* me_get_peer(grpc_endpoint* ep) { - passthru_endpoint* p = ((half*)ep)->parent; - return ((half*)ep) == &p->client ? gpr_strdup("fake:mock_client_endpoint") - : gpr_strdup("fake:mock_server_endpoint"); + passthru_endpoint* p = (reinterpret_cast<half*>(ep))->parent; + return (reinterpret_cast<half*>(ep)) == &p->client + ? gpr_strdup("fake:mock_client_endpoint") + : gpr_strdup("fake:mock_server_endpoint"); } static int me_get_fd(grpc_endpoint* ep) { return -1; } static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) { - half* m = (half*)ep; + half* m = reinterpret_cast<half*>(ep); return m->resource_user; } @@ -191,14 +191,34 @@ void grpc_passthru_endpoint_create(grpc_endpoint** client, grpc_endpoint** server, grpc_resource_quota* resource_quota, grpc_passthru_endpoint_stats* stats) { - passthru_endpoint* m = (passthru_endpoint*)gpr_malloc(sizeof(*m)); + passthru_endpoint* m = + static_cast<passthru_endpoint*>(gpr_malloc(sizeof(*m))); m->halves = 2; m->shutdown = 0; - m->stats = stats == nullptr ? &m->dummy_stats : stats; - memset(m->stats, 0, sizeof(*m->stats)); + if (stats == nullptr) { + m->stats = grpc_passthru_endpoint_stats_create(); + } else { + gpr_ref(&stats->refs); + m->stats = stats; + } half_init(&m->client, m, resource_quota, "client"); half_init(&m->server, m, resource_quota, "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); + } +} diff --git a/test/core/util/passthru_endpoint.h b/test/core/util/passthru_endpoint.h index bddd8ea6a2..a46c775505 100644 --- a/test/core/util/passthru_endpoint.h +++ b/test/core/util/passthru_endpoint.h @@ -23,7 +23,11 @@ #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; @@ -32,4 +36,8 @@ void grpc_passthru_endpoint_create(grpc_endpoint** client, grpc_resource_quota* resource_quota, grpc_passthru_endpoint_stats* stats); +grpc_passthru_endpoint_stats* grpc_passthru_endpoint_stats_create(); + +void grpc_passthru_endpoint_stats_destroy(grpc_passthru_endpoint_stats* stats); + #endif diff --git a/test/core/util/port.cc b/test/core/util/port.cc index 9d02b673ed..303306de45 100644 --- a/test/core/util/port.cc +++ b/test/core/util/port.cc @@ -75,8 +75,8 @@ static void chose_port(int port) { atexit(free_chosen_ports); } num_chosen_ports++; - chosen_ports = - (int*)gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports); + chosen_ports = static_cast<int*>( + gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports)); chosen_ports[num_chosen_ports - 1] = port; } diff --git a/test/core/util/port_isolated_runtime_environment.cc b/test/core/util/port_isolated_runtime_environment.cc index 5f0585e9fb..ff8342ff4a 100644 --- a/test/core/util/port_isolated_runtime_environment.cc +++ b/test/core/util/port_isolated_runtime_environment.cc @@ -19,19 +19,28 @@ /* When running tests on remote machines, the framework takes a round-robin pick * of a port within certain range. There is no need to recycle ports. */ +#include <grpc/support/time.h> +#include <stdlib.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 LOWER_PORT 49152 -static int s_allocated_port = LOWER_PORT; +#define MIN_PORT 49152 +#define MAX_PORT 65536 + +int get_random_starting_port() { + srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); + return rand() % (MAX_PORT - MIN_PORT + 1) + MIN_PORT; +} + +static int s_allocated_port = get_random_starting_port(); int grpc_pick_unused_port_or_die(void) { int allocated_port = s_allocated_port++; - if (s_allocated_port == 65536) { - s_allocated_port = LOWER_PORT; + if (s_allocated_port == MAX_PORT) { + s_allocated_port = MIN_PORT; } return allocated_port; diff --git a/test/core/util/port_server_client.cc b/test/core/util/port_server_client.cc index 7e76c8063f..9a4159944b 100644 --- a/test/core/util/port_server_client.cc +++ b/test/core/util/port_server_client.cc @@ -41,13 +41,14 @@ typedef struct freereq { } freereq; static void destroy_pops_and_shutdown(void* p, grpc_error* error) { - grpc_pollset* pollset = grpc_polling_entity_pollset((grpc_polling_entity*)p); + grpc_pollset* pollset = + grpc_polling_entity_pollset(static_cast<grpc_polling_entity*>(p)); grpc_pollset_destroy(pollset); gpr_free(pollset); } static void freed_port_from_server(void* arg, grpc_error* error) { - freereq* pr = (freereq*)arg; + freereq* pr = static_cast<freereq*>(arg); gpr_mu_lock(pr->mu); pr->done = 1; GRPC_LOG_IF_ERROR( @@ -71,7 +72,8 @@ void grpc_free_port_using_server(int port) { memset(&req, 0, sizeof(req)); memset(&rsp, 0, sizeof(rsp)); - grpc_pollset* pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); + grpc_pollset* pollset = + static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(pollset, &pr.mu); pr.pops = grpc_polling_entity_create_from_pollset(pollset); shutdown_closure = GRPC_CLOSURE_CREATE(destroy_pops_and_shutdown, &pr.pops, @@ -127,7 +129,7 @@ typedef struct portreq { static void got_port_from_server(void* arg, grpc_error* error) { size_t i; int port = 0; - portreq* pr = (portreq*)arg; + portreq* pr = static_cast<portreq*>(arg); int failed = 0; grpc_httpcli_response* response = &pr->response; @@ -158,7 +160,8 @@ static void got_port_from_server(void* arg, grpc_error* error) { gpr_sleep_until(gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis( - (int64_t)(1000.0 * (1 + pow(1.3, pr->retries) * rand() / RAND_MAX)), + static_cast<int64_t>( + 1000.0 * (1 + pow(1.3, pr->retries) * rand() / RAND_MAX)), GPR_TIMESPAN))); pr->retries++; req.host = pr->server; @@ -201,7 +204,8 @@ int grpc_pick_port_using_server(void) { grpc_core::ExecCtx exec_ctx; memset(&pr, 0, sizeof(pr)); memset(&req, 0, sizeof(req)); - grpc_pollset* pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); + grpc_pollset* pollset = + static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(pollset, &pr.mu); pr.pops = grpc_polling_entity_create_from_pollset(pollset); shutdown_closure = GRPC_CLOSURE_CREATE(destroy_pops_and_shutdown, &pr.pops, diff --git a/test/core/util/reconnect_server.cc b/test/core/util/reconnect_server.cc index bcafc4e898..ad7cf42f71 100644 --- a/test/core/util/reconnect_server.cc +++ b/test/core/util/reconnect_server.cc @@ -20,11 +20,12 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> #include <grpc/support/time.h> #include <string.h> + +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/tcp_server.h" @@ -61,7 +62,7 @@ static void on_connect(void* arg, grpc_endpoint* tcp, gpr_free(acceptor); char* peer; char* last_colon; - reconnect_server* server = (reconnect_server*)arg; + 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); @@ -75,8 +76,8 @@ static void on_connect(void* arg, grpc_endpoint* tcp, } else { if (last_colon == nullptr) { gpr_log(GPR_ERROR, "peer does not contain a ':'"); - } else if (strncmp(server->peer, peer, (size_t)(last_colon - peer)) != - 0) { + } else if (strncmp(server->peer, peer, + static_cast<size_t>(last_colon - peer)) != 0) { gpr_log(GPR_ERROR, "mismatched peer! %s vs %s", server->peer, peer); } gpr_free(peer); diff --git a/test/core/util/run_with_poller.sh b/test/core/util/run_with_poller.sh index 05791457a2..382a63e8ae 100755 --- a/test/core/util/run_with_poller.sh +++ b/test/core/util/run_with_poller.sh @@ -16,4 +16,4 @@ set -ex export GRPC_POLL_STRATEGY=$1 shift -$@ +"$@" diff --git a/test/core/util/slice_splitter.cc b/test/core/util/slice_splitter.cc index 7225b6dc03..1f81d03d96 100644 --- a/test/core/util/slice_splitter.cc +++ b/test/core/util/slice_splitter.cc @@ -21,7 +21,8 @@ #include <string.h> #include <grpc/support/alloc.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" const char* grpc_slice_split_mode_name(grpc_slice_split_mode mode) { switch (mode) { @@ -44,8 +45,8 @@ void grpc_split_slices(grpc_slice_split_mode mode, grpc_slice* src_slices, switch (mode) { case GRPC_SLICE_SPLIT_IDENTITY: *dst_slice_count = src_slice_count; - *dst_slices = - (grpc_slice*)gpr_malloc(sizeof(grpc_slice) * 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]); @@ -57,7 +58,7 @@ void grpc_split_slices(grpc_slice_split_mode mode, grpc_slice* src_slices, for (i = 0; i < src_slice_count; i++) { length += GRPC_SLICE_LENGTH(src_slices[i]); } - *dst_slices = (grpc_slice*)gpr_malloc(sizeof(grpc_slice)); + *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++) { @@ -73,7 +74,8 @@ void grpc_split_slices(grpc_slice_split_mode mode, grpc_slice* src_slices, length += GRPC_SLICE_LENGTH(src_slices[i]); } *dst_slice_count = length; - *dst_slices = (grpc_slice*)gpr_malloc(sizeof(grpc_slice) * 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++) { @@ -113,7 +115,7 @@ grpc_slice grpc_slice_merge(grpc_slice* slices, size_t nslices) { for (i = 0; i < nslices; i++) { if (GRPC_SLICE_LENGTH(slices[i]) + length > capacity) { capacity = GPR_MAX(capacity * 2, GRPC_SLICE_LENGTH(slices[i]) + length); - out = (uint8_t*)gpr_realloc(out, capacity); + out = static_cast<uint8_t*>(gpr_realloc(out, capacity)); } memcpy(out + length, GRPC_SLICE_START_PTR(slices[i]), GRPC_SLICE_LENGTH(slices[i])); diff --git a/test/core/util/subprocess.h b/test/core/util/subprocess.h new file mode 100644 index 0000000000..c7fe9af435 --- /dev/null +++ b/test/core/util/subprocess.h @@ -0,0 +1,36 @@ +/* + * + * 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/test/core/util/subprocess_posix.cc b/test/core/util/subprocess_posix.cc new file mode 100644 index 0000000000..ab288d777f --- /dev/null +++ b/test/core/util/subprocess_posix.cc @@ -0,0 +1,100 @@ +/* + * + * 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 "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); + return nullptr; + } else { + r = static_cast<gpr_subprocess*>(gpr_zalloc(sizeof(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/test/core/util/subprocess_windows.cc b/test/core/util/subprocess_windows.cc new file mode 100644 index 0000000000..d3295244ea --- /dev/null +++ b/test/core/util/subprocess_windows.cc @@ -0,0 +1,126 @@ +/* + * + * 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/test/core/util/test_config.cc b/test/core/util/test_config.cc index 9ebb52d83e..6a0d444a73 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -18,6 +18,7 @@ #include "test/core/util/test_config.h" +#include <inttypes.h> #include <signal.h> #include <stdbool.h> #include <stdio.h> @@ -27,15 +28,16 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" int64_t g_fixture_slowdown_factor = 1; int64_t g_poller_slowdown_factor = 1; #if GPR_GETPID_IN_UNISTD_H #include <unistd.h> -static unsigned seed(void) { return (unsigned)getpid(); } +static unsigned seed(void) { return static_cast<unsigned>(getpid()); } #endif #if GPR_GETPID_IN_PROCESS_H @@ -196,7 +198,6 @@ static void install_crash_handler() { #elif GPR_POSIX_CRASH_HANDLER #include <errno.h> #include <execinfo.h> -#include <grpc/support/useful.h> #include <stdio.h> #include <string.h> @@ -264,7 +265,7 @@ static void install_crash_handler() { ss.ss_size = sizeof(g_alt_stack); ss.ss_sp = g_alt_stack; GPR_ASSERT(sigaltstack(&ss, nullptr) == 0); - sa.sa_flags = (int)(SA_SIGINFO | SA_ONSTACK | SA_RESETHAND); + sa.sa_flags = static_cast<int>(SA_SIGINFO | SA_ONSTACK | SA_RESETHAND); sa.sa_sigaction = crash_handler; GPR_ASSERT(sigaction(SIGILL, &sa, nullptr) == 0); GPR_ASSERT(sigaction(SIGABRT, &sa, nullptr) == 0); @@ -365,15 +366,17 @@ int64_t grpc_test_slowdown_factor() { gpr_timespec grpc_timeout_seconds_to_deadline(int64_t time_s) { return gpr_time_add( gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(grpc_test_slowdown_factor() * (int64_t)1e3 * time_s, - GPR_TIMESPAN)); + gpr_time_from_millis( + grpc_test_slowdown_factor() * static_cast<int64_t>(1e3) * time_s, + GPR_TIMESPAN)); } gpr_timespec grpc_timeout_milliseconds_to_deadline(int64_t time_ms) { return gpr_time_add( gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_micros(grpc_test_slowdown_factor() * (int64_t)1e3 * time_ms, - GPR_TIMESPAN)); + gpr_time_from_micros( + grpc_test_slowdown_factor() * static_cast<int64_t>(1e3) * time_ms, + GPR_TIMESPAN)); } void grpc_test_init(int argc, char** argv) { diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 5f6af4e707..610a9918ce 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -17,16 +17,18 @@ */ #include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/socket_utils.h" #include "test/core/util/test_tcp_server.h" #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> #include <grpc/support/time.h> #include <string.h> + +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" @@ -53,12 +55,13 @@ void test_tcp_server_init(test_tcp_server* server, void test_tcp_server_start(test_tcp_server* server, int port) { grpc_resolved_address resolved_addr; - struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr; + grpc_sockaddr_in* addr = + reinterpret_cast<grpc_sockaddr_in*>(resolved_addr.addr); int port_added; grpc_core::ExecCtx exec_ctx; - addr->sin_family = AF_INET; - addr->sin_port = htons((uint16_t)port); + 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)); grpc_error* error = grpc_tcp_server_create(&server->shutdown_complete, diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc index f95ed62463..f2efb049b4 100644 --- a/test/core/util/trickle_endpoint.cc +++ b/test/core/util/trickle_endpoint.cc @@ -26,7 +26,8 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/useful.h> + +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/slice/slice_internal.h" #define WRITE_BUFFER_SIZE (2 * 1024 * 1024) @@ -47,7 +48,7 @@ typedef struct { static void te_read(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); grpc_endpoint_read(te->wrapped, slices, cb); } @@ -62,7 +63,7 @@ static void maybe_call_write_cb_locked(trickle_endpoint* te) { static void te_write(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); gpr_mu_lock(&te->mu); GPR_ASSERT(te->write_cb == nullptr); if (te->write_buffer.length == 0) { @@ -78,24 +79,24 @@ static void te_write(grpc_endpoint* ep, grpc_slice_buffer* slices, } static void te_add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); grpc_endpoint_add_to_pollset(te->wrapped, pollset); } static void te_add_to_pollset_set(grpc_endpoint* ep, grpc_pollset_set* pollset_set) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); grpc_endpoint_add_to_pollset_set(te->wrapped, pollset_set); } static void te_delete_from_pollset_set(grpc_endpoint* ep, grpc_pollset_set* pollset_set) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); grpc_endpoint_delete_from_pollset_set(te->wrapped, pollset_set); } static void te_shutdown(grpc_endpoint* ep, grpc_error* why) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); gpr_mu_lock(&te->mu); if (te->error == GRPC_ERROR_NONE) { te->error = GRPC_ERROR_REF(why); @@ -106,7 +107,7 @@ static void te_shutdown(grpc_endpoint* ep, grpc_error* why) { } static void te_destroy(grpc_endpoint* ep) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); grpc_endpoint_destroy(te->wrapped); gpr_mu_destroy(&te->mu); grpc_slice_buffer_destroy_internal(&te->write_buffer); @@ -116,22 +117,22 @@ static void te_destroy(grpc_endpoint* ep) { } static grpc_resource_user* te_get_resource_user(grpc_endpoint* ep) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); return grpc_endpoint_get_resource_user(te->wrapped); } static char* te_get_peer(grpc_endpoint* ep) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); return grpc_endpoint_get_peer(te->wrapped); } static int te_get_fd(grpc_endpoint* ep) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); return grpc_endpoint_get_fd(te->wrapped); } static void te_finish_write(void* arg, grpc_error* error) { - trickle_endpoint* te = (trickle_endpoint*)arg; + trickle_endpoint* te = static_cast<trickle_endpoint*>(arg); gpr_mu_lock(&te->mu); te->writing = false; grpc_slice_buffer_reset_and_unref(&te->writing_buffer); @@ -151,7 +152,8 @@ static const grpc_endpoint_vtable vtable = {te_read, grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap, double bytes_per_second) { - trickle_endpoint* te = (trickle_endpoint*)gpr_malloc(sizeof(*te)); + trickle_endpoint* te = + static_cast<trickle_endpoint*>(gpr_malloc(sizeof(*te))); te->base.vtable = &vtable; te->wrapped = wrap; te->bytes_per_second = bytes_per_second; @@ -165,16 +167,16 @@ grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap, } static double ts2dbl(gpr_timespec s) { - return (double)s.tv_sec + 1e-9 * (double)s.tv_nsec; + return static_cast<double>(s.tv_sec) + 1e-9 * static_cast<double>(s.tv_nsec); } size_t grpc_trickle_endpoint_trickle(grpc_endpoint* ep) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); gpr_mu_lock(&te->mu); if (!te->writing && te->write_buffer.length > 0) { gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); double elapsed = ts2dbl(gpr_time_sub(now, te->last_write)); - size_t bytes = (size_t)(te->bytes_per_second * elapsed); + size_t bytes = static_cast<size_t>(te->bytes_per_second * elapsed); // gpr_log(GPR_DEBUG, "%lf elapsed --> %" PRIdPTR " bytes", elapsed, bytes); if (bytes > 0) { grpc_slice_buffer_move_first(&te->write_buffer, @@ -194,7 +196,7 @@ size_t grpc_trickle_endpoint_trickle(grpc_endpoint* ep) { } size_t grpc_trickle_get_backlog(grpc_endpoint* ep) { - trickle_endpoint* te = (trickle_endpoint*)ep; + trickle_endpoint* te = reinterpret_cast<trickle_endpoint*>(ep); gpr_mu_lock(&te->mu); size_t backlog = te->write_buffer.length; gpr_mu_unlock(&te->mu); diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index e829d5278b..826907ae4e 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -19,22 +19,24 @@ #include <atomic> #include <memory> #include <mutex> +#include <random> #include <sstream> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/thd.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 "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" #include "test/core/util/port.h" @@ -104,8 +106,8 @@ class BalancerServiceImpl : public LoadBalancer::Service { for (size_t i = 0; i < num_drop_entry; ++i) { random_backend_indices.push_back(-1); } - std::random_shuffle(random_backend_indices.begin(), - random_backend_indices.end()); + std::shuffle(random_backend_indices.begin(), random_backend_indices.end(), + std::mt19937(std::random_device()())); // Build the response according to the random list generated above. LoadBalanceResponse response; for (int index : random_backend_indices) { @@ -149,7 +151,8 @@ class ClientChannelStressTest { addresses.emplace_back(AddressData{balancer_server.port_, true, ""}); } } - std::random_shuffle(addresses.begin(), addresses.end()); + std::shuffle(addresses.begin(), addresses.end(), + std::mt19937(std::random_device()())); SetNextResolution(addresses); std::this_thread::sleep_for(wait_duration); } @@ -228,8 +231,7 @@ class ClientChannelStressTest { } grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args fake_result = {1, &fake_addresses}; - grpc_fake_resolver_response_generator_set_response(response_generator_, - &fake_result); + response_generator_->SetResponse(&fake_result); grpc_lb_addresses_destroy(addresses); } @@ -251,9 +253,10 @@ class ClientChannelStressTest { void CreateStub() { ChannelArguments args; - response_generator_ = grpc_fake_resolver_response_generator_create(); + response_generator_ = + grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_); + response_generator_.get()); std::ostringstream uri; uri << "fake:///servername_not_used"; channel_ = @@ -296,7 +299,6 @@ class ClientChannelStressTest { for (size_t i = 0; i < backends_.size(); ++i) { backend_servers_[i].Shutdown(); } - grpc_fake_resolver_response_generator_unref(response_generator_); } std::atomic_bool shutdown_{false}; @@ -308,7 +310,8 @@ class ClientChannelStressTest { std::vector<std::unique_ptr<BalancerServiceImpl>> balancers_; std::vector<ServerThread<BackendServiceImpl>> backend_servers_; std::vector<ServerThread<BalancerServiceImpl>> balancer_servers_; - grpc_fake_resolver_response_generator* response_generator_; + grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> + response_generator_; std::vector<std::thread> client_threads_; }; diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index 52efce18b3..e64e260a46 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -16,7 +16,7 @@ * */ -#include <grpc++/security/credentials.h> +#include <grpcpp/security/credentials.h> #include <memory> diff --git a/test/cpp/cocoapods/GRPCCppTests.xcodeproj/project.pbxproj b/test/cpp/cocoapods/GRPCCppTests.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..1d332ba7ce --- /dev/null +++ b/test/cpp/cocoapods/GRPCCppTests.xcodeproj/project.pbxproj @@ -0,0 +1,533 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 2D3F2189E2CDF493639A17C5 /* libPods-test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 99B1FD20127AB0F23D6AB570 /* libPods-test.a */; }; + 5E63948A1FDB64B50051E9AA /* server_context_test_spouse_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E6394891FDB64B50051E9AA /* server_context_test_spouse_test.mm */; }; + 5EFA5F731FEDB36700EBF4B7 /* generic.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5EFA5F721FEDB36700EBF4B7 /* generic.mm */; }; + D0F8FABF3ECF587C207C12F3 /* libPods-generic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D0872BAEE90C8A149743DB7 /* libPods-generic.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 3D0872BAEE90C8A149743DB7 /* libPods-generic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-generic.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E63947F1FDB5EA10051E9AA /* test.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = test.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E6394831FDB5EA10051E9AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + 5E6394891FDB64B50051E9AA /* server_context_test_spouse_test.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = server_context_test_spouse_test.mm; sourceTree = "<group>"; }; + 5EFA5F701FEDB36700EBF4B7 /* generic.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = generic.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EFA5F721FEDB36700EBF4B7 /* generic.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = generic.mm; sourceTree = "<group>"; }; + 5EFA5F741FEDB36700EBF4B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + 8682448F311EDE94C14D551D /* Pods-test.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-test.release.xcconfig"; path = "Pods/Target Support Files/Pods-test/Pods-test.release.xcconfig"; sourceTree = "<group>"; }; + 91EDF22ADDE71926C7BC1AF1 /* Pods-test.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-test.debug.xcconfig"; path = "Pods/Target Support Files/Pods-test/Pods-test.debug.xcconfig"; sourceTree = "<group>"; }; + 99B1FD20127AB0F23D6AB570 /* libPods-test.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-test.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + B357AF2DC912B224C026D114 /* Pods-generic.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-generic.release.xcconfig"; path = "Pods/Target Support Files/Pods-generic/Pods-generic.release.xcconfig"; sourceTree = "<group>"; }; + D9B4F77163CB9089C4436BF4 /* Pods-generic.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-generic.debug.xcconfig"; path = "Pods/Target Support Files/Pods-generic/Pods-generic.debug.xcconfig"; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5E63947C1FDB5EA10051E9AA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2D3F2189E2CDF493639A17C5 /* libPods-test.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EFA5F6D1FEDB36700EBF4B7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D0F8FABF3ECF587C207C12F3 /* libPods-generic.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4439BD4D56FD5738BF780F8E /* Pods */ = { + isa = PBXGroup; + children = ( + 91EDF22ADDE71926C7BC1AF1 /* Pods-test.debug.xcconfig */, + 8682448F311EDE94C14D551D /* Pods-test.release.xcconfig */, + D9B4F77163CB9089C4436BF4 /* Pods-generic.debug.xcconfig */, + B357AF2DC912B224C026D114 /* Pods-generic.release.xcconfig */, + ); + name = Pods; + sourceTree = "<group>"; + }; + 5E63944B1FDB5D9B0051E9AA = { + isa = PBXGroup; + children = ( + 5E63947F1FDB5EA10051E9AA /* test.xctest */, + 5E6394801FDB5EA10051E9AA /* test */, + 4439BD4D56FD5738BF780F8E /* Pods */, + 5EFA5F711FEDB36700EBF4B7 /* generic */, + C2E6603B58413BD724AFB400 /* Frameworks */, + 5EFA5F701FEDB36700EBF4B7 /* generic.xctest */, + ); + sourceTree = "<group>"; + }; + 5E6394801FDB5EA10051E9AA /* test */ = { + isa = PBXGroup; + children = ( + 5E6394891FDB64B50051E9AA /* server_context_test_spouse_test.mm */, + 5E6394831FDB5EA10051E9AA /* Info.plist */, + ); + path = test; + sourceTree = "<group>"; + }; + 5EFA5F711FEDB36700EBF4B7 /* generic */ = { + isa = PBXGroup; + children = ( + 5EFA5F721FEDB36700EBF4B7 /* generic.mm */, + 5EFA5F741FEDB36700EBF4B7 /* Info.plist */, + ); + path = generic; + sourceTree = "<group>"; + }; + C2E6603B58413BD724AFB400 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 99B1FD20127AB0F23D6AB570 /* libPods-test.a */, + 3D0872BAEE90C8A149743DB7 /* libPods-generic.a */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5E63947E1FDB5EA10051E9AA /* test */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E6394841FDB5EA10051E9AA /* Build configuration list for PBXNativeTarget "test" */; + buildPhases = ( + 6D8317CF72F9E252442662F8 /* [CP] Check Pods Manifest.lock */, + 5E63947B1FDB5EA10051E9AA /* Sources */, + 5E63947C1FDB5EA10051E9AA /* Frameworks */, + 5E63947D1FDB5EA10051E9AA /* Resources */, + B972D278DA2A2BF12386177C /* [CP] Embed Pods Frameworks */, + 3C2FE7A8DBA8BBCB2923B173 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = test; + productName = test; + productReference = 5E63947F1FDB5EA10051E9AA /* test.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5EFA5F6F1FEDB36700EBF4B7 /* generic */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EFA5F751FEDB36700EBF4B7 /* Build configuration list for PBXNativeTarget "generic" */; + buildPhases = ( + 4844599DC62113265AB660B3 /* [CP] Check Pods Manifest.lock */, + 5EFA5F6C1FEDB36700EBF4B7 /* Sources */, + 5EFA5F6D1FEDB36700EBF4B7 /* Frameworks */, + 5EFA5F6E1FEDB36700EBF4B7 /* Resources */, + 11E4716E0919C734CC6AA8C2 /* [CP] Embed Pods Frameworks */, + 9E149E84C3AA06289FE1F244 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = generic; + productName = generic; + productReference = 5EFA5F701FEDB36700EBF4B7 /* generic.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5E63944C1FDB5D9B0051E9AA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 5E63947E1FDB5EA10051E9AA = { + CreatedOnToolsVersion = 9.1; + ProvisioningStyle = Automatic; + }; + 5EFA5F6F1FEDB36700EBF4B7 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 5E63944F1FDB5D9B0051E9AA /* Build configuration list for PBXProject "GRPCCppTests" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5E63944B1FDB5D9B0051E9AA; + productRefGroup = 5E63944B1FDB5D9B0051E9AA; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5E63947E1FDB5EA10051E9AA /* test */, + 5EFA5F6F1FEDB36700EBF4B7 /* generic */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5E63947D1FDB5EA10051E9AA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EFA5F6E1FEDB36700EBF4B7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 11E4716E0919C734CC6AA8C2 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-generic/Pods-generic-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 3C2FE7A8DBA8BBCB2923B173 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-test/Pods-test-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 4844599DC62113265AB660B3 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-generic-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 6D8317CF72F9E252442662F8 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-test-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9E149E84C3AA06289FE1F244 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-generic/Pods-generic-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + B972D278DA2A2BF12386177C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-test/Pods-test-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5E63947B1FDB5EA10051E9AA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E63948A1FDB64B50051E9AA /* server_context_test_spouse_test.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EFA5F6C1FEDB36700EBF4B7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EFA5F731FEDB36700EBF4B7 /* generic.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 5E6394731FDB5D9B0051E9AA /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ../../../include; + IPHONEOS_DEPLOYMENT_TARGET = 11.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + USER_HEADER_SEARCH_PATHS = ../../..; + }; + name = Debug; + }; + 5E6394741FDB5D9B0051E9AA /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ../../../include; + IPHONEOS_DEPLOYMENT_TARGET = 11.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + USER_HEADER_SEARCH_PATHS = ../../..; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5E6394851FDB5EA10051E9AA /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 91EDF22ADDE71926C7BC1AF1 /* Pods-test.debug.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/BoringSSL\"", + "\"${PODS_ROOT}/Headers/Public/gRPC-C++\"", + "\"${PODS_ROOT}/Headers/Public/gRPC-Core\"", + "\"${PODS_ROOT}/Headers/Public/nanopb\"", + ); + INFOPLIST_FILE = test/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.test; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E6394861FDB5EA10051E9AA /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8682448F311EDE94C14D551D /* Pods-test.release.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/BoringSSL\"", + "\"${PODS_ROOT}/Headers/Public/gRPC-C++\"", + "\"${PODS_ROOT}/Headers/Public/gRPC-Core\"", + "\"${PODS_ROOT}/Headers/Public/nanopb\"", + ); + INFOPLIST_FILE = test/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.test; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 5EFA5F761FEDB36700EBF4B7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D9B4F77163CB9089C4436BF4 /* Pods-generic.debug.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + INFOPLIST_FILE = generic/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.generic; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EFA5F771FEDB36700EBF4B7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B357AF2DC912B224C026D114 /* Pods-generic.release.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + INFOPLIST_FILE = generic/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.generic; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5E63944F1FDB5D9B0051E9AA /* Build configuration list for PBXProject "GRPCCppTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E6394731FDB5D9B0051E9AA /* Debug */, + 5E6394741FDB5D9B0051E9AA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5E6394841FDB5EA10051E9AA /* Build configuration list for PBXNativeTarget "test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E6394851FDB5EA10051E9AA /* Debug */, + 5E6394861FDB5EA10051E9AA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EFA5F751FEDB36700EBF4B7 /* Build configuration list for PBXNativeTarget "generic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EFA5F761FEDB36700EBF4B7 /* Debug */, + 5EFA5F771FEDB36700EBF4B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5E63944C1FDB5D9B0051E9AA /* Project object */; +} diff --git a/test/cpp/cocoapods/Podfile b/test/cpp/cocoapods/Podfile new file mode 100644 index 0000000000..8d8cdaaadd --- /dev/null +++ b/test/cpp/cocoapods/Podfile @@ -0,0 +1,71 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +install! 'cocoapods', :deterministic_uuids => false + +# Location of gRPC's repo root relative to this file. +GRPC_LOCAL_SRC = '../../..' + +%w( + test + generic +).each do |target_name| + target target_name do + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC + pod 'gRPC-C++', :path => GRPC_LOCAL_SRC + pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + end +end + +# gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's +# pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded +# and before they are installed in the user project. +# +# This podspec searches for the gRPC core library headers under "$(PODS_ROOT)/gRPC-Core", where +# Cocoapods normally places the downloaded sources. When doing local development of the libraries, +# though, Cocoapods just takes the sources from whatever directory was specified using `:path`, and +# doesn't copy them under $(PODS_ROOT). When using static libraries, one can sometimes rely on the +# symbolic links to the pods headers that Cocoapods creates under "$(PODS_ROOT)/Headers". But those +# aren't created when using dynamic frameworks. So our solution is to modify the podspec on the fly +# to point at the local directory where the sources are. +# +# TODO(jcanizales): Send a PR to Cocoapods to get rid of this need. +pre_install do |installer| + # This is the gRPC-Core podspec object, as initialized by its podspec file. + grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Core'}.root_spec + + # Copied from gRPC-Core.podspec, except for the adjusted src_root: + src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" + grpc_core_spec.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the + # build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' + end + + # CocoaPods creates duplicated library targets of gRPC-Core when the test targets include + # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core' + # and require the same error suppresion. + if target.name.start_with?('gRPC-Core') + target.build_configurations.each do |config| + # TODO(zyc): Remove this setting after the issue is resolved + # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void + # function" warning + config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1' + end + end + end +end diff --git a/test/cpp/cocoapods/generic/Info.plist b/test/cpp/cocoapods/generic/Info.plist new file mode 100644 index 0000000000..6c40a6cd0c --- /dev/null +++ b/test/cpp/cocoapods/generic/Info.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleVersion</key> + <string>1</string> +</dict> +</plist> diff --git a/test/cpp/cocoapods/generic/generic.mm b/test/cpp/cocoapods/generic/generic.mm new file mode 100644 index 0000000000..6740e9c3ad --- /dev/null +++ b/test/cpp/cocoapods/generic/generic.mm @@ -0,0 +1,245 @@ +/* + * + * 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. + * + */ + +#import <XCTest/XCTest.h> + +#include <sstream> + +#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/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> +#include <grpcpp/support/slice.h> + +#include "src/core/lib/gprpp/thd.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +using std::chrono::system_clock; +using namespace grpc; + +void* tag(int i) { return (void*)(intptr_t)i; } + +static grpc_slice merge_slices(grpc_slice* slices, size_t nslices) { + size_t i; + size_t len = 0; + uint8_t* cursor; + grpc_slice out; + + for (i = 0; i < nslices; i++) { + len += GRPC_SLICE_LENGTH(slices[i]); + } + + out = grpc_slice_malloc(len); + cursor = GRPC_SLICE_START_PTR(out); + + for (i = 0; i < nslices; i++) { + memcpy(cursor, GRPC_SLICE_START_PTR(slices[i]), GRPC_SLICE_LENGTH(slices[i])); + cursor += GRPC_SLICE_LENGTH(slices[i]); + } + + return out; +} + +int byte_buffer_eq_string(ByteBuffer* bb, const char* str) { + int res; + + std::vector<Slice> slices; + bb->Dump(&slices); + grpc_slice* c_slices = new grpc_slice[slices.size()]; + for (int i = 0; i < slices.size(); i++) { + c_slices[i] = slices[i].c_slice(); + } + grpc_slice a = merge_slices(c_slices, slices.size()); + grpc_slice b = grpc_slice_from_copied_string(str); + res = (GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b)) && + (0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), GRPC_SLICE_LENGTH(a))); + grpc_slice_unref(a); + grpc_slice_unref(b); + for (int i = 0; i < slices.size(); i++) { + grpc_slice_unref(c_slices[i]); + } + delete[] c_slices; + + return res; +} + +@interface GenericTest : XCTestCase + +@end + +@implementation GenericTest { + grpc::string server_host_; + CompletionQueue cli_cq_; + std::unique_ptr<ServerCompletionQueue> srv_cq_; + std::unique_ptr<GenericStub> generic_stub_; + std::unique_ptr<Server> server_; + AsyncGenericService generic_service_; + std::ostringstream server_address_; +} + +- (void)verify_ok:(grpc::CompletionQueue*)cq i:(int)i expect_ok:(bool)expect_ok { + bool ok; + void* got_tag; + XCTAssertTrue(cq->Next(&got_tag, &ok)); + XCTAssertEqual(expect_ok, ok); + XCTAssertEqual(tag(i), got_tag); +} + +- (void)server_ok:(int)i { + [self verify_ok:srv_cq_.get() i:i expect_ok:true]; +} +- (void)client_ok:(int)i { + [self verify_ok:&cli_cq_ i:i expect_ok:true]; +} +- (void)server_fail:(int)i { + [self verify_ok:srv_cq_.get() i:i expect_ok:false]; +} +- (void)client_fail:(int)i { + [self verify_ok:&cli_cq_ i:i expect_ok:false]; +} + +- (void)setUp { + [super setUp]; + + server_host_ = "localhost"; + 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)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the + // class. + 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)) + ; + [super tearDown]; +} + +- (void)ResetStub { + std::shared_ptr<Channel> channel = + CreateChannel(server_address_.str(), InsecureChannelCredentials()); + generic_stub_.reset(new GenericStub(channel)); +} + +- (void)SendRpc:(int)num_rpcs { + [self SendRpc:num_rpcs check_deadline:false deadline:gpr_inf_future(GPR_CLOCK_MONOTONIC)]; +} + +- (void)SendRpc:(int)num_rpcs check_deadline:(bool)check_deadline deadline:(gpr_timespec)deadline { + const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); + for (int i = 0; i < num_rpcs; i++) { + 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); + } + + std::unique_ptr<GenericClientAsyncReaderWriter> call = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + [self client_ok:1]; + Slice send_slice = Slice("hello world", 11); + std::unique_ptr<ByteBuffer> send_buffer = + std::unique_ptr<ByteBuffer>(new ByteBuffer(&send_slice, 1)); + call->Write(*send_buffer, tag(2)); + // Send ByteBuffer can be destroyed after calling Write. + send_buffer.reset(); + [self client_ok:2]; + call->WritesDone(tag(3)); + [self client_ok:3]; + + generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), srv_cq_.get(), tag(4)); + + [self verify_ok:srv_cq_.get() i:4 expect_ok:true]; + XCTAssertEqual(server_host_, srv_ctx.host().substr(0, server_host_.length())); + XCTAssertEqual(kMethodName, srv_ctx.method()); + + if (check_deadline) { + XCTAssertTrue(gpr_time_similar(deadline, srv_ctx.raw_deadline(), + gpr_time_from_millis(1000, GPR_TIMESPAN))); + } + + ByteBuffer recv_buffer; + stream.Read(&recv_buffer, tag(5)); + [self server_ok:5]; + XCTAssertTrue(byte_buffer_eq_string(&recv_buffer, "hello world")); + + send_buffer = std::unique_ptr<ByteBuffer>(new ByteBuffer(recv_buffer)); + stream.Write(*send_buffer, tag(6)); + send_buffer.reset(); + [self server_ok:6]; + + stream.Finish(Status::OK, tag(7)); + [self server_ok:7]; + + recv_buffer.Clear(); + call->Read(&recv_buffer, tag(8)); + [self client_ok:8]; + XCTAssertTrue(byte_buffer_eq_string(&recv_buffer, "hello world")); + + call->Finish(&recv_status, tag(9)); + [self client_ok:9]; + + XCTAssertTrue(recv_status.ok()); + } +} + +- (void)testSimpleRpc { + [self ResetStub]; + [self SendRpc:1]; +} + +- (void)testSequentialRpcs { + [self ResetStub]; + [self SendRpc:10]; +} + ++ (void)setUp { + grpc_test_init(0, NULL); +} + +@end diff --git a/test/cpp/cocoapods/test/Info.plist b/test/cpp/cocoapods/test/Info.plist new file mode 100644 index 0000000000..6c40a6cd0c --- /dev/null +++ b/test/cpp/cocoapods/test/Info.plist @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleVersion</key> + <string>1</string> +</dict> +</plist> diff --git a/test/cpp/cocoapods/test/server_context_test_spouse_test.mm b/test/cpp/cocoapods/test/server_context_test_spouse_test.mm new file mode 100644 index 0000000000..59f60e3ca1 --- /dev/null +++ b/test/cpp/cocoapods/test/server_context_test_spouse_test.mm @@ -0,0 +1,98 @@ +/* + * + * 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. + * + */ + +// Hack TEST macro of gTest and make they conform XCTest style. We only +// need test name (b), not test case name (a). +#define TEST(a, b) -(void)test##b +#define ASSERT_TRUE XCTAssert +#define ASSERT_EQ XCTAssertEqual + +#import <XCTest/XCTest.h> + +#include <grpcpp/test/server_context_test_spouse.h> + +#include <cstring> +#include <vector> + +#include <grpcpp/impl/grpc_library.h> + +static grpc::internal::GrpcLibraryInitializer g_initializer; + +const char key1[] = "metadata-key1"; +const char key2[] = "metadata-key2"; +const char val1[] = "metadata-val1"; +const char val2[] = "metadata-val2"; + +bool ClientMetadataContains(const grpc::ServerContext& context, const grpc::string_ref& key, + const grpc::string_ref& value) { + const auto& client_metadata = context.client_metadata(); + for (auto iter = client_metadata.begin(); iter != client_metadata.end(); ++iter) { + if (iter->first == key && iter->second == value) { + return true; + } + } + return false; +} + +@interface ServerContextTestSpouseTest : XCTestCase + +@end + +@implementation ServerContextTestSpouseTest + +TEST(ServerContextTestSpouseTest, ClientMetadata) { + grpc::ServerContext context; + grpc::testing::ServerContextTestSpouse spouse(&context); + + spouse.AddClientMetadata(key1, val1); + ASSERT_TRUE(ClientMetadataContains(context, key1, val1)); + + spouse.AddClientMetadata(key2, val2); + ASSERT_TRUE(ClientMetadataContains(context, key1, val1)); + ASSERT_TRUE(ClientMetadataContains(context, key2, val2)); +} + +TEST(ServerContextTestSpouseTest, InitialMetadata) { + grpc::ServerContext context; + grpc::testing::ServerContextTestSpouse spouse(&context); + std::multimap<grpc::string, grpc::string> metadata; + + context.AddInitialMetadata(key1, val1); + metadata.insert(std::pair<grpc::string, grpc::string>(key1, val1)); + ASSERT_EQ(metadata, spouse.GetInitialMetadata()); + + context.AddInitialMetadata(key2, val2); + metadata.insert(std::pair<grpc::string, grpc::string>(key2, val2)); + ASSERT_EQ(metadata, spouse.GetInitialMetadata()); +} + +TEST(ServerContextTestSpouseTest, TrailingMetadata) { + grpc::ServerContext context; + grpc::testing::ServerContextTestSpouse spouse(&context); + std::multimap<grpc::string, grpc::string> metadata; + + context.AddTrailingMetadata(key1, val1); + metadata.insert(std::pair<grpc::string, grpc::string>(key1, val1)); + ASSERT_EQ(metadata, spouse.GetTrailingMetadata()); + + context.AddTrailingMetadata(key2, val2); + metadata.insert(std::pair<grpc::string, grpc::string>(key2, val2)); + ASSERT_EQ(metadata, spouse.GetTrailingMetadata()); +} + +@end diff --git a/test/cpp/codegen/BUILD b/test/cpp/codegen/BUILD index 6cc81e3398..12712a3e6c 100644 --- a/test/cpp/codegen/BUILD +++ b/test/cpp/codegen/BUILD @@ -14,7 +14,7 @@ licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_package") +load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_package", "grpc_cc_binary", "grpc_sh_test") grpc_package(name = "test/cpp/codegen") @@ -55,17 +55,12 @@ grpc_cc_test( ], ) -grpc_cc_test( +grpc_cc_binary( name = "golden_file_test", + testonly = True, srcs = ["golden_file_test.cc"], - args = ["--generated_file_path=$(GENDIR)/src/proto/grpc/testing/"], - data = [ - ":compiler_test_golden", - "//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen", - ], deps = [ "//:grpc++", - "//src/proto/grpc/testing:compiler_test_proto", "//test/core/util:gpr_test_util", ], external_deps = [ @@ -73,3 +68,29 @@ grpc_cc_test( "gflags", ], ) + +genrule( + name = "copy_compiler_test_grpc_pb_h", + srcs = ["//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen"], + cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h > $@", + outs = ["compiler_test.grpc.pb.h"], +) + +genrule( + name = "copy_compiler_test_mock_grpc_pb_h", + srcs = ["//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen"], + cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test_mock.grpc.pb.h > $@", + outs = ["compiler_test_mock.grpc.pb.h"], +) + +grpc_sh_test( + name = "run_golden_file_test", + srcs = ["run_golden_file_test.sh"], + data = [ + ":golden_file_test", + ":compiler_test_golden", + ":compiler_test_mock_golden", + ":compiler_test.grpc.pb.h", + ":compiler_test_mock.grpc.pb.h", + ], +) diff --git a/test/cpp/codegen/codegen_test_full.cc b/test/cpp/codegen/codegen_test_full.cc index 98792bde04..ccd310fc22 100644 --- a/test/cpp/codegen/codegen_test_full.cc +++ b/test/cpp/codegen/codegen_test_full.cc @@ -16,8 +16,8 @@ * */ -#include <grpc++/completion_queue.h> #include <grpc/support/time.h> +#include <grpcpp/completion_queue.h> #include <gtest/gtest.h> namespace grpc { diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 026a94112a..ca7db5db32 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -26,15 +26,15 @@ #include "src/proto/grpc/testing/compiler_test.pb.h" -#include <grpc++/impl/codegen/async_stream.h> -#include <grpc++/impl/codegen/async_unary_call.h> -#include <grpc++/impl/codegen/method_handler_impl.h> -#include <grpc++/impl/codegen/proto_utils.h> -#include <grpc++/impl/codegen/rpc_method.h> -#include <grpc++/impl/codegen/service_type.h> -#include <grpc++/impl/codegen/status.h> -#include <grpc++/impl/codegen/stub_options.h> -#include <grpc++/impl/codegen/sync_stream.h> +#include <grpcpp/impl/codegen/async_stream.h> +#include <grpcpp/impl/codegen/async_unary_call.h> +#include <grpcpp/impl/codegen/method_handler_impl.h> +#include <grpcpp/impl/codegen/proto_utils.h> +#include <grpcpp/impl/codegen/rpc_method.h> +#include <grpcpp/impl/codegen/service_type.h> +#include <grpcpp/impl/codegen/status.h> +#include <grpcpp/impl/codegen/stub_options.h> +#include <grpcpp/impl/codegen/sync_stream.h> namespace grpc { class CompletionQueue; diff --git a/test/cpp/codegen/compiler_test_mock_golden b/test/cpp/codegen/compiler_test_mock_golden index f97c2dd83a..65a7cb0f85 100644 --- a/test/cpp/codegen/compiler_test_mock_golden +++ b/test/cpp/codegen/compiler_test_mock_golden @@ -5,8 +5,8 @@ #include "src/proto/grpc/testing/compiler_test.pb.h" #include "src/proto/grpc/testing/compiler_test.grpc.pb.h" -#include <grpc++/impl/codegen/async_stream.h> -#include <grpc++/impl/codegen/sync_stream.h> +#include <grpcpp/impl/codegen/async_stream.h> +#include <grpcpp/impl/codegen/sync_stream.h> #include <gmock/gmock.h> namespace grpc { namespace testing { diff --git a/test/cpp/codegen/golden_file_test.cc b/test/cpp/codegen/golden_file_test.cc index 14880982b5..7e4d15a7c9 100644 --- a/test/cpp/codegen/golden_file_test.cc +++ b/test/cpp/codegen/golden_file_test.cc @@ -22,6 +22,13 @@ #include <gflags/gflags.h> #include <gtest/gtest.h> +// In some distros, gflags is in the namespace google, and in some others, +// in gflags. This hack is enabling us to find both. +namespace google {} +namespace gflags {} +using namespace google; +using namespace gflags; + DEFINE_string( generated_file_path, "", "path to the directory containing generated files compiler_test.grpc.pb.h" @@ -60,7 +67,7 @@ TEST(GoldenMockFileTest, TestGeneratedMockFile) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - ::google::ParseCommandLineFlags(&argc, &argv, true); + ParseCommandLineFlags(&argc, &argv, true); if (FLAGS_generated_file_path.empty()) { FLAGS_generated_file_path = "gens/src/proto/grpc/testing/"; } diff --git a/test/cpp/codegen/proto_utils_test.cc b/test/cpp/codegen/proto_utils_test.cc index cc355bb24a..801660eef6 100644 --- a/test/cpp/codegen/proto_utils_test.cc +++ b/test/cpp/codegen/proto_utils_test.cc @@ -16,40 +16,50 @@ * */ -#include <grpc++/impl/codegen/grpc_library.h> -#include <grpc++/impl/codegen/proto_utils.h> -#include <grpc++/impl/grpc_library.h> #include <grpc/impl/codegen/byte_buffer.h> #include <grpc/slice.h> +#include <grpcpp/impl/codegen/grpc_library.h> +#include <grpcpp/impl/codegen/proto_utils.h> +#include <grpcpp/impl/grpc_library.h> #include <gtest/gtest.h> namespace grpc { + namespace internal { -// Provide access to GrpcBufferWriter internals. -class GrpcBufferWriterPeer { +// Provide access to ProtoBufferWriter internals. +class ProtoBufferWriterPeer { public: - explicit GrpcBufferWriterPeer(internal::GrpcBufferWriter* writer) - : writer_(writer) {} + explicit ProtoBufferWriterPeer(ProtoBufferWriter* writer) : writer_(writer) {} bool have_backup() const { return writer_->have_backup_; } const grpc_slice& backup_slice() const { return writer_->backup_slice_; } const grpc_slice& slice() const { return writer_->slice_; } private: - GrpcBufferWriter* writer_; + ProtoBufferWriter* writer_; +}; + +// Provide access to ByteBuffer internals. +class GrpcByteBufferPeer { + public: + explicit GrpcByteBufferPeer(ByteBuffer* bb) : bb_(bb) {} + grpc_byte_buffer* c_buffer() { return bb_->c_buffer(); } + + private: + ByteBuffer* bb_; }; class ProtoUtilsTest : public ::testing::Test {}; // Regression test for a memory corruption bug where a series of -// GrpcBufferWriter Next()/Backup() invocations could result in a dangling +// ProtoBufferWriter Next()/Backup() invocations could result in a dangling // pointer returned by Next() due to the interaction between grpc_slice inlining // and GRPC_SLICE_START_PTR. TEST_F(ProtoUtilsTest, TinyBackupThenNext) { - grpc_byte_buffer* bp; + ByteBuffer bp; const int block_size = 1024; - GrpcBufferWriter writer(&bp, block_size, 8192); - GrpcBufferWriterPeer peer(&writer); + ProtoBufferWriter writer(&bp, block_size, 8192); + ProtoBufferWriterPeer peer(&writer); void* data; int size; @@ -63,17 +73,14 @@ TEST_F(ProtoUtilsTest, TinyBackupThenNext) { ASSERT_TRUE(writer.Next(&data, &size)); EXPECT_TRUE(peer.slice().refcount != nullptr); EXPECT_EQ(block_size, size); - - // Cleanup. - g_core_codegen_interface->grpc_byte_buffer_destroy(bp); } namespace { // Set backup_size to 0 to indicate no backup is needed. void BufferWriterTest(int block_size, int total_size, int backup_size) { - grpc_byte_buffer* bp; - GrpcBufferWriter writer(&bp, block_size, total_size); + ByteBuffer bb; + ProtoBufferWriter writer(&bb, block_size, total_size); int written_size = 0; void* data; @@ -103,17 +110,18 @@ void BufferWriterTest(int block_size, int total_size, int backup_size) { ASSERT_GT(backup_size, 0); } for (int i = 0; i < write_size; i++) { - ((uint8_t*)data)[i] = written_size % 128; + (static_cast<uint8_t*>(data))[i] = written_size % 128; written_size++; } if (should_backup) { writer.BackUp(backup_size); } } - EXPECT_EQ(grpc_byte_buffer_length(bp), (size_t)total_size); + EXPECT_EQ(bb.Length(), (size_t)total_size); grpc_byte_buffer_reader reader; - grpc_byte_buffer_reader_init(&reader, bp); + GrpcByteBufferPeer peer(&bb); + grpc_byte_buffer_reader_init(&reader, peer.c_buffer()); int read_bytes = 0; while (read_bytes < total_size) { grpc_slice s; @@ -126,11 +134,10 @@ void BufferWriterTest(int block_size, int total_size, int backup_size) { } EXPECT_EQ(read_bytes, total_size); grpc_byte_buffer_reader_destroy(&reader); - grpc_byte_buffer_destroy(bp); } TEST(WriterTest, TinyBlockTinyBackup) { - for (int i = 2; i < (int)GRPC_SLICE_INLINED_SIZE; i++) { + for (int i = 2; i < static_cast<int> GRPC_SLICE_INLINED_SIZE; i++) { BufferWriterTest(i, 256, 1); } } @@ -154,7 +161,7 @@ TEST(WriterTest, LargeBlockLargeBackup) { BufferWriterTest(4096, 8192, 4095); } } // namespace grpc int main(int argc, char** argv) { - // Ensure the GrpcBufferWriter internals are initialized. + // Ensure the ProtoBufferWriter internals are initialized. grpc::internal::GrpcLibraryInitializer init; init.summon(); grpc::GrpcLibraryCodegen lib; diff --git a/test/cpp/codegen/run_golden_file_test.sh b/test/cpp/codegen/run_golden_file_test.sh new file mode 100755 index 0000000000..8fe801c876 --- /dev/null +++ b/test/cpp/codegen/run_golden_file_test.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# 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 -eux + +GENERATED_PB_H_DIR="${TEST_SRCDIR}/com_github_grpc_grpc/test/cpp/codegen/" +test/cpp/codegen/golden_file_test --generated_file_path="$GENERATED_PB_H_DIR" diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index e2b6365b13..2cf3ad669f 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -19,8 +19,8 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_package") grpc_package(name = "test/cpp/common") grpc_cc_test( - name = "alarm_cpp_test", - srcs = ["alarm_cpp_test.cc"], + name = "alarm_test", + srcs = ["alarm_test.cc"], deps = [ "//:grpc++_unsecure", "//test/core/util:gpr_test_util", diff --git a/test/cpp/common/alarm_cpp_test.cc b/test/cpp/common/alarm_test.cc index 7adc3102f4..57d958349e 100644 --- a/test/cpp/common/alarm_cpp_test.cc +++ b/test/cpp/common/alarm_test.cc @@ -16,8 +16,8 @@ * */ -#include <grpc++/alarm.h> -#include <grpc++/completion_queue.h> +#include <grpcpp/alarm.h> +#include <grpcpp/completion_queue.h> #include <thread> #include <gtest/gtest.h> @@ -35,8 +35,8 @@ TEST(AlarmTest, RegularExpiry) { void* output_tag; bool ok; - const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(2)); + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); @@ -56,8 +56,8 @@ TEST(AlarmTest, MultithreadedRegularExpiry) { }); std::thread t2([&cq, &ok, &output_tag, &status] { - status = cq.AsyncNext((void**)&output_tag, &ok, - grpc_timeout_seconds_to_deadline(2)); + status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10)); }); t1.join(); @@ -74,8 +74,8 @@ TEST(AlarmTest, DeprecatedRegularExpiry) { void* output_tag; bool ok; - const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(2)); + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); @@ -90,8 +90,8 @@ TEST(AlarmTest, MoveConstructor) { Alarm second(std::move(first)); void* output_tag; bool ok; - const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(2)); + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); EXPECT_EQ(junk, output_tag); @@ -107,8 +107,8 @@ TEST(AlarmTest, MoveAssignment) { void* output_tag; bool ok; - const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(2)); + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); @@ -125,8 +125,8 @@ TEST(AlarmTest, RegularExpiryChrono) { void* output_tag; bool ok; - const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(2)); + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); @@ -141,8 +141,8 @@ TEST(AlarmTest, ZeroExpiry) { void* output_tag; bool ok; - const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); @@ -157,8 +157,8 @@ TEST(AlarmTest, NegativeExpiry) { void* output_tag; bool ok; - const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); @@ -169,19 +169,42 @@ TEST(AlarmTest, Cancellation) { CompletionQueue cq; void* junk = reinterpret_cast<void*>(1618033); Alarm alarm; - alarm.Set(&cq, grpc_timeout_seconds_to_deadline(2), junk); + alarm.Set(&cq, grpc_timeout_seconds_to_deadline(10), junk); alarm.Cancel(); void* output_tag; bool ok; - const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_FALSE(ok); EXPECT_EQ(junk, output_tag); } +TEST(AlarmTest, SetDestruction) { + CompletionQueue cq; + void* junk = reinterpret_cast<void*>(1618033); + { + Alarm alarm; + alarm.Set(&cq, grpc_timeout_seconds_to_deadline(10), junk); + } + + void* output_tag; + bool ok; + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); + + EXPECT_EQ(status, CompletionQueue::GOT_EVENT); + EXPECT_FALSE(ok); + EXPECT_EQ(junk, output_tag); +} + +TEST(AlarmTest, UnsetDestruction) { + CompletionQueue cq; + Alarm alarm; +} + } // namespace } // namespace grpc diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc index fce409aa2f..9634555e4b 100644 --- a/test/cpp/common/auth_property_iterator_test.cc +++ b/test/cpp/common/auth_property_iterator_test.cc @@ -16,8 +16,8 @@ * */ -#include <grpc++/security/auth_context.h> #include <grpc/grpc_security.h> +#include <grpcpp/security/auth_context.h> #include <gtest/gtest.h> #include "src/cpp/common/secure_auth_context.h" #include "test/cpp/util/string_ref_helper.h" diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc index f330c01281..183d2afa78 100644 --- a/test/cpp/common/channel_arguments_test.cc +++ b/test/cpp/common/channel_arguments_test.cc @@ -16,13 +16,13 @@ * */ -#include <grpc++/support/channel_arguments.h> +#include <grpcpp/support/channel_arguments.h> -#include <grpc++/grpc++.h> #include <grpc/grpc.h> -#include <grpc/support/useful.h> +#include <grpcpp/grpcpp.h> #include <gtest/gtest.h> +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_mutator.h" diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc index 7a0530c20a..6461f49743 100644 --- a/test/cpp/common/secure_auth_context_test.cc +++ b/test/cpp/common/secure_auth_context_test.cc @@ -17,8 +17,8 @@ */ #include "src/cpp/common/secure_auth_context.h" -#include <grpc++/security/auth_context.h> #include <grpc/grpc_security.h> +#include <grpcpp/security/auth_context.h> #include <gtest/gtest.h> #include "test/cpp/util/string_ref_helper.h" diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 265f75403d..8ab0811ffa 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -16,25 +16,31 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package", "grpc_cc_binary") -grpc_package(name = "test/cpp/end2end", visibility = "public") # Allows external users to implement end2end tests. +grpc_package( + name = "test/cpp/end2end", + visibility = "public", +) # Allows external users to implement end2end tests. grpc_cc_library( name = "test_service_impl", testonly = True, srcs = ["test_service_impl.cc"], hdrs = ["test_service_impl.h"], + external_deps = [ + "gtest", + ], deps = [ "//src/proto/grpc/testing:echo_proto", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "async_end2end_test", srcs = ["async_end2end_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -47,14 +53,17 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "client_crash_test", srcs = ["client_crash_test.cc"], + data = [ + ":client_crash_test_server", + ], + external_deps = [ + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -66,17 +75,16 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - data = [ - ":client_crash_test_server", - ], - external_deps = [ - "gtest", - ], ) grpc_cc_binary( name = "client_crash_test_server", + testonly = True, srcs = ["client_crash_test_server.cc"], + external_deps = [ + "gflags", + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -88,16 +96,15 @@ grpc_cc_binary( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gflags", - "gtest", - ], ) grpc_cc_library( name = "end2end_test_lib", - srcs = ["end2end_test.cc"], testonly = True, + srcs = ["end2end_test.cc"], + external_deps = [ + "gtest", + ], deps = [ ":test_service_impl", "//:gpr", @@ -110,40 +117,76 @@ grpc_cc_library( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], +) + +grpc_cc_test( + name = "server_early_return_test", + srcs = ["server_early_return_test.cc"], external_deps = [ "gtest", ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], ) grpc_cc_test( name = "end2end_test", deps = [ - ":end2end_test_lib" + ":end2end_test_lib", ], ) grpc_cc_test( - name = "filter_end2end_test", - srcs = ["filter_end2end_test.cc"], + name = "exception_test", + srcs = ["exception_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:gpr", "//:grpc", "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], +) + +grpc_cc_test( + name = "filter_end2end_test", + srcs = ["filter_end2end_test.cc"], external_deps = [ "gtest", ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], ) grpc_cc_test( name = "generic_end2end_test", srcs = ["generic_end2end_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -155,14 +198,35 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], +) + +grpc_cc_test( + name = "health_service_end2end_test", + srcs = ["health_service_end2end_test.cc"], external_deps = [ "gtest", ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/health/v1:health_proto", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], ) grpc_cc_test( name = "hybrid_end2end_test", srcs = ["hybrid_end2end_test.cc"], + external_deps = [ + "gtest", + ], deps = [ ":test_service_impl", "//:gpr", @@ -175,14 +239,15 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "mock_test", srcs = ["mock_test.cc"], + external_deps = [ + "gmock", + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -195,15 +260,32 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], +) + +grpc_cc_test( + name = "nonblocking_test", + srcs = ["nonblocking_test.cc"], external_deps = [ - "gmock", "gtest", ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], ) grpc_cc_test( name = "client_lb_end2end_test", srcs = ["client_lb_end2end_test.cc"], + external_deps = [ + "gtest", + ], deps = [ ":test_service_impl", "//:gpr", @@ -216,37 +298,38 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "grpclb_end2end_test", srcs = ["grpclb_end2end_test.cc"], + external_deps = [ + "gmock", + "gtest", + ], deps = [ ":test_service_impl", "//:gpr", "//:grpc", "//:grpc++", + "//:grpc_resolver_fake", "//src/proto/grpc/lb/v1:load_balancer_proto", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//:grpc_resolver_fake", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gmock", - "gtest", - ], ) grpc_cc_test( name = "proto_server_reflection_test", srcs = ["proto_server_reflection_test.cc"], + external_deps = [ + "gtest", + "gflags", + ], deps = [ ":test_service_impl", "//:gpr", @@ -261,15 +344,14 @@ grpc_cc_test( "//test/cpp/util:grpc++_proto_reflection_desc_db", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - "gflags", - ], ) grpc_cc_test( name = "server_builder_plugin_test", srcs = ["server_builder_plugin_test.cc"], + external_deps = [ + "gtest", + ], deps = [ ":test_service_impl", "//:gpr", @@ -282,14 +364,17 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "server_crash_test", srcs = ["server_crash_test.cc"], + data = [ + ":server_crash_test_client", + ], + external_deps = [ + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -301,17 +386,16 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], - data = [ - ":server_crash_test_client", - ], ) grpc_cc_binary( name = "server_crash_test_client", + testonly = True, srcs = ["server_crash_test_client.cc"], + external_deps = [ + "gflags", + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -323,15 +407,14 @@ grpc_cc_binary( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gflags", - "gtest", - ], ) grpc_cc_test( name = "shutdown_test", srcs = ["shutdown_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -343,14 +426,14 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "streaming_throughput_test", srcs = ["streaming_throughput_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -362,14 +445,14 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "thread_stress_test", srcs = ["thread_stress_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:gpr", "//:grpc", @@ -381,7 +464,4 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - external_deps = [ - "gtest", - ], ) diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 1ea087e706..e8d2325b7d 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -20,22 +20,21 @@ #include <memory> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/ext/health_check_service_server_builder_option.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <grpc/support/tls.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/lib/gpr/env.h" +#include "src/core/lib/gpr/tls.h" #include "src/core/lib/iomgr/port.h" -#include "src/core/lib/support/env.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" @@ -46,62 +45,22 @@ #include <gtest/gtest.h> -#ifdef GRPC_POSIX_SOCKET -#include "src/core/lib/iomgr/ev_posix.h" -#endif - using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; using grpc::testing::kTlsCredentialsType; using std::chrono::system_clock; -GPR_TLS_DECL(g_is_async_end2end_test); - namespace grpc { namespace testing { namespace { -void* tag(int i) { return (void*)(intptr_t)i; } +void* tag(int i) { return (void*)static_cast<intptr_t>(i); } int detag(void* p) { return static_cast<int>(reinterpret_cast<intptr_t>(p)); } -#ifdef GRPC_POSIX_SOCKET -static int maybe_assert_non_blocking_poll(struct pollfd* pfds, nfds_t nfds, - int timeout) { - if (gpr_tls_get(&g_is_async_end2end_test)) { - GPR_ASSERT(timeout == 0); - } - return poll(pfds, nfds, timeout); -} - -class PollOverride { - public: - PollOverride(grpc_poll_function_type f) { - prev_ = grpc_poll_function; - grpc_poll_function = f; - } - - ~PollOverride() { grpc_poll_function = prev_; } - - private: - grpc_poll_function_type prev_; -}; - -class PollingOverrider : public PollOverride { - public: - explicit PollingOverrider(bool allow_blocking) - : PollOverride(allow_blocking ? poll : maybe_assert_non_blocking_poll) {} -}; -#else -class PollingOverrider { - public: - explicit PollingOverrider(bool allow_blocking) {} -}; -#endif - class Verifier { public: - explicit Verifier(bool spin) : spin_(spin), lambda_run_(false) {} + 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); @@ -129,17 +88,7 @@ class Verifier { int Next(CompletionQueue* cq, bool ignore_ok) { bool ok; void* got_tag; - if (spin_) { - for (;;) { - auto r = cq->AsyncNext(&got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME)); - if (r == CompletionQueue::TIMEOUT) continue; - if (r == CompletionQueue::GOT_EVENT) break; - gpr_log(GPR_ERROR, "unexpected result from AsyncNext"); - abort(); - } - } else { - EXPECT_TRUE(cq->Next(&got_tag, &ok)); - } + EXPECT_TRUE(cq->Next(&got_tag, &ok)); GotTag(got_tag, ok, ignore_ok); return detag(got_tag); } @@ -175,34 +124,14 @@ class Verifier { if (expectations_.empty()) { bool ok; void* got_tag; - if (spin_) { - while (std::chrono::system_clock::now() < deadline) { - EXPECT_EQ( - cq->AsyncNext(&got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME)), - CompletionQueue::TIMEOUT); - } - } else { - EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), - CompletionQueue::TIMEOUT); - } + EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), + CompletionQueue::TIMEOUT); } else { while (!expectations_.empty()) { bool ok; void* got_tag; - if (spin_) { - for (;;) { - GPR_ASSERT(std::chrono::system_clock::now() < deadline); - auto r = - cq->AsyncNext(&got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME)); - if (r == CompletionQueue::TIMEOUT) continue; - if (r == CompletionQueue::GOT_EVENT) break; - gpr_log(GPR_ERROR, "unexpected result from AsyncNext"); - abort(); - } - } else { - EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), - CompletionQueue::GOT_EVENT); - } + EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), + CompletionQueue::GOT_EVENT); GotTag(got_tag, ok, false); } } @@ -217,33 +146,14 @@ class Verifier { if (expectations_.empty()) { bool ok; void* got_tag; - if (spin_) { - while (std::chrono::system_clock::now() < deadline) { - EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda), - CompletionQueue::TIMEOUT); - } - } else { - EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda), - CompletionQueue::TIMEOUT); - } + EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda), + CompletionQueue::TIMEOUT); } else { while (!expectations_.empty()) { bool ok; void* got_tag; - if (spin_) { - for (;;) { - GPR_ASSERT(std::chrono::system_clock::now() < deadline); - auto r = DoOnceThenAsyncNext( - cq, &got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME), lambda); - if (r == CompletionQueue::TIMEOUT) continue; - if (r == CompletionQueue::GOT_EVENT) break; - gpr_log(GPR_ERROR, "unexpected result from AsyncNext"); - abort(); - } - } else { - EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda), - CompletionQueue::GOT_EVENT); - } + EXPECT_EQ(DoOnceThenAsyncNext(cq, &got_tag, &ok, deadline, lambda), + CompletionQueue::GOT_EVENT); GotTag(got_tag, ok, false); } } @@ -281,7 +191,6 @@ class Verifier { std::map<void*, bool> expectations_; std::map<void*, MaybeExpect> maybe_expectations_; - bool spin_; bool lambda_run_; }; @@ -307,15 +216,13 @@ class ServerBuilderSyncPluginDisabler : public ::grpc::ServerBuilderOption { class TestScenario { public: - TestScenario(bool non_block, bool inproc_stub, const grpc::string& creds_type, - bool hcs, const grpc::string& content) - : disable_blocking(non_block), - inproc(inproc_stub), + TestScenario(bool inproc_stub, const grpc::string& creds_type, bool hcs, + const grpc::string& content) + : inproc(inproc_stub), health_check_service(hcs), credentials_type(creds_type), message_content(content) {} void Log() const; - bool disable_blocking; bool inproc; bool health_check_service; const grpc::string credentials_type; @@ -324,9 +231,7 @@ class TestScenario { static std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { - return out << "TestScenario{disable_blocking=" - << (scenario.disable_blocking ? "true" : "false") - << ", inproc=" << (scenario.inproc ? "true" : "false") + return out << "TestScenario{inproc=" << (scenario.inproc ? "true" : "false") << ", credentials='" << scenario.credentials_type << ", health_check_service=" << (scenario.health_check_service ? "true" : "false") @@ -346,19 +251,14 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> { AsyncEnd2endTest() { GetParam().Log(); } void SetUp() override { - poll_overrider_.reset(new PollingOverrider(!GetParam().disable_blocking)); - port_ = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port_; // Setup server BuildAndStartServer(); - - gpr_tls_set(&g_is_async_end2end_test, 1); } void TearDown() override { - gpr_tls_set(&g_is_async_end2end_test, 0); server_->Shutdown(); void* ignored_tag; bool ignored_ok; @@ -366,7 +266,6 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> { while (cq_->Next(&ignored_tag, &ignored_ok)) ; stub_.reset(); - poll_overrider_.reset(); grpc_recycle_unused_port(port_); } @@ -420,16 +319,14 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> { service_->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(), cq_.get(), tag(2)); - Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + 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)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); + Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -443,8 +340,6 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> { HealthCheck health_check_; std::ostringstream server_address_; int port_; - - std::unique_ptr<PollingOverrider> poll_overrider_; }; TEST_P(AsyncEnd2endTest, SimpleRpc) { @@ -500,7 +395,6 @@ TEST_P(AsyncEnd2endTest, WaitAndShutdownTest) { ResetStub(); SendRpc(1); EXPECT_EQ(0, notify); - gpr_tls_set(&g_is_async_end2end_test, 0); server_->Shutdown(); wait_thread.join(); EXPECT_EQ(1, notify); @@ -536,24 +430,20 @@ TEST_P(AsyncEnd2endTest, AsyncNextRpc) { std::chrono::system_clock::now()); std::chrono::system_clock::time_point time_limit( std::chrono::system_clock::now() + std::chrono::seconds(10)); - Verifier(GetParam().disable_blocking).Verify(cq_.get(), time_now); - Verifier(GetParam().disable_blocking).Verify(cq_.get(), time_now); + 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(GetParam().disable_blocking) - .Expect(2, true) - .Verify(cq_.get(), time_limit); + 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)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get(), std::chrono::system_clock::time_point::max()); + 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()); @@ -581,33 +471,25 @@ TEST_P(AsyncEnd2endTest, DoThenAsyncNextRpc) { std::chrono::system_clock::now()); std::chrono::system_clock::time_point time_limit( std::chrono::system_clock::now() + std::chrono::seconds(10)); - Verifier(GetParam().disable_blocking).Verify(cq_.get(), time_now); - Verifier(GetParam().disable_blocking).Verify(cq_.get(), time_now); + 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]() { - gpr_log(GPR_ERROR, "CALLED"); 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(GetParam().disable_blocking) - .Expect(2, true) - .Verify(cq_.get(), time_limit, lambda_2); + Verifier().Expect(2, true).Verify(cq_.get(), time_limit, lambda_2); EXPECT_EQ(send_request.message(), recv_request.message()); - auto recv_resp_ptr = &recv_response; - auto status_ptr = &recv_status; send_response.set_message(recv_request.message()); - auto lambda_3 = [&, this, resp_writer_ptr, send_response]() { + auto lambda_3 = [resp_writer_ptr, send_response]() { resp_writer_ptr->Finish(send_response, Status::OK, tag(3)); }; - response_reader->Finish(recv_resp_ptr, status_ptr, tag(4)); - Verifier(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get(), std::chrono::system_clock::time_point::max(), - lambda_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()); @@ -633,41 +515,26 @@ TEST_P(AsyncEnd2endTest, SimpleClientStreaming) { service_->RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), tag(2)); - Verifier(GetParam().disable_blocking) - .Expect(2, true) - .Expect(1, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(5, true) - .Expect(6, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(7, true) - .Expect(8, false) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(9, true) - .Expect(10, true) - .Verify(cq_.get()); + Verifier().Expect(9, true).Expect(10, true).Verify(cq_.get()); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -699,38 +566,26 @@ TEST_P(AsyncEnd2endTest, SimpleClientStreamingWithCoalescingApi) { bool seen3 = false; - Verifier(GetParam().disable_blocking) - .Expect(2, true) - .ExpectMaybe(3, true, &seen3) - .Verify(cq_.get()); + Verifier().Expect(2, true).ExpectMaybe(3, true, &seen3).Verify(cq_.get()); srv_stream.Read(&recv_request, tag(4)); - Verifier(GetParam().disable_blocking) - .ExpectUnless(3, true, seen3) - .Expect(4, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(5, true) - .Expect(6, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking).Expect(7, false).Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(8, true) - .Expect(9, true) - .Verify(cq_.get()); + Verifier().Expect(8, true).Expect(9, true).Verify(cq_.get()); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -756,38 +611,26 @@ TEST_P(AsyncEnd2endTest, SimpleServerStreaming) { service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, cq_.get(), cq_.get(), tag(2)); - Verifier(GetParam().disable_blocking) - .Expect(1, true) - .Expect(2, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(5, true) - .Expect(6, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(7, true) - .Expect(8, false) - .Verify(cq_.get()); + Verifier().Expect(7, true).Expect(8, false).Verify(cq_.get()); cli_stream->Finish(&recv_status, tag(9)); - Verifier(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get()); + Verifier().Expect(9, true).Verify(cq_.get()); EXPECT_TRUE(recv_status.ok()); } @@ -812,34 +655,25 @@ TEST_P(AsyncEnd2endTest, SimpleServerStreamingWithCoalescingApiWAF) { service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, cq_.get(), cq_.get(), tag(2)); - Verifier(GetParam().disable_blocking) - .Expect(1, true) - .Expect(2, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(5, true) - .Expect(6, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking).Expect(7, false).Verify(cq_.get()); + Verifier().Expect(7, false).Verify(cq_.get()); cli_stream->Finish(&recv_status, tag(8)); - Verifier(GetParam().disable_blocking).Expect(8, true).Verify(cq_.get()); + Verifier().Expect(8, true).Verify(cq_.get()); EXPECT_TRUE(recv_status.ok()); } @@ -864,36 +698,26 @@ TEST_P(AsyncEnd2endTest, SimpleServerStreamingWithCoalescingApiWL) { service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, cq_.get(), cq_.get(), tag(2)); - Verifier(GetParam().disable_blocking) - .Expect(1, true) - .Expect(2, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(5, true) - .Expect(6, true) - .Expect(7, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking).Expect(8, false).Verify(cq_.get()); + Verifier().Expect(8, false).Verify(cq_.get()); cli_stream->Finish(&recv_status, tag(9)); - Verifier(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get()); + Verifier().Expect(9, true).Verify(cq_.get()); EXPECT_TRUE(recv_status.ok()); } @@ -918,41 +742,26 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreaming) { service_->RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), tag(2)); - Verifier(GetParam().disable_blocking) - .Expect(1, true) - .Expect(2, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(5, true) - .Expect(6, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(7, true) - .Expect(8, false) - .Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(9, true) - .Expect(10, true) - .Verify(cq_.get()); + Verifier().Expect(9, true).Expect(10, true).Verify(cq_.get()); EXPECT_TRUE(recv_status.ok()); } @@ -982,33 +791,24 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWAF) { bool seen3 = false; - Verifier(GetParam().disable_blocking) - .Expect(2, true) - .ExpectMaybe(3, true, &seen3) - .Verify(cq_.get()); + Verifier().Expect(2, true).ExpectMaybe(3, true, &seen3).Verify(cq_.get()); srv_stream.Read(&recv_request, tag(4)); - Verifier(GetParam().disable_blocking) - .ExpectUnless(3, true, seen3) - .Expect(4, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking).Expect(5, false).Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(6, true) - .Expect(7, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking).Expect(8, true).Verify(cq_.get()); + Verifier().Expect(8, true).Verify(cq_.get()); EXPECT_TRUE(recv_status.ok()); } @@ -1038,35 +838,25 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWL) { bool seen3 = false; - Verifier(GetParam().disable_blocking) - .Expect(2, true) - .ExpectMaybe(3, true, &seen3) - .Verify(cq_.get()); + Verifier().Expect(2, true).ExpectMaybe(3, true, &seen3).Verify(cq_.get()); srv_stream.Read(&recv_request, tag(4)); - Verifier(GetParam().disable_blocking) - .ExpectUnless(3, true, seen3) - .Expect(4, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking).Expect(5, false).Verify(cq_.get()); + 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(GetParam().disable_blocking) - .Expect(6, true) - .Expect(7, true) - .Expect(8, true) - .Verify(cq_.get()); + 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(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get()); + Verifier().Expect(9, true).Verify(cq_.get()); EXPECT_TRUE(recv_status.ok()); } @@ -1095,10 +885,11 @@ TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) { 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(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + Verifier().Expect(2, true).Verify(cq_.get()); EXPECT_EQ(send_request.message(), recv_request.message()); auto client_initial_metadata = srv_ctx.client_metadata(); EXPECT_EQ(meta1.second, @@ -1111,11 +902,7 @@ TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) { send_response.set_message(recv_request.message()); response_writer.Finish(send_response, Status::OK, tag(3)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); + Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -1140,18 +927,16 @@ TEST_P(AsyncEnd2endTest, ServerInitialMetadataRpc) { 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(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + 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(GetParam().disable_blocking).Expect(3, true).Verify(cq_.get()); - - response_reader->ReadInitialMetadata(tag(4)); - Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get()); + Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); auto server_initial_metadata = cli_ctx.GetServerInitialMetadata(); EXPECT_EQ(meta1.second, ToString(server_initial_metadata.find(meta1.first)->second)); @@ -1162,10 +947,7 @@ TEST_P(AsyncEnd2endTest, ServerInitialMetadataRpc) { 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(GetParam().disable_blocking) - .Expect(5, true) - .Expect(6, true) - .Verify(cq_.get()); + Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -1190,24 +972,21 @@ TEST_P(AsyncEnd2endTest, ServerTrailingMetadataRpc) { 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(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + Verifier().Expect(2, true).Verify(cq_.get()); EXPECT_EQ(send_request.message(), recv_request.message()); response_writer.SendInitialMetadata(tag(3)); - Verifier(GetParam().disable_blocking).Expect(3, true).Verify(cq_.get()); + 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)); - response_reader->Finish(&recv_response, &recv_status, tag(5)); - Verifier(GetParam().disable_blocking) - .Expect(4, true) - .Expect(5, true) - .Verify(cq_.get()); + Verifier().Expect(4, true).Expect(5, true).Verify(cq_.get()); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -1253,10 +1032,11 @@ TEST_P(AsyncEnd2endTest, MetadataRpc) { 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(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + Verifier().Expect(2, true).Verify(cq_.get()); EXPECT_EQ(send_request.message(), recv_request.message()); auto client_initial_metadata = srv_ctx.client_metadata(); EXPECT_EQ(meta1.second, @@ -1268,9 +1048,7 @@ TEST_P(AsyncEnd2endTest, MetadataRpc) { srv_ctx.AddInitialMetadata(meta3.first, meta3.second); srv_ctx.AddInitialMetadata(meta4.first, meta4.second); response_writer.SendInitialMetadata(tag(3)); - Verifier(GetParam().disable_blocking).Expect(3, true).Verify(cq_.get()); - response_reader->ReadInitialMetadata(tag(4)); - Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get()); + Verifier().Expect(3, true).Expect(4, true).Verify(cq_.get()); auto server_initial_metadata = cli_ctx.GetServerInitialMetadata(); EXPECT_EQ(meta3.second, ToString(server_initial_metadata.find(meta3.first)->second)); @@ -1284,10 +1062,7 @@ TEST_P(AsyncEnd2endTest, MetadataRpc) { response_writer.Finish(send_response, Status::OK, tag(5)); response_reader->Finish(&recv_response, &recv_status, tag(6)); - Verifier(GetParam().disable_blocking) - .Expect(5, true) - .Expect(6, true) - .Verify(cq_.get()); + Verifier().Expect(5, true).Expect(6, true).Verify(cq_.get()); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -1316,21 +1091,19 @@ TEST_P(AsyncEnd2endTest, ServerCheckCancellation) { 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(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + Verifier().Expect(2, true).Verify(cq_.get()); EXPECT_EQ(send_request.message(), recv_request.message()); cli_ctx.TryCancel(); - Verifier(GetParam().disable_blocking).Expect(5, true).Verify(cq_.get()); + Verifier().Expect(5, true).Expect(4, true).Verify(cq_.get()); EXPECT_TRUE(srv_ctx.IsCancelled()); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get()); - EXPECT_EQ(StatusCode::CANCELLED, recv_status.error_code()); } @@ -1351,22 +1124,18 @@ TEST_P(AsyncEnd2endTest, ServerCheckDone) { 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(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + 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)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Expect(5, true) - .Verify(cq_.get()); + 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()); @@ -1393,7 +1162,7 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) { stub->AsyncUnimplemented(&cli_ctx, send_request, cq_.get())); response_reader->Finish(&recv_response, &recv_status, tag(4)); - Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get()); + Verifier().Expect(4, true).Verify(cq_.get()); EXPECT_EQ(StatusCode::UNIMPLEMENTED, recv_status.error_code()); EXPECT_EQ("", recv_status.error_message()); @@ -1447,10 +1216,8 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { srv_ctx.AsyncNotifyWhenDone(tag(11)); service_->RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), tag(2)); - std::thread t1([this, &cli_cq] { - Verifier(GetParam().disable_blocking).Expect(1, true).Verify(&cli_cq); - }); - Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + 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; @@ -1458,7 +1225,7 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { if (server_try_cancel == CANCEL_BEFORE_PROCESSING) { srv_ctx.TryCancel(); - Verifier(GetParam().disable_blocking).Expect(11, true).Verify(cq_.get()); + Verifier().Expect(11, true).Verify(cq_.get()); EXPECT_TRUE(srv_ctx.IsCancelled()); // Since cancellation is done before server reads any results, we know @@ -1473,19 +1240,19 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { (server_try_cancel == CANCEL_BEFORE_PROCESSING); std::thread cli_thread([&cli_cq, &cli_stream, &expected_client_cq_result, - &ignore_client_cq_result, this] { + &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 " + grpc::to_string(tag_idx)); cli_stream->Write(send_request, tag(tag_idx)); - Verifier(GetParam().disable_blocking) + 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(GetParam().disable_blocking) + Verifier() .Expect(6, expected_client_cq_result) .Verify(&cli_cq, ignore_client_cq_result); }); @@ -1494,7 +1261,7 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { bool want_done_tag = false; std::thread* server_try_cancel_thd = nullptr; - auto verif = Verifier(GetParam().disable_blocking); + auto verif = Verifier(); if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = @@ -1554,11 +1321,11 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { // 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(GetParam().disable_blocking).Expect(9, false).Verify(cq_.get()); + Verifier().Expect(9, false).Verify(cq_.get()); // Client will see the cancellation cli_stream->Finish(&recv_status, tag(10)); - Verifier(GetParam().disable_blocking).Expect(10, true).Verify(&cli_cq); + Verifier().Expect(10, true).Verify(&cli_cq); EXPECT_FALSE(recv_status.ok()); EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code()); @@ -1604,10 +1371,8 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { service_->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, cq_.get(), cq_.get(), tag(2)); - std::thread t1([this, &cli_cq] { - Verifier(GetParam().disable_blocking).Expect(1, true).Verify(&cli_cq); - }); - Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); + 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()); @@ -1621,7 +1386,7 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { if (server_try_cancel == CANCEL_BEFORE_PROCESSING) { srv_ctx.TryCancel(); - Verifier(GetParam().disable_blocking).Expect(11, true).Verify(cq_.get()); + 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 @@ -1631,12 +1396,12 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { } std::thread cli_thread([&cli_cq, &cli_stream, &expected_client_cq_result, - &ignore_client_cq_result, this] { + &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(GetParam().disable_blocking) + Verifier() .Expect(tag_idx, expected_client_cq_result) .Verify(&cli_cq, ignore_client_cq_result); } @@ -1644,7 +1409,7 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { std::thread* server_try_cancel_thd = nullptr; - auto verif = Verifier(GetParam().disable_blocking); + auto verif = Verifier(); if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = @@ -1705,11 +1470,11 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { // Server finishes the stream (but the RPC is already cancelled) srv_stream.Finish(Status::CANCELLED, tag(9)); - Verifier(GetParam().disable_blocking).Expect(9, false).Verify(cq_.get()); + Verifier().Expect(9, false).Verify(cq_.get()); // Client will see the cancellation cli_stream->Finish(&recv_status, tag(10)); - Verifier(GetParam().disable_blocking).Expect(10, true).Verify(&cli_cq); + Verifier().Expect(10, true).Verify(&cli_cq); EXPECT_FALSE(recv_status.ok()); EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code()); @@ -1756,12 +1521,9 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { srv_ctx.AsyncNotifyWhenDone(tag(11)); service_->RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(), tag(2)); - Verifier(GetParam().disable_blocking) - .Expect(1, true) - .Expect(2, true) - .Verify(cq_.get()); + Verifier().Expect(1, true).Expect(2, true).Verify(cq_.get()); - auto verif = Verifier(GetParam().disable_blocking); + auto verif = Verifier(); // Client sends the first and the only message send_request.set_message("Ping"); @@ -1901,10 +1663,10 @@ class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest { // know that cq results are supposed to return false on server. srv_stream.Finish(Status::CANCELLED, tag(9)); - Verifier(GetParam().disable_blocking).Expect(9, false).Verify(cq_.get()); + Verifier().Expect(9, false).Verify(cq_.get()); cli_stream->Finish(&recv_status, tag(10)); - Verifier(GetParam().disable_blocking).Expect(10, true).Verify(cq_.get()); + Verifier().Expect(10, true).Verify(cq_.get()); EXPECT_FALSE(recv_status.ok()); EXPECT_EQ(grpc::StatusCode::CANCELLED, recv_status.error_code()); } @@ -1946,8 +1708,7 @@ TEST_P(AsyncEnd2endServerTryCancelTest, ServerBidiStreamingTryCancelAfter) { TestBidiStreamingServerCancel(CANCEL_AFTER_PROCESSING); } -std::vector<TestScenario> CreateTestScenarios(bool test_disable_blocking, - bool test_secure, +std::vector<TestScenario> CreateTestScenarios(bool test_secure, int test_big_limit) { std::vector<TestScenario> scenarios; std::vector<grpc::string> credentials_types; @@ -1985,14 +1746,10 @@ std::vector<TestScenario> CreateTestScenarios(bool test_disable_blocking, for (auto msg = messages.begin(); msg != messages.end(); msg++) { for (auto cred = credentials_types.begin(); cred != credentials_types.end(); ++cred) { - scenarios.emplace_back(false, false, *cred, health_check_service, *msg); - if (test_disable_blocking) { - scenarios.emplace_back(true, false, *cred, health_check_service, - *msg); - } + scenarios.emplace_back(false, *cred, health_check_service, *msg); } if (insec_ok()) { - scenarios.emplace_back(false, true, kInsecureCredentialsType, + scenarios.emplace_back(true, kInsecureCredentialsType, health_check_service, *msg); } } @@ -2001,12 +1758,10 @@ std::vector<TestScenario> CreateTestScenarios(bool test_disable_blocking, } INSTANTIATE_TEST_CASE_P(AsyncEnd2end, AsyncEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(true, true, - 1024))); + ::testing::ValuesIn(CreateTestScenarios(true, 1024))); INSTANTIATE_TEST_CASE_P(AsyncEnd2endServerTryCancel, AsyncEnd2endServerTryCancelTest, - ::testing::ValuesIn(CreateTestScenarios(false, false, - 0))); + ::testing::ValuesIn(CreateTestScenarios(false, 0))); } // namespace } // namespace testing @@ -2017,9 +1772,7 @@ int main(int argc, char** argv) { // ReconnectChannel test gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "100"); grpc_test_init(argc, argv); - gpr_tls_init(&g_is_async_end2end_test); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); - gpr_tls_destroy(&g_is_async_end2end_test); return ret; } diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc index f34b27511b..2a06f44c60 100644 --- a/test/cpp/end2end/client_crash_test.cc +++ b/test/cpp/end2end/client_crash_test.cc @@ -16,16 +16,15 @@ * */ -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.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" diff --git a/test/cpp/end2end/client_crash_test_server.cc b/test/cpp/end2end/client_crash_test_server.cc index 887504d308..cb4afd7167 100644 --- a/test/cpp/end2end/client_crash_test_server.cc +++ b/test/cpp/end2end/client_crash_test_server.cc @@ -21,10 +21,10 @@ #include <memory> #include <string> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.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" diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index e83a6e675e..eeec8e90bd 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -19,23 +19,28 @@ #include <algorithm> #include <memory> #include <mutex> +#include <random> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.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/thd.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 "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" -#include "src/core/lib/support/env.h" +#include "src/core/lib/backoff/backoff.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/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" @@ -48,10 +53,32 @@ using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; using std::chrono::system_clock; +// 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 { @@ -92,11 +119,11 @@ class ClientLbEnd2endTest : public ::testing::Test { } void SetUp() override { - response_generator_ = grpc_fake_resolver_response_generator_create(); + response_generator_ = + grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); } void TearDown() override { - grpc_fake_resolver_response_generator_unref(response_generator_); for (size_t i = 0; i < servers_.size(); ++i) { servers_[i]->Shutdown(); } @@ -111,8 +138,7 @@ class ClientLbEnd2endTest : public ::testing::Test { } } - void SetNextResolution(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; + grpc_channel_args* BuildFakeResults(const std::vector<int>& ports) { grpc_lb_addresses* addresses = grpc_lb_addresses_create(ports.size(), nullptr); for (size_t i = 0; i < ports.size(); ++i) { @@ -128,53 +154,82 @@ class ClientLbEnd2endTest : public ::testing::Test { } const grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); - grpc_channel_args* fake_result = + grpc_channel_args* fake_results = grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1); - grpc_fake_resolver_response_generator_set_response(response_generator_, - fake_result); - grpc_channel_args_destroy(fake_result); grpc_lb_addresses_destroy(addresses); + return fake_results; + } + + void SetNextResolution(const std::vector<int>& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args* fake_results = BuildFakeResults(ports); + response_generator_->SetResponse(fake_results); + grpc_channel_args_destroy(fake_results); + } + + void SetNextResolutionUponError(const std::vector<int>& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args* fake_results = BuildFakeResults(ports); + response_generator_->SetReresolutionResponse(fake_results); + grpc_channel_args_destroy(fake_results); } - void ResetStub(const grpc::string& lb_policy_name = "") { - ChannelArguments args; + std::vector<int> GetServersPorts() { + std::vector<int> ports; + for (const auto& server : servers_) ports.push_back(server->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( + const grpc::string& lb_policy_name, + ChannelArguments args = ChannelArguments()) { if (lb_policy_name.size() > 0) { args.SetLoadBalancingPolicyName(lb_policy_name); } // else, default to pick first args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_); - args.SetInt("grpc.testing.fixed_reconnect_backoff_ms", 2000); - std::ostringstream uri; - uri << "fake:///"; - for (size_t i = 0; i < servers_.size() - 1; ++i) { - uri << "127.0.0.1:" << servers_[i]->port_ << ","; - } - uri << "127.0.0.1:" << servers_[servers_.size() - 1]->port_; - channel_ = - CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); + response_generator_.get()); + return CreateCustomChannel("fake:///", InsecureChannelCredentials(), args); } - bool SendRpc(EchoResponse* response = nullptr) { + bool SendRpc( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + EchoResponse* response = nullptr, int timeout_ms = 1000, + Status* result = nullptr) { const bool local_response = (response == nullptr); if (local_response) response = new EchoResponse; EchoRequest request; request.set_message(kRequestMessage_); ClientContext context; - Status status = stub_->Echo(&context, request, response); + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + Status status = stub->Echo(&context, request, response); + if (result != nullptr) *result = status; if (local_response) delete response; return status.ok(); } - void CheckRpcSendOk() { + void CheckRpcSendOk( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + const grpc_core::DebugLocation& location) { EchoResponse response; - const bool success = SendRpc(&response); - EXPECT_TRUE(success); - EXPECT_EQ(response.message(), kRequestMessage_); + Status status; + const bool success = SendRpc(stub, &response, 2000, &status); + 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 bool success = SendRpc(); + void CheckRpcSendFailure( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub) { + const bool success = SendRpc(stub); EXPECT_FALSE(success); } @@ -213,7 +268,7 @@ class ClientLbEnd2endTest : public ::testing::Test { } void Shutdown(bool join = true) { - server_->Shutdown(); + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); if (join) thread_->join(); } }; @@ -222,9 +277,11 @@ class ClientLbEnd2endTest : public ::testing::Test { for (const auto& server : servers_) server->service_.ResetCounters(); } - void WaitForServer(size_t server_idx) { + void WaitForServer( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + size_t server_idx, const grpc_core::DebugLocation& location) { do { - CheckRpcSendOk(); + CheckRpcSendOk(stub, location); } while (servers_[server_idx]->service_.request_count() == 0); ResetCounters(); } @@ -255,10 +312,10 @@ class ClientLbEnd2endTest : public ::testing::Test { } const grpc::string server_host_; - std::shared_ptr<Channel> channel_; std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; std::vector<std::unique_ptr<ServerData>> servers_; - grpc_fake_resolver_response_generator* response_generator_; + grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> + response_generator_; const grpc::string kRequestMessage_; }; @@ -266,14 +323,15 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub(); // implicit pick first + auto channel = BuildChannel(""); // test that pick first is the default. + auto stub = BuildStub(channel); std::vector<int> ports; for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); } SetNextResolution(ports); for (size_t i = 0; i < servers_.size(); ++i) { - CheckRpcSendOk(); + CheckRpcSendOk(stub, DEBUG_LOCATION); } // All requests should have gone to a single server. bool found = false; @@ -287,21 +345,78 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { } EXPECT_TRUE(found); // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); + EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); +} + +TEST_F(ClientLbEnd2endTest, PickFirstBackOffInitialReconnect) { + ChannelArguments args; + constexpr int kInitialBackOffMs = 100; + args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); + const std::vector<int> ports = {grpc_pick_unused_port_or_die()}; + const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + 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 = {grpc_pick_unused_port_or_die()}; + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + 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, PickFirstUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub(); // implicit pick first + auto channel = BuildChannel("pick_first"); + auto stub = BuildStub(channel); + std::vector<int> ports; // Perform one RPC against the first server. ports.emplace_back(servers_[0]->port_); SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET [0] *******"); - CheckRpcSendOk(); + CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(servers_[0]->service_.request_count(), 1); // An empty update will result in the channel going into TRANSIENT_FAILURE. @@ -310,7 +425,7 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { gpr_log(GPR_INFO, "****** SET none *******"); grpc_connectivity_state channel_state; do { - channel_state = channel_->GetState(true /* try to connect */); + channel_state = channel->GetState(true /* try to connect */); } while (channel_state == GRPC_CHANNEL_READY); GPR_ASSERT(channel_state != GRPC_CHANNEL_READY); servers_[0]->service_.ResetCounters(); @@ -320,7 +435,7 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { ports.emplace_back(servers_[1]->port_); SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET [1] *******"); - WaitForServer(1); + WaitForServer(stub, 1, DEBUG_LOCATION); EXPECT_EQ(servers_[0]->service_.request_count(), 0); // And again for servers_[2] @@ -328,26 +443,28 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { ports.emplace_back(servers_[2]->port_); SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET [2] *******"); - WaitForServer(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()); + EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub(); // implicit pick first + auto channel = BuildChannel("pick_first"); + auto stub = BuildStub(channel); + std::vector<int> ports; // Perform one RPC against the first server. ports.emplace_back(servers_[0]->port_); SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET [0] *******"); - CheckRpcSendOk(); + CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(servers_[0]->service_.request_count(), 1); servers_[0]->service_.ResetCounters(); @@ -357,20 +474,21 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { ports.emplace_back(servers_[0]->port_); SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET superset *******"); - CheckRpcSendOk(); + CheckRpcSendOk(stub, DEBUG_LOCATION); // We stick to the previously connected server. - WaitForServer(0); + 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()); + EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub(); // implicit pick first + auto channel = BuildChannel("pick_first"); + auto stub = BuildStub(channel); std::vector<int> ports; for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); @@ -379,20 +497,22 @@ TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { grpc_subchannel_index_test_only_set_force_creation(force_creation); gpr_log(GPR_INFO, "Force subchannel creation: %d", force_creation); for (size_t i = 0; i < 1000; ++i) { - std::random_shuffle(ports.begin(), ports.end()); + std::shuffle(ports.begin(), ports.end(), + std::mt19937(std::random_device()())); SetNextResolution(ports); - if (i % 10 == 0) CheckRpcSendOk(); + if (i % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION); } } // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); + EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub("round_robin"); + auto channel = BuildChannel("round_robin"); + auto stub = BuildStub(channel); std::vector<int> ports; for (const auto& server : servers_) { ports.emplace_back(server->port_); @@ -400,15 +520,15 @@ TEST_F(ClientLbEnd2endTest, RoundRobin) { SetNextResolution(ports); // Wait until all backends are ready. do { - CheckRpcSendOk(); + 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(servers_.size() - 1); + WaitForServer(stub, servers_.size() - 1, DEBUG_LOCATION); std::vector<int> connection_order; for (size_t i = 0; i < servers_.size(); ++i) { - CheckRpcSendOk(); + CheckRpcSendOk(stub, DEBUG_LOCATION); UpdateConnectionOrder(servers_, &connection_order); } // Backends should be iterated over in the order in which the addresses were @@ -416,22 +536,23 @@ TEST_F(ClientLbEnd2endTest, RoundRobin) { 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()); + EXPECT_EQ("round_robin", channel->GetLoadBalancingPolicyName()); } TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub("round_robin"); + auto channel = BuildChannel("round_robin"); + auto stub = BuildStub(channel); std::vector<int> ports; // Start with a single server. ports.emplace_back(servers_[0]->port_); SetNextResolution(ports); - WaitForServer(0); + WaitForServer(stub, 0, DEBUG_LOCATION); // Send RPCs. They should all go servers_[0] - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(); + 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()); @@ -445,9 +566,9 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { // Wait until update has been processed, as signaled by the second backend // receiving a request. EXPECT_EQ(0, servers_[1]->service_.request_count()); - WaitForServer(1); + WaitForServer(stub, 1, DEBUG_LOCATION); - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(); + 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()); @@ -457,9 +578,9 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { ports.clear(); ports.emplace_back(servers_[2]->port_); SetNextResolution(ports); - WaitForServer(2); + WaitForServer(stub, 2, DEBUG_LOCATION); - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(); + 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()); @@ -471,12 +592,12 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[2]->port_); SetNextResolution(ports); - WaitForServer(0); - WaitForServer(1); - WaitForServer(2); + 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(); + 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()); @@ -486,7 +607,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { SetNextResolution(ports); grpc_connectivity_state channel_state; do { - channel_state = channel_->GetState(true /* try to connect */); + channel_state = channel->GetState(true /* try to connect */); } while (channel_state == GRPC_CHANNEL_READY); GPR_ASSERT(channel_state != GRPC_CHANNEL_READY); servers_[0]->service_.ResetCounters(); @@ -495,26 +616,27 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { ports.clear(); ports.emplace_back(servers_[1]->port_); SetNextResolution(ports); - WaitForServer(1); - channel_state = channel_->GetState(false /* try to connect */); + WaitForServer(stub, 1, DEBUG_LOCATION); + channel_state = channel->GetState(false /* try to connect */); GPR_ASSERT(channel_state == GRPC_CHANNEL_READY); // Check LB policy name for the channel. - EXPECT_EQ("round_robin", channel_->GetLoadBalancingPolicyName()); + EXPECT_EQ("round_robin", channel->GetLoadBalancingPolicyName()); } TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) { const int kNumServers = 3; StartServers(kNumServers); - ResetStub("round_robin"); + auto channel = BuildChannel("round_robin"); + auto stub = BuildStub(channel); std::vector<int> ports; // Start with a single server. ports.emplace_back(servers_[0]->port_); SetNextResolution(ports); - WaitForServer(0); + WaitForServer(stub, 0, DEBUG_LOCATION); // Send RPCs. They should all go to servers_[0] - for (size_t i = 0; i < 10; ++i) SendRpc(); + 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()); @@ -525,11 +647,11 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) { ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[2]->port_); SetNextResolution(ports); - WaitForServer(0); - WaitForServer(2); + 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(); + 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()); } @@ -538,18 +660,20 @@ TEST_F(ClientLbEnd2endTest, RoundRobinManyUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub("round_robin"); + auto channel = BuildChannel("round_robin"); + auto stub = BuildStub(channel); std::vector<int> ports; for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); } for (size_t i = 0; i < 1000; ++i) { - std::random_shuffle(ports.begin(), ports.end()); + std::shuffle(ports.begin(), ports.end(), + std::mt19937(std::random_device()())); SetNextResolution(ports); - if (i % 10 == 0) CheckRpcSendOk(); + if (i % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION); } // Check LB policy name for the channel. - EXPECT_EQ("round_robin", channel_->GetLoadBalancingPolicyName()); + EXPECT_EQ("round_robin", channel->GetLoadBalancingPolicyName()); } TEST_F(ClientLbEnd2endTest, RoundRobinConcurrentUpdates) { @@ -560,16 +684,21 @@ TEST_F(ClientLbEnd2endTest, RoundRobinConcurrentUpdates) { TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { // Start servers and send one RPC per server. const int kNumServers = 3; - std::vector<int> ports; + std::vector<int> first_ports; + std::vector<int> second_ports; for (int i = 0; i < kNumServers; ++i) { - ports.push_back(grpc_pick_unused_port_or_die()); + first_ports.push_back(grpc_pick_unused_port_or_die()); } - StartServers(kNumServers, ports); - ResetStub("round_robin"); - SetNextResolution(ports); + for (int i = 0; i < kNumServers; ++i) { + second_ports.push_back(grpc_pick_unused_port_or_die()); + } + StartServers(kNumServers, first_ports); + auto channel = BuildChannel("round_robin"); + auto stub = BuildStub(channel); + SetNextResolution(first_ports); // Send a number of RPCs, which succeed. for (size_t i = 0; i < 100; ++i) { - CheckRpcSendOk(); + CheckRpcSendOk(stub, DEBUG_LOCATION); } // Kill all servers gpr_log(GPR_INFO, "****** ABOUT TO KILL SERVERS *******"); @@ -579,23 +708,70 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { 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(); + for (size_t i = 0; i < servers_.size(); ++i) CheckRpcSendFailure(stub); gpr_log(GPR_INFO, "****** DOOMED REQUESTS SENT *******"); - // Bring servers back up on the same port (we aren't recreating the channel). + // 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, ports); + StartServers(kNumServers, second_ports); + // Don't notify of the update. Wait for the LB policy's re-resolution to + // "pull" the new ports. + 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()) break; + if (SendRpc(stub)) break; now = gpr_now(GPR_CLOCK_MONOTONIC); } GPR_ASSERT(gpr_time_cmp(deadline, now) > 0); } +TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { + const int kNumServers = 3; + StartServers(kNumServers); + const auto ports = GetServersPorts(); + auto channel = BuildChannel("round_robin"); + auto stub = BuildStub(channel); + 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(true); + // 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. + servers_[0].reset(new ServerData(server_host_, ports[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); +} + } // namespace } // namespace testing } // namespace grpc diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 4c8dfe0f40..60238e930d 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -19,24 +19,23 @@ #include <mutex> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/resource_quota.h> -#include <grpc++/security/auth_metadata_processor.h> -#include <grpc++/security/credentials.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.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 "src/core/lib/gpr/env.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/support/env.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" @@ -347,7 +346,8 @@ static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs, for (int i = 0; i < num_rpcs; ++i) { ClientContext context; if (with_binary_metadata) { - char bytes[8] = {'\0', '\1', '\2', '\3', '\4', '\5', '\6', (char)i}; + char bytes[8] = {'\0', '\1', '\2', '\3', + '\4', '\5', '\6', static_cast<char>(i)}; context.AddMetadata("custom-bin", grpc::string(bytes, 8)); } context.set_compression_algorithm(GRPC_COMPRESS_GZIP); @@ -706,7 +706,6 @@ TEST_P(End2endTest, ReconnectChannel) { if (GetParam().inproc) { return; } - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200"); int poller_slowdown_factor = 1; // It needs 2 pollset_works to reconnect the channel with polling engine // "poll" @@ -1087,31 +1086,6 @@ TEST_P(End2endTest, RpcMaxMessageSize) { EXPECT_FALSE(s.ok()); } -// Client sends 20 requests and the server returns CANCELLED status after -// reading 10 requests. -TEST_P(End2endTest, RequestStreamServerEarlyCancelTest) { - ResetStub(); - EchoRequest request; - EchoResponse response; - ClientContext context; - - context.AddMetadata(kServerCancelAfterReads, "10"); - auto stream = stub_->RequestStream(&context, &response); - request.set_message("hello"); - int send_messages = 20; - while (send_messages > 10) { - EXPECT_TRUE(stream->Write(request)); - send_messages--; - } - while (send_messages > 0) { - stream->Write(request); - send_messages--; - } - stream->WritesDone(); - Status s = stream->Finish(); - EXPECT_EQ(s.error_code(), StatusCode::CANCELLED); -} - void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream, gpr_event* ev) { EchoResponse resp; @@ -1359,8 +1333,11 @@ TEST_P(ProxyEnd2endTest, EchoDeadline) { EXPECT_TRUE(s.ok()); gpr_timespec sent_deadline; Timepoint2Timespec(deadline, &sent_deadline); - // Allow 1 second error. - EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1); + // 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); } @@ -1609,7 +1586,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); + EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); } TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { @@ -1626,7 +1603,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); + EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); } TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { @@ -1644,7 +1621,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); + EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); EXPECT_EQ(s.error_message(), grpc::string("Getting metadata from plugin failed with error: ") + kTestCredsPluginErrorMsg); @@ -1705,7 +1682,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); + EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); EXPECT_EQ(s.error_message(), grpc::string("Getting metadata from plugin failed with error: ") + kTestCredsPluginErrorMsg); @@ -1853,6 +1830,7 @@ INSTANTIATE_TEST_CASE_P(ResourceQuotaEnd2end, ResourceQuotaEnd2endTest, } // namespace grpc int main(int argc, char** argv) { + gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200"); grpc_test_init(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/exception_test.cc b/test/cpp/end2end/exception_test.cc new file mode 100644 index 0000000000..5343997663 --- /dev/null +++ b/test/cpp/end2end/exception_test.cc @@ -0,0 +1,123 @@ +/* + * + * 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 <exception> +#include <memory> + +#include <grpc/impl/codegen/port_platform.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" + +#include <gtest/gtest.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_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index c4430379db..88f8f380c3 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -19,20 +19,19 @@ #include <memory> #include <mutex> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/generic/async_generic_service.h> -#include <grpc++/generic/generic_stub.h> -#include <grpc++/impl/codegen/proto_utils.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> -#include <grpc++/support/config.h> -#include <grpc++/support/slice.h> #include <grpc/grpc.h> -#include <grpc/support/thd.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" @@ -50,7 +49,7 @@ namespace grpc { namespace testing { namespace { -void* tag(int i) { return (void*)(intptr_t)i; } +void* tag(int i) { return (void*)static_cast<intptr_t>(i); } void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { bool ok; @@ -175,7 +174,8 @@ class FilterEnd2endTest : public ::testing::Test { // 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<GenericClientAsyncReaderWriter> call = - generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + generic_stub_->PrepareCall(&cli_ctx, kMethodName, &cli_cq_); + call->StartCall(tag(1)); client_ok(1); std::unique_ptr<ByteBuffer> send_buffer = SerializeToByteBuffer(&send_request); @@ -268,7 +268,8 @@ TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); send_request.set_message("Hello"); std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream = - generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + 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(), diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 40949e8f3a..88a1227ca2 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -18,19 +18,18 @@ #include <memory> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/generic/async_generic_service.h> -#include <grpc++/generic/generic_stub.h> -#include <grpc++/impl/codegen/proto_utils.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> -#include <grpc++/support/slice.h> #include <grpc/grpc.h> -#include <grpc/support/thd.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" @@ -47,7 +46,7 @@ namespace grpc { namespace testing { namespace { -void* tag(int i) { return (void*)(intptr_t)i; } +void* tag(int i) { return (void*)static_cast<intptr_t>(i); } void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { bool ok; @@ -125,7 +124,8 @@ class GenericEnd2endTest : public ::testing::Test { } std::unique_ptr<GenericClientAsyncReaderWriter> call = - generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + generic_stub_->PrepareCall(&cli_ctx, kMethodName, &cli_cq_); + call->StartCall(tag(1)); client_ok(1); std::unique_ptr<ByteBuffer> send_buffer = SerializeToByteBuffer(&send_request); @@ -271,7 +271,8 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) { cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); send_request.set_message("Hello"); std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream = - generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + 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(), diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index d4ee6b429f..28f9ae6f40 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -21,21 +21,25 @@ #include <sstream> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> -#include <grpc/support/thd.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 "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.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/support/env.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" + +#include "src/cpp/client/secure_credentials.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -120,12 +124,22 @@ class CountedService : public ServiceType { 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(); @@ -184,13 +198,21 @@ class BalancerServiceImpl : public BalancerService { shutdown_(false) {} Status BalanceLoad(ServerContext* context, Stream* stream) override { + // Balancer shouldn't receive the call credentials metadata. + EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), + context->client_metadata().end()); gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); LoadBalanceRequest request; - stream->Read(&request); + std::vector<ResponseDelayPair> responses_and_delays; + + if (!stream->Read(&request)) { + goto done; + } IncreaseRequestCount(); - gpr_log(GPR_INFO, "LB[%p]: recv msg '%s'", this, + 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() @@ -199,7 +221,6 @@ class BalancerServiceImpl : public BalancerService { stream->Write(initial_response); } - std::vector<ResponseDelayPair> responses_and_delays; { std::unique_lock<std::mutex> lock(mu_); responses_and_delays = responses_and_delays_; @@ -215,35 +236,35 @@ class BalancerServiceImpl : public BalancerService { std::unique_lock<std::mutex> lock(mu_); if (shutdown_) goto done; serverlist_cond_.wait(lock, [this] { return serverlist_ready_; }); - serverlist_ready_ = false; } if (client_load_reporting_interval_seconds_ > 0) { request.Clear(); - stream->Read(&request); - gpr_log(GPR_INFO, "LB[%p]: recv client load report msg: '%s'", this, - request.DebugString().c_str()); - GPR_ASSERT(request.has_client_stats()); - // We need to acquire the lock here in order to prevent the notify_one - // below from firing before its corresponding wait is executed. - std::lock_guard<std::mutex> lock(mu_); - client_stats_.num_calls_started += - request.client_stats().num_calls_started(); - client_stats_.num_calls_finished += - request.client_stats().num_calls_finished(); - client_stats_.num_calls_finished_with_client_failed_to_send += - request.client_stats() - .num_calls_finished_with_client_failed_to_send(); - client_stats_.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()) { - client_stats_ - .drop_token_counts[drop_token_count.load_balance_token()] += - drop_token_count.num_calls(); + if (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()); + // We need to acquire the lock here in order to prevent the notify_one + // below from firing before its corresponding wait is executed. + std::lock_guard<std::mutex> lock(mu_); + client_stats_.num_calls_started += + request.client_stats().num_calls_started(); + client_stats_.num_calls_finished += + request.client_stats().num_calls_finished(); + client_stats_.num_calls_finished_with_client_failed_to_send += + request.client_stats() + .num_calls_finished_with_client_failed_to_send(); + client_stats_.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()) { + client_stats_ + .drop_token_counts[drop_token_count.load_balance_token()] += + drop_token_count.num_calls(); + } + load_report_ready_ = true; + load_report_cond_.notify_one(); } - load_report_ready_ = true; - load_report_cond_.notify_one(); } done: gpr_log(GPR_INFO, "LB[%p]: done", this); @@ -294,7 +315,7 @@ class BalancerServiceImpl : public BalancerService { void NotifyDoneWithServerlists() { std::lock_guard<std::mutex> lock(mu_); serverlist_ready_ = true; - serverlist_cond_.notify_one(); + serverlist_cond_.notify_all(); } private: @@ -302,9 +323,7 @@ class BalancerServiceImpl : public BalancerService { int delay_ms) { gpr_log(GPR_INFO, "LB[%p]: sleeping for %d ms...", this, delay_ms); if (delay_ms > 0) { - gpr_sleep_until( - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(delay_ms, GPR_TIMESPAN))); + 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()); @@ -338,7 +357,8 @@ class GrpclbEnd2endTest : public ::testing::Test { } void SetUp() override { - response_generator_ = grpc_fake_resolver_response_generator_create(); + response_generator_ = + grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); // Start the backends. for (size_t i = 0; i < num_backends_; ++i) { backends_.emplace_back(new BackendServiceImpl()); @@ -362,7 +382,6 @@ class GrpclbEnd2endTest : public ::testing::Test { for (size_t i = 0; i < balancers_.size(); ++i) { if (balancers_[i]->Shutdown()) balancer_servers_[i].Shutdown(); } - grpc_fake_resolver_response_generator_unref(response_generator_); } void SetNextResolutionAllBalancers() { @@ -373,15 +392,29 @@ class GrpclbEnd2endTest : public ::testing::Test { SetNextResolution(addresses); } - void ResetStub(int fallback_timeout = 0) { + void ResetStub(int fallback_timeout = 0, + const grpc::string& expected_targets = "") { ChannelArguments args; args.SetGrpclbFallbackTimeout(fallback_timeout); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_); + response_generator_.get()); + if (!expected_targets.empty()) { + args.SetString(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets); + } std::ostringstream uri; - uri << "fake:///servername_not_used"; - channel_ = - CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); + 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))); + grpc_call_credentials_unref(call_creds); + grpc_channel_credentials_unref(channel_creds); + channel_ = CreateCustomChannel(uri.str(), creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } @@ -442,7 +475,7 @@ class GrpclbEnd2endTest : public ::testing::Test { void WaitForBackend(size_t backend_idx) { do { - CheckRpcSendOk(); + (void)SendRpc(); } while (backends_[backend_idx]->request_count() == 0); ResetBackendCounters(); } @@ -453,8 +486,8 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc::string balancer_name; }; - void SetNextResolution(const std::vector<AddressData>& address_data) { - grpc_core::ExecCtx exec_ctx; + grpc_lb_addresses* CreateLbAddressesFromAddressDataList( + const std::vector<AddressData>& address_data) { grpc_lb_addresses* addresses = grpc_lb_addresses_create(address_data.size(), nullptr); for (size_t i = 0; i < address_data.size(); ++i) { @@ -468,10 +501,27 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } + return addresses; + } + + void SetNextResolution(const std::vector<AddressData>& address_data) { + grpc_core::ExecCtx exec_ctx; + grpc_lb_addresses* addresses = + CreateLbAddressesFromAddressDataList(address_data); grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args fake_result = {1, &fake_addresses}; - grpc_fake_resolver_response_generator_set_response(response_generator_, - &fake_result); + response_generator_->SetResponse(&fake_result); + grpc_lb_addresses_destroy(addresses); + } + + void SetNextReresolutionResponse( + const std::vector<AddressData>& address_data) { + grpc_core::ExecCtx exec_ctx; + grpc_lb_addresses* addresses = + CreateLbAddressesFromAddressDataList(address_data); + grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); + grpc_channel_args fake_result = {1, &fake_addresses}; + response_generator_->SetReresolutionResponse(&fake_result); grpc_lb_addresses_destroy(addresses); } @@ -501,10 +551,10 @@ class GrpclbEnd2endTest : public ::testing::Test { return status; } - void CheckRpcSendOk(const size_t times = 1) { + void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000) { for (size_t i = 0; i < times; ++i) { EchoResponse response; - const Status status = SendRpc(&response); + const Status status = SendRpc(&response, timeout_ms); EXPECT_TRUE(status.ok()) << "code=" << status.error_code() << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage_); @@ -542,8 +592,9 @@ class GrpclbEnd2endTest : public ::testing::Test { std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; - builder.AddListeningPort(server_address.str(), - InsecureServerCredentials()); + 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->notify_one(); @@ -573,8 +624,10 @@ class GrpclbEnd2endTest : public ::testing::Test { std::vector<std::unique_ptr<BalancerServiceImpl>> balancers_; std::vector<ServerThread<BackendService>> backend_servers_; std::vector<ServerThread<BalancerService>> balancer_servers_; - grpc_fake_resolver_response_generator* response_generator_; + grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> + response_generator_; const grpc::string kRequestMessage_ = "Live long and prosper."; + const grpc::string kApplicationTargetName_ = "application_target_name"; }; class SingleBalancerTest : public GrpclbEnd2endTest { @@ -610,11 +663,52 @@ TEST_F(SingleBalancerTest, Vanilla) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, SecureNaming) { + ResetStub(0, kApplicationTargetName_ + ";lb"); + SetNextResolution({AddressData{balancer_servers_[0].port_, true, "lb"}}); + const size_t kNumRpcsPerAddress = 100; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::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, + backend_servers_[i].service_->request_count()); + } + balancers_[0]->NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, SecureNamingDeathTest) { + ::testing::FLAGS_gtest_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( + { + ResetStub(0, kApplicationTargetName_ + ";lb"); + SetNextResolution( + {AddressData{balancer_servers_[0].port_, true, "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 = 1000 * 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 @@ -624,28 +718,20 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { const auto t0 = system_clock::now(); // Client will block: LB will initially send empty serverlist. - CheckRpcSendOk(num_backends_); + CheckRpcSendOk(1, kCallDeadlineMs); 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. + // populated serverlist but under the call's deadline (which is enforced by + // the call's deadline). EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); - EXPECT_LT(ellapsed_ms.count(), kCallDeadlineMs); - - // Each backend should have gotten 1 request. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); - } balancers_[0]->NotifyDoneWithServerlists(); // The balancer got a single request. EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); // and sent two responses. EXPECT_EQ(2U, balancer_servers_[0].service_->response_count()); - - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } TEST_F(SingleBalancerTest, Fallback) { @@ -854,8 +940,6 @@ TEST_F(SingleBalancerTest, BackendsRestart) { // machinery to either update the LB responses "on the fly" or instruct // backends which ports to restart on. CheckRpcSendFailure(); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } class UpdatesTest : public GrpclbEnd2endTest { @@ -872,7 +956,10 @@ TEST_F(UpdatesTest, UpdateBalancers) { ScheduleResponseForBalancer( 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); - // Start servers and send 10 RPCs per server. + // 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 =========="); @@ -919,8 +1006,6 @@ TEST_F(UpdatesTest, UpdateBalancers) { EXPECT_EQ(1U, balancer_servers_[1].service_->response_count()); EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } // Send an update with the same set of LBs as the one in SetUp() in order to @@ -936,7 +1021,10 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { ScheduleResponseForBalancer( 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); - // Start servers and send 10 RPCs per server. + // 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 =========="); @@ -992,9 +1080,6 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { // doesn't assign the second backend. EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); balancers_[0]->NotifyDoneWithServerlists(); - - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { @@ -1054,7 +1139,7 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); WaitForBackend(1); - // This is serviced by the existing RR policy + // This is serviced by the updated RR policy backend_servers_[1].service_->ResetCounters(); gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); CheckRpcSendOk(10); @@ -1077,8 +1162,134 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U); EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +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> addresses; + addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{backend_servers_[0].port_, false, ""}); + SetNextResolution(addresses); + // The re-resolution result will contain the addresses of the same balancer + // and a new fallback backend. + addresses.clear(); + addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{backend_servers_[1].port_, false, ""}); + 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 fallback backend. + EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + + // Kill backend 0. + gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); + if (backends_[0]->Shutdown()) backend_servers_[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, backend_servers_[1].service_->request_count()); + + balancers_[0]->NotifyDoneWithServerlists(); + balancers_[1]->NotifyDoneWithServerlists(); + balancers_[2]->NotifyDoneWithServerlists(); + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[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) { + std::vector<AddressData> addresses; + addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + SetNextResolution(addresses); + addresses.clear(); + addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + SetNextReresolutionResponse(addresses); + const std::vector<int> first_backend{GetBackendPorts()[0]}; + const std::vector<int> second_backend{GetBackendPorts()[1]}; + + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::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, backend_servers_[0].service_->request_count()); + + // Kill backend 0. + gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); + if (backends_[0]->Shutdown()) backend_servers_[0].Shutdown(); + gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); + + CheckRpcSendFailure(); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + + // Kill balancer 0. + gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); + if (balancers_[0]->Shutdown()) balancer_servers_[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, backend_servers_[1].service_->request_count()); + + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancer_servers_[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(balancer_servers_[1].service_->request_count(), 1U); + EXPECT_GE(balancer_servers_[1].service_->response_count(), 1U); + EXPECT_LE(balancer_servers_[1].service_->request_count(), 2U); + EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); } TEST_F(SingleBalancerTest, Drop) { @@ -1169,7 +1380,7 @@ TEST_F(SingleBalancerTest, DropAll) { class SingleBalancerWithClientLoadReportingTest : public GrpclbEnd2endTest { public: - SingleBalancerWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 1, 2) {} + SingleBalancerWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 1, 3) {} }; TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) { diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index de732e0154..1c48b9d151 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -21,16 +21,16 @@ #include <thread> #include <vector> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/ext/health_check_service_server_builder_option.h> -#include <grpc++/health_check_service_interface.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/log.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/health_check_service_interface.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> #include "src/proto/grpc/health/v1/health.grpc.pb.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index cb515533ed..10e16429e6 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -19,14 +19,14 @@ #include <memory> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/generic/async_generic_service.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.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/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" @@ -42,7 +42,7 @@ namespace testing { namespace { -void* tag(int i) { return (void*)(intptr_t)i; } +void* tag(int i) { return (void*)static_cast<intptr_t>(i); } bool VerifyReturnSuccess(CompletionQueue* cq, int i) { void* got_tag; diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index 61f4111e3b..ff49902fea 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -19,16 +19,15 @@ #include <climits> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.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" @@ -36,14 +35,13 @@ #include "test/core/util/port.h" #include "test/core/util/test_config.h" -#include <grpc++/test/mock_stream.h> +#include <grpcpp/test/mock_stream.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <iostream> -using namespace std; using ::testing::AtLeast; using ::testing::DoAll; using ::testing::Invoke; @@ -57,6 +55,7 @@ using grpc::testing::EchoResponse; using grpc::testing::EchoTestService; using grpc::testing::MockClientReaderWriter; using std::chrono::system_clock; +using std::vector; namespace grpc { namespace testing { diff --git a/test/cpp/end2end/nonblocking_test.cc b/test/cpp/end2end/nonblocking_test.cc new file mode 100644 index 0000000000..d8337baca2 --- /dev/null +++ b/test/cpp/end2end/nonblocking_test.cc @@ -0,0 +1,194 @@ +/* + * + * 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 <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) +GPR_TLS_DECL(g_is_nonblocking_test); + +namespace { + +int maybe_assert_non_blocking_poll(struct pollfd* pfds, nfds_t nfds, + int timeout) { + if (gpr_tls_get(&g_is_nonblocking_test)) { + 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) { + for (;;) { + auto r = cq_->AsyncNext(tag, ok, gpr_time_0(GPR_CLOCK_REALTIME)); + if (r == CompletionQueue::SHUTDOWN) { + return false; + } else if (r == CompletionQueue::GOT_EVENT) { + 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_.reset(new grpc::testing::EchoTestService::AsyncService()); + builder.RegisterService(service_.get()); + cq_ = builder.AddCompletionQueue(); + server_ = builder.BuildAndStart(); + } + + void ResetStub() { + std::shared_ptr<Channel> channel = 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; +#endif // GRPC_POSIX_SOCKET + + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc index b645d90c63..21a275ef62 100644 --- a/test/cpp/end2end/proto_server_reflection_test.cc +++ b/test/cpp/end2end/proto_server_reflection_test.cc @@ -16,16 +16,16 @@ * */ -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/ext/proto_server_reflection_plugin.h> -#include <grpc++/security/credentials.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.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" diff --git a/test/cpp/end2end/round_robin_end2end_test.cc b/test/cpp/end2end/round_robin_end2end_test.cc deleted file mode 100644 index eee32ce85d..0000000000 --- a/test/cpp/end2end/round_robin_end2end_test.cc +++ /dev/null @@ -1,226 +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 <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc/grpc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.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 <gtest/gtest.h> - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using std::chrono::system_clock; - -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 { - { - std::unique_lock<std::mutex> lock(mu_); - ++request_count_; - } - return TestServiceImpl::Echo(context, request, response); - } - - int request_count() { - std::unique_lock<std::mutex> lock(mu_); - return request_count_; - } - - private: - std::mutex mu_; - int request_count_; -}; - -class RoundRobinEnd2endTest : public ::testing::Test { - protected: - RoundRobinEnd2endTest() : server_host_("localhost") {} - - void StartServers(size_t num_servers, - std::vector<int> ports = std::vector<int>()) { - 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(server_host_, port)); - } - } - - void TearDown() override { - for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(); - } - } - - void ResetStub(bool round_robin) { - ChannelArguments args; - if (round_robin) args.SetLoadBalancingPolicyName("round_robin"); - std::ostringstream uri; - uri << "ipv4:///"; - for (size_t i = 0; i < servers_.size() - 1; ++i) { - uri << "127.0.0.1:" << servers_[i]->port_ << ","; - } - uri << "127.0.0.1:" << servers_[servers_.size() - 1]->port_; - channel_ = - CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - void SendRpc(int num_rpcs, bool expect_ok = true) { - EchoRequest request; - EchoResponse response; - request.set_message("Live long and prosper."); - for (int i = 0; i < num_rpcs; i++) { - ClientContext context; - Status status = stub_->Echo(&context, request, &response); - if (expect_ok) { - EXPECT_TRUE(status.ok()); - EXPECT_EQ(response.message(), request.message()); - } else { - EXPECT_FALSE(status.ok()); - } - } - } - - struct ServerData { - int port_; - std::unique_ptr<Server> server_; - MyTestServiceImpl service_; - - explicit ServerData(const grpc::string& server_host, int port = 0) { - port_ = port > 0 ? port : grpc_pick_unused_port_or_die(); - gpr_log(GPR_INFO, "starting server on port %d", port_); - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - builder.AddListeningPort(server_address.str(), - InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - gpr_log(GPR_INFO, "server startup complete"); - } - - void Shutdown() { server_->Shutdown(); } - }; - - const grpc::string server_host_; - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::vector<std::unique_ptr<ServerData>> servers_; -}; - -TEST_F(RoundRobinEnd2endTest, PickFirst) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - StartServers(kNumServers); - ResetStub(false /* round_robin */); - SendRpc(kNumServers); - // 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(RoundRobinEnd2endTest, RoundRobin) { - // Start servers and send one RPC per server. - const int kNumServers = 3; - StartServers(kNumServers); - ResetStub(true /* round_robin */); - // Send one RPC per backend and make sure they are used in order. - // Note: This relies on the fact that the subchannels are reported in - // state READY in the order in which the addresses are specified, - // which is only true because the backends are all local. - for (size_t i = 0; i < servers_.size(); ++i) { - SendRpc(1); - EXPECT_EQ(1, servers_[i]->service_.request_count()) << "for backend #" << i; - } - // Check LB policy name for the channel. - EXPECT_EQ("round_robin", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(RoundRobinEnd2endTest, RoundRobinReconnect) { - // Start servers and send one RPC per server. - const int kNumServers = 1; - std::vector<int> ports; - ports.push_back(grpc_pick_unused_port_or_die()); - StartServers(kNumServers, ports); - ResetStub(true /* round_robin */); - // Send one RPC per backend and make sure they are used in order. - // Note: This relies on the fact that the subchannels are reported in - // state READY in the order in which the addresses are specified, - // which is only true because the backends are all local. - for (size_t i = 0; i < servers_.size(); ++i) { - SendRpc(1); - EXPECT_EQ(1, servers_[i]->service_.request_count()) << "for backend #" << i; - } - // Check LB policy name for the channel. - EXPECT_EQ("round_robin", channel_->GetLoadBalancingPolicyName()); - - // Kill all servers - for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(); - } - // Client request should fail. - SendRpc(1, false); - - // Bring servers back up on the same port (we aren't recreating the channel). - StartServers(kNumServers, ports); - - // Client request should succeed. - SendRpc(1); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc index 2951a2ebcf..d54523fcbb 100644 --- a/test/cpp/end2end/server_builder_plugin_test.cc +++ b/test/cpp/end2end/server_builder_plugin_test.cc @@ -18,18 +18,18 @@ #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/impl/server_builder_option.h> -#include <grpc++/impl/server_builder_plugin.h> -#include <grpc++/impl/server_initializer.h> -#include <grpc++/security/credentials.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.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" diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc index 528951bb9b..93257b2705 100644 --- a/test/cpp/end2end/server_crash_test.cc +++ b/test/cpp/end2end/server_crash_test.cc @@ -16,16 +16,15 @@ * */ -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/log.h> -#include <grpc/support/thd.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" diff --git a/test/cpp/end2end/server_crash_test_client.cc b/test/cpp/end2end/server_crash_test_client.cc index 45995769fa..c05fcfdb81 100644 --- a/test/cpp/end2end/server_crash_test_client.cc +++ b/test/cpp/end2end/server_crash_test_client.cc @@ -22,10 +22,10 @@ #include <sstream> #include <string> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.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" diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc new file mode 100644 index 0000000000..8948e5b854 --- /dev/null +++ b/test/cpp/end2end/server_early_return_test.cc @@ -0,0 +1,232 @@ +/* + * + * 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/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" + +#include <gtest/gtest.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_ << "127.0.0.1:" << port; + ServerBuilder builder; + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + + channel_ = + 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(grpc::string("hello") + grpc::to_string(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(grpc::string("hello") + grpc::to_string(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_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc index 14ba7c96cc..a53de691bc 100644 --- a/test/cpp/end2end/shutdown_test.cc +++ b/test/cpp/end2end/shutdown_test.cc @@ -18,17 +18,17 @@ #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/log.h> #include <grpc/support/sync.h> - -#include "src/core/lib/support/env.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" diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc index 8fcb8b1d48..898d1ec118 100644 --- a/test/cpp/end2end/streaming_throughput_test.cc +++ b/test/cpp/end2end/streaming_throughput_test.cc @@ -20,19 +20,18 @@ #include <mutex> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/security/credentials.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/atm.h> #include <grpc/support/log.h> -#include <grpc/support/thd.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" diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index e4f7c08f25..3c3a5d9cd4 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -21,9 +21,9 @@ #include <string> #include <thread> -#include <grpc++/security/credentials.h> -#include <grpc++/server_context.h> #include <grpc/support/log.h> +#include <grpcpp/security/credentials.h> +#include <grpcpp/server_context.h> #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/cpp/util/string_ref_helper.h" @@ -181,13 +181,6 @@ Status TestServiceImpl::RequestStream(ServerContext* context, int server_try_cancel = GetIntValueFromMetadata( kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); - // If 'cancel_after_reads' is set in the metadata AND non-zero, the server - // will cancel the RPC (by just returning Status::CANCELLED - doesn't call - // ServerContext::TryCancel()) after reading the number of records specified - // by the 'cancel_after_reads' value set in the metadata. - int cancel_after_reads = GetIntValueFromMetadata( - kServerCancelAfterReads, context->client_metadata(), 0); - EchoRequest request; response->set_message(""); @@ -204,12 +197,6 @@ Status TestServiceImpl::RequestStream(ServerContext* context, int num_msgs_read = 0; while (reader->Read(&request)) { - if (cancel_after_reads == 1) { - gpr_log(GPR_INFO, "return cancel status"); - return Status::CANCELLED; - } else if (cancel_after_reads > 0) { - cancel_after_reads--; - } response->mutable_message()->append(request.message()); } gpr_log(GPR_INFO, "Read: %d messages", num_msgs_read); diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index e485769bb2..052543a03e 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -21,8 +21,8 @@ #include <memory> #include <mutex> -#include <grpc++/server_context.h> #include <grpc/grpc.h> +#include <grpcpp/server_context.h> #include "src/proto/grpc/testing/echo.grpc.pb.h" @@ -31,7 +31,6 @@ namespace testing { const int kServerDefaultResponseStreamsToSend = 3; const char* const kServerResponseStreamsToSend = "server_responses_to_send"; -const char* const kServerCancelAfterReads = "cancel_after_reads"; const char* const kServerTryCancelRequest = "server_try_cancel"; const char* const kDebugInfoTrailerKey = "debug-info-bin"; const char* const kServerFinishAfterNReads = "server_finish_after_n_reads"; diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index 90b2eddbbb..e709a25356 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -19,15 +19,14 @@ #include <mutex> #include <thread> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> -#include <grpc/support/thd.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/surface/api_trace.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" @@ -265,7 +264,7 @@ class CommonStressTestAsyncServer : public BaseClass { service_.RequestEcho(contexts_[i].srv_ctx.get(), &contexts_[i].recv_request, contexts_[i].response_writer.get(), cq_.get(), - cq_.get(), (void*)(intptr_t)i); + cq_.get(), (void*)static_cast<intptr_t>(i)); } } struct Context { diff --git a/test/cpp/grpclb/BUILD b/test/cpp/grpclb/BUILD new file mode 100644 index 0000000000..8319eb5142 --- /dev/null +++ b/test/cpp/grpclb/BUILD @@ -0,0 +1,39 @@ +# 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. + +licenses(["notice"]) # Apache v2 + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package", "grpc_cc_binary") + +grpc_package( + name = "test/cpp/grpclb", + visibility = "public", +) # Allows external users to implement grpclb tests. + +grpc_cc_test( + name = "grpclb_api_test", + srcs = ["grpclb_api_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/lb/v1:load_balancer_proto", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc index 1f2ef0c2de..ecba9f9ca3 100644 --- a/test/cpp/grpclb/grpclb_api_test.cc +++ b/test/cpp/grpclb/grpclb_api_test.cc @@ -16,8 +16,8 @@ * */ -#include <grpc++/impl/codegen/config.h> #include <grpc/grpc.h> +#include <grpcpp/impl/codegen/config.h> #include <gtest/gtest.h> #include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc deleted file mode 100644 index 38b65fbc78..0000000000 --- a/test/cpp/grpclb/grpclb_test.cc +++ /dev/null @@ -1,795 +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 <cinttypes> -#include <cstdarg> -#include <cstdint> -#include <cstring> -#include <string> - -#include <gtest/gtest.h> - -#include <grpc/grpc.h> -#include <grpc/impl/codegen/byte_buffer_reader.h> -#include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpc/support/sync.h> -#include <grpc/support/thd.h> -#include <grpc/support/time.h> - -#include <grpc++/impl/codegen/config.h> - -#include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" -#include "src/core/lib/support/tmpfile.h" -#include "src/core/lib/surface/channel.h" -#include "src/core/lib/surface/server.h" -#include "test/core/end2end/cq_verifier.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -#include "src/proto/grpc/lb/v1/load_balancer.pb.h" - -#define NUM_BACKENDS 4 -#define PAYLOAD "hello you" - -// TODO(dgq): Other scenarios in need of testing: -// - Send an empty serverlist update and verify that the client request blocks -// until a new serverlist with actual contents is available. -// - Send identical serverlist update -// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc). -// - Test reception of invalid serverlist -// - Test pinging -// - Test against a non-LB server. -// - Random LB server closing the stream unexpectedly. -// - Test using DNS-resolvable names (localhost?) -// - Test handling of creation of faulty RR instance by having the LB return a -// serverlist with non-existent backends after having initially returned a -// valid one. -// -// 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. -// - Restart of backend servers with no changes to serverlist. This exercises -// the RR handover mechanism. - -namespace grpc { -namespace { - -typedef struct client_fixture { - grpc_channel* client; - char* server_uri; - grpc_completion_queue* cq; -} client_fixture; - -typedef struct server_fixture { - grpc_server* server; - grpc_call* server_call; - grpc_completion_queue* cq; - char* servers_hostport; - const char* balancer_name; - int port; - const char* lb_token_prefix; - gpr_thd_id tid; - int num_calls_serviced; -} server_fixture; - -typedef struct test_fixture { - server_fixture lb_server; - server_fixture lb_backends[NUM_BACKENDS]; - client_fixture client; - int lb_server_update_delay_ms; -} test_fixture; - -static void* tag(intptr_t t) { return (void*)t; } - -static grpc_slice build_response_payload_slice(const char* host, int* ports, - size_t nports, - const char* token_prefix) { - // server_list { - // servers { - // ip_address: <in_addr/6 bytes of an IP> - // port: <16 bit uint> - // load_balance_token: "token..." - // } - // ... - // } - grpc::lb::v1::LoadBalanceResponse response; - auto* serverlist = response.mutable_server_list(); - - for (size_t i = 0; i < nports; i++) { - auto* server = serverlist->add_servers(); - // TODO(dgq): test ipv6 - struct in_addr ip4; - GPR_ASSERT(inet_pton(AF_INET, host, &ip4) == 1); - server->set_ip_address( - string(reinterpret_cast<const char*>(&ip4), sizeof(ip4))); - server->set_port(ports[i]); - // Missing tokens are acceptable. Test that path. - if (strlen(token_prefix) > 0) { - string token_data = token_prefix + std::to_string(ports[i]); - server->set_load_balance_token(token_data); - } - } - const string& enc_resp = response.SerializeAsString(); - return grpc_slice_from_copied_buffer(enc_resp.data(), enc_resp.size()); -} - -static void drain_cq(grpc_completion_queue* cq) { - grpc_event ev; - do { - ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5), - nullptr); - } while (ev.type != GRPC_QUEUE_SHUTDOWN); -} - -static void sleep_ms(int delay_ms) { - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(delay_ms, GPR_TIMESPAN))); -} - -static void start_lb_server(server_fixture* sf, int* ports, size_t nports, - int update_delay_ms) { - grpc_call* s; - cq_verifier* cqv = cq_verifier_create(sf->cq); - grpc_op ops[6]; - grpc_op* op; - grpc_metadata_array request_metadata_recv; - grpc_call_details call_details; - grpc_call_error error; - int was_cancelled = 2; - grpc_byte_buffer* request_payload_recv; - grpc_byte_buffer* response_payload; - - memset(ops, 0, sizeof(ops)); - grpc_metadata_array_init(&request_metadata_recv); - grpc_call_details_init(&call_details); - - error = grpc_server_request_call(sf->server, &s, &call_details, - &request_metadata_recv, sf->cq, sf->cq, - tag(200)); - GPR_ASSERT(GRPC_CALL_OK == error); - gpr_log(GPR_INFO, "LB Server[%s](%s) up", sf->servers_hostport, - sf->balancer_name); - CQ_EXPECT_COMPLETION(cqv, tag(200), 1); - cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 200", sf->servers_hostport, - sf->balancer_name); - - // make sure we've received the initial metadata from the grpclb request. - GPR_ASSERT(request_metadata_recv.count > 0); - GPR_ASSERT(request_metadata_recv.metadata != nullptr); - - // receive request for backends - op = ops; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message.recv_message = &request_payload_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - CQ_EXPECT_COMPLETION(cqv, tag(202), 1); - cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s](%s) after RECV_MSG", sf->servers_hostport, - sf->balancer_name); - - // validate initial request. - grpc_byte_buffer_reader bbr; - grpc_byte_buffer_reader_init(&bbr, request_payload_recv); - grpc_slice request_payload_slice = grpc_byte_buffer_reader_readall(&bbr); - grpc::lb::v1::LoadBalanceRequest request; - request.ParseFromArray(GRPC_SLICE_START_PTR(request_payload_slice), - GRPC_SLICE_LENGTH(request_payload_slice)); - GPR_ASSERT(request.has_initial_request()); - GPR_ASSERT(request.initial_request().name() == sf->servers_hostport); - grpc_slice_unref(request_payload_slice); - grpc_byte_buffer_reader_destroy(&bbr); - grpc_byte_buffer_destroy(request_payload_recv); - - grpc_slice response_payload_slice; - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(201), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 201", sf->servers_hostport, - sf->balancer_name); - - for (int i = 0; i < 2; i++) { - if (i == 0) { - // First half of the ports. - response_payload_slice = build_response_payload_slice( - "127.0.0.1", ports, nports / 2, sf->lb_token_prefix); - } else { - // Second half of the ports. - sleep_ms(update_delay_ms); - response_payload_slice = build_response_payload_slice( - "127.0.0.1", ports + (nports / 2), (nports + 1) / 2 /* ceil */, - "" /* this half doesn't get to receive an LB token */); - } - - response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); - op = ops; - op->op = GRPC_OP_SEND_MESSAGE; - op->data.send_message.send_message = response_payload; - op->flags = 0; - op->reserved = nullptr; - op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(203), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - CQ_EXPECT_COMPLETION(cqv, tag(203), 1); - cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s](%s) after SEND_MESSAGE, iter %d", - sf->servers_hostport, sf->balancer_name, i); - - grpc_byte_buffer_destroy(response_payload); - grpc_slice_unref(response_payload_slice); - } - gpr_log(GPR_INFO, "LB Server[%s](%s) shutting down", sf->servers_hostport, - sf->balancer_name); - - op = ops; - op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; - op->data.send_status_from_server.trailing_metadata_count = 0; - op->data.send_status_from_server.status = GRPC_STATUS_OK; - grpc_slice status_details = grpc_slice_from_static_string("xyz"); - op->data.send_status_from_server.status_details = &status_details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(204), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(201), 1); - CQ_EXPECT_COMPLETION(cqv, tag(204), 1); - cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 204. All done. LB server out", - sf->servers_hostport, sf->balancer_name); - - grpc_call_unref(s); - - cq_verifier_destroy(cqv); - - grpc_metadata_array_destroy(&request_metadata_recv); - grpc_call_details_destroy(&call_details); -} - -static void start_backend_server(server_fixture* sf) { - grpc_call* s; - cq_verifier* cqv; - grpc_op ops[6]; - grpc_op* op; - grpc_metadata_array request_metadata_recv; - grpc_call_details call_details; - grpc_call_error error; - int was_cancelled; - grpc_byte_buffer* request_payload_recv; - grpc_byte_buffer* response_payload; - grpc_event ev; - - while (true) { - memset(ops, 0, sizeof(ops)); - cqv = cq_verifier_create(sf->cq); - was_cancelled = 2; - grpc_metadata_array_init(&request_metadata_recv); - grpc_call_details_init(&call_details); - - error = grpc_server_request_call(sf->server, &s, &call_details, - &request_metadata_recv, sf->cq, sf->cq, - tag(100)); - GPR_ASSERT(GRPC_CALL_OK == error); - gpr_log(GPR_INFO, "Server[%s] up", sf->servers_hostport); - ev = grpc_completion_queue_next( - sf->cq, grpc_timeout_seconds_to_deadline(60), nullptr); - if (!ev.success) { - gpr_log(GPR_INFO, "Server[%s] being torn down", sf->servers_hostport); - cq_verifier_destroy(cqv); - grpc_metadata_array_destroy(&request_metadata_recv); - grpc_call_details_destroy(&call_details); - return; - } - GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); - const string expected_token = - strlen(sf->lb_token_prefix) == 0 - ? "" - : sf->lb_token_prefix + std::to_string(sf->port); - GPR_ASSERT(contains_metadata(&request_metadata_recv, "lb-token", - expected_token.c_str())); - - gpr_log(GPR_INFO, "Server[%s] after tag 100", sf->servers_hostport); - - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op->flags = 0; - op->reserved = nullptr; - op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - gpr_log(GPR_INFO, "Server[%s] after tag 101", sf->servers_hostport); - - bool exit = false; - grpc_slice response_payload_slice = grpc_slice_from_copied_string(PAYLOAD); - while (!exit) { - op = ops; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message.recv_message = &request_payload_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - ev = grpc_completion_queue_next( - sf->cq, grpc_timeout_seconds_to_deadline(3), nullptr); - if (ev.type == GRPC_OP_COMPLETE && ev.success) { - GPR_ASSERT(ev.tag = tag(102)); - if (request_payload_recv == nullptr) { - exit = true; - gpr_log(GPR_INFO, - "Server[%s] recv \"close\" from client, exiting. Call #%d", - sf->servers_hostport, sf->num_calls_serviced); - } - } else { - gpr_log(GPR_INFO, "Server[%s] forced to shutdown. Call #%d", - sf->servers_hostport, sf->num_calls_serviced); - exit = true; - } - gpr_log(GPR_INFO, "Server[%s] after tag 102. Call #%d", - sf->servers_hostport, sf->num_calls_serviced); - - if (!exit) { - response_payload = - grpc_raw_byte_buffer_create(&response_payload_slice, 1); - op = ops; - op->op = GRPC_OP_SEND_MESSAGE; - op->data.send_message.send_message = response_payload; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - ev = grpc_completion_queue_next( - sf->cq, grpc_timeout_seconds_to_deadline(3), nullptr); - if (ev.type == GRPC_OP_COMPLETE && ev.success) { - GPR_ASSERT(ev.tag = tag(103)); - } else { - gpr_log(GPR_INFO, "Server[%s] forced to shutdown. Call #%d", - sf->servers_hostport, sf->num_calls_serviced); - exit = true; - } - gpr_log(GPR_INFO, "Server[%s] after tag 103. Call #%d", - sf->servers_hostport, sf->num_calls_serviced); - grpc_byte_buffer_destroy(response_payload); - } - - grpc_byte_buffer_destroy(request_payload_recv); - } - ++sf->num_calls_serviced; - - gpr_log(GPR_INFO, "Server[%s] OUT OF THE LOOP", sf->servers_hostport); - grpc_slice_unref(response_payload_slice); - - op = ops; - op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; - op->data.send_status_from_server.trailing_metadata_count = 0; - op->data.send_status_from_server.status = GRPC_STATUS_OK; - grpc_slice status_details = - grpc_slice_from_static_string("Backend server out a-ok"); - op->data.send_status_from_server.status_details = &status_details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = - grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(101), 1); - CQ_EXPECT_COMPLETION(cqv, tag(104), 1); - cq_verify(cqv); - gpr_log(GPR_INFO, "Server[%s] DONE. After servicing %d calls", - sf->servers_hostport, sf->num_calls_serviced); - - grpc_call_unref(s); - cq_verifier_destroy(cqv); - grpc_metadata_array_destroy(&request_metadata_recv); - grpc_call_details_destroy(&call_details); - } -} - -static void perform_request(client_fixture* cf) { - grpc_call* c; - cq_verifier* cqv = cq_verifier_create(cf->cq); - grpc_op ops[6]; - grpc_op* op; - grpc_metadata_array initial_metadata_recv; - grpc_metadata_array trailing_metadata_recv; - grpc_status_code status; - grpc_call_error error; - grpc_slice details; - grpc_byte_buffer* request_payload; - grpc_byte_buffer* response_payload_recv; - int i; - - memset(ops, 0, sizeof(ops)); - grpc_slice request_payload_slice = - grpc_slice_from_copied_string("hello world"); - - grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr:1234"); - c = grpc_channel_create_call(cf->client, nullptr, GRPC_PROPAGATE_DEFAULTS, - cf->cq, grpc_slice_from_static_string("/foo"), - &host, grpc_timeout_seconds_to_deadline(5), - nullptr); - gpr_log(GPR_INFO, "Call 0x%" PRIxPTR " created", (intptr_t)c); - GPR_ASSERT(c); - char* peer; - - grpc_metadata_array_init(&initial_metadata_recv); - grpc_metadata_array_init(&trailing_metadata_recv); - - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_INITIAL_METADATA; - op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; - op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; - op->data.recv_status_on_client.status = &status; - op->data.recv_status_on_client.status_details = &details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - for (i = 0; i < 4; i++) { - request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); - - op = ops; - op->op = GRPC_OP_SEND_MESSAGE; - op->data.send_message.send_message = request_payload; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message.recv_message = &response_payload_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(2), 1); - cq_verify(cqv); - gpr_log(GPR_INFO, "Client after sending msg %d / 4", i + 1); - GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, PAYLOAD)); - - grpc_byte_buffer_destroy(request_payload); - grpc_byte_buffer_destroy(response_payload_recv); - } - - grpc_slice_unref(request_payload_slice); - - op = ops; - op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(1), 1); - CQ_EXPECT_COMPLETION(cqv, tag(3), 1); - cq_verify(cqv); - peer = grpc_call_get_peer(c); - gpr_log(GPR_INFO, "Client DONE WITH SERVER %s ", peer); - - grpc_call_unref(c); - - cq_verify_empty_timeout(cqv, 1 /* seconds */); - cq_verifier_destroy(cqv); - - grpc_metadata_array_destroy(&initial_metadata_recv); - grpc_metadata_array_destroy(&trailing_metadata_recv); - grpc_slice_unref(details); - gpr_log(GPR_INFO, "Client call (peer %s) DESTROYED.", peer); - gpr_free(peer); -} - -#define BALANCERS_NAME "lb.name" -static void setup_client(const server_fixture* lb_server, - const server_fixture* backends, client_fixture* cf) { - grpc_core::ExecCtx exec_ctx; - - char* expected_target_names = nullptr; - const char* backends_name = lb_server->servers_hostport; - gpr_asprintf(&expected_target_names, "%s;%s", backends_name, BALANCERS_NAME); - - grpc_fake_resolver_response_generator* response_generator = - grpc_fake_resolver_response_generator_create(); - - grpc_lb_addresses* addresses = grpc_lb_addresses_create(1, nullptr); - char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:%s", lb_server->servers_hostport); - grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); - GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri(addresses, 0, lb_uri, true, - lb_server->balancer_name, nullptr); - grpc_uri_destroy(lb_uri); - gpr_free(lb_uri_str); - - gpr_asprintf(&cf->server_uri, "fake:///%s", lb_server->servers_hostport); - const grpc_arg fake_addresses = - grpc_lb_addresses_create_channel_arg(addresses); - grpc_channel_args* fake_result = - grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1); - grpc_lb_addresses_destroy(addresses); - - const grpc_arg new_args[] = { - grpc_fake_transport_expected_targets_arg(expected_target_names), - grpc_fake_resolver_response_generator_arg(response_generator)}; - - grpc_channel_args* args = grpc_channel_args_copy_and_add( - nullptr, new_args, GPR_ARRAY_SIZE(new_args)); - gpr_free(expected_target_names); - - cf->cq = grpc_completion_queue_create_for_next(nullptr); - grpc_channel_credentials* fake_creds = - grpc_fake_transport_security_credentials_create(); - cf->client = - grpc_secure_channel_create(fake_creds, cf->server_uri, args, nullptr); - grpc_fake_resolver_response_generator_set_response(response_generator, - fake_result); - grpc_channel_args_destroy(fake_result); - grpc_channel_credentials_unref(fake_creds); - grpc_channel_args_destroy(args); - grpc_fake_resolver_response_generator_unref(response_generator); -} - -static void teardown_client(client_fixture* cf) { - grpc_completion_queue_shutdown(cf->cq); - drain_cq(cf->cq); - grpc_completion_queue_destroy(cf->cq); - cf->cq = nullptr; - grpc_channel_destroy(cf->client); - cf->client = nullptr; - gpr_free(cf->server_uri); -} - -static void setup_server(const char* host, server_fixture* sf) { - int assigned_port; - - sf->cq = grpc_completion_queue_create_for_next(nullptr); - const char* colon_idx = strchr(host, ':'); - if (colon_idx) { - const char* port_str = colon_idx + 1; - sf->port = atoi(port_str); - sf->servers_hostport = gpr_strdup(host); - } else { - sf->port = grpc_pick_unused_port_or_die(); - gpr_join_host_port(&sf->servers_hostport, host, sf->port); - } - - grpc_server_credentials* server_creds = - grpc_fake_transport_security_server_credentials_create(); - - sf->server = grpc_server_create(nullptr, nullptr); - grpc_server_register_completion_queue(sf->server, sf->cq, nullptr); - GPR_ASSERT((assigned_port = grpc_server_add_secure_http2_port( - sf->server, sf->servers_hostport, server_creds)) > 0); - grpc_server_credentials_release(server_creds); - GPR_ASSERT(sf->port == assigned_port); - grpc_server_start(sf->server); -} - -static void teardown_server(server_fixture* sf) { - if (!sf->server) return; - - gpr_log(GPR_INFO, "Server[%s] shutting down", sf->servers_hostport); - - grpc_completion_queue* shutdown_cq = - grpc_completion_queue_create_for_pluck(nullptr); - grpc_server_shutdown_and_notify(sf->server, shutdown_cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(shutdown_cq, tag(1000), - grpc_timeout_seconds_to_deadline(5), - nullptr) - .type == GRPC_OP_COMPLETE); - grpc_completion_queue_destroy(shutdown_cq); - grpc_server_destroy(sf->server); - gpr_thd_join(sf->tid); - - sf->server = nullptr; - grpc_completion_queue_shutdown(sf->cq); - drain_cq(sf->cq); - grpc_completion_queue_destroy(sf->cq); - - gpr_log(GPR_INFO, "Server[%s] bye bye", sf->servers_hostport); - gpr_free(sf->servers_hostport); -} - -static void fork_backend_server(void* arg) { - server_fixture* sf = static_cast<server_fixture*>(arg); - start_backend_server(sf); -} - -static void fork_lb_server(void* arg) { - test_fixture* tf = static_cast<test_fixture*>(arg); - int ports[NUM_BACKENDS]; - for (int i = 0; i < NUM_BACKENDS; i++) { - ports[i] = tf->lb_backends[i].port; - } - start_lb_server(&tf->lb_server, ports, NUM_BACKENDS, - tf->lb_server_update_delay_ms); -} - -#define LB_TOKEN_PREFIX "token" -static test_fixture setup_test_fixture(int lb_server_update_delay_ms) { - test_fixture tf; - memset(&tf, 0, sizeof(tf)); - tf.lb_server_update_delay_ms = lb_server_update_delay_ms; - - gpr_thd_options options = gpr_thd_options_default(); - gpr_thd_options_set_joinable(&options); - - for (int i = 0; i < NUM_BACKENDS; ++i) { - // Only the first half of the servers expect an LB token. - if (i < NUM_BACKENDS / 2) { - tf.lb_backends[i].lb_token_prefix = LB_TOKEN_PREFIX; - } else { - tf.lb_backends[i].lb_token_prefix = ""; - } - setup_server("127.0.0.1", &tf.lb_backends[i]); - gpr_thd_new(&tf.lb_backends[i].tid, "grpclb_backend", fork_backend_server, - &tf.lb_backends[i], &options); - } - - tf.lb_server.lb_token_prefix = LB_TOKEN_PREFIX; - tf.lb_server.balancer_name = BALANCERS_NAME; - setup_server("127.0.0.1", &tf.lb_server); - gpr_thd_new(&tf.lb_server.tid, "grpclb_server", fork_lb_server, &tf.lb_server, - &options); - setup_client(&tf.lb_server, tf.lb_backends, &tf.client); - return tf; -} - -static void teardown_test_fixture(test_fixture* tf) { - teardown_client(&tf->client); - for (int i = 0; i < NUM_BACKENDS; ++i) { - teardown_server(&tf->lb_backends[i]); - } - teardown_server(&tf->lb_server); -} - -// The LB server will send two updates: batch 1 and batch 2. Each batch contains -// two addresses, both of a valid and running backend server. Batch 1 is readily -// available and provided as soon as the client establishes the streaming call. -// Batch 2 is sent after a delay of \a lb_server_update_delay_ms milliseconds. -static test_fixture test_update(int lb_server_update_delay_ms) { - gpr_log(GPR_INFO, "start %s(%d)", __func__, lb_server_update_delay_ms); - test_fixture tf = setup_test_fixture(lb_server_update_delay_ms); - perform_request( - &tf.client); // "consumes" 1st backend server of 1st serverlist - perform_request( - &tf.client); // "consumes" 2nd backend server of 1st serverlist - - perform_request( - &tf.client); // "consumes" 1st backend server of 2nd serverlist - perform_request( - &tf.client); // "consumes" 2nd backend server of 2nd serverlist - - teardown_test_fixture(&tf); - gpr_log(GPR_INFO, "end %s(%d)", __func__, lb_server_update_delay_ms); - return tf; -} - -TEST(GrpclbTest, Updates) { - grpc::test_fixture tf_result; - // Clients take at least one second to complete a call (the last part of the - // call sleeps for 1 second while verifying the client's completion queue is - // empty), more if the system is under load. Therefore: - // - // If the LB server waits 800ms before sending an update, it will arrive - // before the first client request finishes, skipping the second server from - // batch 1. All subsequent picks will come from the second half of the - // backends, those coming in the LB update. - tf_result = grpc::test_update(800); - GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced + - tf_result.lb_backends[1].num_calls_serviced == - 1); - GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced + - tf_result.lb_backends[3].num_calls_serviced > - 0); - int num_serviced_calls = 0; - for (int i = 0; i < 4; i++) { - num_serviced_calls += tf_result.lb_backends[i].num_calls_serviced; - } - GPR_ASSERT(num_serviced_calls == 4); - - // If the LB server waits 2500ms, the update arrives after two calls and three - // picks. The third pick will be the 1st server of the 1st update (RR policy - // going around). The fourth and final pick will come from the second LB - // update. In any case, the total number of serviced calls must again be equal - // to four across all the backends. - tf_result = grpc::test_update(2500); - GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced + - tf_result.lb_backends[1].num_calls_serviced >= - 2); - GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced + - tf_result.lb_backends[3].num_calls_serviced > - 0); - num_serviced_calls = 0; - for (int i = 0; i < 4; i++) { - num_serviced_calls += tf_result.lb_backends[i].num_calls_serviced; - } - GPR_ASSERT(num_serviced_calls == 4); -} - -TEST(GrpclbTest, InvalidAddressInServerlist) {} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1"); - grpc_init(); - const auto result = RUN_ALL_TESTS(); - grpc_shutdown(); - return result; -} diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 716fb96382..3eb155ef95 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -20,18 +20,19 @@ #include <unordered_map> #include <gflags/gflags.h> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" #include "test/cpp/interop/client_helper.h" #include "test/cpp/interop/interop_client.h" #include "test/cpp/util/test_config.h" +DEFINE_bool(use_alts, false, + "Whether to use alts. Enable alts will disable tls."); DEFINE_bool(use_tls, false, "Whether to use tls."); DEFINE_string(custom_credentials_type, "", "User provided credentials type."); DEFINE_bool(use_test_ca, false, "False to use SSL roots for google"); diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc index fee34c52c3..29b5a1ed6c 100644 --- a/test/cpp/interop/client_helper.cc +++ b/test/cpp/interop/client_helper.cc @@ -23,18 +23,19 @@ #include <sstream> #include <gflags/gflags.h> -#include <grpc++/channel.h> -#include <grpc++/create_channel.h> -#include <grpc++/security/credentials.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include <grpcpp/channel.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/security/credentials.h> #include "src/cpp/client/secure_credentials.h" #include "test/core/security/oauth2_utils.h" #include "test/cpp/util/create_test_channel.h" #include "test/cpp/util/test_credentials_provider.h" +DECLARE_bool(use_alts); DECLARE_bool(use_tls); DECLARE_string(custom_credentials_type); DECLARE_bool(use_test_ca); @@ -103,8 +104,10 @@ std::shared_ptr<Channel> CreateChannelForTestCase( GPR_ASSERT(creds); } if (FLAGS_custom_credentials_type.empty()) { + transport_security security_type = + FLAGS_use_alts ? ALTS : (FLAGS_use_tls ? TLS : INSECURE); return CreateTestChannel(host_port, FLAGS_server_host_override, - FLAGS_use_tls, !FLAGS_use_test_ca, creds); + security_type, !FLAGS_use_test_ca, creds); } else { return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds); } diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h index f6e5bc9a51..eada2f671f 100644 --- a/test/cpp/interop/client_helper.h +++ b/test/cpp/interop/client_helper.h @@ -22,7 +22,7 @@ #include <memory> #include <unordered_map> -#include <grpc++/channel.h> +#include <grpcpp/channel.h> #include "src/core/lib/surface/call_test_only.h" diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc index 2de7abcf17..543f159265 100644 --- a/test/cpp/interop/http2_client.cc +++ b/test/cpp/interop/http2_client.cc @@ -19,18 +19,18 @@ #include <thread> #include <gflags/gflags.h> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> #include "src/core/lib/transport/byte_stream.h" #include "src/proto/grpc/testing/messages.pb.h" #include "src/proto/grpc/testing/test.grpc.pb.h" #include "test/cpp/interop/http2_client.h" -#include "src/core/lib/support/string.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "test/cpp/util/create_test_channel.h" #include "test/cpp/util/test_config.h" @@ -194,7 +194,7 @@ int main(int argc, char** argv) { snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(), FLAGS_server_port); std::shared_ptr<grpc::Channel> channel = - grpc::CreateTestChannel(host_port, false); + grpc::CreateTestChannel(host_port, grpc::testing::INSECURE); GPR_ASSERT(channel->WaitForConnected(gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(300, GPR_TIMESPAN)))); grpc::testing::Http2Client client(channel); diff --git a/test/cpp/interop/http2_client.h b/test/cpp/interop/http2_client.h index f64041a803..2bcfdd69db 100644 --- a/test/cpp/interop/http2_client.h +++ b/test/cpp/interop/http2_client.h @@ -21,8 +21,8 @@ #include <memory> -#include <grpc++/channel.h> #include <grpc/grpc.h> +#include <grpcpp/channel.h> #include "src/proto/grpc/testing/messages.pb.h" #include "src/proto/grpc/testing/test.grpc.pb.h" diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index af97fe0940..68bf1e6dc7 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -20,15 +20,14 @@ #include <fstream> #include <memory> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/security/credentials.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include <grpc/support/useful.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/security/credentials.h> #include "src/core/lib/transport/byte_stream.h" #include "src/proto/grpc/testing/empty.pb.h" @@ -122,7 +121,8 @@ InteropClient::InteropClient(std::shared_ptr<Channel> channel, : serviceStub_(channel, new_stub_every_test_case), do_not_abort_on_transient_failures_(do_not_abort_on_transient_failures) {} -bool InteropClient::AssertStatusOk(const Status& s) { +bool InteropClient::AssertStatusOk(const Status& s, + const grpc::string& optional_debug_string) { if (s.ok()) { return true; } @@ -131,17 +131,21 @@ bool InteropClient::AssertStatusOk(const Status& s) { // already checked for s.ok() above). So, the following will call abort() // (unless s.error_code() corresponds to a transient failure and // 'do_not_abort_on_transient_failures' is true) - return AssertStatusCode(s, StatusCode::OK); + return AssertStatusCode(s, StatusCode::OK, optional_debug_string); } -bool InteropClient::AssertStatusCode(const Status& s, - StatusCode expected_code) { +bool InteropClient::AssertStatusCode( + const Status& s, StatusCode expected_code, + const grpc::string& optional_debug_string) { if (s.error_code() == expected_code) { return true; } - gpr_log(GPR_ERROR, "Error status code: %d (expected: %d), message: %s", - s.error_code(), expected_code, s.error_message().c_str()); + gpr_log(GPR_ERROR, + "Error status code: %d (expected: %d), message: %s," + " debug string: %s", + s.error_code(), expected_code, s.error_message().c_str(), + optional_debug_string.c_str()); // In case of transient transient/retryable failures (like a broken // connection) we may or may not abort (see TransientFailureOrAbort()) @@ -161,7 +165,7 @@ bool InteropClient::DoEmpty() { Status s = serviceStub_.Get()->EmptyCall(&context, request, &response); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -191,7 +195,7 @@ bool InteropClient::PerformLargeUnary(SimpleRequest* request, } Status s = serviceStub_.Get()->UnaryCall(&context, *request, response); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -241,7 +245,7 @@ bool InteropClient::DoOauth2AuthToken(const grpc::string& username, Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -269,7 +273,7 @@ bool InteropClient::DoPerRpcCreds(const grpc::string& json_key) { Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -412,7 +416,7 @@ bool InteropClient::DoRequestStreaming() { GPR_ASSERT(stream->WritesDone()); Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -451,7 +455,7 @@ bool InteropClient::DoResponseStreaming() { } Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -516,7 +520,7 @@ bool InteropClient::DoClientCompressedStreaming() { GPR_ASSERT(stream->WritesDone()); s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -578,7 +582,7 @@ bool InteropClient::DoServerCompressedStreaming() { } Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } return true; @@ -619,7 +623,7 @@ bool InteropClient::DoResponseStreamingWithSlowConsumer() { } Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -666,7 +670,7 @@ bool InteropClient::DoHalfDuplex() { } Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -710,7 +714,7 @@ bool InteropClient::DoPingPong() { GPR_ASSERT(!stream->Read(&response)); Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -732,7 +736,8 @@ bool InteropClient::DoCancelAfterBegin() { context.TryCancel(); Status s = stream->Finish(); - if (!AssertStatusCode(s, StatusCode::CANCELLED)) { + if (!AssertStatusCode(s, StatusCode::CANCELLED, + context.debug_error_string())) { return false; } @@ -790,7 +795,8 @@ bool InteropClient::DoTimeoutOnSleepingServer() { stream->Write(request); Status s = stream->Finish(); - if (!AssertStatusCode(s, StatusCode::DEADLINE_EXCEEDED)) { + if (!AssertStatusCode(s, StatusCode::DEADLINE_EXCEEDED, + context.debug_error_string())) { return false; } @@ -810,7 +816,7 @@ bool InteropClient::DoEmptyStream() { GPR_ASSERT(stream->Read(&response) == false); Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -833,7 +839,8 @@ bool InteropClient::DoStatusWithMessage() { requested_status->set_code(test_code); requested_status->set_message(test_msg); Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN)) { + if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN, + context.debug_error_string())) { return false; } GPR_ASSERT(s.error_message() == test_msg); @@ -853,7 +860,8 @@ bool InteropClient::DoStatusWithMessage() { while (stream->Read(&streaming_response)) ; s = stream->Finish(); - if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN)) { + if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN, + context.debug_error_string())) { return false; } GPR_ASSERT(s.error_message() == test_msg); @@ -867,7 +875,8 @@ bool InteropClient::DoCacheableUnary() { // Create request with current timestamp gpr_timespec ts = gpr_now(GPR_CLOCK_PRECISE); - std::string timestamp = std::to_string((long long unsigned)ts.tv_nsec); + std::string timestamp = + std::to_string(static_cast<long long unsigned>(ts.tv_nsec)); SimpleRequest request; request.mutable_payload()->set_body(timestamp.c_str(), timestamp.size()); @@ -880,7 +889,7 @@ bool InteropClient::DoCacheableUnary() { context1.AddMetadata("x-user-ip", "1.2.3.4"); Status s1 = serviceStub_.Get()->CacheableUnaryCall(&context1, request, &response1); - if (!AssertStatusOk(s1)) { + if (!AssertStatusOk(s1, context1.debug_error_string())) { return false; } gpr_log(GPR_DEBUG, "response 1 payload: %s", @@ -893,7 +902,7 @@ bool InteropClient::DoCacheableUnary() { context2.AddMetadata("x-user-ip", "1.2.3.4"); Status s2 = serviceStub_.Get()->CacheableUnaryCall(&context2, request, &response2); - if (!AssertStatusOk(s2)) { + if (!AssertStatusOk(s2, context2.debug_error_string())) { return false; } gpr_log(GPR_DEBUG, "response 2 payload: %s", @@ -906,7 +915,7 @@ bool InteropClient::DoCacheableUnary() { // Request 3 // Modify the request body so it will not get a cache hit ts = gpr_now(GPR_CLOCK_PRECISE); - timestamp = std::to_string((long long unsigned)ts.tv_nsec); + timestamp = std::to_string(static_cast<long long unsigned>(ts.tv_nsec)); SimpleRequest request1; request1.mutable_payload()->set_body(timestamp.c_str(), timestamp.size()); ClientContext context3; @@ -915,7 +924,7 @@ bool InteropClient::DoCacheableUnary() { context3.AddMetadata("x-user-ip", "1.2.3.4"); Status s3 = serviceStub_.Get()->CacheableUnaryCall(&context3, request1, &response3); - if (!AssertStatusOk(s3)) { + if (!AssertStatusOk(s3, context3.debug_error_string())) { return false; } gpr_log(GPR_DEBUG, "response 3 payload: %s", @@ -946,7 +955,7 @@ bool InteropClient::DoCustomMetadata() { request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -997,7 +1006,7 @@ bool InteropClient::DoCustomMetadata() { GPR_ASSERT(!stream->Read(&response)); Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -1028,7 +1037,8 @@ bool InteropClient::DoUnimplementedService() { Status s = stub->UnimplementedCall(&context, request, &response); - if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED)) { + if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED, + context.debug_error_string())) { return false; } @@ -1046,7 +1056,8 @@ bool InteropClient::DoUnimplementedMethod() { Status s = serviceStub_.Get()->UnimplementedCall(&context, request, &response); - if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED)) { + if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED, + context.debug_error_string())) { return false; } diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 57e8ba63f5..79ff24fc47 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -21,8 +21,8 @@ #include <memory> -#include <grpc++/channel.h> #include <grpc/grpc.h> +#include <grpcpp/channel.h> #include "src/proto/grpc/testing/messages.pb.h" #include "src/proto/grpc/testing/test.grpc.pb.h" @@ -103,8 +103,10 @@ class InteropClient { /// Run \a custom_check_fn as an additional check. bool PerformLargeUnary(SimpleRequest* request, SimpleResponse* response, CheckerFn custom_checks_fn); - bool AssertStatusOk(const Status& s); - bool AssertStatusCode(const Status& s, StatusCode expected_code); + bool AssertStatusOk(const Status& s, + const grpc::string& optional_debug_string); + bool AssertStatusCode(const Status& s, StatusCode expected_code, + const grpc::string& optional_debug_string); bool TransientFailureOrAbort(); ServiceStub serviceStub_; diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index 30bd8bfef8..f55d624b21 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -22,16 +22,15 @@ #include <thread> #include <gflags/gflags.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/log.h> #include <grpc/support/time.h> -#include <grpc/support/useful.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/support/string.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/transport/byte_stream.h" #include "src/proto/grpc/testing/empty.pb.h" #include "src/proto/grpc/testing/messages.pb.h" @@ -39,6 +38,8 @@ #include "test/cpp/interop/server_helper.h" #include "test/cpp/util/test_config.h" +DEFINE_bool(use_alts, false, + "Whether to use alts. Enable alts will disable tls."); DEFINE_bool(use_tls, false, "Whether to use tls."); DEFINE_string(custom_credentials_type, "", "User provided credentials type."); DEFINE_int32(port, 0, "Server port."); @@ -317,12 +318,27 @@ class TestServiceImpl : public TestService::Service { void grpc::testing::interop::RunServer( std::shared_ptr<ServerCredentials> creds) { - RunServer(creds, FLAGS_port, nullptr); + RunServer(creds, FLAGS_port, nullptr, nullptr); +} + +void grpc::testing::interop::RunServer( + std::shared_ptr<ServerCredentials> creds, + std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>> + server_options) { + RunServer(creds, FLAGS_port, nullptr, std::move(server_options)); } void grpc::testing::interop::RunServer( std::shared_ptr<ServerCredentials> creds, const int port, ServerStartedCondition* server_started_condition) { + RunServer(creds, port, server_started_condition, nullptr); +} + +void grpc::testing::interop::RunServer( + std::shared_ptr<ServerCredentials> creds, const int port, + ServerStartedCondition* server_started_condition, + std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>> + server_options) { GPR_ASSERT(port != 0); std::ostringstream server_address; server_address << "0.0.0.0:" << port; @@ -334,6 +350,11 @@ void grpc::testing::interop::RunServer( ServerBuilder builder; builder.RegisterService(&service); builder.AddListeningPort(server_address.str(), creds); + if (server_options != nullptr) { + for (size_t i = 0; i < server_options->size(); i++) { + builder.SetOption(std::move((*server_options)[i])); + } + } if (FLAGS_max_send_message_size >= 0) { builder.SetMaxSendMessageSize(FLAGS_max_send_message_size); } diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index 1bf0d8d10f..ae155b65f9 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -31,14 +31,14 @@ #include <gflags/gflags.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include "test/core/util/port.h" #include "test/cpp/util/test_config.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_utils_posix.h" -#include "src/core/lib/support/string.h" DEFINE_string(extra_server_flags, "", "Extra flags to pass to server."); diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc index 1c6237879d..02cd564335 100644 --- a/test/cpp/interop/metrics_client.cc +++ b/test/cpp/interop/metrics_client.cc @@ -20,8 +20,8 @@ #include <string> #include <gflags/gflags.h> -#include <grpc++/grpc++.h> #include <grpc/support/log.h> +#include <grpcpp/grpcpp.h> #include "src/proto/grpc/testing/metrics.grpc.pb.h" #include "src/proto/grpc/testing/metrics.pb.h" diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc index 2d9397a2b8..8a071d417e 100644 --- a/test/cpp/interop/reconnect_interop_client.cc +++ b/test/cpp/interop/reconnect_interop_client.cc @@ -20,11 +20,11 @@ #include <sstream> #include <gflags/gflags.h> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/support/channel_arguments.h> #include <grpc/grpc.h> #include <grpc/support/log.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/support/channel_arguments.h> #include "src/proto/grpc/testing/empty.pb.h" #include "src/proto/grpc/testing/messages.pb.h" #include "src/proto/grpc/testing/test.grpc.pb.h" @@ -44,9 +44,11 @@ using grpc::ClientContext; using grpc::CreateTestChannel; using grpc::Status; using grpc::testing::Empty; +using grpc::testing::INSECURE; using grpc::testing::ReconnectInfo; using grpc::testing::ReconnectParams; using grpc::testing::ReconnectService; +using grpc::testing::TLS; int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); @@ -57,7 +59,7 @@ int main(int argc, char** argv) { server_address << FLAGS_server_host << ':' << FLAGS_server_control_port; std::unique_ptr<ReconnectService::Stub> control_stub( ReconnectService::NewStub( - CreateTestChannel(server_address.str(), false))); + CreateTestChannel(server_address.str(), INSECURE))); ClientContext start_context; ReconnectParams reconnect_params; reconnect_params.set_max_reconnect_backoff_ms(FLAGS_max_reconnect_backoff_ms); @@ -75,7 +77,7 @@ int main(int argc, char** argv) { FLAGS_max_reconnect_backoff_ms); } std::shared_ptr<Channel> retry_channel = - CreateTestChannel(server_address.str(), "foo.test.google.fr", true, false, + CreateTestChannel(server_address.str(), "foo.test.google.fr", TLS, false, std::shared_ptr<CallCredentials>(), channel_args); // About 13 retries. diff --git a/test/cpp/interop/reconnect_interop_server.cc b/test/cpp/interop/reconnect_interop_server.cc index 5e257e1b38..e690c8fb00 100644 --- a/test/cpp/interop/reconnect_interop_server.cc +++ b/test/cpp/interop/reconnect_interop_server.cc @@ -26,11 +26,11 @@ #include <sstream> #include <gflags/gflags.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/grpc.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/empty.pb.h" #include "src/proto/grpc/testing/messages.pb.h" diff --git a/test/cpp/interop/server_helper.cc b/test/cpp/interop/server_helper.cc index be449a9262..2194521998 100644 --- a/test/cpp/interop/server_helper.cc +++ b/test/cpp/interop/server_helper.cc @@ -21,11 +21,12 @@ #include <memory> #include <gflags/gflags.h> -#include <grpc++/security/server_credentials.h> +#include <grpcpp/security/server_credentials.h> #include "src/core/lib/surface/call_test_only.h" #include "test/cpp/util/test_credentials_provider.h" +DECLARE_bool(use_alts); DECLARE_bool(use_tls); DECLARE_string(custom_credentials_type); @@ -36,6 +37,8 @@ std::shared_ptr<ServerCredentials> CreateInteropServerCredentials() { if (!FLAGS_custom_credentials_type.empty()) { return GetCredentialsProvider()->GetServerCredentials( FLAGS_custom_credentials_type); + } else if (FLAGS_use_alts) { + return GetCredentialsProvider()->GetServerCredentials(kAltsCredentialsType); } else if (FLAGS_use_tls) { return GetCredentialsProvider()->GetServerCredentials(kTlsCredentialsType); } else { diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h index 1bf7db1e14..265874df70 100644 --- a/test/cpp/interop/server_helper.h +++ b/test/cpp/interop/server_helper.h @@ -25,8 +25,10 @@ #include <grpc/compression.h> #include <grpc/impl/codegen/atm.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server_context.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> namespace grpc { namespace testing { @@ -72,6 +74,28 @@ void RunServer(std::shared_ptr<ServerCredentials> creds); void RunServer(std::shared_ptr<ServerCredentials> creds, int port, ServerStartedCondition* server_started_condition); +/// Run gRPC interop server. +/// +/// \param creds The credentials associated with the server. +/// \param server_options List of options to set when building the server. +void RunServer( + std::shared_ptr<ServerCredentials> creds, + std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>> + server_options); + +/// Run gRPC interop server. +/// +/// \param creds The credentials associated with the server. +/// \param port Port to use for the server. +/// \param server_options List of options to set when building the server. +/// \param server_started_condition (optional) Struct holding mutex, condition +// variable, and condition used to notify when the server has started. +void RunServer( + std::shared_ptr<ServerCredentials> creds, const int port, + ServerStartedCondition* server_started_condition, + std::unique_ptr<std::vector<std::unique_ptr<grpc::ServerBuilderOption>>> + server_options); + } // namespace interop } // namespace testing } // namespace grpc diff --git a/test/cpp/interop/stress_interop_client.cc b/test/cpp/interop/stress_interop_client.cc index 7afddbb26b..30a8351cfe 100644 --- a/test/cpp/interop/stress_interop_client.cc +++ b/test/cpp/interop/stress_interop_client.cc @@ -22,8 +22,8 @@ #include <string> #include <vector> -#include <grpc++/create_channel.h> #include <grpc/support/log.h> +#include <grpcpp/create_channel.h> #include "test/cpp/interop/interop_client.h" #include "test/cpp/util/metrics_server.h" diff --git a/test/cpp/interop/stress_interop_client.h b/test/cpp/interop/stress_interop_client.h index ee15be0f08..a306dc3565 100644 --- a/test/cpp/interop/stress_interop_client.h +++ b/test/cpp/interop/stress_interop_client.h @@ -23,7 +23,7 @@ #include <string> #include <vector> -#include <grpc++/create_channel.h> +#include <grpcpp/create_channel.h> #include "test/cpp/interop/interop_client.h" #include "test/cpp/util/metrics_server.h" diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc index 4b39dc3211..023e0c8f0b 100644 --- a/test/cpp/interop/stress_test.cc +++ b/test/cpp/interop/stress_test.cc @@ -23,10 +23,10 @@ #include <vector> #include <gflags/gflags.h> -#include <grpc++/create_channel.h> -#include <grpc++/grpc++.h> #include <grpc/support/log.h> #include <grpc/support/time.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/grpcpp.h> #include "src/proto/grpc/testing/metrics.grpc.pb.h" #include "src/proto/grpc/testing/metrics.pb.h" @@ -99,18 +99,24 @@ DEFINE_bool(do_not_abort_on_transient_failures, true, // Options from client.cc (for compatibility with interop test). // TODO(sreek): Consolidate overlapping options +DEFINE_bool(use_alts, false, + "Whether to use alts. Enable alts will disable tls."); DEFINE_bool(use_tls, false, "Whether to use tls."); DEFINE_bool(use_test_ca, false, "False to use SSL roots for google"); DEFINE_string(server_host_override, "foo.test.google.fr", "Override the server host which is sent in HTTP header"); +using grpc::testing::ALTS; +using grpc::testing::INSECURE; using grpc::testing::MetricsService; using grpc::testing::MetricsServiceImpl; using grpc::testing::StressTestInteropClient; +using grpc::testing::TLS; using grpc::testing::TestCaseType; using grpc::testing::UNKNOWN_TEST; using grpc::testing::WeightedRandomTestSelector; using grpc::testing::kTestCaseList; +using grpc::testing::transport_security; static int log_level = GPR_LOG_SEVERITY_DEBUG; @@ -268,6 +274,8 @@ int main(int argc, char** argv) { int thread_idx = 0; int server_idx = -1; char buffer[256]; + transport_security security_type = + FLAGS_use_alts ? ALTS : (FLAGS_use_tls ? TLS : INSECURE); for (auto it = server_addresses.begin(); it != server_addresses.end(); it++) { ++server_idx; // Create channel(s) for each server @@ -276,7 +284,7 @@ int main(int argc, char** argv) { gpr_log(GPR_INFO, "Starting test with %s channel_idx=%d..", it->c_str(), channel_idx); std::shared_ptr<grpc::Channel> channel = grpc::CreateTestChannel( - *it, FLAGS_server_host_override, FLAGS_use_tls, !FLAGS_use_test_ca); + *it, FLAGS_server_host_override, security_type, !FLAGS_use_test_ca); // Create stub(s) for each channel for (int stub_idx = 0; stub_idx < FLAGS_num_stubs_per_channel; diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 0b69e9ba9a..5dcfd94ed3 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -42,6 +42,7 @@ grpc_cc_library( "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", + "//test/cpp/util:test_config", ], ) @@ -113,10 +114,7 @@ grpc_cc_binary( name = "bm_fullstack_trickle", testonly = 1, srcs = ["bm_fullstack_trickle.cc"], - deps = [ - ":helpers", - "//test/cpp/util:test_config", - ], + deps = [":helpers"], ) grpc_cc_library( @@ -143,3 +141,10 @@ grpc_cc_binary( srcs = ["bm_metadata.cc"], deps = [":helpers"], ) + +grpc_cc_binary( + name = "bm_chttp2_hpack", + testonly = 1, + srcs = ["bm_chttp2_hpack.cc"], + deps = [":helpers"], +) diff --git a/test/cpp/microbenchmarks/bm_arena.cc b/test/cpp/microbenchmarks/bm_arena.cc index 5b7c611919..b97c954fae 100644 --- a/test/cpp/microbenchmarks/bm_arena.cc +++ b/test/cpp/microbenchmarks/bm_arena.cc @@ -18,9 +18,10 @@ /* Benchmark arenas */ -#include "src/core/lib/support/arena.h" +#include <benchmark/benchmark.h> +#include "src/core/lib/gpr/arena.h" #include "test/cpp/microbenchmarks/helpers.h" -#include "third_party/benchmark/include/benchmark/benchmark.h" +#include "test/cpp/util/test_config.h" static void BM_Arena_NoOp(benchmark::State& state) { while (state.KeepRunning()) { @@ -56,4 +57,15 @@ static void BM_Arena_Batch(benchmark::State& state) { } BENCHMARK(BM_Arena_Batch)->Ranges({{1, 64 * 1024}, {1, 64}, {1, 1024}}); -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 5c2c38c27d..831b29c506 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -23,11 +23,11 @@ #include <string.h> #include <sstream> -#include <grpc++/channel.h> -#include <grpc++/support/channel_arguments.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/string_util.h> +#include <grpcpp/channel.h> +#include <grpcpp/support/channel_arguments.h> #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" @@ -46,6 +46,7 @@ #include "src/cpp/client/create_channel_internal.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" auto& force_library_initialization = Library::get(); @@ -813,4 +814,15 @@ static void BM_IsolatedCall_StreamingSend(benchmark::State& state) { } BENCHMARK(BM_IsolatedCall_StreamingSend); -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 4b7310389c..823c76f755 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -18,9 +18,11 @@ /* Microbenchmarks around CHTTP2 HPACK operations */ +#include <benchmark/benchmark.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <string.h> +#include <memory> #include <sstream> #include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" @@ -31,7 +33,7 @@ #include "src/core/lib/transport/timeout_encoding.h" #include "test/cpp/microbenchmarks/helpers.h" -#include "third_party/benchmark/include/benchmark/benchmark.h" +#include "test/cpp/util/test_config.h" auto& force_library_initialization = Library::get(); @@ -51,10 +53,11 @@ static grpc_slice MakeSlice(std::vector<uint8_t> bytes) { static void BM_HpackEncoderInitDestroy(benchmark::State& state) { TrackCounters track_counters; grpc_core::ExecCtx exec_ctx; - grpc_chttp2_hpack_compressor c; + std::unique_ptr<grpc_chttp2_hpack_compressor> c( + new grpc_chttp2_hpack_compressor); while (state.KeepRunning()) { - grpc_chttp2_hpack_compressor_init(&c); - grpc_chttp2_hpack_compressor_destroy(&c); + grpc_chttp2_hpack_compressor_init(c.get()); + grpc_chttp2_hpack_compressor_destroy(c.get()); grpc_core::ExecCtx::Get()->Flush(); } @@ -71,8 +74,9 @@ static void BM_HpackEncoderEncodeDeadline(benchmark::State& state) { grpc_metadata_batch_init(&b); b.deadline = saved_now + 30 * 1000; - grpc_chttp2_hpack_compressor c; - grpc_chttp2_hpack_compressor_init(&c); + std::unique_ptr<grpc_chttp2_hpack_compressor> c( + new grpc_chttp2_hpack_compressor); + grpc_chttp2_hpack_compressor_init(c.get()); grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); grpc_slice_buffer outbuf; @@ -82,15 +86,15 @@ static void BM_HpackEncoderEncodeDeadline(benchmark::State& state) { static_cast<uint32_t>(state.iterations()), true, false, - (size_t)1024, + static_cast<size_t>(1024), &stats, }; - grpc_chttp2_encode_header(&c, nullptr, 0, &b, &hopt, &outbuf); + grpc_chttp2_encode_header(c.get(), nullptr, 0, &b, &hopt, &outbuf); grpc_slice_buffer_reset_and_unref_internal(&outbuf); grpc_core::ExecCtx::Get()->Flush(); } grpc_metadata_batch_destroy(&b); - grpc_chttp2_hpack_compressor_destroy(&c); + grpc_chttp2_hpack_compressor_destroy(c.get()); grpc_slice_buffer_destroy_internal(&outbuf); std::ostringstream label; @@ -120,8 +124,9 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State& state) { "addmd", grpc_metadata_batch_add_tail(&b, &storage[i], elems[i]))); } - grpc_chttp2_hpack_compressor c; - grpc_chttp2_hpack_compressor_init(&c); + std::unique_ptr<grpc_chttp2_hpack_compressor> c( + new grpc_chttp2_hpack_compressor); + grpc_chttp2_hpack_compressor_init(c.get()); grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); grpc_slice_buffer outbuf; @@ -131,10 +136,10 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State& state) { static_cast<uint32_t>(state.iterations()), state.range(0) != 0, Fixture::kEnableTrueBinary, - (size_t)state.range(1), + static_cast<size_t>(state.range(1)), &stats, }; - grpc_chttp2_encode_header(&c, nullptr, 0, &b, &hopt, &outbuf); + grpc_chttp2_encode_header(c.get(), nullptr, 0, &b, &hopt, &outbuf); if (!logged_representative_output && state.iterations() > 3) { logged_representative_output = true; for (size_t i = 0; i < outbuf.count; i++) { @@ -147,7 +152,7 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State& state) { grpc_core::ExecCtx::Get()->Flush(); } grpc_metadata_batch_destroy(&b); - grpc_chttp2_hpack_compressor_destroy(&c); + grpc_chttp2_hpack_compressor_destroy(c.get()); grpc_slice_buffer_destroy_internal(&outbuf); std::ostringstream label; @@ -777,7 +782,8 @@ static void OnHeaderNew(void* user_data, grpc_mdelem md) { if (GRPC_MDELEM_IS_INTERNED(md)) { /* not already parsed: parse it now, and store the * result away */ - cached_timeout = (grpc_millis*)gpr_malloc(sizeof(grpc_millis)); + cached_timeout = + static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis))); *cached_timeout = timeout; grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); } @@ -850,4 +856,15 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, SameDeadline, OnHeaderNew); } // namespace hpack_parser_fixtures -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index fcb1677d09..1e9bd273aa 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -18,10 +18,11 @@ /* Microbenchmarks around CHTTP2 transport operations */ -#include <grpc++/support/channel_arguments.h> +#include <benchmark/benchmark.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> +#include <grpcpp/support/channel_arguments.h> #include <string.h> #include <memory> #include <queue> @@ -33,7 +34,7 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/static_metadata.h" #include "test/cpp/microbenchmarks/helpers.h" -#include "third_party/benchmark/include/benchmark/benchmark.h" +#include "test/cpp/util/test_config.h" auto& force_library_initialization = Library::get(); @@ -398,13 +399,13 @@ static void BM_TransportStreamSend(benchmark::State& state) { memset(&op, 0, sizeof(op)); op.payload = &op_payload; }; - grpc_slice_buffer_stream send_stream; - grpc_slice_buffer send_buffer; - grpc_slice_buffer_init(&send_buffer); - grpc_slice_buffer_add(&send_buffer, gpr_slice_malloc(state.range(0))); - memset(GRPC_SLICE_START_PTR(send_buffer.slices[0]), 0, - GRPC_SLICE_LENGTH(send_buffer.slices[0])); - + // Create the send_message payload slice. + // Note: We use grpc_slice_malloc_large() instead of grpc_slice_malloc() + // to force the slice to be refcounted, so that it remains alive when it + // is unreffed after each send_message op. + grpc_slice send_slice = grpc_slice_malloc_large(state.range(0)); + memset(GRPC_SLICE_START_PTR(send_slice), 0, GRPC_SLICE_LENGTH(send_slice)); + grpc_core::ManualConstructor<grpc_core::SliceBufferByteStream> send_stream; grpc_metadata_batch b; grpc_metadata_batch_init(&b); b.deadline = GRPC_MILLIS_INF_FUTURE; @@ -424,14 +425,18 @@ static void BM_TransportStreamSend(benchmark::State& state) { gpr_event_set(bm_done, (void*)1); return; } + grpc_slice_buffer send_buffer; + grpc_slice_buffer_init(&send_buffer); + grpc_slice_buffer_add(&send_buffer, grpc_slice_ref(send_slice)); + send_stream.Init(&send_buffer, 0); + grpc_slice_buffer_destroy(&send_buffer); // force outgoing window to be yuge s->chttp2_stream()->flow_control->TestOnlyForceHugeWindow(); f.chttp2_transport()->flow_control->TestOnlyForceHugeWindow(); - grpc_slice_buffer_stream_init(&send_stream, &send_buffer, 0); reset_op(); op.on_complete = c.get(); op.send_message = true; - op.payload->send_message.send_message = &send_stream.base; + op.payload->send_message.send_message.reset(send_stream.get()); s->Op(&op); }); @@ -454,7 +459,7 @@ static void BM_TransportStreamSend(benchmark::State& state) { s.reset(); track_counters.Finish(state); grpc_metadata_batch_destroy(&b); - grpc_slice_buffer_destroy(&send_buffer); + grpc_slice_unref(send_slice); } BENCHMARK(BM_TransportStreamSend)->Range(0, 128 * 1024 * 1024); @@ -524,7 +529,7 @@ static void BM_TransportStreamRecv(benchmark::State& state) { grpc_transport_stream_op_batch_payload op_payload; memset(&op_payload, 0, sizeof(op_payload)); grpc_transport_stream_op_batch op; - grpc_byte_stream* recv_stream; + grpc_core::OrphanablePtr<grpc_core::ByteStream> recv_stream; grpc_slice incoming_data = CreateIncomingDataSlice(state.range(0), 16384); auto reset_op = [&]() { @@ -579,21 +584,20 @@ static void BM_TransportStreamRecv(benchmark::State& state) { drain = MakeClosure([&](grpc_error* error) { do { - if (received == recv_stream->length) { - grpc_byte_stream_destroy(recv_stream); + if (received == recv_stream->length()) { + recv_stream.reset(); GRPC_CLOSURE_SCHED(c.get(), GRPC_ERROR_NONE); return; } - } while (grpc_byte_stream_next(recv_stream, recv_stream->length - received, - drain_continue.get()) && - GRPC_ERROR_NONE == - grpc_byte_stream_pull(recv_stream, &recv_slice) && + } while (recv_stream->Next(recv_stream->length() - received, + drain_continue.get()) && + GRPC_ERROR_NONE == recv_stream->Pull(&recv_slice) && (received += GRPC_SLICE_LENGTH(recv_slice), grpc_slice_unref_internal(recv_slice), true)); }); drain_continue = MakeClosure([&](grpc_error* error) { - grpc_byte_stream_pull(recv_stream, &recv_slice); + recv_stream->Pull(&recv_slice); received += GRPC_SLICE_LENGTH(recv_slice); grpc_slice_unref_internal(recv_slice); GRPC_CLOSURE_RUN(drain.get(), GRPC_ERROR_NONE); @@ -635,4 +639,15 @@ static void BM_TransportStreamRecv(benchmark::State& state) { } BENCHMARK(BM_TransportStreamRecv)->Range(0, 128 * 1024 * 1024); -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc index 4d5a82c3f6..74ca1ce3a4 100644 --- a/test/cpp/microbenchmarks/bm_closure.cc +++ b/test/cpp/microbenchmarks/bm_closure.cc @@ -22,12 +22,13 @@ #include <grpc/grpc.h> #include <sstream> +#include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/support/spinlock.h" #include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" auto& force_library_initialization = Library::get(); @@ -384,7 +385,7 @@ static void BM_ClosureReschedOnExecCtx(benchmark::State& state) { grpc_core::ExecCtx exec_ctx; Rescheduler r(state, grpc_schedule_on_exec_ctx); r.ScheduleFirst(); - + grpc_core::ExecCtx::Get()->Flush(); track_counters.Finish(state); } BENCHMARK(BM_ClosureReschedOnExecCtx); @@ -415,4 +416,15 @@ static void BM_ClosureReschedOnCombinerFinally(benchmark::State& state) { } BENCHMARK(BM_ClosureReschedOnCombinerFinally); -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index 97242598f1..a7cb939265 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -20,11 +20,12 @@ * working */ #include <benchmark/benchmark.h> -#include <grpc++/completion_queue.h> -#include <grpc++/impl/grpc_library.h> #include <grpc/grpc.h> #include <grpc/support/log.h> +#include <grpcpp/completion_queue.h> +#include <grpcpp/impl/grpc_library.h> #include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" #include "src/core/lib/surface/completion_queue.h" @@ -148,4 +149,15 @@ BENCHMARK(BM_EmptyCore); } // namespace testing } // namespace grpc -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 874c834931..da095c3e68 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -24,6 +24,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/port.h" @@ -38,7 +39,7 @@ namespace testing { auto& force_library_initialization = Library::get(); -static void* g_tag = (void*)(intptr_t)10; // Some random number +static void* g_tag = (void*)static_cast<intptr_t>(10); // Some random number static grpc_completion_queue* g_cq; static grpc_event_engine_vtable g_vtable; static const grpc_event_engine_vtable* g_old_vtable; @@ -74,8 +75,9 @@ static grpc_error* pollset_work(grpc_pollset* ps, grpc_pollset_worker** worker, gpr_mu_unlock(&ps->mu); GPR_ASSERT(grpc_cq_begin_op(g_cq, g_tag)); - grpc_cq_end_op(g_cq, g_tag, GRPC_ERROR_NONE, cq_done_cb, nullptr, - (grpc_cq_completion*)gpr_malloc(sizeof(grpc_cq_completion))); + grpc_cq_end_op( + g_cq, g_tag, GRPC_ERROR_NONE, cq_done_cb, nullptr, + static_cast<grpc_cq_completion*>(gpr_malloc(sizeof(grpc_cq_completion)))); grpc_core::ExecCtx::Get()->Flush(); gpr_mu_lock(&ps->mu); return GRPC_ERROR_NONE; @@ -163,4 +165,15 @@ BENCHMARK(BM_Cq_Throughput)->ThreadRange(1, 16)->UseRealTime(); } // namespace testing } // namespace grpc -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc index d12f475a49..ae557a580a 100644 --- a/test/cpp/microbenchmarks/bm_error.cc +++ b/test/cpp/microbenchmarks/bm_error.cc @@ -25,6 +25,7 @@ #include "src/core/lib/transport/error_utils.h" #include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" auto& force_library_initialization = Library::get(); @@ -310,4 +311,15 @@ BENCHMARK_SUITE(ErrorWithGrpcStatus); BENCHMARK_SUITE(ErrorWithHttpError); BENCHMARK_SUITE(ErrorWithNestedGrpcStatus); -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc index 655e032faf..34df77aca3 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc @@ -19,6 +19,7 @@ /* Benchmark gRPC end2end in various configurations */ #include "test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h" +#include "test/cpp/util/test_config.h" namespace grpc { namespace testing { @@ -114,4 +115,15 @@ BENCHMARK_TEMPLATE(BM_StreamingPingPongWithCoalescingApi, MinInProcess, } // namespace testing } // namespace grpc -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc index c7ceacd320..da98f3cbcd 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc @@ -19,6 +19,7 @@ /* Benchmark gRPC end2end in various configurations */ #include "test/cpp/microbenchmarks/fullstack_streaming_pump.h" +#include "test/cpp/util/test_config.h" namespace grpc { namespace testing { @@ -64,4 +65,15 @@ BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, MinInProcessCHTTP2)->Arg(0); } // namespace testing } // namespace grpc -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc index d6d7d41e5e..1af92d2c80 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc @@ -79,9 +79,11 @@ static void write_csv(std::ostream* out, A0&& a0, Arg&&... arg) { class TrickledCHTTP2 : public EndpointPairFixture { public: TrickledCHTTP2(Service* service, bool streaming, size_t req_size, - size_t resp_size, size_t kilobits_per_second) - : EndpointPairFixture(service, MakeEndpoints(kilobits_per_second), - FixtureConfiguration()) { + size_t resp_size, size_t kilobits_per_second, + grpc_passthru_endpoint_stats* stats) + : EndpointPairFixture(service, MakeEndpoints(kilobits_per_second, stats), + FixtureConfiguration()), + stats_(stats) { if (FLAGS_log) { std::ostringstream fn; fn << "trickle." << (streaming ? "streaming" : "unary") << "." << req_size @@ -101,9 +103,15 @@ class TrickledCHTTP2 : public EndpointPairFixture { } } + virtual ~TrickledCHTTP2() { + if (stats_ != nullptr) { + grpc_passthru_endpoint_stats_destroy(stats_); + } + } + void AddToLabel(std::ostream& out, benchmark::State& state) { out << " writes/iter:" - << ((double)stats_.num_writes / (double)state.iterations()) + << ((double)stats_->num_writes / (double)state.iterations()) << " cli_transport_stalls/iter:" << ((double) client_stats_.streams_stalled_due_to_transport_flow_control / @@ -193,7 +201,7 @@ class TrickledCHTTP2 : public EndpointPairFixture { } private: - grpc_passthru_endpoint_stats stats_; + grpc_passthru_endpoint_stats* stats_; struct Stats { int streams_stalled_due_to_stream_flow_control = 0; int streams_stalled_due_to_transport_flow_control = 0; @@ -203,10 +211,11 @@ class TrickledCHTTP2 : public EndpointPairFixture { std::unique_ptr<std::ofstream> log_; gpr_timespec start_ = gpr_now(GPR_CLOCK_MONOTONIC); - grpc_endpoint_pair MakeEndpoints(size_t kilobits) { + static grpc_endpoint_pair MakeEndpoints(size_t kilobits, + grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), - &stats_); + stats); double bytes_per_second = 125.0 * kilobits; p.client = grpc_trickle_endpoint_create(p.client, bytes_per_second); p.server = grpc_trickle_endpoint_create(p.server, bytes_per_second); @@ -251,7 +260,8 @@ static void BM_PumpStreamServerToClient_Trickle(benchmark::State& state) { EchoTestService::AsyncService service; std::unique_ptr<TrickledCHTTP2> fixture(new TrickledCHTTP2( &service, true, state.range(0) /* req_size */, - state.range(0) /* resp_size */, state.range(1) /* bw in kbit/s */)); + state.range(0) /* resp_size */, state.range(1) /* bw in kbit/s */, + grpc_passthru_endpoint_stats_create())); { EchoResponse send_response; EchoResponse recv_response; @@ -344,7 +354,8 @@ static void BM_PumpUnbalancedUnary_Trickle(benchmark::State& state) { EchoTestService::AsyncService service; std::unique_ptr<TrickledCHTTP2> fixture(new TrickledCHTTP2( &service, false, state.range(0) /* req_size */, - state.range(1) /* resp_size */, state.range(2) /* bw in kbit/s */)); + state.range(1) /* resp_size */, state.range(2) /* bw in kbit/s */, + grpc_passthru_endpoint_stats_create())); EchoRequest send_request; EchoResponse send_response; EchoResponse recv_response; @@ -383,13 +394,13 @@ static void BM_PumpUnbalancedUnary_Trickle(benchmark::State& state) { stub->AsyncEcho(&cli_ctx, send_request, fixture->cq())); void* t; bool ok; + response_reader->Finish(&recv_response, &recv_status, tag(4)); TrickleCQNext(fixture.get(), &t, &ok, in_warmup ? -1 : state.iterations()); GPR_ASSERT(ok); GPR_ASSERT(t == tag(0) || t == tag(1)); intptr_t slot = reinterpret_cast<intptr_t>(t); ServerEnv* senv = server_env[slot]; senv->response_writer.Finish(send_response, Status::OK, tag(3)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); for (int i = (1 << 3) | (1 << 4); i != 0;) { TrickleCQNext(fixture.get(), &t, &ok, in_warmup ? -1 : state.iterations()); @@ -447,10 +458,16 @@ BENCHMARK(BM_PumpUnbalancedUnary_Trickle)->Apply(UnaryTrickleArgs); extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + int main(int argc, char** argv) { ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); grpc_timer_manager_set_threading(false); gpr_now_impl = ::grpc::testing::fake_now; - ::benchmark::RunSpecifiedBenchmarks(); + benchmark::RunTheBenchmarksNamespaced(); } diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc index fa41d114c0..5a7a8d5baf 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc @@ -19,6 +19,7 @@ /* Benchmark gRPC end2end in various configurations */ #include "test/cpp/microbenchmarks/fullstack_unary_ping_pong.h" +#include "test/cpp/util/test_config.h" namespace grpc { namespace testing { @@ -164,4 +165,15 @@ BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcess, NoOpMutator, } // namespace testing } // namespace grpc -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc index f1e7890fc0..553b33c402 100644 --- a/test/cpp/microbenchmarks/bm_metadata.cc +++ b/test/cpp/microbenchmarks/bm_metadata.cc @@ -25,6 +25,7 @@ #include "src/core/lib/transport/static_metadata.h" #include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" auto& force_library_initialization = Library::get(); @@ -290,4 +291,15 @@ static void BM_MetadataRefUnrefStatic(benchmark::State& state) { } BENCHMARK(BM_MetadataRefUnrefStatic); -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc index d9d5164cce..bcb68ff229 100644 --- a/test/cpp/microbenchmarks/bm_pollset.cc +++ b/test/cpp/microbenchmarks/bm_pollset.cc @@ -18,18 +18,19 @@ /* Test out pollset latencies */ +#include <benchmark/benchmark.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include <grpc/support/useful.h> +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/port.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "test/cpp/microbenchmarks/helpers.h" -#include "third_party/benchmark/include/benchmark/benchmark.h" +#include "test/cpp/util/test_config.h" #include <string.h> @@ -256,4 +257,15 @@ static void BM_SingleThreadPollOneFd(benchmark::State& state) { } BENCHMARK(BM_SingleThreadPollOneFd); -BENCHMARK_MAIN(); +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/fullstack_context_mutators.h b/test/cpp/microbenchmarks/fullstack_context_mutators.h index cafbeffdbe..6e7fd57540 100644 --- a/test/cpp/microbenchmarks/fullstack_context_mutators.h +++ b/test/cpp/microbenchmarks/fullstack_context_mutators.h @@ -19,14 +19,14 @@ #ifndef TEST_CPP_MICROBENCHMARKS_FULLSTACK_CONTEXT_MUTATORS_H #define TEST_CPP_MICROBENCHMARKS_FULLSTACK_CONTEXT_MUTATORS_H -#include <grpc++/channel.h> -#include <grpc++/create_channel.h> -#include <grpc++/security/credentials.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> #include <grpc/support/log.h> +#include <grpcpp/channel.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 "test/cpp/microbenchmarks/helpers.h" @@ -72,7 +72,7 @@ class RandomBinaryMetadata { grpc::string s; s.reserve(length + 1); for (int i = 0; i < length; i++) { - s += (char)rand(); + s += static_cast<char>(rand()); } return s; } @@ -95,7 +95,7 @@ class RandomAsciiMetadata { grpc::string s; s.reserve(length + 1); for (int i = 0; i < length; i++) { - s += (char)(rand() % 26 + 'a'); + s += static_cast<char>(rand() % 26 + 'a'); } return s; } diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index d1ede755a5..9d70277fbc 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -19,14 +19,14 @@ #ifndef TEST_CPP_MICROBENCHMARKS_FULLSTACK_FIXTURES_H #define TEST_CPP_MICROBENCHMARKS_FULLSTACK_FIXTURES_H -#include <grpc++/channel.h> -#include <grpc++/create_channel.h> -#include <grpc++/security/credentials.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> #include <grpc/support/atm.h> #include <grpc/support/log.h> +#include <grpcpp/channel.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 "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" @@ -61,6 +61,15 @@ class FixtureConfiguration { class BaseFixture : public TrackCounters {}; +// Special tag to be used in Server shutdown. This tag is *NEVER* returned when +// Cq->Next() API is called (This is because FinalizeResult() function in this +// class always returns 'false'). This is intentional and makes writing shutdown +// code easier. +class ShutdownTag : public internal::CompletionQueueTag { + public: + bool FinalizeResult(void** tag, bool* status) { return false; } +}; + class FullstackFixture : public BaseFixture { public: FullstackFixture(Service* service, const FixtureConfiguration& config, @@ -84,7 +93,11 @@ class FullstackFixture : public BaseFixture { } virtual ~FullstackFixture() { - server_->Shutdown(gpr_inf_past(GPR_CLOCK_MONOTONIC)); + // Dummy shutdown tag (this tag is swallowed by cq->Next() and is not + // returned to the user) see ShutdownTag definition for more details + ShutdownTag shutdown_tag; + grpc_server_shutdown_and_notify(server_->c_server(), cq_->cq(), + &shutdown_tag); cq_->Shutdown(); void* tag; bool ok; @@ -95,7 +108,8 @@ class FullstackFixture : public BaseFixture { void AddToLabel(std::ostream& out, benchmark::State& state) { BaseFixture::AddToLabel(out, state); out << " polls/iter:" - << (double)grpc_get_cq_poll_num(this->cq()->cq()) / state.iterations(); + << static_cast<double>(grpc_get_cq_poll_num(this->cq()->cq())) / + state.iterations(); } ServerCompletionQueue* cq() { return cq_.get(); } @@ -208,7 +222,11 @@ class EndpointPairFixture : public BaseFixture { } virtual ~EndpointPairFixture() { - server_->Shutdown(gpr_inf_past(GPR_CLOCK_MONOTONIC)); + // Dummy shutdown tag (this tag is swallowed by cq->Next() and is not + // returned to the user) see ShutdownTag definition for more details + ShutdownTag shutdown_tag; + grpc_server_shutdown_and_notify(server_->c_server(), cq_->cq(), + &shutdown_tag); cq_->Shutdown(); void* tag; bool ok; @@ -219,7 +237,8 @@ class EndpointPairFixture : public BaseFixture { void AddToLabel(std::ostream& out, benchmark::State& state) { BaseFixture::AddToLabel(out, state); out << " polls/iter:" - << (double)grpc_get_cq_poll_num(this->cq()->cq()) / state.iterations(); + << static_cast<double>(grpc_get_cq_poll_num(this->cq()->cq())) / + state.iterations(); } ServerCompletionQueue* cq() { return cq_.get(); } @@ -245,31 +264,53 @@ class SockPair : public EndpointPairFixture { fixture_configuration) {} }; -class InProcessCHTTP2 : public EndpointPairFixture { +/* Use InProcessCHTTP2 instead. This class (with stats as an explicit parameter) + is here only to be able to initialize both the base class and stats_ with the + same stats instance without accessing the stats_ fields before the object is + properly initialized. */ +class InProcessCHTTP2WithExplicitStats : public EndpointPairFixture { public: - InProcessCHTTP2(Service* service, - const FixtureConfiguration& fixture_configuration = - FixtureConfiguration()) - : EndpointPairFixture(service, MakeEndpoints(), fixture_configuration) {} + InProcessCHTTP2WithExplicitStats( + Service* service, grpc_passthru_endpoint_stats* stats, + const FixtureConfiguration& fixture_configuration) + : EndpointPairFixture(service, MakeEndpoints(stats), + fixture_configuration), + stats_(stats) {} + + virtual ~InProcessCHTTP2WithExplicitStats() { + if (stats_ != nullptr) { + grpc_passthru_endpoint_stats_destroy(stats_); + } + } void AddToLabel(std::ostream& out, benchmark::State& state) { EndpointPairFixture::AddToLabel(out, state); out << " writes/iter:" - << static_cast<double>(gpr_atm_no_barrier_load(&stats_.num_writes)) / + << static_cast<double>(gpr_atm_no_barrier_load(&stats_->num_writes)) / static_cast<double>(state.iterations()); } private: - grpc_passthru_endpoint_stats stats_; + grpc_passthru_endpoint_stats* stats_; - grpc_endpoint_pair MakeEndpoints() { + static grpc_endpoint_pair MakeEndpoints(grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), - &stats_); + stats); return p; } }; +class InProcessCHTTP2 : public InProcessCHTTP2WithExplicitStats { + public: + InProcessCHTTP2(Service* service, + const FixtureConfiguration& fixture_configuration = + FixtureConfiguration()) + : InProcessCHTTP2WithExplicitStats(service, + grpc_passthru_endpoint_stats_create(), + fixture_configuration) {} +}; + //////////////////////////////////////////////////////////////////////////////// // Minimal stack fixtures diff --git a/test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h b/test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h index 0763d07855..f399949a32 100644 --- a/test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h @@ -83,7 +83,7 @@ static void BM_StreamingPingPong(benchmark::State& state) { while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } @@ -99,7 +99,7 @@ static void BM_StreamingPingPong(benchmark::State& state) { while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); // If server recv is complete, start the server send operation if (i == 1) { @@ -122,7 +122,7 @@ static void BM_StreamingPingPong(benchmark::State& state) { need_tags = (1 << 0) | (1 << 1) | (1 << 2); while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } @@ -175,7 +175,7 @@ static void BM_StreamingPingPongMsgs(benchmark::State& state) { while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } @@ -190,7 +190,7 @@ static void BM_StreamingPingPongMsgs(benchmark::State& state) { while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); // If server recv is complete, start the server send operation if (i == 1) { @@ -210,7 +210,7 @@ static void BM_StreamingPingPongMsgs(benchmark::State& state) { need_tags = (1 << 0) | (1 << 1) | (1 << 2); while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } @@ -297,10 +297,10 @@ static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) { // established). It is necessary when client init metadata is // coalesced GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - while ((int)(intptr_t)t != 0) { + while (static_cast<int>((intptr_t)t) != 0) { // In some cases tag:2 comes before tag:0 (write tag comes out // first), this while loop is to make sure get tag:0. - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(await_tags & (1 << i)); await_tags &= ~(1 << i); GPR_ASSERT(fixture->cq()->Next(&t, &ok)); @@ -317,7 +317,7 @@ static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) { while (await_tags != 0) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); // If server recv is complete, start the server send operation if (i == 3) { @@ -367,8 +367,8 @@ static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) { // wait for server call data structure(call_hook, etc.) to be // initialized, since initial metadata is corked. GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - while ((int)(intptr_t)t != 0) { - int i = (int)(intptr_t)t; + while (static_cast<int>((intptr_t)t) != 0) { + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(expect_tags & (1 << i)); expect_tags &= ~(1 << i); GPR_ASSERT(fixture->cq()->Next(&t, &ok)); @@ -385,7 +385,7 @@ static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) { while (expect_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(expect_tags & (1 << i)); expect_tags &= ~(1 << i); } diff --git a/test/cpp/microbenchmarks/fullstack_streaming_pump.h b/test/cpp/microbenchmarks/fullstack_streaming_pump.h index 9e826091ec..3623e373f6 100644 --- a/test/cpp/microbenchmarks/fullstack_streaming_pump.h +++ b/test/cpp/microbenchmarks/fullstack_streaming_pump.h @@ -62,7 +62,7 @@ static void BM_PumpStreamClientToServer(benchmark::State& state) { while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } @@ -85,7 +85,7 @@ static void BM_PumpStreamClientToServer(benchmark::State& state) { need_tags = (1 << 0) | (1 << 1); while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } @@ -95,7 +95,7 @@ static void BM_PumpStreamClientToServer(benchmark::State& state) { need_tags = (1 << 0) | (1 << 1); while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } @@ -131,7 +131,7 @@ static void BM_PumpStreamServerToClient(benchmark::State& state) { while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } @@ -154,7 +154,7 @@ static void BM_PumpStreamServerToClient(benchmark::State& state) { need_tags = (1 << 0) | (1 << 1); while (need_tags) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); - int i = (int)(intptr_t)t; + int i = static_cast<int>((intptr_t)t); GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); } diff --git a/test/cpp/microbenchmarks/fullstack_unary_ping_pong.h b/test/cpp/microbenchmarks/fullstack_unary_ping_pong.h index d448938295..843c8e1486 100644 --- a/test/cpp/microbenchmarks/fullstack_unary_ping_pong.h +++ b/test/cpp/microbenchmarks/fullstack_unary_ping_pong.h @@ -78,6 +78,7 @@ static void BM_UnaryPingPong(benchmark::State& state) { ClientContextMutator cli_ctx_mut(&cli_ctx); std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( stub->AsyncEcho(&cli_ctx, send_request, fixture->cq())); + response_reader->Finish(&recv_response, &recv_status, tag(4)); void* t; bool ok; GPR_ASSERT(fixture->cq()->Next(&t, &ok)); @@ -87,11 +88,10 @@ static void BM_UnaryPingPong(benchmark::State& state) { ServerEnv* senv = server_env[slot]; ServerContextMutator svr_ctx_mut(&senv->ctx); senv->response_writer.Finish(send_response, Status::OK, tag(3)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); for (int i = (1 << 3) | (1 << 4); i != 0;) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int tagnum = (int)reinterpret_cast<intptr_t>(t); + int tagnum = static_cast<int>(reinterpret_cast<intptr_t>(t)); GPR_ASSERT(i & (1 << tagnum)); i -= 1 << tagnum; } diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc index a4c0a3a0ce..e4ba37e2d6 100644 --- a/test/cpp/microbenchmarks/helpers.cc +++ b/test/cpp/microbenchmarks/helpers.cc @@ -43,18 +43,15 @@ void TrackCounters::AddToLabel(std::ostream& out, benchmark::State& state) { grpc_stats_data stats; grpc_stats_diff(&stats_end, &stats_begin_, &stats); for (int i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) { - out << " " << grpc_stats_counter_name[i] - << "/iter:" << ((double)stats.counters[i] / (double)state.iterations()); + out << " " << grpc_stats_counter_name[i] << "/iter:" + << (static_cast<double>(stats.counters[i]) / + static_cast<double>(state.iterations())); } for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) { - std::ostringstream median_ss; - median_ss << grpc_stats_histogram_name[i] << "-median"; - state.counters[median_ss.str()] = benchmark::Counter( - grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 50.0)); - std::ostringstream tail_ss; - tail_ss << grpc_stats_histogram_name[i] << "-99p"; - state.counters[tail_ss.str()] = benchmark::Counter( - grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 99.0)); + out << " " << grpc_stats_histogram_name[i] << "-median:" + << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 50.0) + << " " << grpc_stats_histogram_name[i] << "-99p:" + << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 99.0); } #ifdef GPR_LOW_LEVEL_COUNTERS grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot(); diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h index afa3e0f3ca..4aabd4094a 100644 --- a/test/cpp/microbenchmarks/helpers.h +++ b/test/cpp/microbenchmarks/helpers.h @@ -27,7 +27,7 @@ #include "test/core/util/memory_counters.h" #include <benchmark/benchmark.h> -#include <grpc++/impl/grpc_library.h> +#include <grpcpp/impl/grpc_library.h> class Library { public: diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD index 24c3d1a443..fa0b216f8f 100644 --- a/test/cpp/naming/BUILD +++ b/test/cpp/naming/BUILD @@ -22,28 +22,17 @@ package( licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_py_binary") +load("//bazel:grpc_build_system.bzl", "grpc_py_binary") load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests") # Meant to be invoked only through the top-level shell script driver. -grpc_sh_binary( +grpc_py_binary( name = "resolver_component_tests_runner", srcs = [ - "resolver_component_tests_runner.sh", + "resolver_component_tests_runner.py", ], -) - -grpc_py_binary( - name = "test_dns_server", - srcs = ["test_dns_server.py"], - data = [ - "resolver_test_record_groups.yaml", - ], - deps = [ - "twisted", - "yaml", - ] + testonly = True, ) generate_resolver_component_tests() diff --git a/test/cpp/naming/README.md b/test/cpp/naming/README.md deleted file mode 100644 index e0dd208465..0000000000 --- a/test/cpp/naming/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resolver Tests - -This directory has tests and infrastructure for unit tests and GCE -integration tests of gRPC resolver functionality. - -There are two different tests here: - -## Resolver unit tests (resolver "component" tests) - -These tests run per-change, along with the rest of the grpc unit tests. -They query a local testing DNS server. - -## GCE integration tests - -These tests use the same test binary and the same test records -as the unit tests, but they run against GCE DNS (this is done by -running the test on a GCE instance and not specifying an authority -in uris). These tests run in a background job, which needs to be -actively monitored. - -## Making changes to test records - -After making a change to `resolver_test_record_groups.yaml`: - -1. Increment the "version number" in the `resolver_tests_common_zone_name` - DNS zone (this is a yaml field at the top - of `resolver_test_record_groups.yaml`). - -2. Regenerate projects. - -3. From the repo root, run: - -``` -$ test/cpp/naming/create_private_dns_zone.sh -$ test/cpp/naming/private_dns_zone_init.sh -``` - -Note that these commands must be ran in environment that -has access to the grpc-testing GCE project. - -If everything runs smoothly, then once the change is merged, -the GCE DNS integration testing job will transition to the -new records and continue passing. diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc new file mode 100644 index 0000000000..a92e9e3b3e --- /dev/null +++ b/test/cpp/naming/address_sorting_test.cc @@ -0,0 +1,768 @@ +/* + * + * 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/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 <string.h> + +#include <arpa/inet.h> +#include <gflags/gflags.h> +#include <gmock/gmock.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <vector> + +#include <address_sorting/address_sorting.h> +#include "test/cpp/util/subprocess.h" +#include "test/cpp/util/test_config.h" + +#include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +namespace { + +struct TestAddress { + std::string dest_addr; + int family; +}; + +grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) { + char* host; + char* port; + grpc_resolved_address resolved_addr; + gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port); + if (test_addr.family == AF_INET) { + sockaddr_in in_dest; + memset(&in_dest, 0, sizeof(sockaddr_in)); + in_dest.sin_port = htons(atoi(port)); + in_dest.sin_family = AF_INET; + GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1); + memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in)); + resolved_addr.len = sizeof(sockaddr_in); + } else { + GPR_ASSERT(test_addr.family == AF_INET6); + sockaddr_in6 in6_dest; + memset(&in6_dest, 0, sizeof(sockaddr_in6)); + in6_dest.sin6_port = htons(atoi(port)); + in6_dest.sin6_family = AF_INET6; + GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1); + memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6)); + resolved_addr.len = sizeof(sockaddr_in6); + } + gpr_free(host); + gpr_free(port); + return resolved_addr; +} + +class MockSourceAddrFactory : public address_sorting_source_addr_factory { + public: + MockSourceAddrFactory( + bool ipv4_supported, bool ipv6_supported, + const std::map<std::string, TestAddress>& dest_addr_to_src_addr) + : ipv4_supported_(ipv4_supported), + ipv6_supported_(ipv6_supported), + dest_addr_to_src_addr_(dest_addr_to_src_addr) {} + + bool GetSourceAddr(const address_sorting_address* dest_addr, + address_sorting_address* source_addr) { + if ((address_sorting_abstract_get_family(dest_addr) == + ADDRESS_SORTING_AF_INET && + !ipv4_supported_) || + (address_sorting_abstract_get_family(dest_addr) == + ADDRESS_SORTING_AF_INET6 && + !ipv6_supported_)) { + return false; + } + char* ip_addr_str; + grpc_resolved_address dest_addr_as_resolved_addr; + memcpy(&dest_addr_as_resolved_addr.addr, dest_addr, dest_addr->len); + dest_addr_as_resolved_addr.len = dest_addr->len; + grpc_sockaddr_to_string(&ip_addr_str, &dest_addr_as_resolved_addr, + false /* normalize */); + auto it = dest_addr_to_src_addr_.find(ip_addr_str); + if (it == dest_addr_to_src_addr_.end()) { + gpr_log(GPR_DEBUG, "can't find |%s| in dest to src map", ip_addr_str); + gpr_free(ip_addr_str); + return false; + } + gpr_free(ip_addr_str); + grpc_resolved_address source_addr_as_resolved_addr = + TestAddressToGrpcResolvedAddress(it->second); + memcpy(source_addr->addr, &source_addr_as_resolved_addr.addr, + source_addr_as_resolved_addr.len); + source_addr->len = source_addr_as_resolved_addr.len; + return true; + } + + private: + // user provided test config + bool ipv4_supported_; + bool ipv6_supported_; + std::map<std::string, TestAddress> dest_addr_to_src_addr_; +}; + +static bool mock_source_addr_factory_wrapper_get_source_addr( + address_sorting_source_addr_factory* factory, + const address_sorting_address* dest_addr, + address_sorting_address* source_addr) { + MockSourceAddrFactory* mock = + reinterpret_cast<MockSourceAddrFactory*>(factory); + return mock->GetSourceAddr(dest_addr, source_addr); +} + +void mock_source_addr_factory_wrapper_destroy( + address_sorting_source_addr_factory* factory) { + MockSourceAddrFactory* mock = + reinterpret_cast<MockSourceAddrFactory*>(factory); + delete mock; +} + +const address_sorting_source_addr_factory_vtable kMockSourceAddrFactoryVtable = + { + mock_source_addr_factory_wrapper_get_source_addr, + mock_source_addr_factory_wrapper_destroy, +}; + +void OverrideAddressSortingSourceAddrFactory( + bool ipv4_supported, bool ipv6_supported, + const std::map<std::string, TestAddress>& dest_addr_to_src_addr) { + address_sorting_source_addr_factory* factory = new MockSourceAddrFactory( + ipv4_supported, ipv6_supported, dest_addr_to_src_addr); + factory->vtable = &kMockSourceAddrFactoryVtable; + address_sorting_override_source_addr_factory_for_testing(factory); +} + +grpc_lb_addresses* BuildLbAddrInputs(std::vector<TestAddress> test_addrs) { + grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr); + lb_addrs->addresses = + (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size()); + lb_addrs->num_addresses = test_addrs.size(); + for (size_t i = 0; i < test_addrs.size(); i++) { + lb_addrs->addresses[i].address = + TestAddressToGrpcResolvedAddress(test_addrs[i]); + } + return lb_addrs; +} + +void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs, + std::vector<std::string> expected_addrs) { + EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size()); + for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + char* ip_addr_str; + grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address, + false /* normalize */); + EXPECT_EQ(expected_addrs[i], ip_addr_str); + gpr_free(ip_addr_str); + } + grpc_core::ExecCtx exec_ctx; + grpc_lb_addresses_destroy(lb_addrs); +} + +} // namespace + +/* Tests for rule 1 */ +TEST(AddressSortingTest, TestDepriotizesUnreachableAddresses) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}}, + }); + auto* lb_addrs = BuildLbAddrInputs({ + {"1.2.3.4:443", AF_INET}, + {"5.6.7.8:443", AF_INET}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "1.2.3.4:443", + "5.6.7.8:443", + }); +} + +TEST(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) { + bool ipv4_supported = true; + bool ipv6_supported = false; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}}, + }); + auto lb_addrs = BuildLbAddrInputs({ + {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, + {"1.2.3.4:443", AF_INET}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "1.2.3.4:443", + "[2607:f8b0:400a:801::1002]:443", + }); +} + +TEST(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) { + bool ipv4_supported = false; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}}, + {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, + {"1.2.3.4:443", AF_INET}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[2607:f8b0:400a:801::1002]:443", + "1.2.3.4:443", + }); +} + +/* Tests for rule 2 */ + +TEST(AddressSortingTest, TestDepriotizesNonMatchingScope) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[2000:f8b0:400a:801::1002]:443", + {"[fec0::1000]:0", AF_INET6}}, // global and site-local scope + {"[fec0::5000]:443", + {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[2000:f8b0:400a:801::1002]:443", AF_INET6}, + {"[fec0::5000]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[fec0::5000]:443", + "[2000:f8b0:400a:801::1002]:443", + }); +} + +/* Tests for rule 5 */ + +TEST(AddressSortingTest, TestUsesLabelFromDefaultTable) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}}, + {"[2001::5001]:443", + {"[2001::5002]:0", AF_INET6}}, // matching labels + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[2002::5001]:443", AF_INET6}, + {"[2001::5001]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[2001::5001]:443", + "[2002::5001]:443", + }); +} + +/* Flip the input on the test above to reorder the sort function's + * comparator's inputs. */ +TEST(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}}, + {"[2001::5001]:443", + {"[2001::5002]:0", AF_INET6}}, // matching labels + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[2001::5001]:443", AF_INET6}, + {"[2002::5001]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[2001::5001]:443", + "[2002::5001]:443", + }); +} + +/* Tests for rule 6 */ + +TEST(AddressSortingTest, + TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, + {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe::5001]:443", AF_INET6}, + {"1.2.3.4:443", AF_INET}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs( + lb_addrs, { + // The AF_INET address should be IPv4-mapped by the sort, + // and IPv4-mapped + // addresses have higher precedence than 3ffe::/16 by spec. + "1.2.3.4:443", + "[3ffe::5001]:443", + }); +} + +TEST(AddressSortingTest, + TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) { + bool ipv4_supported = true; + bool ipv6_supported = true; +// Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X. +#if GPR_APPLE == 1 + const char* v4_compat_dest = "[::0.0.0.2]:443"; + const char* v4_compat_src = "[::0.0.0.2]:0"; +#else + const char* v4_compat_dest = "[::2]:443"; + const char* v4_compat_src = "[::2]:0"; +#endif + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[::1]:443", {"[::1]:0", AF_INET6}}, + {v4_compat_dest, {v4_compat_src, AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {v4_compat_dest, AF_INET6}, + {"[::1]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[::1]:443", + v4_compat_dest, + }); +} + +TEST(AddressSortingTest, + TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + // 1234::2 for src and dest to make sure that prefix matching has no + // influence on this test. + {"[1234::2]:443", {"[1234::2]:0", AF_INET6}}, + {"[::1]:443", {"[::1]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[1234::2]:443", AF_INET6}, + {"[::1]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs( + lb_addrs, + { + // ::1 should match the localhost precedence entry and be prioritized + "[::1]:443", + "[1234::2]:443", + }); +} + +TEST(AddressSortingTest, + TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}}, + {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[2001::1234]:443", AF_INET6}, + {"[2000::5001]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs( + lb_addrs, { + // The 2000::/16 address should match the ::/0 prefix rule + "[2000::5001]:443", + "[2001::1234]:443", + }); +} + +TEST( + AddressSortingTest, + TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}}, + {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[2001::1231]:443", AF_INET6}, + {"[2000::5001]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[2000::5001]:443", + "[2001::1231]:443", + }); +} + +TEST(AddressSortingTest, + TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, + {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[fec0::1234]:443", AF_INET6}, + {"[fc00::5001]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[fc00::5001]:443", + "[fec0::1234]:443", + }); +} + +TEST( + AddressSortingTest, + TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[::ffff:0.0.0.2]:443", {"[::ffff:0.0.0.3]:0", AF_INET6}}, + {"[1234::2]:443", {"[1234::3]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[::ffff:0.0.0.2]:443", AF_INET6}, + {"[1234::2]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + // ::ffff:0:2 should match the v4-mapped + // precedence entry and be deprioritized. + "[1234::2]:443", + "[::ffff:0.0.0.2]:443", + }); +} + +/* Tests for rule 8 */ + +TEST(AddressSortingTest, TestPrefersSmallerScope) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + // Both of these destinations have the same precedence in default + // policy + // table. + {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, + {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe::5001]:443", AF_INET6}, + {"[fec0::1234]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[fec0::1234]:443", + "[3ffe::5001]:443", + }); +} + +/* Tests for rule 9 */ + +TEST(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + // Both of these destinations have the same precedence in default + // policy + // table. + {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}}, + {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe:5001::]:443", AF_INET6}, + {"[3ffe:1234::]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[3ffe:1234::]:443", + "[3ffe:5001::]:443", + }); +} + +TEST(AddressSortingTest, + TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}}, + {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe::5001]:443", AF_INET6}, + {"[3ffe::1234]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[3ffe::1234]:443", + "[3ffe::5001]:443", + }); +} + +TEST(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}}, + {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe:8000::]:443", AF_INET6}, + {"[3ffe:2000::]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[3ffe:2000::]:443", + "[3ffe:8000::]:443", + }); +} + +TEST(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}}, + {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe:6::]:443", AF_INET6}, + {"[3ffe:c::]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[3ffe:c::]:443", + "[3ffe:6::]:443", + }); +} + +TEST(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[3ffe:1111:1111:1111::]:443", + {"[3ffe:1111:1111:1111::]:0", AF_INET6}}, + {"[3ffe:1111:1111:1110::]:443", + {"[3ffe:1111:1111:1111::]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe:1111:1111:1110::]:443", AF_INET6}, + {"[3ffe:1111:1111:1111::]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[3ffe:1111:1111:1111::]:443", + "[3ffe:1111:1111:1110::]:443", + }); +} + +/* Tests for rule 10 */ + +TEST(AddressSortingTest, TestStableSort) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}}, + {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe::1234]:443", AF_INET6}, + {"[3ffe::1235]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[3ffe::1234]:443", + "[3ffe::1235]:443", + }); +} + +TEST(AddressSortingTest, TestStableSortFiveElements) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[3ffe::1231]:443", {"[3ffe::1201]:0", AF_INET6}}, + {"[3ffe::1232]:443", {"[3ffe::1202]:0", AF_INET6}}, + {"[3ffe::1233]:443", {"[3ffe::1203]:0", AF_INET6}}, + {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}}, + {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe::1231]:443", AF_INET6}, + {"[3ffe::1232]:443", AF_INET6}, + {"[3ffe::1233]:443", AF_INET6}, + {"[3ffe::1234]:443", AF_INET6}, + {"[3ffe::1235]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[3ffe::1231]:443", + "[3ffe::1232]:443", + "[3ffe::1233]:443", + "[3ffe::1234]:443", + "[3ffe::1235]:443", + }); +} + +TEST(AddressSortingTest, TestStableSortNoSrcAddrsExist) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[3ffe::1231]:443", AF_INET6}, + {"[3ffe::1232]:443", AF_INET6}, + {"[3ffe::1233]:443", AF_INET6}, + {"[3ffe::1234]:443", AF_INET6}, + {"[3ffe::1235]:443", AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[3ffe::1231]:443", + "[3ffe::1232]:443", + "[3ffe::1233]:443", + "[3ffe::1234]:443", + "[3ffe::1235]:443", + }); +} + +TEST(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) { + bool ipv4_supported = true; + bool ipv6_supported = true; + OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[::ffff:5.6.7.8]:443", AF_INET6}, + {"1.2.3.4:443", AF_INET}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, { + "[::ffff:5.6.7.8]:443", + "1.2.3.4:443", + }); +} + +TEST(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { + bool ipv4_supported = true; + bool ipv6_supported = true; +// Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X. +#if GPR_APPLE == 1 + const char* v4_compat_dest = "[::0.0.0.2]:443"; + const char* v4_compat_src = "[::0.0.0.3]:0"; +#else + const char* v4_compat_dest = "[::2]:443"; + const char* v4_compat_src = "[::3]:0"; +#endif + OverrideAddressSortingSourceAddrFactory( + ipv4_supported, ipv6_supported, + { + {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}}, + {v4_compat_dest, {v4_compat_src, AF_INET6}}, + }); + grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + {"[fec0::2000]:443", AF_INET6}, + {v4_compat_dest, AF_INET6}, + }); + grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + VerifyLbAddrOutputs(lb_addrs, + { + // The sort should be stable since + // v4-compatible has same precedence as site-local. + "[fec0::2000]:443", + v4_compat_dest, + }); +} + +int main(int argc, char** argv) { + char* resolver = gpr_getenv("GRPC_DNS_RESOLVER"); + if (resolver == nullptr || strlen(resolver) == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + } else if (strcmp("ares", resolver)) { + gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver); + } + gpr_free(resolver); + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + grpc_init(); + auto result = RUN_ALL_TESTS(); + grpc_shutdown(); + // Test sequential and nested inits and shutdowns. + grpc_init(); + grpc_init(); + grpc_shutdown(); + grpc_shutdown(); + grpc_init(); + grpc_shutdown(); + return result; +} diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index 91718156e9..6e63cbe483 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -22,13 +22,6 @@ import collections import hashlib import json -_LOCAL_DNS_SERVER_ADDRESS = '127.0.0.1:15353' - -_TARGET_RECORDS_TO_SKIP_AGAINST_GCE = [ - # TODO: enable this once able to upload the very large TXT record - # in this group to GCE DNS. - 'ipv4-config-causing-fallback-to-tcp', -] def _append_zone_name(name, zone_name): return '%s.%s' % (name, zone_name) @@ -39,92 +32,22 @@ def _build_expected_addrs_cmd_arg(expected_addrs): out.append('%s,%s' % (addr['address'], str(addr['is_balancer']))) return ';'.join(out) -def _data_for_type(r_type, r_data, common_zone_name): - if r_type in ['A', 'AAAA']: - return ' '.join(map(lambda x: '\"%s\"' % x, r_data)) - if r_type == 'SRV': - assert len(r_data) == 1 - target = r_data[0].split(' ')[3] - uploadable_target = '%s.%s' % (target, common_zone_name) - uploadable = r_data[0].split(' ') - uploadable[3] = uploadable_target - return '\"%s\"' % ' '.join(uploadable) - if r_type == 'TXT': - assert len(r_data) == 1 - chunks = [] - all_data = r_data[0] - cur = 0 - # Split TXT records that span more than 255 characters (the single - # string length-limit in DNS) into multiple strings. Each string - # needs to be wrapped with double-quotes, and all inner double-quotes - # are escaped. The wrapping double-quotes and inner backslashes can be - # counted towards the 255 character length limit (as observed with gcloud), - # so make sure all strings fit within that limit. - while len(all_data[cur:]) > 0: - next_chunk = '\"' - while len(next_chunk) < 254 and len(all_data[cur:]) > 0: - if all_data[cur] == '\"': - if len(next_chunk) < 253: - next_chunk += '\\\"' - else: - break - else: - next_chunk += all_data[cur] - cur += 1 - next_chunk += '\"' - if len(next_chunk) > 255: - raise Exception('Bug: next chunk is too long.') - chunks.append(next_chunk) - # Wrap the whole record in single quotes to make sure all strings - # are associated with the same TXT record (to make it one bash token for - # gcloud) - return '\'%s\'' % ' '.join(chunks) - -# Convert DNS records from their "within a test group" format -# of the yaml file to an easier form for the templates to use. -def _gcloud_uploadable_form(test_cases, common_zone_name): - out = [] - for group in test_cases: - if group['record_to_resolve'] in _TARGET_RECORDS_TO_SKIP_AGAINST_GCE: - continue - for record_name in group['records'].keys(): - r_ttl = None - all_r_data = {} - for r_data in group['records'][record_name]: - # enforce records have the same TTL only for simplicity - if r_ttl is None: - r_ttl = r_data['TTL'] - assert r_ttl == r_data['TTL'], '%s and %s differ' % (r_ttl, r_data['TTL']) - r_type = r_data['type'] - if all_r_data.get(r_type) is None: - all_r_data[r_type] = [] - all_r_data[r_type].append(r_data['data']) - for r_type in all_r_data.keys(): - for r in out: - assert r['name'] != record_name or r['type'] != r_type, 'attempt to add a duplicate record' - out.append({ - 'name': record_name, - 'ttl': r_ttl, - 'type': r_type, - 'data': _data_for_type(r_type, all_r_data[r_type], common_zone_name) - }) - return out - -def _gce_dns_zone_id(resolver_component_data): - dns_name = resolver_component_data['resolver_tests_common_zone_name'] - return dns_name.replace('.', '-') + 'zone-id' - -def _resolver_test_cases(resolver_component_data, records_to_skip): +def _resolver_test_cases(resolver_component_data): out = [] for test_case in resolver_component_data['resolver_component_tests']: - if test_case['record_to_resolve'] in records_to_skip: - continue + target_name = _append_zone_name( + test_case['record_to_resolve'], + resolver_component_data['resolver_tests_common_zone_name']) out.append({ - 'target_name': _append_zone_name(test_case['record_to_resolve'], - resolver_component_data['resolver_tests_common_zone_name']), - 'expected_addrs': _build_expected_addrs_cmd_arg(test_case['expected_addrs']), - 'expected_chosen_service_config': (test_case['expected_chosen_service_config'] or ''), - 'expected_lb_policy': (test_case['expected_lb_policy'] or ''), + 'test_title': target_name, + 'arg_names_and_values': [ + ('target_name', target_name), + ('expected_addrs', + _build_expected_addrs_cmd_arg(test_case['expected_addrs'])), + ('expected_chosen_service_config', + (test_case['expected_chosen_service_config'] or '')), + ('expected_lb_policy', (test_case['expected_lb_policy'] or '')), + ], }) return out @@ -135,11 +58,7 @@ def main(): json = { 'resolver_tests_common_zone_name': resolver_component_data['resolver_tests_common_zone_name'], - 'resolver_gce_integration_tests_zone_id': _gce_dns_zone_id(resolver_component_data), - 'all_integration_test_records': _gcloud_uploadable_form(resolver_component_data['resolver_component_tests'], - resolver_component_data['resolver_tests_common_zone_name']), - 'resolver_gce_integration_test_cases': _resolver_test_cases(resolver_component_data, _TARGET_RECORDS_TO_SKIP_AGAINST_GCE), - 'resolver_component_test_cases': _resolver_test_cases(resolver_component_data, []), + 'resolver_component_test_cases': _resolver_test_cases(resolver_component_data), 'targets': [ { 'name': 'resolver_component_test' + unsecure_build_config_suffix, @@ -182,6 +101,25 @@ def main(): '--running_under_bazel=false', ], } for unsecure_build_config_suffix in ['_unsecure', ''] + ] + [ + { + 'name': 'address_sorting_test' + unsecure_build_config_suffix, + 'build': 'test', + 'language': 'c++', + 'gtest': True, + 'run': True, + 'src': ['test/cpp/naming/address_sorting_test.cc'], + 'platforms': ['linux', 'posix', 'mac'], + 'deps': [ + 'grpc++_test_util' + unsecure_build_config_suffix, + 'grpc_test_util' + unsecure_build_config_suffix, + 'gpr_test_util', + 'grpc++' + unsecure_build_config_suffix, + 'grpc' + unsecure_build_config_suffix, + 'gpr', + 'grpc++_test_config', + ], + } for unsecure_build_config_suffix in ['_unsecure', ''] ] } diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index 118d9452d9..5e9aa63abe 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -13,10 +13,28 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_cc_test", "grpc_cc_binary") +load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_binary") def generate_resolver_component_tests(): for unsecure_build_config_suffix in ['_unsecure', '']: + grpc_cc_test( + name = "address_sorting_test%s" % unsecure_build_config_suffix, + srcs = [ + "address_sorting_test.cc", + ], + external_deps = [ + "gmock", + ], + deps = [ + "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, + "//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, + "//test/core/util:gpr_test_util", + "//:grpc++%s" % unsecure_build_config_suffix, + "//:grpc%s" % unsecure_build_config_suffix, + "//:gpr", + "//test/cpp/util:test_config", + ], + ) # meant to be invoked only through the top-level shell script driver grpc_cc_binary( name = "resolver_component_test%s" % unsecure_build_config_suffix, @@ -54,7 +72,9 @@ def generate_resolver_component_tests(): data = [ ":resolver_component_tests_runner", ":resolver_component_test%s" % unsecure_build_config_suffix, - ":test_dns_server", + "//test/cpp/naming/utils:dns_server", + "//test/cpp/naming/utils:dns_resolver", + "//test/cpp/naming/utils:tcp_connect", "resolver_test_record_groups.yaml", # include the transitive dependency so that the dns sever py binary can locate this ], args = [ diff --git a/test/cpp/naming/private_dns_zone_init.sh b/test/cpp/naming/private_dns_zone_init.sh deleted file mode 100755 index 8fa5a8a475..0000000000 --- a/test/cpp/naming/private_dns_zone_init.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/bin/bash -# 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. - -# This file is auto-generated - -set -ex - -cd $(dirname $0)/../../.. - -gcloud dns record-sets transaction start -z=resolver-tests-version-4-grpctestingexp-zone-id - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpclb._tcp.srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp. \ - --type=SRV \ - --ttl=2100 \ - "0 0 1234 ipv4-single-target.resolver-tests-version-4.grpctestingexp." - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv4-single-target.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpclb._tcp.srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp. \ - --type=SRV \ - --ttl=2100 \ - "0 0 1234 ipv4-multi-target.resolver-tests-version-4.grpctestingexp." - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv4-multi-target.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.5" "1.2.3.6" "1.2.3.7" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpclb._tcp.srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp. \ - --type=SRV \ - --ttl=2100 \ - "0 0 1234 ipv6-single-target.resolver-tests-version-4.grpctestingexp." - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv6-single-target.resolver-tests-version-4.grpctestingexp. \ - --type=AAAA \ - --ttl=2100 \ - "2607:f8b0:400a:801::1001" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpclb._tcp.srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp. \ - --type=SRV \ - --ttl=2100 \ - "0 0 1234 ipv6-multi-target.resolver-tests-version-4.grpctestingexp." - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv6-multi-target.resolver-tests-version-4.grpctestingexp. \ - --type=AAAA \ - --ttl=2100 \ - "2607:f8b0:400a:801::1002" "2607:f8b0:400a:801::1003" "2607:f8b0:400a:801::1004" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpc_config.srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. \ - --type=TXT \ - --ttl=2100 \ - '"grpc_config=[{\"serviceConfig\":{\"loadBalancingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"method\":\"Foo\",\"service\":\"SimpleService\",\"waitForReady\":true}]}]}}]"' - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpclb._tcp.srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. \ - --type=SRV \ - --ttl=2100 \ - "0 0 1234 ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp." - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpc_config.ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp. \ - --type=TXT \ - --ttl=2100 \ - '"grpc_config=[{\"serviceConfig\":{\"loadBalancingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"method\":\"Foo\",\"service\":\"NoSrvSimpleService\",\"waitForReady\":true}]}]}}]"' - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpc_config.ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp. \ - --type=TXT \ - --ttl=2100 \ - '"grpc_config=[{\"clientLanguage\":[\"python\"],\"serviceConfig\":{\"loadBalancingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"method\":\"Foo\",\"service\":\"PythonService\",\"waitForReady\":true}]}]}}]"' - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpc_config.ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp. \ - --type=TXT \ - --ttl=2100 \ - '"grpc_config=[{\"percentage\":0,\"serviceConfig\":{\"loadBalancingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"method\":\"Foo\",\"service\":\"CppService\",\"waitForReady\":true}]}]}}]"' - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpc_config.ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp. \ - --type=TXT \ - --ttl=2100 \ - '"grpc_config=[{\"clientLanguage\":[\"go\"],\"serviceConfig\":{\"loadBalancingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"method\":\"Foo\",\"service\":\"GoService\",\"waitForReady\":true}]}]}},{\"clientLanguage\":[\"c++\"],\"serviceConfig\":{" "\"loadBalancingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"method\":\"Foo\",\"service\":\"CppService\",\"waitForReady\":true}]}]}}]"' - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpc_config.ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp. \ - --type=TXT \ - --ttl=2100 \ - '"grpc_config=[{\"percentage\":0,\"serviceConfig\":{\"loadBalancingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"method\":\"Foo\",\"service\":\"NeverPickedService\",\"waitForReady\":true}]}]}},{\"percentage\":100,\"serviceConfig\":{\"loadBalanc" "ingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"method\":\"Foo\",\"service\":\"AlwaysPickedService\",\"waitForReady\":true}]}]}}]"' - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpclb._tcp.srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. \ - --type=SRV \ - --ttl=2100 \ - "0 0 1234 balancer-for-ipv4-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp." - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=balancer-for-ipv4-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. \ - --type=A \ - --ttl=2100 \ - "1.2.3.4" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=_grpclb._tcp.srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. \ - --type=SRV \ - --ttl=2100 \ - "0 0 1234 balancer-for-ipv6-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp." - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=balancer-for-ipv6-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. \ - --type=AAAA \ - --ttl=2100 \ - "2607:f8b0:400a:801::1002" - -gcloud dns record-sets transaction add \ - -z=resolver-tests-version-4-grpctestingexp-zone-id \ - --name=srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. \ - --type=AAAA \ - --ttl=2100 \ - "2607:f8b0:400a:801::1002" - -gcloud dns record-sets transaction describe -z=resolver-tests-version-4-grpctestingexp-zone-id -gcloud dns record-sets transaction execute -z=resolver-tests-version-4-grpctestingexp-zone-id -gcloud dns record-sets list -z=resolver-tests-version-4-grpctestingexp-zone-id diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 3481d9d1aa..f4be064305 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -18,7 +18,6 @@ #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/sync.h> @@ -37,13 +36,15 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/support/env.h" -#include "src/core/lib/support/string.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -61,11 +62,9 @@ using namespace gflags; DEFINE_string(target_name, "", "Target name to resolve."); DEFINE_string(expected_addrs, "", - "Comma-separated list of expected " - "'<ip0:port0>,<is_balancer0>;<ip1:port1>,<is_balancer1>;...' " - "addresses of " - "backend and/or balancers. 'is_balancer' should be bool, i.e. " - "true or false."); + "List of expected backend or balancer addresses in the form " + "'<ip0:port0>,<is_balancer0>;<ip1:port1>,<is_balancer1>;...'. " + "'is_balancer' should be bool, i.e. true or false."); DEFINE_string(expected_chosen_service_config, "", "Expected service config json string that gets chosen (no " "whitespace). Empty for none."); @@ -102,12 +101,10 @@ vector<GrpcLBAddress> ParseExpectedAddrs(std::string expected_addrs) { // get the next <ip>,<port> (v4 or v6) size_t next_comma = expected_addrs.find(","); if (next_comma == std::string::npos) { - gpr_log( - GPR_ERROR, - "Missing ','. Expected_addrs arg should be a semi-colon-separated " - "list of " - "<ip-port>,<bool> pairs. Left-to-be-parsed arg is |%s|", - expected_addrs.c_str()); + gpr_log(GPR_ERROR, + "Missing ','. Expected_addrs arg should be a semicolon-separated " + "list of <ip-port>,<bool> pairs. Left-to-be-parsed arg is |%s|", + expected_addrs.c_str()); abort(); } std::string next_addr = expected_addrs.substr(0, next_comma); @@ -125,7 +122,7 @@ vector<GrpcLBAddress> ParseExpectedAddrs(std::string expected_addrs) { } if (out.size() == 0) { gpr_log(GPR_ERROR, - "expected_addrs arg should be a comma-separated list of " + "expected_addrs arg should be a semicolon-separated list of " "<ip-port>,<bool> pairs"); abort(); } @@ -287,17 +284,16 @@ TEST(ResolverComponentTest, TestResolvesRelevantRecords) { FLAGS_local_dns_server_address.c_str(), FLAGS_target_name.c_str())); // create resolver and resolve - grpc_resolver* resolver = - grpc_resolver_create(whole_uri, nullptr, args.pollset_set, args.lock); + grpc_core::OrphanablePtr<grpc_core::Resolver> resolver = + grpc_core::ResolverRegistry::CreateResolver(whole_uri, nullptr, + args.pollset_set, args.lock); gpr_free(whole_uri); grpc_closure on_resolver_result_changed; GRPC_CLOSURE_INIT(&on_resolver_result_changed, CheckResolverResultLocked, (void*)&args, grpc_combiner_scheduler(args.lock)); - grpc_resolver_next_locked(resolver, &args.channel_args, - &on_resolver_result_changed); + resolver->NextLocked(&args.channel_args, &on_resolver_result_changed); grpc_core::ExecCtx::Get()->Flush(); PollPollsetUntilRequestDone(&args); - GRPC_RESOLVER_UNREF(resolver, nullptr); ArgsFinish(&args); } diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py new file mode 100755 index 0000000000..d4d904b9a8 --- /dev/null +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -0,0 +1,275 @@ +#!/usr/bin/env python +# 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. + +# This file is auto-generated + +import argparse +import sys +import subprocess +import tempfile +import os +import time +import signal + + +argp = argparse.ArgumentParser(description='Run c-ares resolver tests') +argp.add_argument('--test_bin_path', default=None, type=str, + help='Path to gtest test binary to invoke.') +argp.add_argument('--dns_server_bin_path', default=None, type=str, + help='Path to local DNS server python script.') +argp.add_argument('--records_config_path', default=None, type=str, + help=('Path to DNS records yaml file that ' + 'specifies records for the DNS sever. ')) +argp.add_argument('--dns_server_port', default=None, type=int, + help=('Port that local DNS server is listening on.')) +argp.add_argument('--dns_resolver_bin_path', default=None, type=str, + help=('Path to the DNS health check utility.')) +argp.add_argument('--tcp_connect_bin_path', default=None, type=str, + help=('Path to the TCP health check utility.')) +args = argp.parse_args() + +def test_runner_log(msg): + sys.stderr.write('\n%s: %s\n' % (__file__, msg)) + +cur_resolver = os.environ.get('GRPC_DNS_RESOLVER') +if cur_resolver and cur_resolver != 'ares': + test_runner_log(('WARNING: cur resolver set to %s. This set of tests ' + 'needs to use GRPC_DNS_RESOLVER=ares.')) + test_runner_log('Exit 1 without running tests.') + sys.exit(1) +os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) + +def wait_until_dns_server_is_up(args, + dns_server_subprocess, + dns_server_subprocess_output): + for i in range(0, 30): + test_runner_log('Health check: attempt to connect to DNS server over TCP.') + tcp_connect_subprocess = subprocess.Popen([ + args.tcp_connect_bin_path, + '--server_host', '::1', + '--server_port', str(args.dns_server_port), + '--timeout', str(1)]) + tcp_connect_subprocess.communicate() + if tcp_connect_subprocess.returncode == 0: + test_runner_log(('Health check: attempt to make an A-record ' + 'query to DNS server.')) + dns_resolver_subprocess = subprocess.Popen([ + args.dns_resolver_bin_path, + '--qname', 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp', + '--server_host', '::1', + '--server_port', str(args.dns_server_port)], + stdout=subprocess.PIPE) + dns_resolver_stdout, _ = dns_resolver_subprocess.communicate() + if dns_resolver_subprocess.returncode == 0: + if '123.123.123.123' in dns_resolver_stdout: + test_runner_log(('DNS server is up! ' + 'Successfully reached it over UDP and TCP.')) + return + time.sleep(0.1) + dns_server_subprocess.kill() + dns_server_subprocess.wait() + test_runner_log(('Failed to reach DNS server over TCP and/or UDP. ' + 'Exitting without running tests.')) + test_runner_log('======= DNS server stdout ' + '(merged stdout and stderr) =============') + with open(dns_server_subprocess_output, 'r') as l: + test_runner_log(l.read()) + test_runner_log('======= end DNS server output=========') + sys.exit(1) + +dns_server_subprocess_output = tempfile.mktemp() +with open(dns_server_subprocess_output, 'w') as l: + dns_server_subprocess = subprocess.Popen([ + args.dns_server_bin_path, + '--port', str(args.dns_server_port), + '--records_config_path', args.records_config_path], + stdin=subprocess.PIPE, + stdout=l, + stderr=l) + +def _quit_on_signal(signum, _frame): + test_runner_log('Received signal: %d' % signum) + dns_server_subprocess.kill() + dns_server_subprocess.wait() + sys.exit(1) + +signal.signal(signal.SIGINT, _quit_on_signal) +signal.signal(signal.SIGTERM, _quit_on_signal) +wait_until_dns_server_is_up(args, + dns_server_subprocess, + dns_server_subprocess_output) +num_test_failures = 0 + +test_runner_log('Run test with target: %s' % 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:1234,True', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '[2607:f8b0:400a:801::1001]:1234,True', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:1234,True', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}', + '--expected_lb_policy', 'round_robin', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}', + '--expected_lb_policy', 'round_robin', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}', + '--expected_lb_policy', 'round_robin', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}', + '--expected_lb_policy', 'round_robin', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:1234,True;1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}', + '--expected_lb_policy', '', + '--local_dns_server_address', '[::1]:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('now kill DNS server') +dns_server_subprocess.kill() +dns_server_subprocess.wait() +test_runner_log('%d tests failed.' % num_test_failures) +sys.exit(num_test_failures) diff --git a/test/cpp/naming/resolver_component_tests_runner.sh b/test/cpp/naming/resolver_component_tests_runner.sh deleted file mode 100755 index 11a45d72ce..0000000000 --- a/test/cpp/naming/resolver_component_tests_runner.sh +++ /dev/null @@ -1,181 +0,0 @@ -#!/bin/bash -# 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. - -# This file is auto-generated - -set -ex - -# all command args required in this set order -FLAGS_test_bin_path=`echo "$1" | grep '\--test_bin_path=' | cut -d "=" -f 2` -FLAGS_dns_server_bin_path=`echo "$2" | grep '\--dns_server_bin_path=' | cut -d "=" -f 2` -FLAGS_records_config_path=`echo "$3" | grep '\--records_config_path=' | cut -d "=" -f 2` -FLAGS_test_dns_server_port=`echo "$4" | grep '\--test_dns_server_port=' | cut -d "=" -f 2` - -for cmd_arg in "$FLAGS_test_bin_path" "$FLAGS_dns_server_bin_path" "$FLAGS_records_config_path" "$FLAGS_test_dns_server_port"; do - if [[ "$cmd_arg" == "" ]]; then - echo "Missing a CMD arg" && exit 1 - fi -done - -if [[ "$GRPC_DNS_RESOLVER" != "" && "$GRPC_DNS_RESOLVER" != ares ]]; then - echo "This test only works under GRPC_DNS_RESOLVER=ares. Have GRPC_DNS_RESOLVER=$GRPC_DNS_RESOLVER" && exit 1 -fi -export GRPC_DNS_RESOLVER=ares - -"$FLAGS_dns_server_bin_path" --records_config_path="$FLAGS_records_config_path" --port="$FLAGS_test_dns_server_port" 2>&1 > /dev/null & -DNS_SERVER_PID=$! -echo "Local DNS server started. PID: $DNS_SERVER_PID" - -# Health check local DNS server TCP and UDP ports -for ((i=0;i<30;i++)); -do - echo "Retry health-check DNS query to local DNS server over tcp and udp" - RETRY=0 - dig A health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. @localhost -p "$FLAGS_test_dns_server_port" +tries=1 +timeout=1 | grep '123.123.123.123' || RETRY=1 - dig A health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. @localhost -p "$FLAGS_test_dns_server_port" +tries=1 +timeout=1 +tcp | grep '123.123.123.123' || RETRY=1 - if [[ "$RETRY" == 0 ]]; then - break - fi; - sleep 0.1 -done - -if [[ $RETRY == 1 ]]; then - echo "FAILED TO START LOCAL DNS SERVER" - kill -SIGTERM $DNS_SERVER_PID - wait - exit 1 -fi - -function terminate_all { - echo "Received signal. Terminating $! and $DNS_SERVER_PID" - kill -SIGTERM $! || true - kill -SIGTERM $DNS_SERVER_PID || true - wait - exit 1 -} - -trap terminate_all SIGTERM SIGINT - -EXIT_CODE=0 -# TODO: this test should check for GCE residency and skip tests using _grpclb._tcp.* SRV records once GCE residency checks are made -# in the resolver. - -$FLAGS_test_bin_path \ - --target_name='srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:1234,True' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='[2607:f8b0:400a:801::1001]:1234,True' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:1234,True' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' \ - --expected_lb_policy='round_robin' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' \ - --expected_lb_policy='round_robin' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' \ - --expected_lb_policy='round_robin' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' \ - --expected_lb_policy='round_robin' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:1234,True;1.2.3.4:443,False' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -$FLAGS_test_bin_path \ - --target_name='ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}' \ - --expected_lb_policy='' \ - --local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & -wait $! || EXIT_CODE=1 - -kill -SIGTERM $DNS_SERVER_PID || true -wait -exit $EXIT_CODE diff --git a/test/cpp/naming/resolver_component_tests_runner_invoker.cc b/test/cpp/naming/resolver_component_tests_runner_invoker.cc index 0beb27de1b..45c1029caa 100644 --- a/test/cpp/naming/resolver_component_tests_runner_invoker.cc +++ b/test/cpp/naming/resolver_component_tests_runner_invoker.cc @@ -32,7 +32,7 @@ #include "test/cpp/util/subprocess.h" #include "test/cpp/util/test_config.h" -#include "src/core/lib/support/env.h" +#include "src/core/lib/gpr/env.h" #include "test/core/util/port.h" DEFINE_bool( @@ -44,7 +44,8 @@ DEFINE_bool( DEFINE_string(test_bin_name, "", "Name, without the preceding path, of the test binary"); -DEFINE_string(grpc_test_directory_relative_to_test_srcdir, "/__main__", +DEFINE_string(grpc_test_directory_relative_to_test_srcdir, + "/com_github_grpc_grpc", "This flag only applies if runner_under_bazel is true. This " "flag is ignored if runner_under_bazel is false. " "Directory of the <repo-root>/test directory relative to bazel's " @@ -101,14 +102,18 @@ namespace testing { void InvokeResolverComponentTestsRunner(std::string test_runner_bin_path, std::string test_bin_path, std::string dns_server_bin_path, - std::string records_config_path) { - int test_dns_server_port = grpc_pick_unused_port_or_die(); - - SubProcess* test_driver = new SubProcess( - {test_runner_bin_path, "--test_bin_path=" + test_bin_path, - "--dns_server_bin_path=" + dns_server_bin_path, - "--records_config_path=" + records_config_path, - "--test_dns_server_port=" + std::to_string(test_dns_server_port)}); + std::string records_config_path, + std::string dns_resolver_bin_path, + std::string tcp_connect_bin_path) { + int dns_server_port = grpc_pick_unused_port_or_die(); + + SubProcess* test_driver = + new SubProcess({test_runner_bin_path, "--test_bin_path=" + test_bin_path, + "--dns_server_bin_path=" + dns_server_bin_path, + "--records_config_path=" + records_config_path, + "--dns_server_port=" + std::to_string(dns_server_port), + "--dns_resolver_bin_path=" + dns_resolver_bin_path, + "--tcp_connect_bin_path=" + tcp_connect_bin_path}); gpr_mu test_driver_mu; gpr_mu_init(&test_driver_mu); gpr_cv test_driver_cv; @@ -160,27 +165,31 @@ int main(int argc, char** argv) { GPR_ASSERT(FLAGS_grpc_test_directory_relative_to_test_srcdir != ""); // Use bazel's TEST_SRCDIR environment variable to locate the "test data" // binaries. + char* test_srcdir = gpr_getenv("TEST_SRCDIR"); std::string const bin_dir = - gpr_getenv("TEST_SRCDIR") + - FLAGS_grpc_test_directory_relative_to_test_srcdir + + test_srcdir + FLAGS_grpc_test_directory_relative_to_test_srcdir + std::string("/test/cpp/naming"); // Invoke bazel's executeable links to the .sh and .py scripts (don't use // the .sh and .py suffixes) to make // sure that we're using bazel's test environment. grpc::testing::InvokeResolverComponentTestsRunner( bin_dir + "/resolver_component_tests_runner", - bin_dir + "/" + FLAGS_test_bin_name, bin_dir + "/test_dns_server", - bin_dir + "/resolver_test_record_groups.yaml"); + bin_dir + "/" + FLAGS_test_bin_name, bin_dir + "/utils/dns_server", + bin_dir + "/resolver_test_record_groups.yaml", + bin_dir + "/utils/dns_resolver", bin_dir + "/utils/tcp_connect"); + gpr_free(test_srcdir); } else { // Get the current binary's directory relative to repo root to invoke the // correct build config (asan/tsan/dbg, etc.). std::string const bin_dir = my_bin.substr(0, my_bin.rfind('/')); // Invoke the .sh and .py scripts directly where they are in source code. grpc::testing::InvokeResolverComponentTestsRunner( - "test/cpp/naming/resolver_component_tests_runner.sh", + "test/cpp/naming/resolver_component_tests_runner.py", bin_dir + "/" + FLAGS_test_bin_name, - "test/cpp/naming/test_dns_server.py", - "test/cpp/naming/resolver_test_record_groups.yaml"); + "test/cpp/naming/utils/dns_server.py", + "test/cpp/naming/resolver_test_record_groups.yaml", + "test/cpp/naming/utils/dns_resolver.py", + "test/cpp/naming/utils/tcp_connect.py"); } grpc_shutdown(); return 0; diff --git a/test/cpp/naming/resolver_gce_integration_tests_runner.sh b/test/cpp/naming/resolver_gce_integration_tests_runner.sh deleted file mode 100755 index 091f9efbbd..0000000000 --- a/test/cpp/naming/resolver_gce_integration_tests_runner.sh +++ /dev/null @@ -1,359 +0,0 @@ -#!/bin/bash -# 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. - -# This file is auto-generated - -set -ex - -if [[ "$GRPC_DNS_RESOLVER" == "" ]]; then - export GRPC_DNS_RESOLVER=ares -elif [[ "$GRPC_DNS_RESOLVER" != ares ]]; then - echo "Unexpected: GRPC_DNS_RESOLVER=$GRPC_DNS_RESOLVER. This test only works with c-ares resolver" - exit 1 -fi - -cd $(dirname $0)/../../.. - -if [[ "$CONFIG" == "" ]]; then - export CONFIG=opt -fi -make resolver_component_test -echo "Sanity check DNS records are resolveable with dig:" -EXIT_CODE=0 - -ONE_FAILED=0 -dig SRV _grpclb._tcp.srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig SRV _grpclb._tcp.srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A ipv4-single-target.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A ipv4-single-target.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig SRV _grpclb._tcp.srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig SRV _grpclb._tcp.srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A ipv4-multi-target.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A ipv4-multi-target.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig SRV _grpclb._tcp.srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig SRV _grpclb._tcp.srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig AAAA ipv6-single-target.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig AAAA ipv6-single-target.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig SRV _grpclb._tcp.srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig SRV _grpclb._tcp.srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig AAAA ipv6-multi-target.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig AAAA ipv6-multi-target.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig TXT _grpc_config.srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig TXT _grpc_config.srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig SRV _grpclb._tcp.srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig SRV _grpclb._tcp.srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig TXT _grpc_config.ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig TXT _grpc_config.ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig TXT _grpc_config.ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig TXT _grpc_config.ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig TXT _grpc_config.ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig TXT _grpc_config.ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig TXT _grpc_config.ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig TXT _grpc_config.ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig TXT _grpc_config.ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig TXT _grpc_config.ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig SRV _grpclb._tcp.srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig SRV _grpclb._tcp.srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A balancer-for-ipv4-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A balancer-for-ipv4-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig A srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig A srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig SRV _grpclb._tcp.srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig SRV _grpclb._tcp.srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig AAAA balancer-for-ipv6-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig AAAA balancer-for-ipv6-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -ONE_FAILED=0 -dig AAAA srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Sanity check: dig AAAA srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. FAILED" - exit 1 -fi - -echo "Sanity check PASSED. Run resolver tests:" - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:1234,True' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='[2607:f8b0:400a:801::1001]:1234,True' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:1234,True' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' \ - --expected_lb_policy='round_robin' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' \ - --expected_lb_policy='round_robin' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' \ - --expected_lb_policy='round_robin' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:443,False' \ - --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' \ - --expected_lb_policy='round_robin' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='1.2.3.4:1234,True;1.2.3.4:443,False' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -ONE_FAILED=0 -bins/$CONFIG/resolver_component_test \ - --target_name='srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \ - --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False' \ - --expected_chosen_service_config='' \ - --expected_lb_policy='' || ONE_FAILED=1 -if [[ "$ONE_FAILED" != 0 ]]; then - echo "Test based on target record: srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp. FAILED" - EXIT_CODE=1 -fi - -exit $EXIT_CODE diff --git a/test/cpp/naming/utils/BUILD b/test/cpp/naming/utils/BUILD new file mode 100644 index 0000000000..e7b6bc5fe7 --- /dev/null +++ b/test/cpp/naming/utils/BUILD @@ -0,0 +1,50 @@ +# 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. + +package( + default_visibility = ["//visibility:public"], + features = [ + "-layering_check", + "-parse_headers", + ], +) + +licenses(["notice"]) # Apache v2 + +load("//bazel:grpc_build_system.bzl", "grpc_py_binary") + +grpc_py_binary( + name = "dns_server", + srcs = ["dns_server.py"], + testonly = True, + external_deps = [ + "twisted", + "yaml", + ] +) + +grpc_py_binary( + name = "dns_resolver", + srcs = ["dns_resolver.py"], + testonly = True, + external_deps = [ + "twisted", + ] +) + +grpc_py_binary( + name = "tcp_connect", + srcs = ["tcp_connect.py"], + testonly = True, +) diff --git a/test/cpp/naming/utils/dns_resolver.py b/test/cpp/naming/utils/dns_resolver.py new file mode 100755 index 0000000000..21e37562db --- /dev/null +++ b/test/cpp/naming/utils/dns_resolver.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python2.7 +# 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. + +"""Makes DNS queries for A records to specified servers""" + +import argparse +import threading +import time +import twisted.internet.task as task +import twisted.names.client as client +import twisted.internet.reactor as reactor + + +def main(): + argp = argparse.ArgumentParser(description='Make DNS queries for A records') + argp.add_argument('-s', '--server_host', default='::1', type=str, + help='Host for DNS server to listen on for TCP and UDP.') + argp.add_argument('-p', '--server_port', default=53, type=int, + help='Port that the DNS server is listening on.') + argp.add_argument('-n', '--qname', default=None, type=str, + help=('Name of the record to query for. ')) + argp.add_argument('-t', '--timeout', default=1, type=int, + help=('Force process exit after this number of seconds.')) + args = argp.parse_args() + def OnResolverResultAvailable(result): + answers, authority, additional = result + for a in answers: + print(a.payload) + def BeginQuery(reactor, qname): + servers = [(args.server_host, args.server_port)] + resolver = client.Resolver(servers=servers) + deferred_result = resolver.lookupAddress(args.qname) + deferred_result.addCallback(OnResolverResultAvailable) + return deferred_result + task.react(BeginQuery, [args.qname]) + +if __name__ == '__main__': + main() diff --git a/test/cpp/naming/test_dns_server.py b/test/cpp/naming/utils/dns_server.py index 9f42f65ee6..e198dd132d 100755 --- a/test/cpp/naming/test_dns_server.py +++ b/test/cpp/naming/utils/dns_server.py @@ -20,6 +20,8 @@ import sys import yaml import signal import os +import threading +import time import twisted import twisted.internet @@ -33,6 +35,7 @@ import twisted.names.dns import twisted.names.server from twisted.names import client, server, common, authority, dns import argparse +import platform _SERVER_HEALTH_CHECK_RECORD_NAME = 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp' # missing end '.' for twisted syntax _SERVER_HEALTH_CHECK_RECORD_DATA = '123.123.123.123' @@ -100,11 +103,11 @@ def start_local_dns_server(args): server = twisted.names.server.DNSServerFactory( authorities=[test_domain_com], verbose=2) server.noisy = 2 - twisted.internet.reactor.listenTCP(args.port, server) + twisted.internet.reactor.listenTCP(args.port, server, interface='::1') dns_proto = twisted.names.dns.DNSDatagramProtocol(server) dns_proto.noisy = 2 - twisted.internet.reactor.listenUDP(args.port, dns_proto) - print('starting local dns server on 127.0.0.1:%s' % args.port) + twisted.internet.reactor.listenUDP(args.port, dns_proto, interface='::1') + print('starting local dns server on [::1]:%s' % args.port) print('starting twisted.internet.reactor') twisted.internet.reactor.suggestThreadPoolSize(1) twisted.internet.reactor.run() @@ -115,6 +118,18 @@ def _quit_on_signal(signum, _frame): sys.stdout.flush() sys.exit(0) +def flush_stdout_loop(): + num_timeouts_so_far = 0 + sleep_time = 1 + # Prevent zombies. Tests that use this server are short-lived. + max_timeouts = 60 * 2 + while num_timeouts_so_far < max_timeouts: + sys.stdout.flush() + time.sleep(sleep_time) + num_timeouts_so_far += 1 + print('Process timeout reached, or cancelled. Exitting 0.') + os.kill(os.getpid(), signal.SIGTERM) + def main(): argp = argparse.ArgumentParser(description='Local DNS Server for resolver tests') argp.add_argument('-p', '--port', default=None, type=int, @@ -123,11 +138,11 @@ def main(): help=('Directory of resolver_test_record_groups.yaml file. ' 'Defauls to path needed when the test is invoked as part of run_tests.py.')) args = argp.parse_args() - signal.signal(signal.SIGALRM, _quit_on_signal) signal.signal(signal.SIGTERM, _quit_on_signal) signal.signal(signal.SIGINT, _quit_on_signal) - # Prevent zombies. Tests that use this server are short-lived. - signal.alarm(2 * 60) + output_flush_thread = threading.Thread(target=flush_stdout_loop) + output_flush_thread.setDaemon(True) + output_flush_thread.start() start_local_dns_server(args) if __name__ == '__main__': diff --git a/test/cpp/naming/utils/tcp_connect.py b/test/cpp/naming/utils/tcp_connect.py new file mode 100755 index 0000000000..5773c7cae8 --- /dev/null +++ b/test/cpp/naming/utils/tcp_connect.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python2.7 +# 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. + +"""Opens a TCP connection to a specified server and then exits.""" + +import argparse +import socket +import threading +import time +import sys + + +def main(): + argp = argparse.ArgumentParser(description='Open a TCP handshake to a server') + argp.add_argument('-s', '--server_host', default=None, type=str, + help='Server host name or IP.') + argp.add_argument('-p', '--server_port', default=0, type=int, + help='Port that the server is listening on.') + argp.add_argument('-t', '--timeout', default=1, type=int, + help='Force process exit after this number of seconds.') + args = argp.parse_args() + socket.create_connection([args.server_host, args.server_port]) + +if __name__ == '__main__': + main() diff --git a/test/cpp/performance/BUILD b/test/cpp/performance/BUILD new file mode 100644 index 0000000000..4fe95d5905 --- /dev/null +++ b/test/cpp/performance/BUILD @@ -0,0 +1,34 @@ +# 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. + +licenses(["notice"]) # Apache v2 + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") + +grpc_package(name = "test/cpp/performance") + +grpc_cc_test( + name = "writes_per_rpc_test", + srcs = ["writes_per_rpc_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util_base", + ], +) diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index 0b9dc83f2b..0ea3181f7e 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -16,14 +16,14 @@ * */ -#include <grpc++/channel.h> -#include <grpc++/create_channel.h> -#include <grpc++/impl/grpc_library.h> -#include <grpc++/security/credentials.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> #include <grpc/support/log.h> +#include <grpcpp/channel.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/impl/grpc_library.h> +#include <grpcpp/security/credentials.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> #include <gtest/gtest.h> #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" @@ -142,18 +142,24 @@ class EndpointPairFixture { class InProcessCHTTP2 : public EndpointPairFixture { public: - InProcessCHTTP2(Service* service) - : EndpointPairFixture(service, MakeEndpoints()) {} + InProcessCHTTP2(Service* service, grpc_passthru_endpoint_stats* stats) + : EndpointPairFixture(service, MakeEndpoints(stats)), stats_(stats) {} - int writes_performed() const { return stats_.num_writes; } + virtual ~InProcessCHTTP2() { + if (stats_ != nullptr) { + grpc_passthru_endpoint_stats_destroy(stats_); + } + } + + int writes_performed() const { return stats_->num_writes; } private: - grpc_passthru_endpoint_stats stats_; + grpc_passthru_endpoint_stats* stats_; - grpc_endpoint_pair MakeEndpoints() { + static grpc_endpoint_pair MakeEndpoints(grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; grpc_passthru_endpoint_create(&p.client, &p.server, initialize_stuff.rq(), - &stats_); + stats); return p; } }; @@ -162,7 +168,8 @@ static double UnaryPingPong(int request_size, int response_size) { const int kIterations = 10000; EchoTestService::AsyncService service; - std::unique_ptr<InProcessCHTTP2> fixture(new InProcessCHTTP2(&service)); + std::unique_ptr<InProcessCHTTP2> fixture( + new InProcessCHTTP2(&service, grpc_passthru_endpoint_stats_create())); EchoRequest send_request; EchoResponse send_response; EchoResponse recv_response; @@ -200,17 +207,17 @@ static double UnaryPingPong(int request_size, int response_size) { stub->AsyncEcho(&cli_ctx, send_request, fixture->cq())); void* t; bool ok; + response_reader->Finish(&recv_response, &recv_status, tag(4)); GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); GPR_ASSERT(t == tag(0) || t == tag(1)); intptr_t slot = reinterpret_cast<intptr_t>(t); ServerEnv* senv = server_env[slot]; senv->response_writer.Finish(send_response, Status::OK, tag(3)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); for (int i = (1 << 3) | (1 << 4); i != 0;) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); GPR_ASSERT(ok); - int tagnum = (int)reinterpret_cast<intptr_t>(t); + int tagnum = static_cast<int>(reinterpret_cast<intptr_t>(t)); GPR_ASSERT(i & (1 << tagnum)); i -= 1 << tagnum; } @@ -223,7 +230,8 @@ static double UnaryPingPong(int request_size, int response_size) { } double writes_per_iteration = - (double)fixture->writes_performed() / (double)kIterations; + static_cast<double>(fixture->writes_performed()) / + static_cast<double>(kIterations); fixture.reset(); server_env[0]->~ServerEnv(); diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index f1abb19e64..a348b88079 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -47,9 +47,10 @@ grpc_cc_library( "//:grpc", "//:grpc++", "//:grpc++_core_stats", + "//src/proto/grpc/testing:benchmark_service_proto", "//src/proto/grpc/testing:control_proto", "//src/proto/grpc/testing:payloads_proto", - "//src/proto/grpc/testing:services_proto", + "//src/proto/grpc/testing:worker_service_proto", "//test/core/end2end:ssl_test_data", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", @@ -74,7 +75,8 @@ grpc_cc_library( "//:grpc++", "//src/proto/grpc/testing:control_proto", "//src/proto/grpc/testing:messages_proto", - "//src/proto/grpc/testing:services_proto", + "//src/proto/grpc/testing:report_qps_scenario_service_proto", + "//src/proto/grpc/testing:worker_service_proto", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", diff --git a/test/cpp/qps/benchmark_config.cc b/test/cpp/qps/benchmark_config.cc index fb1e0608c5..a4fd9de820 100644 --- a/test/cpp/qps/benchmark_config.cc +++ b/test/cpp/qps/benchmark_config.cc @@ -18,9 +18,9 @@ #include "test/cpp/qps/benchmark_config.h" #include <gflags/gflags.h> -#include <grpc++/create_channel.h> -#include <grpc++/security/credentials.h> #include <grpc/support/log.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/security/credentials.h> DEFINE_bool(enable_log_reporter, true, "Enable reporting of benchmark results through GprLog"); diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 82c6361abd..31ae6ca1fb 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -24,15 +24,15 @@ #include <unordered_map> #include <vector> -#include <grpc++/channel.h> -#include <grpc++/support/byte_buffer.h> -#include <grpc++/support/channel_arguments.h> -#include <grpc++/support/slice.h> #include <grpc/support/log.h> #include <grpc/support/time.h> +#include <grpcpp/channel.h> +#include <grpcpp/support/byte_buffer.h> +#include <grpcpp/support/channel_arguments.h> +#include <grpcpp/support/slice.h> +#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "src/proto/grpc/testing/payloads.pb.h" -#include "src/proto/grpc/testing/services.grpc.pb.h" #include "src/cpp/util/core_stats.h" #include "test/cpp/qps/histogram.h" diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index 7cf9d3ea7e..c79a10d1b4 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -26,16 +26,16 @@ #include <thread> #include <vector> -#include <grpc++/alarm.h> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/generic/generic_stub.h> #include <grpc/grpc.h> #include <grpc/support/cpu.h> #include <grpc/support/log.h> +#include <grpcpp/alarm.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/generic/generic_stub.h> #include "src/core/lib/surface/completion_queue.h" -#include "src/proto/grpc/testing/services.grpc.pb.h" +#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/client.h" #include "test/cpp/qps/usage_timer.h" #include "test/cpp/util/create_test_channel.h" @@ -50,9 +50,9 @@ class ClientRpcContext { // next state, return false if done. Collect stats when appropriate virtual bool RunNextState(bool, HistogramEntry* entry) = 0; virtual void StartNewClone(CompletionQueue* cq) = 0; - static void* tag(ClientRpcContext* c) { return reinterpret_cast<void*>(c); } + static void* tag(ClientRpcContext* c) { return static_cast<void*>(c); } static ClientRpcContext* detag(void* t) { - return reinterpret_cast<ClientRpcContext*>(t); + return static_cast<ClientRpcContext*>(t); } virtual void Start(CompletionQueue* cq, const ClientConfig& config) = 0; @@ -82,6 +82,7 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { prepare_req_(prepare_req) {} ~ClientRpcContextUnaryImpl() override {} void Start(CompletionQueue* cq, const ClientConfig& config) override { + GPR_ASSERT(!config.use_coalesce_api()); // not supported. StartInternal(cq); } bool RunNextState(bool ok, HistogramEntry* entry) override { @@ -349,10 +350,11 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext { next_state_(State::INVALID), callback_(on_done), next_issue_(next_issue), - prepare_req_(prepare_req) {} + prepare_req_(prepare_req), + coalesce_(false) {} ~ClientRpcContextStreamingPingPongImpl() override {} void Start(CompletionQueue* cq, const ClientConfig& config) override { - StartInternal(cq, config.messages_per_stream()); + StartInternal(cq, config.messages_per_stream(), config.use_coalesce_api()); } bool RunNextState(bool ok, HistogramEntry* entry) override { while (true) { @@ -375,7 +377,12 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext { } start_ = UsageTimer::Now(); next_state_ = State::WRITE_DONE; - stream_->Write(req_, ClientRpcContext::tag(this)); + if (coalesce_ && messages_issued_ == messages_per_stream_ - 1) { + stream_->WriteLast(req_, WriteOptions(), + ClientRpcContext::tag(this)); + } else { + stream_->Write(req_, ClientRpcContext::tag(this)); + } return true; case State::WRITE_DONE: if (!ok) { @@ -391,6 +398,11 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext { if ((messages_per_stream_ != 0) && (++messages_issued_ >= messages_per_stream_)) { next_state_ = State::WRITES_DONE_DONE; + if (coalesce_) { + // WritesDone should have been called on the last Write. + // loop around to call Finish. + break; + } stream_->WritesDone(ClientRpcContext::tag(this)); return true; } @@ -413,7 +425,7 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext { void StartNewClone(CompletionQueue* cq) override { auto* clone = new ClientRpcContextStreamingPingPongImpl( stub_, req_, next_issue_, prepare_req_, callback_); - clone->StartInternal(cq, messages_per_stream_); + clone->StartInternal(cq, messages_per_stream_, coalesce_); } void TryCancel() override { context_.TryCancel(); } @@ -449,14 +461,27 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext { // Allow a limit on number of messages in a stream int messages_per_stream_; int messages_issued_; + // Whether to use coalescing API. + bool coalesce_; - void StartInternal(CompletionQueue* cq, int messages_per_stream) { + void StartInternal(CompletionQueue* cq, int messages_per_stream, + bool coalesce) { cq_ = cq; messages_per_stream_ = messages_per_stream; messages_issued_ = 0; + coalesce_ = coalesce; + if (coalesce_) { + GPR_ASSERT(messages_per_stream_ != 0); + context_.set_initial_metadata_corked(true); + } stream_ = prepare_req_(stub_, &context_, cq); next_state_ = State::STREAM_IDLE; stream_->StartCall(ClientRpcContext::tag(this)); + if (coalesce_) { + // When the intial metadata is corked, the tag will not come back and we + // need to manually drive the state machine. + RunNextState(true, nullptr); + } } }; @@ -512,6 +537,7 @@ class ClientRpcContextStreamingFromClientImpl : public ClientRpcContext { prepare_req_(prepare_req) {} ~ClientRpcContextStreamingFromClientImpl() override {} void Start(CompletionQueue* cq, const ClientConfig& config) override { + GPR_ASSERT(!config.use_coalesce_api()); // not supported yet. StartInternal(cq); } bool RunNextState(bool ok, HistogramEntry* entry) override { @@ -641,6 +667,7 @@ class ClientRpcContextStreamingFromServerImpl : public ClientRpcContext { prepare_req_(prepare_req) {} ~ClientRpcContextStreamingFromServerImpl() override {} void Start(CompletionQueue* cq, const ClientConfig& config) override { + GPR_ASSERT(!config.use_coalesce_api()); // not supported StartInternal(cq); } bool RunNextState(bool ok, HistogramEntry* entry) override { @@ -753,6 +780,7 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext { prepare_req_(prepare_req) {} ~ClientRpcContextGenericStreamingImpl() override {} void Start(CompletionQueue* cq, const ClientConfig& config) override { + GPR_ASSERT(!config.use_coalesce_api()); // not supported yet. StartInternal(cq, config.messages_per_stream()); } bool RunNextState(bool ok, HistogramEntry* entry) override { diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 82a3f0042d..e65e3b43f3 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -24,18 +24,18 @@ #include <thread> #include <vector> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/time.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" -#include "src/proto/grpc/testing/services.grpc.pb.h" +#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/client.h" #include "test/cpp/qps/interarrival.h" #include "test/cpp/qps/usage_timer.h" @@ -402,6 +402,7 @@ class SynchronousStreamingBothWaysClient final }; std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& config) { + GPR_ASSERT(!config.use_coalesce_api()); // not supported yet. switch (config.rpc_type()) { case UNARY: return std::unique_ptr<Client>(new SynchronousUnaryClient(config)); diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 22d039d4b7..34f1291576 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -23,17 +23,17 @@ #include <unordered_map> #include <vector> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" -#include "src/core/lib/support/env.h" -#include "src/proto/grpc/testing/services.grpc.pb.h" +#include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/cpp/qps/client.h" diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index 1ef8f65b0b..776283c25a 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -63,6 +63,11 @@ def guess_cpu(scenario_json, is_tsan): return (scenario_json['num_clients'] * client + scenario_json['num_servers'] * server) +def maybe_exclude_gcov(scenario_json): + if scenario_json['client_config']['client_channels'] > 100: + return ['gcov'] + return [] + print yaml.dump({ 'tests': [ { @@ -76,7 +81,7 @@ print yaml.dump({ 'boringssl': True, 'defaults': 'boringssl', 'cpu_cost': guess_cpu(scenario_json, False), - 'exclude_configs': ['tsan', 'asan'], + 'exclude_configs': ['tsan', 'asan'] + maybe_exclude_gcov(scenario_json), 'timeout_seconds': 2*60, 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), 'auto_timeout_scaling': False diff --git a/test/cpp/qps/interarrival.h b/test/cpp/qps/interarrival.h index 9c48066c9c..ce4bf3d30c 100644 --- a/test/cpp/qps/interarrival.h +++ b/test/cpp/qps/interarrival.h @@ -24,7 +24,7 @@ #include <random> #include <vector> -#include <grpc++/support/config.h> +#include <grpcpp/support/config.h> namespace grpc { namespace testing { diff --git a/test/cpp/qps/json_run_localhost.cc b/test/cpp/qps/json_run_localhost.cc index db8b2a3943..948c3088e6 100644 --- a/test/cpp/qps/json_run_localhost.cc +++ b/test/cpp/qps/json_run_localhost.cc @@ -26,7 +26,7 @@ #include <grpc/support/log.h> -#include "src/core/lib/support/env.h" +#include "src/core/lib/gpr/env.h" #include "test/core/util/port.h" #include "test/cpp/util/subprocess.h" diff --git a/test/cpp/qps/parse_json.h b/test/cpp/qps/parse_json.h index f2fffb52d4..089d9989ba 100644 --- a/test/cpp/qps/parse_json.h +++ b/test/cpp/qps/parse_json.h @@ -19,8 +19,8 @@ #ifndef TEST_QPS_PARSE_JSON_H #define TEST_QPS_PARSE_JSON_H -#include <grpc++/impl/codegen/config_protobuf.h> -#include <grpc++/support/config.h> +#include <grpcpp/impl/codegen/config_protobuf.h> +#include <grpcpp/support/config.h> namespace grpc { namespace testing { diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc index b2449da69c..0ff692255c 100644 --- a/test/cpp/qps/qps_json_driver.cc +++ b/test/cpp/qps/qps_json_driver.cc @@ -21,7 +21,7 @@ #include <memory> #include <set> -#include <grpc++/impl/codegen/config_protobuf.h> +#include <grpcpp/impl/codegen/config_protobuf.h> #include <gflags/gflags.h> #include <grpc/support/log.h> diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc index 4c9ab0ea43..d3f0380474 100644 --- a/test/cpp/qps/qps_worker.cc +++ b/test/cpp/qps/qps_worker.cc @@ -25,17 +25,17 @@ #include <thread> #include <vector> -#include <grpc++/client_context.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/cpu.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> +#include <grpcpp/client_context.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> -#include "src/proto/grpc/testing/services.pb.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/histogram.h" #include "test/cpp/qps/client.h" diff --git a/test/cpp/qps/qps_worker.h b/test/cpp/qps/qps_worker.h index a5167426d0..3a8796ee5a 100644 --- a/test/cpp/qps/qps_worker.h +++ b/test/cpp/qps/qps_worker.h @@ -21,10 +21,10 @@ #include <memory> -#include <grpc++/server.h> -#include <grpc++/support/channel_arguments.h> -#include <grpc++/support/config.h> #include <grpc/support/atm.h> +#include <grpcpp/server.h> +#include <grpcpp/support/channel_arguments.h> +#include <grpcpp/support/config.h> #include "test/cpp/qps/server.h" diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc index 42ebeff41d..607f4e579b 100644 --- a/test/cpp/qps/report.cc +++ b/test/cpp/qps/report.cc @@ -25,9 +25,9 @@ #include "test/cpp/qps/parse_json.h" #include "test/cpp/qps/stats.h" -#include <grpc++/client_context.h> +#include <grpcpp/client_context.h> #include "src/cpp/util/core_stats.h" -#include "src/proto/grpc/testing/services.grpc.pb.h" +#include "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h" namespace grpc { namespace testing { @@ -109,9 +109,12 @@ void GprLogReporter::ReportCoreStats(const char* name, int idx, for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) { gpr_log(GPR_DEBUG, "%s[%d].%s = %.1lf/%.1lf/%.1lf (50/95/99%%-ile)", name, idx, grpc_stats_histogram_name[i], - grpc_stats_histo_percentile(&data, (grpc_stats_histograms)i, 50), - grpc_stats_histo_percentile(&data, (grpc_stats_histograms)i, 95), - grpc_stats_histo_percentile(&data, (grpc_stats_histograms)i, 99)); + grpc_stats_histo_percentile( + &data, static_cast<grpc_stats_histograms>(i), 50), + grpc_stats_histo_percentile( + &data, static_cast<grpc_stats_histograms>(i), 95), + grpc_stats_histo_percentile( + &data, static_cast<grpc_stats_histograms>(i), 99)); } } diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h index 1d7b2b54e7..8e62f4f449 100644 --- a/test/cpp/qps/report.h +++ b/test/cpp/qps/report.h @@ -23,12 +23,12 @@ #include <set> #include <vector> -#include <grpc++/support/config.h> +#include <grpcpp/support/config.h> #include "test/cpp/qps/driver.h" -#include <grpc++/channel.h> -#include "src/proto/grpc/testing/services.grpc.pb.h" +#include <grpcpp/channel.h> +#include "src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h" namespace grpc { namespace testing { diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index 9da33566dd..6b1ef93617 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -19,11 +19,11 @@ #ifndef TEST_QPS_SERVER_H #define TEST_QPS_SERVER_H -#include <grpc++/resource_quota.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server_builder.h> #include <grpc/support/cpu.h> #include <grpc/support/log.h> +#include <grpcpp/resource_quota.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/server_builder.h> #include <vector> #include "src/cpp/util/core_stats.h" @@ -84,7 +84,7 @@ class Server { } payload->set_type(type); // Don't waste time creating a new payload of identical size. - if (payload->body().length() != (size_t)size) { + if (payload->body().length() != static_cast<size_t>(size)) { std::unique_ptr<char[]> body(new char[size]()); payload->set_body(body.get(), size); } diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 72ae772147..1dfef6cfc1 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -23,20 +23,20 @@ #include <mutex> #include <thread> -#include <grpc++/generic/async_generic_service.h> -#include <grpc++/resource_quota.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> -#include <grpc++/support/config.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> #include <grpc/support/log.h> - +#include <grpcpp/generic/async_generic_service.h> +#include <grpcpp/resource_quota.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> +#include <grpcpp/support/config.h> + +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/completion_queue.h" -#include "src/proto/grpc/testing/services.grpc.pb.h" +#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/core/util/test_config.h" #include "test/cpp/qps/server.h" @@ -240,11 +240,9 @@ class AsyncQpsServerTest final : public grpc::testing::Server { private: std::mutex mu_; }; - static void* tag(ServerRpcContext* func) { - return reinterpret_cast<void*>(func); - } + static void* tag(ServerRpcContext* func) { return static_cast<void*>(func); } static ServerRpcContext* detag(void* tag) { - return reinterpret_cast<ServerRpcContext*>(tag); + return static_cast<ServerRpcContext*>(tag); } class ServerRpcContextUnaryImpl final : public ServerRpcContext { diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index ea89a30e2e..82a9186989 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -19,14 +19,14 @@ #include <atomic> #include <thread> -#include <grpc++/security/server_credentials.h> -#include <grpc++/server.h> -#include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/server.h> +#include <grpcpp/server_context.h> -#include "src/proto/grpc/testing/services.grpc.pb.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/server.h" #include "test/cpp/qps/usage_timer.h" diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index 7538845803..3f89d6e26e 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -32,6 +32,19 @@ grpc_cc_test( ) grpc_cc_test( + name = "server_builder_with_socket_mutator_test", + srcs = ["server_builder_with_socket_mutator_test.cc"], + deps = [ + "//:grpc++_unsecure", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util_unsecure", + ], + external_deps = [ + "gtest", + ], +) + +grpc_cc_test( name = "server_request_call_test", srcs = ["server_request_call_test.cc"], deps = [ diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD new file mode 100644 index 0000000000..5cb3a00f82 --- /dev/null +++ b/test/cpp/server/load_reporter/BUILD @@ -0,0 +1,31 @@ +# 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. + +licenses(["notice"]) # Apache v2 + +load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary", "grpc_package") + +grpc_package(name = "test/cpp/server/load_reporter") + +grpc_cc_test( + name = "lb_load_data_store_test", + srcs = ["load_data_store_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + "//:lb_load_data_store", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/cpp/server/load_reporter/load_data_store_test.cc b/test/cpp/server/load_reporter/load_data_store_test.cc new file mode 100644 index 0000000000..8280dee6a4 --- /dev/null +++ b/test/cpp/server/load_reporter/load_data_store_test.cc @@ -0,0 +1,481 @@ +/* + * + * 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/impl/codegen/port_platform.h> + +#include <set> +#include <vector> + +#include <grpc/grpc.h> +#include <gtest/gtest.h> + +#include "src/cpp/server/load_reporter/load_data_store.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +namespace grpc { +namespace testing { +namespace { + +using ::grpc::load_reporter::CallMetricValue; +using ::grpc::load_reporter::LoadDataStore; +using ::grpc::load_reporter::LoadRecordKey; +using ::grpc::load_reporter::LoadRecordValue; +using ::grpc::load_reporter::PerBalancerStore; +using ::grpc::load_reporter::kInvalidLbId; + +class LoadDataStoreTest : public ::testing::Test { + public: + LoadDataStoreTest() + : kKey1(kLbId1, kLbTag1, kUser1, kClientIp1), + kKey2(kLbId2, kLbTag2, kUser2, kClientIp2) {} + + // Check whether per_balancer_stores contains a store which was originally + // created for <hostname, lb_id, and load_key>. + bool PerBalancerStoresContains( + const LoadDataStore& load_data_store, + const std::set<PerBalancerStore*>* per_balancer_stores, + const grpc::string hostname, const grpc::string lb_id, + const grpc::string load_key) { + auto original_per_balancer_store = + load_data_store.FindPerBalancerStore(hostname, lb_id); + EXPECT_NE(original_per_balancer_store, nullptr); + EXPECT_EQ(original_per_balancer_store->lb_id(), lb_id); + EXPECT_EQ(original_per_balancer_store->load_key(), load_key); + for (auto per_balancer_store : *per_balancer_stores) { + if (per_balancer_store == original_per_balancer_store) { + return true; + } + } + return false; + } + + grpc::string FormatLbId(size_t index) { + return "kLbId" + std::to_string(index); + } + + const grpc::string kHostname1 = "kHostname1"; + const grpc::string kHostname2 = "kHostname2"; + const grpc::string kLbId1 = "kLbId1"; + const grpc::string kLbId2 = "kLbId2"; + const grpc::string kLbId3 = "kLbId3"; + const grpc::string kLbId4 = "kLbId4"; + const grpc::string kLoadKey1 = "kLoadKey1"; + const grpc::string kLoadKey2 = "kLoadKey2"; + const grpc::string kLbTag1 = "kLbTag1"; + const grpc::string kLbTag2 = "kLbTag2"; + const grpc::string kUser1 = "kUser1"; + const grpc::string kUser2 = "kUser2"; + const grpc::string kClientIp1 = "00"; + const grpc::string kClientIp2 = "02"; + const grpc::string kMetric1 = "kMetric1"; + const grpc::string kMetric2 = "kMetric2"; + const LoadRecordKey kKey1; + const LoadRecordKey kKey2; +}; + +using PerBalancerStoreTest = LoadDataStoreTest; + +TEST_F(LoadDataStoreTest, AssignToSelf) { + LoadDataStore load_data_store; + load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1); + auto assigned_stores = load_data_store.GetAssignedStores(kHostname1, kLbId1); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_stores, + kHostname1, kLbId1, kLoadKey1)); +} + +TEST_F(LoadDataStoreTest, ReassignOrphanStores) { + LoadDataStore load_data_store; + load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1); + load_data_store.ReportStreamCreated(kHostname1, kLbId2, kLoadKey1); + load_data_store.ReportStreamCreated(kHostname1, kLbId3, kLoadKey2); + load_data_store.ReportStreamCreated(kHostname2, kLbId4, kLoadKey1); + // 1. Close the second stream. + load_data_store.ReportStreamClosed(kHostname1, kLbId2); + auto assigned_to_lb_id_1 = + load_data_store.GetAssignedStores(kHostname1, kLbId1); + // The orphaned store is re-assigned to kLbId1 with the same load key. + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_1, + kHostname1, kLbId1, kLoadKey1)); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_1, + kHostname1, kLbId2, kLoadKey1)); + // 2. Close the first stream. + load_data_store.ReportStreamClosed(kHostname1, kLbId1); + auto assigned_to_lb_id_3 = + load_data_store.GetAssignedStores(kHostname1, kLbId3); + // The orphaned stores are re-assigned to kLbId3 with the same host, + // because there isn't any LB with the same load key. + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3, + kHostname1, kLbId1, kLoadKey1)); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3, + kHostname1, kLbId2, kLoadKey1)); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3, + kHostname1, kLbId3, kLoadKey2)); + // 3. Close the third stream. + load_data_store.ReportStreamClosed(kHostname1, kLbId3); + auto assigned_to_lb_id_4 = + load_data_store.GetAssignedStores(kHostname2, kLbId4); + // There is no active LB for the first host now. kLbId4 is active but + // it's for the second host, so it wll NOT adopt the orphaned stores. + EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4, + kHostname1, kLbId1, kLoadKey1)); + EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4, + kHostname1, kLbId2, kLoadKey1)); + EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4, + kHostname1, kLbId3, kLoadKey2)); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4, + kHostname2, kLbId4, kLoadKey1)); +} + +TEST_F(LoadDataStoreTest, OrphanAssignmentIsSticky) { + LoadDataStore load_data_store; + std::set<grpc::string> active_lb_ids; + size_t num_lb_ids = 1000; + for (size_t i = 0; i < num_lb_ids; ++i) { + load_data_store.ReportStreamCreated(kHostname1, FormatLbId(i), kLoadKey1); + active_lb_ids.insert(FormatLbId(i)); + } + grpc::string orphaned_lb_id = FormatLbId(std::rand() % num_lb_ids); + load_data_store.ReportStreamClosed(kHostname1, orphaned_lb_id); + active_lb_ids.erase(orphaned_lb_id); + // Find which LB is assigned the orphaned store. + grpc::string assigned_lb_id = ""; + for (auto lb_id : active_lb_ids) { + if (PerBalancerStoresContains( + load_data_store, + load_data_store.GetAssignedStores(kHostname1, lb_id), kHostname1, + orphaned_lb_id, kLoadKey1)) { + assigned_lb_id = lb_id; + break; + } + } + EXPECT_STRNE(assigned_lb_id.c_str(), ""); + // Close 10 more stream, skipping the assigned_lb_id. The assignment of + // orphaned_lb_id shouldn't change. + for (size_t _ = 0; _ < 10; ++_) { + grpc::string lb_id_to_close = ""; + for (auto lb_id : active_lb_ids) { + if (lb_id != assigned_lb_id) { + lb_id_to_close = lb_id; + break; + } + } + EXPECT_STRNE(lb_id_to_close.c_str(), ""); + load_data_store.ReportStreamClosed(kHostname1, lb_id_to_close); + active_lb_ids.erase(lb_id_to_close); + EXPECT_TRUE(PerBalancerStoresContains( + load_data_store, + load_data_store.GetAssignedStores(kHostname1, assigned_lb_id), + kHostname1, orphaned_lb_id, kLoadKey1)); + } + // Close the assigned_lb_id, orphaned_lb_id will be re-assigned again. + load_data_store.ReportStreamClosed(kHostname1, assigned_lb_id); + active_lb_ids.erase(assigned_lb_id); + size_t orphaned_lb_id_occurences = 0; + for (auto lb_id : active_lb_ids) { + if (PerBalancerStoresContains( + load_data_store, + load_data_store.GetAssignedStores(kHostname1, lb_id), kHostname1, + orphaned_lb_id, kLoadKey1)) { + orphaned_lb_id_occurences++; + } + } + EXPECT_EQ(orphaned_lb_id_occurences, 1U); +} + +TEST_F(LoadDataStoreTest, HostTemporarilyLoseAllStreams) { + LoadDataStore load_data_store; + load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1); + load_data_store.ReportStreamCreated(kHostname2, kLbId2, kLoadKey1); + auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1); + auto store_invalid_lb_id_1 = + load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId); + EXPECT_FALSE(store_lb_id_1->IsSuspended()); + EXPECT_FALSE(store_invalid_lb_id_1->IsSuspended()); + // Disconnect all the streams of the first host. + load_data_store.ReportStreamClosed(kHostname1, kLbId1); + // All the streams of that host are suspended. + EXPECT_TRUE(store_lb_id_1->IsSuspended()); + EXPECT_TRUE(store_invalid_lb_id_1->IsSuspended()); + // Detailed load data won't be kept when the PerBalancerStore is suspended. + store_lb_id_1->MergeRow(kKey1, LoadRecordValue()); + store_invalid_lb_id_1->MergeRow(kKey1, LoadRecordValue()); + EXPECT_EQ(store_lb_id_1->load_record_map().size(), 0U); + EXPECT_EQ(store_invalid_lb_id_1->load_record_map().size(), 0U); + // The stores for different hosts won't mix, even if the load key is the same. + auto assigned_to_lb_id_2 = + load_data_store.GetAssignedStores(kHostname2, kLbId2); + EXPECT_EQ(assigned_to_lb_id_2->size(), 2U); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_2, + kHostname2, kLbId2, kLoadKey1)); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_2, + kHostname2, kInvalidLbId, "")); + // A new stream is created for the first host. + load_data_store.ReportStreamCreated(kHostname1, kLbId3, kLoadKey2); + // The stores for the first host are resumed. + EXPECT_FALSE(store_lb_id_1->IsSuspended()); + EXPECT_FALSE(store_invalid_lb_id_1->IsSuspended()); + store_lb_id_1->MergeRow(kKey1, LoadRecordValue()); + store_invalid_lb_id_1->MergeRow(kKey1, LoadRecordValue()); + EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U); + EXPECT_EQ(store_invalid_lb_id_1->load_record_map().size(), 1U); + // The resumed stores are assigned to the new LB. + auto assigned_to_lb_id_3 = + load_data_store.GetAssignedStores(kHostname1, kLbId3); + EXPECT_EQ(assigned_to_lb_id_3->size(), 3U); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3, + kHostname1, kLbId1, kLoadKey1)); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3, + kHostname1, kInvalidLbId, "")); + EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3, + kHostname1, kLbId3, kLoadKey2)); +} + +TEST_F(LoadDataStoreTest, OneStorePerLbId) { + LoadDataStore load_data_store; + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kLbId1), nullptr); + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId), + nullptr); + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr); + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr); + // Create The first stream. + load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1); + auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1); + auto store_invalid_lb_id_1 = + load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId); + // Two stores will be created: one is for the stream; the other one is for + // kInvalidLbId. + EXPECT_NE(store_lb_id_1, nullptr); + EXPECT_NE(store_invalid_lb_id_1, nullptr); + EXPECT_NE(store_lb_id_1, store_invalid_lb_id_1); + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr); + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr); + // Create the second stream. + load_data_store.ReportStreamCreated(kHostname2, kLbId3, kLoadKey1); + auto store_lb_id_3 = load_data_store.FindPerBalancerStore(kHostname2, kLbId3); + auto store_invalid_lb_id_2 = + load_data_store.FindPerBalancerStore(kHostname2, kInvalidLbId); + EXPECT_NE(store_lb_id_3, nullptr); + EXPECT_NE(store_invalid_lb_id_2, nullptr); + EXPECT_NE(store_lb_id_3, store_invalid_lb_id_2); + // The PerBalancerStores created for different hosts are independent. + EXPECT_NE(store_lb_id_3, store_invalid_lb_id_1); + EXPECT_NE(store_invalid_lb_id_2, store_invalid_lb_id_1); + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr); +} + +TEST_F(LoadDataStoreTest, ExactlyOnceAssignment) { + LoadDataStore load_data_store; + size_t num_create = 100; + size_t num_close = 50; + for (size_t i = 0; i < num_create; ++i) { + load_data_store.ReportStreamCreated(kHostname1, FormatLbId(i), kLoadKey1); + } + for (size_t i = 0; i < num_close; ++i) { + load_data_store.ReportStreamClosed(kHostname1, FormatLbId(i)); + } + std::set<grpc::string> reported_lb_ids; + for (size_t i = num_close; i < num_create; ++i) { + for (auto assigned_store : + *load_data_store.GetAssignedStores(kHostname1, FormatLbId(i))) { + EXPECT_TRUE(reported_lb_ids.insert(assigned_store->lb_id()).second); + } + } + // Add one for kInvalidLbId. + EXPECT_EQ(reported_lb_ids.size(), (num_create + 1)); + EXPECT_NE(reported_lb_ids.find(kInvalidLbId), reported_lb_ids.end()); +} + +TEST_F(LoadDataStoreTest, UnknownBalancerIdTracking) { + LoadDataStore load_data_store; + load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1); + // Merge data for a known LB ID. + LoadRecordValue v1(192); + load_data_store.MergeRow(kHostname1, kKey1, v1); + // Merge data for unknown LB ID. + LoadRecordValue v2(23); + EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId2)); + load_data_store.MergeRow( + kHostname1, LoadRecordKey(kLbId2, kLbTag1, kUser1, kClientIp1), v2); + EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId2)); + LoadRecordValue v3(952); + load_data_store.MergeRow( + kHostname2, LoadRecordKey(kLbId3, kLbTag1, kUser1, kClientIp1), v3); + EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId3)); + // The data kept for a known LB ID is correct. + auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1); + EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U); + EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.start_count(), + v1.start_count()); + EXPECT_EQ(store_lb_id_1->GetNumCallsInProgressForReport(), v1.start_count()); + // No PerBalancerStore created for Unknown LB ID. + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kLbId2), nullptr); + EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr); + // End all the started RPCs for kLbId1. + LoadRecordValue v4(0, v1.start_count()); + load_data_store.MergeRow(kHostname1, kKey1, v4); + EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U); + EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.start_count(), + v1.start_count()); + EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.ok_count(), + v4.ok_count()); + EXPECT_EQ(store_lb_id_1->GetNumCallsInProgressForReport(), 0U); + EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId1)); + // End all the started RPCs for kLbId2. + LoadRecordValue v5(0, v2.start_count()); + load_data_store.MergeRow( + kHostname1, LoadRecordKey(kLbId2, kLbTag1, kUser1, kClientIp1), v5); + EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId2)); + // End some of the started RPCs for kLbId3. + LoadRecordValue v6(0, v3.start_count() / 2); + load_data_store.MergeRow( + kHostname2, LoadRecordKey(kLbId3, kLbTag1, kUser1, kClientIp1), v6); + EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId3)); +} + +TEST_F(PerBalancerStoreTest, Suspend) { + PerBalancerStore per_balancer_store(kLbId1, kLoadKey1); + EXPECT_FALSE(per_balancer_store.IsSuspended()); + // Suspend the store. + per_balancer_store.Suspend(); + EXPECT_TRUE(per_balancer_store.IsSuspended()); + EXPECT_EQ(0U, per_balancer_store.load_record_map().size()); + // Data merged when the store is suspended won't be kept. + LoadRecordValue v1(139, 19); + per_balancer_store.MergeRow(kKey1, v1); + EXPECT_EQ(0U, per_balancer_store.load_record_map().size()); + // Resume the store. + per_balancer_store.Resume(); + EXPECT_FALSE(per_balancer_store.IsSuspended()); + EXPECT_EQ(0U, per_balancer_store.load_record_map().size()); + // Data merged after the store is resumed will be kept. + LoadRecordValue v2(23, 0, 51); + per_balancer_store.MergeRow(kKey1, v2); + EXPECT_EQ(1U, per_balancer_store.load_record_map().size()); + // Suspend the store. + per_balancer_store.Suspend(); + EXPECT_TRUE(per_balancer_store.IsSuspended()); + EXPECT_EQ(0U, per_balancer_store.load_record_map().size()); + // Data merged when the store is suspended won't be kept. + LoadRecordValue v3(62, 11); + per_balancer_store.MergeRow(kKey1, v3); + EXPECT_EQ(0U, per_balancer_store.load_record_map().size()); + // Resume the store. + per_balancer_store.Resume(); + EXPECT_FALSE(per_balancer_store.IsSuspended()); + EXPECT_EQ(0U, per_balancer_store.load_record_map().size()); + // Data merged after the store is resumed will be kept. + LoadRecordValue v4(225, 98); + per_balancer_store.MergeRow(kKey1, v4); + EXPECT_EQ(1U, per_balancer_store.load_record_map().size()); + // In-progress count is always kept. + EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(), + v1.start_count() - v1.ok_count() + v2.start_count() - + v2.error_count() + v3.start_count() - v3.ok_count() + + v4.start_count() - v4.ok_count()); +} + +TEST_F(PerBalancerStoreTest, DataAggregation) { + PerBalancerStore per_balancer_store(kLbId1, kLoadKey1); + // Construct some Values. + LoadRecordValue v1(992, 34, 13, 234.0, 164.0, 173467.38); + v1.InsertCallMetric(kMetric1, CallMetricValue(3, 2773.2)); + LoadRecordValue v2(4842, 213, 9, 393.0, 974.0, 1345.2398); + v2.InsertCallMetric(kMetric1, CallMetricValue(7, 25.234)); + v2.InsertCallMetric(kMetric2, CallMetricValue(2, 387.08)); + // v3 doesn't change the number of in-progress RPCs. + LoadRecordValue v3(293, 55, 293 - 55, 28764, 5284, 5772); + v3.InsertCallMetric(kMetric1, CallMetricValue(61, 3465.0)); + v3.InsertCallMetric(kMetric2, CallMetricValue(13, 672.0)); + // The initial state of the store. + uint64_t num_calls_in_progress = 0; + EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport()); + EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(), + num_calls_in_progress); + // Merge v1 and get report of the number of in-progress calls. + per_balancer_store.MergeRow(kKey1, v1); + EXPECT_TRUE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport()); + EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(), + num_calls_in_progress += + (v1.start_count() - v1.ok_count() - v1.error_count())); + EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport()); + // Merge v2 and get report of the number of in-progress calls. + per_balancer_store.MergeRow(kKey2, v2); + EXPECT_TRUE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport()); + EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(), + num_calls_in_progress += + (v2.start_count() - v2.ok_count() - v2.error_count())); + EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport()); + // Merge v3 and get report of the number of in-progress calls. + per_balancer_store.MergeRow(kKey1, v3); + EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport()); + EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(), + num_calls_in_progress); + // LoadRecordValue for kKey1 is aggregated correctly. + LoadRecordValue value_for_key1 = + per_balancer_store.load_record_map().find(kKey1)->second; + EXPECT_EQ(value_for_key1.start_count(), v1.start_count() + v3.start_count()); + EXPECT_EQ(value_for_key1.ok_count(), v1.ok_count() + v3.ok_count()); + EXPECT_EQ(value_for_key1.error_count(), v1.error_count() + v3.error_count()); + EXPECT_EQ(value_for_key1.bytes_sent(), v1.bytes_sent() + v3.bytes_sent()); + EXPECT_EQ(value_for_key1.bytes_recv(), v1.bytes_recv() + v3.bytes_recv()); + EXPECT_EQ(value_for_key1.latency_ms(), v1.latency_ms() + v3.latency_ms()); + EXPECT_EQ(value_for_key1.call_metrics().size(), 2U); + EXPECT_EQ(value_for_key1.call_metrics().find(kMetric1)->second.num_calls(), + v1.call_metrics().find(kMetric1)->second.num_calls() + + v3.call_metrics().find(kMetric1)->second.num_calls()); + EXPECT_EQ( + value_for_key1.call_metrics().find(kMetric1)->second.total_metric_value(), + v1.call_metrics().find(kMetric1)->second.total_metric_value() + + v3.call_metrics().find(kMetric1)->second.total_metric_value()); + EXPECT_EQ(value_for_key1.call_metrics().find(kMetric2)->second.num_calls(), + v3.call_metrics().find(kMetric2)->second.num_calls()); + EXPECT_EQ( + value_for_key1.call_metrics().find(kMetric2)->second.total_metric_value(), + v3.call_metrics().find(kMetric2)->second.total_metric_value()); + // LoadRecordValue for kKey2 is aggregated (trivially) correctly. + LoadRecordValue value_for_key2 = + per_balancer_store.load_record_map().find(kKey2)->second; + EXPECT_EQ(value_for_key2.start_count(), v2.start_count()); + EXPECT_EQ(value_for_key2.ok_count(), v2.ok_count()); + EXPECT_EQ(value_for_key2.error_count(), v2.error_count()); + EXPECT_EQ(value_for_key2.bytes_sent(), v2.bytes_sent()); + EXPECT_EQ(value_for_key2.bytes_recv(), v2.bytes_recv()); + EXPECT_EQ(value_for_key2.latency_ms(), v2.latency_ms()); + EXPECT_EQ(value_for_key2.call_metrics().size(), 2U); + EXPECT_EQ(value_for_key2.call_metrics().find(kMetric1)->second.num_calls(), + v2.call_metrics().find(kMetric1)->second.num_calls()); + EXPECT_EQ( + value_for_key2.call_metrics().find(kMetric1)->second.total_metric_value(), + v2.call_metrics().find(kMetric1)->second.total_metric_value()); + EXPECT_EQ(value_for_key2.call_metrics().find(kMetric2)->second.num_calls(), + v2.call_metrics().find(kMetric2)->second.num_calls()); + EXPECT_EQ( + value_for_key2.call_metrics().find(kMetric2)->second.total_metric_value(), + v2.call_metrics().find(kMetric2)->second.total_metric_value()); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc index 694ce549c0..5c22dda16f 100644 --- a/test/cpp/server/server_builder_test.cc +++ b/test/cpp/server/server_builder_test.cc @@ -16,11 +16,11 @@ * */ -#include <grpc++/impl/codegen/config.h> +#include <grpcpp/impl/codegen/config.h> #include <gtest/gtest.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> #include <grpc/grpc.h> @@ -39,7 +39,10 @@ grpc::string MakePort() { return s.str(); } -grpc::string g_port = MakePort(); +const grpc::string& GetPort() { + static grpc::string g_port = MakePort(); + return g_port; +} TEST(ServerBuilderTest, NoOp) { ServerBuilder b; } @@ -50,7 +53,7 @@ TEST(ServerBuilderTest, CreateServerNoPorts) { TEST(ServerBuilderTest, CreateServerOnePort) { ServerBuilder() .RegisterService(&g_service) - .AddListeningPort(g_port, InsecureServerCredentials()) + .AddListeningPort(GetPort(), InsecureServerCredentials()) .BuildAndStart() ->Shutdown(); } @@ -58,8 +61,8 @@ TEST(ServerBuilderTest, CreateServerOnePort) { TEST(ServerBuilderTest, CreateServerRepeatedPort) { ServerBuilder() .RegisterService(&g_service) - .AddListeningPort(g_port, InsecureServerCredentials()) - .AddListeningPort(g_port, InsecureServerCredentials()) + .AddListeningPort(GetPort(), InsecureServerCredentials()) + .AddListeningPort(GetPort(), InsecureServerCredentials()) .BuildAndStart() ->Shutdown(); } @@ -67,8 +70,8 @@ TEST(ServerBuilderTest, CreateServerRepeatedPort) { TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { EXPECT_EQ(ServerBuilder() .RegisterService(&g_service) - .AddListeningPort(g_port, InsecureServerCredentials()) - .AddListeningPort(g_port, InsecureServerCredentials()) + .AddListeningPort(GetPort(), InsecureServerCredentials()) + .AddListeningPort(GetPort(), InsecureServerCredentials()) .AddChannelArgument(GRPC_ARG_ALLOW_REUSEPORT, 0) .BuildAndStart(), nullptr); diff --git a/test/cpp/server/server_builder_with_socket_mutator_test.cc b/test/cpp/server/server_builder_with_socket_mutator_test.cc new file mode 100644 index 0000000000..5c7dd696c9 --- /dev/null +++ b/test/cpp/server/server_builder_with_socket_mutator_test.cc @@ -0,0 +1,116 @@ +/* + * + * 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 <grpcpp/impl/codegen/config.h> +#include <gtest/gtest.h> + +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> + +#include <grpc/grpc.h> +#include <memory> + +#include "src/core/lib/iomgr/socket_mutator.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" + +/* This test does a sanity check that grpc_socket_mutator's + * are used by servers. It's meant to protect code and end-to-end + * tests that rely on this functionality but which live outside + * of the grpc github repo. */ + +namespace grpc { +namespace { + +bool mock_socket_mutator_mutate_fd(int, grpc_socket_mutator*); +int mock_socket_mutator_compare(grpc_socket_mutator*, grpc_socket_mutator*); +void mock_socket_mutator_destroy(grpc_socket_mutator*); + +const grpc_socket_mutator_vtable mock_socket_mutator_vtable = { + mock_socket_mutator_mutate_fd, + mock_socket_mutator_compare, + mock_socket_mutator_destroy, +}; + +class MockSocketMutator : public grpc_socket_mutator { + public: + MockSocketMutator() : mutate_fd_call_count_(0) { + grpc_socket_mutator_init(this, &mock_socket_mutator_vtable); + } + int mutate_fd_call_count_; +}; + +bool mock_socket_mutator_mutate_fd(int fd, grpc_socket_mutator* m) { + MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m); + s->mutate_fd_call_count_++; + return true; +} + +int mock_socket_mutator_compare(grpc_socket_mutator* a, + grpc_socket_mutator* b) { + return (uintptr_t)a - (uintptr_t)b; +} + +void mock_socket_mutator_destroy(grpc_socket_mutator* m) { + MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m); + delete s; +} + +class MockSocketMutatorServerBuilderOption : public grpc::ServerBuilderOption { + public: + MockSocketMutatorServerBuilderOption(MockSocketMutator* mock_socket_mutator) + : mock_socket_mutator_(mock_socket_mutator) {} + + void UpdateArguments(ChannelArguments* args) override { + args->SetSocketMutator(mock_socket_mutator_); + } + + void UpdatePlugins( + std::vector<std::unique_ptr<ServerBuilderPlugin>>*) override{}; + + MockSocketMutator* mock_socket_mutator_; +}; + +TEST(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) { + auto address = "localhost:" + std::to_string(grpc_pick_unused_port_or_die()); + auto mock_socket_mutator = new MockSocketMutator(); + std::unique_ptr<grpc::ServerBuilderOption> mock_socket_mutator_builder_option( + new MockSocketMutatorServerBuilderOption(mock_socket_mutator)); + testing::EchoTestService::Service echo_service; + EXPECT_EQ(mock_socket_mutator->mutate_fd_call_count_, 0); + ServerBuilder builder; + builder.RegisterService(&echo_service); + builder.AddListeningPort(address, InsecureServerCredentials()); + builder.SetOption(std::move(mock_socket_mutator_builder_option)); + std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); + EXPECT_NE(server, nullptr); + // Only assert that the socket mutator was used. + EXPECT_GE(mock_socket_mutator->mutate_fd_call_count_, 1); + server->Shutdown(); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_init(); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/test/cpp/server/server_request_call_test.cc b/test/cpp/server/server_request_call_test.cc index b0a2fa444c..9831c06176 100644 --- a/test/cpp/server/server_request_call_test.cc +++ b/test/cpp/server/server_request_call_test.cc @@ -18,13 +18,13 @@ #include <thread> -#include <grpc++/impl/codegen/config.h> +#include <grpcpp/impl/codegen/config.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> -#include <grpc++/create_channel.h> -#include <grpc++/security/credentials.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/security/credentials.h> #include <grpc/support/log.h> diff --git a/test/cpp/test/BUILD b/test/cpp/test/BUILD new file mode 100644 index 0000000000..c549478919 --- /dev/null +++ b/test/cpp/test/BUILD @@ -0,0 +1,39 @@ +# 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. + +licenses(["notice"]) # Apache v2 + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package", "grpc_cc_binary") + +grpc_package( + name = "test/cpp/test", + visibility = "public", +) + +grpc_cc_test( + name = "server_context_test_spouse_test", + srcs = ["server_context_test_spouse_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//:grpc++_test", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/test/server_context_test_spouse_test.cc b/test/cpp/test/server_context_test_spouse_test.cc index d1dc9d7cac..e199a0fe3d 100644 --- a/test/cpp/test/server_context_test_spouse_test.cc +++ b/test/cpp/test/server_context_test_spouse_test.cc @@ -16,12 +16,12 @@ * */ -#include <grpc++/test/server_context_test_spouse.h> +#include <grpcpp/test/server_context_test_spouse.h> #include <cstring> #include <vector> -#include <grpc++/impl/grpc_library.h> +#include <grpcpp/impl/grpc_library.h> #include <gtest/gtest.h> namespace grpc { diff --git a/test/cpp/thread_manager/BUILD b/test/cpp/thread_manager/BUILD new file mode 100644 index 0000000000..093e51e3fa --- /dev/null +++ b/test/cpp/thread_manager/BUILD @@ -0,0 +1,40 @@ +# 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. + +licenses(["notice"]) # Apache v2 + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package", "grpc_cc_binary") + +grpc_package( + name = "test/cpp/thread_manager", + visibility = "public", +) + +grpc_cc_test( + name = "thread_manager_test", + srcs = ["thread_manager_test.cc"], + external_deps = [ + "gflags", + "gtest", + ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/thread_manager/thread_manager_test.cc b/test/cpp/thread_manager/thread_manager_test.cc index 8282d46694..7a95a9f17d 100644 --- a/test/cpp/thread_manager/thread_manager_test.cc +++ b/test/cpp/thread_manager/thread_manager_test.cc @@ -16,14 +16,15 @@ *is % allowed in string */ +#include <inttypes.h> #include <ctime> #include <memory> #include <string> #include <gflags/gflags.h> -#include <grpc++/grpc++.h> #include <grpc/support/log.h> #include <grpc/support/port_platform.h> +#include <grpcpp/grpcpp.h> #include "src/cpp/thread_manager/thread_manager.h" #include "test/cpp/util/test_config.h" diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index 19e15b1adf..b1153d2df3 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -16,7 +16,10 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_binary", "grpc_cc_test", "grpc_package") -grpc_package(name = "test/cpp/util", visibility = "public") +grpc_package( + name = "test/cpp/util", + visibility = "public", +) grpc_cc_library( name = "test_config", @@ -49,7 +52,7 @@ grpc_cc_library( ], ) -GRPCXX_TESTUTIL_SRCS = [ +GRPCXX_TESTUTIL_SRCS = [ "byte_buffer_proto_helper.cc", "string_ref_helper.cc", "subprocess.cc", @@ -71,11 +74,31 @@ grpc_cc_library( "create_test_channel.h", "test_credentials_provider.h", ], + external_deps = [ + "protobuf", + ], deps = [ "//:grpc++", "//test/core/end2end:ssl_test_data", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_library( + name = "channel_trace_proto_helper", + testonly = 1, + srcs = [ + "channel_trace_proto_helper.cc", + ], + hdrs = [ + "channel_trace_proto_helper.h", + ], + deps = [ + "//:grpc++", + "//src/proto/grpc/channelz:channelz_proto", ], external_deps = [ + "gtest", "protobuf", ], ) @@ -84,12 +107,13 @@ grpc_cc_library( name = "test_util_unsecure", srcs = GRPCXX_TESTUTIL_SRCS, hdrs = GRPCXX_TESTUTIL_HDRS, - deps = [ - "//:grpc++_unsecure", - ], external_deps = [ "protobuf", ], + deps = [ + "//:grpc++_unsecure", + "//test/core/util:grpc_test_util_unsecure", + ], ) grpc_cc_library( @@ -109,16 +133,16 @@ grpc_cc_library( "proto_file_parser.h", "service_describer.h", ], - deps = [ - "//:grpc++", - "//src/proto/grpc/reflection/v1alpha:reflection_proto", - ":grpc++_proto_reflection_desc_db", - ], external_deps = [ "gflags", "protobuf", "protobuf_clib", ], + deps = [ + ":grpc++_proto_reflection_desc_db", + "//:grpc++", + "//src/proto/grpc/reflection/v1alpha:reflection_proto", + ], ) grpc_cc_library( @@ -130,8 +154,8 @@ grpc_cc_library( "metrics_server.h", ], deps = [ - "//src/proto/grpc/testing:metrics_proto", "//:grpc++", + "//src/proto/grpc/testing:metrics_proto", ], ) @@ -140,17 +164,21 @@ grpc_cc_test( srcs = [ "grpc_tool_test.cc", ], - deps = [ - ":grpc_cli_libs", - ":test_util", - "//:grpc++_reflection", - "//src/proto/grpc/testing:echo_proto", - "//src/proto/grpc/testing:echo_messages_proto", - "//test/core/util:grpc_test_util", + data = [ + "//src/proto/grpc/testing:echo.proto", + "//src/proto/grpc/testing:echo_messages.proto", ], external_deps = [ "gtest", ], + deps = [ + ":grpc_cli_libs", + ":test_util", + "//:grpc++_reflection", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( @@ -158,12 +186,12 @@ grpc_cc_test( srcs = [ "byte_buffer_test.cc", ], - deps = [ - ":test_util", - ], external_deps = [ "gtest", ], + deps = [ + ":test_util", + ], ) grpc_cc_test( @@ -171,12 +199,12 @@ grpc_cc_test( srcs = [ "slice_test.cc", ], - deps = [ - ":test_util", - ], external_deps = [ "gtest", ], + deps = [ + ":test_util", + ], ) grpc_cc_test( @@ -184,12 +212,12 @@ grpc_cc_test( srcs = [ "string_ref_test.cc", ], - deps = [ - "//:grpc++", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + ], ) grpc_cc_test( @@ -197,24 +225,11 @@ grpc_cc_test( srcs = [ "time_test.cc", ], - deps = [ - ":test_util", - ], external_deps = [ "gtest", ], -) - -grpc_cc_test( - name = "status_test", - srcs = [ - "status_test.cc", - ], deps = [ - ":test_util", - ], - external_deps = [ - "gtest", + ":test_util", ], ) @@ -223,14 +238,14 @@ grpc_cc_test( srcs = [ "cli_call_test.cc", ], + external_deps = [ + "gtest", + ], deps = [ ":grpc_cli_libs", - ":test_util", + ":test_util", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:grpc_test_util", - ], - external_deps = [ - "gtest", + "//test/core/util:grpc_test_util", ], ) @@ -239,13 +254,13 @@ grpc_cc_test( srcs = [ "error_details_test.cc", ], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_error_details", "//src/proto/grpc/testing:echo_messages_proto", ], - external_deps = [ - "gtest", - ], ) grpc_cc_binary( @@ -268,11 +283,11 @@ grpc_cc_binary( "test_config.h", "test_config_cc.cc", ], + external_deps = [ + "gflags", + ], deps = [ "//:grpc++", "//src/proto/grpc/reflection/v1alpha:reflection_proto", ], - external_deps = [ - "gflags", - ], ) diff --git a/test/cpp/util/byte_buffer_proto_helper.h b/test/cpp/util/byte_buffer_proto_helper.h index 1a9955e38c..94603db110 100644 --- a/test/cpp/util/byte_buffer_proto_helper.h +++ b/test/cpp/util/byte_buffer_proto_helper.h @@ -21,8 +21,8 @@ #include <memory> -#include <grpc++/impl/codegen/config_protobuf.h> -#include <grpc++/support/byte_buffer.h> +#include <grpcpp/impl/codegen/config_protobuf.h> +#include <grpcpp/support/byte_buffer.h> namespace grpc { namespace testing { diff --git a/test/cpp/util/byte_buffer_test.cc b/test/cpp/util/byte_buffer_test.cc index d603b289c8..b48a53eed1 100644 --- a/test/cpp/util/byte_buffer_test.cc +++ b/test/cpp/util/byte_buffer_test.cc @@ -17,16 +17,20 @@ */ #include <grpc++/support/byte_buffer.h> +#include <grpcpp/impl/grpc_library.h> #include <cstring> #include <vector> -#include <grpc++/support/slice.h> #include <grpc/grpc.h> #include <grpc/slice.h> +#include <grpcpp/support/slice.h> #include <gtest/gtest.h> namespace grpc { + +static internal::GrpcLibraryInitializer g_gli_initializer; + namespace { const char* kContent1 = "hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; @@ -34,6 +38,13 @@ const char* kContent2 = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy world"; class ByteBufferTest : public ::testing::Test {}; +TEST_F(ByteBufferTest, CopyCtor) { + ByteBuffer buffer1; + EXPECT_FALSE(buffer1.Valid()); + ByteBuffer buffer2 = buffer1; + EXPECT_FALSE(buffer2.Valid()); +} + TEST_F(ByteBufferTest, CreateFromSingleSlice) { Slice s(kContent1); ByteBuffer buffer(&s, 1); diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc new file mode 100644 index 0000000000..fbc9f1501c --- /dev/null +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -0,0 +1,56 @@ +/* + * + * 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/cpp/util/channel_trace_proto_helper.h" + +#include <google/protobuf/text_format.h> +#include <google/protobuf/util/json_util.h> + +#include <grpc/grpc.h> +#include <grpc/support/log.h> +#include <gtest/gtest.h> + +#include "src/proto/grpc/channelz/channelz.pb.h" + +namespace grpc { +namespace testing { + +void ValidateChannelTraceProtoJsonTranslation(char* tracer_json_c_str) { + std::string tracer_json_str(tracer_json_c_str); + grpc::channelz::ChannelTrace channel_trace; + google::protobuf::util::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. + // + // options.ignore_unknown_fields = true; + ASSERT_EQ(google::protobuf::util::JsonStringToMessage( + tracer_json_str, &channel_trace, parse_options), + google::protobuf::util::Status::OK); + std::string proto_json_str; + ASSERT_EQ(google::protobuf::util::MessageToJsonString(channel_trace, + &proto_json_str), + google::protobuf::util::Status::OK); + // uncomment these to compare the the json strings. + // gpr_log(GPR_ERROR, "tracer json: %s", tracer_json_str.c_str()); + // gpr_log(GPR_ERROR, "proto json: %s", proto_json_str.c_str()); + ASSERT_EQ(tracer_json_str, proto_json_str); +} + +} // namespace testing +} // namespace grpc diff --git a/test/core/support/vector_test.cc b/test/cpp/util/channel_trace_proto_helper.h index aad9f3be90..d7043d9f06 100644 --- a/test/core/support/vector_test.cc +++ b/test/cpp/util/channel_trace_proto_helper.h @@ -1,6 +1,6 @@ /* * - * Copyright 2017 gRPC authors. + * 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. @@ -16,27 +16,15 @@ * */ -#include "src/core/lib/support/vector.h" -#include <gtest/gtest.h> -#include "test/core/util/test_config.h" +#ifndef GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H +#define GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H -namespace grpc_core { +namespace grpc { namespace testing { -TEST(InlinedVectorTest, CreateAndIterate) { - InlinedVector<int, 1> v{1, 2, 3}; - int sum = 0; - for (auto i : v) { - sum += i; - } - EXPECT_EQ(6, sum); -} +void ValidateChannelTraceProtoJsonTranslation(char* tracer_json_c_str); } // namespace testing -} // namespace grpc_core +} // namespace grpc -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} +#endif // GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc index 4f1a20c727..a3992ab278 100644 --- a/test/cpp/util/cli_call.cc +++ b/test/cpp/util/cli_call.cc @@ -20,17 +20,17 @@ #include <iostream> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/support/byte_buffer.h> #include <grpc/grpc.h> #include <grpc/slice.h> #include <grpc/support/log.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/support/byte_buffer.h> namespace grpc { namespace testing { namespace { -void* tag(int i) { return (void*)(intptr_t)i; } +void* tag(int i) { return (void*)static_cast<intptr_t>(i); } } // namespace Status CliCall::Call(std::shared_ptr<grpc::Channel> channel, @@ -60,7 +60,8 @@ CliCall::CliCall(std::shared_ptr<grpc::Channel> channel, ctx_.AddMetadata(iter->first, iter->second); } } - call_ = stub_->Call(&ctx_, method, &cq_, tag(1)); + call_ = stub_->PrepareCall(&ctx_, method, &cq_); + call_->StartCall(tag(1)); void* got_tag; bool ok; cq_.Next(&got_tag, &ok); diff --git a/test/cpp/util/cli_call.h b/test/cpp/util/cli_call.h index eff18ee318..51ffafd29f 100644 --- a/test/cpp/util/cli_call.h +++ b/test/cpp/util/cli_call.h @@ -21,11 +21,11 @@ #include <map> -#include <grpc++/channel.h> -#include <grpc++/completion_queue.h> -#include <grpc++/generic/generic_stub.h> -#include <grpc++/support/status.h> -#include <grpc++/support/string_ref.h> +#include <grpcpp/channel.h> +#include <grpcpp/completion_queue.h> +#include <grpcpp/generic/generic_stub.h> +#include <grpcpp/support/status.h> +#include <grpcpp/support/string_ref.h> namespace grpc { diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index e54cc8528f..516f3fa53d 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -18,13 +18,13 @@ #include "test/cpp/util/cli_call.h" -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.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 <gtest/gtest.h> #include "src/proto/grpc/testing/echo.grpc.pb.h" diff --git a/test/cpp/util/cli_credentials.h b/test/cpp/util/cli_credentials.h index 469e8c54e6..b1358e77d8 100644 --- a/test/cpp/util/cli_credentials.h +++ b/test/cpp/util/cli_credentials.h @@ -19,8 +19,8 @@ #ifndef GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H #define GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H -#include <grpc++/security/credentials.h> -#include <grpc++/support/config.h> +#include <grpcpp/security/credentials.h> +#include <grpcpp/support/config.h> namespace grpc { namespace testing { diff --git a/test/cpp/util/config_grpc_cli.h b/test/cpp/util/config_grpc_cli.h index c157aab25a..358884196d 100644 --- a/test/cpp/util/config_grpc_cli.h +++ b/test/cpp/util/config_grpc_cli.h @@ -19,7 +19,7 @@ #ifndef GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H #define GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H -#include <grpc++/impl/codegen/config_protobuf.h> +#include <grpcpp/impl/codegen/config_protobuf.h> #ifndef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY #include <google/protobuf/dynamic_message.h> diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index 4d047473b9..0bcd4dbc84 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -18,9 +18,9 @@ #include "test/cpp/util/create_test_channel.h" -#include <grpc++/create_channel.h> -#include <grpc++/security/credentials.h> #include <grpc/support/log.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/security/credentials.h> #include "test/cpp/util/test_credentials_provider.h" @@ -107,37 +107,37 @@ std::shared_ptr<Channel> CreateTestChannel( std::shared_ptr<Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, - bool enable_ssl, bool use_prod_roots, + testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr<CallCredentials>& creds, const ChannelArguments& args) { - grpc::string type; - if (enable_ssl) { - type = testing::kTlsCredentialsType; - } - + grpc::string type = + security_type == testing::ALTS + ? testing::kAltsCredentialsType + : (security_type == testing::TLS ? testing::kTlsCredentialsType + : testing::kInsecureCredentialsType); return CreateTestChannel(server, type, override_hostname, use_prod_roots, creds, args); } std::shared_ptr<Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, - bool enable_ssl, bool use_prod_roots, + testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr<CallCredentials>& creds) { - return CreateTestChannel(server, override_hostname, enable_ssl, + return CreateTestChannel(server, override_hostname, security_type, use_prod_roots, creds, ChannelArguments()); } std::shared_ptr<Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, - bool enable_ssl, bool use_prod_roots) { - return CreateTestChannel(server, override_hostname, enable_ssl, + 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 grpc::string& server, - bool enable_ssl) { - return CreateTestChannel(server, "foo.test.google.fr", enable_ssl, false); +std::shared_ptr<Channel> CreateTestChannel( + const grpc::string& server, testing::transport_security security_type) { + return CreateTestChannel(server, "foo.test.google.fr", security_type, false); } std::shared_ptr<Channel> CreateTestChannel( diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index e2ca8f99b4..c615fb7653 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -21,26 +21,32 @@ #include <memory> -#include <grpc++/security/credentials.h> +#include <grpcpp/security/credentials.h> namespace grpc { class Channel; -std::shared_ptr<Channel> CreateTestChannel(const grpc::string& server, - bool enable_ssl); +namespace testing { + +typedef enum { INSECURE = 0, TLS, ALTS } transport_security; + +} // namespace testing + +std::shared_ptr<Channel> CreateTestChannel( + const grpc::string& server, testing::transport_security security_type); std::shared_ptr<Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, - bool enable_ssl, bool use_prod_roots); + testing::transport_security security_type, bool use_prod_roots); std::shared_ptr<Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, - bool enable_ssl, bool use_prod_roots, + testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr<CallCredentials>& creds); std::shared_ptr<Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, - bool enable_ssl, bool use_prod_roots, + testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr<CallCredentials>& creds, const ChannelArguments& args); diff --git a/test/cpp/util/error_details_test.cc b/test/cpp/util/error_details_test.cc index 16a00fb201..f71dfc0df9 100644 --- a/test/cpp/util/error_details_test.cc +++ b/test/cpp/util/error_details_test.cc @@ -16,7 +16,7 @@ * */ -#include <grpc++/support/error_details.h> +#include <grpcpp/support/error_details.h> #include <gtest/gtest.h> #include "src/proto/grpc/status/status.pb.h" diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index 67359434a2..10e13d929b 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -58,7 +58,7 @@ #include <iostream> #include <gflags/gflags.h> -#include <grpc++/support/config.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" diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 4a27bf7414..840ca07d2b 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -27,13 +27,13 @@ #include <thread> #include <gflags/gflags.h> -#include <grpc++/channel.h> -#include <grpc++/create_channel.h> -#include <grpc++/grpc++.h> -#include <grpc++/security/credentials.h> -#include <grpc++/support/string_ref.h> #include <grpc/grpc.h> #include <grpc/support/port_platform.h> +#include <grpcpp/channel.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/grpcpp.h> +#include <grpcpp/security/credentials.h> +#include <grpcpp/support/string_ref.h> #include "test/cpp/util/cli_call.h" #include "test/cpp/util/proto_file_parser.h" @@ -758,6 +758,8 @@ bool GrpcTool::CallMethod(int argc, const char** argv, } } Status status = call.Finish(&server_trailing_metadata); + PrintMetadata(server_trailing_metadata, + "Received trailing metadata from server:"); if (status.ok()) { fprintf(stderr, "Rpc succeeded with OK status\n"); return true; diff --git a/test/cpp/util/grpc_tool.h b/test/cpp/util/grpc_tool.h index a10422f882..fb53af77c8 100644 --- a/test/cpp/util/grpc_tool.h +++ b/test/cpp/util/grpc_tool.h @@ -21,7 +21,7 @@ #include <functional> -#include <grpc++/support/config.h> +#include <grpcpp/support/config.h> #include "test/cpp/util/cli_credentials.h" diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 0b599f4eeb..6574d1bb44 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -21,16 +21,18 @@ #include <sstream> #include <gflags/gflags.h> -#include <grpc++/channel.h> -#include <grpc++/client_context.h> -#include <grpc++/create_channel.h> -#include <grpc++/ext/proto_server_reflection_plugin.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.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 <gtest/gtest.h> +#include "src/core/lib/gpr/env.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "src/proto/grpc/testing/echo.pb.h" #include "test/core/util/port.h" @@ -87,6 +89,7 @@ DECLARE_bool(l); DECLARE_bool(batch); DECLARE_string(metadata); DECLARE_string(protofiles); +DECLARE_string(proto_path); namespace { @@ -707,6 +710,10 @@ TEST_F(GrpcToolTest, CallCommandWithBadMetadata) { const char* argv[] = {"grpc_cli", "call", "localhost:10000", "Echo", "message: 'Hello'"}; FLAGS_protofiles = "src/proto/grpc/testing/echo.proto"; + char* test_srcdir = gpr_getenv("TEST_SRCDIR"); + if (test_srcdir != nullptr) { + FLAGS_proto_path = test_srcdir + std::string("/com_github_grpc_grpc"); + } { std::stringstream output_stream; @@ -732,6 +739,8 @@ TEST_F(GrpcToolTest, CallCommandWithBadMetadata) { FLAGS_metadata = ""; FLAGS_protofiles = ""; + + gpr_free(test_srcdir); } } // namespace testing diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc index 5982815dd7..a058206506 100644 --- a/test/cpp/util/metrics_server.cc +++ b/test/cpp/util/metrics_server.cc @@ -18,9 +18,9 @@ #include "test/cpp/util/metrics_server.h" -#include <grpc++/server.h> -#include <grpc++/server_builder.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" diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc index e2c8b05220..3fc96f38ae 100644 --- a/test/cpp/util/proto_file_parser.cc +++ b/test/cpp/util/proto_file_parser.cc @@ -23,7 +23,7 @@ #include <sstream> #include <unordered_set> -#include <grpc++/support/config.h> +#include <grpcpp/support/config.h> namespace grpc { namespace testing { diff --git a/test/cpp/util/proto_file_parser.h b/test/cpp/util/proto_file_parser.h index 35f3782f14..2236b59451 100644 --- a/test/cpp/util/proto_file_parser.h +++ b/test/cpp/util/proto_file_parser.h @@ -21,7 +21,7 @@ #include <memory> -#include <grpc++/channel.h> +#include <grpcpp/channel.h> #include "test/cpp/util/config_grpc_cli.h" #include "test/cpp/util/proto_reflection_descriptor_database.h" diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc index 0f77934672..0adbf20ce6 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/test/cpp/util/proto_reflection_descriptor_database.cc @@ -43,9 +43,15 @@ ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { stream_->WritesDone(); Status status = stream_->Finish(); if (!status.ok()) { + if (status.error_code() == StatusCode::UNIMPLEMENTED) { + gpr_log(GPR_INFO, + "Reflection request not implemented; " + "is the ServerReflection service enabled?"); + } gpr_log(GPR_INFO, "ServerReflectionInfo rpc failed. Error code: %d, details: %s", - (int)status.error_code(), status.error_message().c_str()); + static_cast<int>(status.error_code()), + status.error_message().c_str()); } } } @@ -64,7 +70,9 @@ bool ProtoReflectionDescriptorDatabase::FindFileByName( request.set_file_by_filename(filename); ServerReflectionResponse response; - DoOneRequest(request, response); + if (!DoOneRequest(request, response)) { + return false; + } if (response.message_response_case() == ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { @@ -109,7 +117,9 @@ bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol( request.set_file_containing_symbol(symbol_name); ServerReflectionResponse response; - DoOneRequest(request, response); + if (!DoOneRequest(request, response)) { + return false; + } if (response.message_response_case() == ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { @@ -163,7 +173,9 @@ bool ProtoReflectionDescriptorDatabase::FindFileContainingExtension( field_number); ServerReflectionResponse response; - DoOneRequest(request, response); + if (!DoOneRequest(request, response)) { + return false; + } if (response.message_response_case() == ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { @@ -213,7 +225,9 @@ bool ProtoReflectionDescriptorDatabase::FindAllExtensionNumbers( request.set_all_extension_numbers_of_type(extendee_type); ServerReflectionResponse response; - DoOneRequest(request, response); + if (!DoOneRequest(request, response)) { + return false; + } if (response.message_response_case() == ServerReflectionResponse::MessageResponseCase:: @@ -245,7 +259,9 @@ bool ProtoReflectionDescriptorDatabase::GetServices( request.set_list_services(""); ServerReflectionResponse response; - DoOneRequest(request, response); + if (!DoOneRequest(request, response)) { + return false; + } if (response.message_response_case() == ServerReflectionResponse::MessageResponseCase::kListServicesResponse) { diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h index a6776c2a86..e4cf2f207e 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.h +++ b/test/cpp/util/proto_reflection_descriptor_database.h @@ -23,8 +23,8 @@ #include <unordered_set> #include <vector> -#include <grpc++/grpc++.h> -#include <grpc++/impl/codegen/config_protobuf.h> +#include <grpcpp/grpcpp.h> +#include <grpcpp/impl/codegen/config_protobuf.h> #include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" namespace grpc { diff --git a/test/cpp/util/service_describer.h b/test/cpp/util/service_describer.h index b7ab7578b4..f7ef50c7bb 100644 --- a/test/cpp/util/service_describer.h +++ b/test/cpp/util/service_describer.h @@ -19,7 +19,7 @@ #ifndef GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H #define GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H -#include <grpc++/support/config.h> +#include <grpcpp/support/config.h> #include "test/cpp/util/config_grpc_cli.h" namespace grpc { diff --git a/test/cpp/util/slice_test.cc b/test/cpp/util/slice_test.cc index c2e55f3374..dc1910038f 100644 --- a/test/cpp/util/slice_test.cc +++ b/test/cpp/util/slice_test.cc @@ -17,12 +17,16 @@ */ #include <grpc++/support/slice.h> +#include <grpcpp/impl/grpc_library.h> #include <grpc/grpc.h> #include <grpc/slice.h> #include <gtest/gtest.h> namespace grpc { + +static internal::GrpcLibraryInitializer g_gli_initializer; + namespace { const char* kContent = "hello xxxxxxxxxxxxxxxxxxxx world"; @@ -67,7 +71,7 @@ TEST_F(SliceTest, StaticBuf) { TEST_F(SliceTest, SliceNew) { char* x = new char[strlen(kContent) + 1]; strcpy(x, kContent); - Slice spp(x, strlen(x), [](void* p) { delete[] reinterpret_cast<char*>(p); }); + Slice spp(x, strlen(x), [](void* p) { delete[] static_cast<char*>(p); }); CheckSlice(spp, kContent); } @@ -86,7 +90,7 @@ TEST_F(SliceTest, SliceNewWithUserData) { strcpy(t->x, kContent); Slice spp(t->x, strlen(t->x), [](void* p) { - auto* t = reinterpret_cast<stest*>(p); + auto* t = static_cast<stest*>(p); delete[] t->x; delete t; }, diff --git a/test/cpp/util/status_test.cc b/test/cpp/util/status_test.cc deleted file mode 100644 index 1047cdb50e..0000000000 --- a/test/cpp/util/status_test.cc +++ /dev/null @@ -1,62 +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/status.h> - -#include <grpc/status.h> -#include <grpc/support/log.h> - -// Make sure the existing grpc_status_code match with grpc::Code. -int main(int argc, char** argv) { - GPR_ASSERT(grpc::StatusCode::OK == - static_cast<grpc::StatusCode>(GRPC_STATUS_OK)); - GPR_ASSERT(grpc::StatusCode::CANCELLED == - static_cast<grpc::StatusCode>(GRPC_STATUS_CANCELLED)); - GPR_ASSERT(grpc::StatusCode::UNKNOWN == - static_cast<grpc::StatusCode>(GRPC_STATUS_UNKNOWN)); - GPR_ASSERT(grpc::StatusCode::INVALID_ARGUMENT == - static_cast<grpc::StatusCode>(GRPC_STATUS_INVALID_ARGUMENT)); - GPR_ASSERT(grpc::StatusCode::DEADLINE_EXCEEDED == - static_cast<grpc::StatusCode>(GRPC_STATUS_DEADLINE_EXCEEDED)); - GPR_ASSERT(grpc::StatusCode::NOT_FOUND == - static_cast<grpc::StatusCode>(GRPC_STATUS_NOT_FOUND)); - GPR_ASSERT(grpc::StatusCode::ALREADY_EXISTS == - static_cast<grpc::StatusCode>(GRPC_STATUS_ALREADY_EXISTS)); - GPR_ASSERT(grpc::StatusCode::PERMISSION_DENIED == - static_cast<grpc::StatusCode>(GRPC_STATUS_PERMISSION_DENIED)); - GPR_ASSERT(grpc::StatusCode::UNAUTHENTICATED == - static_cast<grpc::StatusCode>(GRPC_STATUS_UNAUTHENTICATED)); - GPR_ASSERT(grpc::StatusCode::RESOURCE_EXHAUSTED == - static_cast<grpc::StatusCode>(GRPC_STATUS_RESOURCE_EXHAUSTED)); - GPR_ASSERT(grpc::StatusCode::FAILED_PRECONDITION == - static_cast<grpc::StatusCode>(GRPC_STATUS_FAILED_PRECONDITION)); - GPR_ASSERT(grpc::StatusCode::ABORTED == - static_cast<grpc::StatusCode>(GRPC_STATUS_ABORTED)); - GPR_ASSERT(grpc::StatusCode::OUT_OF_RANGE == - static_cast<grpc::StatusCode>(GRPC_STATUS_OUT_OF_RANGE)); - GPR_ASSERT(grpc::StatusCode::UNIMPLEMENTED == - static_cast<grpc::StatusCode>(GRPC_STATUS_UNIMPLEMENTED)); - GPR_ASSERT(grpc::StatusCode::INTERNAL == - static_cast<grpc::StatusCode>(GRPC_STATUS_INTERNAL)); - GPR_ASSERT(grpc::StatusCode::UNAVAILABLE == - static_cast<grpc::StatusCode>(GRPC_STATUS_UNAVAILABLE)); - GPR_ASSERT(grpc::StatusCode::DATA_LOSS == - static_cast<grpc::StatusCode>(GRPC_STATUS_DATA_LOSS)); - - return 0; -} diff --git a/test/cpp/util/string_ref_helper.h b/test/cpp/util/string_ref_helper.h index e4cb71ad05..707767de07 100644 --- a/test/cpp/util/string_ref_helper.h +++ b/test/cpp/util/string_ref_helper.h @@ -19,7 +19,7 @@ #ifndef GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H #define GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H -#include <grpc++/support/string_ref.h> +#include <grpcpp/support/string_ref.h> namespace grpc { namespace testing { diff --git a/test/cpp/util/string_ref_test.cc b/test/cpp/util/string_ref_test.cc index 3f62760f76..8f7986e64e 100644 --- a/test/cpp/util/string_ref_test.cc +++ b/test/cpp/util/string_ref_test.cc @@ -16,7 +16,7 @@ * */ -#include <grpc++/support/string_ref.h> +#include <grpcpp/support/string_ref.h> #include <string.h> diff --git a/test/cpp/util/subprocess.cc b/test/cpp/util/subprocess.cc index a54d0c087a..ddaad89805 100644 --- a/test/cpp/util/subprocess.cc +++ b/test/cpp/util/subprocess.cc @@ -20,7 +20,7 @@ #include <vector> -#include <grpc/support/subprocess.h> +#include "test/core/util/subprocess.h" namespace grpc { diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 76561007c4..c8b0ac73f4 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -56,6 +56,9 @@ class DefaultCredentialsProvider : public CredentialsProvider { const grpc::string& 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"); @@ -77,6 +80,9 @@ class DefaultCredentialsProvider : public CredentialsProvider { const grpc::string& 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::PemKeyCertPair pkcp = {test_server1_key, test_server1_cert}; diff --git a/test/cpp/util/test_credentials_provider.h b/test/cpp/util/test_credentials_provider.h index 6f8f768d6b..b1d69e893d 100644 --- a/test/cpp/util/test_credentials_provider.h +++ b/test/cpp/util/test_credentials_provider.h @@ -21,18 +21,18 @@ #include <memory> -#include <grpc++/security/credentials.h> -#include <grpc++/security/server_credentials.h> -#include <grpc++/support/channel_arguments.h> +#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"; // Provide test credentials of a particular type. class CredentialTypeProvider { diff --git a/test/cpp/util/time_test.cc b/test/cpp/util/time_test.cc index 73ec44c2a5..a8851a583d 100644 --- a/test/cpp/util/time_test.cc +++ b/test/cpp/util/time_test.cc @@ -16,8 +16,8 @@ * */ -#include <grpc++/support/time.h> #include <grpc/support/time.h> +#include <grpcpp/support/time.h> #include <gtest/gtest.h> using std::chrono::duration_cast; diff --git a/test/distrib/cpp/run_distrib_test_cmake.bat b/test/distrib/cpp/run_distrib_test_cmake.bat index 047846b0f1..8eb3b201b1 100644 --- a/test/distrib/cpp/run_distrib_test_cmake.bat +++ b/test/distrib/cpp/run_distrib_test_cmake.bat @@ -54,17 +54,17 @@ cd ../../../.. cd cmake mkdir build cd build -cmake -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% -DOPENSSL_ROOT_DIR=%OPENSSL_DIR% -DOPENSSL_INCLUDE_DIR=%OPENSSL_DIR%/include -DZLIB_LIBRARY=%INSTALL_DIR%/lib/zlibstatic.lib -DZLIB_INCLUDE_DIR=%INSTALL_DIR%/include -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DgRPC_PROTOBUF_PROVIDER=package -DgRPC_ZLIB_PROVIDER=package -DgRPC_CARES_PROVIDER=package -DgRPC_SSL_PROVIDER=package -DCMAKE_BUILD_TYPE=Release ../.. || goto :error +cmake -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% -DOPENSSL_ROOT_DIR=%OPENSSL_DIR% -DZLIB_ROOT=%INSTALL_DIR% -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DgRPC_PROTOBUF_PROVIDER=package -DgRPC_ZLIB_PROVIDER=package -DgRPC_CARES_PROVIDER=package -DgRPC_SSL_PROVIDER=package -DCMAKE_BUILD_TYPE=Release ../.. || goto :error cmake --build . --config Release --target install || goto :error cd ../.. -# Build helloworld example using cmake +@rem Build helloworld example using cmake cd examples/cpp/helloworld mkdir cmake cd cmake mkdir build cd build -cmake -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% ../.. || goto :error +cmake -DCMAKE_INSTALL_PREFIX=%INSTALL_DIR% -DOPENSSL_ROOT_DIR=%OPENSSL_DIR% -DZLIB_ROOT=%INSTALL_DIR% ../.. || goto :error cmake --build . --config Release || goto :error cd ../../../../.. diff --git a/test/distrib/cpp/run_distrib_test_cmake.sh b/test/distrib/cpp/run_distrib_test_cmake.sh index a9c081c2f5..6ec3cab602 100755 --- a/test/distrib/cpp/run_distrib_test_cmake.sh +++ b/test/distrib/cpp/run_distrib_test_cmake.sh @@ -15,7 +15,7 @@ set -ex -cd $(dirname $0)/../../.. +cd "$(dirname "$0")/../../.." echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list apt-get update diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.bat b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.bat new file mode 100644 index 0000000000..6f4d581944 --- /dev/null +++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.bat @@ -0,0 +1,41 @@ +@rem Copyright 2016 gRPC authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. + +@rem enter this directory +cd /d %~dp0\..\..\.. + +@rem TODO(jtattermusch): Kokoro has pre-installed protoc.exe in C:\Program Files\ProtoC and that directory +@rem is on PATH. To avoid picking up the older version protoc.exe, we change the path to something non-existent. +set PATH=%PATH:ProtoC=DontPickupProtoC% + +@rem Download OpenSSL-Win32 originally installed from https://slproweb.com/products/Win32OpenSSL.html +powershell -Command "(New-Object Net.WebClient).DownloadFile('https://storage.googleapis.com/grpc-testing.appspot.com/OpenSSL-Win32-1_1_0g.zip', 'OpenSSL-Win32.zip')" +powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('OpenSSL-Win32.zip', '.');" + +@rem set absolute path to OpenSSL with forward slashes +set OPENSSL_DIR=%cd:\=/%/OpenSSL-Win32 + +@rem Build helloworld example using cmake +@rem Use non-standard build directory to avoid too long filenames +mkdir example_build +cd example_build +cmake -DOPENSSL_ROOT_DIR=%OPENSSL_DIR% ../examples/cpp/helloworld/cmake_externalproject || goto :error +cmake --build . --config Release || goto :error +cd .. + +goto :EOF + +:error +echo Failed! +exit /b %errorlevel% diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh new file mode 100755 index 0000000000..163527fbd5 --- /dev/null +++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# 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 + +cd "$(dirname "$0")/../../.." + +echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +apt-get update +apt-get install -t jessie-backports -y libssl-dev + +# To increase the confidence that gRPC installation works without depending on +# too many submodules unnecessarily, just wipe out contents of most submodules +# before starting the test. +rm -r third_party/abseil-cpp/* || true +rm -r third_party/benchmark/* || true +rm -r third_party/bloaty/* || true +rm -r third_party/boringssl/* || true +rm -r third_party/boringssl-with-bazel/* || true +rm -r third_party/gflags/* || true +rm -r third_party/googletest/* || true + +# Build helloworld example using cmake superbuild +cd examples/cpp/helloworld/cmake_externalproject +mkdir -p cmake/build +cd cmake/build +cmake ../.. +make + diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_submodule.sh b/test/distrib/cpp/run_distrib_test_cmake_as_submodule.sh new file mode 100755 index 0000000000..defc63e090 --- /dev/null +++ b/test/distrib/cpp/run_distrib_test_cmake_as_submodule.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# 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 + +cd "$(dirname "$0")/../../.." + +# Build helloworld example using cmake, including grpc with "add_subdirectory" +cd examples/cpp/helloworld +mkdir -p cmake/build +cd cmake/build +cmake -DGRPC_AS_SUBMODULE=ON ../.. +make diff --git a/test/distrib/cpp/run_distrib_test_routeguide.sh b/test/distrib/cpp/run_distrib_test_routeguide.sh index b043075d93..dc69ab8377 100755 --- a/test/distrib/cpp/run_distrib_test_routeguide.sh +++ b/test/distrib/cpp/run_distrib_test_routeguide.sh @@ -16,7 +16,7 @@ set -ex # change to grpc repo root -cd $(dirname $0)/../../.. +cd "$(dirname "$0")/../../.." cd third_party/protobuf && ./autogen.sh && \ ./configure && make -j4 && make check && make install && ldconfig diff --git a/test/distrib/csharp/DistribTest/DistribTest.project.json b/test/distrib/csharp/DistribTest/DistribTest.project.json deleted file mode 100644 index 422545ea8f..0000000000 --- a/test/distrib/csharp/DistribTest/DistribTest.project.json +++ /dev/null @@ -1,11 +0,0 @@ -// This file exists only to prevent VS2015 from mistakenly picking up -// project.json file when building .csproj project. -// See https://github.com/Microsoft/msbuild/issues/394 -{ - "frameworks": { - "net45": { } - }, - "runtimes": { - "win": { } - } -} diff --git a/test/distrib/csharp/DistribTest/DistribTestDotNet.csproj b/test/distrib/csharp/DistribTest/DistribTestDotNet.csproj new file mode 100644 index 0000000000..f16a0f9959 --- /dev/null +++ b/test/distrib/csharp/DistribTest/DistribTestDotNet.csproj @@ -0,0 +1,27 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFrameworks>netcoreapp1.0;net45</TargetFrameworks> + <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> + <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> + <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute> + <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute> + <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> + <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute> + <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Grpc" Version="__GRPC_NUGET_VERSION__" /> + <PackageReference Include="Grpc.Auth" Version="__GRPC_NUGET_VERSION__" /> + <PackageReference Include="Grpc.Tools" Version="__GRPC_NUGET_VERSION__" /> + </ItemGroup> + + <PropertyGroup Condition="'$(OS)' != 'Windows_NT'"> + <!-- Workaround for https://github.com/dotnet/sdk/issues/335 --> + <FrameworkPathOverride Condition="Exists('/usr/lib/mono/4.5-api')">/usr/lib/mono/4.5-api</FrameworkPathOverride> + <FrameworkPathOverride Condition="Exists('/usr/local/lib/mono/4.5-api')">/usr/local/lib/mono/4.5-api</FrameworkPathOverride> + <FrameworkPathOverride Condition="Exists('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api</FrameworkPathOverride> + </PropertyGroup> +</Project>
\ No newline at end of file diff --git a/test/distrib/csharp/DistribTest/project.json b/test/distrib/csharp/DistribTest/project.json deleted file mode 100644 index 09266e5d4d..0000000000 --- a/test/distrib/csharp/DistribTest/project.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "buildOptions": { - "emitEntryPoint": true - }, - "dependencies": { - "Grpc.Auth": "__GRPC_NUGET_VERSION__", - "Grpc.Core": "__GRPC_NUGET_VERSION__", - // Necessary for native deps to get copied correctly. - "Microsoft.NETCore.Platforms": "1.0.1" - }, - "frameworks": { - "net45": { }, - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "type": "platform", - "version": "1.0.0" - } - } - } - } -} diff --git a/test/distrib/csharp/run_distrib_test.sh b/test/distrib/csharp/run_distrib_test.sh index 99cdb5e022..eee24d0e57 100755 --- a/test/distrib/csharp/run_distrib_test.sh +++ b/test/distrib/csharp/run_distrib_test.sh @@ -15,7 +15,7 @@ set -ex -cd $(dirname $0) +cd "$(dirname "$0")" unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_windows_dotnetcli.zip" -d TestNugetFeed diff --git a/test/distrib/csharp/run_distrib_test_dotnetcli.sh b/test/distrib/csharp/run_distrib_test_dotnetcli.sh index 53117d4828..86c2d5231e 100755 --- a/test/distrib/csharp/run_distrib_test_dotnetcli.sh +++ b/test/distrib/csharp/run_distrib_test_dotnetcli.sh @@ -15,7 +15,7 @@ set -ex -cd $(dirname $0) +cd "$(dirname "$0")" unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_windows_dotnetcli.zip" -d TestNugetFeed @@ -25,19 +25,22 @@ cd DistribTest # TODO(jtattermusch): make sure we don't pollute the global nuget cache with # the nugets being tested. -dotnet restore +dotnet restore DistribTestDotNet.csproj -dotnet build -dotnet publish +dotnet build DistribTestDotNet.csproj +dotnet publish -f netcoreapp1.0 DistribTestDotNet.csproj +dotnet publish -f net45 DistribTestDotNet.csproj + +ls -R bin # .NET 4.5 target after dotnet build -mono bin/Debug/net45/*-x64/DistribTest.exe +mono bin/Debug/net45/publish/DistribTestDotNet.exe # .NET 4.5 target after dotnet publish -mono bin/Debug/net45/*-x64/publish/DistribTest.exe +mono bin/Debug/net45/publish/DistribTestDotNet.exe # .NET Core target after dotnet build -dotnet exec bin/Debug/netcoreapp1.0/DistribTest.dll +dotnet exec bin/Debug/netcoreapp1.0/DistribTestDotNet.dll # .NET Core target after dotnet publish -dotnet exec bin/Debug/netcoreapp1.0/publish/DistribTest.dll +dotnet exec bin/Debug/netcoreapp1.0/publish/DistribTestDotNet.dll diff --git a/test/distrib/csharp/update_version.sh b/test/distrib/csharp/update_version.sh index 2e9050cb98..9759cc5648 100755 --- a/test/distrib/csharp/update_version.sh +++ b/test/distrib/csharp/update_version.sh @@ -15,15 +15,17 @@ set -e -cd $(dirname $0) +cd "$(dirname "$0")" CSHARP_VERSION="$1" if [ "$CSHARP_VERSION" == "auto" ] then # autodetect C# version from the name of Grpc.Core.0.0.0-x.nupkg file + # TODO: find a better shellcheck-compliant way to write the following line + # shellcheck disable=SC2010 CSHARP_VERSION=$(ls TestNugetFeed | grep -m 1 '^Grpc\.Core\.[0-9].*\.nupkg$' | sed s/^Grpc\.Core\.// | sed s/\.nupkg$// | sed s/\.symbols$//) echo "Autodetected nuget ${CSHARP_VERSION}" fi # Replaces version placeholder with value provided as first argument. -sed -ibak "s/__GRPC_NUGET_VERSION__/${CSHARP_VERSION}/g" DistribTest/packages.config DistribTest/DistribTest.csproj DistribTest/project.json +sed -ibak "s/__GRPC_NUGET_VERSION__/${CSHARP_VERSION}/g" DistribTest/packages.config DistribTest/DistribTest.csproj DistribTest/DistribTestDotNet.csproj diff --git a/test/distrib/php/run_distrib_test.sh b/test/distrib/php/run_distrib_test.sh index 70ebaf88b9..a6102f6075 100755 --- a/test/distrib/php/run_distrib_test.sh +++ b/test/distrib/php/run_distrib_test.sh @@ -15,11 +15,11 @@ set -ex -cd $(dirname $0) +cd "$(dirname "$0")" -cp -r $EXTERNAL_GIT_ROOT/input_artifacts/grpc-*.tgz . +cp -r "$EXTERNAL_GIT_ROOT"/input_artifacts/grpc-*.tgz . -find . -regextype sed -regex ".*/grpc-[0-9].*.tgz" | cut -b3- | \ +find . -regex ".*/grpc-[0-9].*.tgz" | cut -b3- | \ xargs pecl install php -d extension=grpc.so -d max_execution_time=300 distribtest.php diff --git a/test/cpp/naming/create_private_dns_zone.sh b/test/distrib/php/run_distrib_test_macos.sh index 55a4cfe36e..8def049860 100755 --- a/test/cpp/naming/create_private_dns_zone.sh +++ b/test/distrib/php/run_distrib_test_macos.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2015 gRPC authors. +# 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. @@ -13,15 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This file is auto-generated - set -ex -cd $(dirname $0)/../../.. +cd "$(dirname "$0")" + +cp -r "$EXTERNAL_GIT_ROOT"/input_artifacts/grpc-*.tgz . + +find . -regex ".*/grpc-[0-9].*.tgz" | cut -b3- | \ + xargs sudo pecl install -gcloud alpha dns managed-zones create \ - resolver-tests-version-4-grpctestingexp-zone-id \ - --dns-name=resolver-tests-version-4.grpctestingexp. \ - --description="GCE-DNS-private-zone-for-GRPC-testing" \ - --visibility=private \ - --networks=default +php -d extension=grpc.so -d max_execution_time=300 distribtest.php diff --git a/test/distrib/python/run_binary_distrib_test.sh b/test/distrib/python/run_binary_distrib_test.sh new file mode 100755 index 0000000000..061d041637 --- /dev/null +++ b/test/distrib/python/run_binary_distrib_test.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# 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. + +set -ex + +"$(dirname "$0")/test_packages.sh" binary diff --git a/test/distrib/python/run_distrib_test.sh b/test/distrib/python/run_distrib_test.sh deleted file mode 100755 index 02654be467..0000000000 --- a/test/distrib/python/run_distrib_test.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# 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. - -set -ex - -cd $(dirname $0) - -# Pick up the source dist archive whatever its version is -SDIST_ARCHIVES=$EXTERNAL_GIT_ROOT/input_artifacts/grpcio-*.tar.gz -BDIST_ARCHIVES=$EXTERNAL_GIT_ROOT/input_artifacts/grpcio-*.whl -TOOLS_SDIST_ARCHIVES=$EXTERNAL_GIT_ROOT/input_artifacts/grpcio_tools-*.tar.gz -TOOLS_BDIST_ARCHIVES=$EXTERNAL_GIT_ROOT/input_artifacts/grpcio_tools-*.whl - -function make_virtualenv() { - virtualenv $1 - $1/bin/python -m pip install --upgrade six pip - $1/bin/python -m pip install cython -} - -function at_least_one_installs() { - for file in "$@"; do - if python -m pip install $file; then - return 0 - fi - done - return -1 -} - -make_virtualenv bdist_test -make_virtualenv sdist_test - -# -# Install our distributions in order of dependencies -# - -(source bdist_test/bin/activate && at_least_one_installs ${BDIST_ARCHIVES}) -(source bdist_test/bin/activate && at_least_one_installs ${TOOLS_BDIST_ARCHIVES}) - -(source sdist_test/bin/activate && at_least_one_installs ${SDIST_ARCHIVES}) -(source sdist_test/bin/activate && at_least_one_installs ${TOOLS_SDIST_ARCHIVES}) - -# -# Test our distributions -# - -# TODO(jtattermusch): add a .proto file to the distribtest, generate python -# code from it and then use the generated code from distribtest.py -(source bdist_test/bin/activate && python -m grpc.tools.protoc --help) -(source sdist_test/bin/activate && python -m grpc.tools.protoc --help) - -(source bdist_test/bin/activate && python distribtest.py) -(source sdist_test/bin/activate && python distribtest.py) diff --git a/test/distrib/python/run_source_distrib_test.sh b/test/distrib/python/run_source_distrib_test.sh new file mode 100755 index 0000000000..f667674613 --- /dev/null +++ b/test/distrib/python/run_source_distrib_test.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# 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. + +set -ex + +"$(dirname "$0")/test_packages.sh" source diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh new file mode 100755 index 0000000000..6bf49d45b9 --- /dev/null +++ b/test/distrib/python/test_packages.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# 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. + +set -ex + +cd "$(dirname "$0")" + +shopt -s nullglob + +if [[ "$1" == "binary" ]] +then + echo "Testing Python binary distribution" + ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-[0-9]*.whl) + TOOLS_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio_tools-[0-9]*.whl) +else + echo "Testing Python source distribution" + ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-[0-9]*.tar.gz) + TOOLS_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-tools-[0-9]*.tar.gz) + HEALTH_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-health-checking-[0-9]*.tar.gz) + REFLECTION_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-reflection-[0-9]*.tar.gz) +fi + +VIRTUAL_ENV=$(mktemp -d) +virtualenv "$VIRTUAL_ENV" +PYTHON=$VIRTUAL_ENV/bin/python +"$PYTHON" -m pip install --upgrade six pip + +function at_least_one_installs() { + for file in "$@"; do + if "$PYTHON" -m pip install "$file"; then + return 0 + fi + done + return 1 +} + + +# +# Install our distributions in order of dependencies +# + +at_least_one_installs "${ARCHIVES[@]}" +at_least_one_installs "${TOOLS_ARCHIVES[@]}" + +if [[ "$1" == "source" ]] +then + echo "Testing Python health and reflection packages" + at_least_one_installs "${HEALTH_ARCHIVES[@]}" + at_least_one_installs "${REFLECTION_ARCHIVES[@]}" +fi + + +# +# Test our distributions +# + +# TODO(jtattermusch): add a .proto file to the distribtest, generate python +# code from it and then use the generated code from distribtest.py +"$PYTHON" -m grpc.tools.protoc --help + +"$PYTHON" distribtest.py diff --git a/test/distrib/ruby/distribtest.gemspec b/test/distrib/ruby/distribtest.gemspec index d72892f46c..f11f5218d5 100644 --- a/test/distrib/ruby/distribtest.gemspec +++ b/test/distrib/ruby/distribtest.gemspec @@ -14,6 +14,8 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.add_dependency 'grpc', '>=0' + s.add_dependency 'public_suffix', '< 3.0' + s.add_dependency 'jwt', '< 2.0' s.add_development_dependency 'bundler', '~> 1.7' end diff --git a/test/distrib/ruby/run_distrib_test.sh b/test/distrib/ruby/run_distrib_test.sh index 0c214e38f2..cb2eb1ff7d 100755 --- a/test/distrib/ruby/run_distrib_test.sh +++ b/test/distrib/ruby/run_distrib_test.sh @@ -15,15 +15,44 @@ set -ex -cd $(dirname $0) +cd "$(dirname "$0")" +ARCH=$1 +PLATFORM=$2 # Create an indexed local gem source with gRPC gems to test GEM_SOURCE=../../../gem_source -mkdir -p ${GEM_SOURCE}/gems -cp -r $EXTERNAL_GIT_ROOT/input_artifacts/*.gem ${GEM_SOURCE}/gems +mkdir -p "${GEM_SOURCE}/gems" +cp "$EXTERNAL_GIT_ROOT"/input_artifacts/grpc-*"$ARCH-$PLATFORM".gem "${GEM_SOURCE}/gems" +# TODO: rewrite the following line to be shellcheck-compliant +# shellcheck disable=SC2010 +if [[ "$(ls "${GEM_SOURCE}/gems" | grep -c grpc)" != 1 ]]; then + echo "Sanity check failed. Copied over more than one grpc gem into the gem source directory." + exit 1 +fi; gem install builder -gem generate_index --directory ${GEM_SOURCE} +gem generate_index --directory "${GEM_SOURCE}" bundle install bundle exec ./distribtest.rb + +# Attempt to repro https://github.com/google/protobuf/issues/4210. +# TODO: This sanity check only works for linux-based distrib tests and for +# binary gRPC packages. It will need to be ran conditionally if this test script is +# used for other types of distrib tests. +INSTALLATION_DIR="$(gem env | grep '\- INSTALLATION DIRECTORY' | awk '{ print $4 }')" +if [[ "$(find "$INSTALLATION_DIR" -name 'grpc_c.so' | wc -l)" == 0 ]]; then + echo "Sanity check failed. The gRPC package is not installed in $INSTALLATION_DIR." + exit 1 +fi +LIBRUBY_DEPENDENCY_EXISTS="$(find "$INSTALLATION_DIR" -name 'grpc_c.so' -exec ldd {} \; | grep -c 'libruby')" || true +if [[ "$LIBRUBY_DEPENDENCY_EXISTS" != 0 ]]; then + echo "A grpc_c.so file in this binary gRPC package is dynamically linked to libruby." +fi +DEPENDENCY_NOT_FOUND="$(find "$INSTALLATION_DIR" -name 'grpc_c.so' -exec ldd {} \; | grep -c 'not found')" || true +if [[ "$DEPENDENCY_NOT_FOUND" != 0 ]]; then + echo "A grpc_c.so file in this binary gRPC package has an non-portable dependency." +fi +if [ "$LIBRUBY_DEPENDENCY_EXISTS" != 0 ] || [ "$DEPENDENCY_NOT_FOUND" != 0 ]; then + exit 1 +fi |