user32/tests: Add a number of tests for WaitForInputIdle.

With help from Dmitry Timoshkov.
This commit is contained in:
Alexandre Julliard 2009-12-15 13:10:53 +01:00
parent 6c253bb143
commit d6dfcf94b0
1 changed files with 239 additions and 0 deletions

View File

@ -12014,11 +12014,249 @@ static void test_PostMessage(void)
flush_events();
}
static const struct
{
DWORD exp, broken;
BOOL todo;
} wait_idle_expect[] =
{
/* 0 */ { WAIT_TIMEOUT, WAIT_TIMEOUT, FALSE },
{ WAIT_TIMEOUT, 0, FALSE },
{ WAIT_TIMEOUT, 0, FALSE },
{ WAIT_TIMEOUT, WAIT_TIMEOUT, TRUE },
{ WAIT_TIMEOUT, WAIT_TIMEOUT, FALSE },
/* 5 */ { WAIT_TIMEOUT, 0, FALSE },
{ WAIT_TIMEOUT, 0, FALSE },
{ WAIT_TIMEOUT, WAIT_TIMEOUT, FALSE },
{ 0, 0, FALSE },
{ 0, 0, FALSE },
/* 10 */ { 0, 0, FALSE },
{ 0, 0, FALSE },
{ 0, WAIT_FAILED, FALSE },
};
static void do_wait_idle_child( int arg )
{
WNDCLASS cls;
MSG msg;
HWND hwnd = 0;
HANDLE start_event = OpenEventA( EVENT_ALL_ACCESS, FALSE, "test_WaitForInputIdle_start" );
HANDLE end_event = OpenEventA( EVENT_ALL_ACCESS, FALSE, "test_WaitForInputIdle_end" );
memset( &cls, 0, sizeof(cls) );
cls.lpfnWndProc = DefWindowProc;
cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
cls.hCursor = LoadCursor(0, IDC_ARROW);
cls.lpszClassName = "TestClass";
RegisterClass( &cls );
PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ); /* create the msg queue */
ok( start_event != 0, "failed to create start event, error %u\n", GetLastError() );
ok( end_event != 0, "failed to create end event, error %u\n", GetLastError() );
switch (arg)
{
case 0:
SetEvent( start_event );
break;
case 1:
SetEvent( start_event );
Sleep( 200 );
PeekMessage( &msg, 0, 0, 0, PM_REMOVE );
break;
case 2:
SetEvent( start_event );
Sleep( 200 );
PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
PostThreadMessage( GetCurrentThreadId(), WM_COMMAND, 0x1234, 0xabcd );
PeekMessage( &msg, 0, 0, 0, PM_REMOVE );
break;
case 3:
SetEvent( start_event );
Sleep( 200 );
SendMessage( HWND_BROADCAST, WM_WININICHANGE, 0, 0 );
break;
case 4:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessage( &msg );
break;
case 5:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
break;
case 6:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
while (PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ))
{
GetMessage( &msg, 0, 0, 0 );
DispatchMessage( &msg );
}
break;
case 7:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
SetTimer( hwnd, 3, 1, NULL );
Sleep( 1000 );
while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessage( &msg );
break;
case 8:
SetEvent( start_event );
Sleep( 200 );
PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT );
break;
case 9:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
for (;;) GetMessage( &msg, 0, 0, 0 );
break;
case 10:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
SetTimer( hwnd, 3, 1, NULL );
Sleep( 200 );
while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
break;
case 11:
SetEvent( start_event );
Sleep( 200 );
return; /* exiting the process makes WaitForInputIdle return success too */
case 12:
PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
Sleep( 200 );
MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT );
SetEvent( start_event );
break;
}
WaitForSingleObject( end_event, 2000 );
CloseHandle( start_event );
CloseHandle( end_event );
if (hwnd) DestroyWindow( hwnd );
}
static LRESULT CALLBACK wait_idle_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
if (msg == WM_WININICHANGE) Sleep( 200 ); /* make sure the child waits */
return DefWindowProcA( hwnd, msg, wp, lp );
}
static DWORD CALLBACK wait_idle_thread( void *arg )
{
WNDCLASS cls;
MSG msg;
HWND hwnd;
memset( &cls, 0, sizeof(cls) );
cls.lpfnWndProc = wait_idle_proc;
cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
cls.hCursor = LoadCursor(0, IDC_ARROW);
cls.lpszClassName = "TestClass";
RegisterClass( &cls );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL);
while (GetMessage( &msg, 0, 0, 0 )) DispatchMessage( &msg );
return 0;
}
static void test_WaitForInputIdle( char *argv0 )
{
char path[MAX_PATH];
PROCESS_INFORMATION pi;
STARTUPINFOA startup;
BOOL ret;
HANDLE start_event, end_event, thread;
unsigned int i;
DWORD id;
const IMAGE_DOS_HEADER *dos = (const IMAGE_DOS_HEADER *)GetModuleHandleA(0);
const IMAGE_NT_HEADERS *nt = (const IMAGE_NT_HEADERS *)((const char *)dos + dos->e_lfanew);
BOOL console_app = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_GUI);
if (console_app) /* build the test with -mwindows for better coverage */
trace( "not built as a GUI app, WaitForInputIdle may not be fully tested\n" );
start_event = CreateEventA(NULL, 0, 0, "test_WaitForInputIdle_start");
end_event = CreateEventA(NULL, 0, 0, "test_WaitForInputIdle_end");
ok(start_event != 0, "failed to create start event, error %u\n", GetLastError());
ok(end_event != 0, "failed to create end event, error %u\n", GetLastError());
memset( &startup, 0, sizeof(startup) );
startup.cb = sizeof(startup);
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = SW_SHOWNORMAL;
thread = CreateThread( NULL, 0, wait_idle_thread, NULL, 0, &id );
for (i = 0; i < sizeof(wait_idle_expect)/sizeof(wait_idle_expect[0]); i++)
{
sprintf( path, "%s msg %u", argv0, i );
ret = CreateProcessA( NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &pi );
ok( ret, "CreateProcess '%s' failed err %u.\n", path, GetLastError() );
if (ret)
{
ret = WaitForSingleObject( start_event, 5000 );
ok( ret == WAIT_OBJECT_0, "%u: WaitForSingleObject failed\n", i );
if (ret == WAIT_OBJECT_0)
{
ret = WaitForInputIdle( pi.hProcess, 1000 );
if (ret == WAIT_FAILED)
ok( console_app ||
ret == wait_idle_expect[i].exp ||
broken(ret == wait_idle_expect[i].broken),
"%u: WaitForInputIdle error %08x expected %08x\n",
i, ret, wait_idle_expect[i].exp );
else if (wait_idle_expect[i].todo)
todo_wine
ok( ret == wait_idle_expect[i].exp || broken(ret == wait_idle_expect[i].broken),
"%u: WaitForInputIdle error %08x expected %08x\n",
i, ret, wait_idle_expect[i].exp );
else
ok( ret == wait_idle_expect[i].exp || broken(ret == wait_idle_expect[i].broken),
"%u: WaitForInputIdle error %08x expected %08x\n",
i, ret, wait_idle_expect[i].exp );
SetEvent( end_event );
WaitForSingleObject( pi.hProcess, 1000 ); /* give it a chance to exit on its own */
}
TerminateProcess( pi.hProcess, 0 ); /* just in case */
winetest_wait_child_process( pi.hProcess );
ret = WaitForInputIdle( pi.hProcess, 100 );
ok( ret == WAIT_FAILED, "%u: WaitForInputIdle after exit error %08x\n", i, ret );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
}
CloseHandle( start_event );
PostThreadMessage( id, WM_QUIT, 0, 0 );
WaitForSingleObject( thread, 10000 );
CloseHandle( thread );
}
START_TEST(msg)
{
char **test_argv;
BOOL ret;
BOOL (WINAPI *pIsWinEventHookInstalled)(DWORD)= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
int argc = winetest_get_mainargs( &test_argv );
if (argc >= 3)
{
unsigned int arg;
/* Child process. */
sscanf (test_argv[2], "%d", (unsigned int *) &arg);
do_wait_idle_child( arg );
return;
}
init_procs();
if (!RegisterWindowClasses()) assert(0);
@ -12059,6 +12297,7 @@ START_TEST(msg)
test_ShowWindow();
test_PeekMessage();
test_PeekMessage2();
test_WaitForInputIdle( test_argv[0] );
test_scrollwindowex();
test_messages();
test_setwindowpos();