aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core
diff options
context:
space:
mode:
Diffstat (limited to 'test/core')
-rw-r--r--test/core/client_channel/lb_policies_test.c119
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.c2
-rw-r--r--test/core/end2end/goaway_server_test.c10
-rw-r--r--test/core/end2end/tests/connectivity.c10
-rw-r--r--test/core/end2end/tests/filter_latency.c30
-rw-r--r--test/core/end2end/tests/payload.c2
-rw-r--r--test/core/end2end/tests/resource_quota_server.c2
-rw-r--r--test/core/end2end/tests/simple_delayed_request.c19
-rw-r--r--test/core/handshake/client_ssl.c2
-rw-r--r--test/core/security/ssl_server_fuzzer.c24
-rw-r--r--test/core/support/backoff_test.c91
-rw-r--r--test/core/surface/server_chttp2_test.c5
-rw-r--r--test/core/util/port_posix.c14
-rw-r--r--test/core/util/test_config.c19
-rw-r--r--test/core/util/test_config.h3
15 files changed, 208 insertions, 144 deletions
diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c
index 95595d7c51..6e4058fc21 100644
--- a/test/core/client_channel/lb_policies_test.c
+++ b/test/core/client_channel/lb_policies_test.c
@@ -64,9 +64,11 @@ typedef struct servers_fixture {
} servers_fixture;
typedef struct request_sequences {
- size_t n;
- int *connections;
- int *connectivity_states;
+ size_t n; /* number of iterations */
+ int *connections; /* indexed by the interation number, value is the index of
+ the server it connected to or -1 if none */
+ int *connectivity_states; /* indexed by the interation number, value is the
+ client connectivity state */
} request_sequences;
typedef void (*verifier_fn)(const servers_fixture *, grpc_channel *,
@@ -481,7 +483,7 @@ void run_spec(const test_spec *spec) {
gpr_asprintf(&client_hostport, "ipv4:%s", servers_hostports_str);
arg_array[0].type = GRPC_ARG_INTEGER;
- arg_array[0].key = "grpc.testing.fixed_reconnect_backoff";
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
arg_array[0].value.integer = RETRY_TIMEOUT;
arg_array[1].type = GRPC_ARG_STRING;
arg_array[1].key = GRPC_ARG_LB_POLICY_NAME;
@@ -519,7 +521,7 @@ static grpc_channel *create_client(const servers_fixture *f) {
gpr_asprintf(&client_hostport, "ipv4:%s", servers_hostports_str);
arg_array[0].type = GRPC_ARG_INTEGER;
- arg_array[0].key = "grpc.testing.fixed_reconnect_backoff";
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
arg_array[0].value.integer = RETRY_TIMEOUT;
arg_array[1].type = GRPC_ARG_STRING;
arg_array[1].key = GRPC_ARG_LB_POLICY_NAME;
@@ -780,15 +782,17 @@ static void verify_total_carnage_round_robin(const servers_fixture *f,
}
}
- /* no server is ever available. The persistent state is TRANSIENT_FAILURE */
+ /* no server is ever available. The persistent state is TRANSIENT_FAILURE. May
+ * also be CONNECTING if, under load, this check took too long to run and some
+ * subchannel already transitioned to retrying. */
for (size_t i = 0; i < sequences->n; i++) {
const grpc_connectivity_state actual = sequences->connectivity_states[i];
- const grpc_connectivity_state expected = GRPC_CHANNEL_TRANSIENT_FAILURE;
- if (actual != expected) {
+ if (actual != GRPC_CHANNEL_TRANSIENT_FAILURE &&
+ actual != GRPC_CHANNEL_CONNECTING) {
gpr_log(GPR_ERROR,
- "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' "
- "at iteration #%d",
- grpc_connectivity_state_name(expected),
+ "CONNECTIVITY STATUS SEQUENCE FAILURE: expected "
+ "GRPC_CHANNEL_TRANSIENT_FAILURE or GRPC_CHANNEL_CONNECTING, got "
+ "'%s' at iteration #%d",
grpc_connectivity_state_name(actual), (int)i);
abort();
}
@@ -825,8 +829,7 @@ static void verify_partial_carnage_round_robin(
}
/* We can assert that the first client channel state should be READY, when all
- * servers were available; and that the last one should be TRANSIENT_FAILURE,
- * after all servers are gone. */
+ * servers were available */
grpc_connectivity_state actual = sequences->connectivity_states[0];
grpc_connectivity_state expected = GRPC_CHANNEL_READY;
if (actual != expected) {
@@ -838,17 +841,21 @@ static void verify_partial_carnage_round_robin(
abort();
}
+ /* ... and that the last one should be TRANSIENT_FAILURE, after all servers
+ * are gone. May also be CONNECTING if, under load, this check took too long
+ * to run and the subchannel already transitioned to retrying. */
actual = sequences->connectivity_states[num_iters - 1];
- expected = GRPC_CHANNEL_TRANSIENT_FAILURE;
- if (actual != expected) {
- gpr_log(GPR_ERROR,
- "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' "
- "at iteration #%d",
- grpc_connectivity_state_name(expected),
- grpc_connectivity_state_name(actual), (int)num_iters - 1);
- abort();
+ for (i = 0; i < sequences->n; i++) {
+ if (actual != GRPC_CHANNEL_TRANSIENT_FAILURE &&
+ actual != GRPC_CHANNEL_CONNECTING) {
+ gpr_log(GPR_ERROR,
+ "CONNECTIVITY STATUS SEQUENCE FAILURE: expected "
+ "GRPC_CHANNEL_TRANSIENT_FAILURE or GRPC_CHANNEL_CONNECTING, got "
+ "'%s' at iteration #%d",
+ grpc_connectivity_state_name(actual), (int)i);
+ abort();
+ }
}
-
gpr_free(expected_connection_sequence);
}
@@ -873,68 +880,21 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
grpc_channel *client,
const request_sequences *sequences,
const size_t num_iters) {
- int *expected_connection_sequence;
- size_t i, j, unique_seq_last_idx, unique_seq_first_idx;
- const size_t expected_seq_length = f->num_servers;
- int *seen_elements;
-
dump_array("actual_connection_sequence", sequences->connections, num_iters);
- /* verify conn. seq. expectation */
- /* get the first unique run of length "num_servers". */
- expected_connection_sequence = gpr_malloc(sizeof(int) * expected_seq_length);
- seen_elements = gpr_malloc(sizeof(int) * expected_seq_length);
-
- unique_seq_last_idx = ~(size_t)0;
-
- memset(seen_elements, 0, sizeof(int) * expected_seq_length);
- for (i = 0; i < num_iters; i++) {
- if (sequences->connections[i] < 0 ||
- seen_elements[sequences->connections[i]] != 0) {
- /* if anything breaks the uniqueness of the run, back to square zero */
- memset(seen_elements, 0, sizeof(int) * expected_seq_length);
- continue;
- }
- seen_elements[sequences->connections[i]] = 1;
- for (j = 0; j < expected_seq_length; j++) {
- if (seen_elements[j] == 0) break;
- }
- if (j == expected_seq_length) { /* seen all the elements */
- unique_seq_last_idx = i;
- break;
- }
- }
- /* make sure we found a valid run */
- dump_array("seen_elements", seen_elements, expected_seq_length);
- for (j = 0; j < expected_seq_length; j++) {
- GPR_ASSERT(seen_elements[j] != 0);
- }
-
- GPR_ASSERT(unique_seq_last_idx != ~(size_t)0);
-
- unique_seq_first_idx = (unique_seq_last_idx - expected_seq_length + 1);
- memcpy(expected_connection_sequence,
- sequences->connections + unique_seq_first_idx,
- sizeof(int) * expected_seq_length);
-
/* first iteration succeeds */
GPR_ASSERT(sequences->connections[0] != -1);
/* then we fail for a while... */
GPR_ASSERT(sequences->connections[1] == -1);
- /* ... but should be up at "unique_seq_first_idx" */
- GPR_ASSERT(sequences->connections[unique_seq_first_idx] != -1);
-
- for (j = 0, i = unique_seq_first_idx; i < num_iters; i++) {
- const int actual = sequences->connections[i];
- const int expected =
- expected_connection_sequence[j++ % expected_seq_length];
- if (actual != expected) {
- print_failed_expectations(expected_connection_sequence,
- sequences->connections, expected_seq_length,
- num_iters);
- abort();
+ /* ... but should be up eventually */
+ size_t first_iter_back_up = ~0ul;
+ for (size_t i = 2; i < sequences->n; ++i) {
+ if (sequences->connections[i] != -1) {
+ first_iter_back_up = i;
+ break;
}
}
+ GPR_ASSERT(first_iter_back_up != ~0ul);
/* We can assert that the first client channel state should be READY, when all
* servers were available; same thing for the last one. In the middle
@@ -962,7 +922,7 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
}
bool found_failure_status = false;
- for (i = 1; i < sequences->n - 1; i++) {
+ for (size_t i = 1; i < sequences->n - 1; i++) {
if (sequences->connectivity_states[i] == GRPC_CHANNEL_TRANSIENT_FAILURE) {
found_failure_status = true;
break;
@@ -974,14 +934,11 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
"CONNECTIVITY STATUS SEQUENCE FAILURE: "
"GRPC_CHANNEL_TRANSIENT_FAILURE status not found. Got the following "
"instead:");
- for (i = 0; i < num_iters; i++) {
+ for (size_t i = 0; i < num_iters; i++) {
gpr_log(GPR_ERROR, "[%d]: %s", (int)i,
grpc_connectivity_state_name(sequences->connectivity_states[i]));
}
}
-
- gpr_free(expected_connection_sequence);
- gpr_free(seen_elements);
}
int main(int argc, char **argv) {
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c
index 0a45f76395..11af7bee1e 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.c
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c
@@ -144,6 +144,8 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char **argv) {
size_t i;
+ g_fixture_slowdown_factor = 2.0;
+
grpc_test_init(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index a8c7b2be5a..cd68b390bb 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -126,8 +126,16 @@ int main(int argc, char **argv) {
char *addr;
+ grpc_channel_args client_args;
+ grpc_arg arg_array[1];
+ arg_array[0].type = GRPC_ARG_INTEGER;
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
+ arg_array[0].value.integer = 1000;
+ client_args.args = arg_array;
+ client_args.num_args = 1;
+
/* create a channel that picks first amongst the servers */
- grpc_channel *chan = grpc_insecure_channel_create("test", NULL, NULL);
+ grpc_channel *chan = grpc_insecure_channel_create("test", &client_args, NULL);
/* and an initial call to them */
grpc_call *call1 = grpc_channel_create_call(
chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1",
diff --git a/test/core/end2end/tests/connectivity.c b/test/core/end2end/tests/connectivity.c
index 260297ebd4..42475c7331 100644
--- a/test/core/end2end/tests/connectivity.c
+++ b/test/core/end2end/tests/connectivity.c
@@ -68,7 +68,15 @@ static void test_connectivity(grpc_end2end_test_config config) {
gpr_thd_options thdopt = gpr_thd_options_default();
gpr_thd_id thdid;
- config.init_client(&f, NULL);
+ grpc_channel_args client_args;
+ grpc_arg arg_array[1];
+ arg_array[0].type = GRPC_ARG_INTEGER;
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
+ arg_array[0].value.integer = 1000;
+ client_args.args = arg_array;
+ client_args.num_args = 1;
+
+ config.init_client(&f, &client_args);
ce.channel = f.client;
ce.cq = f.cq;
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index 37ce3b1222..ea63d45420 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -226,18 +226,6 @@ static void test_request(grpc_end2end_test_config config) {
grpc_call_destroy(s);
grpc_call_destroy(c);
- const gpr_timespec end_time = gpr_now(GPR_CLOCK_MONOTONIC);
- const gpr_timespec max_latency = gpr_time_sub(end_time, start_time);
-
- gpr_mu_lock(&g_mu);
- GPR_ASSERT(gpr_time_cmp(max_latency, g_client_latency) >= 0);
- GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_client_latency) < 0);
- GPR_ASSERT(gpr_time_cmp(max_latency, g_server_latency) >= 0);
- GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_server_latency) < 0);
- // Server latency should always be smaller than client latency.
- GPR_ASSERT(gpr_time_cmp(g_server_latency, g_client_latency) < 0);
- gpr_mu_unlock(&g_mu);
-
cq_verifier_destroy(cqv);
grpc_byte_buffer_destroy(request_payload);
@@ -245,6 +233,24 @@ static void test_request(grpc_end2end_test_config config) {
end_test(&f);
config.tear_down_data(&f);
+
+ const gpr_timespec end_time = gpr_now(GPR_CLOCK_MONOTONIC);
+ const gpr_timespec max_latency = gpr_time_sub(end_time, start_time);
+
+ // Perform checks after test tear-down
+ // Guards against the case that there's outstanding channel-related work on a
+ // call prior to verification
+ gpr_mu_lock(&g_mu);
+ GPR_ASSERT(gpr_time_cmp(max_latency, g_client_latency) >= 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_client_latency) <= 0);
+ GPR_ASSERT(gpr_time_cmp(max_latency, g_server_latency) >= 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_0(GPR_TIMESPAN), g_server_latency) <= 0);
+ // Server latency should always be smaller than client latency, however since
+ // we only calculate latency at destruction time, and that might mean that we
+ // need to wait for outstanding channel-related work, this isn't verifiable
+ // right now (the server MAY hold on to the call for longer than the client).
+ // GPR_ASSERT(gpr_time_cmp(g_server_latency, g_client_latency) < 0);
+ gpr_mu_unlock(&g_mu);
}
/*******************************************************************************
diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c
index db2e5c83de..4a88c5f2a8 100644
--- a/test/core/end2end/tests/payload.c
+++ b/test/core/end2end/tests/payload.c
@@ -126,7 +126,7 @@ static void request_response_with_payload(grpc_end2end_test_config config,
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_byte_buffer *response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
- gpr_timespec deadline = five_seconds_time();
+ gpr_timespec deadline = n_seconds_time(60);
cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_op ops[6];
grpc_op *op;
diff --git a/test/core/end2end/tests/resource_quota_server.c b/test/core/end2end/tests/resource_quota_server.c
index 7ec33e97a3..c919faea89 100644
--- a/test/core/end2end/tests/resource_quota_server.c
+++ b/test/core/end2end/tests/resource_quota_server.c
@@ -234,7 +234,7 @@ void resource_quota_server(grpc_end2end_test_config config) {
while (pending_client_calls + pending_server_recv_calls +
pending_server_end_calls >
0) {
- grpc_event ev = grpc_completion_queue_next(f.cq, n_seconds_time(10), NULL);
+ grpc_event ev = grpc_completion_queue_next(f.cq, n_seconds_time(60), NULL);
GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
int ev_tag = (int)(intptr_t)ev.tag;
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index ec40c8f22d..414a03d98b 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -200,21 +200,36 @@ static void simple_delayed_request_body(grpc_end2end_test_config config,
static void test_simple_delayed_request_short(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
+ grpc_channel_args client_args;
+ grpc_arg arg_array[1];
+ arg_array[0].type = GRPC_ARG_INTEGER;
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
+ arg_array[0].value.integer = 1000;
+ client_args.args = arg_array;
+ client_args.num_args = 1;
gpr_log(GPR_INFO, "%s/%s", "test_simple_delayed_request_short", config.name);
f = config.create_fixture(NULL, NULL);
- simple_delayed_request_body(config, &f, NULL, NULL, 100000);
+
+ simple_delayed_request_body(config, &f, &client_args, NULL, 100000);
end_test(&f);
config.tear_down_data(&f);
}
static void test_simple_delayed_request_long(grpc_end2end_test_config config) {
grpc_end2end_test_fixture f;
+ grpc_channel_args client_args;
+ grpc_arg arg_array[1];
+ arg_array[0].type = GRPC_ARG_INTEGER;
+ arg_array[0].key = "grpc.testing.fixed_reconnect_backoff_ms";
+ arg_array[0].value.integer = 1000;
+ client_args.args = arg_array;
+ client_args.num_args = 1;
gpr_log(GPR_INFO, "%s/%s", "test_simple_delayed_request_long", config.name);
f = config.create_fixture(NULL, NULL);
/* This timeout should be longer than a single retry */
- simple_delayed_request_body(config, &f, NULL, NULL, 1500000);
+ simple_delayed_request_body(config, &f, &client_args, NULL, 1500000);
end_test(&f);
config.tear_down_data(&f);
}
diff --git a/test/core/handshake/client_ssl.c b/test/core/handshake/client_ssl.c
index 44efe4dbac..24281e0b41 100644
--- a/test/core/handshake/client_ssl.c
+++ b/test/core/handshake/client_ssl.c
@@ -211,7 +211,7 @@ static bool client_ssl_test(char *server_alpn_preferred) {
// and port picking.
int port = -1;
int server_socket = -1;
- int socket_retries = 10;
+ int socket_retries = 30;
while (server_socket == -1 && socket_retries-- > 0) {
port = grpc_pick_unused_port_or_die();
server_socket = create_socket(port);
diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c
index 04969765f5..ca629a6eba 100644
--- a/test/core/security/ssl_server_fuzzer.c
+++ b/test/core/security/ssl_server_fuzzer.c
@@ -58,17 +58,14 @@ struct handshake_state {
bool done_callback_called;
};
-static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
- grpc_security_status status,
- grpc_endpoint *secure_endpoint,
- grpc_auth_context *auth_context) {
- struct handshake_state *state = (struct handshake_state *)statep;
+static void on_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ grpc_handshaker_args *args = arg;
+ struct handshake_state *state = args->user_data;
GPR_ASSERT(state->done_callback_called == false);
state->done_callback_called = true;
// The fuzzer should not pass the handshake.
- GPR_ASSERT(status != GRPC_SECURITY_OK);
- GPR_ASSERT(secure_endpoint == NULL);
- GPR_ASSERT(auth_context == NULL);
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
@@ -108,15 +105,17 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_security_status status =
grpc_server_credentials_create_security_connector(creds, &sc);
GPR_ASSERT(status == GRPC_SECURITY_OK);
- sc->channel_args = NULL;
gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(1, GPR_TIMESPAN));
struct handshake_state state;
state.done_callback_called = false;
- grpc_server_security_connector_do_handshake(&exec_ctx, sc, NULL,
- mock_endpoint, NULL, deadline,
- on_secure_handshake_done, &state);
+ grpc_handshake_manager *handshake_mgr = grpc_handshake_manager_create();
+ grpc_server_security_connector_create_handshakers(&exec_ctx, sc,
+ handshake_mgr);
+ grpc_handshake_manager_do_handshake(
+ &exec_ctx, handshake_mgr, mock_endpoint, NULL /* channel_args */,
+ deadline, NULL /* acceptor */, on_handshake_done, &state);
grpc_exec_ctx_flush(&exec_ctx);
// If the given string happens to be part of the correct client hello, the
@@ -129,6 +128,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
GPR_ASSERT(state.done_callback_called);
+ grpc_handshake_manager_destroy(&exec_ctx, handshake_mgr);
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test");
grpc_server_credentials_release(creds);
grpc_slice_unref(cert_slice);
diff --git a/test/core/support/backoff_test.c b/test/core/support/backoff_test.c
index 13cba7d750..ad6e5a98f2 100644
--- a/test/core/support/backoff_test.c
+++ b/test/core/support/backoff_test.c
@@ -39,61 +39,110 @@
static void test_constant_backoff(void) {
gpr_backoff backoff;
- gpr_backoff_init(&backoff, 1.0, 0.0, 1000, 1000);
+ 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)) == 1000);
+ 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)) == 1000);
+ GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 200);
now = next;
}
}
-static void test_no_jitter_backoff(void) {
+static void test_min_connect(void) {
gpr_backoff backoff;
- gpr_backoff_init(&backoff, 2.0, 0.0, 1, 513);
+ 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_cmp(gpr_time_from_millis(1, GPR_TIMESPAN), next) == 0);
- now = next;
- next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(3, GPR_TIMESPAN), next) == 0);
+ 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(7, GPR_TIMESPAN), next) == 0);
+ 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(15, GPR_TIMESPAN), next) == 0);
+ 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(31, GPR_TIMESPAN), next) == 0);
+ 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(63, GPR_TIMESPAN), next) == 0);
+ 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(127, GPR_TIMESPAN), next) == 0);
+ 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(255, GPR_TIMESPAN), next) == 0);
+ 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(511, GPR_TIMESPAN), next) == 0);
+ 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(1023, GPR_TIMESPAN), next) == 0);
+ GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1022, GPR_TIMESPAN), next) == 0);
now = next;
next = gpr_backoff_step(&backoff, now);
- GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1536, GPR_TIMESPAN), next) == 0);
+ // 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(2049, GPR_TIMESPAN), next) == 0);
+ 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(2562, GPR_TIMESPAN), next) == 0);
+ 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) {
@@ -101,7 +150,9 @@ int main(int argc, char **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/server_chttp2_test.c b/test/core/surface/server_chttp2_test.c
index 6310b6f00b..6c178abdad 100644
--- a/test/core/surface/server_chttp2_test.c
+++ b/test/core/surface/server_chttp2_test.c
@@ -44,8 +44,11 @@
#include "test/core/util/test_config.h"
void test_unparsable_target(void) {
- int port = grpc_server_add_insecure_http2_port(NULL, "[");
+ grpc_channel_args args = {0, NULL};
+ grpc_server *server = grpc_server_create(&args, NULL);
+ int port = grpc_server_add_insecure_http2_port(server, "[");
GPR_ASSERT(port == 0);
+ grpc_server_destroy(server);
}
void test_add_same_port_twice() {
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index 1cb4a8c05f..4a42e4c702 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -127,9 +127,9 @@ static bool is_port_available(int *port, bool is_tcp) {
on each supported family. */
bool got_socket = false;
for (int is_ipv6 = 1; is_ipv6 >= 0; is_ipv6--) {
- const int fd = socket(is_ipv6 ? AF_INET6 : AF_INET,
- is_tcp ? SOCK_STREAM : SOCK_DGRAM,
- is_tcp ? IPPROTO_TCP : 0);
+ const int fd =
+ socket(is_ipv6 ? AF_INET6 : AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM,
+ is_tcp ? IPPROTO_TCP : 0);
if (fd >= 0) {
got_socket = true;
} else {
@@ -147,9 +147,9 @@ static bool is_port_available(int *port, bool is_tcp) {
/* Try binding to port */
grpc_resolved_address addr;
if (is_ipv6) {
- grpc_sockaddr_make_wildcard6(*port, &addr); /* [::]:port */
+ grpc_sockaddr_make_wildcard6(*port, &addr); /* [::]:port */
} else {
- grpc_sockaddr_make_wildcard4(*port, &addr); /* 0.0.0.0:port */
+ grpc_sockaddr_make_wildcard4(*port, &addr); /* 0.0.0.0:port */
}
if (bind(fd, (struct sockaddr *)addr.addr, (socklen_t)addr.len) < 0) {
gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
@@ -158,8 +158,8 @@ static bool is_port_available(int *port, bool is_tcp) {
}
/* Get the bound port number */
- if (getsockname(fd, (struct sockaddr *)addr.addr,
- (socklen_t *)&addr.len) < 0) {
+ if (getsockname(fd, (struct sockaddr *)addr.addr, (socklen_t *)&addr.len) <
+ 0) {
gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno));
close(fd);
return false;
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 479aeda898..d86ed94637 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -33,14 +33,20 @@
#include "test/core/util/test_config.h"
-#include <grpc/support/log.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"
double g_fixture_slowdown_factor = 1.0;
+double g_poller_slowdown_factor = 1.0;
#if GPR_GETPID_IN_UNISTD_H
#include <unistd.h>
@@ -274,9 +280,16 @@ static void install_crash_handler() {}
void grpc_test_init(int argc, char **argv) {
install_crash_handler();
- gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f total=%f",
+ { /* poll-cv poll strategy runs much more slowly than anything else */
+ char *s = gpr_getenv("GRPC_POLL_STRATEGY");
+ if (s != NULL && 0 == strcmp(s, "poll-cv")) {
+ g_poller_slowdown_factor = 5.0;
+ }
+ gpr_free(s);
+ }
+ gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f poll=%f total=%f",
(double)GRPC_TEST_SLOWDOWN_MACHINE_FACTOR,
- (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR,
+ (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR, g_poller_slowdown_factor,
(double)GRPC_TEST_SLOWDOWN_FACTOR);
/* seed rng with pid, so we don't end up with the same random numbers as a
concurrently running test binary */
diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h
index 76686f1c51..c13fe86a64 100644
--- a/test/core/util/test_config.h
+++ b/test/core/util/test_config.h
@@ -49,10 +49,11 @@ extern "C" {
#endif
extern double g_fixture_slowdown_factor;
+extern double g_poller_slowdown_factor;
#define GRPC_TEST_SLOWDOWN_FACTOR \
(GRPC_TEST_SLOWDOWN_BUILD_FACTOR * GRPC_TEST_SLOWDOWN_MACHINE_FACTOR * \
- g_fixture_slowdown_factor)
+ g_fixture_slowdown_factor * g_poller_slowdown_factor)
#define GRPC_TIMEOUT_SECONDS_TO_DEADLINE(x) \
gpr_time_add( \