From 05c7174909e975fc7d0ebf9a59bb07160c09d66d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 7 Feb 2008 12:56:00 +0100 Subject: [PATCH] tests: Add a helper routine to wait for a child process and propagate its result correctly. --- dlls/advapi32/tests/security.c | 4 +++- dlls/kernel32/tests/actctx.c | 3 +-- dlls/kernel32/tests/toolhelp.c | 5 +---- dlls/ntdll/tests/exception.c | 3 ++- dlls/ole32/tests/marshal.c | 2 +- dlls/rpcrt4/tests/server.c | 12 ++++-------- dlls/shell32/tests/shellpath.c | 3 +-- dlls/user32/tests/cursoricon.c | 10 +--------- include/wine/test.h | 18 ++++++++++++++++++ 9 files changed, 32 insertions(+), 28 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 6b43cb347db..97b5a85c402 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -1812,8 +1812,10 @@ static void test_process_security(void) ok(CreateProcessA( NULL, buffer, &psa, NULL, FALSE, 0, NULL, NULL, &startup, &info ), "CreateProcess with err:%d\n", GetLastError()); TEST_GRANTED_ACCESS( info.hProcess, PROCESS_ALL_ACCESS ); - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); + winetest_wait_child_process( info.hProcess ); + CloseHandle( info.hProcess ); + CloseHandle( info.hThread ); CloseHandle( event ); HeapFree(GetProcessHeap(), 0, Acl); HeapFree(GetProcessHeap(), 0, SecurityDescriptor); diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index c36396cb84d..8c764647900 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -1097,9 +1097,8 @@ static void run_child_process(void) sprintf(cmdline, "\"%s\" %s manifest1", argv[0], argv[1]); ok(CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) != 0, "Could not create process: %u\n", GetLastError()); + winetest_wait_child_process( pi.hProcess ); CloseHandle(pi.hThread); - - WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); DeleteFileA(path); } diff --git a/dlls/kernel32/tests/toolhelp.c b/dlls/kernel32/tests/toolhelp.c index 3249379802d..aafc9825e88 100644 --- a/dlls/kernel32/tests/toolhelp.c +++ b/dlls/kernel32/tests/toolhelp.c @@ -342,8 +342,5 @@ START_TEST(toolhelp) test_module(info.dwProcessId, sub_expected_modules, NUM_OF(sub_expected_modules)); SetEvent(ev2); - w = WaitForSingleObject(info.hProcess, WAIT_TIME); - ok(w == WAIT_OBJECT_0, "Failed to wait on sub-process termination\n"); - ok(GetExitCodeProcess(info.hProcess, &w), "couldn't get process exit code\n"); - ok(w == WAIT_OBJECT_0, "Sub-Process failed to terminate properly\n"); + winetest_wait_child_process( info.hProcess ); } diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 9bd5678bb37..ae3c84b1b25 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -619,7 +619,7 @@ static void test_debugger(void) if(de.u.CreateProcessInfo.lpBaseOfImage != pNtCurrentTeb()->Peb->ImageBaseAddress) { skip("child process loaded at different address, terminating it\n"); - pNtTerminateProcess(pi.hProcess, 1); + pNtTerminateProcess(pi.hProcess, 0); } } else if (de.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) @@ -710,6 +710,7 @@ static void test_debugger(void) } while (de.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT); + winetest_wait_child_process( pi.hProcess ); ok(CloseHandle(pi.hThread) != 0, "error %u\n", GetLastError()); ok(CloseHandle(pi.hProcess) != 0, "error %u\n", GetLastError()); diff --git a/dlls/ole32/tests/marshal.c b/dlls/ole32/tests/marshal.c index 035a725f96b..c7f79961bcf 100644 --- a/dlls/ole32/tests/marshal.c +++ b/dlls/ole32/tests/marshal.c @@ -2575,7 +2575,7 @@ static void test_local_server(void) quit_event = CreateEvent(NULL, FALSE, FALSE, "Wine COM Test Quit Event"); SetEvent(quit_event); - WaitForSingleObject(process, INFINITE); + winetest_wait_child_process( process ); CloseHandle(quit_event); CloseHandle(process); } diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 425b20b98af..43c3ec2cd11 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -634,25 +634,21 @@ make_cmdline(char buffer[MAX_PATH], const char *test) sprintf(buffer, "%s server %s", progname, test); } -static int +static void run_client(const char *test) { char cmdline[MAX_PATH]; PROCESS_INFORMATION info; STARTUPINFOA startup; - DWORD exitcode; memset(&startup, 0, sizeof startup); startup.cb = sizeof startup; make_cmdline(cmdline, test); ok(CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); - ok(GetExitCodeProcess(info.hProcess, &exitcode), "GetExitCodeProcess\n"); + winetest_wait_child_process( info.hProcess ); ok(CloseHandle(info.hProcess), "CloseHandle\n"); ok(CloseHandle(info.hThread), "CloseHandle\n"); - - return exitcode == 0; } static void @@ -1208,10 +1204,10 @@ server(void) stop_event = CreateEvent(NULL, FALSE, FALSE, NULL); ok(stop_event != NULL, "CreateEvent failed\n"); - ok(run_client("tcp_basic"), "tcp_basic client test failed\n"); + run_client("tcp_basic"); ok(RPC_S_OK == RpcServerUseProtseqEp(np, 0, pipe, NULL), "RpcServerUseProtseqEp\n"); - ok(run_client("np_basic"), "np_basic client test failed\n"); + run_client("np_basic"); ok(WAIT_OBJECT_0 == WaitForSingleObject(stop_event, 60000), "WaitForSingleObject\n"); todo_wine { diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c index 6fb485e178f..ff041c82963 100644 --- a/dlls/shell32/tests/shellpath.c +++ b/dlls/shell32/tests/shellpath.c @@ -864,8 +864,7 @@ static void testNonExistentPath(void) startup.dwFlags = SW_SHOWNORMAL; CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info); - ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, - "child process termination\n"); + winetest_wait_child_process( info.hProcess ); /* Query the path to be able to delete it below */ hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL, diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c index f65aa5e5f90..ca4b1185120 100644 --- a/dlls/user32/tests/cursoricon.c +++ b/dlls/user32/tests/cursoricon.c @@ -167,16 +167,8 @@ static void do_parent(void) static void finish_child_process(void) { - DWORD exit_code; - BOOL ret; - SendMessage(child, WM_CLOSE, 0, 0); - ok(WaitForSingleObject(child_process, 30000) == WAIT_OBJECT_0, "Child process termination failed.\n"); - - ret = GetExitCodeProcess(child_process, &exit_code); - ok(ret, "GetExitCodeProcess() failed. Error: %u\n", GetLastError()); - ok(exit_code == 0, "Exit code == %u.\n", exit_code); - + winetest_wait_child_process( child_process ); CloseHandle(child_process); } diff --git a/include/wine/test.h b/include/wine/test.h index dbce98c4479..32850ceec84 100644 --- a/include/wine/test.h +++ b/include/wine/test.h @@ -57,6 +57,7 @@ extern void winetest_start_todo( const char* platform ); extern int winetest_loop_todo(void); extern void winetest_end_todo( const char* platform ); extern int winetest_get_mainargs( char*** pargv ); +extern void winetest_wait_child_process( HANDLE process ); #ifdef STANDALONE #define START_TEST(name) \ @@ -340,6 +341,23 @@ int winetest_get_mainargs( char*** pargv ) return winetest_argc; } +void winetest_wait_child_process( HANDLE process ) +{ + DWORD exit_code = 1; + + if (WaitForSingleObject( process, 30000 )) + fprintf( stdout, "%s: child process wait failed\n", current_test->name ); + else + GetExitCodeProcess( process, &exit_code ); + + if (exit_code) + { + fprintf( stdout, "%s: %u failures in child process\n", + current_test->name, exit_code ); + InterlockedExchangeAdd( &failures, exit_code ); + } +} + /* Find a test by name */ static const struct test *find_test( const char *name ) {