pull/6160/head
Craig Tiller 9 years ago
parent ac82c186b9
commit 1395e19c2c
  1. 160
      test/core/end2end/fuzzers/api_fuzzer.c

@ -272,6 +272,8 @@ static void assert_success_and_decrement(void *counter, bool success) {
--*(int *)counter;
}
static void decrement(void *counter, bool success) { --*(int *)counter; }
typedef struct connectivity_watch {
int *counter;
gpr_timespec deadline;
@ -294,9 +296,15 @@ static void validate_connectivity_watch(void *p, bool success) {
gpr_free(w);
}
static void free_non_null(void *p) {
GPR_ASSERT(p != NULL);
gpr_free(p);
}
typedef struct call_state {
grpc_call *client;
grpc_call *server;
grpc_metadata_array recv_initial_metadata;
} call_state;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
@ -314,6 +322,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
bool server_shutdown = false;
int pending_server_shutdowns = 0;
int pending_channel_watches = 0;
int pending_pings = 0;
#define MAX_CALLS 16
call_state calls[MAX_CALLS];
@ -323,7 +332,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
while (!is_eof(&inp) || g_channel != NULL || g_server != NULL ||
pending_channel_watches > 0) {
pending_channel_watches > 0 || pending_pings > 0) {
if (is_eof(&inp)) {
if (g_channel != NULL) {
grpc_channel_destroy(g_channel);
@ -525,6 +534,155 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}
break;
}
// queue some ops on a call
case 12: {
size_t num_ops = next_byte(&inp);
grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops);
bool ok = num_calls > 0;
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;
}
for (size_t i = 0; i < num_ops; i++) {
grpc_op *op = &ops[i];
switch (next_byte(&inp)) {
default:
ok = false;
break;
case GRPC_OP_SEND_INITIAL_METADATA:
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = next_byte(&inp);
read_metadata(&inp, &op->data.send_initial_metadata.count,
&op->data.send_initial_metadata.metadata);
break;
case GRPC_OP_SEND_MESSAGE:
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_message = read_message(&inp);
break;
case GRPC_OP_SEND_STATUS_FROM_SERVER:
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
read_metadata(
&inp,
&op->data.send_status_from_server.trailing_metadata_count,
&op->data.send_status_from_server.trailing_metadata);
break;
case GRPC_OP_RECV_INITIAL_METADATA:
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &calls[0].recv_initial_metadata;
break;
case GRPC_OP_RECV_MESSAGE:
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &calls[0].recv_message[on_server];
break;
case 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.trailing_metadata =
&calls[0].recv_trailing_metadata;
op->data.recv_status_on_client.status_details =
&calls[0].recv_status_details;
op->data.recv_status_on_client.status_details_capacity =
&calls[0].recv_status_details_capacity;
break;
case GRPC_OP_RECV_CLOSE_ON_SERVER:
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &calls[0].cancelled;
break;
}
op->reserved = NULL;
op->flags = read_uint32(&inp);
if (ok) {
grpc_call_error error = grpc_call_start_batch(
on_server ? calls[0].server : calls[0].client, ops, num_ops,
tag, NULL);
} else {
end(&inp);
}
}
break;
}
// cancel current call on client
case 13: {
if (num_calls > 0 && calls[0].client) {
grpc_call_cancel(calls[0].client, NULL);
} else {
end(&inp);
}
break;
}
// cancel current call on server
case 14: {
if (num_calls > 0 && calls[0].server) {
grpc_call_cancel(calls[0].server, NULL)
} 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 {
end(&inp);
}
break;
}
// get a channels target
case 17: {
if (g_channel != NULL) {
free_non_null(grpc_channel_get_target(g_channel));
} else {
end(&inp);
}
break;
}
// send a ping on a channel
case 18: {
if (g_channel != NULL) {
grpc_channel_ping(g_channel, cq,
create_validator(decrement, &pending_pings), NULL);
} else {
end(&inp);
}
break;
}
// enable a tracer
case 19: {
char *tracer = read_string(&inp);
grpc_tracer_set_enabled(tracer, 1);
gpr_free(tracer);
break;
}
// disable a tracer
case 20: {
char *tracer = read_string(&inp);
grpc_tracer_set_enabled(tracer, 0);
gpr_free(tracer);
break;
}
// create an alarm
case 21: {
gpr_timespec deadline =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
grpc_alarm *alarm = grpc_alarm_create(cq, );
}
}
}

Loading…
Cancel
Save