static void verify_vanilla_round_robin(const servers_fixture *f, grpc_channel *client, const int *actual_connection_sequence, const size_t num_iters) { int *expected_connection_sequence; size_t i; const size_t expected_seq_length = f->num_servers; /* verify conn. seq. expectation */ /* get the first sequence of "num_servers" elements */ expected_connection_sequence = gpr_malloc(sizeof(int) * expected_seq_length); memcpy(expected_connection_sequence, actual_connection_sequence, sizeof(int) * expected_seq_length); for (i = 0; i < num_iters; i++) { const int actual = actual_connection_sequence[i]; const int expected = expected_connection_sequence[i % expected_seq_length]; if (actual != expected) { gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected, actual, i); print_failed_expectations(expected_connection_sequence, actual_connection_sequence, expected_seq_length, num_iters); abort(); } } assert_channel_connectivity(client, 1, GRPC_CHANNEL_READY); gpr_free(expected_connection_sequence); }
static void verify_partial_carnage_round_robin( const servers_fixture *f, grpc_channel *client, const int *actual_connection_sequence, const size_t num_iters) { int *expected_connection_sequence; size_t i; const size_t expected_seq_length = f->num_servers; /* verify conn. seq. expectation */ /* get the first sequence of "num_servers" elements */ expected_connection_sequence = gpr_malloc(sizeof(int) * expected_seq_length); memcpy(expected_connection_sequence, actual_connection_sequence, sizeof(int) * expected_seq_length); for (i = 0; i < num_iters / 2; i++) { const int actual = actual_connection_sequence[i]; const int expected = expected_connection_sequence[i % expected_seq_length]; if (actual != expected) { print_failed_expectations(expected_connection_sequence, actual_connection_sequence, expected_seq_length, num_iters); abort(); } } /* second half of the iterations go without response */ for (; i < num_iters; i++) { GPR_ASSERT(actual_connection_sequence[i] == -1); } /* even though we know all the servers are dead, the client is still trying * retrying, believing it's in a transient failure situation */ assert_channel_connectivity(client, 2, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_CHANNEL_CONNECTING); gpr_free(expected_connection_sequence); }
static void verify_partial_carnage_round_robin( const servers_fixture *f, grpc_channel *client, const request_sequences *sequences, const size_t num_iters) { int *expected_connection_sequence; size_t i; const size_t expected_seq_length = f->num_servers; /* verify conn. seq. expectation */ /* get the first sequence of "num_servers" elements */ expected_connection_sequence = gpr_malloc(sizeof(int) * expected_seq_length); memcpy(expected_connection_sequence, sequences->connections, sizeof(int) * expected_seq_length); for (i = 0; i < num_iters / 2; i++) { const int actual = sequences->connections[i]; const int expected = expected_connection_sequence[i % expected_seq_length]; if (actual != expected) { print_failed_expectations(expected_connection_sequence, sequences->connections, expected_seq_length, num_iters); abort(); } } /* second half of the iterations go without response */ for (; i < num_iters; i++) { GPR_ASSERT(sequences->connections[i] == -1); } /* We can assert that the first client channel state should be READY, when all * servers were available */ grpc_connectivity_state actual = sequences->connectivity_states[0]; grpc_connectivity_state expected = GRPC_CHANNEL_READY; if (actual != expected) { gpr_log(GPR_ERROR, "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " "at iteration #%d", grpc_connectivity_state_name(expected), grpc_connectivity_state_name(actual), 0); abort(); } /* ... and that the last one shouldn't be READY (or SHUTDOWN): all servers are * gone. It may be all other states (IDLE, CONNECTING, TRANSIENT_FAILURE), as * the policy transitions while attempting to reconnect. */ actual = sequences->connectivity_states[num_iters - 1]; for (i = 0; i < sequences->n; i++) { if (actual == GRPC_CHANNEL_READY || actual == GRPC_CHANNEL_SHUTDOWN) { gpr_log(GPR_ERROR, "CONNECTIVITY STATUS SEQUENCE FAILURE: got unexpected state " "'%s' at iteration #%d.", grpc_connectivity_state_name(actual), (int)i); abort(); } } gpr_free(expected_connection_sequence); }
/* At the start of the second iteration, all but the first and last servers (as * given in "f") are killed */ static void verify_vanishing_floor_round_robin( const servers_fixture *f, grpc_channel *client, const request_sequences *sequences, const size_t num_iters) { int *expected_connection_sequence; const size_t expected_seq_length = 2; size_t i; /* verify conn. seq. expectation */ /* copy the first full sequence (without -1s) */ expected_connection_sequence = gpr_malloc(sizeof(int) * expected_seq_length); memcpy(expected_connection_sequence, sequences->connections + 2, expected_seq_length * sizeof(int)); /* first two elements of the sequence should be [0 (1st server), -1 (failure)] */ GPR_ASSERT(sequences->connections[0] == 0); GPR_ASSERT(sequences->connections[1] == -1); /* the next two element must be [3, 0], repeating from that point: the 3 is * brought forth by servers 1 and 2 disappearing after the intial pick of 0 */ GPR_ASSERT(sequences->connections[2] == 3); GPR_ASSERT(sequences->connections[3] == 0); /* make sure that the expectation obliges */ for (i = 2; i < num_iters; i++) { const int actual = sequences->connections[i]; const int expected = expected_connection_sequence[i % expected_seq_length]; if (actual != expected) { print_failed_expectations(expected_connection_sequence, sequences->connections, expected_seq_length, num_iters); abort(); } } /* There's always at least one subchannel READY (connected), therefore the * overall state of the client channel is READY at all times. */ for (i = 0; i < sequences->n; i++) { const grpc_connectivity_state actual = sequences->connectivity_states[i]; const grpc_connectivity_state expected = GRPC_CHANNEL_READY; if (actual != expected) { gpr_log(GPR_ERROR, "CONNECTIVITY STATUS SEQUENCE FAILURE: expected '%s', got '%s' " "at iteration #%d", grpc_connectivity_state_name(expected), grpc_connectivity_state_name(actual), (int)i); abort(); } } gpr_free(expected_connection_sequence); }
/* At the start of the second iteration, all but the first and last servers (as * given in "f") are killed */ static void verify_vanishing_floor_round_robin( const servers_fixture *f, grpc_channel *client, const int *actual_connection_sequence, const size_t num_iters) { int *expected_connection_sequence; const size_t expected_seq_length = 2; size_t i; /* verify conn. seq. expectation */ /* copy the first full sequence (without -1s) */ expected_connection_sequence = gpr_malloc(sizeof(int) * expected_seq_length); memcpy(expected_connection_sequence, actual_connection_sequence + 2, expected_seq_length * sizeof(int)); /* first three elements of the sequence should be [<1st>, -1] */ if (actual_connection_sequence[0] != expected_connection_sequence[0]) { gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected_connection_sequence[0], actual_connection_sequence[0], 0); print_failed_expectations(expected_connection_sequence, actual_connection_sequence, expected_seq_length, 1u); abort(); } GPR_ASSERT(actual_connection_sequence[1] == -1); for (i = 2; i < num_iters; i++) { const int actual = actual_connection_sequence[i]; const int expected = expected_connection_sequence[i % expected_seq_length]; if (actual != expected) { gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected, actual, i); print_failed_expectations(expected_connection_sequence, actual_connection_sequence, expected_seq_length, num_iters); abort(); } } gpr_free(expected_connection_sequence); }
/* At the start of the second iteration, all but the first and last servers (as * given in "f") are killed */ static void verify_vanishing_floor_round_robin( const servers_fixture *f, grpc_channel *client, const int *actual_connection_sequence, const size_t num_iters) { int *expected_connection_sequence; const size_t expected_seq_length = 2; size_t i; /* verify conn. seq. expectation */ /* copy the first full sequence (without -1s) */ expected_connection_sequence = gpr_malloc(sizeof(int) * expected_seq_length); memcpy(expected_connection_sequence, actual_connection_sequence + 2, expected_seq_length * sizeof(int)); /* first two elements of the sequence should be [0 (1st server), -1 (failure)] */ GPR_ASSERT(actual_connection_sequence[0] == 0); GPR_ASSERT(actual_connection_sequence[1] == -1); /* the next two element must be [3, 0], repeating from that point: the 3 is * brought forth by servers 1 and 2 disappearing after the intial pick of 0 */ GPR_ASSERT(actual_connection_sequence[2] == 3); GPR_ASSERT(actual_connection_sequence[3] == 0); /* make sure that the expectation obliges */ for (i = 2; i < num_iters; i++) { const int actual = actual_connection_sequence[i]; const int expected = expected_connection_sequence[i % expected_seq_length]; if (actual != expected) { print_failed_expectations(expected_connection_sequence, actual_connection_sequence, expected_seq_length, num_iters); abort(); } } gpr_free(expected_connection_sequence); }
static void verify_rebirth_round_robin(const servers_fixture *f, grpc_channel *client, const int *actual_connection_sequence, 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", actual_connection_sequence, 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 (actual_connection_sequence[i] < 0 || seen_elements[actual_connection_sequence[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[actual_connection_sequence[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, actual_connection_sequence + unique_seq_first_idx, sizeof(int) * expected_seq_length); /* first iteration succeeds */ GPR_ASSERT(actual_connection_sequence[0] != -1); /* then we fail for a while... */ GPR_ASSERT(actual_connection_sequence[1] == -1); /* ... but should be up at "unique_seq_first_idx" */ GPR_ASSERT(actual_connection_sequence[unique_seq_first_idx] != -1); for (j = 0, i = unique_seq_first_idx; i < num_iters; i++) { const int actual = actual_connection_sequence[i]; const int expected = expected_connection_sequence[j++ % expected_seq_length]; if (actual != expected) { gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected, actual, i); print_failed_expectations(expected_connection_sequence, actual_connection_sequence, expected_seq_length, num_iters); abort(); } } /* things are fine once the servers are brought back up */ assert_channel_connectivity(client, 1, GRPC_CHANNEL_READY); gpr_free(expected_connection_sequence); gpr_free(seen_elements); }