Move to a list of active calls

pull/6160/head
Craig Tiller 9 years ago
parent f582305ebe
commit 07f2e5f643
  1. 126
      test/core/end2end/fuzzers/api_fuzzer.c

@ -341,18 +341,39 @@ static void free_non_null(void *p) {
gpr_free(p); gpr_free(p);
} }
typedef enum {
ROOT, CLIENT, SERVER
} call_state_type;
typedef struct call_state { typedef struct call_state {
grpc_call *client; call_state_type type;
grpc_call *server; grpc_call *call;
grpc_byte_buffer *recv_message[2]; grpc_byte_buffer *recv_message;
grpc_status_code status; grpc_status_code status;
grpc_metadata_array recv_initial_metadata; grpc_metadata_array recv_initial_metadata;
grpc_metadata_array recv_trailing_metadata; grpc_metadata_array recv_trailing_metadata;
char *recv_status_details; char *recv_status_details;
size_t recv_status_details_capacity; size_t recv_status_details_capacity;
int cancelled; int cancelled;
struct call_state *next;
struct call_state *prev;
} call_state; } call_state;
static call_state *new_call(call_state *sibling, call_state_type type) {
call_state *c = gpr_malloc(sizeof(*c));
memset(c, 0, sizeof(*c));
if (sibling != NULL) {
c->next = sibling;
c->prev = sibling->prev;
c->next->prev = c->prev->next = c;
} else {
c->next = c->prev = c;
}
c->type = type;
return c;
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_test_only_set_metadata_hash_seed(0); grpc_test_only_set_metadata_hash_seed(0);
if (squelch) gpr_set_log_function(dont_log); if (squelch) gpr_set_log_function(dont_log);
@ -371,10 +392,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
int pending_pings = 0; int pending_pings = 0;
int pending_ops = 0; int pending_ops = 0;
#define MAX_CALLS 16 call_state *active_call = new_call(NULL, ROOT);
call_state calls[MAX_CALLS];
int num_calls = 0;
memset(calls, 0, sizeof(calls));
grpc_completion_queue *cq = grpc_completion_queue_create(NULL); grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
@ -545,14 +563,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
case 10: { case 10: {
bool ok = true; bool ok = true;
if (g_channel == NULL) ok = false; if (g_channel == NULL) ok = false;
if (num_calls >= MAX_CALLS) ok = false;
grpc_call *parent_call = NULL; grpc_call *parent_call = NULL;
uint8_t pcidx = next_byte(&inp); if (active_call->type != ROOT) {
if (pcidx > MAX_CALLS) if (active_call->call == NULL) {
ok = false; end(&inp);
else if (pcidx < MAX_CALLS) { break;
parent_call = calls[pcidx].server; }
if (parent_call == NULL) ok = false; parent_call = active_call->call;
} }
uint32_t propagation_mask = read_uint32(&inp); uint32_t propagation_mask = read_uint32(&inp);
char *method = read_string(&inp); char *method = read_string(&inp);
@ -562,8 +579,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN)); gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
if (ok) { if (ok) {
GPR_ASSERT(calls[num_calls].client == NULL); call_state *cs = new_call(active_call, CLIENT);
calls[num_calls].client = cs->call =
grpc_channel_create_call(g_channel, parent_call, propagation_mask, grpc_channel_create_call(g_channel, parent_call, propagation_mask,
cq, method, host, deadline, NULL); cq, method, host, deadline, NULL);
} else { } else {
@ -573,29 +590,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
} }
// switch the 'current' call // switch the 'current' call
case 11: { case 11: {
uint8_t new_current = next_byte(&inp); active_call = active_call->next;
if (new_current == 0 || new_current >= num_calls) {
end(&inp);
} else {
GPR_SWAP(call_state, calls[0], calls[new_current]);
}
break; break;
} }
// queue some ops on a call // queue some ops on a call
case 12: { case 12: {
if (active_call->type == ROOT || active_call->call == NULL) {
end(&inp);
break;
}
size_t num_ops = next_byte(&inp); size_t num_ops = next_byte(&inp);
grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops); grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops);
bool ok = num_calls > 0; bool ok = true;
uint8_t on_server = next_byte(&inp);
if (on_server != 0 && on_server != 1) {
ok = false;
}
if (ok && on_server && calls[0].server == NULL) {
ok = false;
}
if (ok && !on_server && calls[0].client == NULL) {
ok = false;
}
size_t i; size_t i;
grpc_op *op; grpc_op *op;
for (i = 0; i < num_ops; i++) { for (i = 0; i < num_ops; i++) {
@ -627,25 +633,25 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break; break;
case GRPC_OP_RECV_INITIAL_METADATA: case GRPC_OP_RECV_INITIAL_METADATA:
op->op = GRPC_OP_RECV_INITIAL_METADATA; op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &calls[0].recv_initial_metadata; op->data.recv_initial_metadata = &active_call->recv_initial_metadata;
break; break;
case GRPC_OP_RECV_MESSAGE: case GRPC_OP_RECV_MESSAGE:
op->op = GRPC_OP_RECV_MESSAGE; op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &calls[0].recv_message[on_server]; op->data.recv_message = &active_call->recv_message;
break; break;
case GRPC_OP_RECV_STATUS_ON_CLIENT: case GRPC_OP_RECV_STATUS_ON_CLIENT:
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.status = &calls[0].status; op->data.recv_status_on_client.status = &active_call->status;
op->data.recv_status_on_client.trailing_metadata = op->data.recv_status_on_client.trailing_metadata =
&calls[0].recv_trailing_metadata; &active_call->recv_trailing_metadata;
op->data.recv_status_on_client.status_details = op->data.recv_status_on_client.status_details =
&calls[0].recv_status_details; &active_call->recv_status_details;
op->data.recv_status_on_client.status_details_capacity = op->data.recv_status_on_client.status_details_capacity =
&calls[0].recv_status_details_capacity; &active_call->recv_status_details_capacity;
break; break;
case GRPC_OP_RECV_CLOSE_ON_SERVER: case GRPC_OP_RECV_CLOSE_ON_SERVER:
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &calls[0].cancelled; op->data.recv_close_on_server.cancelled = &active_call->cancelled;
break; break;
} }
op->reserved = NULL; op->reserved = NULL;
@ -655,7 +661,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
validator *v = create_validator(decrement, &pending_ops); validator *v = create_validator(decrement, &pending_ops);
pending_ops++; pending_ops++;
grpc_call_error error = grpc_call_start_batch( grpc_call_error error = grpc_call_start_batch(
on_server ? calls[0].server : calls[0].client, ops, num_ops, active_call->call, ops, num_ops,
v, NULL); v, NULL);
if (error != GRPC_CALL_OK) { if (error != GRPC_CALL_OK) {
v->validate(v->arg, false); v->validate(v->arg, false);
@ -697,44 +703,26 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break; break;
} }
// cancel current call on client // cancel current call
case 13: { case 13: {
if (num_calls > 0 && calls[0].client) { if (active_call->type != ROOT && active_call->call != NULL) {
grpc_call_cancel(calls[0].client, NULL); grpc_call_cancel(active_call->call, NULL);
} else { } else {
end(&inp); end(&inp);
} }
break; break;
} }
// cancel current call on server // get a calls peer
case 14: { case 14: {
if (num_calls > 0 && calls[0].server) { if (active_call->type != ROOT && active_call->call != NULL) {
grpc_call_cancel(calls[0].server, NULL); free_non_null(grpc_call_get_peer(active_call->call));
} else {
end(&inp);
}
break;
}
// get a calls peer on client
case 15: {
if (num_calls > 0 && calls[0].client) {
free_non_null(grpc_call_get_peer(calls[0].client));
} else {
end(&inp);
}
break;
}
// get a calls peer on server
case 16: {
if (num_calls > 0 && calls[0].server) {
free_non_null(grpc_call_get_peer(calls[0].server));
} else { } else {
end(&inp); end(&inp);
} }
break; break;
} }
// get a channels target // get a channels target
case 17: { case 15: {
if (g_channel != NULL) { if (g_channel != NULL) {
free_non_null(grpc_channel_get_target(g_channel)); free_non_null(grpc_channel_get_target(g_channel));
} else { } else {
@ -743,7 +731,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break; break;
} }
// send a ping on a channel // send a ping on a channel
case 18: { case 16: {
if (g_channel != NULL) { if (g_channel != NULL) {
pending_pings++; pending_pings++;
grpc_channel_ping(g_channel, cq, grpc_channel_ping(g_channel, cq,
@ -754,14 +742,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break; break;
} }
// enable a tracer // enable a tracer
case 19: { case 17: {
char *tracer = read_string(&inp); char *tracer = read_string(&inp);
grpc_tracer_set_enabled(tracer, 1); grpc_tracer_set_enabled(tracer, 1);
gpr_free(tracer); gpr_free(tracer);
break; break;
} }
// disable a tracer // disable a tracer
case 20: { case 18: {
char *tracer = read_string(&inp); char *tracer = read_string(&inp);
grpc_tracer_set_enabled(tracer, 0); grpc_tracer_set_enabled(tracer, 0);
gpr_free(tracer); gpr_free(tracer);

Loading…
Cancel
Save