ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

test.h
Go to the documentation of this file.
00001 /*
00002  * Definitions for Wine C unit tests.
00003  *
00004  * Copyright (C) 2002 Alexandre Julliard
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #ifndef __WINE_WINE_TEST_H
00022 #define __WINE_WINE_TEST_H
00023 
00024 #include <stdarg.h>
00025 #include <stdlib.h>
00026 #include <windef.h>
00027 #include <winbase.h>
00028 
00029 #ifdef __WINE_CONFIG_H
00030 #error config.h should not be used in Wine tests
00031 #endif
00032 #ifdef __WINE_WINE_LIBRARY_H
00033 #error wine/library.h should not be used in Wine tests
00034 #endif
00035 #ifdef __WINE_WINE_UNICODE_H
00036 #error wine/unicode.h should not be used in Wine tests
00037 #endif
00038 #ifdef __WINE_WINE_DEBUG_H
00039 #error wine/debug.h should not be used in Wine tests
00040 #endif
00041 
00042 #ifndef INVALID_FILE_ATTRIBUTES
00043 #define INVALID_FILE_ATTRIBUTES  (~0u)
00044 #endif
00045 #ifndef INVALID_SET_FILE_POINTER
00046 #define INVALID_SET_FILE_POINTER (~0u)
00047 #endif
00048 
00049 /* debug level */
00050 extern int winetest_debug;
00051 
00052 /* running in interactive mode? */
00053 extern int winetest_interactive;
00054 
00055 /* current platform */
00056 extern const char *winetest_platform;
00057 
00058 extern void winetest_set_location( const char* file, int line );
00059 extern void winetest_start_todo( const char* platform );
00060 extern int winetest_loop_todo(void);
00061 extern void winetest_end_todo( const char* platform );
00062 extern int winetest_get_mainargs( char*** pargv );
00063 extern void winetest_wait_child_process( HANDLE process );
00064 
00065 extern const char *wine_dbgstr_wn( const WCHAR *str, int n );
00066 static inline const char *wine_dbgstr_w( const WCHAR *s ) { return wine_dbgstr_wn( s, -1 ); }
00067 
00068 /* strcmpW is avaiable for tests compiled under Wine, but not in standalone
00069  * builds under Windows, so we reimplement it under a different name. */
00070 static inline int winetest_strcmpW( const WCHAR *str1, const WCHAR *str2 )
00071 {
00072     while (*str1 && (*str1 == *str2)) { str1++; str2++; }
00073     return *str1 - *str2;
00074 }
00075 
00076 #ifdef STANDALONE
00077 #define START_TEST(name) \
00078   static void func_##name(void); \
00079   const struct test winetest_testlist[] = { { #name, func_##name }, { 0, 0 } }; \
00080   static void func_##name(void)
00081 #else
00082 #define START_TEST(name) void func_##name(void)
00083 #endif
00084 
00085 #if defined(__x86_64__) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
00086 #define __winetest_cdecl __cdecl
00087 #define __winetest_va_list __builtin_ms_va_list
00088 #else
00089 #define __winetest_cdecl
00090 #define __winetest_va_list va_list
00091 #endif
00092 
00093 extern int broken( int condition );
00094 extern int winetest_vok( int condition, const char *msg, __winetest_va_list ap );
00095 extern void winetest_vskip( const char *msg, __winetest_va_list ap );
00096 
00097 #ifdef __GNUC__
00098 
00099 extern void __winetest_cdecl winetest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) ));
00100 extern void __winetest_cdecl winetest_skip( const char *msg, ... ) __attribute__((format (printf,1,2)));
00101 extern void __winetest_cdecl winetest_win_skip( const char *msg, ... ) __attribute__((format (printf,1,2)));
00102 extern void __winetest_cdecl winetest_trace( const char *msg, ... ) __attribute__((format (printf,1,2)));
00103 
00104 #else /* __GNUC__ */
00105 
00106 extern void __winetest_cdecl winetest_ok( int condition, const char *msg, ... );
00107 extern void __winetest_cdecl winetest_skip( const char *msg, ... );
00108 extern void __winetest_cdecl winetest_win_skip( const char *msg, ... );
00109 extern void __winetest_cdecl winetest_trace( const char *msg, ... );
00110 
00111 #endif /* __GNUC__ */
00112 
00113 #define ok_(file, line)       (winetest_set_location(file, line), 0) ? (void)0 : winetest_ok
00114 #define skip_(file, line)     (winetest_set_location(file, line), 0) ? (void)0 : winetest_skip
00115 #define win_skip_(file, line) (winetest_set_location(file, line), 0) ? (void)0 : winetest_win_skip
00116 #define trace_(file, line)    (winetest_set_location(file, line), 0) ? (void)0 : winetest_trace
00117 
00118 #define ok       ok_(__FILE__, __LINE__)
00119 #define skip     skip_(__FILE__, __LINE__)
00120 #define win_skip win_skip_(__FILE__, __LINE__)
00121 #define trace    trace_(__FILE__, __LINE__)
00122 
00123 #define todo(platform) for (winetest_start_todo(platform); \
00124                             winetest_loop_todo(); \
00125                             winetest_end_todo(platform))
00126 #define todo_wine      todo("wine")
00127 
00128 
00129 #ifdef NONAMELESSUNION
00130 # define U(x)  (x).u
00131 # define U1(x) (x).u1
00132 # define U2(x) (x).u2
00133 # define U3(x) (x).u3
00134 # define U4(x) (x).u4
00135 # define U5(x) (x).u5
00136 # define U6(x) (x).u6
00137 # define U7(x) (x).u7
00138 # define U8(x) (x).u8
00139 #else
00140 # define U(x)  (x)
00141 # define U1(x) (x)
00142 # define U2(x) (x)
00143 # define U3(x) (x)
00144 # define U4(x) (x)
00145 # define U5(x) (x)
00146 # define U6(x) (x)
00147 # define U7(x) (x)
00148 # define U8(x) (x)
00149 #endif
00150 
00151 #ifdef NONAMELESSSTRUCT
00152 # define S(x)  (x).s
00153 # define S1(x) (x).s1
00154 # define S2(x) (x).s2
00155 # define S3(x) (x).s3
00156 # define S4(x) (x).s4
00157 # define S5(x) (x).s5
00158 #else
00159 # define S(x)  (x)
00160 # define S1(x) (x)
00161 # define S2(x) (x)
00162 # define S3(x) (x)
00163 # define S4(x) (x)
00164 # define S5(x) (x)
00165 #endif
00166 
00167 
00168 /************************************************************************/
00169 /* Below is the implementation of the various functions, to be included
00170  * directly into the generated testlist.c file.
00171  * It is done that way so that the dlls can build the test routines with
00172  * different includes or flags if needed.
00173  */
00174 
00175 #ifdef STANDALONE
00176 
00177 #include <stdio.h>
00178 
00179 #if defined(__x86_64__) && defined(__GNUC__) && defined(__WINE_USE_MSVCRT)
00180 # define __winetest_va_start(list,arg) __builtin_ms_va_start(list,arg)
00181 # define __winetest_va_end(list) __builtin_ms_va_end(list)
00182 #else
00183 # define __winetest_va_start(list,arg) va_start(list,arg)
00184 # define __winetest_va_end(list) va_end(list)
00185 #endif
00186 
00187 struct test
00188 {
00189     const char *name;
00190     void (*func)(void);
00191 };
00192 
00193 extern const struct test winetest_testlist[];
00194 
00195 /* debug level */
00196 int winetest_debug = 1;
00197 
00198 /* interactive mode? */
00199 int winetest_interactive = 0;
00200 
00201 /* current platform */
00202 const char *winetest_platform = "windows";
00203 
00204 /* report successful tests (BOOL) */
00205 static int report_success = 0;
00206 
00207 /* passing arguments around */
00208 static int winetest_argc;
00209 static char** winetest_argv;
00210 
00211 static const struct test *current_test; /* test currently being run */
00212 
00213 static LONG successes;       /* number of successful tests */
00214 static LONG failures;        /* number of failures */
00215 static LONG skipped;         /* number of skipped test chunks */
00216 static LONG todo_successes;  /* number of successful tests inside todo block */
00217 static LONG todo_failures;   /* number of failures inside todo block */
00218 
00219 /* The following data must be kept track of on a per-thread basis */
00220 typedef struct
00221 {
00222     const char* current_file;        /* file of current check */
00223     int current_line;                /* line of current check */
00224     int todo_level;                  /* current todo nesting level */
00225     int todo_do_loop;
00226     char *str_pos;                   /* position in debug buffer */
00227     char strings[2000];              /* buffer for debug strings */
00228 } tls_data;
00229 static DWORD tls_index;
00230 
00231 static tls_data* get_tls_data(void)
00232 {
00233     tls_data* data;
00234     DWORD last_error;
00235 
00236     last_error=GetLastError();
00237     data=TlsGetValue(tls_index);
00238     if (!data)
00239     {
00240         data=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(tls_data));
00241         data->str_pos = data->strings;
00242         TlsSetValue(tls_index,data);
00243     }
00244     SetLastError(last_error);
00245     return data;
00246 }
00247 
00248 /* allocate some tmp space for a string */
00249 static char *get_temp_buffer( size_t n )
00250 {
00251     tls_data *data = get_tls_data();
00252     char *res = data->str_pos;
00253 
00254     if (res + n >= &data->strings[sizeof(data->strings)]) res = data->strings;
00255     data->str_pos = res + n;
00256     return res;
00257 }
00258 
00259 /* release extra space that we requested in gimme1() */
00260 static void release_temp_buffer( char *ptr, size_t size )
00261 {
00262     tls_data *data = get_tls_data();
00263     data->str_pos = ptr + size;
00264 }
00265 
00266 static void exit_process( int code )
00267 {
00268     fflush( stdout );
00269     ExitProcess( code );
00270 }
00271 
00272 
00273 void winetest_set_location( const char* file, int line )
00274 {
00275     tls_data* data=get_tls_data();
00276     data->current_file=strrchr(file,'/');
00277     if (data->current_file==NULL)
00278         data->current_file=strrchr(file,'\\');
00279     if (data->current_file==NULL)
00280         data->current_file=file;
00281     else
00282         data->current_file++;
00283     data->current_line=line;
00284 }
00285 
00286 int broken( int condition )
00287 {
00288     return (strcmp(winetest_platform, "windows") == 0) && condition;
00289 }
00290 
00291 /*
00292  * Checks condition.
00293  * Parameters:
00294  *   - condition - condition to check;
00295  *   - msg test description;
00296  *   - file - test application source code file name of the check
00297  *   - line - test application source code file line number of the check
00298  * Return:
00299  *   0 if condition does not have the expected value, 1 otherwise
00300  */
00301 int winetest_vok( int condition, const char *msg, __winetest_va_list args )
00302 {
00303     tls_data* data=get_tls_data();
00304 
00305     if (data->todo_level)
00306     {
00307         if (condition)
00308         {
00309             fprintf( stdout, "%s:%d: Test succeeded inside todo block: ",
00310                      data->current_file, data->current_line );
00311             vfprintf(stdout, msg, args);
00312             InterlockedIncrement(&todo_failures);
00313             return 0;
00314         }
00315         else
00316         {
00317             /* show todos even if traces are disabled*/
00318             /*if (winetest_debug > 0)*/
00319             {
00320                 fprintf( stdout, "%s:%d: Test marked todo: ",
00321                          data->current_file, data->current_line );
00322                 vfprintf(stdout, msg, args);
00323             }
00324             InterlockedIncrement(&todo_successes);
00325             return 1;
00326         }
00327     }
00328     else
00329     {
00330         if (!condition)
00331         {
00332             fprintf( stdout, "%s:%d: Test failed: ",
00333                      data->current_file, data->current_line );
00334             vfprintf(stdout, msg, args);
00335             InterlockedIncrement(&failures);
00336             return 0;
00337         }
00338         else
00339         {
00340             if (report_success)
00341                 fprintf( stdout, "%s:%d: Test succeeded\n",
00342                          data->current_file, data->current_line);
00343             InterlockedIncrement(&successes);
00344             return 1;
00345         }
00346     }
00347 }
00348 
00349 void __winetest_cdecl winetest_ok( int condition, const char *msg, ... )
00350 {
00351     __winetest_va_list valist;
00352 
00353     __winetest_va_start(valist, msg);
00354     winetest_vok(condition, msg, valist);
00355     __winetest_va_end(valist);
00356 }
00357 
00358 void __winetest_cdecl winetest_trace( const char *msg, ... )
00359 {
00360     __winetest_va_list valist;
00361     tls_data* data=get_tls_data();
00362 
00363     if (winetest_debug > 0)
00364     {
00365         fprintf( stdout, "%s:%d: ", data->current_file, data->current_line );
00366         __winetest_va_start(valist, msg);
00367         vfprintf(stdout, msg, valist);
00368         __winetest_va_end(valist);
00369     }
00370 }
00371 
00372 void winetest_vskip( const char *msg, __winetest_va_list args )
00373 {
00374     tls_data* data=get_tls_data();
00375 
00376     fprintf( stdout, "%s:%d: Tests skipped: ", data->current_file, data->current_line );
00377     vfprintf(stdout, msg, args);
00378     skipped++;
00379 }
00380 
00381 void __winetest_cdecl winetest_skip( const char *msg, ... )
00382 {
00383     __winetest_va_list valist;
00384     __winetest_va_start(valist, msg);
00385     winetest_vskip(msg, valist);
00386     __winetest_va_end(valist);
00387 }
00388 
00389 void __winetest_cdecl winetest_win_skip( const char *msg, ... )
00390 {
00391     __winetest_va_list valist;
00392     __winetest_va_start(valist, msg);
00393     if (strcmp(winetest_platform, "windows") == 0)
00394         winetest_vskip(msg, valist);
00395     else
00396         winetest_vok(0, msg, valist);
00397     __winetest_va_end(valist);
00398 }
00399 
00400 void winetest_start_todo( const char* platform )
00401 {
00402     tls_data* data=get_tls_data();
00403     if (strcmp(winetest_platform,platform)==0)
00404         data->todo_level++;
00405     data->todo_do_loop=1;
00406 }
00407 
00408 int winetest_loop_todo(void)
00409 {
00410     tls_data* data=get_tls_data();
00411     int do_loop=data->todo_do_loop;
00412     data->todo_do_loop=0;
00413     return do_loop;
00414 }
00415 
00416 void winetest_end_todo( const char* platform )
00417 {
00418     if (strcmp(winetest_platform,platform)==0)
00419     {
00420         tls_data* data=get_tls_data();
00421         data->todo_level--;
00422     }
00423 }
00424 
00425 int winetest_get_mainargs( char*** pargv )
00426 {
00427     *pargv = winetest_argv;
00428     return winetest_argc;
00429 }
00430 
00431 void winetest_wait_child_process( HANDLE process )
00432 {
00433     DWORD exit_code = 1;
00434 
00435     if (WaitForSingleObject( process, 30000 ))
00436         fprintf( stdout, "%s: child process wait failed\n", current_test->name );
00437     else
00438         GetExitCodeProcess( process, &exit_code );
00439 
00440     if (exit_code)
00441     {
00442         if (exit_code > 255)
00443         {
00444             fprintf( stdout, "%s: exception 0x%08x in child process\n", current_test->name, exit_code );
00445             InterlockedIncrement( &failures );
00446         }
00447         else
00448         {
00449             fprintf( stdout, "%s: %u failures in child process\n",
00450                      current_test->name, exit_code );
00451             while (exit_code-- > 0)
00452                 InterlockedIncrement(&failures);
00453         }
00454     }
00455 }
00456 
00457 const char *wine_dbgstr_wn( const WCHAR *str, int n )
00458 {
00459     char *dst, *res;
00460     size_t size;
00461 
00462     if (!((ULONG_PTR)str >> 16))
00463     {
00464         if (!str) return "(null)";
00465         res = get_temp_buffer( 6 );
00466         sprintf( res, "#%04x", LOWORD(str) );
00467         return res;
00468     }
00469     if (n == -1)
00470     {
00471         const WCHAR *end = str;
00472         while (*end) end++;
00473         n = end - str;
00474     }
00475     if (n < 0) n = 0;
00476     size = 12 + min( 300, n * 5 );
00477     dst = res = get_temp_buffer( size );
00478     *dst++ = 'L';
00479     *dst++ = '"';
00480     while (n-- > 0 && dst <= res + size - 10)
00481     {
00482         WCHAR c = *str++;
00483         switch (c)
00484         {
00485         case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
00486         case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
00487         case '\t': *dst++ = '\\'; *dst++ = 't'; break;
00488         case '"':  *dst++ = '\\'; *dst++ = '"'; break;
00489         case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
00490         default:
00491             if (c >= ' ' && c <= 126)
00492                 *dst++ = (char)c;
00493             else
00494             {
00495                 *dst++ = '\\';
00496                 sprintf(dst,"%04x",c);
00497                 dst+=4;
00498             }
00499         }
00500     }
00501     *dst++ = '"';
00502     if (n > 0)
00503     {
00504         *dst++ = '.';
00505         *dst++ = '.';
00506         *dst++ = '.';
00507     }
00508     *dst++ = 0;
00509     release_temp_buffer( res, dst - res );
00510     return res;
00511 }
00512 
00513 /* Find a test by name */
00514 static const struct test *find_test( const char *name )
00515 {
00516     const struct test *test;
00517     const char *p;
00518     size_t len;
00519 
00520     if ((p = strrchr( name, '/' ))) name = p + 1;
00521     if ((p = strrchr( name, '\\' ))) name = p + 1;
00522     len = strlen(name);
00523     if (len > 2 && !strcmp( name + len - 2, ".c" )) len -= 2;
00524 
00525     for (test = winetest_testlist; test->name; test++)
00526     {
00527         if (!strncmp( test->name, name, len ) && !test->name[len]) break;
00528     }
00529     return test->name ? test : NULL;
00530 }
00531 
00532 
00533 /* Display list of valid tests */
00534 static void list_tests(void)
00535 {
00536     const struct test *test;
00537 
00538     fprintf( stdout, "Valid test names:\n" );
00539     for (test = winetest_testlist; test->name; test++) fprintf( stdout, "    %s\n", test->name );
00540 }
00541 
00542 /* Disable false-positive claiming "test" would be NULL-dereferenced */
00543 #if defined(_MSC_VER)
00544 #pragma warning(push)
00545 #pragma warning(disable:28182)
00546 #endif
00547 
00548 /* Run a named test, and return exit status */
00549 static int run_test( const char *name )
00550 {
00551     const struct test *test;
00552     int status;
00553 
00554     if (!(test = find_test( name )))
00555     {
00556         fprintf( stdout, "Fatal: test '%s' does not exist.\n", name );
00557         exit_process(1);
00558     }
00559     successes = failures = todo_successes = todo_failures = 0;
00560     tls_index=TlsAlloc();
00561     current_test = test;
00562     test->func();
00563 
00564     /* show test results even if traces are disabled */
00565     /*if (winetest_debug)*/
00566     {
00567         fprintf( stdout, "%s: %d tests executed (%d marked as todo, %d %s), %d skipped.\n",
00568                  test->name, successes + failures + todo_successes + todo_failures,
00569                  todo_successes, failures + todo_failures,
00570                  (failures + todo_failures != 1) ? "failures" : "failure",
00571                  skipped );
00572     }
00573     status = (failures + todo_failures < 255) ? failures + todo_failures : 255;
00574     return status;
00575 }
00576 
00577 #if defined(_MSC_VER)
00578 #pragma warning(pop)
00579 #endif
00580 
00581 /* Display usage and exit */
00582 static void usage( const char *argv0 )
00583 {
00584     fprintf( stdout, "Usage: %s test_name\n\n", argv0 );
00585     list_tests();
00586     exit_process(1);
00587 }
00588 
00589 
00590 /* main function */
00591 int main( int argc, char **argv )
00592 {
00593     char p[128];
00594 
00595     setvbuf (stdout, NULL, _IONBF, 0);
00596 
00597     winetest_argc = argc;
00598     winetest_argv = argv;
00599 
00600     if (GetEnvironmentVariableA( "WINETEST_PLATFORM", p, sizeof(p) )) winetest_platform = _strdup(p);
00601     if (GetEnvironmentVariableA( "WINETEST_DEBUG", p, sizeof(p) )) winetest_debug = atoi(p);
00602     if (GetEnvironmentVariableA( "WINETEST_INTERACTIVE", p, sizeof(p) )) winetest_interactive = atoi(p);
00603     if (GetEnvironmentVariableA( "WINETEST_REPORT_SUCCESS", p, sizeof(p) )) report_success = atoi(p);
00604 
00605     if (!winetest_interactive) SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX );
00606 
00607     if (!argv[1])
00608     {
00609         if (winetest_testlist[0].name && !winetest_testlist[1].name)  /* only one test */
00610             return run_test( winetest_testlist[0].name );
00611         usage( argv[0] );
00612     }
00613     if (!strcmp( argv[1], "--list" ))
00614     {
00615         list_tests();
00616         return 0;
00617     }
00618     return run_test(argv[1]);
00619 }
00620 
00621 #endif  /* STANDALONE */
00622 
00623 // hack for ntdll winetest (this is defined in excpt.h)
00624 #undef exception_info
00625 
00626 // Some helpful definitions
00627 
00628 #define ok_hex(expression, result) \
00629     { \
00630         int _value = (expression); \
00631         ok(_value == (result), "Wrong value for '%s', expected: " #result " (0x%x), got: 0x%x\n", \
00632            #expression, (int)(result), _value); \
00633     }
00634 
00635 #define ok_dec(expression, result) \
00636     { \
00637         int _value = (expression); \
00638         ok(_value == (result), "Wrong value for '%s', expected: " #result " (%d), got: %d\n", \
00639            #expression, (int)(result), _value); \
00640     }
00641 
00642 #define ok_ptr(expression, result) \
00643     { \
00644         void *_value = (expression); \
00645         ok(_value == (result), "Wrong value for '%s', expected: " #result " (%p), got: %p\n", \
00646            #expression, (void*)(result), _value); \
00647     }
00648 
00649 #define ok_err(error) \
00650     ok(GetLastError() == (error), "Wrong last error. Expected " #error ", got %d\n", (int)GetLastError())
00651 
00652 #define ok_str(x, y) \
00653     ok(strcmp(x, y) == 0, "Wrong string. Expected '%s', got '%s'\n", y, x);
00654 
00655 #define ok_long(expression, result) ok_hex(expression, result)
00656 #define ok_int(expression, result) ok_dec(expression, result)
00657 #define ok_ntstatus(status, expected) ok_hex(status, expected)
00658 #define ok_hdl ok_ptr
00659 
00660 #endif  /* __WINE_WINE_TEST_H */

Generated on Sat May 26 2012 04:32:08 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.