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