1*eabc0478Schristos /* $NetBSD: regress_main.c,v 1.7 2024/08/18 20:47:23 christos Exp $ */ 28585484eSchristos 38585484eSchristos /* 48585484eSchristos * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> 58585484eSchristos * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 68585484eSchristos * 78585484eSchristos * Redistribution and use in source and binary forms, with or without 88585484eSchristos * modification, are permitted provided that the following conditions 98585484eSchristos * are met: 108585484eSchristos * 1. Redistributions of source code must retain the above copyright 118585484eSchristos * notice, this list of conditions and the following disclaimer. 128585484eSchristos * 2. Redistributions in binary form must reproduce the above copyright 138585484eSchristos * notice, this list of conditions and the following disclaimer in the 148585484eSchristos * documentation and/or other materials provided with the distribution. 158585484eSchristos * 3. The name of the author may not be used to endorse or promote products 168585484eSchristos * derived from this software without specific prior written permission. 178585484eSchristos * 188585484eSchristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 198585484eSchristos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 208585484eSchristos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 218585484eSchristos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 228585484eSchristos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 238585484eSchristos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 248585484eSchristos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 258585484eSchristos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 268585484eSchristos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 278585484eSchristos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 288585484eSchristos */ 298585484eSchristos #include "util-internal.h" 308585484eSchristos 318585484eSchristos #ifdef _WIN32 328585484eSchristos #include <winsock2.h> 338585484eSchristos #include <windows.h> 348585484eSchristos #include <io.h> 358585484eSchristos #include <fcntl.h> 368585484eSchristos #endif 378585484eSchristos 38*eabc0478Schristos /* move_pthread_to_realtime_scheduling_class() */ 39*eabc0478Schristos #ifdef EVENT__HAVE_MACH_MACH_H 40*eabc0478Schristos #include <mach/mach.h> 41*eabc0478Schristos #endif 42*eabc0478Schristos #ifdef EVENT__HAVE_MACH_MACH_TIME_H 43*eabc0478Schristos #include <mach/mach_time.h> 44*eabc0478Schristos #endif 45*eabc0478Schristos 468585484eSchristos #if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) 478585484eSchristos #if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \ 488585484eSchristos __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070) 498585484eSchristos #define FORK_BREAKS_GCOV 508585484eSchristos #include <vproc.h> 518585484eSchristos #endif 528585484eSchristos #endif 538585484eSchristos 548585484eSchristos #include "event2/event-config.h" 558585484eSchristos 568585484eSchristos #if 0 578585484eSchristos #include <sys/types.h> 588585484eSchristos #include <sys/stat.h> 598585484eSchristos #ifdef EVENT__HAVE_SYS_TIME_H 608585484eSchristos #include <sys/time.h> 618585484eSchristos #endif 628585484eSchristos #include <sys/queue.h> 638585484eSchristos #include <signal.h> 648585484eSchristos #include <errno.h> 658585484eSchristos #endif 668585484eSchristos 678585484eSchristos #include <sys/types.h> 688585484eSchristos #ifdef EVENT__HAVE_SYS_STAT_H 698585484eSchristos #include <sys/stat.h> 708585484eSchristos #endif 718585484eSchristos 728585484eSchristos #ifndef _WIN32 738585484eSchristos #include <sys/socket.h> 748585484eSchristos #include <sys/wait.h> 758585484eSchristos #include <signal.h> 768585484eSchristos #include <unistd.h> 778585484eSchristos #include <netdb.h> 788585484eSchristos #endif 798585484eSchristos 808585484eSchristos #include <stdlib.h> 818585484eSchristos #include <stdio.h> 828585484eSchristos #include <string.h> 838585484eSchristos #include <assert.h> 848585484eSchristos 858585484eSchristos #include "event2/util.h" 868585484eSchristos #include "event2/event.h" 878585484eSchristos #include "event2/event_compat.h" 888585484eSchristos #include "event2/dns.h" 898585484eSchristos #include "event2/dns_compat.h" 908585484eSchristos #include "event2/thread.h" 918585484eSchristos 928585484eSchristos #include "event2/event-config.h" 938585484eSchristos #include "regress.h" 94*eabc0478Schristos #include "regress_thread.h" 958585484eSchristos #include "tinytest.h" 968585484eSchristos #include "tinytest_macros.h" 978585484eSchristos #include "../iocp-internal.h" 988585484eSchristos #include "../event-internal.h" 99*eabc0478Schristos #include "../evthread-internal.h" 1008585484eSchristos 1017476e6e4Schristos struct evutil_weakrand_state test_weakrand_state; 1027476e6e4Schristos 1038585484eSchristos long 1048585484eSchristos timeval_msec_diff(const struct timeval *start, const struct timeval *end) 1058585484eSchristos { 1068585484eSchristos long ms = end->tv_sec - start->tv_sec; 1078585484eSchristos ms *= 1000; 1088585484eSchristos ms += ((end->tv_usec - start->tv_usec)+500) / 1000; 1098585484eSchristos return ms; 1108585484eSchristos } 1118585484eSchristos 1128585484eSchristos /* ============================================================ */ 1138585484eSchristos /* Code to wrap up old legacy test cases that used setup() and cleanup(). 1148585484eSchristos * 1158585484eSchristos * Not all of the tests designated "legacy" are ones that used setup() and 1168585484eSchristos * cleanup(), of course. A test is legacy it it uses setup()/cleanup(), OR 1178585484eSchristos * if it wants to find its event base/socketpair in global variables (ugh), 1188585484eSchristos * OR if it wants to communicate success/failure through test_ok. 1198585484eSchristos */ 1208585484eSchristos 1218585484eSchristos /* This is set to true if we're inside a legacy test wrapper. It lets the 1228585484eSchristos setup() and cleanup() functions in regress.c know they're not needed. 1238585484eSchristos */ 1248585484eSchristos int in_legacy_test_wrapper = 0; 1258585484eSchristos 1268585484eSchristos static void dnslogcb(int w, const char *m) 1278585484eSchristos { 1288585484eSchristos TT_BLATHER(("%s", m)); 1298585484eSchristos } 1308585484eSchristos 1318585484eSchristos /* creates a temporary file with the data in it. If *filename_out gets set, 1328585484eSchristos * the caller should try to unlink it. */ 1338585484eSchristos int 1348585484eSchristos regress_make_tmpfile(const void *data, size_t datalen, char **filename_out) 1358585484eSchristos { 1368585484eSchristos #ifndef _WIN32 1378585484eSchristos char tmpfilename[32]; 1388585484eSchristos int fd; 1398585484eSchristos *filename_out = NULL; 1408585484eSchristos strcpy(tmpfilename, "/tmp/eventtmp.XXXXXX"); 1418585484eSchristos #ifdef EVENT__HAVE_UMASK 1428585484eSchristos umask(0077); 1438585484eSchristos #endif 1448585484eSchristos fd = mkstemp(tmpfilename); 1458585484eSchristos if (fd == -1) 1468585484eSchristos return (-1); 1478585484eSchristos if (write(fd, data, datalen) != (int)datalen) { 1488585484eSchristos close(fd); 1498585484eSchristos return (-1); 1508585484eSchristos } 1518585484eSchristos lseek(fd, 0, SEEK_SET); 1528585484eSchristos /* remove it from the file system */ 1538585484eSchristos unlink(tmpfilename); 1548585484eSchristos return (fd); 1558585484eSchristos #else 1568585484eSchristos /* XXXX actually delete the file later */ 1578585484eSchristos char tmpfilepath[MAX_PATH]; 1588585484eSchristos char tmpfilename[MAX_PATH]; 1598585484eSchristos DWORD r, written; 1608585484eSchristos int tries = 16; 1618585484eSchristos HANDLE h; 1628585484eSchristos r = GetTempPathA(MAX_PATH, tmpfilepath); 1638585484eSchristos if (r > MAX_PATH || r == 0) 1648585484eSchristos return (-1); 1658585484eSchristos for (; tries > 0; --tries) { 1668585484eSchristos r = GetTempFileNameA(tmpfilepath, "LIBEVENT", 0, tmpfilename); 1678585484eSchristos if (r == 0) 1688585484eSchristos return (-1); 1698585484eSchristos h = CreateFileA(tmpfilename, GENERIC_READ|GENERIC_WRITE, 1708585484eSchristos 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 1718585484eSchristos if (h != INVALID_HANDLE_VALUE) 1728585484eSchristos break; 1738585484eSchristos } 1748585484eSchristos if (tries == 0) 1758585484eSchristos return (-1); 1768585484eSchristos written = 0; 1778585484eSchristos *filename_out = strdup(tmpfilename); 1788585484eSchristos WriteFile(h, data, (DWORD)datalen, &written, NULL); 1798585484eSchristos /* Closing the fd returned by this function will indeed close h. */ 1808585484eSchristos return _open_osfhandle((intptr_t)h,_O_RDONLY); 1818585484eSchristos #endif 1828585484eSchristos } 1838585484eSchristos 1848585484eSchristos #ifndef _WIN32 1858585484eSchristos pid_t 1868585484eSchristos regress_fork(void) 1878585484eSchristos { 1888585484eSchristos pid_t pid = fork(); 1898585484eSchristos #ifdef FORK_BREAKS_GCOV 1908585484eSchristos vproc_transaction_begin(0); 1918585484eSchristos #endif 1928585484eSchristos return pid; 1938585484eSchristos } 1948585484eSchristos #endif 1958585484eSchristos 1968585484eSchristos static void 1978585484eSchristos ignore_log_cb(int s, const char *msg) 1988585484eSchristos { 1998585484eSchristos } 2008585484eSchristos 201*eabc0478Schristos /** 202*eabc0478Schristos * Put into the real time scheduling class for better timers latency. 203*eabc0478Schristos * https://developer.apple.com/library/archive/technotes/tn2169/_index.html#//apple_ref/doc/uid/DTS40013172-CH1-TNTAG6000 204*eabc0478Schristos */ 205*eabc0478Schristos #if defined(__APPLE__) 206*eabc0478Schristos static void move_pthread_to_realtime_scheduling_class(pthread_t pthread) 207*eabc0478Schristos { 208*eabc0478Schristos mach_timebase_info_data_t info; 209*eabc0478Schristos mach_timebase_info(&info); 210*eabc0478Schristos 211*eabc0478Schristos const uint64_t NANOS_PER_MSEC = 1000000ULL; 212*eabc0478Schristos double clock2abs = 213*eabc0478Schristos ((double)info.denom / (double)info.numer) * NANOS_PER_MSEC; 214*eabc0478Schristos 215*eabc0478Schristos thread_time_constraint_policy_data_t policy; 216*eabc0478Schristos policy.period = 0; 217*eabc0478Schristos policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work 218*eabc0478Schristos policy.constraint = (uint32_t)(10 * clock2abs); 219*eabc0478Schristos policy.preemptible = FALSE; 220*eabc0478Schristos 221*eabc0478Schristos int kr = thread_policy_set(pthread_mach_thread_np(pthread), 222*eabc0478Schristos THREAD_TIME_CONSTRAINT_POLICY, 223*eabc0478Schristos (thread_policy_t)&policy, 224*eabc0478Schristos THREAD_TIME_CONSTRAINT_POLICY_COUNT); 225*eabc0478Schristos if (kr != KERN_SUCCESS) { 226*eabc0478Schristos mach_error("thread_policy_set:", kr); 227*eabc0478Schristos exit(1); 228*eabc0478Schristos } 229*eabc0478Schristos } 230*eabc0478Schristos 231*eabc0478Schristos void thread_setup(THREAD_T pthread) 232*eabc0478Schristos { 233*eabc0478Schristos move_pthread_to_realtime_scheduling_class(pthread); 234*eabc0478Schristos } 235*eabc0478Schristos #else /** \__APPLE__ */ 236*eabc0478Schristos void thread_setup(THREAD_T pthread) {} 237*eabc0478Schristos #endif /** \!__APPLE__ */ 238*eabc0478Schristos 239*eabc0478Schristos 240*eabc0478Schristos void * 2418585484eSchristos basic_test_setup(const struct testcase_t *testcase) 2428585484eSchristos { 2438585484eSchristos struct event_base *base = NULL; 2448585484eSchristos evutil_socket_t spair[2] = { -1, -1 }; 2458585484eSchristos struct basic_test_data *data = NULL; 2468585484eSchristos 247*eabc0478Schristos thread_setup(THREAD_SELF()); 248*eabc0478Schristos 2498585484eSchristos #ifndef _WIN32 2508585484eSchristos if (testcase->flags & TT_ENABLE_IOCP_FLAG) 2518585484eSchristos return (void*)TT_SKIP; 2528585484eSchristos #endif 2538585484eSchristos 254*eabc0478Schristos if (testcase->flags & TT_ENABLE_DEBUG_MODE && 255*eabc0478Schristos !libevent_tests_running_in_debug_mode) { 256*eabc0478Schristos event_enable_debug_mode(); 257*eabc0478Schristos libevent_tests_running_in_debug_mode = 1; 258*eabc0478Schristos } 259*eabc0478Schristos 2608585484eSchristos if (testcase->flags & TT_NEED_THREADS) { 2618585484eSchristos if (!(testcase->flags & TT_FORK)) 2628585484eSchristos return NULL; 2638585484eSchristos #if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED) 2648585484eSchristos if (evthread_use_pthreads()) 2658585484eSchristos exit(1); 2668585484eSchristos #elif defined(EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED) 2678585484eSchristos if (evthread_use_windows_threads()) 2688585484eSchristos exit(1); 2698585484eSchristos #else 2708585484eSchristos return (void*)TT_SKIP; 2718585484eSchristos #endif 2728585484eSchristos } 2738585484eSchristos 2748585484eSchristos if (testcase->flags & TT_NEED_SOCKETPAIR) { 2758585484eSchristos if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, spair) == -1) { 2768585484eSchristos fprintf(stderr, "%s: socketpair\n", __func__); 2778585484eSchristos exit(1); 2788585484eSchristos } 2798585484eSchristos 2808585484eSchristos if (evutil_make_socket_nonblocking(spair[0]) == -1) { 2818585484eSchristos fprintf(stderr, "fcntl(O_NONBLOCK)"); 2828585484eSchristos exit(1); 2838585484eSchristos } 2848585484eSchristos 2858585484eSchristos if (evutil_make_socket_nonblocking(spair[1]) == -1) { 2868585484eSchristos fprintf(stderr, "fcntl(O_NONBLOCK)"); 2878585484eSchristos exit(1); 2888585484eSchristos } 2898585484eSchristos } 2908585484eSchristos if (testcase->flags & TT_NEED_BASE) { 2918585484eSchristos if (testcase->flags & TT_LEGACY) 2928585484eSchristos base = event_init(); 2938585484eSchristos else 2948585484eSchristos base = event_base_new(); 2958585484eSchristos if (!base) 2968585484eSchristos exit(1); 2978585484eSchristos } 2988585484eSchristos if (testcase->flags & TT_ENABLE_IOCP_FLAG) { 2998585484eSchristos if (event_base_start_iocp_(base, 0)<0) { 3008585484eSchristos event_base_free(base); 3018585484eSchristos return (void*)TT_SKIP; 3028585484eSchristos } 3038585484eSchristos } 3048585484eSchristos 3058585484eSchristos if (testcase->flags & TT_NEED_DNS) { 3068585484eSchristos evdns_set_log_fn(dnslogcb); 3078585484eSchristos if (evdns_init()) 3088585484eSchristos return NULL; /* fast failure */ /*XXX asserts. */ 3098585484eSchristos } 3108585484eSchristos 3118585484eSchristos if (testcase->flags & TT_NO_LOGS) 3128585484eSchristos event_set_log_callback(ignore_log_cb); 3138585484eSchristos 3148585484eSchristos data = calloc(1, sizeof(*data)); 3158585484eSchristos if (!data) 3168585484eSchristos exit(1); 3178585484eSchristos data->base = base; 3188585484eSchristos data->pair[0] = spair[0]; 3198585484eSchristos data->pair[1] = spair[1]; 3208585484eSchristos data->setup_data = testcase->setup_data; 3218585484eSchristos return data; 3228585484eSchristos } 3238585484eSchristos 324*eabc0478Schristos int 3258585484eSchristos basic_test_cleanup(const struct testcase_t *testcase, void *ptr) 3268585484eSchristos { 3278585484eSchristos struct basic_test_data *data = ptr; 3288585484eSchristos 3298585484eSchristos if (testcase->flags & TT_NO_LOGS) 3308585484eSchristos event_set_log_callback(NULL); 3318585484eSchristos 3328585484eSchristos if (testcase->flags & TT_NEED_SOCKETPAIR) { 3338585484eSchristos if (data->pair[0] != -1) 3348585484eSchristos evutil_closesocket(data->pair[0]); 3358585484eSchristos if (data->pair[1] != -1) 3368585484eSchristos evutil_closesocket(data->pair[1]); 3378585484eSchristos } 3388585484eSchristos 3398585484eSchristos if (testcase->flags & TT_NEED_DNS) { 3408585484eSchristos evdns_shutdown(0); 3418585484eSchristos } 3428585484eSchristos 3438585484eSchristos if (testcase->flags & TT_NEED_BASE) { 3448585484eSchristos if (data->base) { 3458585484eSchristos event_base_assert_ok_(data->base); 3468585484eSchristos event_base_free(data->base); 3478585484eSchristos } 3488585484eSchristos } 3498585484eSchristos 3508585484eSchristos if (testcase->flags & TT_FORK) 3518585484eSchristos libevent_global_shutdown(); 3528585484eSchristos 3538585484eSchristos free(data); 3548585484eSchristos 3558585484eSchristos return 1; 3568585484eSchristos } 3578585484eSchristos 3588585484eSchristos const struct testcase_setup_t basic_setup = { 3598585484eSchristos basic_test_setup, basic_test_cleanup 3608585484eSchristos }; 3618585484eSchristos 3628585484eSchristos /* The "data" for a legacy test is just a pointer to the void fn(void) 3638585484eSchristos function implementing the test case. We need to set up some globals, 3648585484eSchristos though, since that's where legacy tests expect to find a socketpair 3658585484eSchristos (sometimes) and a global event_base (sometimes). 3668585484eSchristos */ 3678585484eSchristos static void * 3688585484eSchristos legacy_test_setup(const struct testcase_t *testcase) 3698585484eSchristos { 3708585484eSchristos struct basic_test_data *data = basic_test_setup(testcase); 3718585484eSchristos if (data == (void*)TT_SKIP || data == NULL) 3728585484eSchristos return data; 3738585484eSchristos global_base = data->base; 3748585484eSchristos pair[0] = data->pair[0]; 3758585484eSchristos pair[1] = data->pair[1]; 3768585484eSchristos data->legacy_test_fn = testcase->setup_data; 3778585484eSchristos return data; 3788585484eSchristos } 3798585484eSchristos 3808585484eSchristos /* This function is the implementation of every legacy test case. It 3818585484eSchristos sets test_ok to 0, invokes the test function, and tells tinytest that 3828585484eSchristos the test failed if the test didn't set test_ok to 1. 3838585484eSchristos */ 3848585484eSchristos void 3858585484eSchristos run_legacy_test_fn(void *ptr) 3868585484eSchristos { 3878585484eSchristos struct basic_test_data *data = ptr; 3888585484eSchristos test_ok = called = 0; 3898585484eSchristos 3908585484eSchristos in_legacy_test_wrapper = 1; 3918585484eSchristos data->legacy_test_fn(); /* This part actually calls the test */ 3928585484eSchristos in_legacy_test_wrapper = 0; 3938585484eSchristos 3948585484eSchristos if (!test_ok) 3958585484eSchristos tt_abort_msg("Legacy unit test failed"); 3968585484eSchristos 3978585484eSchristos end: 3988585484eSchristos test_ok = 0; 3998585484eSchristos } 4008585484eSchristos 4018585484eSchristos /* This function doesn't have to clean up ptr (which is just a pointer 4028585484eSchristos to the test function), but it may need to close the socketpair or 4038585484eSchristos free the event_base. 4048585484eSchristos */ 4058585484eSchristos static int 4068585484eSchristos legacy_test_cleanup(const struct testcase_t *testcase, void *ptr) 4078585484eSchristos { 4088585484eSchristos int r = basic_test_cleanup(testcase, ptr); 4098585484eSchristos pair[0] = pair[1] = -1; 4108585484eSchristos global_base = NULL; 4118585484eSchristos return r; 4128585484eSchristos } 4138585484eSchristos 4148585484eSchristos const struct testcase_setup_t legacy_setup = { 4158585484eSchristos legacy_test_setup, legacy_test_cleanup 4168585484eSchristos }; 4178585484eSchristos 4188585484eSchristos /* ============================================================ */ 4198585484eSchristos 4208585484eSchristos #if (!defined(EVENT__HAVE_PTHREADS) && !defined(_WIN32)) || defined(EVENT__DISABLE_THREAD_SUPPORT) 4218585484eSchristos struct testcase_t thread_testcases[] = { 4228585484eSchristos { "basic", NULL, TT_SKIP, NULL, NULL }, 4238585484eSchristos END_OF_TESTCASES 4248585484eSchristos }; 4258585484eSchristos #endif 4268585484eSchristos 4278585484eSchristos struct testgroup_t testgroups[] = { 4288585484eSchristos { "main/", main_testcases }, 4298585484eSchristos { "heap/", minheap_testcases }, 4308585484eSchristos { "et/", edgetriggered_testcases }, 431b8ecfcfeSchristos { "finalize/", finalize_testcases }, 4328585484eSchristos { "evbuffer/", evbuffer_testcases }, 4338585484eSchristos { "signal/", signal_testcases }, 4348585484eSchristos { "util/", util_testcases }, 4358585484eSchristos { "bufferevent/", bufferevent_testcases }, 4368585484eSchristos { "http/", http_testcases }, 4378585484eSchristos { "dns/", dns_testcases }, 4388585484eSchristos { "evtag/", evtag_testcases }, 4398585484eSchristos { "rpc/", rpc_testcases }, 4408585484eSchristos { "thread/", thread_testcases }, 4418585484eSchristos { "listener/", listener_testcases }, 4428585484eSchristos #ifdef _WIN32 4438585484eSchristos { "iocp/", iocp_testcases }, 4448585484eSchristos { "iocp/bufferevent/", bufferevent_iocp_testcases }, 4458585484eSchristos { "iocp/listener/", listener_iocp_testcases }, 446*eabc0478Schristos { "iocp/http/", http_iocp_testcases }, 4478585484eSchristos #endif 4488585484eSchristos #ifdef EVENT__HAVE_OPENSSL 4498585484eSchristos { "ssl/", ssl_testcases }, 4508585484eSchristos #endif 4518585484eSchristos END_OF_GROUPS 4528585484eSchristos }; 4538585484eSchristos 4548585484eSchristos const char *alltests[] = { "+..", NULL }; 4558585484eSchristos const char *livenettests[] = { 4568585484eSchristos "+util/getaddrinfo_live", 4578585484eSchristos "+dns/gethostby..", 4588585484eSchristos "+dns/resolve_reverse", 4598585484eSchristos NULL 4608585484eSchristos }; 4618585484eSchristos const char *finetimetests[] = { 4628585484eSchristos "+util/monotonic_res_precise", 4638585484eSchristos "+util/monotonic_res_fallback", 4648585484eSchristos "+thread/deferred_cb_skew", 465b8ecfcfeSchristos "+http/connection_retry", 466*eabc0478Schristos "+http/https_connection_retry", 4678585484eSchristos NULL 4688585484eSchristos }; 4698585484eSchristos struct testlist_alias_t testaliases[] = { 4708585484eSchristos { "all", alltests }, 4718585484eSchristos { "live_net", livenettests }, 4728585484eSchristos { "fine_timing", finetimetests }, 4738585484eSchristos END_OF_ALIASES 4748585484eSchristos }; 4758585484eSchristos 476b8ecfcfeSchristos int libevent_tests_running_in_debug_mode = 0; 477b8ecfcfeSchristos 4788585484eSchristos int 4798585484eSchristos main(int argc, const char **argv) 4808585484eSchristos { 4818585484eSchristos #ifdef _WIN32 4828585484eSchristos WORD wVersionRequested; 4838585484eSchristos WSADATA wsaData; 4848585484eSchristos 4858585484eSchristos wVersionRequested = MAKEWORD(2, 2); 4868585484eSchristos 4878585484eSchristos (void) WSAStartup(wVersionRequested, &wsaData); 4888585484eSchristos #endif 4898585484eSchristos 4908585484eSchristos #ifndef _WIN32 4918585484eSchristos if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) 4928585484eSchristos return 1; 4938585484eSchristos #endif 4948585484eSchristos 4958585484eSchristos #ifdef _WIN32 4968585484eSchristos tinytest_skip(testgroups, "http/connection_retry"); 497*eabc0478Schristos tinytest_skip(testgroups, "http/https_connection_retry"); 498*eabc0478Schristos tinytest_skip(testgroups, "http/read_on_write_error"); 4998585484eSchristos #endif 5008585484eSchristos 5018585484eSchristos #ifndef EVENT__DISABLE_THREAD_SUPPORT 5028585484eSchristos if (!getenv("EVENT_NO_DEBUG_LOCKS")) 5038585484eSchristos evthread_enable_lock_debugging(); 5048585484eSchristos #endif 5058585484eSchristos 506b8ecfcfeSchristos if (getenv("EVENT_DEBUG_MODE")) { 507b8ecfcfeSchristos event_enable_debug_mode(); 508b8ecfcfeSchristos libevent_tests_running_in_debug_mode = 1; 509b8ecfcfeSchristos } 510b8ecfcfeSchristos if (getenv("EVENT_DEBUG_LOGGING_ALL")) { 511b8ecfcfeSchristos event_enable_debug_logging(EVENT_DBG_ALL); 512b8ecfcfeSchristos } 513b8ecfcfeSchristos 5148585484eSchristos tinytest_set_aliases(testaliases); 5158585484eSchristos 5167476e6e4Schristos evutil_weakrand_seed_(&test_weakrand_state, 0); 5177476e6e4Schristos 518*eabc0478Schristos if (getenv("EVENT_NO_FILE_BUFFERING")) { 519*eabc0478Schristos setbuf(stdout, NULL); 520*eabc0478Schristos setbuf(stderr, NULL); 521*eabc0478Schristos } 522*eabc0478Schristos 5238585484eSchristos if (tinytest_main(argc,argv,testgroups)) 5248585484eSchristos return 1; 5258585484eSchristos 5268585484eSchristos libevent_global_shutdown(); 5278585484eSchristos 5288585484eSchristos return 0; 5298585484eSchristos } 5308585484eSchristos 531