blob: c1c5966801683523caeca525c25822b2db154a1a [file] [log] [blame]
Craig Tillerfc98f922016-04-13 08:45:06 -07001/*
2 *
3 * Copyright 2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include <string.h>
35
36#include <grpc/grpc.h>
37#include <grpc/support/alloc.h>
38#include <grpc/support/log.h>
39#include <grpc/support/string_util.h>
40
Craig Tillerd2fd7692016-04-13 22:44:48 -070041#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
Craig Tillerfc98f922016-04-13 08:45:06 -070042#include "src/core/lib/channel/channel_args.h"
Craig Tiller99f67d12016-04-13 10:52:23 -070043#include "src/core/lib/iomgr/resolve_address.h"
Craig Tillere6282612016-04-13 14:14:34 -070044#include "src/core/lib/iomgr/tcp_client.h"
Craig Tiller24d687e2016-04-13 19:47:27 -070045#include "src/core/lib/iomgr/timer.h"
Craig Tiller62c7a5a2016-04-13 22:25:03 -070046#include "src/core/lib/surface/server.h"
Craig Tillerd2fd7692016-04-13 22:44:48 -070047#include "src/core/lib/transport/metadata.h"
Craig Tiller62c7a5a2016-04-13 22:25:03 -070048#include "test/core/util/passthru_endpoint.h"
Craig Tillerfc98f922016-04-13 08:45:06 -070049
50////////////////////////////////////////////////////////////////////////////////
51// logging
52
Craig Tiller42fe4cd2016-04-23 12:50:46 -070053static const bool squelch = true;
Craig Tillerfc98f922016-04-13 08:45:06 -070054
55static void dont_log(gpr_log_func_args *args) {}
56
57////////////////////////////////////////////////////////////////////////////////
58// input_stream: allows easy access to input bytes, and allows reading a little
59// past the end (avoiding needing to check everywhere)
60
61typedef struct {
62 const uint8_t *cur;
63 const uint8_t *end;
64} input_stream;
65
66static uint8_t next_byte(input_stream *inp) {
67 if (inp->cur == inp->end) {
68 return 0;
69 }
70 return *inp->cur++;
71}
72
Craig Tillerac82c182016-04-14 09:29:13 -070073static void end(input_stream *inp) { inp->cur = inp->end; }
74
Craig Tillerfc98f922016-04-13 08:45:06 -070075static char *read_string(input_stream *inp) {
Craig Tiller7673f7a2016-04-18 22:44:57 -070076 char *str = NULL;
77 size_t cap = 0;
78 size_t sz = 0;
79 char c;
80 do {
81 if (cap == sz) {
Craig Tiller33fd9fa2016-04-19 16:13:21 -070082 cap = GPR_MAX(3 * cap / 2, cap + 8);
Craig Tiller7673f7a2016-04-18 22:44:57 -070083 str = gpr_realloc(str, cap);
84 }
85 c = (char)next_byte(inp);
86 str[sz++] = c;
87 } while (c != 0);
Craig Tillerfc98f922016-04-13 08:45:06 -070088 return str;
89}
90
Craig Tillerba0d6ac2016-04-15 13:07:54 -070091static void read_buffer(input_stream *inp, char **buffer, size_t *length) {
92 *length = next_byte(inp);
93 *buffer = gpr_malloc(*length);
94 for (size_t i = 0; i < *length; i++) {
95 (*buffer)[i] = (char)next_byte(inp);
96 }
97}
98
Craig Tillerf5823052016-04-15 15:22:09 -070099static uint32_t read_uint22(input_stream *inp) {
100 uint8_t b = next_byte(inp);
101 uint32_t x = b & 0x7f;
102 if (b & 0x80) {
103 x <<= 7;
104 b = next_byte(inp);
105 x |= b & 0x7f;
106 if (b & 0x80) {
107 x <<= 8;
108 x |= next_byte(inp);
109 }
110 }
111 return x;
112}
113
Craig Tillerfc98f922016-04-13 08:45:06 -0700114static uint32_t read_uint32(input_stream *inp) {
115 uint8_t b = next_byte(inp);
116 uint32_t x = b & 0x7f;
117 if (b & 0x80) {
118 x <<= 7;
119 b = next_byte(inp);
120 x |= b & 0x7f;
121 if (b & 0x80) {
122 x <<= 7;
123 b = next_byte(inp);
124 x |= b & 0x7f;
125 if (b & 0x80) {
126 x <<= 7;
127 b = next_byte(inp);
128 x |= b & 0x7f;
129 if (b & 0x80) {
130 x = (x << 4) | (next_byte(inp) & 0x0f);
131 }
132 }
133 }
134 }
135 return x;
136}
137
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700138static grpc_byte_buffer *read_message(input_stream *inp) {
Craig Tillerf5823052016-04-15 15:22:09 -0700139 gpr_slice slice = gpr_slice_malloc(read_uint22(inp));
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700140 memset(GPR_SLICE_START_PTR(slice), 0, GPR_SLICE_LENGTH(slice));
Craig Tillerd78ca882016-04-22 14:47:05 -0700141 grpc_byte_buffer *out = grpc_raw_byte_buffer_create(&slice, 1);
142 gpr_slice_unref(slice);
143 return out;
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700144}
145
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700146static void read_metadata(input_stream *inp, size_t *count,
147 grpc_metadata **metadata) {
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700148 *count = next_byte(inp);
149 *metadata = gpr_malloc(*count * sizeof(**metadata));
150 memset(*metadata, 0, *count * sizeof(**metadata));
151 for (size_t i = 0; i < *count; i++) {
152 (*metadata)[i].key = read_string(inp);
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700153 read_buffer(inp, (char **)&(*metadata)[i].value,
154 &(*metadata)[i].value_length);
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700155 (*metadata)[i].flags = read_uint32(inp);
156 }
157}
158
Craig Tillerfc98f922016-04-13 08:45:06 -0700159static int read_int(input_stream *inp) { return (int)read_uint32(inp); }
160
161static grpc_channel_args *read_args(input_stream *inp) {
162 size_t n = next_byte(inp);
163 grpc_arg *args = gpr_malloc(sizeof(*args) * n);
164 for (size_t i = 0; i < n; i++) {
165 bool is_string = next_byte(inp) & 1;
166 args[i].type = is_string ? GRPC_ARG_STRING : GRPC_ARG_INTEGER;
167 args[i].key = read_string(inp);
168 if (is_string) {
169 args[i].value.string = read_string(inp);
170 } else {
171 args[i].value.integer = read_int(inp);
172 }
173 }
174 grpc_channel_args *a = gpr_malloc(sizeof(*a));
175 a->args = args;
176 a->num_args = n;
177 return a;
178}
179
180static bool is_eof(input_stream *inp) { return inp->cur == inp->end; }
181
182////////////////////////////////////////////////////////////////////////////////
183// global state
184
Craig Tillerfc98f922016-04-13 08:45:06 -0700185static gpr_timespec g_now;
Craig Tillerf224c0c2016-04-13 20:15:13 -0700186static grpc_server *g_server;
187static grpc_channel *g_channel;
Craig Tillerfc98f922016-04-13 08:45:06 -0700188
189extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type);
190
191static gpr_timespec now_impl(gpr_clock_type clock_type) {
192 GPR_ASSERT(clock_type != GPR_TIMESPAN);
Craig Tillerd0b25232016-04-13 19:54:34 -0700193 return g_now;
Craig Tiller99f67d12016-04-13 10:52:23 -0700194}
195
196////////////////////////////////////////////////////////////////////////////////
197// dns resolution
198
Craig Tiller24d687e2016-04-13 19:47:27 -0700199typedef struct addr_req {
200 grpc_timer timer;
201 char *addr;
202 grpc_resolve_cb cb;
203 void *arg;
204} addr_req;
205
206static void finish_resolve(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
Craig Tiller24d687e2016-04-13 19:47:27 -0700207 addr_req *r = arg;
208
Craig Tiller849155d2016-04-13 20:21:42 -0700209 if (success && 0 == strcmp(r->addr, "server")) {
Craig Tiller99f67d12016-04-13 10:52:23 -0700210 grpc_resolved_addresses *addrs = gpr_malloc(sizeof(*addrs));
211 addrs->naddrs = 1;
212 addrs->addrs = gpr_malloc(sizeof(*addrs->addrs));
213 addrs->addrs[0].len = 0;
Craig Tiller24d687e2016-04-13 19:47:27 -0700214 r->cb(exec_ctx, r->arg, addrs);
Craig Tiller99f67d12016-04-13 10:52:23 -0700215 } else {
Craig Tiller24d687e2016-04-13 19:47:27 -0700216 r->cb(exec_ctx, r->arg, NULL);
Craig Tiller99f67d12016-04-13 10:52:23 -0700217 }
Craig Tiller24d687e2016-04-13 19:47:27 -0700218
219 gpr_free(r->addr);
220 gpr_free(r);
221}
222
223void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
224 const char *default_port, grpc_resolve_cb cb,
225 void *arg) {
226 addr_req *r = gpr_malloc(sizeof(*r));
227 r->addr = gpr_strdup(addr);
228 r->cb = cb;
229 r->arg = arg;
230 grpc_timer_init(exec_ctx, &r->timer,
231 gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
232 gpr_time_from_seconds(1, GPR_TIMESPAN)),
233 finish_resolve, r, gpr_now(GPR_CLOCK_MONOTONIC));
Craig Tiller99f67d12016-04-13 10:52:23 -0700234}
235
Craig Tillerfc98f922016-04-13 08:45:06 -0700236////////////////////////////////////////////////////////////////////////////////
Craig Tillere6282612016-04-13 14:14:34 -0700237// client connection
Craig Tillerfc98f922016-04-13 08:45:06 -0700238
Craig Tillere6282612016-04-13 14:14:34 -0700239// defined in tcp_client_posix.c
240extern void (*grpc_tcp_client_connect_impl)(
241 grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_endpoint **ep,
242 grpc_pollset_set *interested_parties, const struct sockaddr *addr,
243 size_t addr_len, gpr_timespec deadline);
244
Craig Tillerd2fd7692016-04-13 22:44:48 -0700245static void sched_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
246 grpc_endpoint **ep, gpr_timespec deadline);
Craig Tillerf224c0c2016-04-13 20:15:13 -0700247
248typedef struct {
249 grpc_timer timer;
250 grpc_closure *closure;
251 grpc_endpoint **ep;
252 gpr_timespec deadline;
253} future_connect;
254
255static void do_connect(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
256 future_connect *fc = arg;
Craig Tillerf4cc2f82016-04-13 20:47:37 -0700257 if (!success) {
258 *fc->ep = NULL;
259 grpc_exec_ctx_enqueue(exec_ctx, fc->closure, false, NULL);
260 } else if (g_server != NULL) {
Craig Tiller62c7a5a2016-04-13 22:25:03 -0700261 grpc_endpoint *client;
262 grpc_endpoint *server;
263 grpc_passthru_endpoint_create(&client, &server);
264 *fc->ep = client;
265
266 grpc_transport *transport =
267 grpc_create_chttp2_transport(exec_ctx, NULL, server, 0);
268 grpc_server_setup_transport(exec_ctx, g_server, transport, NULL);
269 grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0);
270
271 grpc_exec_ctx_enqueue(exec_ctx, fc->closure, false, NULL);
Craig Tillerf224c0c2016-04-13 20:15:13 -0700272 } else {
273 sched_connect(exec_ctx, fc->closure, fc->ep, fc->deadline);
274 }
275 gpr_free(fc);
276}
277
Craig Tillerd2fd7692016-04-13 22:44:48 -0700278static void sched_connect(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
279 grpc_endpoint **ep, gpr_timespec deadline) {
Craig Tillerf4cc2f82016-04-13 20:47:37 -0700280 if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) <= 0) {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700281 *ep = NULL;
282 grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL);
283 return;
284 }
Craig Tillerd2fd7692016-04-13 22:44:48 -0700285
Craig Tillerf224c0c2016-04-13 20:15:13 -0700286 future_connect *fc = gpr_malloc(sizeof(*fc));
287 fc->closure = closure;
288 fc->ep = ep;
289 fc->deadline = deadline;
290 grpc_timer_init(exec_ctx, &fc->timer,
291 gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
292 gpr_time_from_millis(1, GPR_TIMESPAN)),
293 do_connect, fc, gpr_now(GPR_CLOCK_MONOTONIC));
294}
295
Craig Tillere6282612016-04-13 14:14:34 -0700296static void my_tcp_client_connect(grpc_exec_ctx *exec_ctx,
297 grpc_closure *closure, grpc_endpoint **ep,
298 grpc_pollset_set *interested_parties,
299 const struct sockaddr *addr, size_t addr_len,
300 gpr_timespec deadline) {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700301 sched_connect(exec_ctx, closure, ep, deadline);
Craig Tillere6282612016-04-13 14:14:34 -0700302}
Craig Tillerfc98f922016-04-13 08:45:06 -0700303
304////////////////////////////////////////////////////////////////////////////////
305// test driver
306
Craig Tiller36750ed2016-04-14 08:58:35 -0700307typedef struct validator {
308 void (*validate)(void *arg, bool success);
309 void *arg;
310} validator;
Craig Tiller156a2f32016-04-13 09:03:31 -0700311
Craig Tiller36750ed2016-04-14 08:58:35 -0700312static validator *create_validator(void (*validate)(void *arg, bool success),
313 void *arg) {
314 validator *v = gpr_malloc(sizeof(*v));
315 v->validate = validate;
316 v->arg = arg;
317 return v;
318}
319
320static void assert_success_and_decrement(void *counter, bool success) {
321 GPR_ASSERT(success);
322 --*(int *)counter;
323}
324
Craig Tiller1395e192016-04-14 12:49:27 -0700325static void decrement(void *counter, bool success) { --*(int *)counter; }
326
Craig Tiller36750ed2016-04-14 08:58:35 -0700327typedef struct connectivity_watch {
328 int *counter;
329 gpr_timespec deadline;
330} connectivity_watch;
331
332static connectivity_watch *make_connectivity_watch(gpr_timespec s,
333 int *counter) {
334 connectivity_watch *o = gpr_malloc(sizeof(*o));
335 o->deadline = s;
336 o->counter = counter;
337 return o;
338}
339
340static void validate_connectivity_watch(void *p, bool success) {
341 connectivity_watch *w = p;
342 if (!success) {
343 GPR_ASSERT(gpr_time_cmp(gpr_now(w->deadline.clock_type), w->deadline) >= 0);
344 }
345 --*w->counter;
346 gpr_free(w);
347}
Craig Tiller156a2f32016-04-13 09:03:31 -0700348
Craig Tiller1395e192016-04-14 12:49:27 -0700349static void free_non_null(void *p) {
350 GPR_ASSERT(p != NULL);
351 gpr_free(p);
352}
353
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700354typedef enum { ROOT, CLIENT, SERVER, PENDING_SERVER } call_state_type;
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700355
Craig Tillerac82c182016-04-14 09:29:13 -0700356typedef struct call_state {
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700357 call_state_type type;
358 grpc_call *call;
359 grpc_byte_buffer *recv_message;
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700360 grpc_status_code status;
Craig Tiller1395e192016-04-14 12:49:27 -0700361 grpc_metadata_array recv_initial_metadata;
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700362 grpc_metadata_array recv_trailing_metadata;
363 char *recv_status_details;
364 size_t recv_status_details_capacity;
365 int cancelled;
Craig Tiller6321cf22016-04-21 14:37:23 -0700366 int pending_ops;
Craig Tillerdbfc8952016-04-18 22:58:10 -0700367 grpc_call_details call_details;
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700368
369 struct call_state *next;
370 struct call_state *prev;
Craig Tillerac82c182016-04-14 09:29:13 -0700371} call_state;
372
Craig Tiller6321cf22016-04-21 14:37:23 -0700373static call_state *g_active_call;
374
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700375static call_state *new_call(call_state *sibling, call_state_type type) {
376 call_state *c = gpr_malloc(sizeof(*c));
377 memset(c, 0, sizeof(*c));
378 if (sibling != NULL) {
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700379 c->next = sibling;
380 c->prev = sibling->prev;
381 c->next->prev = c->prev->next = c;
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700382 } else {
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700383 c->next = c->prev = c;
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700384 }
385 c->type = type;
386 return c;
387}
388
Craig Tiller6321cf22016-04-21 14:37:23 -0700389static call_state *maybe_delete_call_state(call_state *call) {
Craig Tiller36cce532016-04-19 17:02:49 -0700390 call_state *next = call->next;
Craig Tiller2b3d33a2016-04-21 14:51:44 -0700391
Craig Tiller36cce532016-04-19 17:02:49 -0700392 if (call->call != NULL) return next;
Craig Tiller6321cf22016-04-21 14:37:23 -0700393 if (call->pending_ops != 0) return next;
Craig Tiller36cce532016-04-19 17:02:49 -0700394
Craig Tiller6321cf22016-04-21 14:37:23 -0700395 if (call == g_active_call) {
396 g_active_call = call->next;
397 GPR_ASSERT(call != g_active_call);
Craig Tiller36cce532016-04-19 17:02:49 -0700398 }
399
400 call->prev->next = call->next;
401 call->next->prev = call->prev;
402 grpc_metadata_array_destroy(&call->recv_initial_metadata);
403 grpc_metadata_array_destroy(&call->recv_trailing_metadata);
404 gpr_free(call->recv_status_details);
405 grpc_call_details_destroy(&call->call_details);
406 gpr_free(call);
407
408 return next;
409}
410
Craig Tiller6321cf22016-04-21 14:37:23 -0700411static call_state *destroy_call(call_state *call) {
Craig Tiller36cce532016-04-19 17:02:49 -0700412 grpc_call_destroy(call->call);
413 call->call = NULL;
Craig Tiller6321cf22016-04-21 14:37:23 -0700414 return maybe_delete_call_state(call);
415}
416
417static void finished_request_call(void *csp, bool success) {
418 call_state *cs = csp;
419 GPR_ASSERT(cs->pending_ops > 0);
420 --cs->pending_ops;
421 if (success) {
422 GPR_ASSERT(cs->call != NULL);
423 cs->type = SERVER;
424 } else {
425 maybe_delete_call_state(cs);
426 }
427}
428
429static void finished_batch(void *csp, bool success) {
430 call_state *cs = csp;
431 --cs->pending_ops;
432 maybe_delete_call_state(cs);
Craig Tiller36cce532016-04-19 17:02:49 -0700433}
434
Craig Tillerfc98f922016-04-13 08:45:06 -0700435int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
436 grpc_test_only_set_metadata_hash_seed(0);
437 if (squelch) gpr_set_log_function(dont_log);
438 input_stream inp = {data, data + size};
Craig Tiller24d687e2016-04-13 19:47:27 -0700439 grpc_resolve_address = my_resolve_address;
Craig Tillere6282612016-04-13 14:14:34 -0700440 grpc_tcp_client_connect_impl = my_tcp_client_connect;
Craig Tillerfc98f922016-04-13 08:45:06 -0700441 gpr_now_impl = now_impl;
442 grpc_init();
443
Craig Tillerf224c0c2016-04-13 20:15:13 -0700444 GPR_ASSERT(g_channel == NULL);
445 GPR_ASSERT(g_server == NULL);
446
Craig Tiller156a2f32016-04-13 09:03:31 -0700447 bool server_shutdown = false;
448 int pending_server_shutdowns = 0;
Craig Tillerd2fd7692016-04-13 22:44:48 -0700449 int pending_channel_watches = 0;
Craig Tiller1395e192016-04-14 12:49:27 -0700450 int pending_pings = 0;
Craig Tillerfc98f922016-04-13 08:45:06 -0700451
Craig Tiller6321cf22016-04-21 14:37:23 -0700452 g_active_call = new_call(NULL, ROOT);
Craig Tillerac82c182016-04-14 09:29:13 -0700453
Craig Tillerfc98f922016-04-13 08:45:06 -0700454 grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
455
Craig Tillerd2fd7692016-04-13 22:44:48 -0700456 while (!is_eof(&inp) || g_channel != NULL || g_server != NULL ||
Craig Tiller2b3d33a2016-04-21 14:51:44 -0700457 pending_channel_watches > 0 || pending_pings > 0 ||
458 g_active_call->type != ROOT || g_active_call->next != g_active_call) {
Craig Tiller156a2f32016-04-13 09:03:31 -0700459 if (is_eof(&inp)) {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700460 if (g_channel != NULL) {
461 grpc_channel_destroy(g_channel);
462 g_channel = NULL;
Craig Tiller156a2f32016-04-13 09:03:31 -0700463 }
Craig Tillerf224c0c2016-04-13 20:15:13 -0700464 if (g_server != NULL) {
Craig Tiller156a2f32016-04-13 09:03:31 -0700465 if (!server_shutdown) {
Craig Tiller36750ed2016-04-14 08:58:35 -0700466 grpc_server_shutdown_and_notify(
467 g_server, cq, create_validator(assert_success_and_decrement,
468 &pending_server_shutdowns));
Craig Tiller156a2f32016-04-13 09:03:31 -0700469 server_shutdown = true;
Craig Tiller481635c2016-04-13 10:30:10 -0700470 pending_server_shutdowns++;
Craig Tiller156a2f32016-04-13 09:03:31 -0700471 } else if (pending_server_shutdowns == 0) {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700472 grpc_server_destroy(g_server);
473 g_server = NULL;
Craig Tiller156a2f32016-04-13 09:03:31 -0700474 }
475 }
Craig Tiller6321cf22016-04-21 14:37:23 -0700476 call_state *s = g_active_call;
Craig Tiller36cce532016-04-19 17:02:49 -0700477 do {
478 if (s->type != PENDING_SERVER && s->call != NULL) {
Craig Tiller6321cf22016-04-21 14:37:23 -0700479 s = destroy_call(s);
Craig Tillerffae0172016-04-19 20:47:50 -0700480 } else {
481 s = s->next;
Craig Tiller36cce532016-04-19 17:02:49 -0700482 }
Craig Tiller6321cf22016-04-21 14:37:23 -0700483 } while (s != g_active_call);
Craig Tiller99f67d12016-04-13 10:52:23 -0700484
Craig Tiller99f67d12016-04-13 10:52:23 -0700485 g_now = gpr_time_add(g_now, gpr_time_from_seconds(1, GPR_TIMESPAN));
Craig Tiller156a2f32016-04-13 09:03:31 -0700486 }
487
Craig Tillerfc98f922016-04-13 08:45:06 -0700488 switch (next_byte(&inp)) {
Craig Tillerc1e07762016-04-13 20:49:29 -0700489 // terminate on bad bytes
490 default:
Craig Tillerac82c182016-04-14 09:29:13 -0700491 end(&inp);
Craig Tillerc1e07762016-04-13 20:49:29 -0700492 break;
Craig Tillerfc98f922016-04-13 08:45:06 -0700493 // tickle completion queue
494 case 0: {
495 grpc_event ev = grpc_completion_queue_next(
496 cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
497 switch (ev.type) {
Craig Tiller36750ed2016-04-14 08:58:35 -0700498 case GRPC_OP_COMPLETE: {
499 validator *v = ev.tag;
500 v->validate(v->arg, ev.success);
501 gpr_free(v);
Craig Tillerfc98f922016-04-13 08:45:06 -0700502 break;
Craig Tiller36750ed2016-04-14 08:58:35 -0700503 }
Craig Tillerfc98f922016-04-13 08:45:06 -0700504 case GRPC_QUEUE_TIMEOUT:
505 break;
506 case GRPC_QUEUE_SHUTDOWN:
507 abort();
508 break;
509 }
510 break;
511 }
512 // increment global time
513 case 1: {
Craig Tillerfc98f922016-04-13 08:45:06 -0700514 g_now = gpr_time_add(
Craig Tiller156a2f32016-04-13 09:03:31 -0700515 g_now, gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
Craig Tillerfc98f922016-04-13 08:45:06 -0700516 break;
517 }
518 // create an insecure channel
519 case 2: {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700520 if (g_channel == NULL) {
Craig Tillerfc98f922016-04-13 08:45:06 -0700521 char *target = read_string(&inp);
522 char *target_uri;
Craig Tiller99f67d12016-04-13 10:52:23 -0700523 gpr_asprintf(&target_uri, "dns:%s", target);
Craig Tillerfc98f922016-04-13 08:45:06 -0700524 grpc_channel_args *args = read_args(&inp);
Craig Tillerf224c0c2016-04-13 20:15:13 -0700525 g_channel = grpc_insecure_channel_create(target_uri, args, NULL);
526 GPR_ASSERT(g_channel != NULL);
Craig Tillerfc98f922016-04-13 08:45:06 -0700527 grpc_channel_args_destroy(args);
528 gpr_free(target_uri);
529 gpr_free(target);
Craig Tillerac82c182016-04-14 09:29:13 -0700530 } else {
531 end(&inp);
Craig Tillerfc98f922016-04-13 08:45:06 -0700532 }
533 break;
534 }
535 // destroy a channel
536 case 3: {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700537 if (g_channel != NULL) {
538 grpc_channel_destroy(g_channel);
539 g_channel = NULL;
Craig Tillerac82c182016-04-14 09:29:13 -0700540 } else {
541 end(&inp);
Craig Tillerfc98f922016-04-13 08:45:06 -0700542 }
543 break;
544 }
545 // bring up a server
546 case 4: {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700547 if (g_server == NULL) {
Craig Tillerfc98f922016-04-13 08:45:06 -0700548 grpc_channel_args *args = read_args(&inp);
Craig Tillerf224c0c2016-04-13 20:15:13 -0700549 g_server = grpc_server_create(args, NULL);
550 GPR_ASSERT(g_server != NULL);
Craig Tillerfc98f922016-04-13 08:45:06 -0700551 grpc_channel_args_destroy(args);
Craig Tillerf224c0c2016-04-13 20:15:13 -0700552 grpc_server_register_completion_queue(g_server, cq, NULL);
553 grpc_server_start(g_server);
Craig Tiller156a2f32016-04-13 09:03:31 -0700554 server_shutdown = false;
555 GPR_ASSERT(pending_server_shutdowns == 0);
Craig Tillerac82c182016-04-14 09:29:13 -0700556 } else {
557 end(&inp);
Craig Tillerfc98f922016-04-13 08:45:06 -0700558 }
559 }
Craig Tiller156a2f32016-04-13 09:03:31 -0700560 // begin server shutdown
561 case 5: {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700562 if (g_server != NULL) {
Craig Tiller36750ed2016-04-14 08:58:35 -0700563 grpc_server_shutdown_and_notify(
564 g_server, cq, create_validator(assert_success_and_decrement,
565 &pending_server_shutdowns));
Craig Tiller156a2f32016-04-13 09:03:31 -0700566 pending_server_shutdowns++;
567 server_shutdown = true;
Craig Tillerac82c182016-04-14 09:29:13 -0700568 } else {
569 end(&inp);
Craig Tiller156a2f32016-04-13 09:03:31 -0700570 }
571 break;
572 }
573 // cancel all calls if shutdown
574 case 6: {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700575 if (g_server != NULL && server_shutdown) {
576 grpc_server_cancel_all_calls(g_server);
Craig Tillerac82c182016-04-14 09:29:13 -0700577 } else {
578 end(&inp);
Craig Tiller156a2f32016-04-13 09:03:31 -0700579 }
580 break;
581 }
582 // destroy server
583 case 7: {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700584 if (g_server != NULL && server_shutdown &&
Craig Tiller481635c2016-04-13 10:30:10 -0700585 pending_server_shutdowns == 0) {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700586 grpc_server_destroy(g_server);
587 g_server = NULL;
Craig Tillerac82c182016-04-14 09:29:13 -0700588 } else {
589 end(&inp);
Craig Tiller156a2f32016-04-13 09:03:31 -0700590 }
591 break;
592 }
Craig Tillere6282612016-04-13 14:14:34 -0700593 // check connectivity
594 case 8: {
Craig Tillerf224c0c2016-04-13 20:15:13 -0700595 if (g_channel != NULL) {
Craig Tillerac82c182016-04-14 09:29:13 -0700596 uint8_t try_to_connect = next_byte(&inp);
597 if (try_to_connect == 0 || try_to_connect == 1) {
598 grpc_channel_check_connectivity_state(g_channel, try_to_connect);
599 } else {
600 end(&inp);
601 }
602 } else {
603 end(&inp);
Craig Tillere6282612016-04-13 14:14:34 -0700604 }
605 break;
606 }
Craig Tillerd2fd7692016-04-13 22:44:48 -0700607 // watch connectivity
608 case 9: {
609 if (g_channel != NULL) {
610 grpc_connectivity_state st =
611 grpc_channel_check_connectivity_state(g_channel, 0);
612 if (st != GRPC_CHANNEL_FATAL_FAILURE) {
Craig Tiller36750ed2016-04-14 08:58:35 -0700613 gpr_timespec deadline = gpr_time_add(
614 gpr_now(GPR_CLOCK_REALTIME),
615 gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
Craig Tillerd2fd7692016-04-13 22:44:48 -0700616 grpc_channel_watch_connectivity_state(
Craig Tiller36750ed2016-04-14 08:58:35 -0700617 g_channel, st, deadline, cq,
618 create_validator(validate_connectivity_watch,
619 make_connectivity_watch(
620 deadline, &pending_channel_watches)));
Craig Tillerd2fd7692016-04-13 22:44:48 -0700621 pending_channel_watches++;
622 }
Craig Tillerac82c182016-04-14 09:29:13 -0700623 } else {
624 end(&inp);
Craig Tillerd2fd7692016-04-13 22:44:48 -0700625 }
Craig Tillerac82c182016-04-14 09:29:13 -0700626 break;
627 }
628 // create a call
629 case 10: {
630 bool ok = true;
631 if (g_channel == NULL) ok = false;
Craig Tillerac82c182016-04-14 09:29:13 -0700632 grpc_call *parent_call = NULL;
Craig Tiller6321cf22016-04-21 14:37:23 -0700633 if (g_active_call->type != ROOT) {
634 if (g_active_call->call == NULL || g_active_call->type == CLIENT) {
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700635 end(&inp);
636 break;
637 }
Craig Tiller6321cf22016-04-21 14:37:23 -0700638 parent_call = g_active_call->call;
Craig Tillerac82c182016-04-14 09:29:13 -0700639 }
640 uint32_t propagation_mask = read_uint32(&inp);
641 char *method = read_string(&inp);
642 char *host = read_string(&inp);
643 gpr_timespec deadline =
644 gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
645 gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
646
647 if (ok) {
Craig Tiller6321cf22016-04-21 14:37:23 -0700648 call_state *cs = new_call(g_active_call, CLIENT);
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700649 cs->call =
Craig Tillerac82c182016-04-14 09:29:13 -0700650 grpc_channel_create_call(g_channel, parent_call, propagation_mask,
651 cq, method, host, deadline, NULL);
652 } else {
653 end(&inp);
654 }
Craig Tiller1612abc2016-04-19 19:43:47 -0700655 gpr_free(method);
656 gpr_free(host);
Craig Tillerac82c182016-04-14 09:29:13 -0700657 break;
658 }
659 // switch the 'current' call
660 case 11: {
Craig Tiller6321cf22016-04-21 14:37:23 -0700661 g_active_call = g_active_call->next;
Craig Tillerac82c182016-04-14 09:29:13 -0700662 break;
Craig Tillerd2fd7692016-04-13 22:44:48 -0700663 }
Craig Tiller1395e192016-04-14 12:49:27 -0700664 // queue some ops on a call
665 case 12: {
Craig Tiller2b3d33a2016-04-21 14:51:44 -0700666 if (g_active_call->type == PENDING_SERVER ||
667 g_active_call->type == ROOT || g_active_call->call == NULL) {
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700668 end(&inp);
669 break;
670 }
Craig Tiller1395e192016-04-14 12:49:27 -0700671 size_t num_ops = next_byte(&inp);
Craig Tillercb6d4062016-04-19 19:58:36 -0700672 if (num_ops > 6) {
673 end(&inp);
674 break;
675 }
Craig Tiller1395e192016-04-14 12:49:27 -0700676 grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops);
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700677 bool ok = true;
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700678 size_t i;
679 grpc_op *op;
680 for (i = 0; i < num_ops; i++) {
681 op = &ops[i];
Craig Tiller1395e192016-04-14 12:49:27 -0700682 switch (next_byte(&inp)) {
683 default:
Craig Tillercb6d4062016-04-19 19:58:36 -0700684 /* invalid value */
Craig Tiller7bbcd742016-04-19 20:00:16 -0700685 op->op = (grpc_op_type)-1;
Craig Tiller1395e192016-04-14 12:49:27 -0700686 ok = false;
687 break;
688 case GRPC_OP_SEND_INITIAL_METADATA:
689 op->op = GRPC_OP_SEND_INITIAL_METADATA;
Craig Tiller1395e192016-04-14 12:49:27 -0700690 read_metadata(&inp, &op->data.send_initial_metadata.count,
691 &op->data.send_initial_metadata.metadata);
692 break;
693 case GRPC_OP_SEND_MESSAGE:
Craig Tiller2ca75bf2016-04-15 13:19:55 -0700694 op->op = GRPC_OP_SEND_MESSAGE;
Craig Tiller1395e192016-04-14 12:49:27 -0700695 op->data.send_message = read_message(&inp);
696 break;
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700697 case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
698 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
699 break;
Craig Tiller1395e192016-04-14 12:49:27 -0700700 case GRPC_OP_SEND_STATUS_FROM_SERVER:
701 op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
702 read_metadata(
703 &inp,
704 &op->data.send_status_from_server.trailing_metadata_count,
705 &op->data.send_status_from_server.trailing_metadata);
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700706 op->data.send_status_from_server.status = next_byte(&inp);
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700707 op->data.send_status_from_server.status_details =
708 read_string(&inp);
Craig Tiller1395e192016-04-14 12:49:27 -0700709 break;
710 case GRPC_OP_RECV_INITIAL_METADATA:
711 op->op = GRPC_OP_RECV_INITIAL_METADATA;
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700712 op->data.recv_initial_metadata =
Craig Tiller6321cf22016-04-21 14:37:23 -0700713 &g_active_call->recv_initial_metadata;
Craig Tiller1395e192016-04-14 12:49:27 -0700714 break;
715 case GRPC_OP_RECV_MESSAGE:
716 op->op = GRPC_OP_RECV_MESSAGE;
Craig Tiller6321cf22016-04-21 14:37:23 -0700717 op->data.recv_message = &g_active_call->recv_message;
Craig Tiller1395e192016-04-14 12:49:27 -0700718 break;
719 case GRPC_OP_RECV_STATUS_ON_CLIENT:
720 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
Craig Tiller6321cf22016-04-21 14:37:23 -0700721 op->data.recv_status_on_client.status = &g_active_call->status;
Craig Tiller1395e192016-04-14 12:49:27 -0700722 op->data.recv_status_on_client.trailing_metadata =
Craig Tiller6321cf22016-04-21 14:37:23 -0700723 &g_active_call->recv_trailing_metadata;
Craig Tiller1395e192016-04-14 12:49:27 -0700724 op->data.recv_status_on_client.status_details =
Craig Tiller6321cf22016-04-21 14:37:23 -0700725 &g_active_call->recv_status_details;
Craig Tiller1395e192016-04-14 12:49:27 -0700726 op->data.recv_status_on_client.status_details_capacity =
Craig Tiller6321cf22016-04-21 14:37:23 -0700727 &g_active_call->recv_status_details_capacity;
Craig Tiller1395e192016-04-14 12:49:27 -0700728 break;
729 case GRPC_OP_RECV_CLOSE_ON_SERVER:
730 op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
Craig Tiller2b3d33a2016-04-21 14:51:44 -0700731 op->data.recv_close_on_server.cancelled =
732 &g_active_call->cancelled;
Craig Tiller1395e192016-04-14 12:49:27 -0700733 break;
734 }
735 op->reserved = NULL;
736 op->flags = read_uint32(&inp);
Craig Tiller3e0d9362016-04-15 13:36:25 -0700737 }
738 if (ok) {
Craig Tiller6321cf22016-04-21 14:37:23 -0700739 validator *v = create_validator(finished_batch, g_active_call);
740 g_active_call->pending_ops++;
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700741 grpc_call_error error =
Craig Tiller6321cf22016-04-21 14:37:23 -0700742 grpc_call_start_batch(g_active_call->call, ops, num_ops, v, NULL);
Craig Tiller3e0d9362016-04-15 13:36:25 -0700743 if (error != GRPC_CALL_OK) {
744 v->validate(v->arg, false);
745 gpr_free(v);
Craig Tiller1395e192016-04-14 12:49:27 -0700746 }
Craig Tiller3e0d9362016-04-15 13:36:25 -0700747 } else {
748 end(&inp);
749 }
750 for (i = 0; i < num_ops; i++) {
751 op = &ops[i];
752 switch (op->op) {
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700753 case GRPC_OP_SEND_INITIAL_METADATA:
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700754 for (size_t j = 0; j < op->data.send_initial_metadata.count;
755 j++) {
756 gpr_free(
757 (void *)op->data.send_initial_metadata.metadata[j].key);
758 gpr_free(
759 (void *)op->data.send_initial_metadata.metadata[j].value);
Craig Tiller41703582016-04-15 13:27:40 -0700760 }
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700761 gpr_free(op->data.send_initial_metadata.metadata);
762 break;
763 case GRPC_OP_SEND_MESSAGE:
764 grpc_byte_buffer_destroy(op->data.send_message);
765 break;
766 case GRPC_OP_SEND_STATUS_FROM_SERVER:
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700767 for (size_t j = 0;
768 j < op->data.send_status_from_server.trailing_metadata_count;
769 j++) {
770 gpr_free((void *)op->data.send_status_from_server
771 .trailing_metadata[j]
772 .key);
773 gpr_free((void *)op->data.send_status_from_server
774 .trailing_metadata[j]
775 .value);
Craig Tiller41703582016-04-15 13:27:40 -0700776 }
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700777 gpr_free(op->data.send_status_from_server.trailing_metadata);
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700778 gpr_free((void *)op->data.send_status_from_server.status_details);
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700779 break;
780 case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
781 case GRPC_OP_RECV_INITIAL_METADATA:
782 case GRPC_OP_RECV_MESSAGE:
783 case GRPC_OP_RECV_STATUS_ON_CLIENT:
784 case GRPC_OP_RECV_CLOSE_ON_SERVER:
785 break;
Craig Tillerba0d6ac2016-04-15 13:07:54 -0700786 }
Craig Tiller1395e192016-04-14 12:49:27 -0700787 }
Craig Tiller3e0d9362016-04-15 13:36:25 -0700788 gpr_free(ops);
789
Craig Tiller1395e192016-04-14 12:49:27 -0700790 break;
791 }
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700792 // cancel current call
Craig Tiller1395e192016-04-14 12:49:27 -0700793 case 13: {
Craig Tiller6321cf22016-04-21 14:37:23 -0700794 if (g_active_call->type != ROOT && g_active_call->call != NULL) {
795 grpc_call_cancel(g_active_call->call, NULL);
Craig Tiller1395e192016-04-14 12:49:27 -0700796 } else {
797 end(&inp);
798 }
799 break;
800 }
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700801 // get a calls peer
Craig Tiller1395e192016-04-14 12:49:27 -0700802 case 14: {
Craig Tiller6321cf22016-04-21 14:37:23 -0700803 if (g_active_call->type != ROOT && g_active_call->call != NULL) {
804 free_non_null(grpc_call_get_peer(g_active_call->call));
Craig Tiller1395e192016-04-14 12:49:27 -0700805 } else {
806 end(&inp);
807 }
808 break;
809 }
810 // get a channels target
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700811 case 15: {
Craig Tiller1395e192016-04-14 12:49:27 -0700812 if (g_channel != NULL) {
813 free_non_null(grpc_channel_get_target(g_channel));
814 } else {
815 end(&inp);
816 }
817 break;
818 }
819 // send a ping on a channel
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700820 case 16: {
Craig Tiller1395e192016-04-14 12:49:27 -0700821 if (g_channel != NULL) {
Craig Tiller36d6f782016-04-15 13:48:21 -0700822 pending_pings++;
Craig Tiller1395e192016-04-14 12:49:27 -0700823 grpc_channel_ping(g_channel, cq,
824 create_validator(decrement, &pending_pings), NULL);
825 } else {
826 end(&inp);
827 }
828 break;
829 }
830 // enable a tracer
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700831 case 17: {
Craig Tiller1395e192016-04-14 12:49:27 -0700832 char *tracer = read_string(&inp);
833 grpc_tracer_set_enabled(tracer, 1);
834 gpr_free(tracer);
835 break;
836 }
837 // disable a tracer
Craig Tiller07f2e5f2016-04-18 22:29:26 -0700838 case 18: {
Craig Tiller1395e192016-04-14 12:49:27 -0700839 char *tracer = read_string(&inp);
840 grpc_tracer_set_enabled(tracer, 0);
841 gpr_free(tracer);
842 break;
843 }
Craig Tillerdbfc8952016-04-18 22:58:10 -0700844 // request a server call
845 case 19: {
846 if (g_server == NULL) {
847 end(&inp);
848 break;
849 }
Craig Tiller6321cf22016-04-21 14:37:23 -0700850 call_state *cs = new_call(g_active_call, PENDING_SERVER);
851 cs->pending_ops++;
852 validator *v = create_validator(finished_request_call, cs);
Craig Tiller33fd9fa2016-04-19 16:13:21 -0700853 grpc_call_error error =
854 grpc_server_request_call(g_server, &cs->call, &cs->call_details,
855 &cs->recv_initial_metadata, cq, cq, v);
856 if (error != GRPC_CALL_OK) {
857 v->validate(v->arg, false);
858 gpr_free(v);
859 }
Craig Tillerdbfc8952016-04-18 22:58:10 -0700860 break;
861 }
Craig Tiller36cce532016-04-19 17:02:49 -0700862 // destroy a call
863 case 20: {
Craig Tiller2b3d33a2016-04-21 14:51:44 -0700864 if (g_active_call->type != ROOT &&
865 g_active_call->type != PENDING_SERVER &&
Craig Tiller6321cf22016-04-21 14:37:23 -0700866 g_active_call->call != NULL) {
867 destroy_call(g_active_call);
Craig Tiller36cce532016-04-19 17:02:49 -0700868 } else {
869 end(&inp);
870 }
871 break;
872 }
Craig Tillerfc98f922016-04-13 08:45:06 -0700873 }
874 }
875
Craig Tillerf224c0c2016-04-13 20:15:13 -0700876 GPR_ASSERT(g_channel == NULL);
877 GPR_ASSERT(g_server == NULL);
Craig Tiller6321cf22016-04-21 14:37:23 -0700878 GPR_ASSERT(g_active_call->type == ROOT);
879 GPR_ASSERT(g_active_call->next == g_active_call);
880 gpr_free(g_active_call);
Craig Tillerf224c0c2016-04-13 20:15:13 -0700881
Craig Tillerfc98f922016-04-13 08:45:06 -0700882 grpc_completion_queue_shutdown(cq);
883 GPR_ASSERT(
884 grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), NULL)
885 .type == GRPC_QUEUE_SHUTDOWN);
886 grpc_completion_queue_destroy(cq);
887
888 grpc_shutdown();
Craig Tillerfc98f922016-04-13 08:45:06 -0700889 return 0;
890}