summaryrefslogtreecommitdiff
path: root/test/tinytest.c
diff options
context:
space:
mode:
authorAzat Khuzhin <azat@libevent.org>2020-07-05 15:01:34 +0300
committerAzat Khuzhin <azat@libevent.org>2020-07-05 15:02:46 +0300
commit5df3037d10556bfcb675bc73e516978b75fc7bc7 (patch)
tree9b59b8aec360426931f641d0e58fe57d2e442bad /test/tinytest.c
parent4c908dde58ef780eeefcc9df4db3063ca62ea862 (diff)
parent1324a03c125faa9404c91dbecec540a681a97367 (diff)
downloadlibevent-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.c125
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