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"
77 #include "util-internal.h"
79 #include "iocp-internal.h"
83 #include "regress_testutils.h"
86 * simple bufferevent test
90 readcb(struct bufferevent
*bev
, void *arg
)
92 if (evbuffer_get_length(bev
->input
) == 8333) {
93 struct evbuffer
*evbuf
= evbuffer_new();
94 assert(evbuf
!= NULL
);
96 /* gratuitous test of bufferevent_read_buffer */
97 bufferevent_read_buffer(bev
, evbuf
);
99 bufferevent_disable(bev
, EV_READ
);
101 if (evbuffer_get_length(evbuf
) == 8333) {
105 evbuffer_free(evbuf
);
110 writecb(struct bufferevent
*bev
, void *arg
)
112 if (evbuffer_get_length(bev
->output
) == 0) {
118 errorcb(struct bufferevent
*bev
, short what
, void *arg
)
124 test_bufferevent_impl(int use_pair
)
126 struct bufferevent
*bev1
= NULL
, *bev2
= NULL
;
131 struct bufferevent
*pair
[2];
132 tt_assert(0 == bufferevent_pair_new(NULL
, 0, pair
));
135 bufferevent_setcb(bev1
, readcb
, writecb
, errorcb
, NULL
);
136 bufferevent_setcb(bev2
, readcb
, writecb
, errorcb
, NULL
);
137 tt_int_op(bufferevent_getfd(bev1
), ==, -1);
138 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, NULL
);
139 tt_ptr_op(bufferevent_pair_get_partner(bev1
), ==, bev2
);
140 tt_ptr_op(bufferevent_pair_get_partner(bev2
), ==, bev1
);
142 bev1
= bufferevent_new(pair
[0], readcb
, writecb
, errorcb
, NULL
);
143 bev2
= bufferevent_new(pair
[1], readcb
, writecb
, errorcb
, NULL
);
144 tt_int_op(bufferevent_getfd(bev1
), ==, pair
[0]);
145 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, NULL
);
146 tt_ptr_op(bufferevent_pair_get_partner(bev1
), ==, NULL
);
147 tt_ptr_op(bufferevent_pair_get_partner(bev2
), ==, NULL
);
150 bufferevent_disable(bev1
, EV_READ
);
151 bufferevent_enable(bev2
, EV_READ
);
153 tt_int_op(bufferevent_get_enabled(bev1
), ==, EV_WRITE
);
154 tt_int_op(bufferevent_get_enabled(bev2
), ==, EV_WRITE
|EV_READ
);
156 for (i
= 0; i
< (int)sizeof(buffer
); i
++)
159 bufferevent_write(bev1
, buffer
, sizeof(buffer
));
163 bufferevent_free(bev1
);
164 tt_ptr_op(bufferevent_pair_get_partner(bev2
), ==, NULL
);
165 bufferevent_free(bev2
);
174 test_bufferevent(void)
176 test_bufferevent_impl(0);
180 test_bufferevent_pair(void)
182 test_bufferevent_impl(1);
186 * test watermarks and bufferevent
190 wm_readcb(struct bufferevent
*bev
, void *arg
)
192 struct evbuffer
*evbuf
= evbuffer_new();
193 int len
= (int)evbuffer_get_length(bev
->input
);
196 assert(len
>= 10 && len
<= 20);
198 assert(evbuf
!= NULL
);
200 /* gratuitous test of bufferevent_read_buffer */
201 bufferevent_read_buffer(bev
, evbuf
);
204 if (nread
== 65000) {
205 bufferevent_disable(bev
, EV_READ
);
209 evbuffer_free(evbuf
);
213 wm_writecb(struct bufferevent
*bev
, void *arg
)
215 assert(evbuffer_get_length(bev
->output
) <= 100);
216 if (evbuffer_get_length(bev
->output
) == 0) {
217 evbuffer_drain(bev
->output
, evbuffer_get_length(bev
->output
));
223 wm_errorcb(struct bufferevent
*bev
, short what
, void *arg
)
229 test_bufferevent_watermarks_impl(int use_pair
)
231 struct bufferevent
*bev1
= NULL
, *bev2
= NULL
;
237 struct bufferevent
*pair
[2];
238 tt_assert(0 == bufferevent_pair_new(NULL
, 0, pair
));
241 bufferevent_setcb(bev1
, NULL
, wm_writecb
, errorcb
, NULL
);
242 bufferevent_setcb(bev2
, wm_readcb
, NULL
, errorcb
, NULL
);
244 bev1
= bufferevent_new(pair
[0], NULL
, wm_writecb
, wm_errorcb
, NULL
);
245 bev2
= bufferevent_new(pair
[1], wm_readcb
, NULL
, wm_errorcb
, NULL
);
249 bufferevent_disable(bev1
, EV_READ
);
250 bufferevent_enable(bev2
, EV_READ
);
252 for (i
= 0; i
< (int)sizeof(buffer
); i
++)
255 /* limit the reading on the receiving bufferevent */
256 bufferevent_setwatermark(bev2
, EV_READ
, 10, 20);
258 /* Tell the sending bufferevent not to notify us till it's down to
260 bufferevent_setwatermark(bev1
, EV_WRITE
, 100, 2000);
262 bufferevent_write(bev1
, buffer
, sizeof(buffer
));
266 tt_int_op(test_ok
, ==, 2);
268 /* The write callback drained all the data from outbuf, so we
269 * should have removed the write event... */
270 tt_assert(!event_pending(&bev2
->ev_write
, EV_WRITE
, NULL
));
274 bufferevent_free(bev1
);
276 bufferevent_free(bev2
);
280 test_bufferevent_watermarks(void)
282 test_bufferevent_watermarks_impl(0);
286 test_bufferevent_pair_watermarks(void)
288 test_bufferevent_watermarks_impl(1);
292 * Test bufferevent filters
295 /* strip an 'x' from each byte */
297 static enum bufferevent_filter_result
298 bufferevent_input_filter(struct evbuffer
*src
, struct evbuffer
*dst
,
299 ev_ssize_t lim
, enum bufferevent_flush_mode state
, void *ctx
)
301 const unsigned char *buffer
;
304 buffer
= evbuffer_pullup(src
, evbuffer_get_length(src
));
305 for (i
= 0; i
< evbuffer_get_length(src
); i
+= 2) {
306 assert(buffer
[i
] == 'x');
307 evbuffer_add(dst
, buffer
+ i
+ 1, 1);
309 if (i
+ 2 > evbuffer_get_length(src
))
313 evbuffer_drain(src
, i
);
317 /* add an 'x' before each byte */
319 static enum bufferevent_filter_result
320 bufferevent_output_filter(struct evbuffer
*src
, struct evbuffer
*dst
,
321 ev_ssize_t lim
, enum bufferevent_flush_mode state
, void *ctx
)
323 const unsigned char *buffer
;
326 buffer
= evbuffer_pullup(src
, evbuffer_get_length(src
));
327 for (i
= 0; i
< evbuffer_get_length(src
); ++i
) {
328 evbuffer_add(dst
, "x", 1);
329 evbuffer_add(dst
, buffer
+ i
, 1);
332 evbuffer_drain(src
, evbuffer_get_length(src
));
337 test_bufferevent_filters_impl(int use_pair
)
339 struct bufferevent
*bev1
= NULL
, *bev2
= NULL
;
340 struct bufferevent
*bev1_base
= NULL
, *bev2_base
= NULL
;
347 struct bufferevent
*pair
[2];
348 tt_assert(0 == bufferevent_pair_new(NULL
, 0, pair
));
352 bev1
= bufferevent_socket_new(NULL
, pair
[0], 0);
353 bev2
= bufferevent_socket_new(NULL
, pair
[1], 0);
358 for (i
= 0; i
< (int)sizeof(buffer
); i
++)
361 bev1
= bufferevent_filter_new(bev1
, NULL
, bufferevent_output_filter
,
362 BEV_OPT_CLOSE_ON_FREE
, NULL
, NULL
);
364 bev2
= bufferevent_filter_new(bev2
, bufferevent_input_filter
,
365 NULL
, BEV_OPT_CLOSE_ON_FREE
, NULL
, NULL
);
366 bufferevent_setcb(bev1
, NULL
, writecb
, errorcb
, NULL
);
367 bufferevent_setcb(bev2
, readcb
, NULL
, errorcb
, NULL
);
369 tt_ptr_op(bufferevent_get_underlying(bev1
), ==, bev1_base
);
370 tt_ptr_op(bufferevent_get_underlying(bev2
), ==, bev2_base
);
371 tt_int_op(bufferevent_getfd(bev1
), ==, -1);
372 tt_int_op(bufferevent_getfd(bev2
), ==, -1);
374 bufferevent_disable(bev1
, EV_READ
);
375 bufferevent_enable(bev2
, EV_READ
);
376 /* insert some filters */
377 bufferevent_write(bev1
, buffer
, sizeof(buffer
));
386 bufferevent_free(bev1
);
388 bufferevent_free(bev2
);
393 test_bufferevent_filters(void)
395 test_bufferevent_filters_impl(0);
399 test_bufferevent_pair_filters(void)
401 test_bufferevent_filters_impl(1);
406 sender_writecb(struct bufferevent
*bev
, void *ctx
)
408 if (evbuffer_get_length(bufferevent_get_output(bev
)) == 0) {
409 bufferevent_disable(bev
,EV_READ
|EV_WRITE
);
410 bufferevent_free(bev
);
415 sender_errorcb(struct bufferevent
*bev
, short what
, void *ctx
)
417 TT_FAIL(("Got sender error %d",(int)what
));
420 static int bufferevent_connect_test_flags
= 0;
421 static int n_strings_read
= 0;
422 static int n_reads_invoked
= 0;
424 #define TEST_STR "Now is the time for all good events to signal for " \
425 "the good of their protocol"
427 listen_cb(struct evconnlistener
*listener
, evutil_socket_t fd
,
428 struct sockaddr
*sa
, int socklen
, void *arg
)
430 struct event_base
*base
= arg
;
431 struct bufferevent
*bev
;
432 const char s
[] = TEST_STR
;
433 TT_BLATHER(("Got a request on socket %d", (int)fd
));
434 bev
= bufferevent_socket_new(base
, fd
, bufferevent_connect_test_flags
);
436 bufferevent_setcb(bev
, NULL
, sender_writecb
, sender_errorcb
, NULL
);
437 bufferevent_write(bev
, s
, sizeof(s
));
443 reader_eventcb(struct bufferevent
*bev
, short what
, void *ctx
)
445 struct event_base
*base
= ctx
;
446 if (what
& BEV_EVENT_ERROR
) {
448 TT_FAIL(("got connector error %d", (int)what
));
451 if (what
& BEV_EVENT_CONNECTED
) {
452 bufferevent_enable(bev
, EV_READ
);
454 if (what
& BEV_EVENT_EOF
) {
457 n
= bufferevent_read(bev
, buf
, sizeof(buf
)-1);
459 tt_str_op(buf
, ==, TEST_STR
);
460 if (++n_strings_read
== 2)
461 event_base_loopexit(base
, NULL
);
468 reader_readcb(struct bufferevent
*bev
, void *ctx
)
474 test_bufferevent_connect(void *arg
)
476 struct basic_test_data
*data
= arg
;
477 struct evconnlistener
*lev
=NULL
;
478 struct bufferevent
*bev1
=NULL
, *bev2
=NULL
;
479 struct sockaddr_in localhost
;
480 struct sockaddr_storage ss
;
484 int be_flags
=BEV_OPT_CLOSE_ON_FREE
;
486 if (strstr((char*)data
->setup_data
, "defer")) {
487 be_flags
|= BEV_OPT_DEFER_CALLBACKS
;
489 if (strstr((char*)data
->setup_data
, "unlocked")) {
490 be_flags
|= BEV_OPT_UNLOCK_CALLBACKS
;
492 if (strstr((char*)data
->setup_data
, "lock")) {
493 be_flags
|= BEV_OPT_THREADSAFE
;
495 bufferevent_connect_test_flags
= be_flags
;
497 if (!strcmp((char*)data
->setup_data
, "unset_connectex")) {
498 struct win32_extension_fns
*ext
=
499 (struct win32_extension_fns
*)
500 event_get_win32_extension_fns();
501 ext
->ConnectEx
= NULL
;
505 memset(&localhost
, 0, sizeof(localhost
));
507 localhost
.sin_port
= 0; /* pick-a-port */
508 localhost
.sin_addr
.s_addr
= htonl(0x7f000001L
);
509 localhost
.sin_family
= AF_INET
;
510 sa
= (struct sockaddr
*)&localhost
;
511 lev
= evconnlistener_new_bind(data
->base
, listen_cb
, data
->base
,
512 LEV_OPT_CLOSE_ON_FREE
|LEV_OPT_REUSEABLE
,
513 16, sa
, sizeof(localhost
));
516 sa
= (struct sockaddr
*)&ss
;
518 if (regress_get_listener_addr(lev
, sa
, &slen
) < 0) {
519 tt_abort_perror("getsockname");
522 tt_assert(!evconnlistener_enable(lev
));
523 bev1
= bufferevent_socket_new(data
->base
, -1, be_flags
);
524 bev2
= bufferevent_socket_new(data
->base
, -1, be_flags
);
527 bufferevent_setcb(bev1
, reader_readcb
,NULL
, reader_eventcb
, data
->base
);
528 bufferevent_setcb(bev2
, reader_readcb
,NULL
, reader_eventcb
, data
->base
);
530 bufferevent_enable(bev1
, EV_READ
);
531 bufferevent_enable(bev2
, EV_READ
);
533 tt_want(!bufferevent_socket_connect(bev1
, sa
, sizeof(localhost
)));
534 tt_want(!bufferevent_socket_connect(bev2
, sa
, sizeof(localhost
)));
536 event_base_dispatch(data
->base
);
538 tt_int_op(n_strings_read
, ==, 2);
539 tt_int_op(n_reads_invoked
, >=, 2);
542 evconnlistener_free(lev
);
545 bufferevent_free(bev1
);
548 bufferevent_free(bev2
);
552 want_fail_eventcb(struct bufferevent
*bev
, short what
, void *ctx
)
554 struct event_base
*base
= ctx
;
558 if (what
& BEV_EVENT_ERROR
) {
559 s
= bufferevent_getfd(bev
);
560 err
= evutil_socket_error_to_string(evutil_socket_geterror(s
));
561 TT_BLATHER(("connection failure on "EV_SOCK_FMT
": %s",
562 EV_SOCK_ARG(s
), err
));
565 TT_FAIL(("didn't fail? what %hd", what
));
568 event_base_loopexit(base
, NULL
);
572 close_socket_cb(evutil_socket_t fd
, short what
, void *arg
)
574 evutil_socket_t
*fdp
= arg
;
576 evutil_closesocket(*fdp
);
582 test_bufferevent_connect_fail(void *arg
)
584 struct basic_test_data
*data
= arg
;
585 struct bufferevent
*bev
=NULL
;
586 struct sockaddr_in localhost
;
587 struct sockaddr
*sa
= (struct sockaddr
*)&localhost
;
588 evutil_socket_t fake_listener
= -1;
589 ev_socklen_t slen
= sizeof(localhost
);
590 struct event close_listener_event
;
591 int close_listener_event_added
= 0;
592 struct timeval one_second
= { 1, 0 };
597 memset(&localhost
, 0, sizeof(localhost
));
598 localhost
.sin_port
= 0; /* have the kernel pick a port */
599 localhost
.sin_addr
.s_addr
= htonl(0x7f000001L
);
600 localhost
.sin_family
= AF_INET
;
602 /* bind, but don't listen or accept. should trigger
603 "Connection refused" reliably on most platforms. */
604 fake_listener
= socket(localhost
.sin_family
, SOCK_STREAM
, 0);
605 tt_assert(fake_listener
>= 0);
606 tt_assert(bind(fake_listener
, sa
, slen
) == 0);
607 tt_assert(getsockname(fake_listener
, sa
, &slen
) == 0);
608 bev
= bufferevent_socket_new(data
->base
, -1,
609 BEV_OPT_CLOSE_ON_FREE
| BEV_OPT_DEFER_CALLBACKS
);
611 bufferevent_setcb(bev
, NULL
, NULL
, want_fail_eventcb
, data
->base
);
613 r
= bufferevent_socket_connect(bev
, sa
, slen
);
614 /* XXXX we'd like to test the '0' case everywhere, but FreeBSD tells
615 * detects the error immediately, which is not really wrong of it. */
616 tt_want(r
== 0 || r
== -1);
618 /* Close the listener socket after a second. This should trigger
619 "connection refused" on some other platforms, including OSX. */
620 evtimer_assign(&close_listener_event
, data
->base
, close_socket_cb
,
622 event_add(&close_listener_event
, &one_second
);
623 close_listener_event_added
= 1;
625 event_base_dispatch(data
->base
);
627 tt_int_op(test_ok
, ==, 1);
630 if (fake_listener
>= 0)
631 evutil_closesocket(fake_listener
);
634 bufferevent_free(bev
);
636 if (close_listener_event_added
)
637 event_del(&close_listener_event
);
640 struct timeout_cb_result
{
641 struct timeval read_timeout_at
;
642 struct timeval write_timeout_at
;
643 struct timeval last_wrote_at
;
645 int n_write_timeouts
;
650 bev_timeout_write_cb(struct bufferevent
*bev
, void *arg
)
652 struct timeout_cb_result
*res
= arg
;
653 evutil_gettimeofday(&res
->last_wrote_at
, NULL
);
657 bev_timeout_event_cb(struct bufferevent
*bev
, short what
, void *arg
)
659 struct timeout_cb_result
*res
= arg
;
662 if ((what
& (BEV_EVENT_READING
|BEV_EVENT_TIMEOUT
))
663 == (BEV_EVENT_READING
|BEV_EVENT_TIMEOUT
)) {
664 evutil_gettimeofday(&res
->read_timeout_at
, NULL
);
665 ++res
->n_read_timeouts
;
667 if ((what
& (BEV_EVENT_WRITING
|BEV_EVENT_TIMEOUT
))
668 == (BEV_EVENT_WRITING
|BEV_EVENT_TIMEOUT
)) {
669 evutil_gettimeofday(&res
->write_timeout_at
, NULL
);
670 ++res
->n_write_timeouts
;
675 test_bufferevent_timeouts(void *arg
)
677 /* "arg" is a string containing "pair" and/or "filter". */
678 struct bufferevent
*bev1
= NULL
, *bev2
= NULL
;
679 struct basic_test_data
*data
= arg
;
680 int use_pair
= 0, use_filter
= 0;
681 struct timeval tv_w
, tv_r
, started_at
;
682 struct timeout_cb_result res1
, res2
;
685 memset(&res1
, 0, sizeof(res1
));
686 memset(&res2
, 0, sizeof(res2
));
688 if (strstr((char*)data
->setup_data
, "pair"))
690 if (strstr((char*)data
->setup_data
, "filter"))
694 struct bufferevent
*p
[2];
695 tt_int_op(0, ==, bufferevent_pair_new(data
->base
, 0, p
));
699 bev1
= bufferevent_socket_new(data
->base
, data
->pair
[0], 0);
700 bev2
= bufferevent_socket_new(data
->base
, data
->pair
[1], 0);
707 struct bufferevent
*bevf1
, *bevf2
;
708 bevf1
= bufferevent_filter_new(bev1
, NULL
, NULL
,
709 BEV_OPT_CLOSE_ON_FREE
, NULL
, NULL
);
710 bevf2
= bufferevent_filter_new(bev2
, NULL
, NULL
,
711 BEV_OPT_CLOSE_ON_FREE
, NULL
, NULL
);
718 /* Do this nice and early. */
719 bufferevent_disable(bev2
, EV_READ
);
721 /* bev1 will try to write and read. Both will time out. */
722 evutil_gettimeofday(&started_at
, NULL
);
723 tv_w
.tv_sec
= tv_r
.tv_sec
= 0;
724 tv_w
.tv_usec
= 100*1000;
725 tv_r
.tv_usec
= 150*1000;
726 bufferevent_setcb(bev1
, NULL
, bev_timeout_write_cb
,
727 bev_timeout_event_cb
, &res1
);
728 bufferevent_setwatermark(bev1
, EV_WRITE
, 1024*1024+10, 0);
729 bufferevent_set_timeouts(bev1
, &tv_r
, &tv_w
);
731 /* For a pair, the fact that the other side isn't reading
732 * makes the writer stall */
733 bufferevent_write(bev1
, "ABCDEFG", 7);
735 /* For a real socket, the kernel's TCP buffers can eat a
736 * fair number of bytes; make sure that at some point we
737 * have some bytes that will stall. */
738 struct evbuffer
*output
= bufferevent_get_output(bev1
);
740 memset(buf
, 0xbb, sizeof(buf
));
741 for (i
=0;i
<1024;++i
) {
742 evbuffer_add_reference(output
, buf
, sizeof(buf
),
746 bufferevent_enable(bev1
, EV_READ
|EV_WRITE
);
748 /* bev2 has nothing to say, and isn't listening. */
749 bufferevent_setcb(bev2
, NULL
, bev_timeout_write_cb
,
750 bev_timeout_event_cb
, &res2
);
751 tv_w
.tv_sec
= tv_r
.tv_sec
= 0;
752 tv_w
.tv_usec
= 200*1000;
753 tv_r
.tv_usec
= 100*1000;
754 bufferevent_set_timeouts(bev2
, &tv_r
, &tv_w
);
755 bufferevent_enable(bev2
, EV_WRITE
);
760 event_base_loopexit(data
->base
, &tv_r
);
761 event_base_dispatch(data
->base
);
763 /* XXXX Test that actually reading or writing a little resets the
766 /* Each buf1 timeout happens, and happens only once. */
767 tt_want(res1
.n_read_timeouts
);
768 tt_want(res1
.n_write_timeouts
);
769 tt_want(res1
.n_read_timeouts
== 1);
770 tt_want(res1
.n_write_timeouts
== 1);
772 test_timeval_diff_eq(&started_at
, &res1
.read_timeout_at
, 150);
773 test_timeval_diff_eq(&started_at
, &res1
.write_timeout_at
, 100);
777 bufferevent_free(bev1
);
779 bufferevent_free(bev2
);
782 struct testcase_t bufferevent_testcases
[] = {
784 LEGACY(bufferevent
, TT_ISOLATED
),
785 LEGACY(bufferevent_pair
, TT_ISOLATED
),
786 LEGACY(bufferevent_watermarks
, TT_ISOLATED
),
787 LEGACY(bufferevent_pair_watermarks
, TT_ISOLATED
),
788 LEGACY(bufferevent_filters
, TT_ISOLATED
),
789 LEGACY(bufferevent_pair_filters
, TT_ISOLATED
),
790 { "bufferevent_connect", test_bufferevent_connect
, TT_FORK
|TT_NEED_BASE
,
791 &basic_setup
, (void*)"" },
792 { "bufferevent_connect_defer", test_bufferevent_connect
,
793 TT_FORK
|TT_NEED_BASE
, &basic_setup
, (void*)"defer" },
794 { "bufferevent_connect_lock", test_bufferevent_connect
,
795 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
, &basic_setup
, (void*)"lock" },
796 { "bufferevent_connect_lock_defer", test_bufferevent_connect
,
797 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
, &basic_setup
,
798 (void*)"defer lock" },
799 { "bufferevent_connect_unlocked_cbs", test_bufferevent_connect
,
800 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
, &basic_setup
,
801 (void*)"lock defer unlocked" },
802 { "bufferevent_connect_fail", test_bufferevent_connect_fail
,
803 TT_FORK
|TT_NEED_BASE
, &basic_setup
, NULL
},
804 { "bufferevent_timeout", test_bufferevent_timeouts
,
805 TT_FORK
|TT_NEED_BASE
|TT_NEED_SOCKETPAIR
, &basic_setup
, (void*)"" },
806 { "bufferevent_timeout_pair", test_bufferevent_timeouts
,
807 TT_FORK
|TT_NEED_BASE
, &basic_setup
, (void*)"pair" },
808 { "bufferevent_timeout_filter", test_bufferevent_timeouts
,
809 TT_FORK
|TT_NEED_BASE
, &basic_setup
, (void*)"filter" },
810 { "bufferevent_timeout_filter_pair", test_bufferevent_timeouts
,
811 TT_FORK
|TT_NEED_BASE
, &basic_setup
, (void*)"filter pair" },
812 #ifdef _EVENT_HAVE_LIBZ
813 LEGACY(bufferevent_zlib
, TT_ISOLATED
),
815 { "bufferevent_zlib", NULL
, TT_SKIP
, NULL
, NULL
},
821 struct testcase_t bufferevent_iocp_testcases
[] = {
823 LEGACY(bufferevent
, TT_ISOLATED
|TT_ENABLE_IOCP
),
824 LEGACY(bufferevent_watermarks
, TT_ISOLATED
|TT_ENABLE_IOCP
),
825 LEGACY(bufferevent_filters
, TT_ISOLATED
|TT_ENABLE_IOCP
),
826 { "bufferevent_connect", test_bufferevent_connect
,
827 TT_FORK
|TT_NEED_BASE
|TT_ENABLE_IOCP
, &basic_setup
, (void*)"" },
828 { "bufferevent_connect_defer", test_bufferevent_connect
,
829 TT_FORK
|TT_NEED_BASE
|TT_ENABLE_IOCP
, &basic_setup
, (void*)"defer" },
830 { "bufferevent_connect_lock", test_bufferevent_connect
,
831 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
|TT_ENABLE_IOCP
, &basic_setup
,
833 { "bufferevent_connect_lock_defer", test_bufferevent_connect
,
834 TT_FORK
|TT_NEED_BASE
|TT_NEED_THREADS
|TT_ENABLE_IOCP
, &basic_setup
,
835 (void*)"defer lock" },
836 { "bufferevent_connect_fail", test_bufferevent_connect_fail
,
837 TT_FORK
|TT_NEED_BASE
|TT_ENABLE_IOCP
, &basic_setup
, NULL
},
838 { "bufferevent_connect_nonblocking", test_bufferevent_connect
,
839 TT_FORK
|TT_NEED_BASE
|TT_ENABLE_IOCP
, &basic_setup
,
840 (void*)"unset_connectex" },