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 |