| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2003-2006 Niels Provos <provos@citi.umich.edu> | |
| 3 * All rights reserved. | |
| 4 * | |
| 5 * Redistribution and use in source and binary forms, with or without | |
| 6 * modification, are permitted provided that the following conditions | |
| 7 * are met: | |
| 8 * 1. Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | |
| 11 * notice, this list of conditions and the following disclaimer in the | |
| 12 * documentation and/or other materials provided with the distribution. | |
| 13 * 3. The name of the author may not be used to endorse or promote products | |
| 14 * derived from this software without specific prior written permission. | |
| 15 * | |
| 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
| 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
| 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
| 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 26 */ | |
| 27 | |
| 28 #ifdef WIN32 | |
| 29 #include <winsock2.h> | |
| 30 #include <windows.h> | |
| 31 #endif | |
| 32 | |
| 33 #ifdef HAVE_CONFIG_H | |
| 34 #include "config.h" | |
| 35 #endif | |
| 36 | |
| 37 #include <sys/types.h> | |
| 38 #include <sys/stat.h> | |
| 39 #ifdef HAVE_SYS_TIME_H | |
| 40 #include <sys/time.h> | |
| 41 #endif | |
| 42 #include <sys/queue.h> | |
| 43 #ifndef WIN32 | |
| 44 #include <sys/socket.h> | |
| 45 #include <signal.h> | |
| 46 #include <unistd.h> | |
| 47 #include <netdb.h> | |
| 48 #endif | |
| 49 #include <fcntl.h> | |
| 50 #include <stdlib.h> | |
| 51 #include <stdio.h> | |
| 52 #include <string.h> | |
| 53 #include <errno.h> | |
| 54 #include <assert.h> | |
| 55 | |
| 56 #include "event.h" | |
| 57 #include "evhttp.h" | |
| 58 #include "log.h" | |
| 59 #include "evrpc.h" | |
| 60 | |
| 61 #include "regress.gen.h" | |
| 62 | |
| 63 void rpc_suite(void); | |
| 64 | |
| 65 extern int test_ok; | |
| 66 | |
| 67 static struct evhttp * | |
| 68 http_setup(short *pport) | |
| 69 { | |
| 70 int i; | |
| 71 struct evhttp *myhttp; | |
| 72 short port = -1; | |
| 73 | |
| 74 /* Try a few different ports */ | |
| 75 for (i = 0; i < 50; ++i) { | |
| 76 myhttp = evhttp_start("127.0.0.1", 8080 + i); | |
| 77 if (myhttp != NULL) { | |
| 78 port = 8080 + i; | |
| 79 break; | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 if (port == -1) | |
| 84 event_errx(1, "Could not start web server"); | |
| 85 | |
| 86 *pport = port; | |
| 87 return (myhttp); | |
| 88 } | |
| 89 | |
| 90 EVRPC_HEADER(Message, msg, kill); | |
| 91 EVRPC_HEADER(NeverReply, msg, kill); | |
| 92 | |
| 93 EVRPC_GENERATE(Message, msg, kill); | |
| 94 EVRPC_GENERATE(NeverReply, msg, kill); | |
| 95 | |
| 96 static int need_input_hook = 0; | |
| 97 static int need_output_hook = 0; | |
| 98 | |
| 99 static void | |
| 100 MessageCb(EVRPC_STRUCT(Message)* rpc, void *arg) | |
| 101 { | |
| 102 struct kill* kill_reply = rpc->reply; | |
| 103 | |
| 104 if (need_input_hook) { | |
| 105 struct evhttp_request* req = EVRPC_REQUEST_HTTP(rpc); | |
| 106 const char *header = evhttp_find_header( | |
| 107 req->input_headers, "X-Hook"); | |
| 108 assert(strcmp(header, "input") == 0); | |
| 109 } | |
| 110 | |
| 111 /* we just want to fill in some non-sense */ | |
| 112 EVTAG_ASSIGN(kill_reply, weapon, "dagger"); | |
| 113 EVTAG_ASSIGN(kill_reply, action, "wave around like an idiot"); | |
| 114 | |
| 115 /* no reply to the RPC */ | |
| 116 EVRPC_REQUEST_DONE(rpc); | |
| 117 } | |
| 118 | |
| 119 static EVRPC_STRUCT(NeverReply) *saved_rpc; | |
| 120 | |
| 121 static void | |
| 122 NeverReplyCb(EVRPC_STRUCT(NeverReply)* rpc, void *arg) | |
| 123 { | |
| 124 test_ok += 1; | |
| 125 saved_rpc = rpc; | |
| 126 } | |
| 127 | |
| 128 static void | |
| 129 rpc_setup(struct evhttp **phttp, short *pport, struct evrpc_base **pbase) | |
| 130 { | |
| 131 short port; | |
| 132 struct evhttp *http = NULL; | |
| 133 struct evrpc_base *base = NULL; | |
| 134 | |
| 135 http = http_setup(&port); | |
| 136 base = evrpc_init(http); | |
| 137 | |
| 138 EVRPC_REGISTER(base, Message, msg, kill, MessageCb, NULL); | |
| 139 EVRPC_REGISTER(base, NeverReply, msg, kill, NeverReplyCb, NULL); | |
| 140 | |
| 141 *phttp = http; | |
| 142 *pport = port; | |
| 143 *pbase = base; | |
| 144 | |
| 145 need_input_hook = 0; | |
| 146 need_output_hook = 0; | |
| 147 } | |
| 148 | |
| 149 static void | |
| 150 rpc_teardown(struct evrpc_base *base) | |
| 151 { | |
| 152 assert(EVRPC_UNREGISTER(base, Message) == 0); | |
| 153 assert(EVRPC_UNREGISTER(base, NeverReply) == 0); | |
| 154 | |
| 155 evrpc_free(base); | |
| 156 } | |
| 157 | |
| 158 static void | |
| 159 rpc_postrequest_failure(struct evhttp_request *req, void *arg) | |
| 160 { | |
| 161 if (req->response_code != HTTP_SERVUNAVAIL) { | |
| 162 | |
| 163 fprintf(stderr, "FAILED (response code)\n"); | |
| 164 exit(1); | |
| 165 } | |
| 166 | |
| 167 test_ok = 1; | |
| 168 event_loopexit(NULL); | |
| 169 } | |
| 170 | |
| 171 /* | |
| 172 * Test a malformed payload submitted as an RPC | |
| 173 */ | |
| 174 | |
| 175 static void | |
| 176 rpc_basic_test(void) | |
| 177 { | |
| 178 short port; | |
| 179 struct evhttp *http = NULL; | |
| 180 struct evrpc_base *base = NULL; | |
| 181 struct evhttp_connection *evcon = NULL; | |
| 182 struct evhttp_request *req = NULL; | |
| 183 | |
| 184 fprintf(stdout, "Testing Basic RPC Support: "); | |
| 185 | |
| 186 rpc_setup(&http, &port, &base); | |
| 187 | |
| 188 evcon = evhttp_connection_new("127.0.0.1", port); | |
| 189 if (evcon == NULL) { | |
| 190 fprintf(stdout, "FAILED\n"); | |
| 191 exit(1); | |
| 192 } | |
| 193 | |
| 194 /* | |
| 195 * At this point, we want to schedule an HTTP POST request | |
| 196 * server using our make request method. | |
| 197 */ | |
| 198 | |
| 199 req = evhttp_request_new(rpc_postrequest_failure, NULL); | |
| 200 if (req == NULL) { | |
| 201 fprintf(stdout, "FAILED\n"); | |
| 202 exit(1); | |
| 203 } | |
| 204 | |
| 205 /* Add the information that we care about */ | |
| 206 evhttp_add_header(req->output_headers, "Host", "somehost"); | |
| 207 evbuffer_add_printf(req->output_buffer, "Some Nonsense"); | |
| 208 | |
| 209 if (evhttp_make_request(evcon, req, | |
| 210 EVHTTP_REQ_POST, | |
| 211 "/.rpc.Message") == -1) { | |
| 212 fprintf(stdout, "FAILED\n"); | |
| 213 exit(1); | |
| 214 } | |
| 215 | |
| 216 test_ok = 0; | |
| 217 | |
| 218 event_dispatch(); | |
| 219 | |
| 220 evhttp_connection_free(evcon); | |
| 221 | |
| 222 rpc_teardown(base); | |
| 223 | |
| 224 if (test_ok != 1) { | |
| 225 fprintf(stdout, "FAILED\n"); | |
| 226 exit(1); | |
| 227 } | |
| 228 | |
| 229 fprintf(stdout, "OK\n"); | |
| 230 | |
| 231 evhttp_free(http); | |
| 232 } | |
| 233 | |
| 234 static void | |
| 235 rpc_postrequest_done(struct evhttp_request *req, void *arg) | |
| 236 { | |
| 237 struct kill* kill_reply = NULL; | |
| 238 | |
| 239 if (req->response_code != HTTP_OK) { | |
| 240 | |
| 241 fprintf(stderr, "FAILED (response code)\n"); | |
| 242 exit(1); | |
| 243 } | |
| 244 | |
| 245 kill_reply = kill_new(); | |
| 246 | |
| 247 if ((kill_unmarshal(kill_reply, req->input_buffer)) == -1) { | |
| 248 fprintf(stderr, "FAILED (unmarshal)\n"); | |
| 249 exit(1); | |
| 250 } | |
| 251 | |
| 252 kill_free(kill_reply); | |
| 253 | |
| 254 test_ok = 1; | |
| 255 event_loopexit(NULL); | |
| 256 } | |
| 257 | |
| 258 static void | |
| 259 rpc_basic_message(void) | |
| 260 { | |
| 261 short port; | |
| 262 struct evhttp *http = NULL; | |
| 263 struct evrpc_base *base = NULL; | |
| 264 struct evhttp_connection *evcon = NULL; | |
| 265 struct evhttp_request *req = NULL; | |
| 266 struct msg *msg; | |
| 267 | |
| 268 fprintf(stdout, "Testing Good RPC Post: "); | |
| 269 | |
| 270 rpc_setup(&http, &port, &base); | |
| 271 | |
| 272 evcon = evhttp_connection_new("127.0.0.1", port); | |
| 273 if (evcon == NULL) { | |
| 274 fprintf(stdout, "FAILED\n"); | |
| 275 exit(1); | |
| 276 } | |
| 277 | |
| 278 /* | |
| 279 * At this point, we want to schedule an HTTP POST request | |
| 280 * server using our make request method. | |
| 281 */ | |
| 282 | |
| 283 req = evhttp_request_new(rpc_postrequest_done, NULL); | |
| 284 if (req == NULL) { | |
| 285 fprintf(stdout, "FAILED\n"); | |
| 286 exit(1); | |
| 287 } | |
| 288 | |
| 289 /* Add the information that we care about */ | |
| 290 evhttp_add_header(req->output_headers, "Host", "somehost"); | |
| 291 | |
| 292 /* set up the basic message */ | |
| 293 msg = msg_new(); | |
| 294 EVTAG_ASSIGN(msg, from_name, "niels"); | |
| 295 EVTAG_ASSIGN(msg, to_name, "tester"); | |
| 296 msg_marshal(req->output_buffer, msg); | |
| 297 msg_free(msg); | |
| 298 | |
| 299 if (evhttp_make_request(evcon, req, | |
| 300 EVHTTP_REQ_POST, | |
| 301 "/.rpc.Message") == -1) { | |
| 302 fprintf(stdout, "FAILED\n"); | |
| 303 exit(1); | |
| 304 } | |
| 305 | |
| 306 test_ok = 0; | |
| 307 | |
| 308 event_dispatch(); | |
| 309 | |
| 310 evhttp_connection_free(evcon); | |
| 311 | |
| 312 rpc_teardown(base); | |
| 313 | |
| 314 if (test_ok != 1) { | |
| 315 fprintf(stdout, "FAILED\n"); | |
| 316 exit(1); | |
| 317 } | |
| 318 | |
| 319 fprintf(stdout, "OK\n"); | |
| 320 | |
| 321 evhttp_free(http); | |
| 322 } | |
| 323 | |
| 324 static struct evrpc_pool * | |
| 325 rpc_pool_with_connection(short port) | |
| 326 { | |
| 327 struct evhttp_connection *evcon; | |
| 328 struct evrpc_pool *pool; | |
| 329 | |
| 330 pool = evrpc_pool_new(NULL); | |
| 331 assert(pool != NULL); | |
| 332 | |
| 333 evcon = evhttp_connection_new("127.0.0.1", port); | |
| 334 assert(evcon != NULL); | |
| 335 | |
| 336 evrpc_pool_add_connection(pool, evcon); | |
| 337 | |
| 338 return (pool); | |
| 339 } | |
| 340 | |
| 341 static void | |
| 342 GotKillCb(struct evrpc_status *status, | |
| 343 struct msg *msg, struct kill *kill, void *arg) | |
| 344 { | |
| 345 char *weapon; | |
| 346 char *action; | |
| 347 | |
| 348 if (need_output_hook) { | |
| 349 struct evhttp_request *req = status->http_req; | |
| 350 const char *header = evhttp_find_header( | |
| 351 req->input_headers, "X-Pool-Hook"); | |
| 352 assert(strcmp(header, "ran") == 0); | |
| 353 } | |
| 354 | |
| 355 if (status->error != EVRPC_STATUS_ERR_NONE) | |
| 356 goto done; | |
| 357 | |
| 358 if (EVTAG_GET(kill, weapon, &weapon) == -1) { | |
| 359 fprintf(stderr, "get weapon\n"); | |
| 360 goto done; | |
| 361 } | |
| 362 if (EVTAG_GET(kill, action, &action) == -1) { | |
| 363 fprintf(stderr, "get action\n"); | |
| 364 goto done; | |
| 365 } | |
| 366 | |
| 367 if (strcmp(weapon, "dagger")) | |
| 368 goto done; | |
| 369 | |
| 370 if (strcmp(action, "wave around like an idiot")) | |
| 371 goto done; | |
| 372 | |
| 373 test_ok += 1; | |
| 374 | |
| 375 done: | |
| 376 event_loopexit(NULL); | |
| 377 } | |
| 378 | |
| 379 static void | |
| 380 GotKillCbTwo(struct evrpc_status *status, | |
| 381 struct msg *msg, struct kill *kill, void *arg) | |
| 382 { | |
| 383 char *weapon; | |
| 384 char *action; | |
| 385 | |
| 386 if (status->error != EVRPC_STATUS_ERR_NONE) | |
| 387 goto done; | |
| 388 | |
| 389 if (EVTAG_GET(kill, weapon, &weapon) == -1) { | |
| 390 fprintf(stderr, "get weapon\n"); | |
| 391 goto done; | |
| 392 } | |
| 393 if (EVTAG_GET(kill, action, &action) == -1) { | |
| 394 fprintf(stderr, "get action\n"); | |
| 395 goto done; | |
| 396 } | |
| 397 | |
| 398 if (strcmp(weapon, "dagger")) | |
| 399 goto done; | |
| 400 | |
| 401 if (strcmp(action, "wave around like an idiot")) | |
| 402 goto done; | |
| 403 | |
| 404 test_ok += 1; | |
| 405 | |
| 406 done: | |
| 407 if (test_ok == 2) | |
| 408 event_loopexit(NULL); | |
| 409 } | |
| 410 | |
| 411 static int | |
| 412 rpc_hook_add_header(struct evhttp_request *req, | |
| 413 struct evbuffer *evbuf, void *arg) | |
| 414 { | |
| 415 const char *hook_type = arg; | |
| 416 if (strcmp("input", hook_type) == 0) | |
| 417 evhttp_add_header(req->input_headers, "X-Hook", hook_type); | |
| 418 else | |
| 419 evhttp_add_header(req->output_headers, "X-Hook", hook_type); | |
| 420 return (0); | |
| 421 } | |
| 422 | |
| 423 static int | |
| 424 rpc_hook_remove_header(struct evhttp_request *req, | |
| 425 struct evbuffer *evbuf, void *arg) | |
| 426 { | |
| 427 const char *header = evhttp_find_header(req->input_headers, "X-Hook"); | |
| 428 assert(header != NULL); | |
| 429 assert(strcmp(header, arg) == 0); | |
| 430 evhttp_remove_header(req->input_headers, "X-Hook"); | |
| 431 evhttp_add_header(req->input_headers, "X-Pool-Hook", "ran"); | |
| 432 | |
| 433 return (0); | |
| 434 } | |
| 435 | |
| 436 static void | |
| 437 rpc_basic_client(void) | |
| 438 { | |
| 439 short port; | |
| 440 struct evhttp *http = NULL; | |
| 441 struct evrpc_base *base = NULL; | |
| 442 struct evrpc_pool *pool = NULL; | |
| 443 struct msg *msg; | |
| 444 struct kill *kill; | |
| 445 | |
| 446 fprintf(stdout, "Testing RPC Client: "); | |
| 447 | |
| 448 rpc_setup(&http, &port, &base); | |
| 449 | |
| 450 need_input_hook = 1; | |
| 451 need_output_hook = 1; | |
| 452 | |
| 453 assert(evrpc_add_hook(base, EVRPC_INPUT, rpc_hook_add_header, (void*)"in
put") | |
| 454 != NULL); | |
| 455 assert(evrpc_add_hook(base, EVRPC_OUTPUT, rpc_hook_add_header, (void*)"o
utput") | |
| 456 != NULL); | |
| 457 | |
| 458 pool = rpc_pool_with_connection(port); | |
| 459 | |
| 460 assert(evrpc_add_hook(pool, EVRPC_INPUT, rpc_hook_remove_header, (void*)
"output")); | |
| 461 | |
| 462 /* set up the basic message */ | |
| 463 msg = msg_new(); | |
| 464 EVTAG_ASSIGN(msg, from_name, "niels"); | |
| 465 EVTAG_ASSIGN(msg, to_name, "tester"); | |
| 466 | |
| 467 kill = kill_new(); | |
| 468 | |
| 469 EVRPC_MAKE_REQUEST(Message, pool, msg, kill, GotKillCb, NULL); | |
| 470 | |
| 471 test_ok = 0; | |
| 472 | |
| 473 event_dispatch(); | |
| 474 | |
| 475 if (test_ok != 1) { | |
| 476 fprintf(stdout, "FAILED (1)\n"); | |
| 477 exit(1); | |
| 478 } | |
| 479 | |
| 480 /* we do it twice to make sure that reuse works correctly */ | |
| 481 kill_clear(kill); | |
| 482 | |
| 483 EVRPC_MAKE_REQUEST(Message, pool, msg, kill, GotKillCb, NULL); | |
| 484 | |
| 485 event_dispatch(); | |
| 486 | |
| 487 rpc_teardown(base); | |
| 488 | |
| 489 if (test_ok != 2) { | |
| 490 fprintf(stdout, "FAILED (2)\n"); | |
| 491 exit(1); | |
| 492 } | |
| 493 | |
| 494 fprintf(stdout, "OK\n"); | |
| 495 | |
| 496 msg_free(msg); | |
| 497 kill_free(kill); | |
| 498 | |
| 499 evrpc_pool_free(pool); | |
| 500 evhttp_free(http); | |
| 501 } | |
| 502 | |
| 503 /* | |
| 504 * We are testing that the second requests gets send over the same | |
| 505 * connection after the first RPCs completes. | |
| 506 */ | |
| 507 static void | |
| 508 rpc_basic_queued_client(void) | |
| 509 { | |
| 510 short port; | |
| 511 struct evhttp *http = NULL; | |
| 512 struct evrpc_base *base = NULL; | |
| 513 struct evrpc_pool *pool = NULL; | |
| 514 struct msg *msg; | |
| 515 struct kill *kill_one, *kill_two; | |
| 516 | |
| 517 fprintf(stdout, "Testing RPC (Queued) Client: "); | |
| 518 | |
| 519 rpc_setup(&http, &port, &base); | |
| 520 | |
| 521 pool = rpc_pool_with_connection(port); | |
| 522 | |
| 523 /* set up the basic message */ | |
| 524 msg = msg_new(); | |
| 525 EVTAG_ASSIGN(msg, from_name, "niels"); | |
| 526 EVTAG_ASSIGN(msg, to_name, "tester"); | |
| 527 | |
| 528 kill_one = kill_new(); | |
| 529 kill_two = kill_new(); | |
| 530 | |
| 531 EVRPC_MAKE_REQUEST(Message, pool, msg, kill_one, GotKillCbTwo, NULL); | |
| 532 EVRPC_MAKE_REQUEST(Message, pool, msg, kill_two, GotKillCb, NULL); | |
| 533 | |
| 534 test_ok = 0; | |
| 535 | |
| 536 event_dispatch(); | |
| 537 | |
| 538 rpc_teardown(base); | |
| 539 | |
| 540 if (test_ok != 2) { | |
| 541 fprintf(stdout, "FAILED (1)\n"); | |
| 542 exit(1); | |
| 543 } | |
| 544 | |
| 545 fprintf(stdout, "OK\n"); | |
| 546 | |
| 547 msg_free(msg); | |
| 548 kill_free(kill_one); | |
| 549 kill_free(kill_two); | |
| 550 | |
| 551 evrpc_pool_free(pool); | |
| 552 evhttp_free(http); | |
| 553 } | |
| 554 | |
| 555 static void | |
| 556 GotErrorCb(struct evrpc_status *status, | |
| 557 struct msg *msg, struct kill *kill, void *arg) | |
| 558 { | |
| 559 if (status->error != EVRPC_STATUS_ERR_TIMEOUT) | |
| 560 goto done; | |
| 561 | |
| 562 /* should never be complete but just to check */ | |
| 563 if (kill_complete(kill) == 0) | |
| 564 goto done; | |
| 565 | |
| 566 test_ok += 1; | |
| 567 | |
| 568 done: | |
| 569 event_loopexit(NULL); | |
| 570 } | |
| 571 | |
| 572 static void | |
| 573 rpc_client_timeout(void) | |
| 574 { | |
| 575 short port; | |
| 576 struct evhttp *http = NULL; | |
| 577 struct evrpc_base *base = NULL; | |
| 578 struct evrpc_pool *pool = NULL; | |
| 579 struct msg *msg; | |
| 580 struct kill *kill; | |
| 581 | |
| 582 fprintf(stdout, "Testing RPC Client Timeout: "); | |
| 583 | |
| 584 rpc_setup(&http, &port, &base); | |
| 585 | |
| 586 pool = rpc_pool_with_connection(port); | |
| 587 | |
| 588 /* set the timeout to 5 seconds */ | |
| 589 evrpc_pool_set_timeout(pool, 5); | |
| 590 | |
| 591 /* set up the basic message */ | |
| 592 msg = msg_new(); | |
| 593 EVTAG_ASSIGN(msg, from_name, "niels"); | |
| 594 EVTAG_ASSIGN(msg, to_name, "tester"); | |
| 595 | |
| 596 kill = kill_new(); | |
| 597 | |
| 598 EVRPC_MAKE_REQUEST(NeverReply, pool, msg, kill, GotErrorCb, NULL); | |
| 599 | |
| 600 test_ok = 0; | |
| 601 | |
| 602 event_dispatch(); | |
| 603 | |
| 604 /* free the saved RPC structure up */ | |
| 605 EVRPC_REQUEST_DONE(saved_rpc); | |
| 606 | |
| 607 rpc_teardown(base); | |
| 608 | |
| 609 if (test_ok != 2) { | |
| 610 fprintf(stdout, "FAILED (1)\n"); | |
| 611 exit(1); | |
| 612 } | |
| 613 | |
| 614 fprintf(stdout, "OK\n"); | |
| 615 | |
| 616 msg_free(msg); | |
| 617 kill_free(kill); | |
| 618 | |
| 619 evrpc_pool_free(pool); | |
| 620 evhttp_free(http); | |
| 621 } | |
| 622 | |
| 623 void | |
| 624 rpc_suite(void) | |
| 625 { | |
| 626 rpc_basic_test(); | |
| 627 rpc_basic_message(); | |
| 628 rpc_basic_client(); | |
| 629 rpc_basic_queued_client(); | |
| 630 rpc_client_timeout(); | |
| 631 } | |
| OLD | NEW |