diff options
author | Muxi Yan <mxyan@google.com> | 2017-10-06 18:47:09 -0700 |
---|---|---|
committer | Muxi Yan <mxyan@google.com> | 2017-10-06 18:47:09 -0700 |
commit | 03fc857a6f3ad1ee0a6f46cd19b5c96e56c6fd3b (patch) | |
tree | 38e03428954c3abdf2c88cafa9ffbd205789976b /test | |
parent | 63602748415fb836afd7a9685fbe5e85bf5ebfed (diff) | |
parent | 03bd5daf5cd36373152cb6b06a5f259db1331e87 (diff) |
Merge remote-tracking branch 'upstream/master' into fix-stream-compression-config-interface
Diffstat (limited to 'test')
74 files changed, 2058 insertions, 698 deletions
diff --git a/test/core/backoff/BUILD b/test/core/backoff/BUILD new file mode 100644 index 0000000000..4ae762007c --- /dev/null +++ b/test/core/backoff/BUILD @@ -0,0 +1,36 @@ +# 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") + +licenses(["notice"]) # Apache v2 + +package( + features = [ + "-layering_check", + "-parse_headers", + ], +) + +grpc_cc_test( + name = "backoff_test", + srcs = ["backoff_test.c"], + language = "C", + deps = [ + "//:grpc", + "//test/core/util:grpc_test_util", + "//:gpr", + "//test/core/util:gpr_test_util", + ], +) diff --git a/test/core/backoff/backoff_test.c b/test/core/backoff/backoff_test.c new file mode 100644 index 0000000000..3848b2a54d --- /dev/null +++ b/test/core/backoff/backoff_test.c @@ -0,0 +1,149 @@ +/* + * + * 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 "src/core/lib/backoff/backoff.h" + +#include <grpc/support/log.h> + +#include "test/core/util/test_config.h" + +static void test_constant_backoff(void) { + grpc_backoff backoff; + grpc_backoff_init(&backoff, 200 /* initial timeout */, 1.0 /* multiplier */, + 0.0 /* jitter */, 100 /* min timeout */, + 1000 /* max timeout */); + + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_millis next = grpc_backoff_begin(&exec_ctx, &backoff); + GPR_ASSERT(next - grpc_exec_ctx_now(&exec_ctx) == 200); + for (int i = 0; i < 10000; i++) { + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next - grpc_exec_ctx_now(&exec_ctx) == 200); + exec_ctx.now = next; + } + grpc_exec_ctx_finish(&exec_ctx); +} + +static void test_min_connect(void) { + grpc_backoff backoff; + grpc_backoff_init(&backoff, 100 /* initial timeout */, 1.0 /* multiplier */, + 0.0 /* jitter */, 200 /* min timeout */, + 1000 /* max timeout */); + + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_millis next = grpc_backoff_begin(&exec_ctx, &backoff); + GPR_ASSERT(next - grpc_exec_ctx_now(&exec_ctx) == 200); + grpc_exec_ctx_finish(&exec_ctx); +} + +static void test_no_jitter_backoff(void) { + grpc_backoff backoff; + grpc_backoff_init(&backoff, 2 /* initial timeout */, 2.0 /* multiplier */, + 0.0 /* jitter */, 1 /* min timeout */, + 513 /* max timeout */); + // x_1 = 2 + // x_n = 2**i + x_{i-1} ( = 2**(n+1) - 2 ) + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + exec_ctx.now = 0; + exec_ctx.now_is_valid = true; + grpc_millis next = grpc_backoff_begin(&exec_ctx, &backoff); + GPR_ASSERT(next == 2); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 6); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 14); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 30); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 62); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 126); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 254); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 510); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 1022); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + // Hit the maximum timeout. From this point onwards, retries will increase + // only by max timeout. + GPR_ASSERT(next == 1535); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 2048); + exec_ctx.now = next; + next = grpc_backoff_step(&exec_ctx, &backoff); + GPR_ASSERT(next == 2561); + grpc_exec_ctx_finish(&exec_ctx); +} + +static void test_jitter_backoff(void) { + const int64_t initial_timeout = 500; + const double jitter = 0.1; + grpc_backoff backoff; + grpc_backoff_init(&backoff, initial_timeout, 1.0 /* multiplier */, jitter, + 100 /* min timeout */, 1000 /* max timeout */); + + backoff.rng_state = 0; // force consistent PRNG + + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_millis next = grpc_backoff_begin(&exec_ctx, &backoff); + GPR_ASSERT(next - grpc_exec_ctx_now(&exec_ctx) == 500); + + int64_t expected_next_lower_bound = + (int64_t)((double)initial_timeout * (1 - jitter)); + int64_t expected_next_upper_bound = + (int64_t)((double)initial_timeout * (1 + jitter)); + + for (int i = 0; i < 10000; i++) { + next = grpc_backoff_step(&exec_ctx, &backoff); + + // next-now must be within (jitter*100)% of the previous timeout. + const int64_t timeout_millis = next - grpc_exec_ctx_now(&exec_ctx); + GPR_ASSERT(timeout_millis >= expected_next_lower_bound); + GPR_ASSERT(timeout_millis <= expected_next_upper_bound); + + expected_next_lower_bound = + (int64_t)((double)timeout_millis * (1 - jitter)); + expected_next_upper_bound = + (int64_t)((double)timeout_millis * (1 + jitter)); + exec_ctx.now = next; + } + grpc_exec_ctx_finish(&exec_ctx); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + gpr_time_init(); + + test_constant_backoff(); + test_min_connect(); + test_no_jitter_backoff(); + test_jitter_backoff(); + + return 0; +} diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c index 383d1240cb..b7b28a9ac4 100644 --- a/test/core/bad_client/bad_client.c +++ b/test/core/bad_client/bad_client.c @@ -84,13 +84,18 @@ void grpc_run_bad_client_test( grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_completion_queue *shutdown_cq; - hex = gpr_dump(client_payload, client_payload_length, - GPR_DUMP_HEX | GPR_DUMP_ASCII); + if (client_payload_length < 4 * 1024) { + hex = gpr_dump(client_payload, client_payload_length, + GPR_DUMP_HEX | GPR_DUMP_ASCII); - /* Add a debug log */ - gpr_log(GPR_INFO, "TEST: %s", hex); + /* Add a debug log */ + gpr_log(GPR_INFO, "TEST: %s", hex); - gpr_free(hex); + gpr_free(hex); + } else { + gpr_log(GPR_INFO, "TEST: (%" PRIdPTR " byte long string)", + client_payload_length); + } /* Init grpc */ grpc_init(); @@ -134,9 +139,12 @@ void grpc_run_bad_client_test( grpc_endpoint_write(&exec_ctx, sfd.client, &outgoing, &done_write_closure); grpc_exec_ctx_finish(&exec_ctx); - /* Await completion */ - GPR_ASSERT( - gpr_event_wait(&a.done_write, grpc_timeout_seconds_to_deadline(5))); + /* 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))); + } if (flags & GRPC_BAD_CLIENT_DISCONNECT) { grpc_endpoint_shutdown( @@ -186,6 +194,8 @@ void grpc_run_bad_client_test( grpc_exec_ctx_finish(&exec_ctx); } + GPR_ASSERT( + gpr_event_wait(&a.done_write, grpc_timeout_seconds_to_deadline(1))); shutdown_cq = grpc_completion_queue_create_for_pluck(NULL); grpc_server_shutdown_and_notify(a.server, shutdown_cq, NULL); GPR_ASSERT(grpc_completion_queue_pluck( diff --git a/test/core/bad_client/bad_client.h b/test/core/bad_client/bad_client.h index 22f1a3abc7..a5b01f7f2c 100644 --- a/test/core/bad_client/bad_client.h +++ b/test/core/bad_client/bad_client.h @@ -37,6 +37,7 @@ typedef bool (*grpc_bad_client_client_stream_validator)( grpc_slice_buffer *incoming); #define GRPC_BAD_CLIENT_DISCONNECT 1 +#define GRPC_BAD_CLIENT_LARGE_REQUEST 2 /* Test runner. diff --git a/test/core/bad_client/tests/window_overflow.c b/test/core/bad_client/tests/window_overflow.c index 1f29bd32fb..e4b5f9711b 100644 --- a/test/core/bad_client/tests/window_overflow.c +++ b/test/core/bad_client/tests/window_overflow.c @@ -69,7 +69,7 @@ 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 (100 * 1024) +#define SEND_SIZE (6 * 1024 * 1024) #define NUM_FRAMES (SEND_SIZE / FRAME_SIZE + 1) grpc_test_init(argc, argv); @@ -90,7 +90,8 @@ int main(int argc, char **argv) { addbuf(message, sizeof(message)); } } - grpc_run_bad_client_test(verifier, NULL, g_buffer, g_count, 0); + grpc_run_bad_client_test(verifier, NULL, g_buffer, g_count, + GRPC_BAD_CLIENT_LARGE_REQUEST); gpr_free(g_buffer); return 0; diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index 7c3614b4a2..a07ef89ba8 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -125,7 +125,7 @@ static void test_create_channel_stack(void) { .context = NULL, .path = path, .start_time = gpr_now(GPR_CLOCK_MONOTONIC), - .deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC), + .deadline = GRPC_MILLIS_INF_FUTURE, .arena = NULL}; grpc_error *error = grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack, &args); diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c index 364e180963..4597285063 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c @@ -106,7 +106,7 @@ static bool wait_loop(int deadline_seconds, gpr_event *ev) { deadline_seconds--; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_timer_check(&exec_ctx, gpr_now(GPR_CLOCK_MONOTONIC), NULL); + grpc_timer_check(&exec_ctx, NULL); grpc_exec_ctx_finish(&exec_ctx); } return false; diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c index 9b1ddadfe4..f0a2ee5430 100644 --- a/test/core/end2end/fixtures/h2_ssl_cert.c +++ b/test/core/end2end/fixtures/h2_ssl_cert.c @@ -319,7 +319,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, 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 = NULL; op++; error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); diff --git a/test/core/end2end/fixtures/http_proxy_fixture.c b/test/core/end2end/fixtures/http_proxy_fixture.c index a4cfc77bcb..d29401fdc3 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.c +++ b/test/core/end2end/fixtures/http_proxy_fixture.c @@ -412,8 +412,8 @@ static void on_read_request_done(grpc_exec_ctx* exec_ctx, void* arg, GPR_ASSERT(resolved_addresses->naddrs >= 1); // Connect to requested address. // The connection callback inherits our reference to conn. - const gpr_timespec deadline = gpr_time_add( - gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(10, GPR_TIMESPAN)); + const grpc_millis deadline = + grpc_exec_ctx_now(exec_ctx) + 10 * GPR_MS_PER_SEC; grpc_tcp_client_connect(exec_ctx, &conn->on_server_connect_done, &conn->server_endpoint, conn->pollset_set, NULL, &resolved_addresses->addrs[0], deadline); @@ -469,14 +469,12 @@ static void thread_main(void* arg) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; do { gpr_ref(&proxy->users); - const gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); - const gpr_timespec deadline = - gpr_time_add(now, gpr_time_from_seconds(1, GPR_TIMESPAN)); grpc_pollset_worker* worker = NULL; gpr_mu_lock(proxy->mu); GRPC_LOG_IF_ERROR( "grpc_pollset_work", - grpc_pollset_work(&exec_ctx, proxy->pollset, &worker, now, deadline)); + grpc_pollset_work(&exec_ctx, proxy->pollset, &worker, + grpc_exec_ctx_now(&exec_ctx) + GPR_MS_PER_SEC)); gpr_mu_unlock(proxy->mu); grpc_exec_ctx_flush(&exec_ctx); } while (!gpr_unref(&proxy->users)); diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c index 1228c9fe9a..0a787bbf30 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.c +++ b/test/core/end2end/fuzzers/api_fuzzer.c @@ -60,7 +60,9 @@ extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); static gpr_timespec now_impl(gpr_clock_type clock_type) { GPR_ASSERT(clock_type != GPR_TIMESPAN); - return g_now; + gpr_timespec ts = g_now; + ts.clock_type = clock_type; + return ts; } //////////////////////////////////////////////////////////////////////////////// @@ -407,10 +409,8 @@ void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr, r->addrs = addresses; r->lb_addrs = NULL; grpc_timer_init( - exec_ctx, &r->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(1, GPR_TIMESPAN)), - GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx), - gpr_now(GPR_CLOCK_MONOTONIC)); + exec_ctx, &r->timer, GPR_MS_PER_SEC + grpc_exec_ctx_now(exec_ctx), + GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); } grpc_ares_request *my_dns_lookup_ares( @@ -424,10 +424,8 @@ grpc_ares_request *my_dns_lookup_ares( r->addrs = NULL; r->lb_addrs = lb_addrs; grpc_timer_init( - exec_ctx, &r->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(1, GPR_TIMESPAN)), - GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx), - gpr_now(GPR_CLOCK_MONOTONIC)); + exec_ctx, &r->timer, GPR_MS_PER_SEC + grpc_exec_ctx_now(exec_ctx), + GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); return NULL; } @@ -487,10 +485,8 @@ static void sched_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure, fc->ep = ep; fc->deadline = deadline; grpc_timer_init( - exec_ctx, &fc->timer, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(1, GPR_TIMESPAN)), - GRPC_CLOSURE_CREATE(do_connect, fc, grpc_schedule_on_exec_ctx), - gpr_now(GPR_CLOCK_MONOTONIC)); + exec_ctx, &fc->timer, GPR_MS_PER_SEC + grpc_exec_ctx_now(exec_ctx), + GRPC_CLOSURE_CREATE(do_connect, fc, grpc_schedule_on_exec_ctx)); } static void my_tcp_client_connect(grpc_exec_ctx *exec_ctx, diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c index bf0d08adec..e3fd5a8fbe 100644 --- a/test/core/end2end/invalid_call_argument_test.c +++ b/test/core/end2end/invalid_call_argument_test.c @@ -92,7 +92,7 @@ static void prepare_test(int is_client) { op = g_state.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 = NULL; op++; GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops, diff --git a/test/core/end2end/tests/bad_ping.c b/test/core/end2end/tests/bad_ping.c index c97d11b306..d442f12480 100644 --- a/test/core/end2end/tests/bad_ping.c +++ b/test/core/end2end/tests/bad_ping.c @@ -155,14 +155,16 @@ static void test_bad_ping(grpc_end2end_test_config config) { cq_verify(cqv); // Send too many pings to the server to trigger the punishment: - // The first ping is sent after data frames, it won't trigger a ping strike. - // Each of the following pings will trigger a ping strike, and we need at - // least (MAX_PING_STRIKES + 1) strikes to trigger the punishment. So - // (MAX_PING_STRIKES + 2) pings are needed here. + // 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 + // needed here. int i; - for (i = 200; i < 202 + MAX_PING_STRIKES; i++) { - grpc_channel_ping(f.client, f.cq, tag(i), NULL); - CQ_EXPECT_COMPLETION(cqv, tag(i), 1); + for (i = 1; i <= MAX_PING_STRIKES + 1; i++) { + grpc_channel_ping(f.client, f.cq, tag(200 + i), NULL); + CQ_EXPECT_COMPLETION(cqv, tag(200 + i), 1); + if (i == MAX_PING_STRIKES + 1) { + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + } cq_verify(cqv); } @@ -190,7 +192,6 @@ static void test_bad_ping(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); - CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead)); diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c index 58f46a606c..4263eb1363 100644 --- a/test/core/end2end/tests/compressed_payload.c +++ b/test/core/end2end/tests/compressed_payload.c @@ -193,6 +193,7 @@ static void request_for_disabled_algorithm( GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(101), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); cq_verify(cqv); op = ops; @@ -221,7 +222,6 @@ static void request_for_disabled_algorithm( GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), true); - CQ_EXPECT_COMPLETION(cqv, tag(1), true); cq_verify(cqv); /* call was cancelled (closed) ... */ diff --git a/test/core/end2end/tests/keepalive_timeout.c b/test/core/end2end/tests/keepalive_timeout.c index 8d01f23c00..c4280149c7 100644 --- a/test/core/end2end/tests/keepalive_timeout.c +++ b/test/core/end2end/tests/keepalive_timeout.c @@ -98,21 +98,21 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { grpc_byte_buffer *response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); - grpc_arg keepalive_args[] = {{.type = GRPC_ARG_INTEGER, - .key = GRPC_ARG_KEEPALIVE_TIME_MS, - .value.integer = 1500}, - {.type = GRPC_ARG_INTEGER, - .key = GRPC_ARG_KEEPALIVE_TIMEOUT_MS, - .value.integer = 0}, - {.type = GRPC_ARG_INTEGER, - .key = GRPC_ARG_HTTP2_BDP_PROBE, - .value.integer = 0}}; - - grpc_channel_args client_args = {.num_args = GPR_ARRAY_SIZE(keepalive_args), - .args = keepalive_args}; + grpc_arg keepalive_arg_elems[] = {{.type = GRPC_ARG_INTEGER, + .key = GRPC_ARG_KEEPALIVE_TIME_MS, + .value.integer = 1500}, + {.type = GRPC_ARG_INTEGER, + .key = GRPC_ARG_KEEPALIVE_TIMEOUT_MS, + .value.integer = 0}, + {.type = GRPC_ARG_INTEGER, + .key = GRPC_ARG_HTTP2_BDP_PROBE, + .value.integer = 0}}; + grpc_channel_args keepalive_args = { + .num_args = GPR_ARRAY_SIZE(keepalive_arg_elems), + .args = keepalive_arg_elems}; grpc_end2end_test_fixture f = - begin_test(config, "keepalive_timeout", &client_args, NULL); + begin_test(config, "keepalive_timeout", &keepalive_args, NULL); cq_verifier *cqv = cq_verifier_create(f.cq); grpc_op ops[6]; grpc_op *op; diff --git a/test/core/end2end/tests/stream_compression_compressed_payload.c b/test/core/end2end/tests/stream_compression_compressed_payload.c index c4cf97e416..eb31a80302 100644 --- a/test/core/end2end/tests/stream_compression_compressed_payload.c +++ b/test/core/end2end/tests/stream_compression_compressed_payload.c @@ -193,6 +193,7 @@ static void request_for_disabled_algorithm( GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(101), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); cq_verify(cqv); op = ops; @@ -221,7 +222,6 @@ static void request_for_disabled_algorithm( GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(103), true); - CQ_EXPECT_COMPLETION(cqv, tag(1), true); cq_verify(cqv); /* call was cancelled (closed) ... */ diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c index 8a53903763..cc1c16d695 100644 --- a/test/core/http/httpcli_test.c +++ b/test/core/http/httpcli_test.c @@ -35,8 +35,9 @@ static grpc_httpcli_context g_context; static gpr_mu *g_mu; static grpc_polling_entity g_pops; -static gpr_timespec n_seconds_time(int seconds) { - return grpc_timeout_seconds_to_deadline(seconds); +static grpc_millis n_seconds_time(int seconds) { + return grpc_timespec_to_millis_round_up( + grpc_timeout_seconds_to_deadline(seconds)); } static void on_finish(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -86,8 +87,7 @@ static void test_get(int port) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops), - &worker, gpr_now(GPR_CLOCK_MONOTONIC), - n_seconds_time(1)))); + &worker, n_seconds_time(1)))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -128,8 +128,7 @@ static void test_post(int port) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops), - &worker, gpr_now(GPR_CLOCK_MONOTONIC), - n_seconds_time(1)))); + &worker, n_seconds_time(1)))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c index c7455bd8df..f8a3cfdd76 100644 --- a/test/core/http/httpscli_test.c +++ b/test/core/http/httpscli_test.c @@ -35,8 +35,9 @@ static grpc_httpcli_context g_context; static gpr_mu *g_mu; static grpc_polling_entity g_pops; -static gpr_timespec n_seconds_time(int seconds) { - return grpc_timeout_seconds_to_deadline(seconds); +static grpc_millis n_seconds_time(int seconds) { + return grpc_timespec_to_millis_round_up( + grpc_timeout_seconds_to_deadline(seconds)); } static void on_finish(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -87,8 +88,7 @@ static void test_get(int port) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops), - &worker, gpr_now(GPR_CLOCK_MONOTONIC), - n_seconds_time(1)))); + &worker, n_seconds_time(1)))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -130,8 +130,7 @@ static void test_post(int port) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops), - &worker, gpr_now(GPR_CLOCK_MONOTONIC), - n_seconds_time(1)))); + &worker, n_seconds_time(1)))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c index f8570edde7..61e901f645 100644 --- a/test/core/iomgr/endpoint_tests.c +++ b/test/core/iomgr/endpoint_tests.c @@ -176,10 +176,11 @@ static void read_and_write_test(grpc_endpoint_test_config config, size_t num_bytes, size_t write_size, size_t slice_size, bool shutdown) { struct read_and_write_test_state state; - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(20); grpc_endpoint_test_fixture f = begin_test(config, "read_and_write_test", slice_size); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_millis deadline = + grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(20)); gpr_log(GPR_DEBUG, "num_bytes=%" PRIuPTR " write_size=%" PRIuPTR " slice_size=%" PRIuPTR " shutdown=%d", num_bytes, write_size, slice_size, shutdown); @@ -235,11 +236,10 @@ static void read_and_write_test(grpc_endpoint_test_config config, gpr_mu_lock(g_mu); while (!state.read_done || !state.write_done) { grpc_pollset_worker *worker = NULL; - GPR_ASSERT(gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), deadline) < 0); + GPR_ASSERT(grpc_exec_ctx_now(&exec_ctx) < deadline); GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline))); + grpc_pollset_work(&exec_ctx, g_pollset, &worker, deadline))); } gpr_mu_unlock(g_mu); grpc_exec_ctx_flush(&exec_ctx); @@ -265,14 +265,14 @@ static void wait_for_fail_count(grpc_exec_ctx *exec_ctx, int *fail_count, int want_fail_count) { grpc_exec_ctx_flush(exec_ctx); gpr_mu_lock(g_mu); - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10); - while (gpr_time_cmp(gpr_now(deadline.clock_type), deadline) < 0 && + grpc_millis deadline = + grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(10)); + while (grpc_exec_ctx_now(exec_ctx) < deadline && *fail_count < want_fail_count) { grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", - grpc_pollset_work(exec_ctx, g_pollset, &worker, - gpr_now(deadline.clock_type), deadline))); + grpc_pollset_work(exec_ctx, g_pollset, &worker, deadline))); gpr_mu_unlock(g_mu); grpc_exec_ctx_flush(exec_ctx); gpr_mu_lock(g_mu); diff --git a/test/core/iomgr/ev_epollsig_linux_test.c b/test/core/iomgr/ev_epollsig_linux_test.c index cca07bf002..37aadacd49 100644 --- a/test/core/iomgr/ev_epollsig_linux_test.c +++ b/test/core/iomgr/ev_epollsig_linux_test.c @@ -238,10 +238,8 @@ static void test_threading_loop(void *arg) { grpc_pollset_worker *worker; gpr_mu_lock(shared->mu); GPR_ASSERT(GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, shared->pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)))); + "pollset_work", grpc_pollset_work(&exec_ctx, shared->pollset, &worker, + GRPC_MILLIS_INF_FUTURE))); gpr_mu_unlock(shared->mu); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c index 881277a8d6..1c62f34d3e 100644 --- a/test/core/iomgr/fd_posix_test.c +++ b/test/core/iomgr/fd_posix_test.c @@ -252,10 +252,8 @@ static void server_wait_and_shutdown(server *sv) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)))); + "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, + GRPC_MILLIS_INF_FUTURE))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -371,10 +369,8 @@ static void client_wait_and_shutdown(client *cl) { grpc_pollset_worker *worker = NULL; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GPR_ASSERT(GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)))); + "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, + GRPC_MILLIS_INF_FUTURE))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -477,10 +473,8 @@ static void test_grpc_fd_change(void) { while (a.cb_that_ran == NULL) { grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)))); + "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, + GRPC_MILLIS_INF_FUTURE))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -503,10 +497,8 @@ static void test_grpc_fd_change(void) { while (b.cb_that_ran == NULL) { grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)))); + "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, + GRPC_MILLIS_INF_FUTURE))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); diff --git a/test/core/iomgr/pollset_set_test.c b/test/core/iomgr/pollset_set_test.c index 70efca8b16..3dd4bc887c 100644 --- a/test/core/iomgr/pollset_set_test.c +++ b/test/core/iomgr/pollset_set_test.c @@ -24,7 +24,6 @@ #include <string.h> #include <unistd.h> -#include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/useful.h> @@ -204,7 +203,7 @@ static void pollset_set_test_basic() { */ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_pollset_worker *worker; - gpr_timespec deadline; + grpc_millis deadline; test_fd tfds[10]; test_pollset pollsets[3]; @@ -257,10 +256,10 @@ static void pollset_set_test_basic() { make_test_fds_readable(tfds, num_fds); gpr_mu_lock(pollsets[i].mu); - deadline = grpc_timeout_milliseconds_to_deadline(2); + deadline = grpc_timespec_to_millis_round_up( + grpc_timeout_milliseconds_to_deadline(2)); GPR_ASSERT(GRPC_ERROR_NONE == - grpc_pollset_work(&exec_ctx, pollsets[i].ps, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline)); + grpc_pollset_work(&exec_ctx, pollsets[i].ps, &worker, deadline)); gpr_mu_unlock(pollsets[i].mu); grpc_exec_ctx_flush(&exec_ctx); @@ -309,7 +308,7 @@ void pollset_set_test_dup_fds() { */ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_pollset_worker *worker; - gpr_timespec deadline; + grpc_millis deadline; test_fd tfds[3]; test_pollset pollset; @@ -339,10 +338,10 @@ void pollset_set_test_dup_fds() { make_test_fds_readable(tfds, num_fds); gpr_mu_lock(pollset.mu); - deadline = grpc_timeout_milliseconds_to_deadline(2); + deadline = grpc_timespec_to_millis_round_up( + grpc_timeout_milliseconds_to_deadline(2)); GPR_ASSERT(GRPC_ERROR_NONE == - grpc_pollset_work(&exec_ctx, pollset.ps, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline)); + grpc_pollset_work(&exec_ctx, pollset.ps, &worker, deadline)); gpr_mu_unlock(pollset.mu); grpc_exec_ctx_flush(&exec_ctx); @@ -382,7 +381,7 @@ void pollset_set_test_empty_pollset() { */ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_pollset_worker *worker; - gpr_timespec deadline; + grpc_millis deadline; test_fd tfds[3]; test_pollset pollsets[2]; @@ -408,10 +407,10 @@ void pollset_set_test_empty_pollset() { make_test_fds_readable(tfds, num_fds); gpr_mu_lock(pollsets[0].mu); - deadline = grpc_timeout_milliseconds_to_deadline(2); + deadline = grpc_timespec_to_millis_round_up( + grpc_timeout_milliseconds_to_deadline(2)); GPR_ASSERT(GRPC_ERROR_NONE == - grpc_pollset_work(&exec_ctx, pollsets[0].ps, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline)); + grpc_pollset_work(&exec_ctx, pollsets[0].ps, &worker, deadline)); gpr_mu_unlock(pollsets[0].mu); grpc_exec_ctx_flush(&exec_ctx); @@ -434,7 +433,8 @@ int main(int argc, char **argv) { const char *poll_strategy = grpc_get_poll_strategy_name(); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_test_init(argc, argv); - grpc_init(); + grpc_iomgr_init(&exec_ctx); + grpc_iomgr_start(&exec_ctx); if (poll_strategy != NULL && (strcmp(poll_strategy, "epoll") == 0 || @@ -449,8 +449,8 @@ int main(int argc, char **argv) { poll_strategy); } + grpc_iomgr_shutdown(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx); - grpc_shutdown(); return 0; } #else /* defined(GRPC_LINUX_EPOLL) */ diff --git a/test/core/iomgr/resolve_address_posix_test.c b/test/core/iomgr/resolve_address_posix_test.c index e4be99f03c..cb9d6080fb 100644 --- a/test/core/iomgr/resolve_address_posix_test.c +++ b/test/core/iomgr/resolve_address_posix_test.c @@ -72,35 +72,33 @@ void args_finish(grpc_exec_ctx *exec_ctx, args_struct *args) { gpr_free(args->pollset); } -static gpr_timespec n_sec_deadline(int seconds) { - return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(seconds, GPR_TIMESPAN)); +static grpc_millis n_sec_deadline(int seconds) { + return grpc_timespec_to_millis_round_up( + grpc_timeout_seconds_to_deadline(seconds)); } static void actually_poll(void *argsp) { args_struct *args = argsp; - gpr_timespec deadline = n_sec_deadline(10); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_millis deadline = n_sec_deadline(10); while (true) { bool done = gpr_atm_acq_load(&args->done_atm) != 0; if (done) { break; } - gpr_timespec time_left = - gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME)); - gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done, - time_left.tv_sec, time_left.tv_nsec); - GPR_ASSERT(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) >= 0); + grpc_millis time_left = deadline - grpc_exec_ctx_now(&exec_ctx); + gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRIdPTR, done, time_left); + GPR_ASSERT(time_left >= 0); grpc_pollset_worker *worker = NULL; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, args->pollset, &worker, - gpr_now(GPR_CLOCK_REALTIME), n_sec_deadline(1))); + GRPC_LOG_IF_ERROR("pollset_work", + grpc_pollset_work(&exec_ctx, args->pollset, &worker, + n_sec_deadline(1))); gpr_mu_unlock(args->mu); - grpc_exec_ctx_finish(&exec_ctx); + grpc_exec_ctx_flush(&exec_ctx); } gpr_event_set(&args->ev, (void *)1); + grpc_exec_ctx_finish(&exec_ctx); } static void poll_pollset_until_request_done(args_struct *args) { diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c index 1110c04b6e..178bbbb95f 100644 --- a/test/core/iomgr/resolve_address_test.c +++ b/test/core/iomgr/resolve_address_test.c @@ -68,34 +68,32 @@ void args_finish(grpc_exec_ctx *exec_ctx, args_struct *args) { gpr_free(args->pollset); } -static gpr_timespec n_sec_deadline(int seconds) { - return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(seconds, GPR_TIMESPAN)); +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(args_struct *args) { - gpr_timespec deadline = n_sec_deadline(10); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_millis deadline = n_sec_deadline(10); while (true) { bool done = gpr_atm_acq_load(&args->done_atm) != 0; if (done) { break; } - gpr_timespec time_left = - gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME)); - gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done, - time_left.tv_sec, time_left.tv_nsec); - GPR_ASSERT(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) >= 0); + grpc_millis time_left = deadline - grpc_exec_ctx_now(&exec_ctx); + gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRIdPTR, done, time_left); + GPR_ASSERT(time_left >= 0); grpc_pollset_worker *worker = NULL; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, args->pollset, &worker, - gpr_now(GPR_CLOCK_REALTIME), n_sec_deadline(1))); + GRPC_LOG_IF_ERROR("pollset_work", + grpc_pollset_work(&exec_ctx, args->pollset, &worker, + n_sec_deadline(1))); gpr_mu_unlock(args->mu); - grpc_exec_ctx_finish(&exec_ctx); + grpc_exec_ctx_flush(&exec_ctx); } gpr_event_set(&args->ev, (void *)1); + grpc_exec_ctx_finish(&exec_ctx); } static void must_succeed(grpc_exec_ctx *exec_ctx, void *argsp, diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c index 1032da942b..b8b76d1c42 100644 --- a/test/core/iomgr/tcp_client_posix_test.c +++ b/test/core/iomgr/tcp_client_posix_test.c @@ -46,8 +46,8 @@ static grpc_pollset *g_pollset; static int g_connections_complete = 0; static grpc_endpoint *g_connecting = NULL; -static gpr_timespec test_deadline(void) { - return grpc_timeout_seconds_to_deadline(10); +static grpc_millis test_deadline(void) { + return grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(10)); } static void finish_connection() { @@ -109,7 +109,7 @@ void test_succeeds(void) { (socklen_t *)&resolved_addr.len) == 0); GRPC_CLOSURE_INIT(&done, must_succeed, NULL, grpc_schedule_on_exec_ctx); grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set, NULL, - &resolved_addr, gpr_inf_future(GPR_CLOCK_REALTIME)); + &resolved_addr, GRPC_MILLIS_INF_FUTURE); /* await the connection */ do { @@ -127,8 +127,8 @@ void test_succeeds(void) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - grpc_timeout_seconds_to_deadline(5)))); + grpc_timespec_to_millis_round_up( + grpc_timeout_seconds_to_deadline(5))))); gpr_mu_unlock(g_mu); grpc_exec_ctx_flush(&exec_ctx); gpr_mu_lock(g_mu); @@ -159,25 +159,24 @@ void test_fails(void) { /* connect to a broken address */ GRPC_CLOSURE_INIT(&done, must_fail, NULL, grpc_schedule_on_exec_ctx); grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set, NULL, - &resolved_addr, gpr_inf_future(GPR_CLOCK_REALTIME)); + &resolved_addr, GRPC_MILLIS_INF_FUTURE); gpr_mu_lock(g_mu); /* wait for the connection callback to finish */ while (g_connections_complete == connections_complete_before) { grpc_pollset_worker *worker = NULL; - gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); - gpr_timespec polling_deadline = test_deadline(); - switch (grpc_timer_check(&exec_ctx, now, &polling_deadline)) { + grpc_millis polling_deadline = test_deadline(); + switch (grpc_timer_check(&exec_ctx, &polling_deadline)) { case GRPC_TIMERS_FIRED: break; case GRPC_TIMERS_NOT_CHECKED: - polling_deadline = now; + polling_deadline = 0; /* fall through */ case GRPC_TIMERS_CHECKED_AND_EMPTY: GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, - now, polling_deadline))); + polling_deadline))); break; } gpr_mu_unlock(g_mu); diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c index cfb3cf897c..6501160c6f 100644 --- a/test/core/iomgr/tcp_posix_test.c +++ b/test/core/iomgr/tcp_posix_test.c @@ -162,7 +162,8 @@ static void read_test(size_t num_bytes, size_t slice_size) { grpc_endpoint *ep; struct read_socket_state state; size_t written_bytes; - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(20); + grpc_millis deadline = + grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(20)); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_log(GPR_INFO, "Read test of size %" PRIuPTR ", slice size %" PRIuPTR, @@ -194,8 +195,7 @@ static void read_test(size_t num_bytes, size_t slice_size) { grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline))); + grpc_pollset_work(&exec_ctx, g_pollset, &worker, deadline))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -215,7 +215,8 @@ static void large_read_test(size_t slice_size) { grpc_endpoint *ep; struct read_socket_state state; ssize_t written_bytes; - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(20); + grpc_millis deadline = + grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(20)); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_log(GPR_INFO, "Start large read test, slice size %" PRIuPTR, slice_size); @@ -246,8 +247,7 @@ static void large_read_test(size_t slice_size) { grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline))); + grpc_pollset_work(&exec_ctx, g_pollset, &worker, deadline))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -319,8 +319,8 @@ void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - grpc_timeout_milliseconds_to_deadline(10)))); + grpc_timespec_to_millis_round_up( + grpc_timeout_milliseconds_to_deadline(10))))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); do { @@ -353,7 +353,8 @@ static void write_test(size_t num_bytes, size_t slice_size) { uint8_t current_data = 0; grpc_slice_buffer outgoing; grpc_closure write_done_closure; - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(20); + grpc_millis deadline = + grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(20)); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_log(GPR_INFO, @@ -390,8 +391,7 @@ static void write_test(size_t num_bytes, size_t slice_size) { } GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline))); + grpc_pollset_work(&exec_ctx, g_pollset, &worker, deadline))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -419,7 +419,8 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { struct read_socket_state state; size_t written_bytes; int fd; - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(20); + grpc_millis deadline = + grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(20)); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_closure fd_released_cb; int fd_released_done = 0; @@ -457,8 +458,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline))); + grpc_pollset_work(&exec_ctx, g_pollset, &worker, deadline))); gpr_log(GPR_DEBUG, "wakeup: read=%" PRIdPTR " target=%" PRIdPTR, state.read_bytes, state.target_read_bytes); gpr_mu_unlock(g_mu); @@ -476,8 +476,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline))); + grpc_pollset_work(&exec_ctx, g_pollset, &worker, deadline))); gpr_log(GPR_DEBUG, "wakeup: fd_released_done=%d", fd_released_done); } gpr_mu_unlock(g_mu); diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c index 4d84608376..782dfb413a 100644 --- a/test/core/iomgr/tcp_server_posix_test.c +++ b/test/core/iomgr/tcp_server_posix_test.c @@ -230,7 +230,8 @@ static void test_no_op_with_port_and_start(void) { static grpc_error *tcp_connect(grpc_exec_ctx *exec_ctx, const test_addr *remote, on_connect_result *result) { - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10); + grpc_millis deadline = + grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(10)); int clifd; int nconnects_before; const struct sockaddr *remote_addr = @@ -253,11 +254,10 @@ static grpc_error *tcp_connect(grpc_exec_ctx *exec_ctx, const test_addr *remote, } gpr_log(GPR_DEBUG, "wait"); while (g_nconnects == nconnects_before && - gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) { + deadline > grpc_exec_ctx_now(exec_ctx)) { grpc_pollset_worker *worker = NULL; grpc_error *err; - if ((err = grpc_pollset_work(exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline)) != + if ((err = grpc_pollset_work(exec_ctx, g_pollset, &worker, deadline)) != GRPC_ERROR_NONE) { gpr_mu_unlock(g_mu); close(clifd); diff --git a/test/core/iomgr/timer_list_test.c b/test/core/iomgr/timer_list_test.c index 5f8b01fdc4..c3d9f9d88d 100644 --- a/test/core/iomgr/timer_list_test.c +++ b/test/core/iomgr/timer_list_test.c @@ -41,51 +41,45 @@ static void cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { } static void add_test(void) { - gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME); int i; grpc_timer timers[20]; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_log(GPR_INFO, "add_test"); - grpc_timer_list_init(start); + grpc_timer_list_init(&exec_ctx); grpc_timer_trace.value = 1; grpc_timer_check_trace.value = 1; memset(cb_called, 0, sizeof(cb_called)); + grpc_millis start = grpc_exec_ctx_now(&exec_ctx); + /* 10 ms timers. will expire in the current epoch */ for (i = 0; i < 10; i++) { - grpc_timer_init( - &exec_ctx, &timers[i], - gpr_time_add(start, gpr_time_from_millis(10, GPR_TIMESPAN)), - GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)i, grpc_schedule_on_exec_ctx), - start); + grpc_timer_init(&exec_ctx, &timers[i], start + 10, + GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)i, + grpc_schedule_on_exec_ctx)); } /* 1010 ms timers. will expire in the next epoch */ for (i = 10; i < 20; i++) { - grpc_timer_init( - &exec_ctx, &timers[i], - gpr_time_add(start, gpr_time_from_millis(1010, GPR_TIMESPAN)), - GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)i, grpc_schedule_on_exec_ctx), - start); + grpc_timer_init(&exec_ctx, &timers[i], start + 1010, + GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)i, + grpc_schedule_on_exec_ctx)); } /* collect timers. Only the first batch should be ready. */ - GPR_ASSERT(grpc_timer_check( - &exec_ctx, - gpr_time_add(start, gpr_time_from_millis(500, GPR_TIMESPAN)), - NULL) == GRPC_TIMERS_FIRED); + exec_ctx.now = start + 500; + GPR_ASSERT(grpc_timer_check(&exec_ctx, NULL) == GRPC_TIMERS_FIRED); grpc_exec_ctx_finish(&exec_ctx); for (i = 0; i < 20; i++) { GPR_ASSERT(cb_called[i][1] == (i < 10)); GPR_ASSERT(cb_called[i][0] == 0); } - GPR_ASSERT(grpc_timer_check( - &exec_ctx, - gpr_time_add(start, gpr_time_from_millis(600, GPR_TIMESPAN)), - NULL) == GRPC_TIMERS_CHECKED_AND_EMPTY); + exec_ctx.now = start + 600; + GPR_ASSERT(grpc_timer_check(&exec_ctx, NULL) == + GRPC_TIMERS_CHECKED_AND_EMPTY); grpc_exec_ctx_finish(&exec_ctx); for (i = 0; i < 30; i++) { GPR_ASSERT(cb_called[i][1] == (i < 10)); @@ -93,20 +87,17 @@ static void add_test(void) { } /* collect the rest of the timers */ - GPR_ASSERT(grpc_timer_check( - &exec_ctx, - gpr_time_add(start, gpr_time_from_millis(1500, GPR_TIMESPAN)), - NULL) == GRPC_TIMERS_FIRED); + exec_ctx.now = start + 1500; + GPR_ASSERT(grpc_timer_check(&exec_ctx, NULL) == GRPC_TIMERS_FIRED); grpc_exec_ctx_finish(&exec_ctx); for (i = 0; i < 30; i++) { GPR_ASSERT(cb_called[i][1] == (i < 20)); GPR_ASSERT(cb_called[i][0] == 0); } - GPR_ASSERT(grpc_timer_check( - &exec_ctx, - gpr_time_add(start, gpr_time_from_millis(1600, GPR_TIMESPAN)), - NULL) == GRPC_TIMERS_CHECKED_AND_EMPTY); + exec_ctx.now = start + 1600; + GPR_ASSERT(grpc_timer_check(&exec_ctx, NULL) == + GRPC_TIMERS_CHECKED_AND_EMPTY); for (i = 0; i < 30; i++) { GPR_ASSERT(cb_called[i][1] == (i < 20)); GPR_ASSERT(cb_called[i][0] == 0); @@ -116,10 +107,6 @@ static void add_test(void) { grpc_exec_ctx_finish(&exec_ctx); } -static gpr_timespec tfm(int m) { - return gpr_time_from_millis(m, GPR_CLOCK_REALTIME); -} - /* Cleaning up a list with pending timers. */ void destruction_test(void) { grpc_timer timers[5]; @@ -127,32 +114,30 @@ void destruction_test(void) { gpr_log(GPR_INFO, "destruction_test"); - grpc_timer_list_init(gpr_time_0(GPR_CLOCK_REALTIME)); + exec_ctx.now_is_valid = true; + exec_ctx.now = 0; + grpc_timer_list_init(&exec_ctx); grpc_timer_trace.value = 1; grpc_timer_check_trace.value = 1; memset(cb_called, 0, sizeof(cb_called)); grpc_timer_init( - &exec_ctx, &timers[0], tfm(100), - GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)0, grpc_schedule_on_exec_ctx), - gpr_time_0(GPR_CLOCK_REALTIME)); + &exec_ctx, &timers[0], 100, + GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)0, grpc_schedule_on_exec_ctx)); grpc_timer_init( - &exec_ctx, &timers[1], tfm(3), - GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)1, grpc_schedule_on_exec_ctx), - gpr_time_0(GPR_CLOCK_REALTIME)); + &exec_ctx, &timers[1], 3, + GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)1, grpc_schedule_on_exec_ctx)); grpc_timer_init( - &exec_ctx, &timers[2], tfm(100), - GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)2, grpc_schedule_on_exec_ctx), - gpr_time_0(GPR_CLOCK_REALTIME)); + &exec_ctx, &timers[2], 100, + GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)2, grpc_schedule_on_exec_ctx)); grpc_timer_init( - &exec_ctx, &timers[3], tfm(3), - GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)3, grpc_schedule_on_exec_ctx), - gpr_time_0(GPR_CLOCK_REALTIME)); + &exec_ctx, &timers[3], 3, + GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)3, grpc_schedule_on_exec_ctx)); grpc_timer_init( - &exec_ctx, &timers[4], tfm(1), - GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)4, grpc_schedule_on_exec_ctx), - gpr_time_0(GPR_CLOCK_REALTIME)); - GPR_ASSERT(grpc_timer_check(&exec_ctx, tfm(2), NULL) == GRPC_TIMERS_FIRED); + &exec_ctx, &timers[4], 1, + GRPC_CLOSURE_CREATE(cb, (void *)(intptr_t)4, grpc_schedule_on_exec_ctx)); + exec_ctx.now = 2; + GPR_ASSERT(grpc_timer_check(&exec_ctx, NULL) == GRPC_TIMERS_FIRED); grpc_exec_ctx_finish(&exec_ctx); GPR_ASSERT(1 == cb_called[4][1]); grpc_timer_cancel(&exec_ctx, &timers[0]); diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c index 1d051bea62..2e44d0abc8 100644 --- a/test/core/iomgr/udp_server_test.c +++ b/test/core/iomgr/udp_server_test.c @@ -226,7 +226,7 @@ static void test_receive(int number_of_clients) { grpc_udp_server *s = grpc_udp_server_create(NULL); int i; int number_of_reads_before; - gpr_timespec deadline; + grpc_millis deadline; grpc_pollset *pollsets[1]; LOG_TEST("test_receive"); gpr_log(GPR_INFO, "clients=%d", number_of_clients); @@ -252,7 +252,8 @@ static void test_receive(int number_of_clients) { gpr_mu_lock(g_mu); for (i = 0; i < number_of_clients; i++) { - deadline = grpc_timeout_seconds_to_deadline(10); + deadline = + grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(10)); number_of_reads_before = g_number_of_reads; /* Create a socket, send a packet to the UDP server. */ @@ -262,14 +263,13 @@ static void test_receive(int number_of_clients) { (socklen_t)resolved_addr.len) == 0); GPR_ASSERT(5 == write(clifd, "hello", 5)); while (g_number_of_reads == number_of_reads_before && - gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) { + deadline > grpc_exec_ctx_now(&exec_ctx)) { grpc_pollset_worker *worker = NULL; GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline))); + grpc_pollset_work(&exec_ctx, g_pollset, &worker, deadline))); gpr_mu_unlock(g_mu); - grpc_exec_ctx_finish(&exec_ctx); + grpc_exec_ctx_flush(&exec_ctx); gpr_mu_lock(g_mu); } GPR_ASSERT(g_number_of_reads == number_of_reads_before + 1); diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index 441c431135..34f310142c 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -194,14 +194,13 @@ static void test_add_abunch_to_md_array(void) { static void test_oauth2_token_fetcher_creds_parsing_ok(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem token_md = GRPC_MDNULL; - gpr_timespec token_lifetime; + grpc_millis token_lifetime; grpc_httpcli_response response = http_response(200, valid_oauth2_json_response); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( &exec_ctx, &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_OK); - GPR_ASSERT(token_lifetime.tv_sec == 3599); - GPR_ASSERT(token_lifetime.tv_nsec == 0); + GPR_ASSERT(token_lifetime == 3599 * GPR_MS_PER_SEC); GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDKEY(token_md), "authorization") == 0); GPR_ASSERT(grpc_slice_str_cmp(GRPC_MDVALUE(token_md), "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == @@ -214,7 +213,7 @@ static void test_oauth2_token_fetcher_creds_parsing_ok(void) { static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem token_md = GRPC_MDNULL; - gpr_timespec token_lifetime; + grpc_millis token_lifetime; grpc_httpcli_response response = http_response(401, valid_oauth2_json_response); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( @@ -227,7 +226,7 @@ static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) { static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem token_md = GRPC_MDNULL; - gpr_timespec token_lifetime; + grpc_millis token_lifetime; grpc_httpcli_response response = http_response(200, ""); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( &exec_ctx, &response, &token_md, &token_lifetime) == @@ -239,7 +238,7 @@ static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) { static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem token_md = GRPC_MDNULL; - gpr_timespec token_lifetime; + grpc_millis token_lifetime; grpc_httpcli_response response = http_response(200, "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\"," @@ -255,7 +254,7 @@ static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) { static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem token_md = GRPC_MDNULL; - gpr_timespec token_lifetime; + grpc_millis token_lifetime; grpc_httpcli_response response = http_response(200, "{" " \"expires_in\":3599, " @@ -270,7 +269,7 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) { static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem token_md = GRPC_MDNULL; - gpr_timespec token_lifetime; + grpc_millis token_lifetime; grpc_httpcli_response response = http_response(200, "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\"," @@ -287,7 +286,7 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime( void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_mdelem token_md = GRPC_MDNULL; - gpr_timespec token_lifetime; + grpc_millis token_lifetime; grpc_httpcli_response response = http_response(200, "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\"," @@ -555,7 +554,7 @@ static void validate_compute_engine_http_request( static int compute_engine_httpcli_get_success_override( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_closure *on_done, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { validate_compute_engine_http_request(request); *response = http_response(200, valid_oauth2_json_response); @@ -565,7 +564,7 @@ static int compute_engine_httpcli_get_success_override( static int compute_engine_httpcli_get_failure_override( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_closure *on_done, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { validate_compute_engine_http_request(request); *response = http_response(403, "Not Authorized."); @@ -575,7 +574,7 @@ static int compute_engine_httpcli_get_failure_override( static int httpcli_post_should_not_be_called( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - const char *body_bytes, size_t body_size, gpr_timespec deadline, + const char *body_bytes, size_t body_size, grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { GPR_ASSERT("HTTP POST should not be called" == NULL); return 1; @@ -583,7 +582,7 @@ static int httpcli_post_should_not_be_called( static int httpcli_get_should_not_be_called(grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { GPR_ASSERT("HTTP GET should not be called" == NULL); @@ -663,7 +662,7 @@ static void validate_refresh_token_http_request( static int refresh_token_httpcli_post_success( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - const char *body, size_t body_size, gpr_timespec deadline, + const char *body, size_t body_size, grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { validate_refresh_token_http_request(request, body, body_size); *response = http_response(200, valid_oauth2_json_response); @@ -673,7 +672,7 @@ static int refresh_token_httpcli_post_success( static int refresh_token_httpcli_post_failure( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - const char *body, size_t body_size, gpr_timespec deadline, + const char *body, size_t body_size, grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { validate_refresh_token_http_request(request, body, body_size); *response = http_response(403, "Not Authorized."); @@ -932,7 +931,7 @@ static void test_google_default_creds_refresh_token(void) { static int default_creds_gce_detection_httpcli_get_success_override( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_closure *on_done, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { *response = http_response(200, ""); grpc_http_header *headers = gpr_malloc(sizeof(*headers) * 1); @@ -996,7 +995,7 @@ static void test_google_default_creds_gce(void) { static int default_creds_gce_detection_httpcli_get_failure_override( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_closure *on_done, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { /* No magic header. */ GPR_ASSERT(strcmp(request->http.path, "/") == 0); @@ -1036,39 +1035,46 @@ typedef enum { static const expected_md plugin_md[] = {{"foo", "bar"}, {"hi", "there"}}; -static void plugin_get_metadata_success(void *state, - grpc_auth_metadata_context context, - grpc_credentials_plugin_metadata_cb cb, - void *user_data) { - size_t i; - grpc_metadata md[GPR_ARRAY_SIZE(plugin_md)]; - plugin_state *s = (plugin_state *)state; +static int plugin_get_metadata_success( + void *state, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, void *user_data, + grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], + size_t *num_creds_md, grpc_status_code *status, + const char **error_details) { GPR_ASSERT(strcmp(context.service_url, test_service_url) == 0); GPR_ASSERT(strcmp(context.method_name, test_method) == 0); GPR_ASSERT(context.channel_auth_context == NULL); GPR_ASSERT(context.reserved == NULL); + GPR_ASSERT(GPR_ARRAY_SIZE(plugin_md) < + GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX); + plugin_state *s = (plugin_state *)state; *s = PLUGIN_GET_METADATA_CALLED_STATE; - for (i = 0; i < GPR_ARRAY_SIZE(plugin_md); i++) { - memset(&md[i], 0, sizeof(grpc_metadata)); - md[i].key = grpc_slice_from_copied_string(plugin_md[i].key); - md[i].value = grpc_slice_from_copied_string(plugin_md[i].value); + for (size_t i = 0; i < GPR_ARRAY_SIZE(plugin_md); ++i) { + memset(&creds_md[i], 0, sizeof(grpc_metadata)); + creds_md[i].key = grpc_slice_from_copied_string(plugin_md[i].key); + creds_md[i].value = grpc_slice_from_copied_string(plugin_md[i].value); } - cb(user_data, md, GPR_ARRAY_SIZE(md), GRPC_STATUS_OK, NULL); + *num_creds_md = GPR_ARRAY_SIZE(plugin_md); + return true; // Synchronous return. } static const char *plugin_error_details = "Could not get metadata for plugin."; -static void plugin_get_metadata_failure(void *state, - grpc_auth_metadata_context context, - grpc_credentials_plugin_metadata_cb cb, - void *user_data) { - plugin_state *s = (plugin_state *)state; +static int plugin_get_metadata_failure( + void *state, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, void *user_data, + grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], + size_t *num_creds_md, grpc_status_code *status, + const char **error_details) { GPR_ASSERT(strcmp(context.service_url, test_service_url) == 0); GPR_ASSERT(strcmp(context.method_name, test_method) == 0); GPR_ASSERT(context.channel_auth_context == NULL); GPR_ASSERT(context.reserved == NULL); + plugin_state *s = (plugin_state *)state; *s = PLUGIN_GET_METADATA_CALLED_STATE; - cb(user_data, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, plugin_error_details); + *status = GRPC_STATUS_UNAUTHENTICATED; + *error_details = gpr_strdup(plugin_error_details); + return true; // Synchronous return. } static void plugin_destroy(void *state) { diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c index 9b17fb516d..a4bfe0130e 100644 --- a/test/core/security/jwt_verifier_test.c +++ b/test/core/security/jwt_verifier_test.c @@ -324,7 +324,7 @@ static grpc_httpcli_response http_response(int status, char *body) { static int httpcli_post_should_not_be_called( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - const char *body_bytes, size_t body_size, gpr_timespec deadline, + const char *body_bytes, size_t body_size, grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { GPR_ASSERT("HTTP POST should not be called" == NULL); return 1; @@ -332,7 +332,7 @@ static int httpcli_post_should_not_be_called( static int httpcli_get_google_keys_for_email( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_closure *on_done, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { *response = http_response(200, good_google_email_keys()); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); @@ -379,7 +379,7 @@ static void test_jwt_verifier_google_email_issuer_success(void) { static int httpcli_get_custom_keys_for_email( grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_closure *on_done, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { *response = http_response(200, gpr_strdup(good_jwk_set)); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); @@ -413,7 +413,7 @@ static void test_jwt_verifier_custom_email_issuer_success(void) { static int httpcli_get_jwk_set(grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_closure *on_done, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { *response = http_response(200, gpr_strdup(good_jwk_set)); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); @@ -425,7 +425,7 @@ static int httpcli_get_jwk_set(grpc_exec_ctx *exec_ctx, static int httpcli_get_openid_config(grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { *response = http_response(200, gpr_strdup(good_openid_config)); @@ -471,7 +471,7 @@ static void on_verification_key_retrieval_error(grpc_exec_ctx *exec_ctx, static int httpcli_get_bad_json(grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, grpc_closure *on_done, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { *response = http_response(200, gpr_strdup("{\"bad\": \"stuff\"}")); GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); @@ -581,7 +581,7 @@ static void test_jwt_verifier_bad_signature(void) { static int httpcli_get_should_not_be_called(grpc_exec_ctx *exec_ctx, const grpc_httpcli_request *request, - gpr_timespec deadline, + grpc_millis deadline, grpc_closure *on_done, grpc_httpcli_response *response) { GPR_ASSERT(0); diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c index d240403a29..73d6c5bc7d 100644 --- a/test/core/security/oauth2_utils.c +++ b/test/core/security/oauth2_utils.c @@ -104,8 +104,7 @@ char *grpc_test_fetch_oauth2_token_with_credentials( "pollset_work", grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&request.pops), - &worker, gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)))) { + &worker, GRPC_MILLIS_INF_FUTURE))) { request.is_done = true; } } diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c index 3144717a85..29c38dfdf8 100644 --- a/test/core/security/print_google_default_creds_token.c +++ b/test/core/security/print_google_default_creds_token.c @@ -110,8 +110,7 @@ int main(int argc, char **argv) { "pollset_work", grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&sync.pops), &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)))) + GRPC_MILLIS_INF_FUTURE))) sync.is_done = true; gpr_mu_unlock(sync.mu); grpc_exec_ctx_flush(&exec_ctx); diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c index 9858b11c7c..f9b754b8f2 100644 --- a/test/core/security/ssl_server_fuzzer.c +++ b/test/core/security/ssl_server_fuzzer.c @@ -84,8 +84,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_security_status status = grpc_server_credentials_create_security_connector(&exec_ctx, creds, &sc); GPR_ASSERT(status == GRPC_SECURITY_OK); - gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(1, GPR_TIMESPAN)); + grpc_millis deadline = GPR_MS_PER_SEC + grpc_exec_ctx_now(&exec_ctx); struct handshake_state state; state.done_callback_called = false; diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c index 5faa6352a8..cec6fb94b4 100644 --- a/test/core/security/verify_jwt.c +++ b/test/core/security/verify_jwt.c @@ -102,11 +102,9 @@ int main(int argc, char **argv) { gpr_mu_lock(sync.mu); while (!sync.is_done) { grpc_pollset_worker *worker = NULL; - if (!GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, sync.pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC)))) + if (!GRPC_LOG_IF_ERROR("pollset_work", + grpc_pollset_work(&exec_ctx, sync.pollset, &worker, + GRPC_MILLIS_INF_FUTURE))) sync.is_done = true; gpr_mu_unlock(sync.mu); grpc_exec_ctx_flush(&exec_ctx); diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD index f86a3a6082..ad2308a4d6 100644 --- a/test/core/slice/BUILD +++ b/test/core/slice/BUILD @@ -21,10 +21,22 @@ licenses(["notice"]) # Apache v2 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( + name = "percent_encode_fuzzer", + srcs = ["percent_encode_fuzzer.c"], + language = "C", + corpus = "percent_encode_corpus", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_fuzzer( name = "percent_decode_fuzzer", srcs = ["percent_decode_fuzzer.c"], language = "C", - corpus = "response_corpus", + corpus = "percent_decode_corpus", deps = [ "//:gpr", "//:grpc", diff --git a/test/core/support/BUILD b/test/core/support/BUILD index 096576e13c..407c3eff7b 100644 --- a/test/core/support/BUILD +++ b/test/core/support/BUILD @@ -39,16 +39,6 @@ grpc_cc_test( ) grpc_cc_test( - name = "backoff_test", - srcs = ["backoff_test.c"], - language = "C", - deps = [ - "//:gpr", - "//test/core/util:gpr_test_util", - ], -) - -grpc_cc_test( name = "cmdline_test", srcs = ["cmdline_test.c"], language = "C", diff --git a/test/core/support/backoff_test.c b/test/core/support/backoff_test.c deleted file mode 100644 index 23e3005af0..0000000000 --- a/test/core/support/backoff_test.c +++ /dev/null @@ -1,143 +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 "src/core/lib/support/backoff.h" - -#include <grpc/support/log.h> - -#include "test/core/util/test_config.h" - -static void test_constant_backoff(void) { - gpr_backoff backoff; - gpr_backoff_init(&backoff, 200 /* initial timeout */, 1.0 /* multiplier */, - 0.0 /* jitter */, 100 /* min timeout */, - 1000 /* max timeout */); - - gpr_timespec now = gpr_time_0(GPR_TIMESPAN); - gpr_timespec next = gpr_backoff_begin(&backoff, now); - GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 200); - for (int i = 0; i < 10000; i++) { - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 200); - now = next; - } -} - -static void test_min_connect(void) { - gpr_backoff backoff; - gpr_backoff_init(&backoff, 100 /* initial timeout */, 1.0 /* multiplier */, - 0.0 /* jitter */, 200 /* min timeout */, - 1000 /* max timeout */); - - gpr_timespec now = gpr_time_0(GPR_TIMESPAN); - gpr_timespec next = gpr_backoff_begin(&backoff, now); - GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 200); -} - -static void test_no_jitter_backoff(void) { - gpr_backoff backoff; - gpr_backoff_init(&backoff, 2 /* initial timeout */, 2.0 /* multiplier */, - 0.0 /* jitter */, 1 /* min timeout */, - 513 /* max timeout */); - // x_1 = 2 - // x_n = 2**i + x_{i-1} ( = 2**(n+1) - 2 ) - gpr_timespec now = gpr_time_0(GPR_TIMESPAN); - gpr_timespec next = gpr_backoff_begin(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(6, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(14, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(30, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(62, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(126, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(254, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(510, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1022, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - // Hit the maximum timeout. From this point onwards, retries will increase - // only by max timeout. - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1535, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2048, GPR_TIMESPAN), next) == 0); - now = next; - next = gpr_backoff_step(&backoff, now); - GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2561, GPR_TIMESPAN), next) == 0); -} - -static void test_jitter_backoff(void) { - const int64_t initial_timeout = 500; - const double jitter = 0.1; - gpr_backoff backoff; - gpr_backoff_init(&backoff, initial_timeout, 1.0 /* multiplier */, jitter, - 100 /* min timeout */, 1000 /* max timeout */); - - backoff.rng_state = 0; // force consistent PRNG - - gpr_timespec now = gpr_time_0(GPR_TIMESPAN); - gpr_timespec next = gpr_backoff_begin(&backoff, now); - GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 500); - - int64_t expected_next_lower_bound = - (int64_t)((double)initial_timeout * (1 - jitter)); - int64_t expected_next_upper_bound = - (int64_t)((double)initial_timeout * (1 + jitter)); - - for (int i = 0; i < 10000; i++) { - next = gpr_backoff_step(&backoff, now); - - // next-now must be within (jitter*100)% of the previous timeout. - const int64_t timeout_millis = gpr_time_to_millis(gpr_time_sub(next, now)); - GPR_ASSERT(timeout_millis >= expected_next_lower_bound); - GPR_ASSERT(timeout_millis <= expected_next_upper_bound); - - expected_next_lower_bound = - (int64_t)((double)timeout_millis * (1 - jitter)); - expected_next_upper_bound = - (int64_t)((double)timeout_millis * (1 + jitter)); - now = next; - } -} - -int main(int argc, char **argv) { - grpc_test_init(argc, argv); - gpr_time_init(); - - test_constant_backoff(); - test_min_connect(); - test_no_jitter_backoff(); - test_jitter_backoff(); - - return 0; -} diff --git a/test/core/surface/concurrent_connectivity_test.c b/test/core/surface/concurrent_connectivity_test.c index ec2cd8610b..3595885ff6 100644 --- a/test/core/surface/concurrent_connectivity_test.c +++ b/test/core/surface/concurrent_connectivity_test.c @@ -135,14 +135,12 @@ void bad_server_thread(void *vargs) { gpr_mu_lock(args->mu); while (gpr_atm_acq_load(&args->stop) == 0) { - gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); - gpr_timespec deadline = - gpr_time_add(now, gpr_time_from_millis(100, GPR_TIMESPAN)); + grpc_millis deadline = grpc_exec_ctx_now(&exec_ctx) + 100; grpc_pollset_worker *worker = NULL; - if (!GRPC_LOG_IF_ERROR("pollset_work", - grpc_pollset_work(&exec_ctx, args->pollset, &worker, - now, deadline))) { + if (!GRPC_LOG_IF_ERROR( + "pollset_work", + grpc_pollset_work(&exec_ctx, args->pollset, &worker, deadline))) { gpr_atm_rel_store(&args->stop, 1); } gpr_mu_unlock(args->mu); diff --git a/test/core/surface/invalid_channel_args_test.c b/test/core/surface/invalid_channel_args_test.c index 84d7627d29..9c84c30f03 100644 --- a/test/core/surface/invalid_channel_args_test.c +++ b/test/core/surface/invalid_channel_args_test.c @@ -25,7 +25,7 @@ #include "test/core/util/test_config.h" static char *g_last_log_error_message = NULL; -static const char *g_file_name = "channel.c"; +static const char *g_file_name = "channel.cc"; static int ends_with(const char *src, const char *suffix) { size_t src_len = strlen(src); diff --git a/test/core/transport/bdp_estimator_test.c b/test/core/transport/bdp_estimator_test.c index dda48f45b1..4912ad5887 100644 --- a/test/core/transport/bdp_estimator_test.c +++ b/test/core/transport/bdp_estimator_test.c @@ -24,9 +24,22 @@ #include <grpc/support/string_util.h> #include <grpc/support/useful.h> #include <limits.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); + +static int g_clock = 0; + +static gpr_timespec fake_gpr_now(gpr_clock_type clock_type) { + return (gpr_timespec){ + .tv_sec = g_clock, .tv_nsec = 0, .clock_type = clock_type, + }; +} + +static void inc_time(void) { g_clock += 30; } + static void test_noop(void) { gpr_log(GPR_INFO, "test_noop"); grpc_bdp_estimator est; @@ -44,16 +57,19 @@ static void test_get_estimate_no_samples(void) { static void add_samples(grpc_bdp_estimator *estimator, int64_t *samples, size_t n) { grpc_bdp_estimator_add_incoming_bytes(estimator, 1234567); - GPR_ASSERT(grpc_bdp_estimator_need_ping(estimator) == true); + inc_time(); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GPR_ASSERT(grpc_bdp_estimator_need_ping(&exec_ctx, estimator) == true); grpc_bdp_estimator_schedule_ping(estimator); grpc_bdp_estimator_start_ping(estimator); for (size_t i = 0; i < n; i++) { grpc_bdp_estimator_add_incoming_bytes(estimator, samples[i]); - GPR_ASSERT(grpc_bdp_estimator_need_ping(estimator) == false); + GPR_ASSERT(grpc_bdp_estimator_need_ping(&exec_ctx, estimator) == false); } gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(1, GPR_TIMESPAN))); - grpc_bdp_estimator_complete_ping(estimator); + grpc_bdp_estimator_complete_ping(&exec_ctx, estimator); + grpc_exec_ctx_finish(&exec_ctx); } static void add_sample(grpc_bdp_estimator *estimator, int64_t sample) { @@ -130,7 +146,9 @@ static void test_get_estimate_random_values(size_t n) { int main(int argc, char **argv) { grpc_test_init(argc, argv); + gpr_now_impl = fake_gpr_now; grpc_init(); + grpc_timer_manager_set_threading(false); test_noop(); test_get_estimate_no_samples(); test_get_estimate_1_sample(); diff --git a/test/core/transport/status_conversion_test.c b/test/core/transport/status_conversion_test.c index 89558964c1..de8fa4458a 100644 --- a/test/core/transport/status_conversion_test.c +++ b/test/core/transport/status_conversion_test.c @@ -22,8 +22,13 @@ #define GRPC_STATUS_TO_HTTP2_ERROR(a, b) \ GPR_ASSERT(grpc_status_to_http2_error(a) == (b)) -#define HTTP2_ERROR_TO_GRPC_STATUS(a, deadline, b) \ - GPR_ASSERT(grpc_http2_error_to_grpc_status(a, deadline) == (b)) +#define HTTP2_ERROR_TO_GRPC_STATUS(a, deadline, b) \ + do { \ + grpc_exec_ctx my_exec_ctx = GRPC_EXEC_CTX_INIT; \ + GPR_ASSERT(grpc_http2_error_to_grpc_status(&my_exec_ctx, a, deadline) == \ + (b)); \ + grpc_exec_ctx_finish(&my_exec_ctx); \ + } while (0) #define GRPC_STATUS_TO_HTTP2_STATUS(a, b) \ GPR_ASSERT(grpc_status_to_http2_status(a) == (b)) #define HTTP2_STATUS_TO_GRPC_STATUS(a, b) \ @@ -79,7 +84,7 @@ int main(int argc, char **argv) { GRPC_STATUS_TO_HTTP2_STATUS(GRPC_STATUS_UNAVAILABLE, 200); GRPC_STATUS_TO_HTTP2_STATUS(GRPC_STATUS_DATA_LOSS, 200); - const gpr_timespec before_deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + const grpc_millis before_deadline = GRPC_MILLIS_INF_FUTURE; HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_NO_ERROR, before_deadline, GRPC_STATUS_INTERNAL); HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_PROTOCOL_ERROR, before_deadline, @@ -107,7 +112,7 @@ int main(int argc, char **argv) { HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_INADEQUATE_SECURITY, before_deadline, GRPC_STATUS_PERMISSION_DENIED); - const gpr_timespec after_deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC); + const grpc_millis after_deadline = 0; HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_NO_ERROR, after_deadline, GRPC_STATUS_INTERNAL); HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_PROTOCOL_ERROR, after_deadline, diff --git a/test/core/transport/timeout_encoding_test.c b/test/core/transport/timeout_encoding_test.c index 6388ffbcec..3010c6d057 100644 --- a/test/core/transport/timeout_encoding_test.c +++ b/test/core/transport/timeout_encoding_test.c @@ -25,12 +25,13 @@ #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 "test/core/util/test_config.h" #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) -static void assert_encodes_as(gpr_timespec ts, const char *s) { +static void assert_encodes_as(grpc_millis ts, const char *s) { char buffer[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; grpc_http2_encode_timeout(ts, buffer); gpr_log(GPR_INFO, "check '%s' == '%s'", buffer, s); @@ -39,47 +40,43 @@ static void assert_encodes_as(gpr_timespec ts, const char *s) { void test_encoding(void) { LOG_TEST("test_encoding"); - assert_encodes_as(gpr_time_from_micros(-1, GPR_TIMESPAN), "1n"); - assert_encodes_as(gpr_time_from_seconds(-10, GPR_TIMESPAN), "1n"); - assert_encodes_as(gpr_time_from_nanos(10, GPR_TIMESPAN), "10n"); - assert_encodes_as(gpr_time_from_nanos(999999999, GPR_TIMESPAN), "1S"); - assert_encodes_as(gpr_time_from_micros(1, GPR_TIMESPAN), "1u"); - assert_encodes_as(gpr_time_from_micros(10, GPR_TIMESPAN), "10u"); - assert_encodes_as(gpr_time_from_micros(100, GPR_TIMESPAN), "100u"); - assert_encodes_as(gpr_time_from_micros(890, GPR_TIMESPAN), "890u"); - assert_encodes_as(gpr_time_from_micros(900, GPR_TIMESPAN), "900u"); - assert_encodes_as(gpr_time_from_micros(901, GPR_TIMESPAN), "901u"); - assert_encodes_as(gpr_time_from_millis(1, GPR_TIMESPAN), "1m"); - assert_encodes_as(gpr_time_from_millis(2, GPR_TIMESPAN), "2m"); - assert_encodes_as(gpr_time_from_micros(10001, GPR_TIMESPAN), "10100u"); - assert_encodes_as(gpr_time_from_micros(999999, GPR_TIMESPAN), "1S"); - assert_encodes_as(gpr_time_from_millis(1000, GPR_TIMESPAN), "1S"); - assert_encodes_as(gpr_time_from_millis(2000, GPR_TIMESPAN), "2S"); - assert_encodes_as(gpr_time_from_millis(2500, GPR_TIMESPAN), "2500m"); - assert_encodes_as(gpr_time_from_millis(59900, GPR_TIMESPAN), "59900m"); - assert_encodes_as(gpr_time_from_seconds(50, GPR_TIMESPAN), "50S"); - assert_encodes_as(gpr_time_from_seconds(59, GPR_TIMESPAN), "59S"); - assert_encodes_as(gpr_time_from_seconds(60, GPR_TIMESPAN), "1M"); - assert_encodes_as(gpr_time_from_seconds(80, GPR_TIMESPAN), "80S"); - assert_encodes_as(gpr_time_from_seconds(90, GPR_TIMESPAN), "90S"); - assert_encodes_as(gpr_time_from_minutes(2, GPR_TIMESPAN), "2M"); - assert_encodes_as(gpr_time_from_minutes(20, GPR_TIMESPAN), "20M"); - assert_encodes_as(gpr_time_from_hours(1, GPR_TIMESPAN), "1H"); - assert_encodes_as(gpr_time_from_hours(10, GPR_TIMESPAN), "10H"); - assert_encodes_as(gpr_time_from_seconds(1000000000, GPR_TIMESPAN), - "1000000000S"); + assert_encodes_as(-1, "1n"); + assert_encodes_as(-10, "1n"); + assert_encodes_as(1, "1m"); + assert_encodes_as(10, "10m"); + assert_encodes_as(100, "100m"); + assert_encodes_as(890, "890m"); + assert_encodes_as(900, "900m"); + assert_encodes_as(901, "901m"); + assert_encodes_as(1000, "1S"); + assert_encodes_as(2000, "2S"); + assert_encodes_as(2500, "2500m"); + assert_encodes_as(59900, "59900m"); + assert_encodes_as(50000, "50S"); + assert_encodes_as(59000, "59S"); + assert_encodes_as(60000, "1M"); + assert_encodes_as(80000, "80S"); + assert_encodes_as(90000, "90S"); + assert_encodes_as(120000, "2M"); + assert_encodes_as(20 * 60 * GPR_MS_PER_SEC, "20M"); + assert_encodes_as(60 * 60 * GPR_MS_PER_SEC, "1H"); + assert_encodes_as(10 * 60 * 60 * GPR_MS_PER_SEC, "10H"); } -static void assert_decodes_as(const char *buffer, gpr_timespec expected) { - gpr_timespec got; - gpr_log(GPR_INFO, "check decoding '%s'", buffer); +static void assert_decodes_as(const char *buffer, grpc_millis expected) { + grpc_millis got; + uint32_t hash = gpr_murmur_hash3(buffer, strlen(buffer), 0); + gpr_log(GPR_INFO, "check decoding '%s' (hash=0x%x)", buffer, hash); GPR_ASSERT(1 == grpc_http2_decode_timeout( grpc_slice_from_static_string(buffer), &got)); - GPR_ASSERT(0 == gpr_time_cmp(got, expected)); + if (got != expected) { + gpr_log(GPR_ERROR, "got:'%" PRIdPTR "' != expected:'%" PRIdPTR "'", got, + expected); + abort(); + } } -void decode_suite(char ext, - gpr_timespec (*answer)(int64_t x, gpr_clock_type clock)) { +void decode_suite(char ext, grpc_millis (*answer)(int64_t x)) { long test_vals[] = {1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789, 98765432, 9876543, 987654, 98765, 9876, 987, 98, 9}; @@ -87,41 +84,55 @@ void decode_suite(char ext, char *input; for (i = 0; i < GPR_ARRAY_SIZE(test_vals); i++) { gpr_asprintf(&input, "%ld%c", test_vals[i], ext); - assert_decodes_as(input, answer(test_vals[i], GPR_TIMESPAN)); + assert_decodes_as(input, answer(test_vals[i])); gpr_free(input); gpr_asprintf(&input, " %ld%c", test_vals[i], ext); - assert_decodes_as(input, answer(test_vals[i], GPR_TIMESPAN)); + assert_decodes_as(input, answer(test_vals[i])); gpr_free(input); gpr_asprintf(&input, "%ld %c", test_vals[i], ext); - assert_decodes_as(input, answer(test_vals[i], GPR_TIMESPAN)); + assert_decodes_as(input, answer(test_vals[i])); gpr_free(input); gpr_asprintf(&input, "%ld %c ", test_vals[i], ext); - assert_decodes_as(input, answer(test_vals[i], GPR_TIMESPAN)); + assert_decodes_as(input, answer(test_vals[i])); gpr_free(input); } } +static grpc_millis millis_from_nanos(int64_t x) { + return x / GPR_NS_PER_MS + (x % GPR_NS_PER_MS != 0); +} +static grpc_millis millis_from_micros(int64_t x) { + return x / GPR_US_PER_MS + (x % GPR_US_PER_MS != 0); +} +static grpc_millis millis_from_millis(int64_t x) { return x; } +static grpc_millis millis_from_seconds(int64_t x) { return x * GPR_MS_PER_SEC; } +static grpc_millis millis_from_minutes(int64_t x) { + return x * 60 * GPR_MS_PER_SEC; +} +static grpc_millis millis_from_hours(int64_t x) { + return x * 3600 * GPR_MS_PER_SEC; +} + void test_decoding(void) { LOG_TEST("test_decoding"); - decode_suite('n', gpr_time_from_nanos); - decode_suite('u', gpr_time_from_micros); - decode_suite('m', gpr_time_from_millis); - decode_suite('S', gpr_time_from_seconds); - decode_suite('M', gpr_time_from_minutes); - decode_suite('H', gpr_time_from_hours); - assert_decodes_as("1000000000S", - gpr_time_from_seconds(1000 * 1000 * 1000, GPR_TIMESPAN)); - assert_decodes_as("1000000000000000000000u", gpr_inf_future(GPR_TIMESPAN)); - assert_decodes_as("1000000001S", gpr_inf_future(GPR_TIMESPAN)); - assert_decodes_as("2000000001S", gpr_inf_future(GPR_TIMESPAN)); - assert_decodes_as("9999999999S", gpr_inf_future(GPR_TIMESPAN)); + decode_suite('n', millis_from_nanos); + decode_suite('u', millis_from_micros); + decode_suite('m', millis_from_millis); + decode_suite('S', millis_from_seconds); + decode_suite('M', millis_from_minutes); + decode_suite('H', millis_from_hours); + assert_decodes_as("1000000000S", millis_from_seconds(1000 * 1000 * 1000)); + assert_decodes_as("1000000000000000000000u", GRPC_MILLIS_INF_FUTURE); + assert_decodes_as("1000000001S", GRPC_MILLIS_INF_FUTURE); + assert_decodes_as("2000000001S", GRPC_MILLIS_INF_FUTURE); + assert_decodes_as("9999999999S", GRPC_MILLIS_INF_FUTURE); } static void assert_decoding_fails(const char *s) { - gpr_timespec x; + grpc_millis x; GPR_ASSERT(0 == grpc_http2_decode_timeout(grpc_slice_from_static_string(s), &x)); } diff --git a/test/core/tsi/transport_security_test_lib.c b/test/core/tsi/transport_security_test_lib.c index 7d66e110f2..329b2371bf 100644 --- a/test/core/tsi/transport_security_test_lib.c +++ b/test/core/tsi/transport_security_test_lib.c @@ -23,9 +23,26 @@ #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" +static void notification_signal(tsi_test_fixture *fixture) { + gpr_mu_lock(&fixture->mu); + fixture->notified = true; + gpr_cv_signal(&fixture->cv); + gpr_mu_unlock(&fixture->mu); +} + +static void notification_wait(tsi_test_fixture *fixture) { + gpr_mu_lock(&fixture->mu); + while (!fixture->notified) { + gpr_cv_wait(&fixture->cv, &fixture->mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + fixture->notified = false; + gpr_mu_unlock(&fixture->mu); +} + typedef struct handshaker_args { tsi_test_fixture *fixture; unsigned char *handshake_buffer; @@ -273,9 +290,11 @@ grpc_error *on_handshake_next_done(tsi_result result, void *user_data, /* Read more data if we need to. */ if (result == TSI_INCOMPLETE_DATA) { GPR_ASSERT(bytes_to_send_size == 0); + notification_signal(fixture); return error; } if (result != TSI_OK) { + notification_signal(fixture); return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake failed"), result); } @@ -295,6 +314,7 @@ grpc_error *on_handshake_next_done(tsi_result result, void *user_data, if (handshaker_result != NULL) { maybe_append_unused_bytes(args); } + notification_signal(fixture); return error; } @@ -345,7 +365,11 @@ static void do_handshaker_next(handshaker_args *args) { if (result != TSI_ASYNC) { args->error = on_handshake_next_done(result, args, bytes_to_send, bytes_to_send_size, handshaker_result); + if (args->error != GRPC_ERROR_NONE) { + return; + } } + notification_wait(fixture); } void tsi_test_do_handshake(tsi_test_fixture *fixture) { @@ -532,6 +556,9 @@ void tsi_test_fixture_init(tsi_test_fixture *fixture) { fixture->bytes_read_from_server_channel = 0; fixture->test_unused_bytes = true; fixture->has_client_finished_first = false; + gpr_mu_init(&fixture->mu); + gpr_cv_init(&fixture->cv); + fixture->notified = false; } void tsi_test_fixture_destroy(tsi_test_fixture *fixture) { @@ -546,5 +573,7 @@ void tsi_test_fixture_destroy(tsi_test_fixture *fixture) { GPR_ASSERT(fixture->vtable != NULL); GPR_ASSERT(fixture->vtable->destruct != NULL); fixture->vtable->destruct(fixture); + gpr_mu_destroy(&fixture->mu); + gpr_cv_destroy(&fixture->cv); gpr_free(fixture); } diff --git a/test/core/tsi/transport_security_test_lib.h b/test/core/tsi/transport_security_test_lib.h index 8ae2024ee4..ed8ff856df 100644 --- a/test/core/tsi/transport_security_test_lib.h +++ b/test/core/tsi/transport_security_test_lib.h @@ -21,6 +21,10 @@ #include "src/core/tsi/transport_security_interface.h" +#ifdef __cplusplus +extern "C" { +#endif + #define TSI_TEST_TINY_HANDSHAKE_BUFFER_SIZE 32 #define TSI_TEST_SMALL_HANDSHAKE_BUFFER_SIZE 128 #define TSI_TEST_SMALL_READ_BUFFER_ALLOCATED_SIZE 41 @@ -56,10 +60,10 @@ typedef struct tsi_test_fixture_vtable { void (*setup_handshakers)(tsi_test_fixture *fixture); void (*check_handshaker_peers)(tsi_test_fixture *fixture); void (*destruct)(tsi_test_fixture *fixture); -} tranport_security_test_vtable; +} tsi_test_fixture_vtable; struct tsi_test_fixture { - const struct tsi_test_fixture_vtable *vtable; + const tsi_test_fixture_vtable *vtable; /* client/server TSI handshaker used to perform TSI handshakes, and will get instantiated during the call to setup_handshakers. */ tsi_handshaker *client_handshaker; @@ -95,6 +99,13 @@ struct tsi_test_fixture { (https://github.com/grpc/grpc/issues/12164). */ bool test_unused_bytes; + /* These objects will be used coordinate client/server handshakers with TSI + thread to perform TSI handshakes in an asynchronous manner (for GTS TSI + implementations). + */ + gpr_cv cv; + gpr_mu mu; + bool notified; }; struct tsi_test_frame_protector_config { @@ -162,4 +173,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); +#ifdef __cplusplus +} +#endif + #endif // GRPC_TEST_CORE_TSI_TRANSPORT_SECURITY_TEST_LIB_H_ diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 10eefe159a..abb50a0c99 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -89,12 +89,16 @@ grpc_cc_library( ) grpc_cc_library( - name = "one_corpus_entry_fuzzer", - srcs = ["one_corpus_entry_fuzzer.c"], + name = "fuzzer_corpus_test", + srcs = ["fuzzer_corpus_test.cc"], deps = [ ":gpr_test_util", "//:grpc", ], + external_deps = [ + "gtest", + "gflags", + ], ) sh_library( diff --git a/test/core/util/fuzzer_corpus_test.cc b/test/core/util/fuzzer_corpus_test.cc new file mode 100644 index 0000000000..a5e99a1bac --- /dev/null +++ b/test/core/util/fuzzer_corpus_test.cc @@ -0,0 +1,136 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdbool.h> + +#include <dirent.h> +#include <gflags/gflags.h> +#include <grpc/support/log.h> +#include <gtest/gtest.h> +#include <stdio.h> +#include <sys/types.h> + +#include "src/core/lib/iomgr/load_file.h" +#include "test/core/util/test_config.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); +extern "C" bool squelch; +extern "C" bool leak_check; + +DEFINE_string(file, "", "Use this file as test data"); +DEFINE_string(directory, "", "Use this directory as test data"); + +class FuzzerCorpusTest : public ::testing::TestWithParam<std::string> {}; + +TEST_P(FuzzerCorpusTest, RunOneExample) { + gpr_log(GPR_DEBUG, "Example file: %s", GetParam().c_str()); + grpc_slice buffer; + squelch = false; + leak_check = false; + GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(GetParam().c_str(), 0, &buffer))); + LLVMFuzzerTestOneInput(GRPC_SLICE_START_PTR(buffer), + GRPC_SLICE_LENGTH(buffer)); + grpc_slice_unref(buffer); +} + +class ExampleGenerator + : public ::testing::internal::ParamGeneratorInterface<std::string> { + public: + virtual ::testing::internal::ParamIteratorInterface<std::string>* Begin() + const; + virtual ::testing::internal::ParamIteratorInterface<std::string>* End() const; + + private: + void Materialize() const { + if (examples_.empty()) { + if (!FLAGS_file.empty()) examples_.push_back(FLAGS_file); + if (!FLAGS_directory.empty()) { + DIR* dp; + struct dirent* ep; + dp = opendir(FLAGS_directory.c_str()); + + if (dp != NULL) { + while ((ep = readdir(dp)) != nullptr) { + if (ep->d_type == DT_REG) { + examples_.push_back(FLAGS_directory + "/" + ep->d_name); + } + } + + (void)closedir(dp); + } else { + perror("Couldn't open the directory"); + abort(); + } + } + } + } + + mutable std::vector<std::string> examples_; +}; + +class ExampleIterator + : public ::testing::internal::ParamIteratorInterface<std::string> { + public: + ExampleIterator(const ExampleGenerator& base_, + std::vector<std::string>::const_iterator begin) + : base_(base_), begin_(begin), current_(begin) {} + + virtual const ExampleGenerator* BaseGenerator() const { return &base_; } + + virtual void Advance() { current_++; } + virtual ExampleIterator* Clone() const { return new ExampleIterator(*this); } + virtual const std::string* Current() const { return &*current_; } + + virtual bool Equals(const ParamIteratorInterface<std::string>& other) const { + return &base_ == other.BaseGenerator() && + current_ == dynamic_cast<const ExampleIterator*>(&other)->current_; + } + + private: + ExampleIterator(const ExampleIterator& other) + : base_(other.base_), begin_(other.begin_), current_(other.current_) {} + + const ExampleGenerator& base_; + const std::vector<std::string>::const_iterator begin_; + std::vector<std::string>::const_iterator current_; +}; + +::testing::internal::ParamIteratorInterface<std::string>* +ExampleGenerator::Begin() const { + Materialize(); + return new ExampleIterator(*this, examples_.begin()); +} + +::testing::internal::ParamIteratorInterface<std::string>* +ExampleGenerator::End() const { + Materialize(); + return new ExampleIterator(*this, examples_.end()); +} + +INSTANTIATE_TEST_CASE_P( + CorpusExamples, FuzzerCorpusTest, + ::testing::internal::ParamGenerator<std::string>(new ExampleGenerator)); + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::gflags::ParseCommandLineFlags(&argc, &argv, true); + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/core/util/grpc_fuzzer.bzl b/test/core/util/grpc_fuzzer.bzl index 41f6cdc8ba..55b6f1c1a5 100644 --- a/test/core/util/grpc_fuzzer.bzl +++ b/test/core/util/grpc_fuzzer.bzl @@ -12,19 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:grpc_build_system.bzl", "grpc_cc_binary") +load("//bazel:grpc_build_system.bzl", "grpc_cc_test") def grpc_fuzzer(name, corpus, srcs = [], deps = [], **kwargs): - grpc_cc_binary( - name = '%s/one_entry.bin' % name, + grpc_cc_test( + name = name, srcs = srcs, - deps = deps + ["//test/core/util:one_corpus_entry_fuzzer"], + deps = deps + ["//test/core/util:fuzzer_corpus_test"], + data = [corpus], + args = ['--directory', '$(location %s)' % corpus], + external_deps = [ + 'gtest', + ], **kwargs ) - for entry in native.glob(['%s/*' % corpus]): - native.sh_test( - name = '%s/one_entry/%s' % (name, entry), - data = [':%s/one_entry.bin' % name, entry], - srcs = ['//test/core/util:fuzzer_one_entry_runner'], - args = ['$(location :%s/one_entry.bin)' % name, '$(location %s)' % entry] - ) diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c index ba4028dbee..7b94ac4ada 100644 --- a/test/core/util/port_server_client.c +++ b/test/core/util/port_server_client.c @@ -88,7 +88,7 @@ void grpc_free_port_using_server(int port) { grpc_resource_quota *resource_quota = grpc_resource_quota_create("port_server_client/free"); grpc_httpcli_get(&exec_ctx, &context, &pr.pops, resource_quota, &req, - grpc_timeout_seconds_to_deadline(30), + grpc_exec_ctx_now(&exec_ctx) + 30 * GPR_MS_PER_SEC, GRPC_CLOSURE_CREATE(freed_port_from_server, &pr, grpc_schedule_on_exec_ctx), &rsp); @@ -100,8 +100,8 @@ void grpc_free_port_using_server(int port) { if (!GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&pr.pops), - &worker, gpr_now(GPR_CLOCK_MONOTONIC), - grpc_timeout_seconds_to_deadline(1)))) { + &worker, + grpc_exec_ctx_now(&exec_ctx) + GPR_MS_PER_SEC))) { pr.done = 1; } } @@ -173,7 +173,7 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg, grpc_resource_quota *resource_quota = grpc_resource_quota_create("port_server_client/pick_retry"); grpc_httpcli_get(exec_ctx, pr->ctx, &pr->pops, resource_quota, &req, - grpc_timeout_seconds_to_deadline(10), + grpc_exec_ctx_now(exec_ctx) + 30 * GPR_MS_PER_SEC, GRPC_CLOSURE_CREATE(got_port_from_server, pr, grpc_schedule_on_exec_ctx), &pr->response); @@ -224,7 +224,7 @@ int grpc_pick_port_using_server(void) { grpc_resource_quota_create("port_server_client/pick"); grpc_httpcli_get( &exec_ctx, &context, &pr.pops, resource_quota, &req, - grpc_timeout_seconds_to_deadline(30), + grpc_exec_ctx_now(&exec_ctx) + 30 * GPR_MS_PER_SEC, GRPC_CLOSURE_CREATE(got_port_from_server, &pr, grpc_schedule_on_exec_ctx), &pr.response); grpc_resource_quota_unref_internal(&exec_ctx, resource_quota); @@ -235,8 +235,8 @@ int grpc_pick_port_using_server(void) { if (!GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&pr.pops), - &worker, gpr_now(GPR_CLOCK_MONOTONIC), - grpc_timeout_seconds_to_deadline(1)))) { + &worker, + grpc_exec_ctx_now(&exec_ctx) + GPR_MS_PER_SEC))) { pr.port = 0; } } diff --git a/test/core/util/test_tcp_server.c b/test/core/util/test_tcp_server.c index d3a1de8a3b..611ecb330c 100644 --- a/test/core/util/test_tcp_server.c +++ b/test/core/util/test_tcp_server.c @@ -31,6 +31,7 @@ #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" #include "test/core/util/port.h" +#include "test/core/util/test_config.h" static void on_server_destroyed(grpc_exec_ctx *exec_ctx, void *data, grpc_error *error) { @@ -78,14 +79,13 @@ void test_tcp_server_start(test_tcp_server *server, int port) { void test_tcp_server_poll(test_tcp_server *server, int seconds) { grpc_pollset_worker *worker = NULL; - gpr_timespec deadline = - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(seconds, GPR_TIMESPAN)); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_millis deadline = grpc_timespec_to_millis_round_up( + grpc_timeout_seconds_to_deadline(seconds)); gpr_mu_lock(server->mu); - GRPC_LOG_IF_ERROR("pollset_work", - grpc_pollset_work(&exec_ctx, server->pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline)); + GRPC_LOG_IF_ERROR( + "pollset_work", + grpc_pollset_work(&exec_ctx, server->pollset, &worker, deadline)); gpr_mu_unlock(server->mu); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/cpp/common/alarm_cpp_test.cc b/test/cpp/common/alarm_cpp_test.cc index 212972d25d..7adc3102f4 100644 --- a/test/cpp/common/alarm_cpp_test.cc +++ b/test/cpp/common/alarm_cpp_test.cc @@ -142,7 +142,7 @@ TEST(AlarmTest, ZeroExpiry) { void* output_tag; bool ok; const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(0)); + (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); @@ -158,7 +158,7 @@ TEST(AlarmTest, NegativeExpiry) { void* output_tag; bool ok; const CompletionQueue::NextStatus status = cq.AsyncNext( - (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(0)); + (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(1)); EXPECT_EQ(status, CompletionQueue::GOT_EVENT); EXPECT_TRUE(ok); diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 41090d161a..f938aea40e 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -105,6 +105,13 @@ class Verifier { expectations_[tag(i)] = expect_ok; return *this; } + // AcceptOnce sets the expected ok value for a specific tag, but does not + // require it to appear + // If it does, sets *seen to true + Verifier& AcceptOnce(int i, bool expect_ok, bool* seen) { + maybe_expectations_[tag(i)] = MaybeExpect{expect_ok, seen}; + return *this; + } // Next waits for 1 async tag to complete, checks its // expectations, and returns the tag @@ -122,12 +129,7 @@ class Verifier { } else { EXPECT_TRUE(cq->Next(&got_tag, &ok)); } - auto it = expectations_.find(got_tag); - EXPECT_TRUE(it != expectations_.end()); - if (!ignore_ok) { - EXPECT_EQ(it->second, ok); - } - expectations_.erase(it); + GotTag(got_tag, ok, ignore_ok); return detag(got_tag); } @@ -138,7 +140,7 @@ class Verifier { // This version of Verify allows optionally ignoring the // outcome of the expectation void Verify(CompletionQueue* cq, bool ignore_ok) { - GPR_ASSERT(!expectations_.empty()); + GPR_ASSERT(!expectations_.empty() || !maybe_expectations_.empty()); while (!expectations_.empty()) { Next(cq, ignore_ok); } @@ -177,16 +179,43 @@ class Verifier { EXPECT_EQ(cq->AsyncNext(&got_tag, &ok, deadline), CompletionQueue::GOT_EVENT); } - auto it = expectations_.find(got_tag); - EXPECT_TRUE(it != expectations_.end()); - EXPECT_EQ(it->second, ok); - expectations_.erase(it); + GotTag(got_tag, ok, false); } } } private: + void GotTag(void* got_tag, bool ok, bool ignore_ok) { + auto it = expectations_.find(got_tag); + if (it != expectations_.end()) { + if (!ignore_ok) { + EXPECT_EQ(it->second, ok); + } + expectations_.erase(it); + } else { + auto it2 = maybe_expectations_.find(got_tag); + if (it2 != maybe_expectations_.end()) { + if (it2->second.seen != nullptr) { + EXPECT_FALSE(*it2->second.seen); + *it2->second.seen = true; + } + if (!ignore_ok) { + EXPECT_EQ(it2->second.ok, ok); + } + } else { + gpr_log(GPR_ERROR, "Unexpected tag: %p", tag); + abort(); + } + } + } + + struct MaybeExpect { + bool ok; + bool* seen; + }; + std::map<void*, bool> expectations_; + std::map<void*, MaybeExpect> maybe_expectations_; bool spin_; }; @@ -223,11 +252,8 @@ class TestScenario { bool disable_blocking; bool inproc; bool health_check_service; - // Although the below grpc::string's are logically const, we can't declare - // them const because of a limitation in the way old compilers (e.g., gcc-4.4) - // manage vector insertion using a copy constructor - grpc::string credentials_type; - grpc::string message_content; + const grpc::string credentials_type; + const grpc::string message_content; }; static std::ostream& operator<<(std::ostream& out, @@ -539,31 +565,19 @@ TEST_P(AsyncEnd2endTest, SimpleClientStreamingWithCoalescingApi) { cli_stream->Write(send_request, tag(3)); - // 65536(64KB) is the default flow control window size. Should change this - // number when default flow control window size changes. For the write of - // send_request larger than the flow control window size, tag:3 will not come - // up until server read is initiated. For write of send_request smaller than - // the flow control window size, the request can take the free ride with - // initial metadata due to coalescing, thus write tag:3 will come up here. - if (GetParam().message_content.length() < 65536 || GetParam().inproc) { - Verifier(GetParam().disable_blocking) - .Expect(2, true) - .Expect(3, true) - .Verify(cq_.get()); - } else { - Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); - } + bool seen3 = false; + + Verifier(GetParam().disable_blocking) + .Expect(2, true) + .AcceptOnce(3, true, &seen3) + .Verify(cq_.get()); srv_stream.Read(&recv_request, tag(4)); - if (GetParam().message_content.length() < 65536 || GetParam().inproc) { - Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get()); - } else { - Verifier(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); - } + Verifier(GetParam().disable_blocking) + .AcceptOnce(3, true, &seen3) + .Expect(4, true) + .Verify(cq_.get()); EXPECT_EQ(send_request.message(), recv_request.message()); @@ -588,6 +602,7 @@ TEST_P(AsyncEnd2endTest, SimpleClientStreamingWithCoalescingApi) { EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); + EXPECT_TRUE(seen3); } // One ping, two pongs. @@ -834,31 +849,19 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWAF) { cli_stream->WriteLast(send_request, WriteOptions(), tag(3)); - // 65536(64KB) is the default flow control window size. Should change this - // number when default flow control window size changes. For the write of - // send_request larger than the flow control window size, tag:3 will not come - // up until server read is initiated. For write of send_request smaller than - // the flow control window size, the request can take the free ride with - // initial metadata due to coalescing, thus write tag:3 will come up here. - if (GetParam().message_content.length() < 65536 || GetParam().inproc) { - Verifier(GetParam().disable_blocking) - .Expect(2, true) - .Expect(3, true) - .Verify(cq_.get()); - } else { - Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); - } + bool seen3 = false; + + Verifier(GetParam().disable_blocking) + .Expect(2, true) + .AcceptOnce(3, true, &seen3) + .Verify(cq_.get()); srv_stream.Read(&recv_request, tag(4)); - if (GetParam().message_content.length() < 65536 || GetParam().inproc) { - Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get()); - } else { - Verifier(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); - } + Verifier(GetParam().disable_blocking) + .AcceptOnce(3, true, &seen3) + .Expect(4, true) + .Verify(cq_.get()); EXPECT_EQ(send_request.message(), recv_request.message()); srv_stream.Read(&recv_request, tag(5)); @@ -877,6 +880,7 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWAF) { Verifier(GetParam().disable_blocking).Expect(8, true).Verify(cq_.get()); EXPECT_TRUE(recv_status.ok()); + EXPECT_TRUE(seen3); } // One ping, one pong. Using server:WriteLast api @@ -902,31 +906,19 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWL) { cli_stream->WriteLast(send_request, WriteOptions(), tag(3)); - // 65536(64KB) is the default flow control window size. Should change this - // number when default flow control window size changes. For the write of - // send_request larger than the flow control window size, tag:3 will not come - // up until server read is initiated. For write of send_request smaller than - // the flow control window size, the request can take the free ride with - // initial metadata due to coalescing, thus write tag:3 will come up here. - if (GetParam().message_content.length() < 65536 || GetParam().inproc) { - Verifier(GetParam().disable_blocking) - .Expect(2, true) - .Expect(3, true) - .Verify(cq_.get()); - } else { - Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get()); - } + bool seen3 = false; + + Verifier(GetParam().disable_blocking) + .Expect(2, true) + .AcceptOnce(3, true, &seen3) + .Verify(cq_.get()); srv_stream.Read(&recv_request, tag(4)); - if (GetParam().message_content.length() < 65536 || GetParam().inproc) { - Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get()); - } else { - Verifier(GetParam().disable_blocking) - .Expect(3, true) - .Expect(4, true) - .Verify(cq_.get()); - } + Verifier(GetParam().disable_blocking) + .AcceptOnce(3, true, &seen3) + .Expect(4, true) + .Verify(cq_.get()); EXPECT_EQ(send_request.message(), recv_request.message()); srv_stream.Read(&recv_request, tag(5)); @@ -947,6 +939,7 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWL) { Verifier(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get()); EXPECT_TRUE(recv_status.ok()); + EXPECT_TRUE(seen3); } // Metadata tests @@ -1788,7 +1781,7 @@ std::vector<TestScenario> CreateTestScenarios(bool test_disable_blocking, GPR_ASSERT(!credentials_types.empty()); messages.push_back("Hello"); - for (int sz = 1; sz < test_big_limit; sz *= 2) { + for (int sz = 1; sz <= test_big_limit; sz *= 32) { grpc::string big_msg; for (int i = 0; i < sz * 1024; i++) { char c = 'a' + (i % 26); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 7137a91ad9..7f5d6f9740 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -198,10 +198,7 @@ class TestScenario { void Log() const; bool use_proxy; bool inproc; - // Although the below grpc::string is logically const, we can't declare - // them const because of a limitation in the way old compilers (e.g., gcc-4.4) - // manage vector insertion using a copy constructor - grpc::string credentials_type; + const grpc::string credentials_type; }; static std::ostream& operator<<(std::ostream& out, @@ -1673,6 +1670,34 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { kTestCredsPluginErrorMsg); } +TEST_P(SecureEnd2endTest, CompositeCallCreds) { + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + const char kMetadataKey1[] = "call-creds-key1"; + const char kMetadataKey2[] = "call-creds-key2"; + const char kMetadataVal1[] = "call-creds-val1"; + const char kMetadataVal2[] = "call-creds-val2"; + + context.set_credentials(CompositeCallCredentials( + MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>( + new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, true, + true))), + MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>( + new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, true, + true))))); + request.set_message("Hello"); + request.mutable_param()->set_echo_metadata(true); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_TRUE(s.ok()); + EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), + kMetadataKey1, kMetadataVal1)); + EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(), + kMetadataKey2, kMetadataVal2)); +} + TEST_P(SecureEnd2endTest, ClientAuthContext) { ResetStub(); EchoRequest request; diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 04502e3e7f..b37452deb5 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -145,7 +145,7 @@ class GenericEnd2endTest : public ::testing::Test { if (check_deadline) { EXPECT_TRUE(gpr_time_similar(deadline, srv_ctx.raw_deadline(), - gpr_time_from_millis(100, GPR_TIMESPAN))); + gpr_time_from_millis(1000, GPR_TIMESPAN))); } ByteBuffer recv_buffer; diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 77ed155292..f73a9c1791 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -368,8 +368,9 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc_fake_resolver_response_generator_unref(response_generator_); } - void ResetStub() { + void ResetStub(int fallback_timeout = 0) { ChannelArguments args; + args.SetGrpclbFallbackTimeout(fallback_timeout); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_); std::ostringstream uri; @@ -470,10 +471,10 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc_exec_ctx_finish(&exec_ctx); } - const std::vector<int> GetBackendPorts() const { + const std::vector<int> GetBackendPorts(const size_t start_index = 0) const { std::vector<int> backend_ports; - for (const auto& bs : backend_servers_) { - backend_ports.push_back(bs.port_); + for (size_t i = start_index; i < backend_servers_.size(); ++i) { + backend_ports.push_back(backend_servers_[i].port_); } return backend_ports; } @@ -642,6 +643,177 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, Fallback) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const size_t kNumBackendInResolution = backends_.size() / 2; + + ResetStub(kFallbackTimeoutMs); + std::vector<AddressData> addresses; + addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + for (size_t i = 0; i < kNumBackendInResolution; ++i) { + addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + } + SetNextResolution(addresses); + + // Send non-empty serverlist only after kServerlistDelayMs. + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumBackendInResolution /* start_index */), {}), + kServerlistDelayMs); + + // Wait until all the fallback backends are reachable. + for (size_t i = 0; i < kNumBackendInResolution; ++i) { + WaitForBackend(i); + } + + // The first request. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(kNumBackendInResolution); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + + // Fallback is used: each backend returned by the resolver should have + // gotten one request. + for (size_t i = 0; i < kNumBackendInResolution; ++i) { + EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + } + for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + } + + // Wait until the serverlist reception has been processed and all backends + // in the serverlist are reachable. + for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { + WaitForBackend(i); + } + + // Send out the second request. + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(backends_.size() - kNumBackendInResolution); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + + // Serverlist is used: each backend returned by the balancer should + // have gotten one request. + for (size_t i = 0; i < kNumBackendInResolution; ++i) { + EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + } + for (size_t i = kNumBackendInResolution; 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 a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); +} + +TEST_F(SingleBalancerTest, FallbackUpdate) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const size_t kNumBackendInResolution = backends_.size() / 3; + const size_t kNumBackendInResolutionUpdate = backends_.size() / 3; + + ResetStub(kFallbackTimeoutMs); + std::vector<AddressData> addresses; + addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + for (size_t i = 0; i < kNumBackendInResolution; ++i) { + addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + } + SetNextResolution(addresses); + + // Send non-empty serverlist only after kServerlistDelayMs. + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumBackendInResolution + + kNumBackendInResolutionUpdate /* start_index */), + {}), + kServerlistDelayMs); + + // Wait until all the fallback backends are reachable. + for (size_t i = 0; i < kNumBackendInResolution; ++i) { + WaitForBackend(i); + } + + // The first request. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(kNumBackendInResolution); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + + // Fallback is used: each backend returned by the resolver should have + // gotten one request. + for (size_t i = 0; i < kNumBackendInResolution; ++i) { + EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + } + for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + } + + addresses.clear(); + addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + for (size_t i = kNumBackendInResolution; + i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + } + SetNextResolution(addresses); + + // Wait until the resolution update has been processed and all the new + // fallback backends are reachable. + for (size_t i = kNumBackendInResolution; + i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + WaitForBackend(i); + } + + // Send out the second request. + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(kNumBackendInResolutionUpdate); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + + // The resolution update is used: each backend in the resolution update should + // have gotten one request. + for (size_t i = 0; i < kNumBackendInResolution; ++i) { + EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + } + for (size_t i = kNumBackendInResolution; + i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + } + for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + i < backends_.size(); ++i) { + EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + } + + // Wait until the serverlist reception has been processed and all backends + // in the serverlist are reachable. + for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + i < backends_.size(); ++i) { + WaitForBackend(i); + } + + // Send out the third request. + gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); + CheckRpcSendOk(backends_.size() - kNumBackendInResolution - + kNumBackendInResolutionUpdate); + gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); + + // Serverlist is used: each backend returned by the balancer should + // have gotten one request. + for (size_t i = 0; + i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + } + for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + 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 a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); +} + TEST_F(SingleBalancerTest, BackendsRestart) { const size_t kNumRpcsPerAddress = 100; ScheduleResponseForBalancer( diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc index 9cc5a8168b..c6d3600be8 100644 --- a/test/cpp/interop/stress_test.cc +++ b/test/cpp/interop/stress_test.cc @@ -257,6 +257,7 @@ int main(int argc, char** argv) { gpr_log(GPR_INFO, "Starting test(s).."); std::vector<std::thread> test_threads; + std::vector<std::unique_ptr<StressTestInteropClient>> clients; // Create and start the test threads. // Note that: @@ -282,9 +283,9 @@ int main(int argc, char** argv) { // Create stub(s) for each channel for (int stub_idx = 0; stub_idx < FLAGS_num_stubs_per_channel; stub_idx++) { - StressTestInteropClient* client = new StressTestInteropClient( + clients.emplace_back(new StressTestInteropClient( ++thread_idx, *it, channel, test_selector, FLAGS_test_duration_secs, - FLAGS_sleep_duration_ms, FLAGS_do_not_abort_on_transient_failures); + FLAGS_sleep_duration_ms, FLAGS_do_not_abort_on_transient_failures)); bool is_already_created = false; // QpsGauge name @@ -293,7 +294,7 @@ int main(int argc, char** argv) { server_idx, channel_idx, stub_idx); test_threads.emplace_back(std::thread( - &StressTestInteropClient::MainLoop, client, + &StressTestInteropClient::MainLoop, clients.back().get(), metrics_service.CreateQpsGauge(buffer, &is_already_created))); // The QpsGauge should not have been already created diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index cadc9b2a11..cf9a42e8c6 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -554,7 +554,7 @@ static void BM_IsolatedFilter(benchmark::State &state) { grpc_exec_ctx_flush(&exec_ctx); grpc_call_stack *call_stack = static_cast<grpc_call_stack *>( gpr_zalloc(channel_stack->call_stack_size)); - gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + grpc_millis deadline = GRPC_MILLIS_INF_FUTURE; gpr_timespec start_time = gpr_now(GPR_CLOCK_MONOTONIC); grpc_slice method = grpc_slice_from_static_string("/foo/bar"); grpc_call_final_info final_info; diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 070034fe33..6f9dee7822 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -321,7 +321,7 @@ static void BM_StreamCreateSendInitialMetadataDestroy(benchmark::State &state) { grpc_metadata_batch b; grpc_metadata_batch_init(&b); - b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + b.deadline = GRPC_MILLIS_INF_FUTURE; std::vector<grpc_mdelem> elems = Metadata::GetElems(f.exec_ctx()); std::vector<grpc_linked_mdelem> storage(elems.size()); for (size_t i = 0; i < elems.size(); i++) { @@ -410,7 +410,7 @@ static void BM_TransportStreamSend(benchmark::State &state) { grpc_metadata_batch b; grpc_metadata_batch_init(&b); - b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + b.deadline = GRPC_MILLIS_INF_FUTURE; std::vector<grpc_mdelem> elems = RepresentativeClientInitialMetadata::GetElems(f.exec_ctx()); std::vector<grpc_linked_mdelem> storage(elems.size()); @@ -542,7 +542,7 @@ static void BM_TransportStreamRecv(benchmark::State &state) { grpc_metadata_batch_init(&b); grpc_metadata_batch b_recv; grpc_metadata_batch_init(&b_recv); - b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + b.deadline = GRPC_MILLIS_INF_FUTURE; std::vector<grpc_mdelem> elems = RepresentativeClientInitialMetadata::GetElems(f.exec_ctx()); std::vector<grpc_linked_mdelem> storage(elems.size()); diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 5c9405f583..57a69acf01 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -73,9 +73,9 @@ static void cq_done_cb(grpc_exec_ctx* exec_ctx, void* done_arg, /* Queues a completion tag if deadline is > 0. * Does nothing if deadline is 0 (i.e gpr_time_0(GPR_CLOCK_MONOTONIC)) */ static grpc_error* pollset_work(grpc_exec_ctx* exec_ctx, grpc_pollset* ps, - grpc_pollset_worker** worker, gpr_timespec now, - gpr_timespec deadline) { - if (gpr_time_cmp(deadline, gpr_time_0(GPR_CLOCK_MONOTONIC)) == 0) { + grpc_pollset_worker** worker, + grpc_millis deadline) { + if (deadline == 0) { gpr_log(GPR_DEBUG, "no-op"); return GRPC_ERROR_NONE; } diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc index bd5f02e172..56b80dfcf6 100644 --- a/test/cpp/microbenchmarks/bm_error.cc +++ b/test/cpp/microbenchmarks/bm_error.cc @@ -159,39 +159,39 @@ BENCHMARK(BM_ErrorGetPresentInt); // Fixtures for tests: generate different kinds of errors class ErrorNone { public: - gpr_timespec deadline() const { return deadline_; } + grpc_millis deadline() const { return deadline_; } grpc_error* error() const { return GRPC_ERROR_NONE; } private: - const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC); + const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE; }; class ErrorCancelled { public: - gpr_timespec deadline() const { return deadline_; } + grpc_millis deadline() const { return deadline_; } grpc_error* error() const { return GRPC_ERROR_CANCELLED; } private: - const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC); + const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE; }; class SimpleError { public: - gpr_timespec deadline() const { return deadline_; } + grpc_millis deadline() const { return deadline_; } grpc_error* error() const { return error_.get(); } private: - const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC); + const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE; ErrorPtr error_{GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error")}; }; class ErrorWithGrpcStatus { public: - gpr_timespec deadline() const { return deadline_; } + grpc_millis deadline() const { return deadline_; } grpc_error* error() const { return error_.get(); } private: - const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC); + const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE; ErrorPtr error_{grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED)}; @@ -199,11 +199,11 @@ class ErrorWithGrpcStatus { class ErrorWithHttpError { public: - gpr_timespec deadline() const { return deadline_; } + grpc_millis deadline() const { return deadline_; } grpc_error* error() const { return error_.get(); } private: - const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC); + const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE; ErrorPtr error_{grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_COMPRESSION_ERROR)}; @@ -211,11 +211,11 @@ class ErrorWithHttpError { class ErrorWithNestedGrpcStatus { public: - gpr_timespec deadline() const { return deadline_; } + grpc_millis deadline() const { return deadline_; } grpc_error* error() const { return error_.get(); } private: - const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC); + const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE; ErrorPtr nested_error_{grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNIMPLEMENTED)}; @@ -248,12 +248,14 @@ template <class Fixture> static void BM_ErrorGetStatus(benchmark::State& state) { TrackCounters track_counters; Fixture fixture; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; while (state.KeepRunning()) { grpc_status_code status; grpc_slice slice; - grpc_error_get_status(fixture.error(), fixture.deadline(), &status, &slice, - NULL); + grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(), + &status, &slice, NULL); } + grpc_exec_ctx_finish(&exec_ctx); track_counters.Finish(state); } @@ -261,11 +263,13 @@ template <class Fixture> static void BM_ErrorGetStatusCode(benchmark::State& state) { TrackCounters track_counters; Fixture fixture; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; while (state.KeepRunning()) { grpc_status_code status; - grpc_error_get_status(fixture.error(), fixture.deadline(), &status, NULL, - NULL); + grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(), + &status, NULL, NULL); } + grpc_exec_ctx_finish(&exec_ctx); track_counters.Finish(state); } @@ -273,11 +277,13 @@ template <class Fixture> static void BM_ErrorHttpError(benchmark::State& state) { TrackCounters track_counters; Fixture fixture; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; while (state.KeepRunning()) { grpc_http2_error_code error; - grpc_error_get_status(fixture.error(), fixture.deadline(), NULL, NULL, - &error); + grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(), NULL, + NULL, &error); } + grpc_exec_ctx_finish(&exec_ctx); track_counters.Finish(state); } diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc index 2656566a50..adb5e6657f 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc @@ -29,6 +29,7 @@ extern "C" { #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/ext/transport/chttp2/transport/internal.h" +#include "src/core/lib/iomgr/timer_manager.h" #include "test/core/util/trickle_endpoint.h" } @@ -45,6 +46,22 @@ DEFINE_int32(warmup_max_time_seconds, 10, namespace grpc { namespace testing { +gpr_atm g_now_us = 0; + +static gpr_timespec fake_now(gpr_clock_type clock_type) { + gpr_timespec t; + gpr_atm now = gpr_atm_no_barrier_load(&g_now_us); + t.tv_sec = now / GPR_US_PER_SEC; + t.tv_nsec = (now % GPR_US_PER_SEC) * GPR_NS_PER_US; + t.clock_type = clock_type; + return t; +} + +static void inc_time() { + gpr_atm_no_barrier_fetch_add(&g_now_us, 100); + grpc_timer_manager_tick(); +} + static void* tag(intptr_t x) { return reinterpret_cast<void*>(x); } template <class A0> @@ -158,6 +175,7 @@ class TrickledCHTTP2 : public EndpointPairFixture { void Step(bool update_stats) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + inc_time(); size_t client_backlog = grpc_trickle_endpoint_trickle(&exec_ctx, endpoint_pair_.client); size_t server_backlog = @@ -212,9 +230,8 @@ static void TrickleCQNext(TrickledCHTTP2* fixture, void** t, bool* ok, int64_t iteration) { while (true) { fixture->Log(iteration); - switch (fixture->cq()->AsyncNext( - t, ok, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_micros(100, GPR_TIMESPAN)))) { + switch ( + fixture->cq()->AsyncNext(t, ok, gpr_inf_past(GPR_CLOCK_MONOTONIC))) { case CompletionQueue::TIMEOUT: fixture->Step(iteration != -1); break; @@ -289,9 +306,15 @@ static void BM_PumpStreamServerToClient_Trickle(benchmark::State& state) { inner_loop(false); } response_rw.Finish(Status::OK, tag(1)); - need_tags = (1 << 0) | (1 << 1); + grpc::Status status; + request_rw->Finish(&status, tag(2)); + need_tags = (1 << 0) | (1 << 1) | (1 << 2); while (need_tags) { TrickleCQNext(fixture.get(), &t, &ok, -1); + if (t == tag(0) && ok) { + request_rw->Read(&recv_response, tag(0)); + continue; + } int i = (int)(intptr_t)t; GPR_ASSERT(need_tags & (1 << i)); need_tags &= ~(1 << i); @@ -419,8 +442,12 @@ BENCHMARK(BM_PumpUnbalancedUnary_Trickle)->Apply(UnaryTrickleArgs); } } +extern "C" gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); + 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(); } diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc index 1fc1f2f83b..eab1e89480 100644 --- a/test/cpp/microbenchmarks/bm_pollset.cc +++ b/test/cpp/microbenchmarks/bm_pollset.cc @@ -117,11 +117,9 @@ static void BM_PollEmptyPollset(benchmark::State& state) { gpr_mu* mu; grpc_pollset_init(ps, &mu); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - gpr_timespec now = gpr_time_0(GPR_CLOCK_MONOTONIC); - gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC); gpr_mu_lock(mu); while (state.KeepRunning()) { - GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, NULL, now, deadline)); + GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, NULL, 0)); } grpc_closure shutdown_ps_closure; GRPC_CLOSURE_INIT(&shutdown_ps_closure, shutdown_ps, ps, @@ -223,8 +221,6 @@ static void BM_SingleThreadPollOneFd(benchmark::State& state) { gpr_mu* mu; grpc_pollset_init(ps, &mu); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - gpr_timespec now = gpr_time_0(GPR_CLOCK_MONOTONIC); - gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); grpc_wakeup_fd wakeup_fd; GRPC_ERROR_UNREF(grpc_wakeup_fd_init(&wakeup_fd)); grpc_fd* wakeup = grpc_fd_create(wakeup_fd.read_fd, "wakeup_read"); @@ -245,7 +241,8 @@ static void BM_SingleThreadPollOneFd(benchmark::State& state) { grpc_fd_notify_on_read(&exec_ctx, wakeup, continue_closure); gpr_mu_lock(mu); while (!done) { - GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, NULL, now, deadline)); + GRPC_ERROR_UNREF( + grpc_pollset_work(&exec_ctx, ps, NULL, GRPC_MILLIS_INF_FUTURE)); } grpc_fd_orphan(&exec_ctx, wakeup, NULL, NULL, false /* already_closed */, "done"); diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index ecd28c3f8a..a7f8504505 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -85,7 +85,7 @@ class FullstackFixture : public BaseFixture { } virtual ~FullstackFixture() { - server_->Shutdown(); + server_->Shutdown(gpr_inf_past(GPR_CLOCK_MONOTONIC)); cq_->Shutdown(); void* tag; bool ok; @@ -212,7 +212,7 @@ class EndpointPairFixture : public BaseFixture { } virtual ~EndpointPairFixture() { - server_->Shutdown(); + server_->Shutdown(gpr_inf_past(GPR_CLOCK_MONOTONIC)); cq_->Shutdown(); void* tag; bool ok; diff --git a/test/cpp/naming/README.md b/test/cpp/naming/README.md new file mode 100644 index 0000000000..e33184620c --- /dev/null +++ b/test/cpp/naming/README.md @@ -0,0 +1,43 @@ +# 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_dns_private_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/create_private_dns_zone.sh b/test/cpp/naming/create_private_dns_zone.sh new file mode 100755 index 0000000000..3d7520b90a --- /dev/null +++ b/test/cpp/naming/create_private_dns_zone.sh @@ -0,0 +1,27 @@ +#!/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 alpha dns managed-zones create \ + resolver-tests-version-1-grpctestingexp-zone-id \ + --dns-name=resolver-tests-version-1.grpctestingexp. \ + --description="GCE-DNS-private-zone-for-GRPC-testing" \ + --visibility=private \ + --networks=default diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index 3a51fef7a0..91718156e9 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -24,6 +24,12 @@ 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) @@ -33,21 +39,107 @@ 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): + out = [] + for test_case in resolver_component_data['resolver_component_tests']: + if test_case['record_to_resolve'] in records_to_skip: + continue + 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 ''), + }) + return out + def main(): resolver_component_data = '' with open('test/cpp/naming/resolver_test_record_groups.yaml') as f: resolver_component_data = yaml.load(f) json = { - 'resolver_component_test_cases': [ - { - 'target_name': _append_zone_name(test_case['record_to_resolve'], - resolver_component_data['resolver_component_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 ''), - } for test_case in resolver_component_data['resolver_component_tests'] - ], + '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, []), 'targets': [ { 'name': 'resolver_component_test' + unsecure_build_config_suffix, diff --git a/test/cpp/naming/private_dns_zone_init.sh b/test/cpp/naming/private_dns_zone_init.sh new file mode 100755 index 0000000000..4eaf750ab7 --- /dev/null +++ b/test/cpp/naming/private_dns_zone_init.sh @@ -0,0 +1,215 @@ +#!/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-1-grpctestingexp-zone-id + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=_grpclb._tcp.srv-ipv4-single-target.resolver-tests-version-1.grpctestingexp. \ + --type=SRV \ + --ttl=2100 \ + "0 0 1234 ipv4-single-target.resolver-tests-version-1.grpctestingexp." + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv4-single-target.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=_grpclb._tcp.srv-ipv4-multi-target.resolver-tests-version-1.grpctestingexp. \ + --type=SRV \ + --ttl=2100 \ + "0 0 1234 ipv4-multi-target.resolver-tests-version-1.grpctestingexp." + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv4-multi-target.resolver-tests-version-1.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-1-grpctestingexp-zone-id \ + --name=_grpclb._tcp.srv-ipv6-single-target.resolver-tests-version-1.grpctestingexp. \ + --type=SRV \ + --ttl=2100 \ + "0 0 1234 ipv6-single-target.resolver-tests-version-1.grpctestingexp." + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv6-single-target.resolver-tests-version-1.grpctestingexp. \ + --type=AAAA \ + --ttl=2100 \ + "2607:f8b0:400a:801::1001" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=_grpclb._tcp.srv-ipv6-multi-target.resolver-tests-version-1.grpctestingexp. \ + --type=SRV \ + --ttl=2100 \ + "0 0 1234 ipv6-multi-target.resolver-tests-version-1.grpctestingexp." + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv6-multi-target.resolver-tests-version-1.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-1-grpctestingexp-zone-id \ + --name=srv-ipv4-simple-service-config.resolver-tests-version-1.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-1-grpctestingexp-zone-id \ + --name=ipv4-simple-service-config.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=_grpclb._tcp.srv-ipv4-simple-service-config.resolver-tests-version-1.grpctestingexp. \ + --type=SRV \ + --ttl=2100 \ + "0 0 1234 ipv4-simple-service-config.resolver-tests-version-1.grpctestingexp." + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv4-no-srv-simple-service-config.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv4-no-srv-simple-service-config.resolver-tests-version-1.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-1-grpctestingexp-zone-id \ + --name=ipv4-no-config-for-cpp.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv4-no-config-for-cpp.resolver-tests-version-1.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-1-grpctestingexp-zone-id \ + --name=ipv4-cpp-config-has-zero-percentage.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv4-cpp-config-has-zero-percentage.resolver-tests-version-1.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-1-grpctestingexp-zone-id \ + --name=ipv4-second-language-is-cpp.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv4-second-language-is-cpp.resolver-tests-version-1.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-1-grpctestingexp-zone-id \ + --name=ipv4-config-with-percentages.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=ipv4-config-with-percentages.resolver-tests-version-1.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-1-grpctestingexp-zone-id \ + --name=_grpclb._tcp.srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp. \ + --type=SRV \ + --ttl=2100 \ + "0 0 1234 balancer-for-ipv4-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp." + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=balancer-for-ipv4-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp. \ + --type=A \ + --ttl=2100 \ + "1.2.3.4" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=_grpclb._tcp.srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp. \ + --type=SRV \ + --ttl=2100 \ + "0 0 1234 balancer-for-ipv6-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp." + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=balancer-for-ipv6-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp. \ + --type=AAAA \ + --ttl=2100 \ + "2607:f8b0:400a:801::1002" + +gcloud dns record-sets transaction add \ + -z=resolver-tests-version-1-grpctestingexp-zone-id \ + --name=srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp. \ + --type=AAAA \ + --ttl=2100 \ + "2607:f8b0:400a:801::1002" + +gcloud dns record-sets transaction describe -z=resolver-tests-version-1-grpctestingexp-zone-id +gcloud dns record-sets transaction execute -z=resolver-tests-version-1-grpctestingexp-zone-id +gcloud dns record-sets list -z=resolver-tests-version-1-grpctestingexp-zone-id diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index cc851ca9d5..7d0371bea4 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -199,10 +199,10 @@ void PollPollsetUntilRequestDone(ArgsStruct *args) { grpc_pollset_worker *worker = NULL; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(&exec_ctx, args->pollset, &worker, - gpr_now(GPR_CLOCK_REALTIME), NSecondDeadline(1))); + GRPC_LOG_IF_ERROR("pollset_work", + grpc_pollset_work(&exec_ctx, args->pollset, &worker, + grpc_timespec_to_millis_round_up( + NSecondDeadline(1)))); gpr_mu_unlock(args->mu); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/cpp/naming/resolver_component_tests_runner.sh b/test/cpp/naming/resolver_component_tests_runner.sh index cf71c9dcf9..407db5ed66 100755 --- a/test/cpp/naming/resolver_component_tests_runner.sh +++ b/test/cpp/naming/resolver_component_tests_runner.sh @@ -73,7 +73,7 @@ EXIT_CODE=0 # in the resolver. $FLAGS_test_bin_path \ - --target_name='srv-ipv4-single-target.resolver-tests.grpctestingexp.' \ + --target_name='srv-ipv4-single-target.resolver-tests-version-1.grpctestingexp.' \ --expected_addrs='1.2.3.4:1234,True' \ --expected_chosen_service_config='' \ --expected_lb_policy='' \ @@ -81,7 +81,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='srv-ipv4-multi-target.resolver-tests.grpctestingexp.' \ + --target_name='srv-ipv4-multi-target.resolver-tests-version-1.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='' \ @@ -89,7 +89,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='srv-ipv6-single-target.resolver-tests.grpctestingexp.' \ + --target_name='srv-ipv6-single-target.resolver-tests-version-1.grpctestingexp.' \ --expected_addrs='[2607:f8b0:400a:801::1001]:1234,True' \ --expected_chosen_service_config='' \ --expected_lb_policy='' \ @@ -97,7 +97,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='srv-ipv6-multi-target.resolver-tests.grpctestingexp.' \ + --target_name='srv-ipv6-multi-target.resolver-tests-version-1.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='' \ @@ -105,7 +105,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='srv-ipv4-simple-service-config.resolver-tests.grpctestingexp.' \ + --target_name='srv-ipv4-simple-service-config.resolver-tests-version-1.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' \ @@ -113,7 +113,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='ipv4-no-srv-simple-service-config.resolver-tests.grpctestingexp.' \ + --target_name='ipv4-no-srv-simple-service-config.resolver-tests-version-1.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' \ @@ -121,7 +121,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='ipv4-no-config-for-cpp.resolver-tests.grpctestingexp.' \ + --target_name='ipv4-no-config-for-cpp.resolver-tests-version-1.grpctestingexp.' \ --expected_addrs='1.2.3.4:443,False' \ --expected_chosen_service_config='' \ --expected_lb_policy='' \ @@ -129,7 +129,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='ipv4-cpp-config-has-zero-percentage.resolver-tests.grpctestingexp.' \ + --target_name='ipv4-cpp-config-has-zero-percentage.resolver-tests-version-1.grpctestingexp.' \ --expected_addrs='1.2.3.4:443,False' \ --expected_chosen_service_config='' \ --expected_lb_policy='' \ @@ -137,7 +137,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='ipv4-second-language-is-cpp.resolver-tests.grpctestingexp.' \ + --target_name='ipv4-second-language-is-cpp.resolver-tests-version-1.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' \ @@ -145,7 +145,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='ipv4-config-with-percentages.resolver-tests.grpctestingexp.' \ + --target_name='ipv4-config-with-percentages.resolver-tests-version-1.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' \ @@ -153,7 +153,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='srv-ipv4-target-has-backend-and-balancer.resolver-tests.grpctestingexp.' \ + --target_name='srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp.' \ --expected_addrs='1.2.3.4:1234,True;1.2.3.4:443,False' \ --expected_chosen_service_config='' \ --expected_lb_policy='' \ @@ -161,7 +161,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='srv-ipv6-target-has-backend-and-balancer.resolver-tests.grpctestingexp.' \ + --target_name='srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-1.grpctestingexp.' \ --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False' \ --expected_chosen_service_config='' \ --expected_lb_policy='' \ @@ -169,7 +169,7 @@ $FLAGS_test_bin_path \ wait $! || EXIT_CODE=1 $FLAGS_test_bin_path \ - --target_name='ipv4-config-causing-fallback-to-tcp.resolver-tests.grpctestingexp.' \ + --target_name='ipv4-config-causing-fallback-to-tcp.resolver-tests-version-1.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='' \ diff --git a/test/cpp/naming/resolver_gce_integration_tests_runner.sh b/test/cpp/naming/resolver_gce_integration_tests_runner.sh new file mode 100755 index 0000000000..b20d18d9d1 --- /dev/null +++ b/test/cpp/naming/resolver_gce_integration_tests_runner.sh @@ -0,0 +1,359 @@ +#!/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-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A ipv4-single-target.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig A ipv4-single-target.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig SRV _grpclb._tcp.srv-ipv4-multi-target.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A ipv4-multi-target.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig A ipv4-multi-target.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig SRV _grpclb._tcp.srv-ipv6-single-target.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig AAAA ipv6-single-target.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig AAAA ipv6-single-target.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig SRV _grpclb._tcp.srv-ipv6-multi-target.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig AAAA ipv6-multi-target.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig AAAA ipv6-multi-target.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig TXT srv-ipv4-simple-service-config.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig TXT srv-ipv4-simple-service-config.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A ipv4-simple-service-config.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig A ipv4-simple-service-config.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig SRV _grpclb._tcp.srv-ipv4-simple-service-config.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A ipv4-no-srv-simple-service-config.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig TXT ipv4-no-srv-simple-service-config.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig TXT ipv4-no-srv-simple-service-config.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A ipv4-no-config-for-cpp.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig TXT ipv4-no-config-for-cpp.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig TXT ipv4-no-config-for-cpp.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A ipv4-cpp-config-has-zero-percentage.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig TXT ipv4-cpp-config-has-zero-percentage.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig TXT ipv4-cpp-config-has-zero-percentage.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A ipv4-second-language-is-cpp.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig TXT ipv4-second-language-is-cpp.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig TXT ipv4-second-language-is-cpp.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A ipv4-config-with-percentages.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig A ipv4-config-with-percentages.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig TXT ipv4-config-with-percentages.resolver-tests-version-1.grpctestingexp. | grep 'ANSWER SECTION' || ONE_FAILED=1 +if [[ "$ONE_FAILED" != 0 ]]; then + echo "Sanity check: dig TXT ipv4-config-with-percentages.resolver-tests-version-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig SRV _grpclb._tcp.srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A balancer-for-ipv4-has-backend-and-balancer.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig A srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig SRV _grpclb._tcp.srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig AAAA balancer-for-ipv6-has-backend-and-balancer.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + exit 1 +fi + +ONE_FAILED=0 +dig AAAA srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-1.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-1.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-1.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-1.grpctestingexp. FAILED" + EXIT_CODE=1 +fi + +ONE_FAILED=0 +bins/$CONFIG/resolver_component_test \ + --target_name='srv-ipv4-multi-target.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + EXIT_CODE=1 +fi + +ONE_FAILED=0 +bins/$CONFIG/resolver_component_test \ + --target_name='srv-ipv6-single-target.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + EXIT_CODE=1 +fi + +ONE_FAILED=0 +bins/$CONFIG/resolver_component_test \ + --target_name='srv-ipv6-multi-target.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + EXIT_CODE=1 +fi + +ONE_FAILED=0 +bins/$CONFIG/resolver_component_test \ + --target_name='srv-ipv4-simple-service-config.resolver-tests-version-1.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-1.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-1.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-1.grpctestingexp. FAILED" + EXIT_CODE=1 +fi + +ONE_FAILED=0 +bins/$CONFIG/resolver_component_test \ + --target_name='ipv4-no-config-for-cpp.resolver-tests-version-1.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-1.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-1.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-1.grpctestingexp. FAILED" + EXIT_CODE=1 +fi + +ONE_FAILED=0 +bins/$CONFIG/resolver_component_test \ + --target_name='ipv4-second-language-is-cpp.resolver-tests-version-1.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-1.grpctestingexp. FAILED" + EXIT_CODE=1 +fi + +ONE_FAILED=0 +bins/$CONFIG/resolver_component_test \ + --target_name='ipv4-config-with-percentages.resolver-tests-version-1.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-1.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-1.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-1.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-1.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-1.grpctestingexp. FAILED" + EXIT_CODE=1 +fi + +exit $EXIT_CODE diff --git a/test/cpp/naming/resolver_test_record_groups.yaml b/test/cpp/naming/resolver_test_record_groups.yaml index 33d774ca70..2b3204335c 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -1,4 +1,4 @@ -resolver_component_tests_common_zone_name: resolver-tests.grpctestingexp. +resolver_tests_common_zone_name: resolver-tests-version-1.grpctestingexp. resolver_component_tests: - expected_addrs: - {address: '1.2.3.4:1234', is_balancer: true} diff --git a/test/cpp/naming/test_dns_server.py b/test/cpp/naming/test_dns_server.py index 9d4b89cffb..9f42f65ee6 100755 --- a/test/cpp/naming/test_dns_server.py +++ b/test/cpp/naming/test_dns_server.py @@ -66,7 +66,7 @@ def start_local_dns_server(args): with open(args.records_config_path) as config: test_records_config = yaml.load(config) - common_zone_name = test_records_config['resolver_component_tests_common_zone_name'] + common_zone_name = test_records_config['resolver_tests_common_zone_name'] for group in test_records_config['resolver_component_tests']: for name in group['records'].keys(): for record in group['records'][name]: diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index a3ccbcf576..8575fe5a05 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -77,7 +77,7 @@ print yaml.dump({ 'defaults': 'boringssl', 'cpu_cost': guess_cpu(scenario_json, False), 'exclude_configs': ['tsan', 'asan'], - 'timeout_seconds': 6*60, + 'timeout_seconds': 2*60, 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []) } for scenario_json in scenario_config.CXXLanguage().scenarios() @@ -95,7 +95,7 @@ print yaml.dump({ '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': 6*60, + 'timeout_seconds': 2*60, 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []) } for scenario_json in scenario_config.CXXLanguage().scenarios() diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index bb6f878020..cd6084ac6d 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -58,6 +58,11 @@ DEFINE_string(protofiles, "", "Name of the proto file."); DEFINE_bool(binary_input, false, "Input in binary format"); DEFINE_bool(binary_output, false, "Output in binary format"); DEFINE_string(infile, "", "Input file (default is stdin)"); +DEFINE_bool(batch, false, + "Input contains multiple requests. Please do not use this to send " + "more than a few RPCs. gRPC CLI has very different performance " + "characteristics compared with normal RPC calls which make it " + "unsuitable for loadtesting or significant production traffic."); namespace { @@ -460,12 +465,17 @@ bool GrpcTool::CallMethod(int argc, const char** argv, return false; } + if (argc == 3) { + request_text = argv[2]; + } + if (parser->IsStreaming(method_name, true /* is_request */)) { std::istream* input_stream; std::ifstream input_file; - if (argc == 3) { - request_text = argv[2]; + if (FLAGS_batch) { + fprintf(stderr, "Batch mode for streaming RPC is not supported.\n"); + return false; } std::multimap<grpc::string, grpc::string> client_metadata; @@ -549,8 +559,115 @@ bool GrpcTool::CallMethod(int argc, const char** argv, } } else { // parser->IsStreaming(method_name, true /* is_request */) + if (FLAGS_batch) { + if (parser->IsStreaming(method_name, false /* is_request */)) { + fprintf(stderr, "Batch mode for streaming RPC is not supported.\n"); + return false; + } + + std::istream* input_stream; + std::ifstream input_file; + + if (FLAGS_infile.empty()) { + if (isatty(fileno(stdin))) { + print_mode = true; + fprintf(stderr, "reading request messages from stdin...\n"); + } + input_stream = &std::cin; + } else { + input_file.open(FLAGS_infile, std::ios::in | std::ios::binary); + input_stream = &input_file; + } + + std::multimap<grpc::string, grpc::string> client_metadata; + ParseMetadataFlag(&client_metadata); + if (print_mode) { + PrintMetadata(client_metadata, "Sending client initial metadata:"); + } + + std::stringstream request_ss; + grpc::string line; + while (!request_text.empty() || + (!input_stream->eof() && getline(*input_stream, line))) { + if (!request_text.empty()) { + if (FLAGS_binary_input) { + serialized_request_proto = request_text; + request_text.clear(); + } else { + serialized_request_proto = parser->GetSerializedProtoFromMethod( + method_name, request_text, true /* is_request */); + request_text.clear(); + if (parser->HasError()) { + if (print_mode) { + fprintf(stderr, "Failed to parse request.\n"); + } + continue; + } + } + + grpc::string serialized_response_proto; + std::multimap<grpc::string_ref, grpc::string_ref> + server_initial_metadata, server_trailing_metadata; + CliCall call(channel, formatted_method_name, client_metadata); + call.Write(serialized_request_proto); + call.WritesDone(); + if (!call.Read(&serialized_response_proto, + &server_initial_metadata)) { + fprintf(stderr, "Failed to read response.\n"); + } + Status status = call.Finish(&server_trailing_metadata); + + if (status.ok()) { + if (print_mode) { + fprintf(stderr, "Rpc succeeded with OK status.\n"); + PrintMetadata(server_initial_metadata, + "Received initial metadata from server:"); + PrintMetadata(server_trailing_metadata, + "Received trailing metadata from server:"); + } + + if (FLAGS_binary_output) { + if (!callback(serialized_response_proto)) { + break; + } + } else { + grpc::string response_text = parser->GetTextFormatFromMethod( + method_name, serialized_response_proto, + false /* is_request */); + if (parser->HasError() && print_mode) { + fprintf(stderr, "Failed to parse response.\n"); + } else { + if (!callback(response_text)) { + break; + } + } + } + } else { + if (print_mode) { + fprintf(stderr, + "Rpc failed with status code %d, error message: %s\n", + status.error_code(), status.error_message().c_str()); + } + } + } else { + if (line.length() == 0) { + request_text = request_ss.str(); + request_ss.str(grpc::string()); + request_ss.clear(); + } else { + request_ss << line << ' '; + } + } + } + + if (input_file.is_open()) { + input_file.close(); + } + + return true; + } + if (argc == 3) { - request_text = argv[2]; if (!FLAGS_infile.empty()) { fprintf(stderr, "warning: request given in argv, ignoring --infile\n"); } @@ -571,9 +688,7 @@ bool GrpcTool::CallMethod(int argc, const char** argv, if (FLAGS_binary_input) { serialized_request_proto = request_text; - // formatted_method_name = method_name; } else { - // formatted_method_name = parser->GetFormattedMethodName(method_name); serialized_request_proto = parser->GetSerializedProtoFromMethod( method_name, request_text, true /* is_request */); if (parser->HasError()) { diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index dd00581f2b..d0b3d7b81b 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -84,6 +84,7 @@ namespace testing { DECLARE_bool(binary_input); DECLARE_bool(binary_output); DECLARE_bool(l); +DECLARE_bool(batch); namespace { @@ -399,6 +400,60 @@ TEST_F(GrpcToolTest, CallCommand) { ShutdownServer(); } +TEST_F(GrpcToolTest, CallCommandBatch) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "message: 'Hello0'"}; + + // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_batch = false; + + // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: + // "Hello2"\n" + EXPECT_TRUE(NULL != strstr(output_stream.str().c_str(), + "message: \"Hello0\"\nmessage: " + "\"Hello1\"\nmessage: \"Hello2\"\n")); + std::cin.rdbuf(orig); + ShutdownServer(); +} + +TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "message: 'Hello0'"}; + + // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss("message: 1\n\n message: 'Hello2'\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_batch = false; + + // Expected output: "message: "Hello0"\nmessage: "Hello2"\n" + EXPECT_TRUE(NULL != strstr(output_stream.str().c_str(), + "message: \"Hello0\"\nmessage: \"Hello2\"\n")); + std::cin.rdbuf(orig); + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommandRequestStream) { // Test input: grpc_cli call localhost:<port> RequestStream "message: // 'Hello0'" |