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