diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/core/backoff/BUILD | 7 | ||||
-rw-r--r-- | test/core/backoff/backoff_test.cc | 202 | ||||
-rw-r--r-- | test/core/iomgr/udp_server_test.cc | 60 | ||||
-rw-r--r-- | test/cpp/codegen/BUILD | 21 | ||||
-rw-r--r-- | test/cpp/codegen/golden_file_test.cc | 9 | ||||
-rwxr-xr-x | test/cpp/codegen/run_golden_file_test.sh | 19 | ||||
-rw-r--r-- | test/cpp/end2end/client_lb_end2end_test.cc | 115 | ||||
-rw-r--r-- | test/cpp/end2end/mock_test.cc | 2 | ||||
-rw-r--r-- | test/cpp/interop/interop_client.cc | 69 | ||||
-rw-r--r-- | test/cpp/interop/interop_client.h | 6 | ||||
-rwxr-xr-x | test/cpp/qps/gen_build_yaml.py | 40 |
11 files changed, 343 insertions, 207 deletions
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..7bc4d14ce6 100644 --- a/test/core/backoff/backoff_test.cc +++ b/test/core/backoff/backoff_test.cc @@ -18,137 +18,131 @@ #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.Begin(); + 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.Step(); + 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.Begin(); + 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.Begin(); + EXPECT_EQ(next, 2); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + EXPECT_EQ(next, 6); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + EXPECT_EQ(next, 14); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + EXPECT_EQ(next, 30); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + EXPECT_EQ(next, 62); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + EXPECT_EQ(next, 126); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + EXPECT_EQ(next, 254); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + EXPECT_EQ(next, 510); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + EXPECT_EQ(next, 1022); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); // 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.Step(); + EXPECT_EQ(next, 2048); + grpc_core::ExecCtx::Get()->TestOnlySetNow(next); + next = backoff.Step(); + 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 next = backoff.Begin(); + EXPECT_EQ(next - grpc_core::ExecCtx::Get()->Now(), initial_backoff); grpc_millis expected_next_lower_bound = (grpc_millis)((double)current_backoff * (1 - jitter)); @@ -156,33 +150,27 @@ static void test_jitter_backoff(void) { (grpc_millis)((double)current_backoff * (1 + jitter)); for (int i = 0; i < 10000; i++) { - next_deadlines = grpc_backoff_step(&backoff); + next = backoff.Step(); // 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( + 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( (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); } } +} // 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/iomgr/udp_server_test.cc b/test/core/iomgr/udp_server_test.cc index 0deb534abd..dc1248bc1c 100644 --- a/test/core/iomgr/udp_server_test.cc +++ b/test/core/iomgr/udp_server_test.cc @@ -49,8 +49,11 @@ 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) { +static void on_start(grpc_fd* emfd, void* user_data) { g_number_of_starts++; } + +static bool on_read(grpc_fd* emfd) { char read_buffer[512]; ssize_t byte_count; @@ -129,21 +132,41 @@ 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; @@ -154,16 +177,18 @@ static void test_no_op_with_port(void) { memset(&resolved_addr, 0, sizeof(resolved_addr)); resolved_addr.len = 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, on_start, on_read, + on_write, on_fd_orphaned)); 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); + 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; @@ -182,8 +207,8 @@ static void test_no_op_with_port_and_socket_factory(void) { memset(&resolved_addr, 0, sizeof(resolved_addr)); resolved_addr.len = 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, on_start, 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); @@ -193,9 +218,11 @@ static void test_no_op_with_port_and_socket_factory(void) { /* The server had a single FD, which should have been orphaned. */ GPR_ASSERT(g_number_of_orphan_calls == 1); + 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; @@ -206,19 +233,21 @@ static void test_no_op_with_port_and_start(void) { memset(&resolved_addr, 0, sizeof(resolved_addr)); resolved_addr.len = 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, on_start, on_read, + on_write, on_fd_orphaned)); grpc_udp_server_start(s, nullptr, 0, nullptr); - + GPR_ASSERT(g_number_of_starts == 1); 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); + 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; @@ -236,8 +265,8 @@ static void test_receive(int number_of_clients) { memset(&resolved_addr, 0, sizeof(resolved_addr)); resolved_addr.len = 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, on_start, on_read, + on_write, on_fd_orphaned)); svrfd = grpc_udp_server_get_fd(s, 0); GPR_ASSERT(svrfd >= 0); @@ -281,20 +310,15 @@ 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)); + shutdown_and_destroy_pollset(); } int main(int argc, char** argv) { - grpc_closure destroyed; grpc_test_init(argc, argv); grpc_init(); { 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 +328,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/cpp/codegen/BUILD b/test/cpp/codegen/BUILD index 6cc81e3398..1388dbc650 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,14 +55,10 @@ 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", @@ -73,3 +69,14 @@ grpc_cc_test( "gflags", ], ) + +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", + "//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen", + ], +) 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/run_golden_file_test.sh b/test/cpp/codegen/run_golden_file_test.sh new file mode 100755 index 0000000000..cdfaa96a1c --- /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 -ex + +GENERATED_FILES_PATH="$TEST_SRCDIR/../../../../../genfiles/src/proto/grpc/testing/" +test/cpp/codegen/golden_file_test --generated_file_path="$GENERATED_FILES_PATH" diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index e83a6e675e..c6e9577f0c 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -28,6 +28,7 @@ #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> @@ -35,6 +36,7 @@ #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/backoff/backoff.h" #include "src/core/lib/support/env.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" @@ -48,10 +50,33 @@ using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; using std::chrono::system_clock; +// 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); + +const auto original_tcp_connect_fn = grpc_tcp_client_connect_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)); + } + original_tcp_connect_fn(closure, ep, interested_parties, channel_args, addr, + deadline + delay_ms); +} + // Subclass of TestServiceImpl that increments a request counter for // every call to the Echo RPC. class MyTestServiceImpl : public TestServiceImpl { @@ -136,22 +161,22 @@ class ClientLbEnd2endTest : public ::testing::Test { grpc_lb_addresses_destroy(addresses); } - 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; + } + + void ResetStub(const std::vector<int>& ports, + 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); + CreateCustomChannel("fake:///", InsecureChannelCredentials(), args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } @@ -266,7 +291,7 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub(); // implicit pick first + ResetStub(GetServersPorts(), ""); // test that pick first is the default. std::vector<int> ports; for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); @@ -290,11 +315,63 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { 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); + ResetStub(ports, "pick_first", args); + 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 %ld 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()}; + ResetStub(ports, "pick_first", args); + 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); + grpc_tcp_client_connect_impl = tcp_client_connect_with_delay; + 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 %ld 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 + ResetStub(GetServersPorts(), "pick_first"); std::vector<int> ports; // Perform one RPC against the first server. @@ -340,7 +417,7 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub(); // implicit pick first + ResetStub(GetServersPorts(), "pick_first"); std::vector<int> ports; // Perform one RPC against the first server. @@ -370,7 +447,7 @@ TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub(); // implicit pick first + ResetStub(GetServersPorts(), "pick_first"); std::vector<int> ports; for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); @@ -392,7 +469,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub("round_robin"); + ResetStub(GetServersPorts(), "round_robin"); std::vector<int> ports; for (const auto& server : servers_) { ports.emplace_back(server->port_); @@ -423,7 +500,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub("round_robin"); + ResetStub(GetServersPorts(), "round_robin"); std::vector<int> ports; // Start with a single server. @@ -506,7 +583,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) { const int kNumServers = 3; StartServers(kNumServers); - ResetStub("round_robin"); + ResetStub(GetServersPorts(), "round_robin"); std::vector<int> ports; // Start with a single server. @@ -538,7 +615,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinManyUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - ResetStub("round_robin"); + ResetStub(GetServersPorts(), "round_robin"); std::vector<int> ports; for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); @@ -565,7 +642,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { ports.push_back(grpc_pick_unused_port_or_die()); } StartServers(kNumServers, ports); - ResetStub("round_robin"); + ResetStub(GetServersPorts(), "round_robin"); SetNextResolution(ports); // Send a number of RPCs, which succeed. for (size_t i = 0; i < 100; ++i) { diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index 61f4111e3b..175ecea2b3 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -43,7 +43,6 @@ #include <iostream> -using namespace std; using ::testing::AtLeast; using ::testing::DoAll; using ::testing::Invoke; @@ -57,6 +56,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/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index af97fe0940..d2192f5e70 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -122,7 +122,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 +132,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 +166,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 +196,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 +246,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 +274,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 +417,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 +456,7 @@ bool InteropClient::DoResponseStreaming() { } Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -516,7 +521,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 +583,7 @@ bool InteropClient::DoServerCompressedStreaming() { } Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } return true; @@ -619,7 +624,7 @@ bool InteropClient::DoResponseStreamingWithSlowConsumer() { } Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -666,7 +671,7 @@ bool InteropClient::DoHalfDuplex() { } Status s = stream->Finish(); - if (!AssertStatusOk(s)) { + if (!AssertStatusOk(s, context.debug_error_string())) { return false; } @@ -710,7 +715,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 +737,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 +796,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 +817,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 +840,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 +861,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); @@ -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", @@ -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..b8bb134c20 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.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/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index 1ef8f65b0b..bd40d0a5a2 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -101,24 +101,26 @@ print yaml.dump({ } for scenario_json in scenario_config.CXXLanguage().scenarios() if 'inproc' in scenario_json.get('CATEGORIES', []) - ] + [ - { - 'name': 'json_run_localhost', - 'shortname': 'json_run_localhost:%s_low_thread_count' % scenario_json['name'], - 'args': ['--scenarios_json', _scenario_json_string(scenario_json, True)], - 'ci_platforms': ['linux'], - 'platforms': ['linux'], - 'flaky': False, - 'language': 'c++', - 'boringssl': True, - 'defaults': 'boringssl', - 'cpu_cost': guess_cpu(scenario_json, True), - 'exclude_configs': sorted(c for c in configs_from_yaml if c not in ('tsan', 'asan')), - 'timeout_seconds': 10*60, - 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), - 'auto_timeout_scaling': False - } - for scenario_json in scenario_config.CXXLanguage().scenarios() - if 'scalable' in scenario_json.get('CATEGORIES', []) ] + # Disabled until https://github.com/grpc/grpc/issues/13122 is resolved. + # + [ + # { + # 'name': 'json_run_localhost', + # 'shortname': 'json_run_localhost:%s_low_thread_count' % scenario_json['name'], + # 'args': ['--scenarios_json', _scenario_json_string(scenario_json, True)], + # 'ci_platforms': ['linux'], + # 'platforms': ['linux'], + # 'flaky': False, + # 'language': 'c++', + # 'boringssl': True, + # 'defaults': 'boringssl', + # 'cpu_cost': guess_cpu(scenario_json, True), + # 'exclude_configs': sorted(c for c in configs_from_yaml if c not in ('tsan', 'asan')), + # 'timeout_seconds': 10*60, + # 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), + # 'auto_timeout_scaling': False + # } + # for scenario_json in scenario_config.CXXLanguage().scenarios() + # if 'scalable' in scenario_json.get('CATEGORIES', []) + # ] }) |