Merge pull request #8915 from dgquintas/lb_pol_test_deflake

Deflaked lb_policies_test
pull/8933/head
David G. Quintas 8 years ago committed by GitHub
commit eaa6202ac9
  1. 115
      test/core/client_channel/lb_policies_test.c

@ -64,9 +64,11 @@ typedef struct servers_fixture {
} servers_fixture; } servers_fixture;
typedef struct request_sequences { typedef struct request_sequences {
size_t n; size_t n; /* number of iterations */
int *connections; int *connections; /* indexed by the interation number, value is the index of
int *connectivity_states; 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; } request_sequences;
typedef void (*verifier_fn)(const servers_fixture *, grpc_channel *, typedef void (*verifier_fn)(const servers_fixture *, grpc_channel *,
@ -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++) { for (size_t i = 0; i < sequences->n; i++) {
const grpc_connectivity_state actual = sequences->connectivity_states[i]; const grpc_connectivity_state actual = sequences->connectivity_states[i];
const grpc_connectivity_state expected = GRPC_CHANNEL_TRANSIENT_FAILURE; if (actual != GRPC_CHANNEL_TRANSIENT_FAILURE &&
if (actual != expected) { actual != GRPC_CHANNEL_CONNECTING) {
gpr_log(GPR_ERROR, gpr_log(GPR_ERROR,
"CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " "CONNECTIVITY STATUS SEQUENCE FAILURE: expected "
"at iteration #%d", "GRPC_CHANNEL_TRANSIENT_FAILURE or GRPC_CHANNEL_CONNECTING, got "
grpc_connectivity_state_name(expected), "'%s' at iteration #%d",
grpc_connectivity_state_name(actual), (int)i); grpc_connectivity_state_name(actual), (int)i);
abort(); 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 /* 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, * servers were available */
* after all servers are gone. */
grpc_connectivity_state actual = sequences->connectivity_states[0]; grpc_connectivity_state actual = sequences->connectivity_states[0];
grpc_connectivity_state expected = GRPC_CHANNEL_READY; grpc_connectivity_state expected = GRPC_CHANNEL_READY;
if (actual != expected) { if (actual != expected) {
@ -838,17 +841,21 @@ static void verify_partial_carnage_round_robin(
abort(); 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]; actual = sequences->connectivity_states[num_iters - 1];
expected = GRPC_CHANNEL_TRANSIENT_FAILURE; for (i = 0; i < sequences->n; i++) {
if (actual != expected) { if (actual != GRPC_CHANNEL_TRANSIENT_FAILURE &&
gpr_log(GPR_ERROR, actual != GRPC_CHANNEL_CONNECTING) {
"CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " gpr_log(GPR_ERROR,
"at iteration #%d", "CONNECTIVITY STATUS SEQUENCE FAILURE: expected "
grpc_connectivity_state_name(expected), "GRPC_CHANNEL_TRANSIENT_FAILURE or GRPC_CHANNEL_CONNECTING, got "
grpc_connectivity_state_name(actual), (int)num_iters - 1); "'%s' at iteration #%d",
abort(); grpc_connectivity_state_name(actual), (int)i);
abort();
}
} }
gpr_free(expected_connection_sequence); gpr_free(expected_connection_sequence);
} }
@ -873,68 +880,21 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
grpc_channel *client, grpc_channel *client,
const request_sequences *sequences, const request_sequences *sequences,
const size_t num_iters) { 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); 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 */ /* first iteration succeeds */
GPR_ASSERT(sequences->connections[0] != -1); GPR_ASSERT(sequences->connections[0] != -1);
/* then we fail for a while... */ /* then we fail for a while... */
GPR_ASSERT(sequences->connections[1] == -1); GPR_ASSERT(sequences->connections[1] == -1);
/* ... but should be up at "unique_seq_first_idx" */ /* ... but should be up eventually */
GPR_ASSERT(sequences->connections[unique_seq_first_idx] != -1); size_t first_iter_back_up = ~0ul;
for (size_t i = 2; i < sequences->n; ++i) {
for (j = 0, i = unique_seq_first_idx; i < num_iters; i++) { if (sequences->connections[i] != -1) {
const int actual = sequences->connections[i]; first_iter_back_up = i;
const int expected = break;
expected_connection_sequence[j++ % expected_seq_length];
if (actual != expected) {
print_failed_expectations(expected_connection_sequence,
sequences->connections, expected_seq_length,
num_iters);
abort();
} }
} }
GPR_ASSERT(first_iter_back_up != ~0ul);
/* We can assert that the first client channel state should be READY, when all /* 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 * 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; 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) { if (sequences->connectivity_states[i] == GRPC_CHANNEL_TRANSIENT_FAILURE) {
found_failure_status = true; found_failure_status = true;
break; break;
@ -974,14 +934,11 @@ static void verify_rebirth_round_robin(const servers_fixture *f,
"CONNECTIVITY STATUS SEQUENCE FAILURE: " "CONNECTIVITY STATUS SEQUENCE FAILURE: "
"GRPC_CHANNEL_TRANSIENT_FAILURE status not found. Got the following " "GRPC_CHANNEL_TRANSIENT_FAILURE status not found. Got the following "
"instead:"); "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, gpr_log(GPR_ERROR, "[%d]: %s", (int)i,
grpc_connectivity_state_name(sequences->connectivity_states[i])); grpc_connectivity_state_name(sequences->connectivity_states[i]));
} }
} }
gpr_free(expected_connection_sequence);
gpr_free(seen_elements);
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {

Loading…
Cancel
Save