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)*-1000)
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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>