diff options
author | Emil Velikov <emil.l.velikov@gmail.com> | 2014-07-28 23:40:04 +0100 |
---|---|---|
committer | Emil Velikov <emil.l.velikov@gmail.com> | 2014-11-09 22:44:08 +0000 |
commit | 800fa9971cb5c798edbb5915cad8de1022e5e92f (patch) | |
tree | 74b2b4648f75e32690c7a9cfadf642e622af787b | |
parent | 15cb3a4ccae06a71a26f48a9d632b45fe920b1b3 (diff) |
test/gl_basic_test: implement windows version for run_testsuite()
Windows lacks fork, waitid and co. As such create a separate thread
rather than cloning the current process.
The thread itself runs the tests, as such properly annotate the
testsuite_wgl functions' calling convention.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
-rw-r--r-- | include/waffle_test/waffle_test.h | 4 | ||||
-rw-r--r-- | src/waffle_test/wt_main.c | 4 | ||||
-rw-r--r-- | tests/functional/gl_basic_test.c | 62 |
3 files changed, 70 insertions, 0 deletions
diff --git a/include/waffle_test/waffle_test.h b/include/waffle_test/waffle_test.h index aec28e9..32cd2b6 100644 --- a/include/waffle_test/waffle_test.h +++ b/include/waffle_test/waffle_test.h @@ -58,7 +58,11 @@ /// @param test_runners is a list of functions that call TEST_RUN(). The list /// is a null-terminated. /// @return number of failed tests. +#ifdef _WIN32 +int wt_main(int *argc, char **argv, void (__stdcall *test_suites[])(void)); +#else int wt_main(int *argc, char **argv, void (*test_suites[])(void)); +#endif // _WIN32 #define TEST_PASS() wt_test_pass() #define TEST_SKIP() wt_test_skip() diff --git a/src/waffle_test/wt_main.c b/src/waffle_test/wt_main.c index 205c83c..b3e6580 100644 --- a/src/waffle_test/wt_main.c +++ b/src/waffle_test/wt_main.c @@ -27,7 +27,11 @@ #include "priv/wt_runner.h" int +#ifdef _WIN32 +wt_main(int *argc, char **argv, void (__stdcall *test_suites[])(void)) +#else wt_main(int *argc, char **argv, void (*test_suites[])(void)) +#endif // _WIN32 { int num_fail; diff --git a/tests/functional/gl_basic_test.c b/tests/functional/gl_basic_test.c index e7806c7..03692e0 100644 --- a/tests/functional/gl_basic_test.c +++ b/tests/functional/gl_basic_test.c @@ -39,6 +39,8 @@ #include <string.h> #if !defined(_WIN32) #include <unistd.h> +#else +#include <windows.h> #endif #include <sys/types.h> @@ -1086,6 +1088,64 @@ usage_error(void) exit(1); } +#ifdef _WIN32 +static DWORD __stdcall +worker_thread(LPVOID lpParam) +{ + void (__stdcall *testsuite)(void) = lpParam; + void (__stdcall *testsuites[])(void) = {testsuite, 0}; + int argc = 0; + DWORD num_failures = wt_main(&argc, NULL, testsuites); + + return num_failures; +} + +/// Run the testsuite in a separate thread. If the testsuite fails, then exit +/// immediately. +static void +run_testsuite(void (*testsuite)(void)) +{ + HANDLE hThread; + DWORD dwThreadId; + + hThread = CreateThread(NULL, 0, worker_thread, testsuite, 0, &dwThreadId); + if (hThread != NULL) { + // XXX: Add a decent timeout interval + if (WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0) { + DWORD exit_status; + + if (GetExitCodeThread(hThread, &exit_status)) { + // exit_status is number of failures. + if (exit_status == 0) { + // All tests passed. + CloseHandle(hThread); + return; + } + else { + // Some tests failed. Don't run any more tests. + exit(exit_status); + // or exit process ? + } + } + else { + fprintf(stderr, "gl_basic_test: error: get thread exit status" + " failed (%d)\n", GetLastError()); + abort(); + } + } + else { + fprintf(stderr, "gl_basic_test: error: wait for thread failed\n"); + abort(); + } + } + else { + fprintf(stderr, "gl_basic_test: error: CreateThread failed\n"); + abort(); + } +} + +#else + /// Run the testsuite in a separate process. If the testsuite fails, then exit /// immediately. static void @@ -1132,6 +1192,8 @@ run_testsuite(void (*testsuite)(void)) } } +#endif // _WIN32 + int main(int argc, char *argv[]) { |