2 * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
28 /* The old tests here need assertions to work. */
36 #include "event2/event-config.h"
38 #include <sys/types.h>
40 #ifdef _EVENT_HAVE_SYS_TIME_H
43 #include <sys/queue.h>
45 #include <sys/socket.h>
50 #include <netinet/in.h>
60 #ifdef _EVENT_HAVE_ARPA_INET_H
61 #include <arpa/inet.h>
64 #include "event2/event-config.h"
65 #include "event2/event.h"
66 #include "event2/event_struct.h"
67 #include "event2/event_compat.h"
68 #include "event2/tag.h"
69 #include "event2/buffer.h"
70 #include "event2/bufferevent.h"
71 #include "event2/bufferevent_compat.h"
72 #include "event2/bufferevent_struct.h"
73 #include "event2/listener.h"
74 #include "event2/util.h"
76 #include "bufferevent-internal.h"
78 #include "iocp-internal.h"
82 #include "regress_testutils.h"
85 * simple bufferevent test
89 readcb(struct bufferevent
*bev
, void *arg
)
91 if (evbuffer_get_length(bev
->input
) == 8333) {
92 struct evbuffer
*evbuf
= evbuffer_new();
93 assert(evbuf
!= NULL
);
95 /* gratuitous test of bufferevent_read_buffer */
96 bufferevent_read_buffer(bev
, evbuf
);
98 bufferevent_disable(bev
, EV_READ
);
100 if (evbuffer_get_length(evbuf
) == 8333) {
104 evbuffer_free(evbuf
);
109 writecb(struct bufferevent
*bev
, void *arg
)
111 if (evbuffer_get_length(bev
->output
) == 0) {
117 errorcb(struct bufferevent
*bev
, short what
, void *arg
)
123 test_bufferevent_impl(int use_pair
)
125 struct bufferevent
*bev1
= NULL
, *bev2
= NULL
;
130 struct bufferevent
*pair
[2];
131 tt_assert(0 == bufferevent_pair_new(NULL
, 0, pair
));
134 bufferevent_setcb(bev1
, readcb
, writecb
, errorcb
, NULL
);
135 bufferevent_setcb(bev2
, readcb
, writecb
, errorcb
, NULL
);
136 tt_int_op(bufferevent_getfd(bev1
), ==, -1);
137 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, NULL
);
138 tt_ptr_op(bufferevent_pair_get_partner(bev1
), ==, bev2
);
139 tt_ptr_op(bufferevent_pair_get_partner(bev2
), ==, bev1
);
141 bev1
= bufferevent_new(pair
[0], readcb
, writecb
, errorcb
, NULL
);
142 bev2
= bufferevent_new(pair
[1], readcb
, writecb
, errorcb
, NULL
);
143 tt_int_op(bufferevent_getfd(bev1
), ==, pair
[0]);
144 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, NULL
);
145 tt_ptr_op(bufferevent_pair_get_partner(bev1
), ==, NULL
);
146 tt_ptr_op(bufferevent_pair_get_partner(bev2
), ==, NULL
);
149 bufferevent_disable(bev1
, EV_READ
);
150 bufferevent_enable(bev2
, EV_READ
);
152 tt_int_op(bufferevent_get_enabled(bev1
), ==, EV_WRITE
);
153 tt_int_op(bufferevent_get_enabled(bev2
), ==, EV_WRITE
|EV_READ
);
155 for (i
= 0; i
< (int)sizeof(buffer
); i
++)
158 bufferevent_write(bev1
, buffer
, sizeof(buffer
));
162 bufferevent_free(bev1
);
163 tt_ptr_op(bufferevent_pair_get_partner(bev2
), ==, NULL
);
164 bufferevent_free(bev2
);
173 test_bufferevent(void)
175 test_bufferevent_impl(0);
179 test_bufferevent_pair(void)
181 test_bufferevent_impl(1);
185 * test watermarks and bufferevent
189 wm_readcb(struct bufferevent
*bev
, void *arg
)
191 struct evbuffer
*evbuf
= evbuffer_new();
192 int len
= (int)evbuffer_get_length(bev
->input
);
195 assert(len
>= 10 && len
<= 20);
197 assert(evbuf
!= NULL
);
199 /* gratuitous test of bufferevent_read_buffer */
200 bufferevent_read_buffer(bev
, evbuf
);
203 if (nread
== 65000) {
204 bufferevent_disable(bev
, EV_READ
);
208 evbuffer_free(evbuf
);
212 wm_writecb(struct bufferevent
*bev
, void *arg
)
214 assert(evbuffer_get_length(bev
->output
) <= 100);
215 if (evbuffer_get_length(bev
->output
) == 0) {
216 evbuffer_drain(bev
->output
, evbuffer_get_length(bev
->output
));
222 wm_errorcb(struct bufferevent
*bev
, short what
, void *arg
)
228 test_bufferevent_watermarks_impl(int use_pair
)
230 struct bufferevent
*bev1
= NULL
, *bev2
= NULL
;
236 struct bufferevent
*pair
[2];
237 tt_assert(0 == bufferevent_pair_new(NULL
, 0, pair
));
240 bufferevent_setcb(bev1
, NULL
, wm_writecb
, errorcb
, NULL
);
241 bufferevent_setcb(bev2
, wm_readcb
, NULL
, errorcb
, NULL
);
243 bev1
= bufferevent_new(pair
[0], NULL
, wm_writecb
, wm_errorcb
, NULL
);
244 bev2
= bufferevent_new(pair
[1], wm_readcb
, NULL
, wm_errorcb
, NULL
);
246 bufferevent_disable(bev1
, EV_READ
);
247 bufferevent_enable(bev2
, EV_READ
);
249 for (i
= 0; i
< (int)sizeof(buffer
); i
++)
252 /* limit the reading on the receiving bufferevent */
253 bufferevent_setwatermark(bev2
, EV_READ
, 10, 20);
255 /* Tell the sending bufferevent not to notify us till it's down to
257 bufferevent_setwatermark(bev1
, EV_WRITE
, 100, 2000);
259 bufferevent_write(bev1
, buffer
, sizeof(buffer
));
263 tt_int_op(test_ok
, ==, 2);
265 /* The write callback drained all the data from outbuf, so we
266 * should have removed the write event... */
267 tt_assert(!event_pending(&bev2
->ev_write
, EV_WRITE
, NULL
));
270 bufferevent_free(bev1
);
271 bufferevent_free(bev2
);
275 test_bufferevent_watermarks(void)
277 test_bufferevent_watermarks_impl(0);
281 test_bufferevent_pair_watermarks(void)
283 test_bufferevent_watermarks_impl(1);
287 * Test bufferevent filters
290 /* strip an 'x' from each byte */
292 static enum bufferevent_filter_result
293 bufferevent_input_filter(struct evbuffer
*src
, struct evbuffer
*dst
,
294 ev_ssize_t lim
, enum bufferevent_flush_mode state
, void *ctx
)
296 const unsigned char *buffer
;
299 buffer
= evbuffer_pullup(src
, evbuffer_get_length(src
));
300 for (i
= 0; i
< evbuffer_get_length(src
); i
+= 2) {
301 assert(buffer
[i
] == 'x');
302 evbuffer_add(dst
, buffer
+ i
+ 1, 1);
304 if (i
+ 2 > evbuffer_get_length(src
))
308 evbuffer_drain(src
, i
);
312 /* add an 'x' before each byte */
314 static enum bufferevent_filter_result
315 bufferevent_output_filter(struct evbuffer
*src
, struct evbuffer
*dst
,
316 ev_ssize_t lim
, enum bufferevent_flush_mode state
, void *ctx
)
318 const unsigned char *buffer
;
321 buffer
= evbuffer_pullup(src
, evbuffer_get_length(src
));
322 for (i
= 0; i
< evbuffer_get_length(src
); ++i
) {
323 evbuffer_add(dst
, "x", 1);
324 evbuffer_add(dst
, buffer
+ i
, 1);
327 evbuffer_drain(src
, evbuffer_get_length(src
));
332 test_bufferevent_filters_impl(int use_pair
)
334 struct bufferevent
*bev1
= NULL
, *bev2
= NULL
;
335 struct bufferevent
*bev1_base
= NULL
, *bev2_base
= NULL
;
342 struct bufferevent
*pair
[2];
343 tt_assert(0 == bufferevent_pair_new(NULL
, 0, pair
));
347 bev1
= bufferevent_socket_new(NULL
, pair
[0], 0);
348 bev2
= bufferevent_socket_new(NULL
, pair
[1], 0);
353 for (i
= 0; i
< (int)sizeof(buffer
); i
++)
356 bev1
= bufferevent_filter_new(bev1
, NULL
, bufferevent_output_filter
,
357 BEV_OPT_CLOSE_ON_FREE
, NULL
, NULL
);
359 bev2
= bufferevent_filter_new(bev2
, bufferevent_input_filter
,
360 NULL
, BEV_OPT_CLOSE_ON_FREE
, NULL
, NULL
);
361 bufferevent_setcb(bev1
, NULL
, writecb
, errorcb
, NULL
);
362 bufferevent_setcb(bev2
, readcb
, NULL
, errorcb
, NULL
);
364 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, bev1_base
);
365 tt_ptr_op(bufferevent_get_underlying(bev2
), ==, bev2_base
);
366 tt_int_op(bufferevent_getfd(bev1
), ==, -1);
367 tt_int_op(bufferevent_getfd(bev2
), ==, -1);
369 bufferevent_disable(bev1
, EV_READ
);
370 bufferevent_enable(bev2
, EV_READ
);
371 /* insert some filters */
372 bufferevent_write(bev1
, buffer
, sizeof(buffer
));
380 bufferevent_free(bev1
);
381 bufferevent_free(bev2
);
386 test_bufferevent_filters(void)
388 test_bufferevent_filters_impl(0);
392 test_bufferevent_pair_filters(void)
394 test_bufferevent_filters_impl(1);
399 sender_writecb(struct bufferevent
*bev
, void *ctx
)
401 if (evbuffer_get_length(bufferevent_get_output(bev
)) == 0) {
402 bufferevent_disable(bev
,EV_READ
|EV_WRITE
);
403 bufferevent_free(bev
);
408 sender_errorcb(struct bufferevent
*bev
, short what
, void *ctx
)
410 TT_FAIL(("Got sender error %d",(int)what
));
413 static int bufferevent_connect_test_flags
= 0;
414 static int n_strings_read
= 0;
415 static int n_reads_invoked
= 0;
417 #define TEST_STR "Now is the time for all good events to signal for " \
418 "the good of their protocol"
420 listen_cb(struct evconnlistener
*listener
, evutil_socket_t fd
,
421 struct sockaddr
*sa
, int socklen
, void *arg
)
423 struct event_base
*base
= arg
;
424 struct bufferevent
*bev
;
425 const char s
[] = TEST_STR
;
426 TT_BLATHER(("Got a request on socket %d", (int)fd
));
427 bev
= bufferevent_socket_new(base
, fd
, bufferevent_connect_test_flags
);
429 bufferevent_setcb(bev
, NULL
, sender_writecb
, sender_errorcb
, NULL
);
430 bufferevent_write(bev
, s
, sizeof(s
));
436 reader_eventcb(struct bufferevent
*bev
, short what
, void *ctx
)
438 struct event_base
*base
= ctx
;
439 if (what
& BEV_EVENT_ERROR
) {
441 TT_FAIL(("got connector error %d", (int)what
));
444 if (what
& BEV_EVENT_CONNECTED
) {
445 bufferevent_enable(bev
, EV_READ
);
447 if (what
& BEV_EVENT_EOF
) {
450 n
= bufferevent_read(bev
, buf
, sizeof(buf
)-1);
452 tt_str_op(buf
, ==, TEST_STR
);
453 if (++n_strings_read
== 2)
454 event_base_loopexit(base
, NULL
);
461 reader_readcb(struct bufferevent
*bev
, void *ctx
)
467 test_bufferevent_connect(void *arg
)
469 struct basic_test_data
*data
= arg
;
470 struct evconnlistener
*lev
=NULL
;
471 struct bufferevent
*bev1
=NULL
, *bev2
=NULL
;
472 struct sockaddr_in localhost
;
473 struct sockaddr_storage ss
;
477 int be_flags
=BEV_OPT_CLOSE_ON_FREE
;
479 if (strstr((char*)data
->setup_data
, "defer")) {
480 be_flags
|= BEV_OPT_DEFER_CALLBACKS
;
482 if (strstr((char*)data
->setup_data
, "unlocked")) {
483 be_flags
|= BEV_OPT_UNLOCK_CALLBACKS
;
485 if (strstr((char*)data
->setup_data
, "lock")) {
486 be_flags
|= BEV_OPT_THREADSAFE
;
488 bufferevent_connect_test_flags
= be_flags
;
490 if (!strcmp((char*)data
->setup_data
, "unset_connectex")) {
491 struct win32_extension_fns
*ext
=
492 (struct win32_extension_fns
*)
493 event_get_win32_extension_fns();
494 ext
->ConnectEx
= NULL
;
498 memset(&localhost
, 0, sizeof(localhost
));
500 localhost
.sin_port
= 0; /* pick-a-port */
501 localhost
.sin_addr
.s_addr
= htonl(0x7f000001L
);
502 localhost
.sin_family
= AF_INET
;
503 sa
= (struct sockaddr
*)&localhost
;
504 lev
= evconnlistener_new_bind(data
->base
, listen_cb
, data
->base
,
505 LEV_OPT_CLOSE_ON_FREE
|LEV_OPT_REUSEABLE
,
506 16, sa
, sizeof(localhost
));
509 sa
= (struct sockaddr
*)&ss
;
511 if (regress_get_listener_addr(lev
, sa
, &slen
) < 0) {
512 tt_abort_perror("getsockname");
515 tt_assert(!evconnlistener_enable(lev
));
516 bev1
= bufferevent_socket_new(data
->base
, -1, be_flags
);
517 bev2
= bufferevent_socket_new(data
->base
, -1, be_flags
);
520 bufferevent_setcb(bev1
, reader_readcb
,NULL
, reader_eventcb
, data
->base
);
521 bufferevent_setcb(bev2
, reader_readcb
,NULL
, reader_eventcb
, data
->base
);
523 bufferevent_enable(bev1
, EV_READ
);
524 bufferevent_enable(bev2
, EV_READ
);
526 tt_want(!bufferevent_socket_connect(bev1
, sa
, sizeof(localhost
)));
527 tt_want(!bufferevent_socket_connect(bev2
, sa
, sizeof(localhost
)));
529 event_base_dispatch(data
->base
);
531 tt_int_op(n_strings_read
, ==, 2);
532 tt_int_op(n_reads_invoked
, >=, 2);
535 evconnlistener_free(lev
);
538 bufferevent_free(bev1
);
541 bufferevent_free(bev2
);
545 want_fail_eventcb(struct bufferevent
*bev
, short what
, void *ctx
)
547 struct event_base
*base
= ctx
;
551 if (what
& BEV_EVENT_ERROR
) {
552 s
= bufferevent_getfd(bev
);
553 err
= evutil_socket_error_to_string(evutil_socket_geterror(s
));
554 TT_BLATHER(("connection failure on %d: %s", s
, err
));
557 TT_FAIL(("didn't fail? what %hd", what
));
560 event_base_loopexit(base
, NULL
);
564 close_socket_cb(evutil_socket_t fd
, short what
, void *arg
)
566 evutil_socket_t
*fdp
= arg
;
568 evutil_closesocket(*fdp
);
574 test_bufferevent_connect_fail(void *arg
)
576 struct basic_test_data
*data
= arg
;
577 struct bufferevent
*bev
=NULL
;
578 struct sockaddr_in localhost
;
579 struct sockaddr
*sa
= (struct sockaddr
*)&localhost
;
580 evutil_socket_t fake_listener
= -1;
581 ev_socklen_t slen
= sizeof(localhost
);
582 struct event close_listener_event
;
583 int close_listener_event_added
= 0;
584 struct timeval one_second
= { 1, 0 };
589 memset(&localhost
, 0, sizeof(localhost
));
590 localhost
.sin_port
= 0; /* have the kernel pick a port */
591 localhost
.sin_addr
.s_addr
= htonl(0x7f000001L
);
592 localhost
.sin_family
= AF_INET
;
594 /* bind, but don't listen or accept. should trigger
595 "Connection refused" reliably on most platforms. */
596 fake_listener
= socket(localhost
.sin_family
, SOCK_STREAM
, 0);
597 tt_assert(fake_listener
>= 0);
598 tt_assert(bind(fake_listener
, sa
, slen
) == 0);
599 tt_assert(getsockname(fake_listener
, sa
, &slen
) == 0);
600 bev
= bufferevent_socket_new(data
->base
, -1,
601 BEV_OPT_CLOSE_ON_FREE
| BEV_OPT_DEFER_CALLBACKS
);
603 bufferevent_setcb(bev
, NULL
, NULL
, want_fail_eventcb
, data
->base
);
605 r
= bufferevent_socket_connect(bev
, sa
, slen
);
606 /* XXXX we'd like to test the '0' case everywhere, but FreeBSD tells
607 * detects the error immediately, which is not really wrong of it. */
608 tt_want(r
== 0 || r
== -1);
610 /* Close the listener socket after a second. This should trigger
611 "connection refused" on some other platforms, including OSX. */
612 evtimer_assign(&close_listener_event
, data
->base
, close_socket_cb
,
614 event_add(&close_listener_event
, &one_second
);
615 close_listener_event_added
= 1;
617 event_base_dispatch(data
->base
);
619 tt_int_op(test_ok
, ==, 1);
622 if (fake_listener
>= 0)
623 evutil_closesocket(fake_listener
);
626 bufferevent_free(bev
);
628 if (close_listener_event_added
)
629 event_del(&close_listener_event
);
632 struct timeout_cb_result
{
633 struct timeval read_timeout_at
;
634 struct timeval write_timeout_at
;
635 struct timeval last_wrote_at
;
637 int n_write_timeouts
;
642 bev_timeout_write_cb(struct bufferevent
*bev
, void *arg
)
644 struct timeout_cb_result
*res
= arg
;
645 evutil_gettimeofday(&res
->last_wrote_at
, NULL
);
649 bev_timeout_event_cb(struct bufferevent
*bev
, short what
, void *arg
)
651 struct timeout_cb_result
*res
= arg
;
654 if ((what
& (BEV_EVENT_READING
|BEV_EVENT_TIMEOUT
))
655 == (BEV_EVENT_READING
|BEV_EVENT_TIMEOUT
)) {
656 evutil_gettimeofday(&res
->read_timeout_at
, NULL
);
657 ++res
->n_read_timeouts
;
659 if ((what
& (BEV_EVENT_WRITING
|BEV_EVENT_TIMEOUT
))
660 == (BEV_EVENT_WRITING
|BEV_EVENT_TIMEOUT
)) {
661 evutil_gettimeofday(&res
->write_timeout_at
, NULL
);
662 ++res
->n_write_timeouts
;
667 test_bufferevent_timeouts(void *arg
)
669 /* "arg" is a string containing "pair" and/or "filter". */
670 struct bufferevent
*bev1
= NULL
, *bev2
= NULL
;
671 struct basic_test_data
*data
= arg
;
672 int use_pair
= 0, use_filter
= 0;
673 struct timeval tv_w
, tv_r
, started_at
;
674 struct timeout_cb_result res1
, res2
;
677 memset(&res1
, 0, sizeof(res1
));
678 memset(&res2
, 0, sizeof(res2
));
680 if (strstr((char*)data
->setup_data
, "pair"))
682 if (strstr((char*)data
->setup_data
, "filter"))
686 struct bufferevent
*p
[2];
687 tt_int_op(0, ==, bufferevent_pair_new(data
->base
, 0, p
));
691 bev1
= bufferevent_socket_new(data
->base
, data
->pair
[0], 0);
692 bev2
= bufferevent_socket_new(data
->base
, data
->pair
[1], 0);
699 struct bufferevent
*bevf1
, *bevf2
;
700 bevf1
= bufferevent_filter_new(bev1
, NULL
, NULL
,
701 BEV_OPT_CLOSE_ON_FREE
, NULL
, NULL
);
702 bevf2
= bufferevent_filter_new(bev2
, NULL
, NULL
,
703 BEV_OPT_CLOSE_ON_FREE
, NULL
, NULL
);
710 /* Do this nice and early. */
711 bufferevent_disable(bev2
, EV_READ
);
713 /* bev1 will try to write and read. Both will time out. */
714 evutil_gettimeofday(&started_at
, NULL
);
715 tv_w
.tv_sec
= tv_r
.tv_sec
= 0;
716 tv_w
.tv_usec
= 100*1000;
717 tv_r
.tv_usec
= 150*1000;
718 bufferevent_setcb(bev1
, NULL
, bev_timeout_write_cb
,
719 bev_timeout_event_cb
, &res1
);
720 bufferevent_setwatermark(bev1
, EV_WRITE
, 1024*1024+10, 0);
721 bufferevent_set_timeouts(bev1
, &tv_r
, &tv_w
);
723 /* For a pair, the fact that the other side isn't reading
724 * makes the writer stall */
725 bufferevent_write(bev1
, "ABCDEFG", 7);
727 /* For a real socket, the kernel's TCP buffers can eat a
728 * fair number of bytes; make sure that at some point we
729 * have some bytes that will stall. */
730 struct evbuffer
*output
= bufferevent_get_output(bev1
);
732 memset(buf
, 0xbb, sizeof(buf
));
733 for (i
=0;i
<1024;++i
) {
734 evbuffer_add_reference(output
, buf
, sizeof(buf
),
738 bufferevent_enable(bev1
, EV_READ
|EV_WRITE
);
740 /* bev2 has nothing to say, and isn't listening. */
741 bufferevent_setcb(bev2
, NULL
, bev_timeout_write_cb
,
742 bev_timeout_event_cb
, &res2
);
743 tv_w
.tv_sec
= tv_r
.tv_sec
= 0;
744 tv_w
.tv_usec
= 200*1000;
745 tv_r
.tv_usec
= 100*1000;
746 bufferevent_set_timeouts(bev2
, &tv_r
, &tv_w
);
747 bufferevent_enable(bev2
, EV_WRITE
);
752 event_base_loopexit(data
->base
, &tv_r
);
753 event_base_dispatch(data
->base
);
755 /* XXXX Test that actually reading or writing a little resets the
758 /* Each buf1 timeout happens, and happens only once. */
759 tt_want(res1
.n_read_timeouts
);
760 tt_want(res1
.n_write_timeouts
);
761 tt_want(res1
.n_read_timeouts
== 1);
762 tt_want(res1
.n_write_timeouts
== 1);
764 test_timeval_diff_eq(&started_at
, &res1
.read_timeout_at
, 150);
765 test_timeval_diff_eq(&started_at
, &res1
.write_timeout_at
, 100);
769 bufferevent_free(bev1
);
771 bufferevent_free(bev2
);
774 struct testcase_t bufferevent_testcases
[] = {
776 LEGACY(bufferevent
, TT_ISOLATED
),
777 LEGACY(bufferevent_pair
, TT_ISOLATED
),
778 LEGACY(bufferevent_watermarks
, TT_ISOLATED
),
779 LEGACY(bufferevent_pair_watermarks
, TT_ISOLATED
),
780 LEGACY(bufferevent_filters
, TT_ISOLATED
),
781 LEGACY(bufferevent_pair_filters
, TT_ISOLATED
),
782 { "bufferevent_connect", test_bufferevent_connect
, TT_FORK
|TT_NEED_BASE
,
783 &basic_setup
, (void*)"" },
784 { "bufferevent_connect_defer", test_bufferevent_connect
,
785 TT_FORK
|TT_NEED_BASE
, &basic_setup
, (void*)"defer" },
786 { "bufferevent_connect_lock", test_bufferevent_connect
,
787 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
, &basic_setup
, (void*)"lock" },
788 { "bufferevent_connect_lock_defer", test_bufferevent_connect
,
789 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
, &basic_setup
,
790 (void*)"defer lock" },
791 { "bufferevent_connect_unlocked_cbs", test_bufferevent_connect
,
792 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
, &basic_setup
,
793 (void*)"lock defer unlocked" },
794 { "bufferevent_connect_fail", test_bufferevent_connect_fail
,
795 TT_FORK
|TT_NEED_BASE
, &basic_setup
, NULL
},
796 { "bufferevent_timeout", test_bufferevent_timeouts
,
797 TT_FORK
|TT_NEED_BASE
|TT_NEED_SOCKETPAIR
, &basic_setup
, (void*)"" },
798 { "bufferevent_timeout_pair", test_bufferevent_timeouts
,
799 TT_FORK
|TT_NEED_BASE
, &basic_setup
, (void*)"pair" },
800 { "bufferevent_timeout_filter", test_bufferevent_timeouts
,
801 TT_FORK
|TT_NEED_BASE
, &basic_setup
, (void*)"filter" },
802 { "bufferevent_timeout_filter_pair", test_bufferevent_timeouts
,
803 TT_FORK
|TT_NEED_BASE
, &basic_setup
, (void*)"filter pair" },
804 #ifdef _EVENT_HAVE_LIBZ
805 LEGACY(bufferevent_zlib
, TT_ISOLATED
),
807 { "bufferevent_zlib", NULL
, TT_SKIP
, NULL
, NULL
},
813 struct testcase_t bufferevent_iocp_testcases
[] = {
815 LEGACY(bufferevent
, TT_ISOLATED
|TT_ENABLE_IOCP
),
816 LEGACY(bufferevent_watermarks
, TT_ISOLATED
|TT_ENABLE_IOCP
),
817 LEGACY(bufferevent_filters
, TT_ISOLATED
|TT_ENABLE_IOCP
),
818 { "bufferevent_connect", test_bufferevent_connect
,
819 TT_FORK
|TT_NEED_BASE
|TT_ENABLE_IOCP
, &basic_setup
, (void*)"" },
820 { "bufferevent_connect_defer", test_bufferevent_connect
,
821 TT_FORK
|TT_NEED_BASE
|TT_ENABLE_IOCP
, &basic_setup
, (void*)"defer" },
822 { "bufferevent_connect_lock", test_bufferevent_connect
,
823 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
|TT_ENABLE_IOCP
, &basic_setup
,
825 { "bufferevent_connect_lock_defer", test_bufferevent_connect
,
826 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
|TT_ENABLE_IOCP
, &basic_setup
,
827 (void*)"defer lock" },
828 { "bufferevent_connect_fail", test_bufferevent_connect_fail
,
829 TT_FORK
|TT_NEED_BASE
|TT_ENABLE_IOCP
, &basic_setup
, NULL
},
830 { "bufferevent_connect_nonblocking", test_bufferevent_connect
,
831 TT_FORK
|TT_NEED_BASE
|TT_ENABLE_IOCP
, &basic_setup
,
832 (void*)"unset_connectex" },