First MR to begin de-duplicating WineTest helpers.
The idea is to make most helpers static inline, and the counters extern, prefixing any variable moved to the global scope. This will allow dinput / ntoskrnl driver tests to re-use the helpers by only having to provide the counters and an implementation of `winetest_get_thread_data` / `winetest_vprintf` (and a couple of other functions).
Then, it will also be re-usable in WinRT tests for https://gitlab.winehq.org/wine/wine/-/merge_requests/3643.
From: Rémi Bernon rbernon@codeweavers.com
--- include/wine/test.h | 67 +++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 36 deletions(-)
diff --git a/include/wine/test.h b/include/wine/test.h index 73d6d164c46..3bb50ad22cf 100644 --- a/include/wine/test.h +++ b/include/wine/test.h @@ -189,15 +189,15 @@ static char** winetest_argv;
static const struct test *current_test; /* test currently being run */
-static LONG successes; /* number of successful tests */ -static LONG failures; /* number of failures */ -static LONG flaky_failures; /* number of failures inside flaky block */ -static LONG skipped; /* number of skipped test chunks */ -static LONG todo_successes; /* number of successful tests inside todo block */ -static LONG todo_failures; /* number of failures inside todo block */ -static LONG muted_traces; /* number of silenced traces */ -static LONG muted_skipped; /* same as skipped but silent */ -static LONG muted_todo_successes; /* same as todo_successes but silent */ +static LONG winetest_successes; /* number of successful tests */ +static LONG winetest_failures; /* number of failures */ +static LONG winetest_flaky_failures; /* number of failures inside flaky block */ +static LONG winetest_skipped; /* number of skipped test chunks */ +static LONG winetest_todo_successes; /* number of successful tests inside todo block */ +static LONG winetest_todo_failures; /* number of failures inside todo block */ +static LONG winetest_muted_traces; /* number of silenced traces */ +static LONG winetest_muted_skipped; /* same as skipped but silent */ +static LONG winetest_muted_todo_successes; /* same as todo_successes but silent */
/* counts how many times a given line printed a message */ static LONG line_counters[16384]; @@ -376,14 +376,14 @@ int winetest_vok( int condition, const char *msg, va_list args ) if (winetest_color) printf( color_dark_purple ); winetest_print_context( "Test succeeded inside flaky todo block: " ); vprintf(msg, args); - InterlockedIncrement(&flaky_failures); + InterlockedIncrement( &winetest_flaky_failures ); } else { if (winetest_color) printf( color_dark_red ); winetest_print_context( "Test succeeded inside todo block: " ); vprintf(msg, args); - InterlockedIncrement(&todo_failures); + InterlockedIncrement( &winetest_todo_failures ); } if (winetest_color) printf( color_reset ); winetest_print_unlock(); @@ -403,10 +403,9 @@ int winetest_vok( int condition, const char *msg, va_list args ) if (winetest_color) printf( color_reset ); winetest_print_unlock(); } - InterlockedIncrement(&todo_successes); + InterlockedIncrement( &winetest_todo_successes ); } - else - InterlockedIncrement(&muted_todo_successes); + else InterlockedIncrement( &winetest_muted_todo_successes ); return 1; } } @@ -420,14 +419,14 @@ int winetest_vok( int condition, const char *msg, va_list args ) if (winetest_color) printf( color_bright_purple ); winetest_print_context( "Test marked flaky: " ); vprintf(msg, args); - InterlockedIncrement(&flaky_failures); + InterlockedIncrement( &winetest_flaky_failures ); } else { if (winetest_color) printf( color_bright_red ); winetest_print_context( "Test failed: " ); vprintf(msg, args); - InterlockedIncrement(&failures); + InterlockedIncrement( &winetest_failures ); } if (winetest_color) printf( color_reset ); winetest_print_unlock(); @@ -444,7 +443,7 @@ int winetest_vok( int condition, const char *msg, va_list args ) if (winetest_color) printf( color_reset ); winetest_print_unlock(); } - InterlockedIncrement(&successes); + InterlockedIncrement( &winetest_successes ); return 1; } } @@ -474,8 +473,7 @@ void winetest_trace( const char *msg, ... ) va_end(valist); winetest_print_unlock(); } - else - InterlockedIncrement(&muted_traces); + else InterlockedIncrement( &winetest_muted_traces ); }
void winetest_vskip( const char *msg, va_list args ) @@ -488,10 +486,9 @@ void winetest_vskip( const char *msg, va_list args ) vprintf(msg, args); if (winetest_color) printf( color_reset ); winetest_print_unlock(); - InterlockedIncrement(&skipped); + InterlockedIncrement( &winetest_skipped ); } - else - InterlockedIncrement(&muted_skipped); + else InterlockedIncrement( &winetest_muted_skipped ); }
void winetest_skip( const char *msg, ... ) @@ -586,13 +583,12 @@ int winetest_get_mainargs( char*** pargv )
LONG winetest_get_failures(void) { - return failures; + return winetest_failures; }
void winetest_add_failures( LONG new_failures ) { - while (new_failures-- > 0) - InterlockedIncrement( &failures ); + while (new_failures-- > 0) InterlockedIncrement( &winetest_failures ); }
void winetest_wait_child_process( HANDLE process ) @@ -620,15 +616,14 @@ void winetest_wait_child_process( HANDLE process ) winetest_printf( "unhandled exception %08x in child process %04x\n", (UINT)exit_code, (UINT)pid ); if (winetest_color) printf( color_reset ); winetest_print_unlock(); - InterlockedIncrement( &failures ); + InterlockedIncrement( &winetest_failures ); } else if (exit_code) { winetest_print_lock(); winetest_printf( "%u failures in child process\n", (UINT)exit_code ); winetest_print_unlock(); - while (exit_code-- > 0) - InterlockedIncrement(&failures); + while (exit_code-- > 0) InterlockedIncrement( &winetest_failures ); } } } @@ -682,20 +677,20 @@ static int run_test( const char *name ) if (winetest_debug) { winetest_print_lock(); - if (muted_todo_successes || muted_skipped || muted_traces) + if (winetest_muted_todo_successes || winetest_muted_skipped || winetest_muted_traces) printf( "%04x:%s:%s Silenced %d todos, %d skips and %d traces.\n", (UINT)GetCurrentProcessId(), test->name, winetest_elapsed(), - (UINT)muted_todo_successes, (UINT)muted_skipped, (UINT)muted_traces); + (UINT)winetest_muted_todo_successes, (UINT)winetest_muted_skipped, (UINT)winetest_muted_traces); printf( "%04x:%s:%s %d tests executed (%d marked as todo, %d as flaky, %d %s), %d skipped.\n", (UINT)GetCurrentProcessId(), test->name, winetest_elapsed(), - (UINT)(successes + failures + flaky_failures + todo_successes + todo_failures), - (UINT)todo_successes, (UINT)flaky_failures, (UINT)(failures + todo_failures), - (failures + todo_failures != 1) ? "failures" : "failure", - (UINT)skipped ); + (UINT)(winetest_successes + winetest_failures + winetest_flaky_failures + winetest_todo_successes + winetest_todo_failures), + (UINT)winetest_todo_successes, (UINT)winetest_flaky_failures, (UINT)(winetest_failures + winetest_todo_failures), + (winetest_failures + winetest_todo_failures != 1) ? "failures" : "failure", + (UINT)winetest_skipped ); winetest_print_unlock(); } - status = failures + todo_failures; - if (winetest_report_flaky) status += flaky_failures; + status = winetest_failures + winetest_todo_failures; + if (winetest_report_flaky) status += winetest_flaky_failures; if (status > 255) status = 255; return status; }
From: Rémi Bernon rbernon@codeweavers.com
--- include/wine/test.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/include/wine/test.h b/include/wine/test.h index 3bb50ad22cf..88884946e89 100644 --- a/include/wine/test.h +++ b/include/wine/test.h @@ -203,7 +203,7 @@ static LONG winetest_muted_todo_successes; /* same as todo_successes but silent static LONG line_counters[16384];
/* The following data must be kept track of on a per-thread basis */ -struct tls_data +struct winetest_thread_data { const char* current_file; /* file of current check */ int current_line; /* line of current check */ @@ -218,9 +218,9 @@ struct tls_data }; static DWORD tls_index;
-static struct tls_data *get_tls_data(void) +static struct winetest_thread_data *winetest_get_thread_data(void) { - struct tls_data *data; + struct winetest_thread_data *data; DWORD last_error;
last_error=GetLastError(); @@ -244,7 +244,7 @@ static void exit_process( int code )
void winetest_set_location( const char* file, int line ) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); data->current_file=strrchr(file,'/'); if (data->current_file==NULL) data->current_file=strrchr(file,'\'); @@ -276,7 +276,7 @@ static const char color_bright_purple[] = "\x1b[1;95m"; static void winetest_printf( const char *msg, ... ) __WINE_PRINTF_ATTR(1,2); static void winetest_printf( const char *msg, ... ) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); va_list valist;
printf( "%s:%d:%s ", data->current_file, data->current_line, winetest_elapsed() ); @@ -286,7 +286,7 @@ static void winetest_printf( const char *msg, ... ) } static void winetest_print_context( const char *msgtype ) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); unsigned int i;
winetest_printf( "%s", msgtype ); @@ -333,13 +333,13 @@ int broken( int condition )
static LONG winetest_add_line( void ) { - struct tls_data *data; + struct winetest_thread_data *data; int index, count;
if (winetest_debug > 1) return 0;
- data = get_tls_data(); + data = winetest_get_thread_data(); index = data->current_line % ARRAY_SIZE(line_counters); count = InterlockedIncrement(line_counters + index) - 1; if (count == winetest_mute_threshold) @@ -364,7 +364,7 @@ static LONG winetest_add_line( void ) */ int winetest_vok( int condition, const char *msg, va_list args ) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data();
if (data->todo_level) { @@ -512,14 +512,14 @@ void winetest_win_skip( const char *msg, ... )
void winetest_start_flaky( int is_flaky ) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); data->flaky_level = (data->flaky_level << 1) | (is_flaky != 0); data->flaky_do_loop = 1; }
int winetest_loop_flaky(void) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); int do_flaky = data->flaky_do_loop; data->flaky_do_loop = 0; return do_flaky; @@ -527,20 +527,20 @@ int winetest_loop_flaky(void)
void winetest_end_flaky(void) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); data->flaky_level >>= 1; }
void winetest_start_todo( int is_todo ) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); data->todo_level = (data->todo_level << 1) | (is_todo != 0); data->todo_do_loop=1; }
int winetest_loop_todo(void) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); int do_loop=data->todo_do_loop; data->todo_do_loop=0; return do_loop; @@ -548,13 +548,13 @@ int winetest_loop_todo(void)
void winetest_end_todo(void) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); data->todo_level >>= 1; }
void winetest_push_context( const char *fmt, ... ) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data(); va_list valist;
if (data->context_count < ARRAY_SIZE(data->context)) @@ -569,7 +569,7 @@ void winetest_push_context( const char *fmt, ... )
void winetest_pop_context(void) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data();
if (data->context_count) --data->context_count; @@ -707,7 +707,7 @@ static void usage( const char *argv0 ) /* trap unhandled exceptions */ static LONG CALLBACK exc_filter( EXCEPTION_POINTERS *ptrs ) { - struct tls_data *data = get_tls_data(); + struct winetest_thread_data *data = winetest_get_thread_data();
winetest_print_lock(); if (data->current_file)
From: Rémi Bernon rbernon@codeweavers.com
--- include/wine/test.h | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/include/wine/test.h b/include/wine/test.h index 88884946e89..fd8b4619e8e 100644 --- a/include/wine/test.h +++ b/include/wine/test.h @@ -264,14 +264,14 @@ const char *winetest_elapsed(void) return wine_dbg_sprintf( "%.3f", (now - winetest_start_time) / 1000.0); }
-static const char color_reset[] = "\x1b[0m"; -static const char color_dark_red[] = "\x1b[31m"; -static const char color_dark_purple[] = "\x1b[35m"; -static const char color_green[] = "\x1b[32m"; -static const char color_yellow[] = "\x1b[33m"; -static const char color_blue[] = "\x1b[34m"; -static const char color_bright_red[] = "\x1b[1;91m"; -static const char color_bright_purple[] = "\x1b[1;95m"; +static const char winetest_color_reset[] = "\x1b[0m"; +static const char winetest_color_dark_red[] = "\x1b[31m"; +static const char winetest_color_dark_purple[] = "\x1b[35m"; +static const char winetest_color_green[] = "\x1b[32m"; +static const char winetest_color_yellow[] = "\x1b[33m"; +static const char winetest_color_blue[] = "\x1b[34m"; +static const char winetest_color_bright_red[] = "\x1b[1;91m"; +static const char winetest_color_bright_purple[] = "\x1b[1;95m";
static void winetest_printf( const char *msg, ... ) __WINE_PRINTF_ATTR(1,2); static void winetest_printf( const char *msg, ... ) @@ -373,19 +373,19 @@ int winetest_vok( int condition, const char *msg, va_list args ) winetest_print_lock(); if (data->flaky_level) { - if (winetest_color) printf( color_dark_purple ); + if (winetest_color) printf( winetest_color_dark_purple ); winetest_print_context( "Test succeeded inside flaky todo block: " ); vprintf(msg, args); InterlockedIncrement( &winetest_flaky_failures ); } else { - if (winetest_color) printf( color_dark_red ); + if (winetest_color) printf( winetest_color_dark_red ); winetest_print_context( "Test succeeded inside todo block: " ); vprintf(msg, args); InterlockedIncrement( &winetest_todo_failures ); } - if (winetest_color) printf( color_reset ); + if (winetest_color) printf( winetest_color_reset ); winetest_print_unlock(); return 0; } @@ -397,10 +397,10 @@ int winetest_vok( int condition, const char *msg, va_list args ) if (winetest_debug > 0) { winetest_print_lock(); - if (winetest_color) printf( color_yellow ); + if (winetest_color) printf( winetest_color_yellow ); winetest_print_context( "Test marked todo: " ); vprintf(msg, args); - if (winetest_color) printf( color_reset ); + if (winetest_color) printf( winetest_color_reset ); winetest_print_unlock(); } InterlockedIncrement( &winetest_todo_successes ); @@ -416,19 +416,19 @@ int winetest_vok( int condition, const char *msg, va_list args ) winetest_print_lock(); if (data->flaky_level) { - if (winetest_color) printf( color_bright_purple ); + if (winetest_color) printf( winetest_color_bright_purple ); winetest_print_context( "Test marked flaky: " ); vprintf(msg, args); InterlockedIncrement( &winetest_flaky_failures ); } else { - if (winetest_color) printf( color_bright_red ); + if (winetest_color) printf( winetest_color_bright_red ); winetest_print_context( "Test failed: " ); vprintf(msg, args); InterlockedIncrement( &winetest_failures ); } - if (winetest_color) printf( color_reset ); + if (winetest_color) printf( winetest_color_reset ); winetest_print_unlock(); return 0; } @@ -438,9 +438,9 @@ int winetest_vok( int condition, const char *msg, va_list args ) (winetest_time && GetTickCount() >= winetest_last_time + 1000)) { winetest_print_lock(); - if (winetest_color) printf( color_green ); + if (winetest_color) printf( winetest_color_green ); winetest_printf("Test succeeded\n"); - if (winetest_color) printf( color_reset ); + if (winetest_color) printf( winetest_color_reset ); winetest_print_unlock(); } InterlockedIncrement( &winetest_successes ); @@ -481,10 +481,10 @@ void winetest_vskip( const char *msg, va_list args ) if (winetest_add_line() < winetest_mute_threshold) { winetest_print_lock(); - if (winetest_color) printf( color_blue ); + if (winetest_color) printf( winetest_color_blue ); winetest_print_context( "Tests skipped: " ); vprintf(msg, args); - if (winetest_color) printf( color_reset ); + if (winetest_color) printf( winetest_color_reset ); winetest_print_unlock(); InterlockedIncrement( &winetest_skipped ); } @@ -612,9 +612,9 @@ void winetest_wait_child_process( HANDLE process ) { DWORD pid = GetProcessId( process ); winetest_print_lock(); - if (winetest_color) printf( color_bright_red ); + if (winetest_color) printf( winetest_color_bright_red ); winetest_printf( "unhandled exception %08x in child process %04x\n", (UINT)exit_code, (UINT)pid ); - if (winetest_color) printf( color_reset ); + if (winetest_color) printf( winetest_color_reset ); winetest_print_unlock(); InterlockedIncrement( &winetest_failures ); } @@ -713,11 +713,11 @@ static LONG CALLBACK exc_filter( EXCEPTION_POINTERS *ptrs ) if (data->current_file) printf( "%s:%d: this is the last test seen before the exception\n", data->current_file, data->current_line ); - if (winetest_color) printf( color_bright_red ); + if (winetest_color) printf( winetest_color_bright_red ); printf( "%04x:%s:%s unhandled exception %08x at %p\n", (UINT)GetCurrentProcessId(), current_test->name, winetest_elapsed(), (UINT)ptrs->ExceptionRecord->ExceptionCode, ptrs->ExceptionRecord->ExceptionAddress ); - if (winetest_color) printf( color_reset ); + if (winetest_color) printf( winetest_color_reset ); fflush( stdout ); winetest_print_unlock(); return EXCEPTION_EXECUTE_HANDLER;
From: Rémi Bernon rbernon@codeweavers.com
--- include/wine/test.h | 366 ++++++++++++++++++++++---------------------- 1 file changed, 184 insertions(+), 182 deletions(-)
diff --git a/include/wine/test.h b/include/wine/test.h index fd8b4619e8e..723d23cfc02 100644 --- a/include/wine/test.h +++ b/include/wine/test.h @@ -40,6 +40,7 @@ extern int winetest_debug;
/* trace timing information */ extern int winetest_time; +extern DWORD winetest_start_time, winetest_last_time;
/* running in interactive mode? */ extern int winetest_interactive; @@ -56,18 +57,40 @@ extern int winetest_mute_threshold; /* current platform */ extern const char *winetest_platform;
-extern void winetest_set_location( const char* file, int line ); -extern void winetest_subtest( const char* name ); -extern void winetest_ignore_exceptions( BOOL ignore ); -extern void winetest_start_todo( int is_todo ); -extern int winetest_loop_todo(void); -extern void winetest_end_todo(void); -extern void winetest_start_flaky( int is_flaky ); -extern int winetest_loop_flaky(void); -extern void winetest_end_flaky(void); +/* use ANSI escape codes for output coloring */ +extern int winetest_color; + +extern LONG winetest_successes; /* number of successful tests */ +extern LONG winetest_failures; /* number of failures */ +extern LONG winetest_flaky_failures; /* number of failures inside flaky block */ +extern LONG winetest_skipped; /* number of skipped test chunks */ +extern LONG winetest_todo_successes; /* number of successful tests inside todo block */ +extern LONG winetest_todo_failures; /* number of failures inside todo block */ +extern LONG winetest_muted_traces; /* number of silenced traces */ +extern LONG winetest_muted_skipped; /* same as skipped but silent */ +extern LONG winetest_muted_todo_successes; /* same as todo_successes but silent */ + +/* The following data must be kept track of on a per-thread basis */ +struct winetest_thread_data +{ + const char* current_file; /* file of current check */ + int current_line; /* line of current check */ + unsigned int flaky_level; /* current flaky nesting level */ + int flaky_do_loop; + unsigned int todo_level; /* current todo nesting level */ + int todo_do_loop; + char *str_pos; /* position in debug buffer */ + char strings[2000]; /* buffer for debug strings */ + char context[8][128]; /* data to print before messages */ + unsigned int context_count; /* number of context prefixes */ +}; + +extern struct winetest_thread_data *winetest_get_thread_data(void); +extern void winetest_print_lock(void); +extern void winetest_print_unlock(void); +extern const char *winetest_elapsed(void); + extern int winetest_get_mainargs( char*** pargv ); -extern LONG winetest_get_failures(void); -extern void winetest_add_failures( LONG new_failures ); extern void winetest_wait_child_process( HANDLE process );
#ifdef STANDALONE @@ -79,18 +102,6 @@ extern void winetest_wait_child_process( HANDLE process ); #define START_TEST(name) void func_##name(void) #endif
-extern int broken( int condition ); -extern int winetest_vok( int condition, const char *msg, va_list ap ); -extern void winetest_vskip( const char *msg, va_list ap ); - -extern void winetest_ok( int condition, const char *msg, ... ) __WINE_PRINTF_ATTR(2,3); -extern void winetest_skip( const char *msg, ... ) __WINE_PRINTF_ATTR(1,2); -extern void winetest_win_skip( const char *msg, ... ) __WINE_PRINTF_ATTR(1,2); -extern void winetest_trace( const char *msg, ... ) __WINE_PRINTF_ATTR(1,2); - -extern void winetest_push_context( const char *fmt, ... ) __WINE_PRINTF_ATTR(1, 2); -extern void winetest_pop_context(void); - #ifdef WINETEST_NO_LINE_NUMBERS # define subtest_(file, line) (winetest_set_location(file, 0), 0) ? (void)0 : winetest_subtest # define ignore_exceptions_(file, line) (winetest_set_location(file, 0), 0) ? (void)0 : winetest_ignore_exceptions @@ -135,114 +146,7 @@ extern void winetest_pop_context(void); # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif
- -/************************************************************************/ -/* Below is the implementation of the various functions, to be included - * directly into the generated testlist.c file. - * It is done that way so that the dlls can build the test routines with - * different includes or flags if needed. - */ - -#ifdef STANDALONE - -#include <stdio.h> -#include <excpt.h> - -struct test -{ - const char *name; - void (*func)(void); -}; - -extern const struct test winetest_testlist[]; - -/* debug level */ -int winetest_debug = 1; - -/* trace timing information */ -int winetest_time = 0; -DWORD winetest_start_time, winetest_last_time; - -/* interactive mode? */ -int winetest_interactive = 0; - -/* current platform */ -const char *winetest_platform = "windows"; - -/* report failed flaky tests as failures (BOOL) */ -int winetest_report_flaky = 0; - -/* report successful tests (BOOL) */ -int winetest_report_success = 0; - -/* silence todos and skips above this threshold */ -int winetest_mute_threshold = 42; - -/* use ANSI escape codes for output coloring */ -static int winetest_color; - -static HANDLE winetest_mutex; - -/* passing arguments around */ -static int winetest_argc; -static char** winetest_argv; - -static const struct test *current_test; /* test currently being run */ - -static LONG winetest_successes; /* number of successful tests */ -static LONG winetest_failures; /* number of failures */ -static LONG winetest_flaky_failures; /* number of failures inside flaky block */ -static LONG winetest_skipped; /* number of skipped test chunks */ -static LONG winetest_todo_successes; /* number of successful tests inside todo block */ -static LONG winetest_todo_failures; /* number of failures inside todo block */ -static LONG winetest_muted_traces; /* number of silenced traces */ -static LONG winetest_muted_skipped; /* same as skipped but silent */ -static LONG winetest_muted_todo_successes; /* same as todo_successes but silent */ - -/* counts how many times a given line printed a message */ -static LONG line_counters[16384]; - -/* The following data must be kept track of on a per-thread basis */ -struct winetest_thread_data -{ - const char* current_file; /* file of current check */ - int current_line; /* line of current check */ - unsigned int flaky_level; /* current flaky nesting level */ - int flaky_do_loop; - unsigned int todo_level; /* current todo nesting level */ - int todo_do_loop; - char *str_pos; /* position in debug buffer */ - char strings[2000]; /* buffer for debug strings */ - char context[8][128]; /* data to print before messages */ - unsigned int context_count; /* number of context prefixes */ -}; -static DWORD tls_index; - -static struct winetest_thread_data *winetest_get_thread_data(void) -{ - struct winetest_thread_data *data; - DWORD last_error; - - last_error=GetLastError(); - data=TlsGetValue(tls_index); - if (!data) - { - data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)); - data->str_pos = data->strings; - TlsSetValue(tls_index,data); - } - SetLastError(last_error); - return data; -} - -static void exit_process( int code ) -{ - fflush( stdout ); - ExitProcess( code ); -} - - -void winetest_set_location( const char* file, int line ) +static inline void winetest_set_location( const char *file, int line ) { struct winetest_thread_data *data = winetest_get_thread_data(); data->current_file=strrchr(file,'/'); @@ -255,15 +159,6 @@ void winetest_set_location( const char* file, int line ) data->current_line=line; }
-const char *winetest_elapsed(void) -{ - DWORD now; - - if (!winetest_time) return ""; - winetest_last_time = now = GetTickCount(); - return wine_dbg_sprintf( "%.3f", (now - winetest_start_time) / 1000.0); -} - static const char winetest_color_reset[] = "\x1b[0m"; static const char winetest_color_dark_red[] = "\x1b[31m"; static const char winetest_color_dark_purple[] = "\x1b[35m"; @@ -284,6 +179,7 @@ static void winetest_printf( const char *msg, ... ) vprintf( msg, valist ); va_end( valist ); } + static void winetest_print_context( const char *msgtype ) { struct winetest_thread_data *data = winetest_get_thread_data(); @@ -294,45 +190,30 @@ static void winetest_print_context( const char *msgtype ) printf( "%s: ", data->context[i] ); }
-static void winetest_print_lock(void) -{ - UINT ret; - - if (!winetest_mutex) return; - ret = WaitForSingleObject(winetest_mutex, 30000); - if (ret != WAIT_OBJECT_0 && ret != WAIT_ABANDONED) - { - winetest_printf("could not get the print lock: %u\n", ret); - winetest_mutex = 0; - } -} - -static void winetest_print_unlock(void) -{ - if (winetest_mutex) ReleaseMutex(winetest_mutex); -} - -void winetest_subtest( const char* name ) +static inline void winetest_subtest( const char *name ) { winetest_print_lock(); winetest_printf( "Subtest %s\n", name ); winetest_print_unlock(); }
-void winetest_ignore_exceptions( BOOL ignore ) +static inline void winetest_ignore_exceptions( BOOL ignore ) { winetest_print_lock(); winetest_printf( "IgnoreExceptions=%d\n", ignore ? 1 : 0 ); winetest_print_unlock(); }
-int broken( int condition ) +static inline int broken( int condition ) { return (strcmp(winetest_platform, "windows") == 0) && condition; }
static LONG winetest_add_line( void ) { + /* counts how many times a given line printed a message */ + static LONG line_counters[16384]; + struct winetest_thread_data *data; int index, count;
@@ -362,7 +243,7 @@ static LONG winetest_add_line( void ) * Return: * 0 if condition does not have the expected value, 1 otherwise */ -int winetest_vok( int condition, const char *msg, va_list args ) +static int winetest_vok( int condition, const char *msg, va_list args ) { struct winetest_thread_data *data = winetest_get_thread_data();
@@ -449,7 +330,8 @@ int winetest_vok( int condition, const char *msg, va_list args ) } }
-void winetest_ok( int condition, const char *msg, ... ) +static void winetest_ok( int condition, const char *msg, ... ) __WINE_PRINTF_ATTR(2,3); +static inline void winetest_ok( int condition, const char *msg, ... ) { va_list valist;
@@ -458,7 +340,8 @@ void winetest_ok( int condition, const char *msg, ... ) va_end(valist); }
-void winetest_trace( const char *msg, ... ) +static void winetest_trace( const char *msg, ... ) __WINE_PRINTF_ATTR(1,2); +static inline void winetest_trace( const char *msg, ... ) { va_list valist;
@@ -476,7 +359,7 @@ void winetest_trace( const char *msg, ... ) else InterlockedIncrement( &winetest_muted_traces ); }
-void winetest_vskip( const char *msg, va_list args ) +static void winetest_vskip( const char *msg, va_list args ) { if (winetest_add_line() < winetest_mute_threshold) { @@ -491,7 +374,8 @@ void winetest_vskip( const char *msg, va_list args ) else InterlockedIncrement( &winetest_muted_skipped ); }
-void winetest_skip( const char *msg, ... ) +static void winetest_skip( const char *msg, ... ) __WINE_PRINTF_ATTR(1,2); +static inline void winetest_skip( const char *msg, ... ) { va_list valist; va_start(valist, msg); @@ -499,7 +383,8 @@ void winetest_skip( const char *msg, ... ) va_end(valist); }
-void winetest_win_skip( const char *msg, ... ) +static void winetest_win_skip( const char *msg, ... ) __WINE_PRINTF_ATTR(1,2); +static inline void winetest_win_skip( const char *msg, ... ) { va_list valist; va_start(valist, msg); @@ -510,14 +395,14 @@ void winetest_win_skip( const char *msg, ... ) va_end(valist); }
-void winetest_start_flaky( int is_flaky ) +static inline void winetest_start_flaky( int is_flaky ) { struct winetest_thread_data *data = winetest_get_thread_data(); data->flaky_level = (data->flaky_level << 1) | (is_flaky != 0); data->flaky_do_loop = 1; }
-int winetest_loop_flaky(void) +static inline int winetest_loop_flaky(void) { struct winetest_thread_data *data = winetest_get_thread_data(); int do_flaky = data->flaky_do_loop; @@ -525,20 +410,20 @@ int winetest_loop_flaky(void) return do_flaky; }
-void winetest_end_flaky(void) +static inline void winetest_end_flaky(void) { struct winetest_thread_data *data = winetest_get_thread_data(); data->flaky_level >>= 1; }
-void winetest_start_todo( int is_todo ) +static inline void winetest_start_todo( int is_todo ) { struct winetest_thread_data *data = winetest_get_thread_data(); data->todo_level = (data->todo_level << 1) | (is_todo != 0); data->todo_do_loop=1; }
-int winetest_loop_todo(void) +static inline int winetest_loop_todo(void) { struct winetest_thread_data *data = winetest_get_thread_data(); int do_loop=data->todo_do_loop; @@ -546,13 +431,14 @@ int winetest_loop_todo(void) return do_loop; }
-void winetest_end_todo(void) +static inline void winetest_end_todo(void) { struct winetest_thread_data *data = winetest_get_thread_data(); data->todo_level >>= 1; }
-void winetest_push_context( const char *fmt, ... ) +static void winetest_push_context( const char *fmt, ... ) __WINE_PRINTF_ATTR(1, 2); +static inline void winetest_push_context( const char *fmt, ... ) { struct winetest_thread_data *data = winetest_get_thread_data(); va_list valist; @@ -567,7 +453,7 @@ void winetest_push_context( const char *fmt, ... ) ++data->context_count; }
-void winetest_pop_context(void) +static inline void winetest_pop_context(void) { struct winetest_thread_data *data = winetest_get_thread_data();
@@ -575,20 +461,136 @@ void winetest_pop_context(void) --data->context_count; }
-int winetest_get_mainargs( char*** pargv ) +static inline LONG winetest_get_failures(void) { - *pargv = winetest_argv; - return winetest_argc; + return winetest_failures; }
-LONG winetest_get_failures(void) +static inline void winetest_add_failures( LONG new_failures ) { - return winetest_failures; + while (new_failures-- > 0) InterlockedIncrement( &winetest_failures ); }
-void winetest_add_failures( LONG new_failures ) + +/************************************************************************/ +/* Below is the implementation of the various functions, to be included + * directly into the generated testlist.c file. + * It is done that way so that the dlls can build the test routines with + * different includes or flags if needed. + */ + +#ifdef STANDALONE + +#include <stdio.h> +#include <excpt.h> + +struct test { - while (new_failures-- > 0) InterlockedIncrement( &winetest_failures ); + const char *name; + void (*func)(void); +}; + +extern const struct test winetest_testlist[]; + +/* debug level */ +int winetest_debug = 1; + +/* trace timing information */ +int winetest_time = 0; +DWORD winetest_start_time, winetest_last_time; + +/* interactive mode? */ +int winetest_interactive = 0; + +/* current platform */ +const char *winetest_platform = "windows"; + +/* report failed flaky tests as failures (BOOL) */ +int winetest_report_flaky = 0; + +/* report successful tests (BOOL) */ +int winetest_report_success = 0; + +/* silence todos and skips above this threshold */ +int winetest_mute_threshold = 42; + +/* use ANSI escape codes for output coloring */ +int winetest_color; + +static HANDLE winetest_mutex; + +/* passing arguments around */ +static int winetest_argc; +static char** winetest_argv; + +static const struct test *current_test; /* test currently being run */ + +LONG winetest_successes; /* number of successful tests */ +LONG winetest_failures; /* number of failures */ +LONG winetest_flaky_failures; /* number of failures inside flaky block */ +LONG winetest_skipped; /* number of skipped test chunks */ +LONG winetest_todo_successes; /* number of successful tests inside todo block */ +LONG winetest_todo_failures; /* number of failures inside todo block */ +LONG winetest_muted_traces; /* number of silenced traces */ +LONG winetest_muted_skipped; /* same as skipped but silent */ +LONG winetest_muted_todo_successes; /* same as todo_successes but silent */ + +static DWORD tls_index; + +struct winetest_thread_data *winetest_get_thread_data(void) +{ + struct winetest_thread_data *data; + DWORD last_error; + + last_error = GetLastError(); + data = TlsGetValue( tls_index ); + if (!data) + { + data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) ); + data->str_pos = data->strings; + TlsSetValue( tls_index, data ); + } + SetLastError( last_error ); + return data; +} + +static void exit_process( int code ) +{ + fflush( stdout ); + ExitProcess( code ); +} + +const char *winetest_elapsed(void) +{ + DWORD now; + + if (!winetest_time) return ""; + winetest_last_time = now = GetTickCount(); + return wine_dbg_sprintf( "%.3f", (now - winetest_start_time) / 1000.0); +} + +void winetest_print_lock(void) +{ + UINT ret; + + if (!winetest_mutex) return; + ret = WaitForSingleObject( winetest_mutex, 30000 ); + if (ret != WAIT_OBJECT_0 && ret != WAIT_ABANDONED) + { + winetest_printf( "could not get the print lock: %u\n", ret ); + winetest_mutex = 0; + } +} + +void winetest_print_unlock(void) +{ + if (winetest_mutex) ReleaseMutex( winetest_mutex ); +} + +int winetest_get_mainargs( char ***pargv ) +{ + *pargv = winetest_argv; + return winetest_argc; }
void winetest_wait_child_process( HANDLE process )