1*663afb9bSAndroid Build Coastguard Worker /*
2*663afb9bSAndroid Build Coastguard Worker * Copyright (c) 2003-2007 Niels Provos <[email protected]>
3*663afb9bSAndroid Build Coastguard Worker * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
4*663afb9bSAndroid Build Coastguard Worker *
5*663afb9bSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*663afb9bSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
7*663afb9bSAndroid Build Coastguard Worker * are met:
8*663afb9bSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
9*663afb9bSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
10*663afb9bSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
11*663afb9bSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
12*663afb9bSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
13*663afb9bSAndroid Build Coastguard Worker * 3. The name of the author may not be used to endorse or promote products
14*663afb9bSAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*663afb9bSAndroid Build Coastguard Worker *
16*663afb9bSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*663afb9bSAndroid Build Coastguard Worker * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*663afb9bSAndroid Build Coastguard Worker * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*663afb9bSAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*663afb9bSAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*663afb9bSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*663afb9bSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*663afb9bSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*663afb9bSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*663afb9bSAndroid Build Coastguard Worker * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*663afb9bSAndroid Build Coastguard Worker */
27*663afb9bSAndroid Build Coastguard Worker #include "util-internal.h"
28*663afb9bSAndroid Build Coastguard Worker
29*663afb9bSAndroid Build Coastguard Worker /* The old tests here need assertions to work. */
30*663afb9bSAndroid Build Coastguard Worker #undef NDEBUG
31*663afb9bSAndroid Build Coastguard Worker
32*663afb9bSAndroid Build Coastguard Worker /**
33*663afb9bSAndroid Build Coastguard Worker * - clang supports __has_feature
34*663afb9bSAndroid Build Coastguard Worker * - gcc supports __SANITIZE_ADDRESS__
35*663afb9bSAndroid Build Coastguard Worker *
36*663afb9bSAndroid Build Coastguard Worker * Let's set __SANITIZE_ADDRESS__ if __has_feature(address_sanitizer)
37*663afb9bSAndroid Build Coastguard Worker */
38*663afb9bSAndroid Build Coastguard Worker #ifndef __has_feature
39*663afb9bSAndroid Build Coastguard Worker #define __has_feature(x) 0
40*663afb9bSAndroid Build Coastguard Worker #endif
41*663afb9bSAndroid Build Coastguard Worker #if !defined(__SANITIZE_ADDRESS__) && __has_feature(address_sanitizer)
42*663afb9bSAndroid Build Coastguard Worker #define __SANITIZE_ADDRESS__
43*663afb9bSAndroid Build Coastguard Worker #endif
44*663afb9bSAndroid Build Coastguard Worker
45*663afb9bSAndroid Build Coastguard Worker #ifdef _WIN32
46*663afb9bSAndroid Build Coastguard Worker #include <winsock2.h>
47*663afb9bSAndroid Build Coastguard Worker #include <windows.h>
48*663afb9bSAndroid Build Coastguard Worker #endif
49*663afb9bSAndroid Build Coastguard Worker
50*663afb9bSAndroid Build Coastguard Worker #include "event2/event-config.h"
51*663afb9bSAndroid Build Coastguard Worker
52*663afb9bSAndroid Build Coastguard Worker #include <sys/types.h>
53*663afb9bSAndroid Build Coastguard Worker #include <sys/stat.h>
54*663afb9bSAndroid Build Coastguard Worker #ifdef EVENT__HAVE_SYS_TIME_H
55*663afb9bSAndroid Build Coastguard Worker #include <sys/time.h>
56*663afb9bSAndroid Build Coastguard Worker #endif
57*663afb9bSAndroid Build Coastguard Worker #include <sys/queue.h>
58*663afb9bSAndroid Build Coastguard Worker #ifndef _WIN32
59*663afb9bSAndroid Build Coastguard Worker #include <sys/socket.h>
60*663afb9bSAndroid Build Coastguard Worker #include <sys/wait.h>
61*663afb9bSAndroid Build Coastguard Worker #include <signal.h>
62*663afb9bSAndroid Build Coastguard Worker #include <unistd.h>
63*663afb9bSAndroid Build Coastguard Worker #include <netdb.h>
64*663afb9bSAndroid Build Coastguard Worker #include <netinet/in.h>
65*663afb9bSAndroid Build Coastguard Worker #endif
66*663afb9bSAndroid Build Coastguard Worker #include <fcntl.h>
67*663afb9bSAndroid Build Coastguard Worker #include <signal.h>
68*663afb9bSAndroid Build Coastguard Worker #include <stdlib.h>
69*663afb9bSAndroid Build Coastguard Worker #include <stdio.h>
70*663afb9bSAndroid Build Coastguard Worker #include <string.h>
71*663afb9bSAndroid Build Coastguard Worker #include <errno.h>
72*663afb9bSAndroid Build Coastguard Worker #include <assert.h>
73*663afb9bSAndroid Build Coastguard Worker
74*663afb9bSAndroid Build Coastguard Worker #ifdef EVENT__HAVE_ARPA_INET_H
75*663afb9bSAndroid Build Coastguard Worker #include <arpa/inet.h>
76*663afb9bSAndroid Build Coastguard Worker #endif
77*663afb9bSAndroid Build Coastguard Worker
78*663afb9bSAndroid Build Coastguard Worker #include "event2/event-config.h"
79*663afb9bSAndroid Build Coastguard Worker #include "event2/event.h"
80*663afb9bSAndroid Build Coastguard Worker #include "event2/event_struct.h"
81*663afb9bSAndroid Build Coastguard Worker #include "event2/event_compat.h"
82*663afb9bSAndroid Build Coastguard Worker #include "event2/tag.h"
83*663afb9bSAndroid Build Coastguard Worker #include "event2/buffer.h"
84*663afb9bSAndroid Build Coastguard Worker #include "event2/bufferevent.h"
85*663afb9bSAndroid Build Coastguard Worker #include "event2/bufferevent_compat.h"
86*663afb9bSAndroid Build Coastguard Worker #include "event2/bufferevent_struct.h"
87*663afb9bSAndroid Build Coastguard Worker #include "event2/listener.h"
88*663afb9bSAndroid Build Coastguard Worker #include "event2/util.h"
89*663afb9bSAndroid Build Coastguard Worker
90*663afb9bSAndroid Build Coastguard Worker #include "bufferevent-internal.h"
91*663afb9bSAndroid Build Coastguard Worker #include "evthread-internal.h"
92*663afb9bSAndroid Build Coastguard Worker #include "util-internal.h"
93*663afb9bSAndroid Build Coastguard Worker #ifdef _WIN32
94*663afb9bSAndroid Build Coastguard Worker #include "iocp-internal.h"
95*663afb9bSAndroid Build Coastguard Worker #endif
96*663afb9bSAndroid Build Coastguard Worker
97*663afb9bSAndroid Build Coastguard Worker #include "regress.h"
98*663afb9bSAndroid Build Coastguard Worker #include "regress_testutils.h"
99*663afb9bSAndroid Build Coastguard Worker
100*663afb9bSAndroid Build Coastguard Worker /*
101*663afb9bSAndroid Build Coastguard Worker * simple bufferevent test
102*663afb9bSAndroid Build Coastguard Worker */
103*663afb9bSAndroid Build Coastguard Worker
104*663afb9bSAndroid Build Coastguard Worker static void
readcb(struct bufferevent * bev,void * arg)105*663afb9bSAndroid Build Coastguard Worker readcb(struct bufferevent *bev, void *arg)
106*663afb9bSAndroid Build Coastguard Worker {
107*663afb9bSAndroid Build Coastguard Worker if (evbuffer_get_length(bev->input) == 8333) {
108*663afb9bSAndroid Build Coastguard Worker struct evbuffer *evbuf = evbuffer_new();
109*663afb9bSAndroid Build Coastguard Worker assert(evbuf != NULL);
110*663afb9bSAndroid Build Coastguard Worker
111*663afb9bSAndroid Build Coastguard Worker /* gratuitous test of bufferevent_read_buffer */
112*663afb9bSAndroid Build Coastguard Worker bufferevent_read_buffer(bev, evbuf);
113*663afb9bSAndroid Build Coastguard Worker
114*663afb9bSAndroid Build Coastguard Worker bufferevent_disable(bev, EV_READ);
115*663afb9bSAndroid Build Coastguard Worker
116*663afb9bSAndroid Build Coastguard Worker if (evbuffer_get_length(evbuf) == 8333) {
117*663afb9bSAndroid Build Coastguard Worker test_ok++;
118*663afb9bSAndroid Build Coastguard Worker }
119*663afb9bSAndroid Build Coastguard Worker
120*663afb9bSAndroid Build Coastguard Worker evbuffer_free(evbuf);
121*663afb9bSAndroid Build Coastguard Worker }
122*663afb9bSAndroid Build Coastguard Worker }
123*663afb9bSAndroid Build Coastguard Worker
124*663afb9bSAndroid Build Coastguard Worker static void
writecb(struct bufferevent * bev,void * arg)125*663afb9bSAndroid Build Coastguard Worker writecb(struct bufferevent *bev, void *arg)
126*663afb9bSAndroid Build Coastguard Worker {
127*663afb9bSAndroid Build Coastguard Worker if (evbuffer_get_length(bev->output) == 0) {
128*663afb9bSAndroid Build Coastguard Worker test_ok++;
129*663afb9bSAndroid Build Coastguard Worker }
130*663afb9bSAndroid Build Coastguard Worker }
131*663afb9bSAndroid Build Coastguard Worker
132*663afb9bSAndroid Build Coastguard Worker static void
errorcb(struct bufferevent * bev,short what,void * arg)133*663afb9bSAndroid Build Coastguard Worker errorcb(struct bufferevent *bev, short what, void *arg)
134*663afb9bSAndroid Build Coastguard Worker {
135*663afb9bSAndroid Build Coastguard Worker test_ok = -2;
136*663afb9bSAndroid Build Coastguard Worker }
137*663afb9bSAndroid Build Coastguard Worker
138*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_impl(int use_pair,int flush)139*663afb9bSAndroid Build Coastguard Worker test_bufferevent_impl(int use_pair, int flush)
140*663afb9bSAndroid Build Coastguard Worker {
141*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev1 = NULL, *bev2 = NULL;
142*663afb9bSAndroid Build Coastguard Worker char buffer[8333];
143*663afb9bSAndroid Build Coastguard Worker int i;
144*663afb9bSAndroid Build Coastguard Worker int expected = 2;
145*663afb9bSAndroid Build Coastguard Worker
146*663afb9bSAndroid Build Coastguard Worker if (use_pair) {
147*663afb9bSAndroid Build Coastguard Worker struct bufferevent *pair[2];
148*663afb9bSAndroid Build Coastguard Worker tt_assert(0 == bufferevent_pair_new(NULL, 0, pair));
149*663afb9bSAndroid Build Coastguard Worker bev1 = pair[0];
150*663afb9bSAndroid Build Coastguard Worker bev2 = pair[1];
151*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev1, readcb, writecb, errorcb, bev1);
152*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL);
153*663afb9bSAndroid Build Coastguard Worker tt_fd_op(bufferevent_getfd(bev1), ==, EVUTIL_INVALID_SOCKET);
154*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_get_underlying(bev1), ==, NULL);
155*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_pair_get_partner(bev1), ==, bev2);
156*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_pair_get_partner(bev2), ==, bev1);
157*663afb9bSAndroid Build Coastguard Worker } else {
158*663afb9bSAndroid Build Coastguard Worker bev1 = bufferevent_new(pair[0], readcb, writecb, errorcb, NULL);
159*663afb9bSAndroid Build Coastguard Worker bev2 = bufferevent_new(pair[1], readcb, writecb, errorcb, NULL);
160*663afb9bSAndroid Build Coastguard Worker tt_fd_op(bufferevent_getfd(bev1), ==, pair[0]);
161*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_get_underlying(bev1), ==, NULL);
162*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_pair_get_partner(bev1), ==, NULL);
163*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_pair_get_partner(bev2), ==, NULL);
164*663afb9bSAndroid Build Coastguard Worker }
165*663afb9bSAndroid Build Coastguard Worker
166*663afb9bSAndroid Build Coastguard Worker {
167*663afb9bSAndroid Build Coastguard Worker /* Test getcb. */
168*663afb9bSAndroid Build Coastguard Worker bufferevent_data_cb r, w;
169*663afb9bSAndroid Build Coastguard Worker bufferevent_event_cb e;
170*663afb9bSAndroid Build Coastguard Worker void *a;
171*663afb9bSAndroid Build Coastguard Worker bufferevent_getcb(bev1, &r, &w, &e, &a);
172*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(r, ==, readcb);
173*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(w, ==, writecb);
174*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(e, ==, errorcb);
175*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(a, ==, use_pair ? bev1 : NULL);
176*663afb9bSAndroid Build Coastguard Worker }
177*663afb9bSAndroid Build Coastguard Worker
178*663afb9bSAndroid Build Coastguard Worker bufferevent_disable(bev1, EV_READ);
179*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev2, EV_READ);
180*663afb9bSAndroid Build Coastguard Worker
181*663afb9bSAndroid Build Coastguard Worker tt_int_op(bufferevent_get_enabled(bev1), ==, EV_WRITE);
182*663afb9bSAndroid Build Coastguard Worker tt_int_op(bufferevent_get_enabled(bev2), ==, EV_WRITE|EV_READ);
183*663afb9bSAndroid Build Coastguard Worker
184*663afb9bSAndroid Build Coastguard Worker for (i = 0; i < (int)sizeof(buffer); i++)
185*663afb9bSAndroid Build Coastguard Worker buffer[i] = i;
186*663afb9bSAndroid Build Coastguard Worker
187*663afb9bSAndroid Build Coastguard Worker bufferevent_write(bev1, buffer, sizeof(buffer));
188*663afb9bSAndroid Build Coastguard Worker if (flush >= 0) {
189*663afb9bSAndroid Build Coastguard Worker tt_int_op(bufferevent_flush(bev1, EV_WRITE, flush), >=, 0);
190*663afb9bSAndroid Build Coastguard Worker }
191*663afb9bSAndroid Build Coastguard Worker
192*663afb9bSAndroid Build Coastguard Worker event_dispatch();
193*663afb9bSAndroid Build Coastguard Worker
194*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev2);
195*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_pair_get_partner(bev1), ==, NULL);
196*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev1);
197*663afb9bSAndroid Build Coastguard Worker
198*663afb9bSAndroid Build Coastguard Worker /** Only pair call errorcb for BEV_FINISHED */
199*663afb9bSAndroid Build Coastguard Worker if (use_pair && flush == BEV_FINISHED) {
200*663afb9bSAndroid Build Coastguard Worker expected = -1;
201*663afb9bSAndroid Build Coastguard Worker }
202*663afb9bSAndroid Build Coastguard Worker if (test_ok != expected)
203*663afb9bSAndroid Build Coastguard Worker test_ok = 0;
204*663afb9bSAndroid Build Coastguard Worker end:
205*663afb9bSAndroid Build Coastguard Worker ;
206*663afb9bSAndroid Build Coastguard Worker }
207*663afb9bSAndroid Build Coastguard Worker
test_bufferevent(void)208*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent(void) { test_bufferevent_impl(0, -1); }
test_bufferevent_pair(void)209*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_pair(void) { test_bufferevent_impl(1, -1); }
210*663afb9bSAndroid Build Coastguard Worker
test_bufferevent_flush_normal(void)211*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_flush_normal(void) { test_bufferevent_impl(0, BEV_NORMAL); }
test_bufferevent_flush_flush(void)212*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_flush_flush(void) { test_bufferevent_impl(0, BEV_FLUSH); }
test_bufferevent_flush_finished(void)213*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_flush_finished(void) { test_bufferevent_impl(0, BEV_FINISHED); }
214*663afb9bSAndroid Build Coastguard Worker
test_bufferevent_pair_flush_normal(void)215*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_pair_flush_normal(void) { test_bufferevent_impl(1, BEV_NORMAL); }
test_bufferevent_pair_flush_flush(void)216*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_pair_flush_flush(void) { test_bufferevent_impl(1, BEV_FLUSH); }
test_bufferevent_pair_flush_finished(void)217*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_pair_flush_finished(void) { test_bufferevent_impl(1, BEV_FINISHED); }
218*663afb9bSAndroid Build Coastguard Worker
219*663afb9bSAndroid Build Coastguard Worker #if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED) && !defined(__SANITIZE_ADDRESS__)
220*663afb9bSAndroid Build Coastguard Worker /**
221*663afb9bSAndroid Build Coastguard Worker * Trace lock/unlock/alloc/free for locks.
222*663afb9bSAndroid Build Coastguard Worker * (More heavier then evthread_debug*)
223*663afb9bSAndroid Build Coastguard Worker */
224*663afb9bSAndroid Build Coastguard Worker typedef struct
225*663afb9bSAndroid Build Coastguard Worker {
226*663afb9bSAndroid Build Coastguard Worker void *lock;
227*663afb9bSAndroid Build Coastguard Worker enum {
228*663afb9bSAndroid Build Coastguard Worker ALLOC, FREE,
229*663afb9bSAndroid Build Coastguard Worker } status;
230*663afb9bSAndroid Build Coastguard Worker size_t locked /** allow recursive locking */;
231*663afb9bSAndroid Build Coastguard Worker } lock_wrapper;
232*663afb9bSAndroid Build Coastguard Worker struct lock_unlock_base
233*663afb9bSAndroid Build Coastguard Worker {
234*663afb9bSAndroid Build Coastguard Worker /* Original callbacks */
235*663afb9bSAndroid Build Coastguard Worker struct evthread_lock_callbacks cbs;
236*663afb9bSAndroid Build Coastguard Worker /* Map of locks */
237*663afb9bSAndroid Build Coastguard Worker lock_wrapper *locks;
238*663afb9bSAndroid Build Coastguard Worker size_t nr_locks;
239*663afb9bSAndroid Build Coastguard Worker } lu_base = {
240*663afb9bSAndroid Build Coastguard Worker .locks = NULL,
241*663afb9bSAndroid Build Coastguard Worker };
242*663afb9bSAndroid Build Coastguard Worker
lu_find(void * lock_)243*663afb9bSAndroid Build Coastguard Worker static lock_wrapper *lu_find(void *lock_)
244*663afb9bSAndroid Build Coastguard Worker {
245*663afb9bSAndroid Build Coastguard Worker size_t i;
246*663afb9bSAndroid Build Coastguard Worker for (i = 0; i < lu_base.nr_locks; ++i) {
247*663afb9bSAndroid Build Coastguard Worker lock_wrapper *lock = &lu_base.locks[i];
248*663afb9bSAndroid Build Coastguard Worker if (lock->lock == lock_)
249*663afb9bSAndroid Build Coastguard Worker return lock;
250*663afb9bSAndroid Build Coastguard Worker }
251*663afb9bSAndroid Build Coastguard Worker return NULL;
252*663afb9bSAndroid Build Coastguard Worker }
253*663afb9bSAndroid Build Coastguard Worker
trace_lock_alloc(unsigned locktype)254*663afb9bSAndroid Build Coastguard Worker static void *trace_lock_alloc(unsigned locktype)
255*663afb9bSAndroid Build Coastguard Worker {
256*663afb9bSAndroid Build Coastguard Worker void *lock;
257*663afb9bSAndroid Build Coastguard Worker ++lu_base.nr_locks;
258*663afb9bSAndroid Build Coastguard Worker lu_base.locks = realloc(lu_base.locks,
259*663afb9bSAndroid Build Coastguard Worker sizeof(lock_wrapper) * lu_base.nr_locks);
260*663afb9bSAndroid Build Coastguard Worker lock = lu_base.cbs.alloc(locktype);
261*663afb9bSAndroid Build Coastguard Worker lu_base.locks[lu_base.nr_locks - 1] = (lock_wrapper){ lock, ALLOC, 0 };
262*663afb9bSAndroid Build Coastguard Worker return lock;
263*663afb9bSAndroid Build Coastguard Worker }
trace_lock_free(void * lock_,unsigned locktype)264*663afb9bSAndroid Build Coastguard Worker static void trace_lock_free(void *lock_, unsigned locktype)
265*663afb9bSAndroid Build Coastguard Worker {
266*663afb9bSAndroid Build Coastguard Worker lock_wrapper *lock = lu_find(lock_);
267*663afb9bSAndroid Build Coastguard Worker if (!lock || lock->status == FREE || lock->locked) {
268*663afb9bSAndroid Build Coastguard Worker TT_FAIL(("lock: free error"));
269*663afb9bSAndroid Build Coastguard Worker } else {
270*663afb9bSAndroid Build Coastguard Worker lock->status = FREE;
271*663afb9bSAndroid Build Coastguard Worker lu_base.cbs.free(lock_, locktype);
272*663afb9bSAndroid Build Coastguard Worker }
273*663afb9bSAndroid Build Coastguard Worker }
trace_lock_lock(unsigned mode,void * lock_)274*663afb9bSAndroid Build Coastguard Worker static int trace_lock_lock(unsigned mode, void *lock_)
275*663afb9bSAndroid Build Coastguard Worker {
276*663afb9bSAndroid Build Coastguard Worker lock_wrapper *lock = lu_find(lock_);
277*663afb9bSAndroid Build Coastguard Worker if (!lock || lock->status == FREE) {
278*663afb9bSAndroid Build Coastguard Worker TT_FAIL(("lock: lock error"));
279*663afb9bSAndroid Build Coastguard Worker return -1;
280*663afb9bSAndroid Build Coastguard Worker } else {
281*663afb9bSAndroid Build Coastguard Worker ++lock->locked;
282*663afb9bSAndroid Build Coastguard Worker return lu_base.cbs.lock(mode, lock_);
283*663afb9bSAndroid Build Coastguard Worker }
284*663afb9bSAndroid Build Coastguard Worker }
trace_lock_unlock(unsigned mode,void * lock_)285*663afb9bSAndroid Build Coastguard Worker static int trace_lock_unlock(unsigned mode, void *lock_)
286*663afb9bSAndroid Build Coastguard Worker {
287*663afb9bSAndroid Build Coastguard Worker lock_wrapper *lock = lu_find(lock_);
288*663afb9bSAndroid Build Coastguard Worker if (!lock || lock->status == FREE || !lock->locked) {
289*663afb9bSAndroid Build Coastguard Worker TT_FAIL(("lock: unlock error"));
290*663afb9bSAndroid Build Coastguard Worker return -1;
291*663afb9bSAndroid Build Coastguard Worker } else {
292*663afb9bSAndroid Build Coastguard Worker --lock->locked;
293*663afb9bSAndroid Build Coastguard Worker return lu_base.cbs.unlock(mode, lock_);
294*663afb9bSAndroid Build Coastguard Worker }
295*663afb9bSAndroid Build Coastguard Worker }
lock_unlock_free_thread_cbs(void)296*663afb9bSAndroid Build Coastguard Worker static void lock_unlock_free_thread_cbs(void)
297*663afb9bSAndroid Build Coastguard Worker {
298*663afb9bSAndroid Build Coastguard Worker event_base_free(NULL);
299*663afb9bSAndroid Build Coastguard Worker
300*663afb9bSAndroid Build Coastguard Worker if (libevent_tests_running_in_debug_mode)
301*663afb9bSAndroid Build Coastguard Worker libevent_global_shutdown();
302*663afb9bSAndroid Build Coastguard Worker
303*663afb9bSAndroid Build Coastguard Worker /** drop immutable flag */
304*663afb9bSAndroid Build Coastguard Worker evthread_set_lock_callbacks(NULL);
305*663afb9bSAndroid Build Coastguard Worker /** avoid calling of event_global_setup_locks_() for new cbs */
306*663afb9bSAndroid Build Coastguard Worker libevent_global_shutdown();
307*663afb9bSAndroid Build Coastguard Worker /** drop immutable flag for non-debug ops (since called after shutdown) */
308*663afb9bSAndroid Build Coastguard Worker evthread_set_lock_callbacks(NULL);
309*663afb9bSAndroid Build Coastguard Worker }
310*663afb9bSAndroid Build Coastguard Worker
use_lock_unlock_profiler(void)311*663afb9bSAndroid Build Coastguard Worker static int use_lock_unlock_profiler(void)
312*663afb9bSAndroid Build Coastguard Worker {
313*663afb9bSAndroid Build Coastguard Worker struct evthread_lock_callbacks cbs = {
314*663afb9bSAndroid Build Coastguard Worker EVTHREAD_LOCK_API_VERSION,
315*663afb9bSAndroid Build Coastguard Worker EVTHREAD_LOCKTYPE_RECURSIVE,
316*663afb9bSAndroid Build Coastguard Worker trace_lock_alloc,
317*663afb9bSAndroid Build Coastguard Worker trace_lock_free,
318*663afb9bSAndroid Build Coastguard Worker trace_lock_lock,
319*663afb9bSAndroid Build Coastguard Worker trace_lock_unlock,
320*663afb9bSAndroid Build Coastguard Worker };
321*663afb9bSAndroid Build Coastguard Worker memcpy(&lu_base.cbs, evthread_get_lock_callbacks(),
322*663afb9bSAndroid Build Coastguard Worker sizeof(lu_base.cbs));
323*663afb9bSAndroid Build Coastguard Worker {
324*663afb9bSAndroid Build Coastguard Worker lock_unlock_free_thread_cbs();
325*663afb9bSAndroid Build Coastguard Worker
326*663afb9bSAndroid Build Coastguard Worker evthread_set_lock_callbacks(&cbs);
327*663afb9bSAndroid Build Coastguard Worker /** re-create debug locks correctly */
328*663afb9bSAndroid Build Coastguard Worker evthread_enable_lock_debugging();
329*663afb9bSAndroid Build Coastguard Worker
330*663afb9bSAndroid Build Coastguard Worker event_init();
331*663afb9bSAndroid Build Coastguard Worker }
332*663afb9bSAndroid Build Coastguard Worker return 0;
333*663afb9bSAndroid Build Coastguard Worker }
free_lock_unlock_profiler(struct basic_test_data * data)334*663afb9bSAndroid Build Coastguard Worker static void free_lock_unlock_profiler(struct basic_test_data *data)
335*663afb9bSAndroid Build Coastguard Worker {
336*663afb9bSAndroid Build Coastguard Worker /** fix "held_by" for kqueue */
337*663afb9bSAndroid Build Coastguard Worker evthread_set_lock_callbacks(NULL);
338*663afb9bSAndroid Build Coastguard Worker
339*663afb9bSAndroid Build Coastguard Worker lock_unlock_free_thread_cbs();
340*663afb9bSAndroid Build Coastguard Worker free(lu_base.locks);
341*663afb9bSAndroid Build Coastguard Worker data->base = NULL;
342*663afb9bSAndroid Build Coastguard Worker }
343*663afb9bSAndroid Build Coastguard Worker
test_bufferevent_pair_release_lock(void * arg)344*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_pair_release_lock(void *arg)
345*663afb9bSAndroid Build Coastguard Worker {
346*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = arg;
347*663afb9bSAndroid Build Coastguard Worker use_lock_unlock_profiler();
348*663afb9bSAndroid Build Coastguard Worker {
349*663afb9bSAndroid Build Coastguard Worker struct bufferevent *pair[2];
350*663afb9bSAndroid Build Coastguard Worker if (!bufferevent_pair_new(NULL, BEV_OPT_THREADSAFE, pair)) {
351*663afb9bSAndroid Build Coastguard Worker bufferevent_free(pair[0]);
352*663afb9bSAndroid Build Coastguard Worker bufferevent_free(pair[1]);
353*663afb9bSAndroid Build Coastguard Worker } else
354*663afb9bSAndroid Build Coastguard Worker tt_abort_perror("bufferevent_pair_new");
355*663afb9bSAndroid Build Coastguard Worker }
356*663afb9bSAndroid Build Coastguard Worker free_lock_unlock_profiler(data);
357*663afb9bSAndroid Build Coastguard Worker end:
358*663afb9bSAndroid Build Coastguard Worker ;
359*663afb9bSAndroid Build Coastguard Worker }
360*663afb9bSAndroid Build Coastguard Worker #endif
361*663afb9bSAndroid Build Coastguard Worker
362*663afb9bSAndroid Build Coastguard Worker /*
363*663afb9bSAndroid Build Coastguard Worker * test watermarks and bufferevent
364*663afb9bSAndroid Build Coastguard Worker */
365*663afb9bSAndroid Build Coastguard Worker
366*663afb9bSAndroid Build Coastguard Worker static void
wm_readcb(struct bufferevent * bev,void * arg)367*663afb9bSAndroid Build Coastguard Worker wm_readcb(struct bufferevent *bev, void *arg)
368*663afb9bSAndroid Build Coastguard Worker {
369*663afb9bSAndroid Build Coastguard Worker struct evbuffer *evbuf = evbuffer_new();
370*663afb9bSAndroid Build Coastguard Worker int len = (int)evbuffer_get_length(bev->input);
371*663afb9bSAndroid Build Coastguard Worker static int nread;
372*663afb9bSAndroid Build Coastguard Worker
373*663afb9bSAndroid Build Coastguard Worker assert(len >= 10 && len <= 20);
374*663afb9bSAndroid Build Coastguard Worker
375*663afb9bSAndroid Build Coastguard Worker assert(evbuf != NULL);
376*663afb9bSAndroid Build Coastguard Worker
377*663afb9bSAndroid Build Coastguard Worker /* gratuitous test of bufferevent_read_buffer */
378*663afb9bSAndroid Build Coastguard Worker bufferevent_read_buffer(bev, evbuf);
379*663afb9bSAndroid Build Coastguard Worker
380*663afb9bSAndroid Build Coastguard Worker nread += len;
381*663afb9bSAndroid Build Coastguard Worker if (nread == 65000) {
382*663afb9bSAndroid Build Coastguard Worker bufferevent_disable(bev, EV_READ);
383*663afb9bSAndroid Build Coastguard Worker test_ok++;
384*663afb9bSAndroid Build Coastguard Worker }
385*663afb9bSAndroid Build Coastguard Worker
386*663afb9bSAndroid Build Coastguard Worker evbuffer_free(evbuf);
387*663afb9bSAndroid Build Coastguard Worker }
388*663afb9bSAndroid Build Coastguard Worker
389*663afb9bSAndroid Build Coastguard Worker static void
wm_writecb(struct bufferevent * bev,void * arg)390*663afb9bSAndroid Build Coastguard Worker wm_writecb(struct bufferevent *bev, void *arg)
391*663afb9bSAndroid Build Coastguard Worker {
392*663afb9bSAndroid Build Coastguard Worker assert(evbuffer_get_length(bev->output) <= 100);
393*663afb9bSAndroid Build Coastguard Worker if (evbuffer_get_length(bev->output) == 0) {
394*663afb9bSAndroid Build Coastguard Worker evbuffer_drain(bev->output, evbuffer_get_length(bev->output));
395*663afb9bSAndroid Build Coastguard Worker test_ok++;
396*663afb9bSAndroid Build Coastguard Worker }
397*663afb9bSAndroid Build Coastguard Worker }
398*663afb9bSAndroid Build Coastguard Worker
399*663afb9bSAndroid Build Coastguard Worker static void
wm_errorcb(struct bufferevent * bev,short what,void * arg)400*663afb9bSAndroid Build Coastguard Worker wm_errorcb(struct bufferevent *bev, short what, void *arg)
401*663afb9bSAndroid Build Coastguard Worker {
402*663afb9bSAndroid Build Coastguard Worker test_ok = -2;
403*663afb9bSAndroid Build Coastguard Worker }
404*663afb9bSAndroid Build Coastguard Worker
405*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_watermarks_impl(int use_pair)406*663afb9bSAndroid Build Coastguard Worker test_bufferevent_watermarks_impl(int use_pair)
407*663afb9bSAndroid Build Coastguard Worker {
408*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev1 = NULL, *bev2 = NULL;
409*663afb9bSAndroid Build Coastguard Worker char buffer[65000];
410*663afb9bSAndroid Build Coastguard Worker size_t low, high;
411*663afb9bSAndroid Build Coastguard Worker int i;
412*663afb9bSAndroid Build Coastguard Worker test_ok = 0;
413*663afb9bSAndroid Build Coastguard Worker
414*663afb9bSAndroid Build Coastguard Worker if (use_pair) {
415*663afb9bSAndroid Build Coastguard Worker struct bufferevent *pair[2];
416*663afb9bSAndroid Build Coastguard Worker tt_assert(0 == bufferevent_pair_new(NULL, 0, pair));
417*663afb9bSAndroid Build Coastguard Worker bev1 = pair[0];
418*663afb9bSAndroid Build Coastguard Worker bev2 = pair[1];
419*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev1, NULL, wm_writecb, errorcb, NULL);
420*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev2, wm_readcb, NULL, errorcb, NULL);
421*663afb9bSAndroid Build Coastguard Worker } else {
422*663afb9bSAndroid Build Coastguard Worker bev1 = bufferevent_new(pair[0], NULL, wm_writecb, wm_errorcb, NULL);
423*663afb9bSAndroid Build Coastguard Worker bev2 = bufferevent_new(pair[1], wm_readcb, NULL, wm_errorcb, NULL);
424*663afb9bSAndroid Build Coastguard Worker }
425*663afb9bSAndroid Build Coastguard Worker tt_assert(bev1);
426*663afb9bSAndroid Build Coastguard Worker tt_assert(bev2);
427*663afb9bSAndroid Build Coastguard Worker bufferevent_disable(bev1, EV_READ);
428*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev2, EV_READ);
429*663afb9bSAndroid Build Coastguard Worker
430*663afb9bSAndroid Build Coastguard Worker /* By default, low watermarks are set to 0 */
431*663afb9bSAndroid Build Coastguard Worker bufferevent_getwatermark(bev1, EV_READ, &low, NULL);
432*663afb9bSAndroid Build Coastguard Worker tt_int_op(low, ==, 0);
433*663afb9bSAndroid Build Coastguard Worker bufferevent_getwatermark(bev2, EV_WRITE, &low, NULL);
434*663afb9bSAndroid Build Coastguard Worker tt_int_op(low, ==, 0);
435*663afb9bSAndroid Build Coastguard Worker
436*663afb9bSAndroid Build Coastguard Worker for (i = 0; i < (int)sizeof(buffer); i++)
437*663afb9bSAndroid Build Coastguard Worker buffer[i] = (char)i;
438*663afb9bSAndroid Build Coastguard Worker
439*663afb9bSAndroid Build Coastguard Worker /* limit the reading on the receiving bufferevent */
440*663afb9bSAndroid Build Coastguard Worker bufferevent_setwatermark(bev2, EV_READ, 10, 20);
441*663afb9bSAndroid Build Coastguard Worker
442*663afb9bSAndroid Build Coastguard Worker bufferevent_getwatermark(bev2, EV_READ, &low, &high);
443*663afb9bSAndroid Build Coastguard Worker tt_int_op(low, ==, 10);
444*663afb9bSAndroid Build Coastguard Worker tt_int_op(high, ==, 20);
445*663afb9bSAndroid Build Coastguard Worker
446*663afb9bSAndroid Build Coastguard Worker /* Tell the sending bufferevent not to notify us till it's down to
447*663afb9bSAndroid Build Coastguard Worker 100 bytes. */
448*663afb9bSAndroid Build Coastguard Worker bufferevent_setwatermark(bev1, EV_WRITE, 100, 2000);
449*663afb9bSAndroid Build Coastguard Worker
450*663afb9bSAndroid Build Coastguard Worker bufferevent_getwatermark(bev1, EV_WRITE, &low, &high);
451*663afb9bSAndroid Build Coastguard Worker tt_int_op(low, ==, 100);
452*663afb9bSAndroid Build Coastguard Worker tt_int_op(high, ==, 2000);
453*663afb9bSAndroid Build Coastguard Worker
454*663afb9bSAndroid Build Coastguard Worker {
455*663afb9bSAndroid Build Coastguard Worker int r = bufferevent_getwatermark(bev1, EV_WRITE | EV_READ, &low, &high);
456*663afb9bSAndroid Build Coastguard Worker tt_int_op(r, !=, 0);
457*663afb9bSAndroid Build Coastguard Worker }
458*663afb9bSAndroid Build Coastguard Worker
459*663afb9bSAndroid Build Coastguard Worker bufferevent_write(bev1, buffer, sizeof(buffer));
460*663afb9bSAndroid Build Coastguard Worker
461*663afb9bSAndroid Build Coastguard Worker event_dispatch();
462*663afb9bSAndroid Build Coastguard Worker
463*663afb9bSAndroid Build Coastguard Worker tt_int_op(test_ok, ==, 2);
464*663afb9bSAndroid Build Coastguard Worker
465*663afb9bSAndroid Build Coastguard Worker /* The write callback drained all the data from outbuf, so we
466*663afb9bSAndroid Build Coastguard Worker * should have removed the write event... */
467*663afb9bSAndroid Build Coastguard Worker tt_assert(!event_pending(&bev2->ev_write, EV_WRITE, NULL));
468*663afb9bSAndroid Build Coastguard Worker
469*663afb9bSAndroid Build Coastguard Worker end:
470*663afb9bSAndroid Build Coastguard Worker if (bev1)
471*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev1);
472*663afb9bSAndroid Build Coastguard Worker if (bev2)
473*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev2);
474*663afb9bSAndroid Build Coastguard Worker }
475*663afb9bSAndroid Build Coastguard Worker
476*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_watermarks(void)477*663afb9bSAndroid Build Coastguard Worker test_bufferevent_watermarks(void)
478*663afb9bSAndroid Build Coastguard Worker {
479*663afb9bSAndroid Build Coastguard Worker test_bufferevent_watermarks_impl(0);
480*663afb9bSAndroid Build Coastguard Worker }
481*663afb9bSAndroid Build Coastguard Worker
482*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_pair_watermarks(void)483*663afb9bSAndroid Build Coastguard Worker test_bufferevent_pair_watermarks(void)
484*663afb9bSAndroid Build Coastguard Worker {
485*663afb9bSAndroid Build Coastguard Worker test_bufferevent_watermarks_impl(1);
486*663afb9bSAndroid Build Coastguard Worker }
487*663afb9bSAndroid Build Coastguard Worker
488*663afb9bSAndroid Build Coastguard Worker /*
489*663afb9bSAndroid Build Coastguard Worker * Test bufferevent filters
490*663afb9bSAndroid Build Coastguard Worker */
491*663afb9bSAndroid Build Coastguard Worker
492*663afb9bSAndroid Build Coastguard Worker /* strip an 'x' from each byte */
493*663afb9bSAndroid Build Coastguard Worker
494*663afb9bSAndroid Build Coastguard Worker static enum bufferevent_filter_result
bufferevent_input_filter(struct evbuffer * src,struct evbuffer * dst,ev_ssize_t lim,enum bufferevent_flush_mode state,void * ctx)495*663afb9bSAndroid Build Coastguard Worker bufferevent_input_filter(struct evbuffer *src, struct evbuffer *dst,
496*663afb9bSAndroid Build Coastguard Worker ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
497*663afb9bSAndroid Build Coastguard Worker {
498*663afb9bSAndroid Build Coastguard Worker const unsigned char *buffer;
499*663afb9bSAndroid Build Coastguard Worker unsigned i;
500*663afb9bSAndroid Build Coastguard Worker
501*663afb9bSAndroid Build Coastguard Worker buffer = evbuffer_pullup(src, evbuffer_get_length(src));
502*663afb9bSAndroid Build Coastguard Worker for (i = 0; i < evbuffer_get_length(src); i += 2) {
503*663afb9bSAndroid Build Coastguard Worker if (buffer[i] == '-')
504*663afb9bSAndroid Build Coastguard Worker continue;
505*663afb9bSAndroid Build Coastguard Worker
506*663afb9bSAndroid Build Coastguard Worker assert(buffer[i] == 'x');
507*663afb9bSAndroid Build Coastguard Worker evbuffer_add(dst, buffer + i + 1, 1);
508*663afb9bSAndroid Build Coastguard Worker }
509*663afb9bSAndroid Build Coastguard Worker
510*663afb9bSAndroid Build Coastguard Worker evbuffer_drain(src, i);
511*663afb9bSAndroid Build Coastguard Worker return (BEV_OK);
512*663afb9bSAndroid Build Coastguard Worker }
513*663afb9bSAndroid Build Coastguard Worker
514*663afb9bSAndroid Build Coastguard Worker /* add an 'x' before each byte */
515*663afb9bSAndroid Build Coastguard Worker
516*663afb9bSAndroid Build Coastguard Worker static enum bufferevent_filter_result
bufferevent_output_filter(struct evbuffer * src,struct evbuffer * dst,ev_ssize_t lim,enum bufferevent_flush_mode state,void * ctx)517*663afb9bSAndroid Build Coastguard Worker bufferevent_output_filter(struct evbuffer *src, struct evbuffer *dst,
518*663afb9bSAndroid Build Coastguard Worker ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
519*663afb9bSAndroid Build Coastguard Worker {
520*663afb9bSAndroid Build Coastguard Worker const unsigned char *buffer;
521*663afb9bSAndroid Build Coastguard Worker unsigned i;
522*663afb9bSAndroid Build Coastguard Worker struct bufferevent **bevp = ctx;
523*663afb9bSAndroid Build Coastguard Worker
524*663afb9bSAndroid Build Coastguard Worker ++test_ok;
525*663afb9bSAndroid Build Coastguard Worker
526*663afb9bSAndroid Build Coastguard Worker if (test_ok == 1) {
527*663afb9bSAndroid Build Coastguard Worker buffer = evbuffer_pullup(src, evbuffer_get_length(src));
528*663afb9bSAndroid Build Coastguard Worker for (i = 0; i < evbuffer_get_length(src); ++i) {
529*663afb9bSAndroid Build Coastguard Worker evbuffer_add(dst, "x", 1);
530*663afb9bSAndroid Build Coastguard Worker evbuffer_add(dst, buffer + i, 1);
531*663afb9bSAndroid Build Coastguard Worker }
532*663afb9bSAndroid Build Coastguard Worker evbuffer_drain(src, evbuffer_get_length(src));
533*663afb9bSAndroid Build Coastguard Worker } else {
534*663afb9bSAndroid Build Coastguard Worker return BEV_ERROR;
535*663afb9bSAndroid Build Coastguard Worker }
536*663afb9bSAndroid Build Coastguard Worker
537*663afb9bSAndroid Build Coastguard Worker if (bevp && test_ok == 1) {
538*663afb9bSAndroid Build Coastguard Worker int prev = ++test_ok;
539*663afb9bSAndroid Build Coastguard Worker bufferevent_write(*bevp, "-", 1);
540*663afb9bSAndroid Build Coastguard Worker /* check that during this bufferevent_write()
541*663afb9bSAndroid Build Coastguard Worker * bufferevent_output_filter() will not be called again */
542*663afb9bSAndroid Build Coastguard Worker assert(test_ok == prev);
543*663afb9bSAndroid Build Coastguard Worker --test_ok;
544*663afb9bSAndroid Build Coastguard Worker }
545*663afb9bSAndroid Build Coastguard Worker
546*663afb9bSAndroid Build Coastguard Worker return (BEV_OK);
547*663afb9bSAndroid Build Coastguard Worker }
548*663afb9bSAndroid Build Coastguard Worker
549*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_filters_impl(int use_pair,int disable)550*663afb9bSAndroid Build Coastguard Worker test_bufferevent_filters_impl(int use_pair, int disable)
551*663afb9bSAndroid Build Coastguard Worker {
552*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev1 = NULL, *bev2 = NULL;
553*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev1_base = NULL, *bev2_base = NULL;
554*663afb9bSAndroid Build Coastguard Worker char buffer[8333];
555*663afb9bSAndroid Build Coastguard Worker int i;
556*663afb9bSAndroid Build Coastguard Worker
557*663afb9bSAndroid Build Coastguard Worker test_ok = 0;
558*663afb9bSAndroid Build Coastguard Worker
559*663afb9bSAndroid Build Coastguard Worker if (use_pair) {
560*663afb9bSAndroid Build Coastguard Worker struct bufferevent *pair[2];
561*663afb9bSAndroid Build Coastguard Worker tt_assert(0 == bufferevent_pair_new(NULL, 0, pair));
562*663afb9bSAndroid Build Coastguard Worker bev1 = pair[0];
563*663afb9bSAndroid Build Coastguard Worker bev2 = pair[1];
564*663afb9bSAndroid Build Coastguard Worker } else {
565*663afb9bSAndroid Build Coastguard Worker bev1 = bufferevent_socket_new(NULL, pair[0], 0);
566*663afb9bSAndroid Build Coastguard Worker bev2 = bufferevent_socket_new(NULL, pair[1], 0);
567*663afb9bSAndroid Build Coastguard Worker }
568*663afb9bSAndroid Build Coastguard Worker bev1_base = bev1;
569*663afb9bSAndroid Build Coastguard Worker bev2_base = bev2;
570*663afb9bSAndroid Build Coastguard Worker
571*663afb9bSAndroid Build Coastguard Worker for (i = 0; i < (int)sizeof(buffer); i++)
572*663afb9bSAndroid Build Coastguard Worker buffer[i] = i;
573*663afb9bSAndroid Build Coastguard Worker
574*663afb9bSAndroid Build Coastguard Worker bev1 = bufferevent_filter_new(bev1, NULL, bufferevent_output_filter,
575*663afb9bSAndroid Build Coastguard Worker BEV_OPT_CLOSE_ON_FREE, NULL,
576*663afb9bSAndroid Build Coastguard Worker disable ? &bev1 : NULL);
577*663afb9bSAndroid Build Coastguard Worker
578*663afb9bSAndroid Build Coastguard Worker bev2 = bufferevent_filter_new(bev2, bufferevent_input_filter,
579*663afb9bSAndroid Build Coastguard Worker NULL, BEV_OPT_CLOSE_ON_FREE, NULL, NULL);
580*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev1, NULL, writecb, errorcb, NULL);
581*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev2, readcb, NULL, errorcb, NULL);
582*663afb9bSAndroid Build Coastguard Worker
583*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev1_base);
584*663afb9bSAndroid Build Coastguard Worker tt_ptr_op(bufferevent_get_underlying(bev2), ==, bev2_base);
585*663afb9bSAndroid Build Coastguard Worker tt_fd_op(bufferevent_getfd(bev1), ==, bufferevent_getfd(bev1_base));
586*663afb9bSAndroid Build Coastguard Worker tt_fd_op(bufferevent_getfd(bev2), ==, bufferevent_getfd(bev2_base));
587*663afb9bSAndroid Build Coastguard Worker
588*663afb9bSAndroid Build Coastguard Worker bufferevent_disable(bev1, EV_READ);
589*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev2, EV_READ);
590*663afb9bSAndroid Build Coastguard Worker /* insert some filters */
591*663afb9bSAndroid Build Coastguard Worker bufferevent_write(bev1, buffer, sizeof(buffer));
592*663afb9bSAndroid Build Coastguard Worker
593*663afb9bSAndroid Build Coastguard Worker event_dispatch();
594*663afb9bSAndroid Build Coastguard Worker
595*663afb9bSAndroid Build Coastguard Worker if (test_ok != 3 + !!disable)
596*663afb9bSAndroid Build Coastguard Worker test_ok = 0;
597*663afb9bSAndroid Build Coastguard Worker
598*663afb9bSAndroid Build Coastguard Worker end:
599*663afb9bSAndroid Build Coastguard Worker if (bev1)
600*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev1);
601*663afb9bSAndroid Build Coastguard Worker if (bev2)
602*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev2);
603*663afb9bSAndroid Build Coastguard Worker
604*663afb9bSAndroid Build Coastguard Worker }
605*663afb9bSAndroid Build Coastguard Worker
test_bufferevent_filters(void)606*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_filters(void)
607*663afb9bSAndroid Build Coastguard Worker { test_bufferevent_filters_impl(0, 0); }
test_bufferevent_pair_filters(void)608*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_pair_filters(void)
609*663afb9bSAndroid Build Coastguard Worker { test_bufferevent_filters_impl(1, 0); }
test_bufferevent_filters_disable(void)610*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_filters_disable(void)
611*663afb9bSAndroid Build Coastguard Worker { test_bufferevent_filters_impl(0, 1); }
test_bufferevent_pair_filters_disable(void)612*663afb9bSAndroid Build Coastguard Worker static void test_bufferevent_pair_filters_disable(void)
613*663afb9bSAndroid Build Coastguard Worker { test_bufferevent_filters_impl(1, 1); }
614*663afb9bSAndroid Build Coastguard Worker
615*663afb9bSAndroid Build Coastguard Worker
616*663afb9bSAndroid Build Coastguard Worker static void
sender_writecb(struct bufferevent * bev,void * ctx)617*663afb9bSAndroid Build Coastguard Worker sender_writecb(struct bufferevent *bev, void *ctx)
618*663afb9bSAndroid Build Coastguard Worker {
619*663afb9bSAndroid Build Coastguard Worker if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) {
620*663afb9bSAndroid Build Coastguard Worker bufferevent_disable(bev,EV_READ|EV_WRITE);
621*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("Flushed %d: freeing it.", (int)bufferevent_getfd(bev)));
622*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev);
623*663afb9bSAndroid Build Coastguard Worker }
624*663afb9bSAndroid Build Coastguard Worker }
625*663afb9bSAndroid Build Coastguard Worker
626*663afb9bSAndroid Build Coastguard Worker static void
sender_errorcb(struct bufferevent * bev,short what,void * ctx)627*663afb9bSAndroid Build Coastguard Worker sender_errorcb(struct bufferevent *bev, short what, void *ctx)
628*663afb9bSAndroid Build Coastguard Worker {
629*663afb9bSAndroid Build Coastguard Worker TT_FAIL(("Got sender error %d",(int)what));
630*663afb9bSAndroid Build Coastguard Worker }
631*663afb9bSAndroid Build Coastguard Worker
632*663afb9bSAndroid Build Coastguard Worker static int bufferevent_connect_test_flags = 0;
633*663afb9bSAndroid Build Coastguard Worker static int bufferevent_trigger_test_flags = 0;
634*663afb9bSAndroid Build Coastguard Worker static int n_strings_read = 0;
635*663afb9bSAndroid Build Coastguard Worker static int n_reads_invoked = 0;
636*663afb9bSAndroid Build Coastguard Worker static int n_events_invoked = 0;
637*663afb9bSAndroid Build Coastguard Worker
638*663afb9bSAndroid Build Coastguard Worker #define TEST_STR "Now is the time for all good events to signal for " \
639*663afb9bSAndroid Build Coastguard Worker "the good of their protocol"
640*663afb9bSAndroid Build Coastguard Worker static void
listen_cb(struct evconnlistener * listener,evutil_socket_t fd,struct sockaddr * sa,int socklen,void * arg)641*663afb9bSAndroid Build Coastguard Worker listen_cb(struct evconnlistener *listener, evutil_socket_t fd,
642*663afb9bSAndroid Build Coastguard Worker struct sockaddr *sa, int socklen, void *arg)
643*663afb9bSAndroid Build Coastguard Worker {
644*663afb9bSAndroid Build Coastguard Worker struct event_base *base = arg;
645*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev;
646*663afb9bSAndroid Build Coastguard Worker const char s[] = TEST_STR;
647*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("Got a request on socket %d", (int)fd ));
648*663afb9bSAndroid Build Coastguard Worker bev = bufferevent_socket_new(base, fd, bufferevent_connect_test_flags);
649*663afb9bSAndroid Build Coastguard Worker tt_assert(bev);
650*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev, NULL, sender_writecb, sender_errorcb, NULL);
651*663afb9bSAndroid Build Coastguard Worker bufferevent_write(bev, s, sizeof(s));
652*663afb9bSAndroid Build Coastguard Worker end:
653*663afb9bSAndroid Build Coastguard Worker ;
654*663afb9bSAndroid Build Coastguard Worker }
655*663afb9bSAndroid Build Coastguard Worker
656*663afb9bSAndroid Build Coastguard Worker static evutil_socket_t
fake_listener_create(struct sockaddr_in * localhost)657*663afb9bSAndroid Build Coastguard Worker fake_listener_create(struct sockaddr_in *localhost)
658*663afb9bSAndroid Build Coastguard Worker {
659*663afb9bSAndroid Build Coastguard Worker struct sockaddr *sa = (struct sockaddr *)localhost;
660*663afb9bSAndroid Build Coastguard Worker evutil_socket_t fd = -1;
661*663afb9bSAndroid Build Coastguard Worker ev_socklen_t slen = sizeof(*localhost);
662*663afb9bSAndroid Build Coastguard Worker
663*663afb9bSAndroid Build Coastguard Worker memset(localhost, 0, sizeof(*localhost));
664*663afb9bSAndroid Build Coastguard Worker localhost->sin_port = 0; /* have the kernel pick a port */
665*663afb9bSAndroid Build Coastguard Worker localhost->sin_addr.s_addr = htonl(0x7f000001L);
666*663afb9bSAndroid Build Coastguard Worker localhost->sin_family = AF_INET;
667*663afb9bSAndroid Build Coastguard Worker
668*663afb9bSAndroid Build Coastguard Worker /* bind, but don't listen or accept. should trigger
669*663afb9bSAndroid Build Coastguard Worker "Connection refused" reliably on most platforms. */
670*663afb9bSAndroid Build Coastguard Worker fd = socket(localhost->sin_family, SOCK_STREAM, 0);
671*663afb9bSAndroid Build Coastguard Worker tt_assert(fd >= 0);
672*663afb9bSAndroid Build Coastguard Worker tt_assert(bind(fd, sa, slen) == 0);
673*663afb9bSAndroid Build Coastguard Worker tt_assert(getsockname(fd, sa, &slen) == 0);
674*663afb9bSAndroid Build Coastguard Worker
675*663afb9bSAndroid Build Coastguard Worker return fd;
676*663afb9bSAndroid Build Coastguard Worker
677*663afb9bSAndroid Build Coastguard Worker end:
678*663afb9bSAndroid Build Coastguard Worker return -1;
679*663afb9bSAndroid Build Coastguard Worker }
680*663afb9bSAndroid Build Coastguard Worker
681*663afb9bSAndroid Build Coastguard Worker static void
reader_eventcb(struct bufferevent * bev,short what,void * ctx)682*663afb9bSAndroid Build Coastguard Worker reader_eventcb(struct bufferevent *bev, short what, void *ctx)
683*663afb9bSAndroid Build Coastguard Worker {
684*663afb9bSAndroid Build Coastguard Worker struct event_base *base = ctx;
685*663afb9bSAndroid Build Coastguard Worker if (what & BEV_EVENT_ERROR) {
686*663afb9bSAndroid Build Coastguard Worker perror("foobar");
687*663afb9bSAndroid Build Coastguard Worker TT_FAIL(("got connector error %d", (int)what));
688*663afb9bSAndroid Build Coastguard Worker return;
689*663afb9bSAndroid Build Coastguard Worker }
690*663afb9bSAndroid Build Coastguard Worker if (what & BEV_EVENT_CONNECTED) {
691*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("connected on %d", (int)bufferevent_getfd(bev)));
692*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev, EV_READ);
693*663afb9bSAndroid Build Coastguard Worker }
694*663afb9bSAndroid Build Coastguard Worker if (what & BEV_EVENT_EOF) {
695*663afb9bSAndroid Build Coastguard Worker char buf[512];
696*663afb9bSAndroid Build Coastguard Worker size_t n;
697*663afb9bSAndroid Build Coastguard Worker n = bufferevent_read(bev, buf, sizeof(buf)-1);
698*663afb9bSAndroid Build Coastguard Worker tt_int_op(n, >=, 0);
699*663afb9bSAndroid Build Coastguard Worker buf[n] = '\0';
700*663afb9bSAndroid Build Coastguard Worker tt_str_op(buf, ==, TEST_STR);
701*663afb9bSAndroid Build Coastguard Worker if (++n_strings_read == 2)
702*663afb9bSAndroid Build Coastguard Worker event_base_loopexit(base, NULL);
703*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("EOF on %d: %d strings read.",
704*663afb9bSAndroid Build Coastguard Worker (int)bufferevent_getfd(bev), n_strings_read));
705*663afb9bSAndroid Build Coastguard Worker }
706*663afb9bSAndroid Build Coastguard Worker end:
707*663afb9bSAndroid Build Coastguard Worker ;
708*663afb9bSAndroid Build Coastguard Worker }
709*663afb9bSAndroid Build Coastguard Worker
710*663afb9bSAndroid Build Coastguard Worker static void
reader_eventcb_simple(struct bufferevent * bev,short what,void * ctx)711*663afb9bSAndroid Build Coastguard Worker reader_eventcb_simple(struct bufferevent *bev, short what, void *ctx)
712*663afb9bSAndroid Build Coastguard Worker {
713*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("Read eventcb simple invoked on %d.",
714*663afb9bSAndroid Build Coastguard Worker (int)bufferevent_getfd(bev)));
715*663afb9bSAndroid Build Coastguard Worker n_events_invoked++;
716*663afb9bSAndroid Build Coastguard Worker }
717*663afb9bSAndroid Build Coastguard Worker
718*663afb9bSAndroid Build Coastguard Worker static void
reader_readcb(struct bufferevent * bev,void * ctx)719*663afb9bSAndroid Build Coastguard Worker reader_readcb(struct bufferevent *bev, void *ctx)
720*663afb9bSAndroid Build Coastguard Worker {
721*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("Read invoked on %d.", (int)bufferevent_getfd(bev)));
722*663afb9bSAndroid Build Coastguard Worker n_reads_invoked++;
723*663afb9bSAndroid Build Coastguard Worker }
724*663afb9bSAndroid Build Coastguard Worker
725*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_connect(void * arg)726*663afb9bSAndroid Build Coastguard Worker test_bufferevent_connect(void *arg)
727*663afb9bSAndroid Build Coastguard Worker {
728*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = arg;
729*663afb9bSAndroid Build Coastguard Worker struct evconnlistener *lev=NULL;
730*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev1=NULL, *bev2=NULL;
731*663afb9bSAndroid Build Coastguard Worker struct sockaddr_in localhost;
732*663afb9bSAndroid Build Coastguard Worker struct sockaddr_storage ss;
733*663afb9bSAndroid Build Coastguard Worker struct sockaddr *sa;
734*663afb9bSAndroid Build Coastguard Worker ev_socklen_t slen;
735*663afb9bSAndroid Build Coastguard Worker
736*663afb9bSAndroid Build Coastguard Worker int be_flags=BEV_OPT_CLOSE_ON_FREE;
737*663afb9bSAndroid Build Coastguard Worker
738*663afb9bSAndroid Build Coastguard Worker if (strstr((char*)data->setup_data, "defer")) {
739*663afb9bSAndroid Build Coastguard Worker be_flags |= BEV_OPT_DEFER_CALLBACKS;
740*663afb9bSAndroid Build Coastguard Worker }
741*663afb9bSAndroid Build Coastguard Worker if (strstr((char*)data->setup_data, "unlocked")) {
742*663afb9bSAndroid Build Coastguard Worker be_flags |= BEV_OPT_UNLOCK_CALLBACKS;
743*663afb9bSAndroid Build Coastguard Worker }
744*663afb9bSAndroid Build Coastguard Worker if (strstr((char*)data->setup_data, "lock")) {
745*663afb9bSAndroid Build Coastguard Worker be_flags |= BEV_OPT_THREADSAFE;
746*663afb9bSAndroid Build Coastguard Worker }
747*663afb9bSAndroid Build Coastguard Worker bufferevent_connect_test_flags = be_flags;
748*663afb9bSAndroid Build Coastguard Worker #ifdef _WIN32
749*663afb9bSAndroid Build Coastguard Worker if (!strcmp((char*)data->setup_data, "unset_connectex")) {
750*663afb9bSAndroid Build Coastguard Worker struct win32_extension_fns *ext =
751*663afb9bSAndroid Build Coastguard Worker (struct win32_extension_fns *)
752*663afb9bSAndroid Build Coastguard Worker event_get_win32_extension_fns_();
753*663afb9bSAndroid Build Coastguard Worker ext->ConnectEx = NULL;
754*663afb9bSAndroid Build Coastguard Worker }
755*663afb9bSAndroid Build Coastguard Worker #endif
756*663afb9bSAndroid Build Coastguard Worker
757*663afb9bSAndroid Build Coastguard Worker memset(&localhost, 0, sizeof(localhost));
758*663afb9bSAndroid Build Coastguard Worker
759*663afb9bSAndroid Build Coastguard Worker localhost.sin_port = 0; /* pick-a-port */
760*663afb9bSAndroid Build Coastguard Worker localhost.sin_addr.s_addr = htonl(0x7f000001L);
761*663afb9bSAndroid Build Coastguard Worker localhost.sin_family = AF_INET;
762*663afb9bSAndroid Build Coastguard Worker sa = (struct sockaddr *)&localhost;
763*663afb9bSAndroid Build Coastguard Worker lev = evconnlistener_new_bind(data->base, listen_cb, data->base,
764*663afb9bSAndroid Build Coastguard Worker LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,
765*663afb9bSAndroid Build Coastguard Worker 16, sa, sizeof(localhost));
766*663afb9bSAndroid Build Coastguard Worker tt_assert(lev);
767*663afb9bSAndroid Build Coastguard Worker
768*663afb9bSAndroid Build Coastguard Worker sa = (struct sockaddr *)&ss;
769*663afb9bSAndroid Build Coastguard Worker slen = sizeof(ss);
770*663afb9bSAndroid Build Coastguard Worker if (regress_get_listener_addr(lev, sa, &slen) < 0) {
771*663afb9bSAndroid Build Coastguard Worker tt_abort_perror("getsockname");
772*663afb9bSAndroid Build Coastguard Worker }
773*663afb9bSAndroid Build Coastguard Worker
774*663afb9bSAndroid Build Coastguard Worker tt_assert(!evconnlistener_enable(lev));
775*663afb9bSAndroid Build Coastguard Worker bev1 = bufferevent_socket_new(data->base, -1, be_flags);
776*663afb9bSAndroid Build Coastguard Worker bev2 = bufferevent_socket_new(data->base, -1, be_flags);
777*663afb9bSAndroid Build Coastguard Worker tt_assert(bev1);
778*663afb9bSAndroid Build Coastguard Worker tt_assert(bev2);
779*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev1, reader_readcb,NULL, reader_eventcb, data->base);
780*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev2, reader_readcb,NULL, reader_eventcb, data->base);
781*663afb9bSAndroid Build Coastguard Worker
782*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev1, EV_READ);
783*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev2, EV_READ);
784*663afb9bSAndroid Build Coastguard Worker
785*663afb9bSAndroid Build Coastguard Worker tt_want(!bufferevent_socket_connect(bev1, sa, sizeof(localhost)));
786*663afb9bSAndroid Build Coastguard Worker tt_want(!bufferevent_socket_connect(bev2, sa, sizeof(localhost)));
787*663afb9bSAndroid Build Coastguard Worker
788*663afb9bSAndroid Build Coastguard Worker event_base_dispatch(data->base);
789*663afb9bSAndroid Build Coastguard Worker
790*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_strings_read, ==, 2);
791*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_reads_invoked, >=, 2);
792*663afb9bSAndroid Build Coastguard Worker end:
793*663afb9bSAndroid Build Coastguard Worker if (lev)
794*663afb9bSAndroid Build Coastguard Worker evconnlistener_free(lev);
795*663afb9bSAndroid Build Coastguard Worker
796*663afb9bSAndroid Build Coastguard Worker if (bev1)
797*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev1);
798*663afb9bSAndroid Build Coastguard Worker
799*663afb9bSAndroid Build Coastguard Worker if (bev2)
800*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev2);
801*663afb9bSAndroid Build Coastguard Worker }
802*663afb9bSAndroid Build Coastguard Worker
803*663afb9bSAndroid Build Coastguard Worker static void
close_socket_cb(evutil_socket_t fd,short what,void * arg)804*663afb9bSAndroid Build Coastguard Worker close_socket_cb(evutil_socket_t fd, short what, void *arg)
805*663afb9bSAndroid Build Coastguard Worker {
806*663afb9bSAndroid Build Coastguard Worker evutil_socket_t *fdp = arg;
807*663afb9bSAndroid Build Coastguard Worker if (*fdp >= 0) {
808*663afb9bSAndroid Build Coastguard Worker evutil_closesocket(*fdp);
809*663afb9bSAndroid Build Coastguard Worker *fdp = -1;
810*663afb9bSAndroid Build Coastguard Worker }
811*663afb9bSAndroid Build Coastguard Worker }
812*663afb9bSAndroid Build Coastguard Worker
813*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_connect_fail_eventcb(void * arg)814*663afb9bSAndroid Build Coastguard Worker test_bufferevent_connect_fail_eventcb(void *arg)
815*663afb9bSAndroid Build Coastguard Worker {
816*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = arg;
817*663afb9bSAndroid Build Coastguard Worker int flags = BEV_OPT_CLOSE_ON_FREE | (long)data->setup_data;
818*663afb9bSAndroid Build Coastguard Worker struct event close_listener_event;
819*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev = NULL;
820*663afb9bSAndroid Build Coastguard Worker struct evconnlistener *lev = NULL;
821*663afb9bSAndroid Build Coastguard Worker struct sockaddr_in localhost;
822*663afb9bSAndroid Build Coastguard Worker struct timeval close_timeout = { 0, 300000 };
823*663afb9bSAndroid Build Coastguard Worker ev_socklen_t slen = sizeof(localhost);
824*663afb9bSAndroid Build Coastguard Worker evutil_socket_t fake_listener = -1;
825*663afb9bSAndroid Build Coastguard Worker int r;
826*663afb9bSAndroid Build Coastguard Worker
827*663afb9bSAndroid Build Coastguard Worker fake_listener = fake_listener_create(&localhost);
828*663afb9bSAndroid Build Coastguard Worker
829*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_events_invoked, ==, 0);
830*663afb9bSAndroid Build Coastguard Worker
831*663afb9bSAndroid Build Coastguard Worker bev = bufferevent_socket_new(data->base, -1, flags);
832*663afb9bSAndroid Build Coastguard Worker tt_assert(bev);
833*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev, reader_readcb, reader_readcb,
834*663afb9bSAndroid Build Coastguard Worker reader_eventcb_simple, data->base);
835*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev, EV_READ|EV_WRITE);
836*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_events_invoked, ==, 0);
837*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_reads_invoked, ==, 0);
838*663afb9bSAndroid Build Coastguard Worker
839*663afb9bSAndroid Build Coastguard Worker /** @see also test_bufferevent_connect_fail() */
840*663afb9bSAndroid Build Coastguard Worker r = bufferevent_socket_connect(bev, (struct sockaddr *)&localhost, slen);
841*663afb9bSAndroid Build Coastguard Worker /* XXXX we'd like to test the '0' case everywhere, but FreeBSD tells
842*663afb9bSAndroid Build Coastguard Worker * detects the error immediately, which is not really wrong of it. */
843*663afb9bSAndroid Build Coastguard Worker tt_want(r == 0 || r == -1);
844*663afb9bSAndroid Build Coastguard Worker
845*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_events_invoked, ==, 0);
846*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_reads_invoked, ==, 0);
847*663afb9bSAndroid Build Coastguard Worker
848*663afb9bSAndroid Build Coastguard Worker /* Close the listener socket after a delay. This should trigger
849*663afb9bSAndroid Build Coastguard Worker "connection refused" on some other platforms, including OSX. */
850*663afb9bSAndroid Build Coastguard Worker evtimer_assign(&close_listener_event, data->base, close_socket_cb,
851*663afb9bSAndroid Build Coastguard Worker &fake_listener);
852*663afb9bSAndroid Build Coastguard Worker event_add(&close_listener_event, &close_timeout);
853*663afb9bSAndroid Build Coastguard Worker
854*663afb9bSAndroid Build Coastguard Worker event_base_dispatch(data->base);
855*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_events_invoked, ==, 1);
856*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_reads_invoked, ==, 0);
857*663afb9bSAndroid Build Coastguard Worker
858*663afb9bSAndroid Build Coastguard Worker end:
859*663afb9bSAndroid Build Coastguard Worker if (lev)
860*663afb9bSAndroid Build Coastguard Worker evconnlistener_free(lev);
861*663afb9bSAndroid Build Coastguard Worker if (bev)
862*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev);
863*663afb9bSAndroid Build Coastguard Worker if (fake_listener >= 0)
864*663afb9bSAndroid Build Coastguard Worker evutil_closesocket(fake_listener);
865*663afb9bSAndroid Build Coastguard Worker }
866*663afb9bSAndroid Build Coastguard Worker
867*663afb9bSAndroid Build Coastguard Worker static void
want_fail_eventcb(struct bufferevent * bev,short what,void * ctx)868*663afb9bSAndroid Build Coastguard Worker want_fail_eventcb(struct bufferevent *bev, short what, void *ctx)
869*663afb9bSAndroid Build Coastguard Worker {
870*663afb9bSAndroid Build Coastguard Worker struct event_base *base = ctx;
871*663afb9bSAndroid Build Coastguard Worker const char *err;
872*663afb9bSAndroid Build Coastguard Worker evutil_socket_t s;
873*663afb9bSAndroid Build Coastguard Worker
874*663afb9bSAndroid Build Coastguard Worker if (what & BEV_EVENT_ERROR) {
875*663afb9bSAndroid Build Coastguard Worker s = bufferevent_getfd(bev);
876*663afb9bSAndroid Build Coastguard Worker err = evutil_socket_error_to_string(evutil_socket_geterror(s));
877*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("connection failure on "EV_SOCK_FMT": %s",
878*663afb9bSAndroid Build Coastguard Worker EV_SOCK_ARG(s), err));
879*663afb9bSAndroid Build Coastguard Worker test_ok = 1;
880*663afb9bSAndroid Build Coastguard Worker } else {
881*663afb9bSAndroid Build Coastguard Worker TT_FAIL(("didn't fail? what %hd", what));
882*663afb9bSAndroid Build Coastguard Worker }
883*663afb9bSAndroid Build Coastguard Worker
884*663afb9bSAndroid Build Coastguard Worker event_base_loopexit(base, NULL);
885*663afb9bSAndroid Build Coastguard Worker }
886*663afb9bSAndroid Build Coastguard Worker
887*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_connect_fail(void * arg)888*663afb9bSAndroid Build Coastguard Worker test_bufferevent_connect_fail(void *arg)
889*663afb9bSAndroid Build Coastguard Worker {
890*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = (struct basic_test_data *)arg;
891*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev=NULL;
892*663afb9bSAndroid Build Coastguard Worker struct event close_listener_event;
893*663afb9bSAndroid Build Coastguard Worker int close_listener_event_added = 0;
894*663afb9bSAndroid Build Coastguard Worker struct timeval close_timeout = { 0, 300000 };
895*663afb9bSAndroid Build Coastguard Worker struct sockaddr_in localhost;
896*663afb9bSAndroid Build Coastguard Worker ev_socklen_t slen = sizeof(localhost);
897*663afb9bSAndroid Build Coastguard Worker evutil_socket_t fake_listener = -1;
898*663afb9bSAndroid Build Coastguard Worker int r;
899*663afb9bSAndroid Build Coastguard Worker
900*663afb9bSAndroid Build Coastguard Worker test_ok = 0;
901*663afb9bSAndroid Build Coastguard Worker
902*663afb9bSAndroid Build Coastguard Worker fake_listener = fake_listener_create(&localhost);
903*663afb9bSAndroid Build Coastguard Worker bev = bufferevent_socket_new(data->base, -1,
904*663afb9bSAndroid Build Coastguard Worker BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
905*663afb9bSAndroid Build Coastguard Worker tt_assert(bev);
906*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev, NULL, NULL, want_fail_eventcb, data->base);
907*663afb9bSAndroid Build Coastguard Worker
908*663afb9bSAndroid Build Coastguard Worker r = bufferevent_socket_connect(bev, (struct sockaddr *)&localhost, slen);
909*663afb9bSAndroid Build Coastguard Worker /* XXXX we'd like to test the '0' case everywhere, but FreeBSD tells
910*663afb9bSAndroid Build Coastguard Worker * detects the error immediately, which is not really wrong of it. */
911*663afb9bSAndroid Build Coastguard Worker tt_want(r == 0 || r == -1);
912*663afb9bSAndroid Build Coastguard Worker
913*663afb9bSAndroid Build Coastguard Worker /* Close the listener socket after a delay. This should trigger
914*663afb9bSAndroid Build Coastguard Worker "connection refused" on some other platforms, including OSX. */
915*663afb9bSAndroid Build Coastguard Worker evtimer_assign(&close_listener_event, data->base, close_socket_cb,
916*663afb9bSAndroid Build Coastguard Worker &fake_listener);
917*663afb9bSAndroid Build Coastguard Worker event_add(&close_listener_event, &close_timeout);
918*663afb9bSAndroid Build Coastguard Worker close_listener_event_added = 1;
919*663afb9bSAndroid Build Coastguard Worker
920*663afb9bSAndroid Build Coastguard Worker event_base_dispatch(data->base);
921*663afb9bSAndroid Build Coastguard Worker
922*663afb9bSAndroid Build Coastguard Worker tt_int_op(test_ok, ==, 1);
923*663afb9bSAndroid Build Coastguard Worker
924*663afb9bSAndroid Build Coastguard Worker end:
925*663afb9bSAndroid Build Coastguard Worker if (fake_listener >= 0)
926*663afb9bSAndroid Build Coastguard Worker evutil_closesocket(fake_listener);
927*663afb9bSAndroid Build Coastguard Worker
928*663afb9bSAndroid Build Coastguard Worker if (bev)
929*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev);
930*663afb9bSAndroid Build Coastguard Worker
931*663afb9bSAndroid Build Coastguard Worker if (close_listener_event_added)
932*663afb9bSAndroid Build Coastguard Worker event_del(&close_listener_event);
933*663afb9bSAndroid Build Coastguard Worker }
934*663afb9bSAndroid Build Coastguard Worker
935*663afb9bSAndroid Build Coastguard Worker struct timeout_cb_result {
936*663afb9bSAndroid Build Coastguard Worker struct timeval read_timeout_at;
937*663afb9bSAndroid Build Coastguard Worker struct timeval write_timeout_at;
938*663afb9bSAndroid Build Coastguard Worker struct timeval last_wrote_at;
939*663afb9bSAndroid Build Coastguard Worker struct timeval last_read_at;
940*663afb9bSAndroid Build Coastguard Worker int n_read_timeouts;
941*663afb9bSAndroid Build Coastguard Worker int n_write_timeouts;
942*663afb9bSAndroid Build Coastguard Worker int total_calls;
943*663afb9bSAndroid Build Coastguard Worker };
944*663afb9bSAndroid Build Coastguard Worker
945*663afb9bSAndroid Build Coastguard Worker static void
bev_timeout_read_cb(struct bufferevent * bev,void * arg)946*663afb9bSAndroid Build Coastguard Worker bev_timeout_read_cb(struct bufferevent *bev, void *arg)
947*663afb9bSAndroid Build Coastguard Worker {
948*663afb9bSAndroid Build Coastguard Worker struct timeout_cb_result *res = arg;
949*663afb9bSAndroid Build Coastguard Worker evutil_gettimeofday(&res->last_read_at, NULL);
950*663afb9bSAndroid Build Coastguard Worker }
951*663afb9bSAndroid Build Coastguard Worker static void
bev_timeout_write_cb(struct bufferevent * bev,void * arg)952*663afb9bSAndroid Build Coastguard Worker bev_timeout_write_cb(struct bufferevent *bev, void *arg)
953*663afb9bSAndroid Build Coastguard Worker {
954*663afb9bSAndroid Build Coastguard Worker struct timeout_cb_result *res = arg;
955*663afb9bSAndroid Build Coastguard Worker evutil_gettimeofday(&res->last_wrote_at, NULL);
956*663afb9bSAndroid Build Coastguard Worker }
957*663afb9bSAndroid Build Coastguard Worker static void
bev_timeout_event_cb(struct bufferevent * bev,short what,void * arg)958*663afb9bSAndroid Build Coastguard Worker bev_timeout_event_cb(struct bufferevent *bev, short what, void *arg)
959*663afb9bSAndroid Build Coastguard Worker {
960*663afb9bSAndroid Build Coastguard Worker struct timeout_cb_result *res = arg;
961*663afb9bSAndroid Build Coastguard Worker ++res->total_calls;
962*663afb9bSAndroid Build Coastguard Worker
963*663afb9bSAndroid Build Coastguard Worker if ((what & (BEV_EVENT_READING|BEV_EVENT_TIMEOUT))
964*663afb9bSAndroid Build Coastguard Worker == (BEV_EVENT_READING|BEV_EVENT_TIMEOUT)) {
965*663afb9bSAndroid Build Coastguard Worker evutil_gettimeofday(&res->read_timeout_at, NULL);
966*663afb9bSAndroid Build Coastguard Worker ++res->n_read_timeouts;
967*663afb9bSAndroid Build Coastguard Worker }
968*663afb9bSAndroid Build Coastguard Worker if ((what & (BEV_EVENT_WRITING|BEV_EVENT_TIMEOUT))
969*663afb9bSAndroid Build Coastguard Worker == (BEV_EVENT_WRITING|BEV_EVENT_TIMEOUT)) {
970*663afb9bSAndroid Build Coastguard Worker evutil_gettimeofday(&res->write_timeout_at, NULL);
971*663afb9bSAndroid Build Coastguard Worker ++res->n_write_timeouts;
972*663afb9bSAndroid Build Coastguard Worker }
973*663afb9bSAndroid Build Coastguard Worker }
974*663afb9bSAndroid Build Coastguard Worker
975*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_timeouts(void * arg)976*663afb9bSAndroid Build Coastguard Worker test_bufferevent_timeouts(void *arg)
977*663afb9bSAndroid Build Coastguard Worker {
978*663afb9bSAndroid Build Coastguard Worker /* "arg" is a string containing "pair" and/or "filter". */
979*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev1 = NULL, *bev2 = NULL;
980*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = arg;
981*663afb9bSAndroid Build Coastguard Worker int use_pair = 0, use_filter = 0;
982*663afb9bSAndroid Build Coastguard Worker struct timeval tv_w, tv_r, started_at;
983*663afb9bSAndroid Build Coastguard Worker struct timeout_cb_result res1, res2;
984*663afb9bSAndroid Build Coastguard Worker
985*663afb9bSAndroid Build Coastguard Worker memset(&res1, 0, sizeof(res1));
986*663afb9bSAndroid Build Coastguard Worker memset(&res2, 0, sizeof(res2));
987*663afb9bSAndroid Build Coastguard Worker
988*663afb9bSAndroid Build Coastguard Worker if (strstr((char*)data->setup_data, "pair"))
989*663afb9bSAndroid Build Coastguard Worker use_pair = 1;
990*663afb9bSAndroid Build Coastguard Worker if (strstr((char*)data->setup_data, "filter"))
991*663afb9bSAndroid Build Coastguard Worker use_filter = 1;
992*663afb9bSAndroid Build Coastguard Worker
993*663afb9bSAndroid Build Coastguard Worker if (use_pair) {
994*663afb9bSAndroid Build Coastguard Worker struct bufferevent *p[2];
995*663afb9bSAndroid Build Coastguard Worker tt_int_op(0, ==, bufferevent_pair_new(data->base, 0, p));
996*663afb9bSAndroid Build Coastguard Worker bev1 = p[0];
997*663afb9bSAndroid Build Coastguard Worker bev2 = p[1];
998*663afb9bSAndroid Build Coastguard Worker } else {
999*663afb9bSAndroid Build Coastguard Worker bev1 = bufferevent_socket_new(data->base, data->pair[0], 0);
1000*663afb9bSAndroid Build Coastguard Worker bev2 = bufferevent_socket_new(data->base, data->pair[1], 0);
1001*663afb9bSAndroid Build Coastguard Worker }
1002*663afb9bSAndroid Build Coastguard Worker tt_assert(bev1);
1003*663afb9bSAndroid Build Coastguard Worker tt_assert(bev2);
1004*663afb9bSAndroid Build Coastguard Worker
1005*663afb9bSAndroid Build Coastguard Worker if (use_filter) {
1006*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bevf1, *bevf2;
1007*663afb9bSAndroid Build Coastguard Worker bevf1 = bufferevent_filter_new(bev1, NULL, NULL,
1008*663afb9bSAndroid Build Coastguard Worker BEV_OPT_CLOSE_ON_FREE, NULL, NULL);
1009*663afb9bSAndroid Build Coastguard Worker bevf2 = bufferevent_filter_new(bev2, NULL, NULL,
1010*663afb9bSAndroid Build Coastguard Worker BEV_OPT_CLOSE_ON_FREE, NULL, NULL);
1011*663afb9bSAndroid Build Coastguard Worker tt_assert(bevf1);
1012*663afb9bSAndroid Build Coastguard Worker tt_assert(bevf2);
1013*663afb9bSAndroid Build Coastguard Worker bev1 = bevf1;
1014*663afb9bSAndroid Build Coastguard Worker bev2 = bevf2;
1015*663afb9bSAndroid Build Coastguard Worker }
1016*663afb9bSAndroid Build Coastguard Worker
1017*663afb9bSAndroid Build Coastguard Worker /* Do this nice and early. */
1018*663afb9bSAndroid Build Coastguard Worker bufferevent_disable(bev2, EV_READ);
1019*663afb9bSAndroid Build Coastguard Worker
1020*663afb9bSAndroid Build Coastguard Worker /* bev1 will try to write and read. Both will time out. */
1021*663afb9bSAndroid Build Coastguard Worker evutil_gettimeofday(&started_at, NULL);
1022*663afb9bSAndroid Build Coastguard Worker tv_w.tv_sec = tv_r.tv_sec = 0;
1023*663afb9bSAndroid Build Coastguard Worker tv_w.tv_usec = 100*1000;
1024*663afb9bSAndroid Build Coastguard Worker tv_r.tv_usec = 150*1000;
1025*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev1, bev_timeout_read_cb, bev_timeout_write_cb,
1026*663afb9bSAndroid Build Coastguard Worker bev_timeout_event_cb, &res1);
1027*663afb9bSAndroid Build Coastguard Worker bufferevent_set_timeouts(bev1, &tv_r, &tv_w);
1028*663afb9bSAndroid Build Coastguard Worker bufferevent_write(bev1, "ABCDEFG", 7);
1029*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev1, EV_READ|EV_WRITE);
1030*663afb9bSAndroid Build Coastguard Worker
1031*663afb9bSAndroid Build Coastguard Worker /* bev2 has nothing to say, and isn't listening. */
1032*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev2, bev_timeout_read_cb, bev_timeout_write_cb,
1033*663afb9bSAndroid Build Coastguard Worker bev_timeout_event_cb, &res2);
1034*663afb9bSAndroid Build Coastguard Worker tv_w.tv_sec = tv_r.tv_sec = 0;
1035*663afb9bSAndroid Build Coastguard Worker tv_w.tv_usec = 200*1000;
1036*663afb9bSAndroid Build Coastguard Worker tv_r.tv_usec = 100*1000;
1037*663afb9bSAndroid Build Coastguard Worker bufferevent_set_timeouts(bev2, &tv_r, &tv_w);
1038*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev2, EV_WRITE);
1039*663afb9bSAndroid Build Coastguard Worker
1040*663afb9bSAndroid Build Coastguard Worker tv_r.tv_sec = 0;
1041*663afb9bSAndroid Build Coastguard Worker tv_r.tv_usec = 350000;
1042*663afb9bSAndroid Build Coastguard Worker
1043*663afb9bSAndroid Build Coastguard Worker event_base_loopexit(data->base, &tv_r);
1044*663afb9bSAndroid Build Coastguard Worker event_base_dispatch(data->base);
1045*663afb9bSAndroid Build Coastguard Worker
1046*663afb9bSAndroid Build Coastguard Worker /* XXXX Test that actually reading or writing a little resets the
1047*663afb9bSAndroid Build Coastguard Worker * timeouts. */
1048*663afb9bSAndroid Build Coastguard Worker
1049*663afb9bSAndroid Build Coastguard Worker tt_want(res1.total_calls == 2);
1050*663afb9bSAndroid Build Coastguard Worker tt_want(res1.n_read_timeouts == 1);
1051*663afb9bSAndroid Build Coastguard Worker tt_want(res1.n_write_timeouts == 1);
1052*663afb9bSAndroid Build Coastguard Worker tt_want(res2.total_calls == !(use_pair && !use_filter));
1053*663afb9bSAndroid Build Coastguard Worker tt_want(res2.n_write_timeouts == !(use_pair && !use_filter));
1054*663afb9bSAndroid Build Coastguard Worker tt_want(!res2.n_read_timeouts);
1055*663afb9bSAndroid Build Coastguard Worker
1056*663afb9bSAndroid Build Coastguard Worker test_timeval_diff_eq(&started_at, &res1.read_timeout_at, 150);
1057*663afb9bSAndroid Build Coastguard Worker test_timeval_diff_eq(&started_at, &res1.write_timeout_at, 100);
1058*663afb9bSAndroid Build Coastguard Worker
1059*663afb9bSAndroid Build Coastguard Worker #define tt_assert_timeval_empty(tv) do { \
1060*663afb9bSAndroid Build Coastguard Worker tt_int_op((tv).tv_sec, ==, 0); \
1061*663afb9bSAndroid Build Coastguard Worker tt_int_op((tv).tv_usec, ==, 0); \
1062*663afb9bSAndroid Build Coastguard Worker } while(0)
1063*663afb9bSAndroid Build Coastguard Worker tt_assert_timeval_empty(res1.last_read_at);
1064*663afb9bSAndroid Build Coastguard Worker tt_assert_timeval_empty(res2.last_read_at);
1065*663afb9bSAndroid Build Coastguard Worker tt_assert_timeval_empty(res2.last_wrote_at);
1066*663afb9bSAndroid Build Coastguard Worker tt_assert_timeval_empty(res2.last_wrote_at);
1067*663afb9bSAndroid Build Coastguard Worker #undef tt_assert_timeval_empty
1068*663afb9bSAndroid Build Coastguard Worker
1069*663afb9bSAndroid Build Coastguard Worker end:
1070*663afb9bSAndroid Build Coastguard Worker if (bev1)
1071*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev1);
1072*663afb9bSAndroid Build Coastguard Worker if (bev2)
1073*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev2);
1074*663afb9bSAndroid Build Coastguard Worker }
1075*663afb9bSAndroid Build Coastguard Worker
1076*663afb9bSAndroid Build Coastguard Worker static void
trigger_failure_cb(evutil_socket_t fd,short what,void * ctx)1077*663afb9bSAndroid Build Coastguard Worker trigger_failure_cb(evutil_socket_t fd, short what, void *ctx)
1078*663afb9bSAndroid Build Coastguard Worker {
1079*663afb9bSAndroid Build Coastguard Worker TT_FAIL(("The triggered callback did not fire or the machine is really slow (try increasing timeout)."));
1080*663afb9bSAndroid Build Coastguard Worker }
1081*663afb9bSAndroid Build Coastguard Worker
1082*663afb9bSAndroid Build Coastguard Worker static void
trigger_eventcb(struct bufferevent * bev,short what,void * ctx)1083*663afb9bSAndroid Build Coastguard Worker trigger_eventcb(struct bufferevent *bev, short what, void *ctx)
1084*663afb9bSAndroid Build Coastguard Worker {
1085*663afb9bSAndroid Build Coastguard Worker struct event_base *base = ctx;
1086*663afb9bSAndroid Build Coastguard Worker if (what == ~0) {
1087*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("Event successfully triggered."));
1088*663afb9bSAndroid Build Coastguard Worker event_base_loopexit(base, NULL);
1089*663afb9bSAndroid Build Coastguard Worker return;
1090*663afb9bSAndroid Build Coastguard Worker }
1091*663afb9bSAndroid Build Coastguard Worker reader_eventcb(bev, what, ctx);
1092*663afb9bSAndroid Build Coastguard Worker }
1093*663afb9bSAndroid Build Coastguard Worker
1094*663afb9bSAndroid Build Coastguard Worker static void
trigger_readcb_triggered(struct bufferevent * bev,void * ctx)1095*663afb9bSAndroid Build Coastguard Worker trigger_readcb_triggered(struct bufferevent *bev, void *ctx)
1096*663afb9bSAndroid Build Coastguard Worker {
1097*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("Read successfully triggered."));
1098*663afb9bSAndroid Build Coastguard Worker n_reads_invoked++;
1099*663afb9bSAndroid Build Coastguard Worker bufferevent_trigger_event(bev, ~0, bufferevent_trigger_test_flags);
1100*663afb9bSAndroid Build Coastguard Worker }
1101*663afb9bSAndroid Build Coastguard Worker
1102*663afb9bSAndroid Build Coastguard Worker static void
trigger_readcb(struct bufferevent * bev,void * ctx)1103*663afb9bSAndroid Build Coastguard Worker trigger_readcb(struct bufferevent *bev, void *ctx)
1104*663afb9bSAndroid Build Coastguard Worker {
1105*663afb9bSAndroid Build Coastguard Worker struct timeval timeout = { 30, 0 };
1106*663afb9bSAndroid Build Coastguard Worker struct event_base *base = ctx;
1107*663afb9bSAndroid Build Coastguard Worker size_t low, high, len;
1108*663afb9bSAndroid Build Coastguard Worker int expected_reads;
1109*663afb9bSAndroid Build Coastguard Worker
1110*663afb9bSAndroid Build Coastguard Worker TT_BLATHER(("Read invoked on %d.", (int)bufferevent_getfd(bev)));
1111*663afb9bSAndroid Build Coastguard Worker expected_reads = ++n_reads_invoked;
1112*663afb9bSAndroid Build Coastguard Worker
1113*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev, trigger_readcb_triggered, NULL, trigger_eventcb, ctx);
1114*663afb9bSAndroid Build Coastguard Worker
1115*663afb9bSAndroid Build Coastguard Worker bufferevent_getwatermark(bev, EV_READ, &low, &high);
1116*663afb9bSAndroid Build Coastguard Worker len = evbuffer_get_length(bufferevent_get_input(bev));
1117*663afb9bSAndroid Build Coastguard Worker
1118*663afb9bSAndroid Build Coastguard Worker bufferevent_setwatermark(bev, EV_READ, len + 1, 0);
1119*663afb9bSAndroid Build Coastguard Worker bufferevent_trigger(bev, EV_READ, bufferevent_trigger_test_flags);
1120*663afb9bSAndroid Build Coastguard Worker /* no callback expected */
1121*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_reads_invoked, ==, expected_reads);
1122*663afb9bSAndroid Build Coastguard Worker
1123*663afb9bSAndroid Build Coastguard Worker if ((bufferevent_trigger_test_flags & BEV_TRIG_DEFER_CALLBACKS) ||
1124*663afb9bSAndroid Build Coastguard Worker (bufferevent_connect_test_flags & BEV_OPT_DEFER_CALLBACKS)) {
1125*663afb9bSAndroid Build Coastguard Worker /* will be deferred */
1126*663afb9bSAndroid Build Coastguard Worker } else {
1127*663afb9bSAndroid Build Coastguard Worker expected_reads++;
1128*663afb9bSAndroid Build Coastguard Worker }
1129*663afb9bSAndroid Build Coastguard Worker
1130*663afb9bSAndroid Build Coastguard Worker event_base_once(base, -1, EV_TIMEOUT, trigger_failure_cb, NULL, &timeout);
1131*663afb9bSAndroid Build Coastguard Worker
1132*663afb9bSAndroid Build Coastguard Worker bufferevent_trigger(bev, EV_READ,
1133*663afb9bSAndroid Build Coastguard Worker bufferevent_trigger_test_flags | BEV_TRIG_IGNORE_WATERMARKS);
1134*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_reads_invoked, ==, expected_reads);
1135*663afb9bSAndroid Build Coastguard Worker
1136*663afb9bSAndroid Build Coastguard Worker bufferevent_setwatermark(bev, EV_READ, low, high);
1137*663afb9bSAndroid Build Coastguard Worker end:
1138*663afb9bSAndroid Build Coastguard Worker ;
1139*663afb9bSAndroid Build Coastguard Worker }
1140*663afb9bSAndroid Build Coastguard Worker
1141*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_trigger(void * arg)1142*663afb9bSAndroid Build Coastguard Worker test_bufferevent_trigger(void *arg)
1143*663afb9bSAndroid Build Coastguard Worker {
1144*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = arg;
1145*663afb9bSAndroid Build Coastguard Worker struct evconnlistener *lev=NULL;
1146*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev=NULL;
1147*663afb9bSAndroid Build Coastguard Worker struct sockaddr_in localhost;
1148*663afb9bSAndroid Build Coastguard Worker struct sockaddr_storage ss;
1149*663afb9bSAndroid Build Coastguard Worker struct sockaddr *sa;
1150*663afb9bSAndroid Build Coastguard Worker ev_socklen_t slen;
1151*663afb9bSAndroid Build Coastguard Worker
1152*663afb9bSAndroid Build Coastguard Worker int be_flags=BEV_OPT_CLOSE_ON_FREE;
1153*663afb9bSAndroid Build Coastguard Worker int trig_flags=0;
1154*663afb9bSAndroid Build Coastguard Worker
1155*663afb9bSAndroid Build Coastguard Worker if (strstr((char*)data->setup_data, "defer")) {
1156*663afb9bSAndroid Build Coastguard Worker be_flags |= BEV_OPT_DEFER_CALLBACKS;
1157*663afb9bSAndroid Build Coastguard Worker }
1158*663afb9bSAndroid Build Coastguard Worker bufferevent_connect_test_flags = be_flags;
1159*663afb9bSAndroid Build Coastguard Worker
1160*663afb9bSAndroid Build Coastguard Worker if (strstr((char*)data->setup_data, "postpone")) {
1161*663afb9bSAndroid Build Coastguard Worker trig_flags |= BEV_TRIG_DEFER_CALLBACKS;
1162*663afb9bSAndroid Build Coastguard Worker }
1163*663afb9bSAndroid Build Coastguard Worker bufferevent_trigger_test_flags = trig_flags;
1164*663afb9bSAndroid Build Coastguard Worker
1165*663afb9bSAndroid Build Coastguard Worker memset(&localhost, 0, sizeof(localhost));
1166*663afb9bSAndroid Build Coastguard Worker
1167*663afb9bSAndroid Build Coastguard Worker localhost.sin_port = 0; /* pick-a-port */
1168*663afb9bSAndroid Build Coastguard Worker localhost.sin_addr.s_addr = htonl(0x7f000001L);
1169*663afb9bSAndroid Build Coastguard Worker localhost.sin_family = AF_INET;
1170*663afb9bSAndroid Build Coastguard Worker sa = (struct sockaddr *)&localhost;
1171*663afb9bSAndroid Build Coastguard Worker lev = evconnlistener_new_bind(data->base, listen_cb, data->base,
1172*663afb9bSAndroid Build Coastguard Worker LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,
1173*663afb9bSAndroid Build Coastguard Worker 16, sa, sizeof(localhost));
1174*663afb9bSAndroid Build Coastguard Worker tt_assert(lev);
1175*663afb9bSAndroid Build Coastguard Worker
1176*663afb9bSAndroid Build Coastguard Worker sa = (struct sockaddr *)&ss;
1177*663afb9bSAndroid Build Coastguard Worker slen = sizeof(ss);
1178*663afb9bSAndroid Build Coastguard Worker if (regress_get_listener_addr(lev, sa, &slen) < 0) {
1179*663afb9bSAndroid Build Coastguard Worker tt_abort_perror("getsockname");
1180*663afb9bSAndroid Build Coastguard Worker }
1181*663afb9bSAndroid Build Coastguard Worker
1182*663afb9bSAndroid Build Coastguard Worker tt_assert(!evconnlistener_enable(lev));
1183*663afb9bSAndroid Build Coastguard Worker bev = bufferevent_socket_new(data->base, -1, be_flags);
1184*663afb9bSAndroid Build Coastguard Worker tt_assert(bev);
1185*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev, trigger_readcb, NULL, trigger_eventcb, data->base);
1186*663afb9bSAndroid Build Coastguard Worker
1187*663afb9bSAndroid Build Coastguard Worker bufferevent_enable(bev, EV_READ);
1188*663afb9bSAndroid Build Coastguard Worker
1189*663afb9bSAndroid Build Coastguard Worker tt_want(!bufferevent_socket_connect(bev, sa, sizeof(localhost)));
1190*663afb9bSAndroid Build Coastguard Worker
1191*663afb9bSAndroid Build Coastguard Worker event_base_dispatch(data->base);
1192*663afb9bSAndroid Build Coastguard Worker
1193*663afb9bSAndroid Build Coastguard Worker tt_int_op(n_reads_invoked, ==, 2);
1194*663afb9bSAndroid Build Coastguard Worker end:
1195*663afb9bSAndroid Build Coastguard Worker if (lev)
1196*663afb9bSAndroid Build Coastguard Worker evconnlistener_free(lev);
1197*663afb9bSAndroid Build Coastguard Worker
1198*663afb9bSAndroid Build Coastguard Worker if (bev)
1199*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev);
1200*663afb9bSAndroid Build Coastguard Worker }
1201*663afb9bSAndroid Build Coastguard Worker
1202*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_socket_filter_inactive(void * arg)1203*663afb9bSAndroid Build Coastguard Worker test_bufferevent_socket_filter_inactive(void *arg)
1204*663afb9bSAndroid Build Coastguard Worker {
1205*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = arg;
1206*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev = NULL, *bevf = NULL;
1207*663afb9bSAndroid Build Coastguard Worker
1208*663afb9bSAndroid Build Coastguard Worker bev = bufferevent_socket_new(data->base, -1, 0);
1209*663afb9bSAndroid Build Coastguard Worker tt_assert(bev);
1210*663afb9bSAndroid Build Coastguard Worker bevf = bufferevent_filter_new(bev, NULL, NULL, 0, NULL, NULL);
1211*663afb9bSAndroid Build Coastguard Worker tt_assert(bevf);
1212*663afb9bSAndroid Build Coastguard Worker
1213*663afb9bSAndroid Build Coastguard Worker end:
1214*663afb9bSAndroid Build Coastguard Worker if (bevf)
1215*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bevf);
1216*663afb9bSAndroid Build Coastguard Worker if (bev)
1217*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev);
1218*663afb9bSAndroid Build Coastguard Worker }
1219*663afb9bSAndroid Build Coastguard Worker
1220*663afb9bSAndroid Build Coastguard Worker static void
pair_flush_eventcb(struct bufferevent * bev,short what,void * ctx)1221*663afb9bSAndroid Build Coastguard Worker pair_flush_eventcb(struct bufferevent *bev, short what, void *ctx)
1222*663afb9bSAndroid Build Coastguard Worker {
1223*663afb9bSAndroid Build Coastguard Worker int *callback_what = ctx;
1224*663afb9bSAndroid Build Coastguard Worker *callback_what = what;
1225*663afb9bSAndroid Build Coastguard Worker }
1226*663afb9bSAndroid Build Coastguard Worker
1227*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_pair_flush(void * arg)1228*663afb9bSAndroid Build Coastguard Worker test_bufferevent_pair_flush(void *arg)
1229*663afb9bSAndroid Build Coastguard Worker {
1230*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = arg;
1231*663afb9bSAndroid Build Coastguard Worker struct bufferevent *pair[2];
1232*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev1 = NULL;
1233*663afb9bSAndroid Build Coastguard Worker struct bufferevent *bev2 = NULL;
1234*663afb9bSAndroid Build Coastguard Worker int callback_what = 0;
1235*663afb9bSAndroid Build Coastguard Worker
1236*663afb9bSAndroid Build Coastguard Worker tt_assert(0 == bufferevent_pair_new(data->base, 0, pair));
1237*663afb9bSAndroid Build Coastguard Worker bev1 = pair[0];
1238*663afb9bSAndroid Build Coastguard Worker bev2 = pair[1];
1239*663afb9bSAndroid Build Coastguard Worker tt_assert(0 == bufferevent_enable(bev1, EV_WRITE));
1240*663afb9bSAndroid Build Coastguard Worker tt_assert(0 == bufferevent_enable(bev2, EV_READ));
1241*663afb9bSAndroid Build Coastguard Worker
1242*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(bev2, NULL, NULL, pair_flush_eventcb, &callback_what);
1243*663afb9bSAndroid Build Coastguard Worker
1244*663afb9bSAndroid Build Coastguard Worker bufferevent_flush(bev1, EV_WRITE, BEV_FINISHED);
1245*663afb9bSAndroid Build Coastguard Worker
1246*663afb9bSAndroid Build Coastguard Worker event_base_loop(data->base, EVLOOP_ONCE);
1247*663afb9bSAndroid Build Coastguard Worker
1248*663afb9bSAndroid Build Coastguard Worker tt_assert(callback_what == (BEV_EVENT_READING | BEV_EVENT_EOF));
1249*663afb9bSAndroid Build Coastguard Worker
1250*663afb9bSAndroid Build Coastguard Worker end:
1251*663afb9bSAndroid Build Coastguard Worker if (bev1)
1252*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev1);
1253*663afb9bSAndroid Build Coastguard Worker if (bev2)
1254*663afb9bSAndroid Build Coastguard Worker bufferevent_free(bev2);
1255*663afb9bSAndroid Build Coastguard Worker }
1256*663afb9bSAndroid Build Coastguard Worker
1257*663afb9bSAndroid Build Coastguard Worker struct bufferevent_filter_data_stuck {
1258*663afb9bSAndroid Build Coastguard Worker size_t header_size;
1259*663afb9bSAndroid Build Coastguard Worker size_t total_read;
1260*663afb9bSAndroid Build Coastguard Worker };
1261*663afb9bSAndroid Build Coastguard Worker
1262*663afb9bSAndroid Build Coastguard Worker static void
bufferevent_filter_data_stuck_readcb(struct bufferevent * bev,void * arg)1263*663afb9bSAndroid Build Coastguard Worker bufferevent_filter_data_stuck_readcb(struct bufferevent *bev, void *arg)
1264*663afb9bSAndroid Build Coastguard Worker {
1265*663afb9bSAndroid Build Coastguard Worker struct bufferevent_filter_data_stuck *filter_data = arg;
1266*663afb9bSAndroid Build Coastguard Worker struct evbuffer *input = bufferevent_get_input(bev);
1267*663afb9bSAndroid Build Coastguard Worker size_t read_size = evbuffer_get_length(input);
1268*663afb9bSAndroid Build Coastguard Worker evbuffer_drain(input, read_size);
1269*663afb9bSAndroid Build Coastguard Worker filter_data->total_read += read_size;
1270*663afb9bSAndroid Build Coastguard Worker }
1271*663afb9bSAndroid Build Coastguard Worker
1272*663afb9bSAndroid Build Coastguard Worker /**
1273*663afb9bSAndroid Build Coastguard Worker * This filter prepends header once before forwarding data.
1274*663afb9bSAndroid Build Coastguard Worker */
1275*663afb9bSAndroid Build Coastguard Worker static enum bufferevent_filter_result
bufferevent_filter_data_stuck_inputcb(struct evbuffer * src,struct evbuffer * dst,ev_ssize_t dst_limit,enum bufferevent_flush_mode mode,void * ctx)1276*663afb9bSAndroid Build Coastguard Worker bufferevent_filter_data_stuck_inputcb(
1277*663afb9bSAndroid Build Coastguard Worker struct evbuffer *src, struct evbuffer *dst, ev_ssize_t dst_limit,
1278*663afb9bSAndroid Build Coastguard Worker enum bufferevent_flush_mode mode, void *ctx)
1279*663afb9bSAndroid Build Coastguard Worker {
1280*663afb9bSAndroid Build Coastguard Worker struct bufferevent_filter_data_stuck *filter_data = ctx;
1281*663afb9bSAndroid Build Coastguard Worker static int header_inserted = 0;
1282*663afb9bSAndroid Build Coastguard Worker size_t payload_size;
1283*663afb9bSAndroid Build Coastguard Worker size_t header_size = 0;
1284*663afb9bSAndroid Build Coastguard Worker
1285*663afb9bSAndroid Build Coastguard Worker if (!header_inserted) {
1286*663afb9bSAndroid Build Coastguard Worker char *header = calloc(filter_data->header_size, 1);
1287*663afb9bSAndroid Build Coastguard Worker evbuffer_add(dst, header, filter_data->header_size);
1288*663afb9bSAndroid Build Coastguard Worker free(header);
1289*663afb9bSAndroid Build Coastguard Worker header_size = filter_data->header_size;
1290*663afb9bSAndroid Build Coastguard Worker header_inserted = 1;
1291*663afb9bSAndroid Build Coastguard Worker }
1292*663afb9bSAndroid Build Coastguard Worker
1293*663afb9bSAndroid Build Coastguard Worker payload_size = evbuffer_get_length(src);
1294*663afb9bSAndroid Build Coastguard Worker if (payload_size > dst_limit - header_size) {
1295*663afb9bSAndroid Build Coastguard Worker payload_size = dst_limit - header_size;
1296*663afb9bSAndroid Build Coastguard Worker }
1297*663afb9bSAndroid Build Coastguard Worker
1298*663afb9bSAndroid Build Coastguard Worker tt_int_op(payload_size, ==, evbuffer_remove_buffer(src, dst, payload_size));
1299*663afb9bSAndroid Build Coastguard Worker
1300*663afb9bSAndroid Build Coastguard Worker end:
1301*663afb9bSAndroid Build Coastguard Worker return BEV_OK;
1302*663afb9bSAndroid Build Coastguard Worker }
1303*663afb9bSAndroid Build Coastguard Worker
1304*663afb9bSAndroid Build Coastguard Worker static void
test_bufferevent_filter_data_stuck(void * arg)1305*663afb9bSAndroid Build Coastguard Worker test_bufferevent_filter_data_stuck(void *arg)
1306*663afb9bSAndroid Build Coastguard Worker {
1307*663afb9bSAndroid Build Coastguard Worker const size_t read_high_wm = 4096;
1308*663afb9bSAndroid Build Coastguard Worker struct bufferevent_filter_data_stuck filter_data;
1309*663afb9bSAndroid Build Coastguard Worker struct basic_test_data *data = arg;
1310*663afb9bSAndroid Build Coastguard Worker struct bufferevent *pair[2];
1311*663afb9bSAndroid Build Coastguard Worker struct bufferevent *filter = NULL;
1312*663afb9bSAndroid Build Coastguard Worker
1313*663afb9bSAndroid Build Coastguard Worker int options = BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS;
1314*663afb9bSAndroid Build Coastguard Worker
1315*663afb9bSAndroid Build Coastguard Worker char payload[4096];
1316*663afb9bSAndroid Build Coastguard Worker int payload_size = sizeof(payload);
1317*663afb9bSAndroid Build Coastguard Worker
1318*663afb9bSAndroid Build Coastguard Worker memset(&filter_data, 0, sizeof(filter_data));
1319*663afb9bSAndroid Build Coastguard Worker filter_data.header_size = 20;
1320*663afb9bSAndroid Build Coastguard Worker
1321*663afb9bSAndroid Build Coastguard Worker tt_assert(bufferevent_pair_new(data->base, options, pair) == 0);
1322*663afb9bSAndroid Build Coastguard Worker
1323*663afb9bSAndroid Build Coastguard Worker bufferevent_setwatermark(pair[0], EV_READ, 0, read_high_wm);
1324*663afb9bSAndroid Build Coastguard Worker bufferevent_setwatermark(pair[1], EV_READ, 0, read_high_wm);
1325*663afb9bSAndroid Build Coastguard Worker
1326*663afb9bSAndroid Build Coastguard Worker tt_assert(
1327*663afb9bSAndroid Build Coastguard Worker filter =
1328*663afb9bSAndroid Build Coastguard Worker bufferevent_filter_new(pair[1],
1329*663afb9bSAndroid Build Coastguard Worker bufferevent_filter_data_stuck_inputcb,
1330*663afb9bSAndroid Build Coastguard Worker NULL,
1331*663afb9bSAndroid Build Coastguard Worker options,
1332*663afb9bSAndroid Build Coastguard Worker NULL,
1333*663afb9bSAndroid Build Coastguard Worker &filter_data));
1334*663afb9bSAndroid Build Coastguard Worker
1335*663afb9bSAndroid Build Coastguard Worker bufferevent_setcb(filter,
1336*663afb9bSAndroid Build Coastguard Worker bufferevent_filter_data_stuck_readcb,
1337*663afb9bSAndroid Build Coastguard Worker NULL,
1338*663afb9bSAndroid Build Coastguard Worker NULL,
1339*663afb9bSAndroid Build Coastguard Worker &filter_data);
1340*663afb9bSAndroid Build Coastguard Worker
1341*663afb9bSAndroid Build Coastguard Worker tt_assert(bufferevent_enable(filter, EV_READ|EV_WRITE) == 0);
1342*663afb9bSAndroid Build Coastguard Worker
1343*663afb9bSAndroid Build Coastguard Worker bufferevent_setwatermark(filter, EV_READ, 0, read_high_wm);
1344*663afb9bSAndroid Build Coastguard Worker
1345*663afb9bSAndroid Build Coastguard Worker tt_assert(bufferevent_write(pair[0], payload, sizeof(payload)) == 0);
1346*663afb9bSAndroid Build Coastguard Worker
1347*663afb9bSAndroid Build Coastguard Worker event_base_dispatch(data->base);
1348*663afb9bSAndroid Build Coastguard Worker
1349*663afb9bSAndroid Build Coastguard Worker tt_int_op(filter_data.total_read, ==, payload_size + filter_data.header_size);
1350*663afb9bSAndroid Build Coastguard Worker end:
1351*663afb9bSAndroid Build Coastguard Worker if (pair[0])
1352*663afb9bSAndroid Build Coastguard Worker bufferevent_free(pair[0]);
1353*663afb9bSAndroid Build Coastguard Worker if (filter)
1354*663afb9bSAndroid Build Coastguard Worker bufferevent_free(filter);
1355*663afb9bSAndroid Build Coastguard Worker }
1356*663afb9bSAndroid Build Coastguard Worker
1357*663afb9bSAndroid Build Coastguard Worker struct testcase_t bufferevent_testcases[] = {
1358*663afb9bSAndroid Build Coastguard Worker
1359*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent, TT_ISOLATED),
1360*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_pair, TT_ISOLATED),
1361*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_flush_normal, TT_ISOLATED),
1362*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_flush_flush, TT_ISOLATED),
1363*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_flush_finished, TT_ISOLATED),
1364*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_pair_flush_normal, TT_ISOLATED),
1365*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_pair_flush_flush, TT_ISOLATED),
1366*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_pair_flush_finished, TT_ISOLATED),
1367*663afb9bSAndroid Build Coastguard Worker #if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED) && !defined(__SANITIZE_ADDRESS__)
1368*663afb9bSAndroid Build Coastguard Worker { "bufferevent_pair_release_lock", test_bufferevent_pair_release_lock,
1369*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_ISOLATED|TT_NEED_THREADS|TT_NEED_BASE|TT_LEGACY|TT_NO_LOGS,
1370*663afb9bSAndroid Build Coastguard Worker &basic_setup, NULL },
1371*663afb9bSAndroid Build Coastguard Worker #endif
1372*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_watermarks, TT_ISOLATED),
1373*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_pair_watermarks, TT_ISOLATED),
1374*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_filters, TT_ISOLATED),
1375*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_pair_filters, TT_ISOLATED),
1376*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_filters_disable, TT_ISOLATED),
1377*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_pair_filters_disable, TT_ISOLATED),
1378*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect", test_bufferevent_connect, TT_FORK|TT_NEED_BASE,
1379*663afb9bSAndroid Build Coastguard Worker &basic_setup, (void*)"" },
1380*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_defer", test_bufferevent_connect,
1381*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"defer" },
1382*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_lock", test_bufferevent_connect,
1383*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup, (void*)"lock" },
1384*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_lock_defer", test_bufferevent_connect,
1385*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup,
1386*663afb9bSAndroid Build Coastguard Worker (void*)"defer lock" },
1387*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_unlocked_cbs", test_bufferevent_connect,
1388*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup,
1389*663afb9bSAndroid Build Coastguard Worker (void*)"lock defer unlocked" },
1390*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_fail", test_bufferevent_connect_fail,
1391*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
1392*663afb9bSAndroid Build Coastguard Worker { "bufferevent_timeout", test_bufferevent_timeouts,
1393*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"" },
1394*663afb9bSAndroid Build Coastguard Worker { "bufferevent_timeout_pair", test_bufferevent_timeouts,
1395*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"pair" },
1396*663afb9bSAndroid Build Coastguard Worker { "bufferevent_timeout_filter", test_bufferevent_timeouts,
1397*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"filter" },
1398*663afb9bSAndroid Build Coastguard Worker { "bufferevent_timeout_filter_pair", test_bufferevent_timeouts,
1399*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"filter pair" },
1400*663afb9bSAndroid Build Coastguard Worker { "bufferevent_trigger", test_bufferevent_trigger, TT_FORK|TT_NEED_BASE,
1401*663afb9bSAndroid Build Coastguard Worker &basic_setup, (void*)"" },
1402*663afb9bSAndroid Build Coastguard Worker { "bufferevent_trigger_defer", test_bufferevent_trigger,
1403*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"defer" },
1404*663afb9bSAndroid Build Coastguard Worker { "bufferevent_trigger_postpone", test_bufferevent_trigger,
1405*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup,
1406*663afb9bSAndroid Build Coastguard Worker (void*)"postpone" },
1407*663afb9bSAndroid Build Coastguard Worker { "bufferevent_trigger_defer_postpone", test_bufferevent_trigger,
1408*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup,
1409*663afb9bSAndroid Build Coastguard Worker (void*)"defer postpone" },
1410*663afb9bSAndroid Build Coastguard Worker #ifdef EVENT__HAVE_LIBZ
1411*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_zlib, TT_ISOLATED),
1412*663afb9bSAndroid Build Coastguard Worker #else
1413*663afb9bSAndroid Build Coastguard Worker { "bufferevent_zlib", NULL, TT_SKIP, NULL, NULL },
1414*663afb9bSAndroid Build Coastguard Worker #endif
1415*663afb9bSAndroid Build Coastguard Worker
1416*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_fail_eventcb_defer",
1417*663afb9bSAndroid Build Coastguard Worker test_bufferevent_connect_fail_eventcb,
1418*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, (void*)BEV_OPT_DEFER_CALLBACKS },
1419*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_fail_eventcb",
1420*663afb9bSAndroid Build Coastguard Worker test_bufferevent_connect_fail_eventcb,
1421*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
1422*663afb9bSAndroid Build Coastguard Worker
1423*663afb9bSAndroid Build Coastguard Worker { "bufferevent_socket_filter_inactive",
1424*663afb9bSAndroid Build Coastguard Worker test_bufferevent_socket_filter_inactive,
1425*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
1426*663afb9bSAndroid Build Coastguard Worker { "bufferevent_pair_flush",
1427*663afb9bSAndroid Build Coastguard Worker test_bufferevent_pair_flush,
1428*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
1429*663afb9bSAndroid Build Coastguard Worker { "bufferevent_filter_data_stuck",
1430*663afb9bSAndroid Build Coastguard Worker test_bufferevent_filter_data_stuck,
1431*663afb9bSAndroid Build Coastguard Worker TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
1432*663afb9bSAndroid Build Coastguard Worker
1433*663afb9bSAndroid Build Coastguard Worker END_OF_TESTCASES,
1434*663afb9bSAndroid Build Coastguard Worker };
1435*663afb9bSAndroid Build Coastguard Worker
1436*663afb9bSAndroid Build Coastguard Worker #define TT_IOCP (TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP)
1437*663afb9bSAndroid Build Coastguard Worker #define TT_IOCP_LEGACY (TT_ISOLATED|TT_ENABLE_IOCP)
1438*663afb9bSAndroid Build Coastguard Worker struct testcase_t bufferevent_iocp_testcases[] = {
1439*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent, TT_IOCP_LEGACY),
1440*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_flush_normal, TT_ISOLATED),
1441*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_flush_flush, TT_ISOLATED),
1442*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_flush_finished, TT_ISOLATED),
1443*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_watermarks, TT_IOCP_LEGACY),
1444*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_filters, TT_IOCP_LEGACY),
1445*663afb9bSAndroid Build Coastguard Worker LEGACY(bufferevent_filters_disable, TT_IOCP_LEGACY),
1446*663afb9bSAndroid Build Coastguard Worker
1447*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect", test_bufferevent_connect,
1448*663afb9bSAndroid Build Coastguard Worker TT_IOCP, &basic_setup, (void*)"" },
1449*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_defer", test_bufferevent_connect,
1450*663afb9bSAndroid Build Coastguard Worker TT_IOCP, &basic_setup, (void*)"defer" },
1451*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_lock", test_bufferevent_connect,
1452*663afb9bSAndroid Build Coastguard Worker TT_IOCP, &basic_setup, (void*)"lock" },
1453*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_lock_defer", test_bufferevent_connect,
1454*663afb9bSAndroid Build Coastguard Worker TT_IOCP, &basic_setup, (void*)"defer lock" },
1455*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_fail", test_bufferevent_connect_fail,
1456*663afb9bSAndroid Build Coastguard Worker TT_IOCP, &basic_setup, NULL },
1457*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_nonblocking", test_bufferevent_connect,
1458*663afb9bSAndroid Build Coastguard Worker TT_IOCP, &basic_setup, (void*)"unset_connectex" },
1459*663afb9bSAndroid Build Coastguard Worker
1460*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_fail_eventcb_defer",
1461*663afb9bSAndroid Build Coastguard Worker test_bufferevent_connect_fail_eventcb,
1462*663afb9bSAndroid Build Coastguard Worker TT_IOCP, &basic_setup, (void*)BEV_OPT_DEFER_CALLBACKS },
1463*663afb9bSAndroid Build Coastguard Worker { "bufferevent_connect_fail_eventcb",
1464*663afb9bSAndroid Build Coastguard Worker test_bufferevent_connect_fail_eventcb, TT_IOCP, &basic_setup, NULL },
1465*663afb9bSAndroid Build Coastguard Worker
1466*663afb9bSAndroid Build Coastguard Worker END_OF_TESTCASES,
1467*663afb9bSAndroid Build Coastguard Worker };
1468