1c43e99fdSEd Maste /*
2c43e99fdSEd Maste * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3c43e99fdSEd Maste * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
4c43e99fdSEd Maste *
5c43e99fdSEd Maste * Redistribution and use in source and binary forms, with or without
6c43e99fdSEd Maste * modification, are permitted provided that the following conditions
7c43e99fdSEd Maste * are met:
8c43e99fdSEd Maste * 1. Redistributions of source code must retain the above copyright
9c43e99fdSEd Maste * notice, this list of conditions and the following disclaimer.
10c43e99fdSEd Maste * 2. Redistributions in binary form must reproduce the above copyright
11c43e99fdSEd Maste * notice, this list of conditions and the following disclaimer in the
12c43e99fdSEd Maste * documentation and/or other materials provided with the distribution.
13c43e99fdSEd Maste * 3. The name of the author may not be used to endorse or promote products
14c43e99fdSEd Maste * derived from this software without specific prior written permission.
15c43e99fdSEd Maste *
16c43e99fdSEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17c43e99fdSEd Maste * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18c43e99fdSEd Maste * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19c43e99fdSEd Maste * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20c43e99fdSEd Maste * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21c43e99fdSEd Maste * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22c43e99fdSEd Maste * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23c43e99fdSEd Maste * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24c43e99fdSEd Maste * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25c43e99fdSEd Maste * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26c43e99fdSEd Maste */
27c43e99fdSEd Maste #include "util-internal.h"
28c43e99fdSEd Maste
29c43e99fdSEd Maste #ifdef _WIN32
30c43e99fdSEd Maste #include <winsock2.h>
31c43e99fdSEd Maste #include <windows.h>
32c43e99fdSEd Maste #include <io.h>
33c43e99fdSEd Maste #include <fcntl.h>
34c43e99fdSEd Maste #endif
35c43e99fdSEd Maste
36*b50261e2SCy Schubert /* move_pthread_to_realtime_scheduling_class() */
37*b50261e2SCy Schubert #ifdef EVENT__HAVE_MACH_MACH_H
38*b50261e2SCy Schubert #include <mach/mach.h>
39*b50261e2SCy Schubert #endif
40*b50261e2SCy Schubert #ifdef EVENT__HAVE_MACH_MACH_TIME_H
41*b50261e2SCy Schubert #include <mach/mach_time.h>
42*b50261e2SCy Schubert #endif
43*b50261e2SCy Schubert
44c43e99fdSEd Maste #if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
45c43e99fdSEd Maste #if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \
46c43e99fdSEd Maste __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)
47c43e99fdSEd Maste #define FORK_BREAKS_GCOV
48c43e99fdSEd Maste #include <vproc.h>
49c43e99fdSEd Maste #endif
50c43e99fdSEd Maste #endif
51c43e99fdSEd Maste
52c43e99fdSEd Maste #include "event2/event-config.h"
53c43e99fdSEd Maste
54c43e99fdSEd Maste #if 0
55c43e99fdSEd Maste #include <sys/types.h>
56c43e99fdSEd Maste #include <sys/stat.h>
57c43e99fdSEd Maste #ifdef EVENT__HAVE_SYS_TIME_H
58c43e99fdSEd Maste #include <sys/time.h>
59c43e99fdSEd Maste #endif
60c43e99fdSEd Maste #include <sys/queue.h>
61c43e99fdSEd Maste #include <signal.h>
62c43e99fdSEd Maste #include <errno.h>
63c43e99fdSEd Maste #endif
64c43e99fdSEd Maste
65c43e99fdSEd Maste #include <sys/types.h>
66c43e99fdSEd Maste #ifdef EVENT__HAVE_SYS_STAT_H
67c43e99fdSEd Maste #include <sys/stat.h>
68c43e99fdSEd Maste #endif
69c43e99fdSEd Maste
70c43e99fdSEd Maste #ifndef _WIN32
71c43e99fdSEd Maste #include <sys/socket.h>
72c43e99fdSEd Maste #include <sys/wait.h>
73c43e99fdSEd Maste #include <signal.h>
74c43e99fdSEd Maste #include <unistd.h>
75c43e99fdSEd Maste #include <netdb.h>
76c43e99fdSEd Maste #endif
77c43e99fdSEd Maste
78c43e99fdSEd Maste #include <stdlib.h>
79c43e99fdSEd Maste #include <stdio.h>
80c43e99fdSEd Maste #include <string.h>
81c43e99fdSEd Maste #include <assert.h>
82c43e99fdSEd Maste
83c43e99fdSEd Maste #include "event2/util.h"
84c43e99fdSEd Maste #include "event2/event.h"
85c43e99fdSEd Maste #include "event2/event_compat.h"
86c43e99fdSEd Maste #include "event2/dns.h"
87c43e99fdSEd Maste #include "event2/dns_compat.h"
88c43e99fdSEd Maste #include "event2/thread.h"
89c43e99fdSEd Maste
90c43e99fdSEd Maste #include "event2/event-config.h"
91c43e99fdSEd Maste #include "regress.h"
92*b50261e2SCy Schubert #include "regress_thread.h"
93c43e99fdSEd Maste #include "tinytest.h"
94c43e99fdSEd Maste #include "tinytest_macros.h"
95c43e99fdSEd Maste #include "../iocp-internal.h"
96c43e99fdSEd Maste #include "../event-internal.h"
97*b50261e2SCy Schubert #include "../evthread-internal.h"
98c43e99fdSEd Maste
99c43e99fdSEd Maste struct evutil_weakrand_state test_weakrand_state;
100c43e99fdSEd Maste
101c43e99fdSEd Maste long
timeval_msec_diff(const struct timeval * start,const struct timeval * end)102c43e99fdSEd Maste timeval_msec_diff(const struct timeval *start, const struct timeval *end)
103c43e99fdSEd Maste {
104c43e99fdSEd Maste long ms = end->tv_sec - start->tv_sec;
105c43e99fdSEd Maste ms *= 1000;
106c43e99fdSEd Maste ms += ((end->tv_usec - start->tv_usec)+500) / 1000;
107c43e99fdSEd Maste return ms;
108c43e99fdSEd Maste }
109c43e99fdSEd Maste
110c43e99fdSEd Maste /* ============================================================ */
111c43e99fdSEd Maste /* Code to wrap up old legacy test cases that used setup() and cleanup().
112c43e99fdSEd Maste *
113c43e99fdSEd Maste * Not all of the tests designated "legacy" are ones that used setup() and
114c43e99fdSEd Maste * cleanup(), of course. A test is legacy it it uses setup()/cleanup(), OR
115c43e99fdSEd Maste * if it wants to find its event base/socketpair in global variables (ugh),
116c43e99fdSEd Maste * OR if it wants to communicate success/failure through test_ok.
117c43e99fdSEd Maste */
118c43e99fdSEd Maste
119c43e99fdSEd Maste /* This is set to true if we're inside a legacy test wrapper. It lets the
120c43e99fdSEd Maste setup() and cleanup() functions in regress.c know they're not needed.
121c43e99fdSEd Maste */
122c43e99fdSEd Maste int in_legacy_test_wrapper = 0;
123c43e99fdSEd Maste
dnslogcb(int w,const char * m)124c43e99fdSEd Maste static void dnslogcb(int w, const char *m)
125c43e99fdSEd Maste {
126c43e99fdSEd Maste TT_BLATHER(("%s", m));
127c43e99fdSEd Maste }
128c43e99fdSEd Maste
129c43e99fdSEd Maste /* creates a temporary file with the data in it. If *filename_out gets set,
130c43e99fdSEd Maste * the caller should try to unlink it. */
131c43e99fdSEd Maste int
regress_make_tmpfile(const void * data,size_t datalen,char ** filename_out)132c43e99fdSEd Maste regress_make_tmpfile(const void *data, size_t datalen, char **filename_out)
133c43e99fdSEd Maste {
134c43e99fdSEd Maste #ifndef _WIN32
135c43e99fdSEd Maste char tmpfilename[32];
136c43e99fdSEd Maste int fd;
137c43e99fdSEd Maste *filename_out = NULL;
138c43e99fdSEd Maste strcpy(tmpfilename, "/tmp/eventtmp.XXXXXX");
139c43e99fdSEd Maste #ifdef EVENT__HAVE_UMASK
140c43e99fdSEd Maste umask(0077);
141c43e99fdSEd Maste #endif
142c43e99fdSEd Maste fd = mkstemp(tmpfilename);
143c43e99fdSEd Maste if (fd == -1)
144c43e99fdSEd Maste return (-1);
145c43e99fdSEd Maste if (write(fd, data, datalen) != (int)datalen) {
146c43e99fdSEd Maste close(fd);
147c43e99fdSEd Maste return (-1);
148c43e99fdSEd Maste }
149c43e99fdSEd Maste lseek(fd, 0, SEEK_SET);
150c43e99fdSEd Maste /* remove it from the file system */
151c43e99fdSEd Maste unlink(tmpfilename);
152c43e99fdSEd Maste return (fd);
153c43e99fdSEd Maste #else
154c43e99fdSEd Maste /* XXXX actually delete the file later */
155c43e99fdSEd Maste char tmpfilepath[MAX_PATH];
156c43e99fdSEd Maste char tmpfilename[MAX_PATH];
157c43e99fdSEd Maste DWORD r, written;
158c43e99fdSEd Maste int tries = 16;
159c43e99fdSEd Maste HANDLE h;
160c43e99fdSEd Maste r = GetTempPathA(MAX_PATH, tmpfilepath);
161c43e99fdSEd Maste if (r > MAX_PATH || r == 0)
162c43e99fdSEd Maste return (-1);
163c43e99fdSEd Maste for (; tries > 0; --tries) {
164c43e99fdSEd Maste r = GetTempFileNameA(tmpfilepath, "LIBEVENT", 0, tmpfilename);
165c43e99fdSEd Maste if (r == 0)
166c43e99fdSEd Maste return (-1);
167c43e99fdSEd Maste h = CreateFileA(tmpfilename, GENERIC_READ|GENERIC_WRITE,
168c43e99fdSEd Maste 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
169c43e99fdSEd Maste if (h != INVALID_HANDLE_VALUE)
170c43e99fdSEd Maste break;
171c43e99fdSEd Maste }
172c43e99fdSEd Maste if (tries == 0)
173c43e99fdSEd Maste return (-1);
174c43e99fdSEd Maste written = 0;
175c43e99fdSEd Maste *filename_out = strdup(tmpfilename);
176c43e99fdSEd Maste WriteFile(h, data, (DWORD)datalen, &written, NULL);
177c43e99fdSEd Maste /* Closing the fd returned by this function will indeed close h. */
178c43e99fdSEd Maste return _open_osfhandle((intptr_t)h,_O_RDONLY);
179c43e99fdSEd Maste #endif
180c43e99fdSEd Maste }
181c43e99fdSEd Maste
182c43e99fdSEd Maste #ifndef _WIN32
183c43e99fdSEd Maste pid_t
regress_fork(void)184c43e99fdSEd Maste regress_fork(void)
185c43e99fdSEd Maste {
186c43e99fdSEd Maste pid_t pid = fork();
187c43e99fdSEd Maste #ifdef FORK_BREAKS_GCOV
188c43e99fdSEd Maste vproc_transaction_begin(0);
189c43e99fdSEd Maste #endif
190c43e99fdSEd Maste return pid;
191c43e99fdSEd Maste }
192c43e99fdSEd Maste #endif
193c43e99fdSEd Maste
194c43e99fdSEd Maste static void
ignore_log_cb(int s,const char * msg)195c43e99fdSEd Maste ignore_log_cb(int s, const char *msg)
196c43e99fdSEd Maste {
197c43e99fdSEd Maste }
198c43e99fdSEd Maste
199*b50261e2SCy Schubert /**
200*b50261e2SCy Schubert * Put into the real time scheduling class for better timers latency.
201*b50261e2SCy Schubert * https://developer.apple.com/library/archive/technotes/tn2169/_index.html#//apple_ref/doc/uid/DTS40013172-CH1-TNTAG6000
202*b50261e2SCy Schubert */
203*b50261e2SCy Schubert #if defined(__APPLE__)
move_pthread_to_realtime_scheduling_class(pthread_t pthread)204*b50261e2SCy Schubert static void move_pthread_to_realtime_scheduling_class(pthread_t pthread)
205*b50261e2SCy Schubert {
206*b50261e2SCy Schubert mach_timebase_info_data_t info;
207*b50261e2SCy Schubert mach_timebase_info(&info);
208*b50261e2SCy Schubert
209*b50261e2SCy Schubert const uint64_t NANOS_PER_MSEC = 1000000ULL;
210*b50261e2SCy Schubert double clock2abs =
211*b50261e2SCy Schubert ((double)info.denom / (double)info.numer) * NANOS_PER_MSEC;
212*b50261e2SCy Schubert
213*b50261e2SCy Schubert thread_time_constraint_policy_data_t policy;
214*b50261e2SCy Schubert policy.period = 0;
215*b50261e2SCy Schubert policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work
216*b50261e2SCy Schubert policy.constraint = (uint32_t)(10 * clock2abs);
217*b50261e2SCy Schubert policy.preemptible = FALSE;
218*b50261e2SCy Schubert
219*b50261e2SCy Schubert int kr = thread_policy_set(pthread_mach_thread_np(pthread),
220*b50261e2SCy Schubert THREAD_TIME_CONSTRAINT_POLICY,
221*b50261e2SCy Schubert (thread_policy_t)&policy,
222*b50261e2SCy Schubert THREAD_TIME_CONSTRAINT_POLICY_COUNT);
223*b50261e2SCy Schubert if (kr != KERN_SUCCESS) {
224*b50261e2SCy Schubert mach_error("thread_policy_set:", kr);
225*b50261e2SCy Schubert exit(1);
226*b50261e2SCy Schubert }
227*b50261e2SCy Schubert }
228*b50261e2SCy Schubert
thread_setup(THREAD_T pthread)229*b50261e2SCy Schubert void thread_setup(THREAD_T pthread)
230*b50261e2SCy Schubert {
231*b50261e2SCy Schubert move_pthread_to_realtime_scheduling_class(pthread);
232*b50261e2SCy Schubert }
233*b50261e2SCy Schubert #else /** \__APPLE__ */
thread_setup(THREAD_T pthread)234*b50261e2SCy Schubert void thread_setup(THREAD_T pthread) {}
235*b50261e2SCy Schubert #endif /** \!__APPLE__ */
236*b50261e2SCy Schubert
237*b50261e2SCy Schubert
238*b50261e2SCy Schubert void *
basic_test_setup(const struct testcase_t * testcase)239c43e99fdSEd Maste basic_test_setup(const struct testcase_t *testcase)
240c43e99fdSEd Maste {
241c43e99fdSEd Maste struct event_base *base = NULL;
242c43e99fdSEd Maste evutil_socket_t spair[2] = { -1, -1 };
243c43e99fdSEd Maste struct basic_test_data *data = NULL;
244c43e99fdSEd Maste
245*b50261e2SCy Schubert thread_setup(THREAD_SELF());
246*b50261e2SCy Schubert
247c43e99fdSEd Maste #ifndef _WIN32
248c43e99fdSEd Maste if (testcase->flags & TT_ENABLE_IOCP_FLAG)
249c43e99fdSEd Maste return (void*)TT_SKIP;
250c43e99fdSEd Maste #endif
251c43e99fdSEd Maste
252*b50261e2SCy Schubert if (testcase->flags & TT_ENABLE_DEBUG_MODE &&
253*b50261e2SCy Schubert !libevent_tests_running_in_debug_mode) {
254*b50261e2SCy Schubert event_enable_debug_mode();
255*b50261e2SCy Schubert libevent_tests_running_in_debug_mode = 1;
256*b50261e2SCy Schubert }
257*b50261e2SCy Schubert
258c43e99fdSEd Maste if (testcase->flags & TT_NEED_THREADS) {
259c43e99fdSEd Maste if (!(testcase->flags & TT_FORK))
260c43e99fdSEd Maste return NULL;
261c43e99fdSEd Maste #if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED)
262c43e99fdSEd Maste if (evthread_use_pthreads())
263c43e99fdSEd Maste exit(1);
264c43e99fdSEd Maste #elif defined(EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED)
265c43e99fdSEd Maste if (evthread_use_windows_threads())
266c43e99fdSEd Maste exit(1);
267c43e99fdSEd Maste #else
268c43e99fdSEd Maste return (void*)TT_SKIP;
269c43e99fdSEd Maste #endif
270c43e99fdSEd Maste }
271c43e99fdSEd Maste
272c43e99fdSEd Maste if (testcase->flags & TT_NEED_SOCKETPAIR) {
273c43e99fdSEd Maste if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, spair) == -1) {
274c43e99fdSEd Maste fprintf(stderr, "%s: socketpair\n", __func__);
275c43e99fdSEd Maste exit(1);
276c43e99fdSEd Maste }
277c43e99fdSEd Maste
278c43e99fdSEd Maste if (evutil_make_socket_nonblocking(spair[0]) == -1) {
279c43e99fdSEd Maste fprintf(stderr, "fcntl(O_NONBLOCK)");
280c43e99fdSEd Maste exit(1);
281c43e99fdSEd Maste }
282c43e99fdSEd Maste
283c43e99fdSEd Maste if (evutil_make_socket_nonblocking(spair[1]) == -1) {
284c43e99fdSEd Maste fprintf(stderr, "fcntl(O_NONBLOCK)");
285c43e99fdSEd Maste exit(1);
286c43e99fdSEd Maste }
287c43e99fdSEd Maste }
288c43e99fdSEd Maste if (testcase->flags & TT_NEED_BASE) {
289c43e99fdSEd Maste if (testcase->flags & TT_LEGACY)
290c43e99fdSEd Maste base = event_init();
291c43e99fdSEd Maste else
292c43e99fdSEd Maste base = event_base_new();
293c43e99fdSEd Maste if (!base)
294c43e99fdSEd Maste exit(1);
295c43e99fdSEd Maste }
296c43e99fdSEd Maste if (testcase->flags & TT_ENABLE_IOCP_FLAG) {
297c43e99fdSEd Maste if (event_base_start_iocp_(base, 0)<0) {
298c43e99fdSEd Maste event_base_free(base);
299c43e99fdSEd Maste return (void*)TT_SKIP;
300c43e99fdSEd Maste }
301c43e99fdSEd Maste }
302c43e99fdSEd Maste
303c43e99fdSEd Maste if (testcase->flags & TT_NEED_DNS) {
304c43e99fdSEd Maste evdns_set_log_fn(dnslogcb);
305c43e99fdSEd Maste if (evdns_init())
306c43e99fdSEd Maste return NULL; /* fast failure */ /*XXX asserts. */
307c43e99fdSEd Maste }
308c43e99fdSEd Maste
309c43e99fdSEd Maste if (testcase->flags & TT_NO_LOGS)
310c43e99fdSEd Maste event_set_log_callback(ignore_log_cb);
311c43e99fdSEd Maste
312c43e99fdSEd Maste data = calloc(1, sizeof(*data));
313c43e99fdSEd Maste if (!data)
314c43e99fdSEd Maste exit(1);
315c43e99fdSEd Maste data->base = base;
316c43e99fdSEd Maste data->pair[0] = spair[0];
317c43e99fdSEd Maste data->pair[1] = spair[1];
318c43e99fdSEd Maste data->setup_data = testcase->setup_data;
319c43e99fdSEd Maste return data;
320c43e99fdSEd Maste }
321c43e99fdSEd Maste
322*b50261e2SCy Schubert int
basic_test_cleanup(const struct testcase_t * testcase,void * ptr)323c43e99fdSEd Maste basic_test_cleanup(const struct testcase_t *testcase, void *ptr)
324c43e99fdSEd Maste {
325c43e99fdSEd Maste struct basic_test_data *data = ptr;
326c43e99fdSEd Maste
327c43e99fdSEd Maste if (testcase->flags & TT_NO_LOGS)
328c43e99fdSEd Maste event_set_log_callback(NULL);
329c43e99fdSEd Maste
330c43e99fdSEd Maste if (testcase->flags & TT_NEED_SOCKETPAIR) {
331c43e99fdSEd Maste if (data->pair[0] != -1)
332c43e99fdSEd Maste evutil_closesocket(data->pair[0]);
333c43e99fdSEd Maste if (data->pair[1] != -1)
334c43e99fdSEd Maste evutil_closesocket(data->pair[1]);
335c43e99fdSEd Maste }
336c43e99fdSEd Maste
337c43e99fdSEd Maste if (testcase->flags & TT_NEED_DNS) {
338c43e99fdSEd Maste evdns_shutdown(0);
339c43e99fdSEd Maste }
340c43e99fdSEd Maste
341c43e99fdSEd Maste if (testcase->flags & TT_NEED_BASE) {
342c43e99fdSEd Maste if (data->base) {
343c43e99fdSEd Maste event_base_assert_ok_(data->base);
344c43e99fdSEd Maste event_base_free(data->base);
345c43e99fdSEd Maste }
346c43e99fdSEd Maste }
347c43e99fdSEd Maste
348c43e99fdSEd Maste if (testcase->flags & TT_FORK)
349c43e99fdSEd Maste libevent_global_shutdown();
350c43e99fdSEd Maste
351c43e99fdSEd Maste free(data);
352c43e99fdSEd Maste
353c43e99fdSEd Maste return 1;
354c43e99fdSEd Maste }
355c43e99fdSEd Maste
356c43e99fdSEd Maste const struct testcase_setup_t basic_setup = {
357c43e99fdSEd Maste basic_test_setup, basic_test_cleanup
358c43e99fdSEd Maste };
359c43e99fdSEd Maste
360c43e99fdSEd Maste /* The "data" for a legacy test is just a pointer to the void fn(void)
361c43e99fdSEd Maste function implementing the test case. We need to set up some globals,
362c43e99fdSEd Maste though, since that's where legacy tests expect to find a socketpair
363c43e99fdSEd Maste (sometimes) and a global event_base (sometimes).
364c43e99fdSEd Maste */
365c43e99fdSEd Maste static void *
legacy_test_setup(const struct testcase_t * testcase)366c43e99fdSEd Maste legacy_test_setup(const struct testcase_t *testcase)
367c43e99fdSEd Maste {
368c43e99fdSEd Maste struct basic_test_data *data = basic_test_setup(testcase);
369c43e99fdSEd Maste if (data == (void*)TT_SKIP || data == NULL)
370c43e99fdSEd Maste return data;
371c43e99fdSEd Maste global_base = data->base;
372c43e99fdSEd Maste pair[0] = data->pair[0];
373c43e99fdSEd Maste pair[1] = data->pair[1];
374c43e99fdSEd Maste data->legacy_test_fn = testcase->setup_data;
375c43e99fdSEd Maste return data;
376c43e99fdSEd Maste }
377c43e99fdSEd Maste
378c43e99fdSEd Maste /* This function is the implementation of every legacy test case. It
379c43e99fdSEd Maste sets test_ok to 0, invokes the test function, and tells tinytest that
380c43e99fdSEd Maste the test failed if the test didn't set test_ok to 1.
381c43e99fdSEd Maste */
382c43e99fdSEd Maste void
run_legacy_test_fn(void * ptr)383c43e99fdSEd Maste run_legacy_test_fn(void *ptr)
384c43e99fdSEd Maste {
385c43e99fdSEd Maste struct basic_test_data *data = ptr;
386c43e99fdSEd Maste test_ok = called = 0;
387c43e99fdSEd Maste
388c43e99fdSEd Maste in_legacy_test_wrapper = 1;
389c43e99fdSEd Maste data->legacy_test_fn(); /* This part actually calls the test */
390c43e99fdSEd Maste in_legacy_test_wrapper = 0;
391c43e99fdSEd Maste
392c43e99fdSEd Maste if (!test_ok)
393c43e99fdSEd Maste tt_abort_msg("Legacy unit test failed");
394c43e99fdSEd Maste
395c43e99fdSEd Maste end:
396c43e99fdSEd Maste test_ok = 0;
397c43e99fdSEd Maste }
398c43e99fdSEd Maste
399c43e99fdSEd Maste /* This function doesn't have to clean up ptr (which is just a pointer
400c43e99fdSEd Maste to the test function), but it may need to close the socketpair or
401c43e99fdSEd Maste free the event_base.
402c43e99fdSEd Maste */
403c43e99fdSEd Maste static int
legacy_test_cleanup(const struct testcase_t * testcase,void * ptr)404c43e99fdSEd Maste legacy_test_cleanup(const struct testcase_t *testcase, void *ptr)
405c43e99fdSEd Maste {
406c43e99fdSEd Maste int r = basic_test_cleanup(testcase, ptr);
407c43e99fdSEd Maste pair[0] = pair[1] = -1;
408c43e99fdSEd Maste global_base = NULL;
409c43e99fdSEd Maste return r;
410c43e99fdSEd Maste }
411c43e99fdSEd Maste
412c43e99fdSEd Maste const struct testcase_setup_t legacy_setup = {
413c43e99fdSEd Maste legacy_test_setup, legacy_test_cleanup
414c43e99fdSEd Maste };
415c43e99fdSEd Maste
416c43e99fdSEd Maste /* ============================================================ */
417c43e99fdSEd Maste
418c43e99fdSEd Maste #if (!defined(EVENT__HAVE_PTHREADS) && !defined(_WIN32)) || defined(EVENT__DISABLE_THREAD_SUPPORT)
419c43e99fdSEd Maste struct testcase_t thread_testcases[] = {
420c43e99fdSEd Maste { "basic", NULL, TT_SKIP, NULL, NULL },
421c43e99fdSEd Maste END_OF_TESTCASES
422c43e99fdSEd Maste };
423c43e99fdSEd Maste #endif
424c43e99fdSEd Maste
425c43e99fdSEd Maste struct testgroup_t testgroups[] = {
426c43e99fdSEd Maste { "main/", main_testcases },
427c43e99fdSEd Maste { "heap/", minheap_testcases },
428c43e99fdSEd Maste { "et/", edgetriggered_testcases },
429c43e99fdSEd Maste { "finalize/", finalize_testcases },
430c43e99fdSEd Maste { "evbuffer/", evbuffer_testcases },
431c43e99fdSEd Maste { "signal/", signal_testcases },
432c43e99fdSEd Maste { "util/", util_testcases },
433c43e99fdSEd Maste { "bufferevent/", bufferevent_testcases },
434c43e99fdSEd Maste { "http/", http_testcases },
435c43e99fdSEd Maste { "dns/", dns_testcases },
436c43e99fdSEd Maste { "evtag/", evtag_testcases },
437c43e99fdSEd Maste { "rpc/", rpc_testcases },
438c43e99fdSEd Maste { "thread/", thread_testcases },
439c43e99fdSEd Maste { "listener/", listener_testcases },
440c43e99fdSEd Maste #ifdef _WIN32
441c43e99fdSEd Maste { "iocp/", iocp_testcases },
442c43e99fdSEd Maste { "iocp/bufferevent/", bufferevent_iocp_testcases },
443c43e99fdSEd Maste { "iocp/listener/", listener_iocp_testcases },
444*b50261e2SCy Schubert { "iocp/http/", http_iocp_testcases },
445c43e99fdSEd Maste #endif
446c43e99fdSEd Maste #ifdef EVENT__HAVE_OPENSSL
447c43e99fdSEd Maste { "ssl/", ssl_testcases },
448c43e99fdSEd Maste #endif
449c43e99fdSEd Maste END_OF_GROUPS
450c43e99fdSEd Maste };
451c43e99fdSEd Maste
452c43e99fdSEd Maste const char *alltests[] = { "+..", NULL };
453c43e99fdSEd Maste const char *livenettests[] = {
454c43e99fdSEd Maste "+util/getaddrinfo_live",
455c43e99fdSEd Maste "+dns/gethostby..",
456c43e99fdSEd Maste "+dns/resolve_reverse",
457c43e99fdSEd Maste NULL
458c43e99fdSEd Maste };
459c43e99fdSEd Maste const char *finetimetests[] = {
460c43e99fdSEd Maste "+util/monotonic_res_precise",
461c43e99fdSEd Maste "+util/monotonic_res_fallback",
462c43e99fdSEd Maste "+thread/deferred_cb_skew",
463c43e99fdSEd Maste "+http/connection_retry",
464c43e99fdSEd Maste "+http/https_connection_retry",
465c43e99fdSEd Maste NULL
466c43e99fdSEd Maste };
467c43e99fdSEd Maste struct testlist_alias_t testaliases[] = {
468c43e99fdSEd Maste { "all", alltests },
469c43e99fdSEd Maste { "live_net", livenettests },
470c43e99fdSEd Maste { "fine_timing", finetimetests },
471c43e99fdSEd Maste END_OF_ALIASES
472c43e99fdSEd Maste };
473c43e99fdSEd Maste
474c43e99fdSEd Maste int libevent_tests_running_in_debug_mode = 0;
475c43e99fdSEd Maste
476c43e99fdSEd Maste int
main(int argc,const char ** argv)477c43e99fdSEd Maste main(int argc, const char **argv)
478c43e99fdSEd Maste {
479c43e99fdSEd Maste #ifdef _WIN32
480c43e99fdSEd Maste WORD wVersionRequested;
481c43e99fdSEd Maste WSADATA wsaData;
482c43e99fdSEd Maste
483c43e99fdSEd Maste wVersionRequested = MAKEWORD(2, 2);
484c43e99fdSEd Maste
485c43e99fdSEd Maste (void) WSAStartup(wVersionRequested, &wsaData);
486c43e99fdSEd Maste #endif
487c43e99fdSEd Maste
488c43e99fdSEd Maste #ifndef _WIN32
489c43e99fdSEd Maste if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
490c43e99fdSEd Maste return 1;
491c43e99fdSEd Maste #endif
492c43e99fdSEd Maste
493c43e99fdSEd Maste #ifdef _WIN32
494c43e99fdSEd Maste tinytest_skip(testgroups, "http/connection_retry");
495c43e99fdSEd Maste tinytest_skip(testgroups, "http/https_connection_retry");
496*b50261e2SCy Schubert tinytest_skip(testgroups, "http/read_on_write_error");
497c43e99fdSEd Maste #endif
498c43e99fdSEd Maste
499c43e99fdSEd Maste #ifndef EVENT__DISABLE_THREAD_SUPPORT
500c43e99fdSEd Maste if (!getenv("EVENT_NO_DEBUG_LOCKS"))
501c43e99fdSEd Maste evthread_enable_lock_debugging();
502c43e99fdSEd Maste #endif
503c43e99fdSEd Maste
504c43e99fdSEd Maste if (getenv("EVENT_DEBUG_MODE")) {
505c43e99fdSEd Maste event_enable_debug_mode();
506c43e99fdSEd Maste libevent_tests_running_in_debug_mode = 1;
507c43e99fdSEd Maste }
508c43e99fdSEd Maste if (getenv("EVENT_DEBUG_LOGGING_ALL")) {
509c43e99fdSEd Maste event_enable_debug_logging(EVENT_DBG_ALL);
510c43e99fdSEd Maste }
511c43e99fdSEd Maste
512c43e99fdSEd Maste tinytest_set_aliases(testaliases);
513c43e99fdSEd Maste
514c43e99fdSEd Maste evutil_weakrand_seed_(&test_weakrand_state, 0);
515c43e99fdSEd Maste
516*b50261e2SCy Schubert if (getenv("EVENT_NO_FILE_BUFFERING")) {
517*b50261e2SCy Schubert setbuf(stdout, NULL);
518*b50261e2SCy Schubert setbuf(stderr, NULL);
519*b50261e2SCy Schubert }
520*b50261e2SCy Schubert
521c43e99fdSEd Maste if (tinytest_main(argc,argv,testgroups))
522c43e99fdSEd Maste return 1;
523c43e99fdSEd Maste
524c43e99fdSEd Maste libevent_global_shutdown();
525c43e99fdSEd Maste
526c43e99fdSEd Maste return 0;
527c43e99fdSEd Maste }
528c43e99fdSEd Maste
529