| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2003, 2004 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 <sys/wait.h> | |
| 46 #include <signal.h> | |
| 47 #include <unistd.h> | |
| 48 #include <netdb.h> | |
| 49 #endif | |
| 50 #include <assert.h> | |
| 51 #include <fcntl.h> | |
| 52 #include <signal.h> | |
| 53 #include <stdlib.h> | |
| 54 #include <stdio.h> | |
| 55 #include <string.h> | |
| 56 #include <errno.h> | |
| 57 | |
| 58 #include "event.h" | |
| 59 #include "evutil.h" | |
| 60 #include "event-internal.h" | |
| 61 #include "log.h" | |
| 62 | |
| 63 #include "regress.h" | |
| 64 #ifndef WIN32 | |
| 65 #include "regress.gen.h" | |
| 66 #endif | |
| 67 | |
| 68 int pair[2]; | |
| 69 int test_ok; | |
| 70 static int called; | |
| 71 static char wbuf[4096]; | |
| 72 static char rbuf[4096]; | |
| 73 static int woff; | |
| 74 static int roff; | |
| 75 static int usepersist; | |
| 76 static struct timeval tset; | |
| 77 static struct timeval tcalled; | |
| 78 static struct event_base *global_base; | |
| 79 | |
| 80 #define TEST1 "this is a test" | |
| 81 #define SECONDS 1 | |
| 82 | |
| 83 #ifndef SHUT_WR | |
| 84 #define SHUT_WR 1 | |
| 85 #endif | |
| 86 | |
| 87 #ifdef WIN32 | |
| 88 #define write(fd,buf,len) send((fd),(buf),(len),0) | |
| 89 #define read(fd,buf,len) recv((fd),(buf),(len),0) | |
| 90 #endif | |
| 91 | |
| 92 static void | |
| 93 simple_read_cb(int fd, short event, void *arg) | |
| 94 { | |
| 95 char buf[256]; | |
| 96 int len; | |
| 97 | |
| 98 if (arg == NULL) | |
| 99 return; | |
| 100 | |
| 101 len = read(fd, buf, sizeof(buf)); | |
| 102 | |
| 103 if (len) { | |
| 104 if (!called) { | |
| 105 if (event_add(arg, NULL) == -1) | |
| 106 exit(1); | |
| 107 } | |
| 108 } else if (called == 1) | |
| 109 test_ok = 1; | |
| 110 | |
| 111 called++; | |
| 112 } | |
| 113 | |
| 114 static void | |
| 115 simple_write_cb(int fd, short event, void *arg) | |
| 116 { | |
| 117 int len; | |
| 118 | |
| 119 if (arg == NULL) | |
| 120 return; | |
| 121 | |
| 122 len = write(fd, TEST1, strlen(TEST1) + 1); | |
| 123 if (len == -1) | |
| 124 test_ok = 0; | |
| 125 else | |
| 126 test_ok = 1; | |
| 127 } | |
| 128 | |
| 129 static void | |
| 130 multiple_write_cb(int fd, short event, void *arg) | |
| 131 { | |
| 132 struct event *ev = arg; | |
| 133 int len; | |
| 134 | |
| 135 len = 128; | |
| 136 if (woff + len >= sizeof(wbuf)) | |
| 137 len = sizeof(wbuf) - woff; | |
| 138 | |
| 139 len = write(fd, wbuf + woff, len); | |
| 140 if (len == -1) { | |
| 141 fprintf(stderr, "%s: write\n", __func__); | |
| 142 if (usepersist) | |
| 143 event_del(ev); | |
| 144 return; | |
| 145 } | |
| 146 | |
| 147 woff += len; | |
| 148 | |
| 149 if (woff >= sizeof(wbuf)) { | |
| 150 shutdown(fd, SHUT_WR); | |
| 151 if (usepersist) | |
| 152 event_del(ev); | |
| 153 return; | |
| 154 } | |
| 155 | |
| 156 if (!usepersist) { | |
| 157 if (event_add(ev, NULL) == -1) | |
| 158 exit(1); | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 static void | |
| 163 multiple_read_cb(int fd, short event, void *arg) | |
| 164 { | |
| 165 struct event *ev = arg; | |
| 166 int len; | |
| 167 | |
| 168 len = read(fd, rbuf + roff, sizeof(rbuf) - roff); | |
| 169 if (len == -1) | |
| 170 fprintf(stderr, "%s: read\n", __func__); | |
| 171 if (len <= 0) { | |
| 172 if (usepersist) | |
| 173 event_del(ev); | |
| 174 return; | |
| 175 } | |
| 176 | |
| 177 roff += len; | |
| 178 if (!usepersist) { | |
| 179 if (event_add(ev, NULL) == -1) | |
| 180 exit(1); | |
| 181 } | |
| 182 } | |
| 183 | |
| 184 static void | |
| 185 timeout_cb(int fd, short event, void *arg) | |
| 186 { | |
| 187 struct timeval tv; | |
| 188 int diff; | |
| 189 | |
| 190 evutil_gettimeofday(&tcalled, NULL); | |
| 191 if (evutil_timercmp(&tcalled, &tset, >)) | |
| 192 evutil_timersub(&tcalled, &tset, &tv); | |
| 193 else | |
| 194 evutil_timersub(&tset, &tcalled, &tv); | |
| 195 | |
| 196 diff = tv.tv_sec*1000 + tv.tv_usec/1000 - SECONDS * 1000; | |
| 197 if (diff < 0) | |
| 198 diff = -diff; | |
| 199 | |
| 200 if (diff < 100) | |
| 201 test_ok = 1; | |
| 202 } | |
| 203 | |
| 204 #ifndef WIN32 | |
| 205 static void | |
| 206 signal_cb_sa(int sig) | |
| 207 { | |
| 208 test_ok = 2; | |
| 209 } | |
| 210 | |
| 211 static void | |
| 212 signal_cb(int fd, short event, void *arg) | |
| 213 { | |
| 214 struct event *ev = arg; | |
| 215 | |
| 216 signal_del(ev); | |
| 217 test_ok = 1; | |
| 218 } | |
| 219 #endif | |
| 220 | |
| 221 struct both { | |
| 222 struct event ev; | |
| 223 int nread; | |
| 224 }; | |
| 225 | |
| 226 static void | |
| 227 combined_read_cb(int fd, short event, void *arg) | |
| 228 { | |
| 229 struct both *both = arg; | |
| 230 char buf[128]; | |
| 231 int len; | |
| 232 | |
| 233 len = read(fd, buf, sizeof(buf)); | |
| 234 if (len == -1) | |
| 235 fprintf(stderr, "%s: read\n", __func__); | |
| 236 if (len <= 0) | |
| 237 return; | |
| 238 | |
| 239 both->nread += len; | |
| 240 if (event_add(&both->ev, NULL) == -1) | |
| 241 exit(1); | |
| 242 } | |
| 243 | |
| 244 static void | |
| 245 combined_write_cb(int fd, short event, void *arg) | |
| 246 { | |
| 247 struct both *both = arg; | |
| 248 char buf[128]; | |
| 249 int len; | |
| 250 | |
| 251 len = sizeof(buf); | |
| 252 if (len > both->nread) | |
| 253 len = both->nread; | |
| 254 | |
| 255 len = write(fd, buf, len); | |
| 256 if (len == -1) | |
| 257 fprintf(stderr, "%s: write\n", __func__); | |
| 258 if (len <= 0) { | |
| 259 shutdown(fd, SHUT_WR); | |
| 260 return; | |
| 261 } | |
| 262 | |
| 263 both->nread -= len; | |
| 264 if (event_add(&both->ev, NULL) == -1) | |
| 265 exit(1); | |
| 266 } | |
| 267 | |
| 268 /* Test infrastructure */ | |
| 269 | |
| 270 static int | |
| 271 setup_test(const char *name) | |
| 272 { | |
| 273 | |
| 274 fprintf(stdout, "%s", name); | |
| 275 | |
| 276 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { | |
| 277 fprintf(stderr, "%s: socketpair\n", __func__); | |
| 278 exit(1); | |
| 279 } | |
| 280 | |
| 281 #ifdef HAVE_FCNTL | |
| 282 if (fcntl(pair[0], F_SETFL, O_NONBLOCK) == -1) | |
| 283 fprintf(stderr, "fcntl(O_NONBLOCK)"); | |
| 284 | |
| 285 if (fcntl(pair[1], F_SETFL, O_NONBLOCK) == -1) | |
| 286 fprintf(stderr, "fcntl(O_NONBLOCK)"); | |
| 287 #endif | |
| 288 | |
| 289 test_ok = 0; | |
| 290 called = 0; | |
| 291 return (0); | |
| 292 } | |
| 293 | |
| 294 static int | |
| 295 cleanup_test(void) | |
| 296 { | |
| 297 #ifndef WIN32 | |
| 298 close(pair[0]); | |
| 299 close(pair[1]); | |
| 300 #else | |
| 301 CloseHandle((HANDLE)pair[0]); | |
| 302 CloseHandle((HANDLE)pair[1]); | |
| 303 #endif | |
| 304 if (test_ok) | |
| 305 fprintf(stdout, "OK\n"); | |
| 306 else { | |
| 307 fprintf(stdout, "FAILED\n"); | |
| 308 exit(1); | |
| 309 } | |
| 310 test_ok = 0; | |
| 311 return (0); | |
| 312 } | |
| 313 | |
| 314 static void | |
| 315 test_registerfds(void) | |
| 316 { | |
| 317 int i, j; | |
| 318 int pair[2]; | |
| 319 struct event read_evs[512]; | |
| 320 struct event write_evs[512]; | |
| 321 | |
| 322 struct event_base *base = event_base_new(); | |
| 323 | |
| 324 fprintf(stdout, "Testing register fds: "); | |
| 325 | |
| 326 for (i = 0; i < 512; ++i) { | |
| 327 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { | |
| 328 /* run up to the limit of file descriptors */ | |
| 329 break; | |
| 330 } | |
| 331 event_set(&read_evs[i], pair[0], | |
| 332 EV_READ|EV_PERSIST, simple_read_cb, NULL); | |
| 333 event_base_set(base, &read_evs[i]); | |
| 334 event_add(&read_evs[i], NULL); | |
| 335 event_set(&write_evs[i], pair[1], | |
| 336 EV_WRITE|EV_PERSIST, simple_write_cb, NULL); | |
| 337 event_base_set(base, &write_evs[i]); | |
| 338 event_add(&write_evs[i], NULL); | |
| 339 | |
| 340 /* just loop once */ | |
| 341 event_base_loop(base, EVLOOP_ONCE); | |
| 342 } | |
| 343 | |
| 344 /* now delete everything */ | |
| 345 for (j = 0; j < i; ++j) { | |
| 346 event_del(&read_evs[j]); | |
| 347 event_del(&write_evs[j]); | |
| 348 #ifndef WIN32 | |
| 349 close(read_evs[j].ev_fd); | |
| 350 close(write_evs[j].ev_fd); | |
| 351 #else | |
| 352 CloseHandle((HANDLE)read_evs[j].ev_fd); | |
| 353 CloseHandle((HANDLE)write_evs[j].ev_fd); | |
| 354 #endif | |
| 355 | |
| 356 /* just loop once */ | |
| 357 event_base_loop(base, EVLOOP_ONCE); | |
| 358 } | |
| 359 | |
| 360 event_base_free(base); | |
| 361 | |
| 362 fprintf(stdout, "OK\n"); | |
| 363 } | |
| 364 | |
| 365 static void | |
| 366 test_simpleread(void) | |
| 367 { | |
| 368 struct event ev; | |
| 369 | |
| 370 /* Very simple read test */ | |
| 371 setup_test("Simple read: "); | |
| 372 | |
| 373 write(pair[0], TEST1, strlen(TEST1)+1); | |
| 374 shutdown(pair[0], SHUT_WR); | |
| 375 | |
| 376 event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); | |
| 377 if (event_add(&ev, NULL) == -1) | |
| 378 exit(1); | |
| 379 event_dispatch(); | |
| 380 | |
| 381 cleanup_test(); | |
| 382 } | |
| 383 | |
| 384 static void | |
| 385 test_simplewrite(void) | |
| 386 { | |
| 387 struct event ev; | |
| 388 | |
| 389 /* Very simple write test */ | |
| 390 setup_test("Simple write: "); | |
| 391 | |
| 392 event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev); | |
| 393 if (event_add(&ev, NULL) == -1) | |
| 394 exit(1); | |
| 395 event_dispatch(); | |
| 396 | |
| 397 cleanup_test(); | |
| 398 } | |
| 399 | |
| 400 static void | |
| 401 test_multiple(void) | |
| 402 { | |
| 403 struct event ev, ev2; | |
| 404 int i; | |
| 405 | |
| 406 /* Multiple read and write test */ | |
| 407 setup_test("Multiple read/write: "); | |
| 408 memset(rbuf, 0, sizeof(rbuf)); | |
| 409 for (i = 0; i < sizeof(wbuf); i++) | |
| 410 wbuf[i] = i; | |
| 411 | |
| 412 roff = woff = 0; | |
| 413 usepersist = 0; | |
| 414 | |
| 415 event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev); | |
| 416 if (event_add(&ev, NULL) == -1) | |
| 417 exit(1); | |
| 418 event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2); | |
| 419 if (event_add(&ev2, NULL) == -1) | |
| 420 exit(1); | |
| 421 event_dispatch(); | |
| 422 | |
| 423 if (roff == woff) | |
| 424 test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0; | |
| 425 | |
| 426 cleanup_test(); | |
| 427 } | |
| 428 | |
| 429 static void | |
| 430 test_persistent(void) | |
| 431 { | |
| 432 struct event ev, ev2; | |
| 433 int i; | |
| 434 | |
| 435 /* Multiple read and write test with persist */ | |
| 436 setup_test("Persist read/write: "); | |
| 437 memset(rbuf, 0, sizeof(rbuf)); | |
| 438 for (i = 0; i < sizeof(wbuf); i++) | |
| 439 wbuf[i] = i; | |
| 440 | |
| 441 roff = woff = 0; | |
| 442 usepersist = 1; | |
| 443 | |
| 444 event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev); | |
| 445 if (event_add(&ev, NULL) == -1) | |
| 446 exit(1); | |
| 447 event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2); | |
| 448 if (event_add(&ev2, NULL) == -1) | |
| 449 exit(1); | |
| 450 event_dispatch(); | |
| 451 | |
| 452 if (roff == woff) | |
| 453 test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0; | |
| 454 | |
| 455 cleanup_test(); | |
| 456 } | |
| 457 | |
| 458 static void | |
| 459 test_combined(void) | |
| 460 { | |
| 461 struct both r1, r2, w1, w2; | |
| 462 | |
| 463 setup_test("Combined read/write: "); | |
| 464 memset(&r1, 0, sizeof(r1)); | |
| 465 memset(&r2, 0, sizeof(r2)); | |
| 466 memset(&w1, 0, sizeof(w1)); | |
| 467 memset(&w2, 0, sizeof(w2)); | |
| 468 | |
| 469 w1.nread = 4096; | |
| 470 w2.nread = 8192; | |
| 471 | |
| 472 event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1); | |
| 473 event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1); | |
| 474 event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2); | |
| 475 event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2); | |
| 476 if (event_add(&r1.ev, NULL) == -1) | |
| 477 exit(1); | |
| 478 if (event_add(&w1.ev, NULL)) | |
| 479 exit(1); | |
| 480 if (event_add(&r2.ev, NULL)) | |
| 481 exit(1); | |
| 482 if (event_add(&w2.ev, NULL)) | |
| 483 exit(1); | |
| 484 | |
| 485 event_dispatch(); | |
| 486 | |
| 487 if (r1.nread == 8192 && r2.nread == 4096) | |
| 488 test_ok = 1; | |
| 489 | |
| 490 cleanup_test(); | |
| 491 } | |
| 492 | |
| 493 static void | |
| 494 test_simpletimeout(void) | |
| 495 { | |
| 496 struct timeval tv; | |
| 497 struct event ev; | |
| 498 | |
| 499 setup_test("Simple timeout: "); | |
| 500 | |
| 501 tv.tv_usec = 0; | |
| 502 tv.tv_sec = SECONDS; | |
| 503 evtimer_set(&ev, timeout_cb, NULL); | |
| 504 evtimer_add(&ev, &tv); | |
| 505 | |
| 506 evutil_gettimeofday(&tset, NULL); | |
| 507 event_dispatch(); | |
| 508 | |
| 509 cleanup_test(); | |
| 510 } | |
| 511 | |
| 512 #ifndef WIN32 | |
| 513 extern struct event_base *current_base; | |
| 514 | |
| 515 static void | |
| 516 child_signal_cb(int fd, short event, void *arg) | |
| 517 { | |
| 518 struct timeval tv; | |
| 519 int *pint = arg; | |
| 520 | |
| 521 *pint = 1; | |
| 522 | |
| 523 tv.tv_usec = 500000; | |
| 524 tv.tv_sec = 0; | |
| 525 event_loopexit(&tv); | |
| 526 } | |
| 527 | |
| 528 static void | |
| 529 test_fork(void) | |
| 530 { | |
| 531 int status, got_sigchld = 0; | |
| 532 struct event ev, sig_ev; | |
| 533 pid_t pid; | |
| 534 | |
| 535 setup_test("After fork: "); | |
| 536 | |
| 537 write(pair[0], TEST1, strlen(TEST1)+1); | |
| 538 | |
| 539 event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); | |
| 540 if (event_add(&ev, NULL) == -1) | |
| 541 exit(1); | |
| 542 | |
| 543 signal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld); | |
| 544 signal_add(&sig_ev, NULL); | |
| 545 | |
| 546 if ((pid = fork()) == 0) { | |
| 547 /* in the child */ | |
| 548 if (event_reinit(current_base) == -1) { | |
| 549 fprintf(stderr, "FAILED (reinit)\n"); | |
| 550 exit(1); | |
| 551 } | |
| 552 | |
| 553 signal_del(&sig_ev); | |
| 554 | |
| 555 called = 0; | |
| 556 | |
| 557 event_dispatch(); | |
| 558 | |
| 559 /* we do not send an EOF; simple_read_cb requires an EOF | |
| 560 * to set test_ok. we just verify that the callback was | |
| 561 * called. */ | |
| 562 exit(test_ok != 0 || called != 2 ? -2 : 76); | |
| 563 } | |
| 564 | |
| 565 /* wait for the child to read the data */ | |
| 566 sleep(1); | |
| 567 | |
| 568 write(pair[0], TEST1, strlen(TEST1)+1); | |
| 569 | |
| 570 if (waitpid(pid, &status, 0) == -1) { | |
| 571 fprintf(stderr, "FAILED (fork)\n"); | |
| 572 exit(1); | |
| 573 } | |
| 574 | |
| 575 if (WEXITSTATUS(status) != 76) { | |
| 576 fprintf(stderr, "FAILED (exit): %d\n", WEXITSTATUS(status)); | |
| 577 exit(1); | |
| 578 } | |
| 579 | |
| 580 /* test that the current event loop still works */ | |
| 581 write(pair[0], TEST1, strlen(TEST1)+1); | |
| 582 shutdown(pair[0], SHUT_WR); | |
| 583 | |
| 584 event_dispatch(); | |
| 585 | |
| 586 if (!got_sigchld) { | |
| 587 fprintf(stdout, "FAILED (sigchld)\n"); | |
| 588 exit(1); | |
| 589 } | |
| 590 | |
| 591 signal_del(&sig_ev); | |
| 592 | |
| 593 cleanup_test(); | |
| 594 } | |
| 595 | |
| 596 static void | |
| 597 test_simplesignal(void) | |
| 598 { | |
| 599 struct event ev; | |
| 600 struct itimerval itv; | |
| 601 | |
| 602 setup_test("Simple signal: "); | |
| 603 signal_set(&ev, SIGALRM, signal_cb, &ev); | |
| 604 signal_add(&ev, NULL); | |
| 605 /* find bugs in which operations are re-ordered */ | |
| 606 signal_del(&ev); | |
| 607 signal_add(&ev, NULL); | |
| 608 | |
| 609 memset(&itv, 0, sizeof(itv)); | |
| 610 itv.it_value.tv_sec = 1; | |
| 611 if (setitimer(ITIMER_REAL, &itv, NULL) == -1) | |
| 612 goto skip_simplesignal; | |
| 613 | |
| 614 event_dispatch(); | |
| 615 skip_simplesignal: | |
| 616 if (signal_del(&ev) == -1) | |
| 617 test_ok = 0; | |
| 618 | |
| 619 cleanup_test(); | |
| 620 } | |
| 621 | |
| 622 static void | |
| 623 test_multiplesignal(void) | |
| 624 { | |
| 625 struct event ev_one, ev_two; | |
| 626 struct itimerval itv; | |
| 627 | |
| 628 setup_test("Multiple signal: "); | |
| 629 | |
| 630 signal_set(&ev_one, SIGALRM, signal_cb, &ev_one); | |
| 631 signal_add(&ev_one, NULL); | |
| 632 | |
| 633 signal_set(&ev_two, SIGALRM, signal_cb, &ev_two); | |
| 634 signal_add(&ev_two, NULL); | |
| 635 | |
| 636 memset(&itv, 0, sizeof(itv)); | |
| 637 itv.it_value.tv_sec = 1; | |
| 638 if (setitimer(ITIMER_REAL, &itv, NULL) == -1) | |
| 639 goto skip_simplesignal; | |
| 640 | |
| 641 event_dispatch(); | |
| 642 | |
| 643 skip_simplesignal: | |
| 644 if (signal_del(&ev_one) == -1) | |
| 645 test_ok = 0; | |
| 646 if (signal_del(&ev_two) == -1) | |
| 647 test_ok = 0; | |
| 648 | |
| 649 cleanup_test(); | |
| 650 } | |
| 651 | |
| 652 static void | |
| 653 test_immediatesignal(void) | |
| 654 { | |
| 655 struct event ev; | |
| 656 | |
| 657 test_ok = 0; | |
| 658 printf("Immediate signal: "); | |
| 659 signal_set(&ev, SIGUSR1, signal_cb, &ev); | |
| 660 signal_add(&ev, NULL); | |
| 661 raise(SIGUSR1); | |
| 662 event_loop(EVLOOP_NONBLOCK); | |
| 663 signal_del(&ev); | |
| 664 cleanup_test(); | |
| 665 } | |
| 666 | |
| 667 static void | |
| 668 test_signal_dealloc(void) | |
| 669 { | |
| 670 /* make sure that signal_event is event_del'ed and pipe closed */ | |
| 671 struct event ev; | |
| 672 struct event_base *base = event_init(); | |
| 673 printf("Signal dealloc: "); | |
| 674 signal_set(&ev, SIGUSR1, signal_cb, &ev); | |
| 675 signal_add(&ev, NULL); | |
| 676 signal_del(&ev); | |
| 677 event_base_free(base); | |
| 678 /* If we got here without asserting, we're fine. */ | |
| 679 test_ok = 1; | |
| 680 cleanup_test(); | |
| 681 } | |
| 682 | |
| 683 static void | |
| 684 test_signal_pipeloss(void) | |
| 685 { | |
| 686 /* make sure that the base1 pipe is closed correctly. */ | |
| 687 struct event_base *base1, *base2; | |
| 688 int pipe1; | |
| 689 test_ok = 0; | |
| 690 printf("Signal pipeloss: "); | |
| 691 base1 = event_init(); | |
| 692 pipe1 = base1->sig.ev_signal_pair[0]; | |
| 693 base2 = event_init(); | |
| 694 event_base_free(base2); | |
| 695 event_base_free(base1); | |
| 696 if (close(pipe1) != -1 || errno!=EBADF) { | |
| 697 /* fd must be closed, so second close gives -1, EBADF */ | |
| 698 printf("signal pipe not closed. "); | |
| 699 test_ok = 0; | |
| 700 } else { | |
| 701 test_ok = 1; | |
| 702 } | |
| 703 cleanup_test(); | |
| 704 } | |
| 705 | |
| 706 /* | |
| 707 * make two bases to catch signals, use both of them. this only works | |
| 708 * for event mechanisms that use our signal pipe trick. kqueue handles | |
| 709 * signals internally, and all interested kqueues get all the signals. | |
| 710 */ | |
| 711 static void | |
| 712 test_signal_switchbase(void) | |
| 713 { | |
| 714 struct event ev1, ev2; | |
| 715 struct event_base *base1, *base2; | |
| 716 int is_kqueue; | |
| 717 test_ok = 0; | |
| 718 printf("Signal switchbase: "); | |
| 719 base1 = event_init(); | |
| 720 base2 = event_init(); | |
| 721 is_kqueue = !strcmp(event_get_method(),"kqueue"); | |
| 722 signal_set(&ev1, SIGUSR1, signal_cb, &ev1); | |
| 723 signal_set(&ev2, SIGUSR1, signal_cb, &ev2); | |
| 724 if (event_base_set(base1, &ev1) || | |
| 725 event_base_set(base2, &ev2) || | |
| 726 event_add(&ev1, NULL) || | |
| 727 event_add(&ev2, NULL)) { | |
| 728 fprintf(stderr, "%s: cannot set base, add\n", __func__); | |
| 729 exit(1); | |
| 730 } | |
| 731 | |
| 732 test_ok = 0; | |
| 733 /* can handle signal before loop is called */ | |
| 734 raise(SIGUSR1); | |
| 735 event_base_loop(base2, EVLOOP_NONBLOCK); | |
| 736 if (is_kqueue) { | |
| 737 if (!test_ok) | |
| 738 goto done; | |
| 739 test_ok = 0; | |
| 740 } | |
| 741 event_base_loop(base1, EVLOOP_NONBLOCK); | |
| 742 if (test_ok && !is_kqueue) { | |
| 743 test_ok = 0; | |
| 744 | |
| 745 /* set base1 to handle signals */ | |
| 746 event_base_loop(base1, EVLOOP_NONBLOCK); | |
| 747 raise(SIGUSR1); | |
| 748 event_base_loop(base1, EVLOOP_NONBLOCK); | |
| 749 event_base_loop(base2, EVLOOP_NONBLOCK); | |
| 750 } | |
| 751 done: | |
| 752 event_base_free(base1); | |
| 753 event_base_free(base2); | |
| 754 cleanup_test(); | |
| 755 } | |
| 756 | |
| 757 /* | |
| 758 * assert that a signal event removed from the event queue really is | |
| 759 * removed - with no possibility of it's parent handler being fired. | |
| 760 */ | |
| 761 static void | |
| 762 test_signal_assert(void) | |
| 763 { | |
| 764 struct event ev; | |
| 765 struct event_base *base = event_init(); | |
| 766 test_ok = 0; | |
| 767 printf("Signal handler assert: "); | |
| 768 /* use SIGCONT so we don't kill ourselves when we signal to nowhere */ | |
| 769 signal_set(&ev, SIGCONT, signal_cb, &ev); | |
| 770 signal_add(&ev, NULL); | |
| 771 /* | |
| 772 * if signal_del() fails to reset the handler, it's current handler | |
| 773 * will still point to evsignal_handler(). | |
| 774 */ | |
| 775 signal_del(&ev); | |
| 776 | |
| 777 raise(SIGCONT); | |
| 778 /* only way to verify we were in evsignal_handler() */ | |
| 779 if (base->sig.evsignal_caught) | |
| 780 test_ok = 0; | |
| 781 else | |
| 782 test_ok = 1; | |
| 783 | |
| 784 event_base_free(base); | |
| 785 cleanup_test(); | |
| 786 return; | |
| 787 } | |
| 788 | |
| 789 /* | |
| 790 * assert that we restore our previous signal handler properly. | |
| 791 */ | |
| 792 static void | |
| 793 test_signal_restore(void) | |
| 794 { | |
| 795 struct event ev; | |
| 796 struct event_base *base = event_init(); | |
| 797 #ifdef HAVE_SIGACTION | |
| 798 struct sigaction sa; | |
| 799 #endif | |
| 800 | |
| 801 test_ok = 0; | |
| 802 printf("Signal handler restore: "); | |
| 803 #ifdef HAVE_SIGACTION | |
| 804 sa.sa_handler = signal_cb_sa; | |
| 805 sa.sa_flags = 0x0; | |
| 806 sigemptyset(&sa.sa_mask); | |
| 807 if (sigaction(SIGUSR1, &sa, NULL) == -1) | |
| 808 goto out; | |
| 809 #else | |
| 810 if (signal(SIGUSR1, signal_cb_sa) == SIG_ERR) | |
| 811 goto out; | |
| 812 #endif | |
| 813 signal_set(&ev, SIGUSR1, signal_cb, &ev); | |
| 814 signal_add(&ev, NULL); | |
| 815 signal_del(&ev); | |
| 816 | |
| 817 raise(SIGUSR1); | |
| 818 /* 1 == signal_cb, 2 == signal_cb_sa, we want our previous handler */ | |
| 819 if (test_ok != 2) | |
| 820 test_ok = 0; | |
| 821 out: | |
| 822 event_base_free(base); | |
| 823 cleanup_test(); | |
| 824 return; | |
| 825 } | |
| 826 | |
| 827 static void | |
| 828 signal_cb_swp(int sig, short event, void *arg) | |
| 829 { | |
| 830 called++; | |
| 831 if (called < 5) | |
| 832 raise(sig); | |
| 833 else | |
| 834 event_loopexit(NULL); | |
| 835 } | |
| 836 static void | |
| 837 timeout_cb_swp(int fd, short event, void *arg) | |
| 838 { | |
| 839 if (called == -1) { | |
| 840 struct timeval tv = {5, 0}; | |
| 841 | |
| 842 called = 0; | |
| 843 evtimer_add((struct event *)arg, &tv); | |
| 844 raise(SIGUSR1); | |
| 845 return; | |
| 846 } | |
| 847 test_ok = 0; | |
| 848 event_loopexit(NULL); | |
| 849 } | |
| 850 | |
| 851 static void | |
| 852 test_signal_while_processing(void) | |
| 853 { | |
| 854 struct event_base *base = event_init(); | |
| 855 struct event ev, ev_timer; | |
| 856 struct timeval tv = {0, 0}; | |
| 857 | |
| 858 setup_test("Receiving a signal while processing other signal: "); | |
| 859 | |
| 860 called = -1; | |
| 861 test_ok = 1; | |
| 862 signal_set(&ev, SIGUSR1, signal_cb_swp, NULL); | |
| 863 signal_add(&ev, NULL); | |
| 864 evtimer_set(&ev_timer, timeout_cb_swp, &ev_timer); | |
| 865 evtimer_add(&ev_timer, &tv); | |
| 866 event_dispatch(); | |
| 867 | |
| 868 event_base_free(base); | |
| 869 cleanup_test(); | |
| 870 return; | |
| 871 } | |
| 872 #endif | |
| 873 | |
| 874 static void | |
| 875 test_free_active_base(void) | |
| 876 { | |
| 877 struct event_base *base1; | |
| 878 struct event ev1; | |
| 879 setup_test("Free active base: "); | |
| 880 base1 = event_init(); | |
| 881 event_set(&ev1, pair[1], EV_READ, simple_read_cb, &ev1); | |
| 882 event_base_set(base1, &ev1); | |
| 883 event_add(&ev1, NULL); | |
| 884 /* event_del(&ev1); */ | |
| 885 event_base_free(base1); | |
| 886 test_ok = 1; | |
| 887 cleanup_test(); | |
| 888 } | |
| 889 | |
| 890 static void | |
| 891 test_event_base_new(void) | |
| 892 { | |
| 893 struct event_base *base; | |
| 894 struct event ev1; | |
| 895 setup_test("Event base new: "); | |
| 896 | |
| 897 write(pair[0], TEST1, strlen(TEST1)+1); | |
| 898 shutdown(pair[0], SHUT_WR); | |
| 899 | |
| 900 base = event_base_new(); | |
| 901 event_set(&ev1, pair[1], EV_READ, simple_read_cb, &ev1); | |
| 902 event_base_set(base, &ev1); | |
| 903 event_add(&ev1, NULL); | |
| 904 | |
| 905 event_base_dispatch(base); | |
| 906 | |
| 907 event_base_free(base); | |
| 908 test_ok = 1; | |
| 909 cleanup_test(); | |
| 910 } | |
| 911 | |
| 912 static void | |
| 913 test_loopexit(void) | |
| 914 { | |
| 915 struct timeval tv, tv_start, tv_end; | |
| 916 struct event ev; | |
| 917 | |
| 918 setup_test("Loop exit: "); | |
| 919 | |
| 920 tv.tv_usec = 0; | |
| 921 tv.tv_sec = 60*60*24; | |
| 922 evtimer_set(&ev, timeout_cb, NULL); | |
| 923 evtimer_add(&ev, &tv); | |
| 924 | |
| 925 tv.tv_usec = 0; | |
| 926 tv.tv_sec = 1; | |
| 927 event_loopexit(&tv); | |
| 928 | |
| 929 evutil_gettimeofday(&tv_start, NULL); | |
| 930 event_dispatch(); | |
| 931 evutil_gettimeofday(&tv_end, NULL); | |
| 932 evutil_timersub(&tv_end, &tv_start, &tv_end); | |
| 933 | |
| 934 evtimer_del(&ev); | |
| 935 | |
| 936 if (tv.tv_sec < 2) | |
| 937 test_ok = 1; | |
| 938 | |
| 939 cleanup_test(); | |
| 940 } | |
| 941 | |
| 942 static void | |
| 943 test_loopexit_multiple(void) | |
| 944 { | |
| 945 struct timeval tv; | |
| 946 struct event_base *base; | |
| 947 | |
| 948 setup_test("Loop Multiple exit: "); | |
| 949 | |
| 950 base = event_base_new(); | |
| 951 | |
| 952 tv.tv_usec = 0; | |
| 953 tv.tv_sec = 1; | |
| 954 event_base_loopexit(base, &tv); | |
| 955 | |
| 956 tv.tv_usec = 0; | |
| 957 tv.tv_sec = 2; | |
| 958 event_base_loopexit(base, &tv); | |
| 959 | |
| 960 event_base_dispatch(base); | |
| 961 | |
| 962 event_base_free(base); | |
| 963 | |
| 964 test_ok = 1; | |
| 965 | |
| 966 cleanup_test(); | |
| 967 } | |
| 968 | |
| 969 static void | |
| 970 break_cb(int fd, short events, void *arg) | |
| 971 { | |
| 972 test_ok = 1; | |
| 973 event_loopbreak(); | |
| 974 } | |
| 975 | |
| 976 static void | |
| 977 fail_cb(int fd, short events, void *arg) | |
| 978 { | |
| 979 test_ok = 0; | |
| 980 } | |
| 981 | |
| 982 static void | |
| 983 test_loopbreak(void) | |
| 984 { | |
| 985 struct event ev1, ev2; | |
| 986 struct timeval tv; | |
| 987 | |
| 988 setup_test("Loop break: "); | |
| 989 | |
| 990 tv.tv_sec = 0; | |
| 991 tv.tv_usec = 0; | |
| 992 evtimer_set(&ev1, break_cb, NULL); | |
| 993 evtimer_add(&ev1, &tv); | |
| 994 evtimer_set(&ev2, fail_cb, NULL); | |
| 995 evtimer_add(&ev2, &tv); | |
| 996 | |
| 997 event_dispatch(); | |
| 998 | |
| 999 evtimer_del(&ev1); | |
| 1000 evtimer_del(&ev2); | |
| 1001 | |
| 1002 cleanup_test(); | |
| 1003 } | |
| 1004 | |
| 1005 static void | |
| 1006 test_evbuffer(void) { | |
| 1007 | |
| 1008 struct evbuffer *evb = evbuffer_new(); | |
| 1009 setup_test("Testing Evbuffer: "); | |
| 1010 | |
| 1011 evbuffer_add_printf(evb, "%s/%d", "hello", 1); | |
| 1012 | |
| 1013 if (EVBUFFER_LENGTH(evb) == 7 && | |
| 1014 strcmp((char*)EVBUFFER_DATA(evb), "hello/1") == 0) | |
| 1015 test_ok = 1; | |
| 1016 | |
| 1017 evbuffer_free(evb); | |
| 1018 | |
| 1019 cleanup_test(); | |
| 1020 } | |
| 1021 | |
| 1022 static void | |
| 1023 test_evbuffer_readln(void) | |
| 1024 { | |
| 1025 struct evbuffer *evb = evbuffer_new(); | |
| 1026 struct evbuffer *evb_tmp = evbuffer_new(); | |
| 1027 const char *s; | |
| 1028 char *cp = NULL; | |
| 1029 size_t sz; | |
| 1030 | |
| 1031 #define tt_line_eq(content) \ | |
| 1032 if (!cp || sz != strlen(content) || strcmp(cp, content)) { \ | |
| 1033 fprintf(stdout, "FAILED\n"); \ | |
| 1034 exit(1); \ | |
| 1035 } | |
| 1036 #define tt_assert(expression) \ | |
| 1037 if (!(expression)) { \ | |
| 1038 fprintf(stdout, "FAILED\n"); \ | |
| 1039 exit(1); \ | |
| 1040 } \ | |
| 1041 | |
| 1042 /* Test EOL_ANY. */ | |
| 1043 fprintf(stdout, "Testing evbuffer_readln EOL_ANY: "); | |
| 1044 | |
| 1045 s = "complex silly newline\r\n\n\r\n\n\rmore\0\n"; | |
| 1046 evbuffer_add(evb, s, strlen(s)+2); | |
| 1047 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY); | |
| 1048 tt_line_eq("complex silly newline"); | |
| 1049 free(cp); | |
| 1050 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY); | |
| 1051 if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6)) { | |
| 1052 fprintf(stdout, "FAILED\n"); | |
| 1053 exit(1); | |
| 1054 } | |
| 1055 if (evb->totallen == 0) { | |
| 1056 fprintf(stdout, "FAILED\n"); | |
| 1057 exit(1); | |
| 1058 } | |
| 1059 s = "\nno newline"; | |
| 1060 evbuffer_add(evb, s, strlen(s)); | |
| 1061 free(cp); | |
| 1062 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY); | |
| 1063 tt_line_eq(""); | |
| 1064 free(cp); | |
| 1065 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY); | |
| 1066 tt_assert(!cp); | |
| 1067 evbuffer_drain(evb, EVBUFFER_LENGTH(evb)); | |
| 1068 tt_assert(EVBUFFER_LENGTH(evb) == 0); | |
| 1069 | |
| 1070 fprintf(stdout, "OK\n"); | |
| 1071 | |
| 1072 /* Test EOL_CRLF */ | |
| 1073 fprintf(stdout, "Testing evbuffer_readln EOL_CRLF: "); | |
| 1074 | |
| 1075 s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n"; | |
| 1076 evbuffer_add(evb, s, strlen(s)); | |
| 1077 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); | |
| 1078 tt_line_eq("Line with\rin the middle"); | |
| 1079 free(cp); | |
| 1080 | |
| 1081 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); | |
| 1082 tt_line_eq("Line with good crlf"); | |
| 1083 free(cp); | |
| 1084 | |
| 1085 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); | |
| 1086 tt_line_eq(""); | |
| 1087 free(cp); | |
| 1088 | |
| 1089 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); | |
| 1090 tt_line_eq("final"); | |
| 1091 s = "x"; | |
| 1092 evbuffer_add(evb, s, 1); | |
| 1093 free(cp); | |
| 1094 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); | |
| 1095 tt_assert(!cp); | |
| 1096 | |
| 1097 fprintf(stdout, "OK\n"); | |
| 1098 | |
| 1099 /* Test CRLF_STRICT */ | |
| 1100 fprintf(stdout, "Testing evbuffer_readln CRLF_STRICT: "); | |
| 1101 | |
| 1102 s = " and a bad crlf\nand a good one\r\n\r\nMore\r"; | |
| 1103 evbuffer_add(evb, s, strlen(s)); | |
| 1104 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1105 tt_line_eq("x and a bad crlf\nand a good one"); | |
| 1106 free(cp); | |
| 1107 | |
| 1108 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1109 tt_line_eq(""); | |
| 1110 free(cp); | |
| 1111 | |
| 1112 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1113 tt_assert(!cp); | |
| 1114 evbuffer_add(evb, "\n", 1); | |
| 1115 | |
| 1116 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1117 tt_line_eq("More"); | |
| 1118 free(cp); | |
| 1119 tt_assert(EVBUFFER_LENGTH(evb) == 0); | |
| 1120 | |
| 1121 s = "An internal CR\r is not an eol\r\nNor is a lack of one"; | |
| 1122 evbuffer_add(evb, s, strlen(s)); | |
| 1123 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1124 tt_line_eq("An internal CR\r is not an eol"); | |
| 1125 free(cp); | |
| 1126 | |
| 1127 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1128 tt_assert(!cp); | |
| 1129 | |
| 1130 evbuffer_add(evb, "\r\n", 2); | |
| 1131 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1132 tt_line_eq("Nor is a lack of one"); | |
| 1133 free(cp); | |
| 1134 tt_assert(EVBUFFER_LENGTH(evb) == 0); | |
| 1135 | |
| 1136 fprintf(stdout, "OK\n"); | |
| 1137 | |
| 1138 /* Test LF */ | |
| 1139 fprintf(stdout, "Testing evbuffer_readln LF: "); | |
| 1140 | |
| 1141 s = "An\rand a nl\n\nText"; | |
| 1142 evbuffer_add(evb, s, strlen(s)); | |
| 1143 | |
| 1144 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); | |
| 1145 tt_line_eq("An\rand a nl"); | |
| 1146 free(cp); | |
| 1147 | |
| 1148 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); | |
| 1149 tt_line_eq(""); | |
| 1150 free(cp); | |
| 1151 | |
| 1152 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); | |
| 1153 tt_assert(!cp); | |
| 1154 free(cp); | |
| 1155 evbuffer_add(evb, "\n", 1); | |
| 1156 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); | |
| 1157 tt_line_eq("Text"); | |
| 1158 free(cp); | |
| 1159 | |
| 1160 fprintf(stdout, "OK\n"); | |
| 1161 | |
| 1162 /* Test CRLF_STRICT - across boundaries */ | |
| 1163 fprintf(stdout, | |
| 1164 "Testing evbuffer_readln CRLF_STRICT across boundaries: "); | |
| 1165 | |
| 1166 s = " and a bad crlf\nand a good one\r"; | |
| 1167 evbuffer_add(evb_tmp, s, strlen(s)); | |
| 1168 evbuffer_add_buffer(evb, evb_tmp); | |
| 1169 s = "\n\r"; | |
| 1170 evbuffer_add(evb_tmp, s, strlen(s)); | |
| 1171 evbuffer_add_buffer(evb, evb_tmp); | |
| 1172 s = "\nMore\r"; | |
| 1173 evbuffer_add(evb_tmp, s, strlen(s)); | |
| 1174 evbuffer_add_buffer(evb, evb_tmp); | |
| 1175 | |
| 1176 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1177 tt_line_eq(" and a bad crlf\nand a good one"); | |
| 1178 free(cp); | |
| 1179 | |
| 1180 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1181 tt_line_eq(""); | |
| 1182 free(cp); | |
| 1183 | |
| 1184 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1185 tt_assert(!cp); | |
| 1186 free(cp); | |
| 1187 evbuffer_add(evb, "\n", 1); | |
| 1188 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); | |
| 1189 tt_line_eq("More"); | |
| 1190 free(cp); cp = NULL; | |
| 1191 if (EVBUFFER_LENGTH(evb) != 0) { | |
| 1192 fprintf(stdout, "FAILED\n"); | |
| 1193 exit(1); | |
| 1194 } | |
| 1195 | |
| 1196 fprintf(stdout, "OK\n"); | |
| 1197 | |
| 1198 /* Test memory problem */ | |
| 1199 fprintf(stdout, "Testing evbuffer_readln memory problem: "); | |
| 1200 | |
| 1201 s = "one line\ntwo line\nblue line"; | |
| 1202 evbuffer_add(evb_tmp, s, strlen(s)); | |
| 1203 evbuffer_add_buffer(evb, evb_tmp); | |
| 1204 | |
| 1205 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); | |
| 1206 tt_line_eq("one line"); | |
| 1207 free(cp); cp = NULL; | |
| 1208 | |
| 1209 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); | |
| 1210 tt_line_eq("two line"); | |
| 1211 free(cp); cp = NULL; | |
| 1212 | |
| 1213 fprintf(stdout, "OK\n"); | |
| 1214 | |
| 1215 test_ok = 1; | |
| 1216 evbuffer_free(evb); | |
| 1217 evbuffer_free(evb_tmp); | |
| 1218 if (cp) free(cp); | |
| 1219 } | |
| 1220 | |
| 1221 static void | |
| 1222 test_evbuffer_find(void) | |
| 1223 { | |
| 1224 u_char* p; | |
| 1225 const char* test1 = "1234567890\r\n"; | |
| 1226 const char* test2 = "1234567890\r"; | |
| 1227 #define EVBUFFER_INITIAL_LENGTH 256 | |
| 1228 char test3[EVBUFFER_INITIAL_LENGTH]; | |
| 1229 unsigned int i; | |
| 1230 struct evbuffer * buf = evbuffer_new(); | |
| 1231 | |
| 1232 /* make sure evbuffer_find doesn't match past the end of the buffer */ | |
| 1233 fprintf(stdout, "Testing evbuffer_find 1: "); | |
| 1234 evbuffer_add(buf, (u_char*)test1, strlen(test1)); | |
| 1235 evbuffer_drain(buf, strlen(test1)); | |
| 1236 evbuffer_add(buf, (u_char*)test2, strlen(test2)); | |
| 1237 p = evbuffer_find(buf, (u_char*)"\r\n", 2); | |
| 1238 if (p == NULL) { | |
| 1239 fprintf(stdout, "OK\n"); | |
| 1240 } else { | |
| 1241 fprintf(stdout, "FAILED\n"); | |
| 1242 exit(1); | |
| 1243 } | |
| 1244 | |
| 1245 /* | |
| 1246 * drain the buffer and do another find; in r309 this would | |
| 1247 * read past the allocated buffer causing a valgrind error. | |
| 1248 */ | |
| 1249 fprintf(stdout, "Testing evbuffer_find 2: "); | |
| 1250 evbuffer_drain(buf, strlen(test2)); | |
| 1251 for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i) | |
| 1252 test3[i] = 'a'; | |
| 1253 test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x'; | |
| 1254 evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH); | |
| 1255 p = evbuffer_find(buf, (u_char *)"xy", 2); | |
| 1256 if (p == NULL) { | |
| 1257 printf("OK\n"); | |
| 1258 } else { | |
| 1259 fprintf(stdout, "FAILED\n"); | |
| 1260 exit(1); | |
| 1261 } | |
| 1262 | |
| 1263 /* simple test for match at end of allocated buffer */ | |
| 1264 fprintf(stdout, "Testing evbuffer_find 3: "); | |
| 1265 p = evbuffer_find(buf, (u_char *)"ax", 2); | |
| 1266 if (p != NULL && strncmp((char*)p, "ax", 2) == 0) { | |
| 1267 printf("OK\n"); | |
| 1268 } else { | |
| 1269 fprintf(stdout, "FAILED\n"); | |
| 1270 exit(1); | |
| 1271 } | |
| 1272 | |
| 1273 evbuffer_free(buf); | |
| 1274 } | |
| 1275 | |
| 1276 /* | |
| 1277 * simple bufferevent test | |
| 1278 */ | |
| 1279 | |
| 1280 static void | |
| 1281 readcb(struct bufferevent *bev, void *arg) | |
| 1282 { | |
| 1283 if (EVBUFFER_LENGTH(bev->input) == 8333) { | |
| 1284 bufferevent_disable(bev, EV_READ); | |
| 1285 test_ok++; | |
| 1286 } | |
| 1287 } | |
| 1288 | |
| 1289 static void | |
| 1290 writecb(struct bufferevent *bev, void *arg) | |
| 1291 { | |
| 1292 if (EVBUFFER_LENGTH(bev->output) == 0) | |
| 1293 test_ok++; | |
| 1294 } | |
| 1295 | |
| 1296 static void | |
| 1297 errorcb(struct bufferevent *bev, short what, void *arg) | |
| 1298 { | |
| 1299 test_ok = -2; | |
| 1300 } | |
| 1301 | |
| 1302 static void | |
| 1303 test_bufferevent(void) | |
| 1304 { | |
| 1305 struct bufferevent *bev1, *bev2; | |
| 1306 char buffer[8333]; | |
| 1307 int i; | |
| 1308 | |
| 1309 setup_test("Bufferevent: "); | |
| 1310 | |
| 1311 bev1 = bufferevent_new(pair[0], readcb, writecb, errorcb, NULL); | |
| 1312 bev2 = bufferevent_new(pair[1], readcb, writecb, errorcb, NULL); | |
| 1313 | |
| 1314 bufferevent_disable(bev1, EV_READ); | |
| 1315 bufferevent_enable(bev2, EV_READ); | |
| 1316 | |
| 1317 for (i = 0; i < sizeof(buffer); i++) | |
| 1318 buffer[i] = i; | |
| 1319 | |
| 1320 bufferevent_write(bev1, buffer, sizeof(buffer)); | |
| 1321 | |
| 1322 event_dispatch(); | |
| 1323 | |
| 1324 bufferevent_free(bev1); | |
| 1325 bufferevent_free(bev2); | |
| 1326 | |
| 1327 if (test_ok != 2) | |
| 1328 test_ok = 0; | |
| 1329 | |
| 1330 cleanup_test(); | |
| 1331 } | |
| 1332 | |
| 1333 /* | |
| 1334 * test watermarks and bufferevent | |
| 1335 */ | |
| 1336 | |
| 1337 static void | |
| 1338 wm_readcb(struct bufferevent *bev, void *arg) | |
| 1339 { | |
| 1340 int len = EVBUFFER_LENGTH(bev->input); | |
| 1341 static int nread; | |
| 1342 | |
| 1343 assert(len >= 10 && len <= 20); | |
| 1344 | |
| 1345 evbuffer_drain(bev->input, len); | |
| 1346 | |
| 1347 nread += len; | |
| 1348 if (nread == 65000) { | |
| 1349 bufferevent_disable(bev, EV_READ); | |
| 1350 test_ok++; | |
| 1351 } | |
| 1352 } | |
| 1353 | |
| 1354 static void | |
| 1355 wm_writecb(struct bufferevent *bev, void *arg) | |
| 1356 { | |
| 1357 if (EVBUFFER_LENGTH(bev->output) == 0) | |
| 1358 test_ok++; | |
| 1359 } | |
| 1360 | |
| 1361 static void | |
| 1362 wm_errorcb(struct bufferevent *bev, short what, void *arg) | |
| 1363 { | |
| 1364 test_ok = -2; | |
| 1365 } | |
| 1366 | |
| 1367 static void | |
| 1368 test_bufferevent_watermarks(void) | |
| 1369 { | |
| 1370 struct bufferevent *bev1, *bev2; | |
| 1371 char buffer[65000]; | |
| 1372 int i; | |
| 1373 | |
| 1374 setup_test("Bufferevent Watermarks: "); | |
| 1375 | |
| 1376 bev1 = bufferevent_new(pair[0], NULL, wm_writecb, wm_errorcb, NULL); | |
| 1377 bev2 = bufferevent_new(pair[1], wm_readcb, NULL, wm_errorcb, NULL); | |
| 1378 | |
| 1379 bufferevent_disable(bev1, EV_READ); | |
| 1380 bufferevent_enable(bev2, EV_READ); | |
| 1381 | |
| 1382 for (i = 0; i < sizeof(buffer); i++) | |
| 1383 buffer[i] = i; | |
| 1384 | |
| 1385 bufferevent_write(bev1, buffer, sizeof(buffer)); | |
| 1386 | |
| 1387 /* limit the reading on the receiving bufferevent */ | |
| 1388 bufferevent_setwatermark(bev2, EV_READ, 10, 20); | |
| 1389 | |
| 1390 event_dispatch(); | |
| 1391 | |
| 1392 bufferevent_free(bev1); | |
| 1393 bufferevent_free(bev2); | |
| 1394 | |
| 1395 if (test_ok != 2) | |
| 1396 test_ok = 0; | |
| 1397 | |
| 1398 cleanup_test(); | |
| 1399 } | |
| 1400 | |
| 1401 struct test_pri_event { | |
| 1402 struct event ev; | |
| 1403 int count; | |
| 1404 }; | |
| 1405 | |
| 1406 static void | |
| 1407 test_priorities_cb(int fd, short what, void *arg) | |
| 1408 { | |
| 1409 struct test_pri_event *pri = arg; | |
| 1410 struct timeval tv; | |
| 1411 | |
| 1412 if (pri->count == 3) { | |
| 1413 event_loopexit(NULL); | |
| 1414 return; | |
| 1415 } | |
| 1416 | |
| 1417 pri->count++; | |
| 1418 | |
| 1419 evutil_timerclear(&tv); | |
| 1420 event_add(&pri->ev, &tv); | |
| 1421 } | |
| 1422 | |
| 1423 static void | |
| 1424 test_priorities(int npriorities) | |
| 1425 { | |
| 1426 char buf[32]; | |
| 1427 struct test_pri_event one, two; | |
| 1428 struct timeval tv; | |
| 1429 | |
| 1430 evutil_snprintf(buf, sizeof(buf), "Testing Priorities %d: ", npriorities
); | |
| 1431 setup_test(buf); | |
| 1432 | |
| 1433 event_base_priority_init(global_base, npriorities); | |
| 1434 | |
| 1435 memset(&one, 0, sizeof(one)); | |
| 1436 memset(&two, 0, sizeof(two)); | |
| 1437 | |
| 1438 timeout_set(&one.ev, test_priorities_cb, &one); | |
| 1439 if (event_priority_set(&one.ev, 0) == -1) { | |
| 1440 fprintf(stderr, "%s: failed to set priority", __func__); | |
| 1441 exit(1); | |
| 1442 } | |
| 1443 | |
| 1444 timeout_set(&two.ev, test_priorities_cb, &two); | |
| 1445 if (event_priority_set(&two.ev, npriorities - 1) == -1) { | |
| 1446 fprintf(stderr, "%s: failed to set priority", __func__); | |
| 1447 exit(1); | |
| 1448 } | |
| 1449 | |
| 1450 evutil_timerclear(&tv); | |
| 1451 | |
| 1452 if (event_add(&one.ev, &tv) == -1) | |
| 1453 exit(1); | |
| 1454 if (event_add(&two.ev, &tv) == -1) | |
| 1455 exit(1); | |
| 1456 | |
| 1457 event_dispatch(); | |
| 1458 | |
| 1459 event_del(&one.ev); | |
| 1460 event_del(&two.ev); | |
| 1461 | |
| 1462 if (npriorities == 1) { | |
| 1463 if (one.count == 3 && two.count == 3) | |
| 1464 test_ok = 1; | |
| 1465 } else if (npriorities == 2) { | |
| 1466 /* Two is called once because event_loopexit is priority 1 */ | |
| 1467 if (one.count == 3 && two.count == 1) | |
| 1468 test_ok = 1; | |
| 1469 } else { | |
| 1470 if (one.count == 3 && two.count == 0) | |
| 1471 test_ok = 1; | |
| 1472 } | |
| 1473 | |
| 1474 cleanup_test(); | |
| 1475 } | |
| 1476 | |
| 1477 static void | |
| 1478 test_multiple_cb(int fd, short event, void *arg) | |
| 1479 { | |
| 1480 if (event & EV_READ) | |
| 1481 test_ok |= 1; | |
| 1482 else if (event & EV_WRITE) | |
| 1483 test_ok |= 2; | |
| 1484 } | |
| 1485 | |
| 1486 static void | |
| 1487 test_multiple_events_for_same_fd(void) | |
| 1488 { | |
| 1489 struct event e1, e2; | |
| 1490 | |
| 1491 setup_test("Multiple events for same fd: "); | |
| 1492 | |
| 1493 event_set(&e1, pair[0], EV_READ, test_multiple_cb, NULL); | |
| 1494 event_add(&e1, NULL); | |
| 1495 event_set(&e2, pair[0], EV_WRITE, test_multiple_cb, NULL); | |
| 1496 event_add(&e2, NULL); | |
| 1497 event_loop(EVLOOP_ONCE); | |
| 1498 event_del(&e2); | |
| 1499 write(pair[1], TEST1, strlen(TEST1)+1); | |
| 1500 event_loop(EVLOOP_ONCE); | |
| 1501 event_del(&e1); | |
| 1502 | |
| 1503 if (test_ok != 3) | |
| 1504 test_ok = 0; | |
| 1505 | |
| 1506 cleanup_test(); | |
| 1507 } | |
| 1508 | |
| 1509 int evtag_decode_int(uint32_t *pnumber, struct evbuffer *evbuf); | |
| 1510 int evtag_encode_tag(struct evbuffer *evbuf, uint32_t number); | |
| 1511 int evtag_decode_tag(uint32_t *pnumber, struct evbuffer *evbuf); | |
| 1512 | |
| 1513 static void | |
| 1514 read_once_cb(int fd, short event, void *arg) | |
| 1515 { | |
| 1516 char buf[256]; | |
| 1517 int len; | |
| 1518 | |
| 1519 len = read(fd, buf, sizeof(buf)); | |
| 1520 | |
| 1521 if (called) { | |
| 1522 test_ok = 0; | |
| 1523 } else if (len) { | |
| 1524 /* Assumes global pair[0] can be used for writing */ | |
| 1525 write(pair[0], TEST1, strlen(TEST1)+1); | |
| 1526 test_ok = 1; | |
| 1527 } | |
| 1528 | |
| 1529 called++; | |
| 1530 } | |
| 1531 | |
| 1532 static void | |
| 1533 test_want_only_once(void) | |
| 1534 { | |
| 1535 struct event ev; | |
| 1536 struct timeval tv; | |
| 1537 | |
| 1538 /* Very simple read test */ | |
| 1539 setup_test("Want read only once: "); | |
| 1540 | |
| 1541 write(pair[0], TEST1, strlen(TEST1)+1); | |
| 1542 | |
| 1543 /* Setup the loop termination */ | |
| 1544 evutil_timerclear(&tv); | |
| 1545 tv.tv_sec = 1; | |
| 1546 event_loopexit(&tv); | |
| 1547 | |
| 1548 event_set(&ev, pair[1], EV_READ, read_once_cb, &ev); | |
| 1549 if (event_add(&ev, NULL) == -1) | |
| 1550 exit(1); | |
| 1551 event_dispatch(); | |
| 1552 | |
| 1553 cleanup_test(); | |
| 1554 } | |
| 1555 | |
| 1556 #define TEST_MAX_INT 6 | |
| 1557 | |
| 1558 static void | |
| 1559 evtag_int_test(void) | |
| 1560 { | |
| 1561 struct evbuffer *tmp = evbuffer_new(); | |
| 1562 uint32_t integers[TEST_MAX_INT] = { | |
| 1563 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000 | |
| 1564 }; | |
| 1565 uint32_t integer; | |
| 1566 int i; | |
| 1567 | |
| 1568 for (i = 0; i < TEST_MAX_INT; i++) { | |
| 1569 int oldlen, newlen; | |
| 1570 oldlen = EVBUFFER_LENGTH(tmp); | |
| 1571 encode_int(tmp, integers[i]); | |
| 1572 newlen = EVBUFFER_LENGTH(tmp); | |
| 1573 fprintf(stdout, "\t\tencoded 0x%08x with %d bytes\n", | |
| 1574 integers[i], newlen - oldlen); | |
| 1575 } | |
| 1576 | |
| 1577 for (i = 0; i < TEST_MAX_INT; i++) { | |
| 1578 if (evtag_decode_int(&integer, tmp) == -1) { | |
| 1579 fprintf(stderr, "decode %d failed", i); | |
| 1580 exit(1); | |
| 1581 } | |
| 1582 if (integer != integers[i]) { | |
| 1583 fprintf(stderr, "got %x, wanted %x", | |
| 1584 integer, integers[i]); | |
| 1585 exit(1); | |
| 1586 } | |
| 1587 } | |
| 1588 | |
| 1589 if (EVBUFFER_LENGTH(tmp) != 0) { | |
| 1590 fprintf(stderr, "trailing data"); | |
| 1591 exit(1); | |
| 1592 } | |
| 1593 evbuffer_free(tmp); | |
| 1594 | |
| 1595 fprintf(stdout, "\t%s: OK\n", __func__); | |
| 1596 } | |
| 1597 | |
| 1598 static void | |
| 1599 evtag_fuzz(void) | |
| 1600 { | |
| 1601 u_char buffer[4096]; | |
| 1602 struct evbuffer *tmp = evbuffer_new(); | |
| 1603 struct timeval tv; | |
| 1604 int i, j; | |
| 1605 | |
| 1606 int not_failed = 0; | |
| 1607 for (j = 0; j < 100; j++) { | |
| 1608 for (i = 0; i < sizeof(buffer); i++) | |
| 1609 buffer[i] = rand(); | |
| 1610 evbuffer_drain(tmp, -1); | |
| 1611 evbuffer_add(tmp, buffer, sizeof(buffer)); | |
| 1612 | |
| 1613 if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) | |
| 1614 not_failed++; | |
| 1615 } | |
| 1616 | |
| 1617 /* The majority of decodes should fail */ | |
| 1618 if (not_failed >= 10) { | |
| 1619 fprintf(stderr, "evtag_unmarshal should have failed"); | |
| 1620 exit(1); | |
| 1621 } | |
| 1622 | |
| 1623 /* Now insert some corruption into the tag length field */ | |
| 1624 evbuffer_drain(tmp, -1); | |
| 1625 evutil_timerclear(&tv); | |
| 1626 tv.tv_sec = 1; | |
| 1627 evtag_marshal_timeval(tmp, 0, &tv); | |
| 1628 evbuffer_add(tmp, buffer, sizeof(buffer)); | |
| 1629 | |
| 1630 EVBUFFER_DATA(tmp)[1] = 0xff; | |
| 1631 if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) { | |
| 1632 fprintf(stderr, "evtag_unmarshal_timeval should have failed"); | |
| 1633 exit(1); | |
| 1634 } | |
| 1635 | |
| 1636 evbuffer_free(tmp); | |
| 1637 | |
| 1638 fprintf(stdout, "\t%s: OK\n", __func__); | |
| 1639 } | |
| 1640 | |
| 1641 static void | |
| 1642 evtag_tag_encoding(void) | |
| 1643 { | |
| 1644 struct evbuffer *tmp = evbuffer_new(); | |
| 1645 uint32_t integers[TEST_MAX_INT] = { | |
| 1646 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000 | |
| 1647 }; | |
| 1648 uint32_t integer; | |
| 1649 int i; | |
| 1650 | |
| 1651 for (i = 0; i < TEST_MAX_INT; i++) { | |
| 1652 int oldlen, newlen; | |
| 1653 oldlen = EVBUFFER_LENGTH(tmp); | |
| 1654 evtag_encode_tag(tmp, integers[i]); | |
| 1655 newlen = EVBUFFER_LENGTH(tmp); | |
| 1656 fprintf(stdout, "\t\tencoded 0x%08x with %d bytes\n", | |
| 1657 integers[i], newlen - oldlen); | |
| 1658 } | |
| 1659 | |
| 1660 for (i = 0; i < TEST_MAX_INT; i++) { | |
| 1661 if (evtag_decode_tag(&integer, tmp) == -1) { | |
| 1662 fprintf(stderr, "decode %d failed", i); | |
| 1663 exit(1); | |
| 1664 } | |
| 1665 if (integer != integers[i]) { | |
| 1666 fprintf(stderr, "got %x, wanted %x", | |
| 1667 integer, integers[i]); | |
| 1668 exit(1); | |
| 1669 } | |
| 1670 } | |
| 1671 | |
| 1672 if (EVBUFFER_LENGTH(tmp) != 0) { | |
| 1673 fprintf(stderr, "trailing data"); | |
| 1674 exit(1); | |
| 1675 } | |
| 1676 evbuffer_free(tmp); | |
| 1677 | |
| 1678 fprintf(stdout, "\t%s: OK\n", __func__); | |
| 1679 } | |
| 1680 | |
| 1681 static void | |
| 1682 evtag_test(void) | |
| 1683 { | |
| 1684 fprintf(stdout, "Testing Tagging:\n"); | |
| 1685 | |
| 1686 evtag_init(); | |
| 1687 evtag_int_test(); | |
| 1688 evtag_fuzz(); | |
| 1689 | |
| 1690 evtag_tag_encoding(); | |
| 1691 | |
| 1692 fprintf(stdout, "OK\n"); | |
| 1693 } | |
| 1694 | |
| 1695 #ifndef WIN32 | |
| 1696 static void | |
| 1697 rpc_test(void) | |
| 1698 { | |
| 1699 struct msg *msg, *msg2; | |
| 1700 struct kill *attack; | |
| 1701 struct run *run; | |
| 1702 struct evbuffer *tmp = evbuffer_new(); | |
| 1703 struct timeval tv_start, tv_end; | |
| 1704 uint32_t tag; | |
| 1705 int i; | |
| 1706 | |
| 1707 fprintf(stdout, "Testing RPC: "); | |
| 1708 | |
| 1709 msg = msg_new(); | |
| 1710 EVTAG_ASSIGN(msg, from_name, "niels"); | |
| 1711 EVTAG_ASSIGN(msg, to_name, "phoenix"); | |
| 1712 | |
| 1713 if (EVTAG_GET(msg, attack, &attack) == -1) { | |
| 1714 fprintf(stderr, "Failed to set kill message.\n"); | |
| 1715 exit(1); | |
| 1716 } | |
| 1717 | |
| 1718 EVTAG_ASSIGN(attack, weapon, "feather"); | |
| 1719 EVTAG_ASSIGN(attack, action, "tickle"); | |
| 1720 | |
| 1721 evutil_gettimeofday(&tv_start, NULL); | |
| 1722 for (i = 0; i < 1000; ++i) { | |
| 1723 run = EVTAG_ADD(msg, run); | |
| 1724 if (run == NULL) { | |
| 1725 fprintf(stderr, "Failed to add run message.\n"); | |
| 1726 exit(1); | |
| 1727 } | |
| 1728 EVTAG_ASSIGN(run, how, "very fast but with some data in it"); | |
| 1729 EVTAG_ASSIGN(run, fixed_bytes, | |
| 1730 (unsigned char*)"012345678901234567890123"); | |
| 1731 } | |
| 1732 | |
| 1733 if (msg_complete(msg) == -1) { | |
| 1734 fprintf(stderr, "Failed to make complete message.\n"); | |
| 1735 exit(1); | |
| 1736 } | |
| 1737 | |
| 1738 evtag_marshal_msg(tmp, 0xdeaf, msg); | |
| 1739 | |
| 1740 if (evtag_peek(tmp, &tag) == -1) { | |
| 1741 fprintf(stderr, "Failed to peak tag.\n"); | |
| 1742 exit (1); | |
| 1743 } | |
| 1744 | |
| 1745 if (tag != 0xdeaf) { | |
| 1746 fprintf(stderr, "Got incorrect tag: %0x.\n", tag); | |
| 1747 exit (1); | |
| 1748 } | |
| 1749 | |
| 1750 msg2 = msg_new(); | |
| 1751 if (evtag_unmarshal_msg(tmp, 0xdeaf, msg2) == -1) { | |
| 1752 fprintf(stderr, "Failed to unmarshal message.\n"); | |
| 1753 exit(1); | |
| 1754 } | |
| 1755 | |
| 1756 evutil_gettimeofday(&tv_end, NULL); | |
| 1757 evutil_timersub(&tv_end, &tv_start, &tv_end); | |
| 1758 fprintf(stderr, "(%.1f us/add) ", | |
| 1759 (float)tv_end.tv_sec/(float)i * 1000000.0 + | |
| 1760 tv_end.tv_usec / (float)i); | |
| 1761 | |
| 1762 if (!EVTAG_HAS(msg2, from_name) || | |
| 1763 !EVTAG_HAS(msg2, to_name) || | |
| 1764 !EVTAG_HAS(msg2, attack)) { | |
| 1765 fprintf(stderr, "Missing data structures.\n"); | |
| 1766 exit(1); | |
| 1767 } | |
| 1768 | |
| 1769 if (EVTAG_LEN(msg2, run) != i) { | |
| 1770 fprintf(stderr, "Wrong number of run messages.\n"); | |
| 1771 exit(1); | |
| 1772 } | |
| 1773 | |
| 1774 msg_free(msg); | |
| 1775 msg_free(msg2); | |
| 1776 | |
| 1777 evbuffer_free(tmp); | |
| 1778 | |
| 1779 fprintf(stdout, "OK\n"); | |
| 1780 } | |
| 1781 #endif | |
| 1782 | |
| 1783 static void | |
| 1784 test_evutil_strtoll(void) | |
| 1785 { | |
| 1786 const char *s; | |
| 1787 char *endptr; | |
| 1788 setup_test("evutil_stroll: "); | |
| 1789 test_ok = 0; | |
| 1790 | |
| 1791 if (evutil_strtoll("5000000000", NULL, 10) != ((ev_int64_t)5000000)*1000
) | |
| 1792 goto err; | |
| 1793 if (evutil_strtoll("-5000000000", NULL, 10) != ((ev_int64_t)5000000)*-10
00) | |
| 1794 goto err; | |
| 1795 s = " 99999stuff"; | |
| 1796 if (evutil_strtoll(s, &endptr, 10) != (ev_int64_t)99999) | |
| 1797 goto err; | |
| 1798 if (endptr != s+6) | |
| 1799 goto err; | |
| 1800 if (evutil_strtoll("foo", NULL, 10) != 0) | |
| 1801 goto err; | |
| 1802 | |
| 1803 test_ok = 1; | |
| 1804 err: | |
| 1805 cleanup_test(); | |
| 1806 } | |
| 1807 | |
| 1808 | |
| 1809 int | |
| 1810 main (int argc, char **argv) | |
| 1811 { | |
| 1812 #ifdef WIN32 | |
| 1813 WORD wVersionRequested; | |
| 1814 WSADATA wsaData; | |
| 1815 int err; | |
| 1816 | |
| 1817 wVersionRequested = MAKEWORD( 2, 2 ); | |
| 1818 | |
| 1819 err = WSAStartup( wVersionRequested, &wsaData ); | |
| 1820 #endif | |
| 1821 | |
| 1822 #ifndef WIN32 | |
| 1823 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) | |
| 1824 return (1); | |
| 1825 #endif | |
| 1826 setvbuf(stdout, NULL, _IONBF, 0); | |
| 1827 | |
| 1828 /* Initalize the event library */ | |
| 1829 global_base = event_init(); | |
| 1830 | |
| 1831 test_registerfds(); | |
| 1832 | |
| 1833 test_evutil_strtoll(); | |
| 1834 | |
| 1835 /* use the global event base and need to be called first */ | |
| 1836 test_priorities(1); | |
| 1837 test_priorities(2); | |
| 1838 test_priorities(3); | |
| 1839 | |
| 1840 test_evbuffer(); | |
| 1841 test_evbuffer_find(); | |
| 1842 test_evbuffer_readln(); | |
| 1843 | |
| 1844 test_bufferevent(); | |
| 1845 test_bufferevent_watermarks(); | |
| 1846 | |
| 1847 test_free_active_base(); | |
| 1848 | |
| 1849 test_event_base_new(); | |
| 1850 | |
| 1851 http_suite(); | |
| 1852 | |
| 1853 #ifndef WIN32 | |
| 1854 rpc_suite(); | |
| 1855 #endif | |
| 1856 | |
| 1857 dns_suite(); | |
| 1858 | |
| 1859 #ifndef WIN32 | |
| 1860 test_fork(); | |
| 1861 #endif | |
| 1862 | |
| 1863 test_simpleread(); | |
| 1864 | |
| 1865 test_simplewrite(); | |
| 1866 | |
| 1867 test_multiple(); | |
| 1868 | |
| 1869 test_persistent(); | |
| 1870 | |
| 1871 test_combined(); | |
| 1872 | |
| 1873 test_simpletimeout(); | |
| 1874 #ifndef WIN32 | |
| 1875 test_simplesignal(); | |
| 1876 test_multiplesignal(); | |
| 1877 test_immediatesignal(); | |
| 1878 #endif | |
| 1879 test_loopexit(); | |
| 1880 test_loopbreak(); | |
| 1881 | |
| 1882 test_loopexit_multiple(); | |
| 1883 | |
| 1884 test_multiple_events_for_same_fd(); | |
| 1885 | |
| 1886 test_want_only_once(); | |
| 1887 | |
| 1888 evtag_test(); | |
| 1889 | |
| 1890 #ifndef WIN32 | |
| 1891 rpc_test(); | |
| 1892 | |
| 1893 test_signal_dealloc(); | |
| 1894 test_signal_pipeloss(); | |
| 1895 test_signal_switchbase(); | |
| 1896 test_signal_restore(); | |
| 1897 test_signal_assert(); | |
| 1898 test_signal_while_processing(); | |
| 1899 #endif | |
| 1900 | |
| 1901 return (0); | |
| 1902 } | |
| 1903 | |
| OLD | NEW |