diff options
author | Azat Khuzhin <azat@libevent.org> | 2020-07-05 15:01:34 +0300 |
---|---|---|
committer | Azat Khuzhin <azat@libevent.org> | 2020-07-05 15:02:46 +0300 |
commit | 5df3037d10556bfcb675bc73e516978b75fc7bc7 (patch) | |
tree | 9b59b8aec360426931f641d0e58fe57d2e442bad /test/tinytest.c | |
parent | 4c908dde58ef780eeefcc9df4db3063ca62ea862 (diff) | |
parent | 1324a03c125faa9404c91dbecec540a681a97367 (diff) | |
download | libevent-5df3037d10556bfcb675bc73e516978b75fc7bc7.tar.gz |
Merge branch 'release-2.1.12-stable-pull' into patches-2.1release-2.1.12-stablepatches-2.1
PR: https://github.com/libevent/libevent/pull/1045
* release-2.1.12-stable-pull:
Update ChangeLog
ci/linux: create dist artifact only if dist archive was built
Merge branch 'fix-signal-leak'
test: fix leak in dns/getaddrinfo_cancel_stress
test: fix UB in evbuffer/empty_reference_prepend_buffer
ci: set build type to debug with sanitizers
test: really disable bufferevent_pair_release_lock under ASAN (and fix gcc)
test-closed: fix leak
test-export: adjust libevent version
cmake: set rpath for libraries on linux
test-export: compatible with all versions of visual studio
Bump version to 2.1.12-stable (w/o ABI breakage)
ci: run ABI for release-*-pull branches too
Purge travis-ci config
Purge appveyor config
Bump ChangeLog for 2.1.12
Update AUTHORS for 2.1.12
Backport github actions to 2.1
test: add getaddrinfo(AI_ADDRCONFIG) test (off by default)
build: remove duplicate -Wredundant-decls
test: fix memory leaks for https (add BEV_OPT_CLOSE_ON_FREE)
test: "fix" (with a quirk) leak in ssl/bufferevent_wm (w/o defer callbacks)
test: disable bufferevent/bufferevent_pair_release_lock under ASAN (too tricky)
test: detect test failures if atexit handler calls _exit(!0) (sanitizers)
Make all classes Entry, Struct, etc) new-style classes
buffer: do not pass NULL to memcpy() from evbuffer_pullup()
test: do not pass NULL to memcmp() in evbuffer_datacmp() helper
http: fix undefined-shift in EVUTIL_IS*_ helpers
Check error code of evhttp_add_header_internal() in evhttp_parse_query_impl()
cmake: avoid problems from use of CMAKE_USE_PTHREADS_INIT
test/regress_testutils: use inet_addr()
remove FindGit.cmake, improve `git describe` command
checkpatch.sh: fix clang-format-diff usage
checkpatch.sh: fix usage
Fix clang-format-diff usage
variable redefinition in win32_dispatch
test: http/autofree_connection cleanup
http: fix EVHTTP_CON_AUTOFREE in case of timeout (and some else)
test: cleanup http/autofree_connection
test: fix http/autofree_connection
evdns: Add additional validation for values of dns options
test: Fix test_simpleclose for Windows platform
abi-check: abi-monitor 1.10 does not support -make -j8 (1.12 supports though)
Add API/ABI checker (using LVC)
Update list of cmake files for autotools dist archive
Pass --quiet to the event_rcpgen.py (autotools already does this)
There is typo in GetAdaptersAddresses windows library. It should be iphlpapi.dll
Support EV_CLOSED on linux for poll(2)
Fix EV_CLOSED detection/reporting (epoll only)
Merge branch 'EV_CLOSED-and-EV_ET-fixes'
bufferevent: allow setting priority on socket and openssl type
cmake: set a default value for LIBEVENT_STATIC_LINK
evutil_time: improve evutil_gettimeofday on Windows
bench: Allow backend method selection
cmake: missing test-closed binary
Merge branch 'event_rpcgen.py-cleanup'
cmake: replace CheckFunctionExists with CheckSymbolExists
LibeventConfig.cmake: restore CMAKE_FIND_LIBRARY_SUFFIXES and LIBEVENT_STATIC_LINK default
cmake: fix getaddrinfo checking error
cmake: remove CheckFunctionExistsEx
autoconf: fix getaddrinfo checking errors on mingw
test-time: do not use deprecated API
test-time: enable debug mode if EVENT_DEBUG_LOGGING_ALL env set
increase segment refcnt only if evbuffer_add_file_segment() succeeds
evdns: fix a crash when evdns_base with waiting requests is freed
event_base_once: fix potential null pointer threat
test-ratelim: add missing free
Do not use shared global structures on CYGWIN
test: move thread into realtime class even on EVENT__DISABLE_THREAD_SUPPORT
test: fix compilation without thread support (EVENT__DISABLE_THREAD_SUPPORT=ON)
test: fix bufferevent/bufferevent_connect_fail_eventcb* under osx/freebsd
test: fix dst thread in move_pthread_to_realtime_scheduling_class (osx)
test: fix compilation under win32 (rearrange thread_setup() code)
test: use THREAD_* wrappers over pthread* in del_notify
Merge branch 'osx-clock'
cmake: do not print used method (EVENT_SHOW_METHOD) while running tests
cmake: run regress test quietly like autotools (makes CI logs cleaner)
Merge branch 'http-connect'
http: do not assume body for CONNECT
Added uninstall target check to cmakelists
Fix compilation without OPENSSL_API_COMPAT
evutil_time: Implements usleep() using wait funtion on Windows
Initialize variable to 0 replace use memset function in sample/hello-world.c
cmake: set CMAKE_{RUNTIME,LIBRARY,ARCHIVE}_OUTPUT_DIRECTORY they are not defined
cmake: use CMAKE_LIBRARY_OUTPUT_DIRECTORY for the final shared library symlink
test-ratelim: calculate timers bias (for slow CPUs) to avoid false-positive
mailmap: add name/email aliases for yuangongji (name and email)
cmake: test for find_package()
cmake: improve package config file
Link with iphlpapi only on windows
Parse IPv6 scope IDs.
Relax bufferevent_connect_hostname_emfile
autotools: fails build when need but can not find openssl
cmake: eliminate duplicate installation of public headers
append to CMAKE_MODULE_PATH
Do not use sysctl.h on linux (it had been deprecated)
sample/https-client: link crypt32 explicitly when build with mingw-w64
Fix compat with NetBSD >= 10
Avoid transforming base C_FLAGS set deliberately
tinytest: support timeout on Windows
Merge branch 'upstream/pr/899' (evbuffer_freeze testcase enhancements)
evbuffer_add_file: fix freeing of segment in the error path
evutil_time: detect and use _gmtime64_s()/_gmtime64()
http: rename bind_socket_ai() to create_bind_socket_nonblock()
https-client: load certificates from the system cert store on Windows
Fix checking return value of the evdns_base_resolv_conf_parse()
cmake: fix getrandom() detection
arc4random: replace sysctl() with getrandom (on linux)
Upgrade autoconf (after upgrading minimum required to 2.67)
Revert "Warn if forked from the event loop during event_reinit()"
eliminate some C4267 warnings in Windows
autotools: attach doxygen target into all target
cmake: attach doxygen target into all target
Fix memory corruption in EV_CLOSURE_EVENT_FINALIZE with debug enabled
test: prevent duplicate event_enable_debug_mode() for TT_ENABLE_DEBUG_MODE
test: introduce TT_ENABLE_DEBUG_MODE flag
sample/http-server: fix parameter parsing
sample/signal-test: fix use of uninitialized variable
Fix typos in comments (sample/test/event-internal.h)
sample/signal-test: add NULL checks
Change the minimum version of automake to 1.13 and autoconf to 2.67
Add Uninstall.cmake.in into dist archive
Diffstat (limited to 'test/tinytest.c')
-rw-r--r-- | test/tinytest.c | 125 |
1 files changed, 92 insertions, 33 deletions
diff --git a/test/tinytest.c b/test/tinytest.c index a94fb9d4..85dfe74a 100644 --- a/test/tinytest.c +++ b/test/tinytest.c @@ -60,12 +60,8 @@ #include "tinytest_macros.h" #define LONGEST_TEST_NAME 16384 - -#ifndef _WIN32 #define DEFAULT_TESTCASE_TIMEOUT 30U -#else -#define DEFAULT_TESTCASE_TIMEOUT 0U -#endif +#define MAGIC_EXITCODE 42 static int in_tinytest_main = 0; /**< true if we're in tinytest_main().*/ static int n_ok = 0; /**< Number of tests that have passed */ @@ -86,33 +82,73 @@ const char *cur_test_prefix = NULL; /**< prefix of the current test group */ /** Name of the current test, if we haven't logged is yet. Used for --quiet */ const char *cur_test_name = NULL; +static void usage(struct testgroup_t *groups, int list_groups) + __attribute__((noreturn)); +static int process_test_option(struct testgroup_t *groups, const char *test); + #ifdef _WIN32 /* Copy of argv[0] for win32. */ static char commandname[MAX_PATH+1]; -#endif -static void usage(struct testgroup_t *groups, int list_groups) - __attribute__((noreturn)); -static int process_test_option(struct testgroup_t *groups, const char *test); +struct timeout_thread_args { + const testcase_fn *fn; + void *env; +}; +static DWORD WINAPI +timeout_thread_proc_(LPVOID arg) +{ + struct timeout_thread_args *args = arg; + (*(args->fn))(args->env); + ExitThread(cur_test_outcome == FAIL ? 1 : 0); +} + +static enum outcome +testcase_run_in_thread_(const struct testcase_t *testcase, void *env) +{ + /* We will never run testcase in a new thread when the + timeout is set to zero */ + assert(opt_timeout); + DWORD ret, tid; + HANDLE handle; + struct timeout_thread_args args = { + &(testcase->fn), + env + }; + + handle =CreateThread(NULL, 0, timeout_thread_proc_, + (LPVOID)&args, 0, &tid); + ret = WaitForSingleObject(handle, opt_timeout * 1000U); + if (ret == WAIT_OBJECT_0) { + ret = 0; + if (!GetExitCodeThread(handle, &ret)) { + printf("GetExitCodeThread failed\n"); + ret = 1; + } + } else if (ret == WAIT_TIMEOUT) { + printf("timeout\n"); + } else { + printf("Wait failed\n"); + } + CloseHandle(handle); + if (ret == 0) + return OK; + else if (ret == MAGIC_EXITCODE) + return SKIP; + else + return FAIL; +} +#else static unsigned int testcase_set_timeout_(void) { - if (!opt_timeout) - return 0; -#ifndef _WIN32 return alarm(opt_timeout); -#else - /** TODO: win32 support */ - fprintf(stderr, "You cannot set alarm on windows\n"); - exit(1); -#endif } + static unsigned int testcase_reset_timeout_(void) { -#ifndef _WIN32 return alarm(0); -#endif } +#endif static enum outcome testcase_run_bare_(const struct testcase_t *testcase) @@ -129,9 +165,17 @@ testcase_run_bare_(const struct testcase_t *testcase) cur_test_outcome = OK; { - testcase_set_timeout_(); - testcase->fn(env); - testcase_reset_timeout_(); + if (opt_timeout) { +#ifdef _WIN32 + cur_test_outcome = testcase_run_in_thread_(testcase, env); +#else + testcase_set_timeout_(); + testcase->fn(env); + testcase_reset_timeout_(); +#endif + } else { + testcase->fn(env); + } } outcome = cur_test_outcome; @@ -143,7 +187,6 @@ testcase_run_bare_(const struct testcase_t *testcase) return outcome; } -#define MAGIC_EXITCODE 42 #ifndef NO_FORKING @@ -164,7 +207,7 @@ testcase_run_forked_(const struct testgroup_t *group, char buffer[LONGEST_TEST_NAME+256]; STARTUPINFOA si; PROCESS_INFORMATION info; - DWORD exitcode; + DWORD ret; if (!in_tinytest_main) { printf("\nERROR. On Windows, testcase_run_forked_ must be" @@ -174,7 +217,7 @@ testcase_run_forked_(const struct testgroup_t *group, if (opt_verbosity>0) printf("[forking] "); - snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", + snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s --timeout 0 %s%s", commandname, verbosity_flag, group->prefix, testcase->name); memset(&si, 0, sizeof(si)); @@ -185,15 +228,23 @@ testcase_run_forked_(const struct testgroup_t *group, 0, NULL, NULL, &si, &info); if (!ok) { printf("CreateProcess failed!\n"); - return 0; + return FAIL; + } + ret = WaitForSingleObject(info.hProcess, + (opt_timeout ? opt_timeout * 1000U : INFINITE)); + + if (ret == WAIT_OBJECT_0) { + GetExitCodeProcess(info.hProcess, &ret); + } else if (ret == WAIT_TIMEOUT) { + printf("timeout\n"); + } else { + printf("Wait failed\n"); } - WaitForSingleObject(info.hProcess, INFINITE); - GetExitCodeProcess(info.hProcess, &exitcode); CloseHandle(info.hProcess); CloseHandle(info.hThread); - if (exitcode == 0) + if (ret == 0) return OK; - else if (exitcode == MAGIC_EXITCODE) + else if (ret == MAGIC_EXITCODE) return SKIP; else return FAIL; @@ -228,7 +279,7 @@ testcase_run_forked_(const struct testgroup_t *group, return FAIL; /* unreachable */ } else { /* parent */ - int status, r; + int status, r, exitcode; char b[1]; /* Close this now, so that if the other side closes it, * our read fails. */ @@ -236,12 +287,20 @@ testcase_run_forked_(const struct testgroup_t *group, r = (int)read(outcome_pipe[0], b, 1); if (r == 0) { printf("[Lost connection!] "); - return 0; + return FAIL; } else if (r != 1) { perror("read outcome from pipe"); } waitpid(pid, &status, 0); + exitcode = WEXITSTATUS(status); close(outcome_pipe[0]); + if (opt_verbosity>1) + printf("%s%s: exited with %i (%i)\n", group->prefix, testcase->name, exitcode, status); + if (exitcode != 0) + { + printf("[atexit failure!] "); + return FAIL; + } return b[0]=='Y' ? OK : (b[0]=='S' ? SKIP : FAIL); } #endif @@ -520,7 +579,7 @@ tinytest_set_test_failed_(void) printf("%s%s: ", cur_test_prefix, cur_test_name); cur_test_name = NULL; } - cur_test_outcome = 0; + cur_test_outcome = FAIL; } void |