aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core/end2end
diff options
context:
space:
mode:
Diffstat (limited to 'test/core/end2end')
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.c126
1 files changed, 57 insertions, 69 deletions
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 6f9be8ecd6..9f11e750c7 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -341,18 +341,39 @@ static void free_non_null(void *p) {
gpr_free(p);
}
+typedef enum {
+ ROOT, CLIENT, SERVER
+} call_state_type;
+
typedef struct call_state {
- grpc_call *client;
- grpc_call *server;
- grpc_byte_buffer *recv_message[2];
+ call_state_type type;
+ grpc_call *call;
+ grpc_byte_buffer *recv_message;
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;
+
+ struct call_state *next;
+ struct call_state *prev;
} 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) {
grpc_test_only_set_metadata_hash_seed(0);
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_ops = 0;
-#define MAX_CALLS 16
- call_state calls[MAX_CALLS];
- int num_calls = 0;
- memset(calls, 0, sizeof(calls));
+ call_state *active_call = new_call(NULL, ROOT);
grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
@@ -545,14 +563,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
case 10: {
bool ok = true;
if (g_channel == NULL) ok = false;
- if (num_calls >= MAX_CALLS) ok = false;
grpc_call *parent_call = NULL;
- uint8_t pcidx = next_byte(&inp);
- if (pcidx > MAX_CALLS)
- ok = false;
- else if (pcidx < MAX_CALLS) {
- parent_call = calls[pcidx].server;
- if (parent_call == NULL) ok = false;
+ if (active_call->type != ROOT) {
+ if (active_call->call == NULL) {
+ end(&inp);
+ break;
+ }
+ parent_call = active_call->call;
}
uint32_t propagation_mask = read_uint32(&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));
if (ok) {
- GPR_ASSERT(calls[num_calls].client == NULL);
- calls[num_calls].client =
+ call_state *cs = new_call(active_call, CLIENT);
+ cs->call =
grpc_channel_create_call(g_channel, parent_call, propagation_mask,
cq, method, host, deadline, NULL);
} else {
@@ -573,29 +590,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}
// switch the 'current' call
case 11: {
- uint8_t new_current = next_byte(&inp);
- if (new_current == 0 || new_current >= num_calls) {
- end(&inp);
- } else {
- GPR_SWAP(call_state, calls[0], calls[new_current]);
- }
+ active_call = active_call->next;
break;
}
// queue some ops on a call
case 12: {
+ if (active_call->type == ROOT || active_call->call == NULL) {
+ end(&inp);
+ break;
+ }
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;
- }
+ bool ok = true;
size_t i;
grpc_op *op;
for (i = 0; i < num_ops; i++) {
@@ -627,25 +633,25 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break;
case 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;
case 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;
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.status = &active_call->status;
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 =
- &calls[0].recv_status_details;
+ &active_call->recv_status_details;
op->data.recv_status_on_client.status_details_capacity =
- &calls[0].recv_status_details_capacity;
+ &active_call->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;
+ op->data.recv_close_on_server.cancelled = &active_call->cancelled;
break;
}
op->reserved = NULL;
@@ -655,7 +661,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
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,
+ active_call->call, ops, num_ops,
v, NULL);
if (error != GRPC_CALL_OK) {
v->validate(v->arg, false);
@@ -697,44 +703,26 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break;
}
- // cancel current call on client
+ // cancel current call
case 13: {
- if (num_calls > 0 && calls[0].client) {
- grpc_call_cancel(calls[0].client, NULL);
+ if (active_call->type != ROOT && active_call->call != NULL) {
+ grpc_call_cancel(active_call->call, NULL);
} else {
end(&inp);
}
break;
}
- // cancel current call on server
+ // get a calls peer
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));
+ if (active_call->type != ROOT && active_call->call != NULL) {
+ free_non_null(grpc_call_get_peer(active_call->call));
} else {
end(&inp);
}
break;
}
// get a channels target
- case 17: {
+ case 15: {
if (g_channel != NULL) {
free_non_null(grpc_channel_get_target(g_channel));
} else {
@@ -743,7 +731,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break;
}
// send a ping on a channel
- case 18: {
+ case 16: {
if (g_channel != NULL) {
pending_pings++;
grpc_channel_ping(g_channel, cq,
@@ -754,14 +742,14 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
break;
}
// enable a tracer
- case 19: {
+ case 17: {
char *tracer = read_string(&inp);
grpc_tracer_set_enabled(tracer, 1);
gpr_free(tracer);
break;
}
// disable a tracer
- case 20: {
+ case 18: {
char *tracer = read_string(&inp);
grpc_tracer_set_enabled(tracer, 0);
gpr_free(tracer);