aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-04-15 13:07:54 -0700
committerGravatar Craig Tiller <ctiller@google.com>2016-04-15 13:07:54 -0700
commitba0d6ac79a0b937ee41d9d9c81547af2ebc78302 (patch)
tree97a5480405cae2c9f07409385035872830855a9f /test
parentb91fe568007ede00f2d1b3530e4ba04c2d84f188 (diff)
First pass client call fuzzing
Diffstat (limited to 'test')
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.c84
1 files changed, 71 insertions, 13 deletions
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index c74783bee4..cc98e02529 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -82,6 +82,14 @@ static char *read_string(input_stream *inp) {
return str;
}
+static void read_buffer(input_stream *inp, char **buffer, size_t *length) {
+ *length = next_byte(inp);
+ *buffer = gpr_malloc(*length);
+ for (size_t i = 0; i < *length; i++) {
+ (*buffer)[i] = (char)next_byte(inp);
+ }
+}
+
static uint32_t read_uint32(input_stream *inp) {
uint8_t b = next_byte(inp);
uint32_t x = b & 0x7f;
@@ -106,6 +114,23 @@ static uint32_t read_uint32(input_stream *inp) {
return x;
}
+static grpc_byte_buffer *read_message(input_stream *inp) {
+ gpr_slice slice = gpr_slice_malloc(read_uint32(inp));
+ memset(GPR_SLICE_START_PTR(slice), 0, GPR_SLICE_LENGTH(slice));
+ return grpc_raw_byte_buffer_create(&slice, 1);
+}
+
+static void read_metadata(input_stream *inp, size_t *count, grpc_metadata **metadata) {
+ *count = next_byte(inp);
+ *metadata = gpr_malloc(*count * sizeof(**metadata));
+ memset(*metadata, 0, *count * sizeof(**metadata));
+ for (size_t i = 0; i < *count; i++) {
+ (*metadata)[i].key = read_string(inp);
+ read_buffer(inp, (char**)&(*metadata[i]).value, &(*metadata[i]).value_length);
+ (*metadata)[i].flags = read_uint32(inp);
+ }
+}
+
static int read_int(input_stream *inp) { return (int)read_uint32(inp); }
static grpc_channel_args *read_args(input_stream *inp) {
@@ -304,7 +329,13 @@ static void free_non_null(void *p) {
typedef struct call_state {
grpc_call *client;
grpc_call *server;
+ grpc_byte_buffer *recv_message[2];
+ grpc_status_code status;
grpc_metadata_array recv_initial_metadata;
+ grpc_metadata_array recv_trailing_metadata;
+ char *recv_status_details;
+ size_t recv_status_details_capacity;
+ int cancelled;
} call_state;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
@@ -323,6 +354,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
int pending_server_shutdowns = 0;
int pending_channel_watches = 0;
int pending_pings = 0;
+ int pending_ops = 0;
#define MAX_CALLS 16
call_state calls[MAX_CALLS];
@@ -332,7 +364,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_pings > 0) {
+ pending_channel_watches > 0 || pending_pings > 0 || pending_ops > 0) {
if (is_eof(&inp)) {
if (g_channel != NULL) {
grpc_channel_destroy(g_channel);
@@ -549,15 +581,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (ok && !on_server && calls[0].client == NULL) {
ok = false;
}
- for (size_t i = 0; i < num_ops; i++) {
- grpc_op *op = &ops[i];
+ size_t i;
+ grpc_op *op;
+ for (i = 0; i < num_ops; i++) {
+ 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;
@@ -565,12 +598,17 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_message = read_message(&inp);
break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ 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);
+ op->data.send_status_from_server.status = next_byte(&inp);
+ op->data.send_status_from_server.status_details = read_string(&inp);
break;
case GRPC_OP_RECV_INITIAL_METADATA:
op->op = GRPC_OP_RECV_INITIAL_METADATA;
@@ -598,12 +636,39 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
op->reserved = NULL;
op->flags = read_uint32(&inp);
if (ok) {
+ validator *v = create_validator(decrement, &pending_ops);
+ pending_ops++;
grpc_call_error error = grpc_call_start_batch(
on_server ? calls[0].server : calls[0].client, ops, num_ops,
- tag, NULL);
+ v, NULL);
+ if (error != GRPC_CALL_OK) {
+ v->validate(v->arg, false);
+ gpr_free(v);
+ }
} else {
end(&inp);
}
+ for (i = 0; i < num_ops; i++) {
+ op = &ops[i];
+ switch (op->op) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ gpr_free(op->data.send_initial_metadata.metadata);
+ break;
+ case GRPC_OP_SEND_MESSAGE:
+ grpc_byte_buffer_destroy(op->data.send_message);
+ break;
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ gpr_free(op->data.send_status_from_server.trailing_metadata);
+ gpr_free((void*)op->data.send_status_from_server.status_details);
+ break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ case GRPC_OP_RECV_MESSAGE:
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ break;
+ }
+ }
}
break;
}
@@ -619,7 +684,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// cancel current call on server
case 14: {
if (num_calls > 0 && calls[0].server) {
- grpc_call_cancel(calls[0].server, NULL)
+ grpc_call_cancel(calls[0].server, NULL);
} else {
end(&inp);
}
@@ -676,13 +741,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
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, );
- }
}
}