eliminate GCC warning about initialization order
[reactos.git] / reactos / regtests / shared / regtests.h
1 /*
2 * PROJECT: ReactOS kernel
3 * FILE: regtests/shared/regtests.h
4 * PURPOSE: Regression testing
5 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
6 * UPDATE HISTORY:
7 * 06-07-2003 CSH Created
8 */
9 #ifndef __REGTESTS_H
10 #define __REGTESTS_H
11 #include <stdio.h>
12 #include <string.h>
13
14 typedef DWORD (STDCALL _LPTHREAD_START_ROUTINE)(LPVOID lpParameter);
15
16 typedef struct __FILETIME
17 {
18 DWORD dwLowDateTime;
19 DWORD dwHighDateTime;
20 } _FILETIME, *_PFILETIME, *_LPFILETIME;
21
22 extern void SetupOnce();
23
24 #define _SetupOnce() \
25 void SetupOnce()
26
27 /* Valid values for Command parameter of TestRoutine */
28 #define TESTCMD_RUN 0 /* Buffer contains information about what failed */
29 #define TESTCMD_TESTTYPE 1 /* Buffer contains type of test */
30 #define TESTCMD_TESTNAME 2 /* Buffer contains description of test */
31 #define TESTCMD_TIMEOUT 3 /* Buffer contains timeout for test (DWORD, default is 5000 ms) */
32
33 /* Test types */
34 #define TT_NORMAL 0
35
36 /* Valid values for return values of TestRoutine */
37 #define TS_TIMEDOUT ((DWORD)-2)
38 #define TS_EXCEPTION ((DWORD)-1)
39 #define TS_OK 0
40 #define TS_FAILED 1
41
42 extern int _Result;
43 extern char *_Buffer;
44
45 /* Macros to simplify tests */
46 #define _DispatcherTypeTimeout(FunctionName, TestName, TestType, TimeOut) \
47 void \
48 FunctionName(int Command) \
49 { \
50 switch (Command) \
51 { \
52 case TESTCMD_RUN: \
53 RunTest(); \
54 break; \
55 case TESTCMD_TESTTYPE: \
56 *(PDWORD)_Buffer = (DWORD)TestType; \
57 break; \
58 case TESTCMD_TESTNAME: \
59 strcpy(_Buffer, TestName); \
60 break; \
61 case TESTCMD_TIMEOUT: \
62 *(PDWORD)_Buffer = (DWORD)TimeOut; \
63 break; \
64 default: \
65 _Result = TS_FAILED; \
66 break; \
67 } \
68 }
69
70 #define _DispatcherTimeout(FunctionName, TestName, TimeOut) \
71 _DispatcherTypeTimeout(FunctionName, TestName, TT_NORMAL, TimeOut)
72
73 #define _DispatcherType(FunctionName, TestName, TestType) \
74 _DispatcherTypeTimeout(FunctionName, TestName, TestType, 5000)
75
76 #define _Dispatcher(FunctionName, TestName) \
77 _DispatcherTimeout(FunctionName, TestName, 5000)
78
79 static __inline void
80 AppendAssertion(char *message)
81 {
82 if (strlen(_Buffer) != 0)
83 strcat(_Buffer, "\n");
84 strcat(_Buffer, message);
85 _Result = TS_FAILED;
86 }
87
88 #define _AssertTrue(_Condition) \
89 { \
90 if (!(_Condition)) \
91 { \
92 char _message[100]; \
93 sprintf(_message, "Condition was not true at %s:%d", \
94 __FILE__, __LINE__); \
95 AppendAssertion(_message); \
96 } \
97 }
98
99 #define _AssertFalse(_Condition) \
100 { \
101 if (_Condition) \
102 { \
103 char _message[100]; \
104 sprintf(_message, "Condition was not false at %s:%d", \
105 __FILE__, __LINE__); \
106 AppendAssertion(_message); \
107 } \
108 }
109
110 #define _AssertEqualValue(_Expected, _Actual) \
111 { \
112 ULONG __Expected = (ULONG) (_Expected); \
113 ULONG __Actual = (ULONG) (_Actual); \
114 if ((__Expected) != (__Actual)) \
115 { \
116 char _message[100]; \
117 sprintf(_message, "Expected %ld/0x%.08lx was %ld/0x%.08lx at %s:%d", \
118 (__Expected), (__Expected), (__Actual), (__Actual), __FILE__, __LINE__); \
119 AppendAssertion(_message); \
120 } \
121 }
122
123 #define _AssertEqualWideString(_Expected, _Actual) \
124 { \
125 LPWSTR __Expected = (LPWSTR) (_Expected); \
126 LPWSTR __Actual = (LPWSTR) (_Actual); \
127 if (wcscmp((__Expected), (__Actual)) != 0) \
128 { \
129 char _message[100]; \
130 sprintf(_message, "Expected %S was %S at %s:%d", \
131 (__Expected), (__Actual), __FILE__, __LINE__); \
132 AppendAssertion(_message); \
133 } \
134 }
135
136 #define _AssertNotEqualValue(_Expected, _Actual) \
137 { \
138 ULONG __Expected = (ULONG) (_Expected); \
139 ULONG __Actual = (ULONG) (_Actual); \
140 if ((__Expected) == (__Actual)) \
141 { \
142 char _message[100]; \
143 sprintf(_message, "Actual value expected to be different from %ld/0x%.08lx at %s:%d", \
144 (__Expected), (__Expected), __FILE__, __LINE__); \
145 AppendAssertion(_message); \
146 } \
147 }
148
149
150 /*
151 * Test routine prototype
152 * Command - The command to process
153 */
154 typedef void (*TestRoutine)(int Command);
155
156 /*
157 * Test output routine prototype
158 * Buffer - Address of buffer with text to output
159 */
160 typedef void (*TestOutputRoutine)(char *Buffer);
161
162 /*
163 * Test driver entry routine.
164 * OutputRoutine - Output routine.
165 * TestName - If NULL all tests are run. If non-NULL specifies the test to be run
166 */
167 typedef void STDCALL (*TestDriverMain)(TestOutputRoutine OutputRoutine, char *TestName);
168
169 typedef struct __TEST
170 {
171 LIST_ENTRY ListEntry;
172 TestRoutine Routine;
173 } _TEST, *_PTEST;
174
175 extern VOID InitializeTests();
176 extern VOID RegisterTests();
177 extern VOID PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName);
178
179
180 typedef struct __API_DESCRIPTION
181 {
182 PCHAR FileName;
183 PCHAR FunctionName;
184 PCHAR ForwardedFunctionName;
185 PVOID FunctionAddress;
186 PVOID MockFunctionAddress;
187 } _API_DESCRIPTION, *_PAPI_DESCRIPTION;
188
189 extern _API_DESCRIPTION ExternalDependencies[];
190 extern ULONG MaxExternalDependency;
191
192 HANDLE STDCALL
193 _GetModuleHandleA(LPCSTR lpModuleName);
194
195 PVOID STDCALL
196 _GetProcAddress(HANDLE hModule,
197 LPCSTR lpProcName);
198
199 HANDLE STDCALL
200 _LoadLibraryA(LPCSTR lpLibFileName);
201
202 VOID STDCALL
203 _ExitProcess(UINT uExitCode);
204
205 HANDLE STDCALL
206 _CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize,
207 _LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter,
208 DWORD dwCreationFlags, LPDWORD lpThreadId);
209
210 WINBOOL STDCALL
211 _TerminateThread(HANDLE hThread, DWORD dwExitCode);
212
213 DWORD STDCALL
214 _WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
215
216 DWORD STDCALL
217 _GetLastError();
218
219 VOID STDCALL
220 _CloseHandle(HANDLE handle);
221
222 BOOL STDCALL
223 _GetThreadTimes(HANDLE hThread,
224 _LPFILETIME lpCreationTime,
225 _LPFILETIME lpExitTime,
226 _LPFILETIME lpKernelTime,
227 _LPFILETIME lpUserTime);
228
229 BOOL STDCALL
230 _SetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass);
231
232 BOOL STDCALL
233 _SetThreadPriority(HANDLE hThread, int nPriority);
234
235 HANDLE STDCALL
236 _GetCurrentProcess();
237
238 HANDLE STDCALL
239 _GetCurrentThread();
240
241 VOID STDCALL
242 _Sleep(DWORD dwMilliseconds);
243
244
245 static __inline PCHAR
246 FrameworkGetExportedFunctionNameInternal(_PAPI_DESCRIPTION ApiDescription)
247 {
248 if (ApiDescription->ForwardedFunctionName != NULL)
249 {
250 return ApiDescription->ForwardedFunctionName;
251 }
252 else
253 {
254 return ApiDescription->FunctionName;
255 }
256 }
257
258 static __inline PVOID
259 FrameworkGetFunction(_PAPI_DESCRIPTION ApiDescription)
260 {
261 HANDLE hModule;
262 PVOID function = NULL;
263 PCHAR exportedFunctionName;
264
265 exportedFunctionName = FrameworkGetExportedFunctionNameInternal(ApiDescription);
266
267 hModule = _GetModuleHandleA(ApiDescription->FileName);
268 if (hModule != NULL)
269 {
270 function = _GetProcAddress(hModule, exportedFunctionName);
271 }
272 else
273 {
274 hModule = _LoadLibraryA(ApiDescription->FileName);
275 if (hModule != NULL)
276 {
277 function = _GetProcAddress(hModule, exportedFunctionName);
278 //FreeLibrary(hModule);
279 }
280 }
281 return function;
282 }
283
284 static __inline PVOID
285 FrameworkGetHookInternal(ULONG index)
286 {
287 PVOID address;
288 PCHAR exportedFunctionName;
289
290 if (index > MaxExternalDependency)
291 return NULL;
292
293 if (ExternalDependencies[index].MockFunctionAddress != NULL)
294 return ExternalDependencies[index].MockFunctionAddress;
295
296 if (ExternalDependencies[index].FunctionAddress != NULL)
297 return ExternalDependencies[index].FunctionAddress;
298
299 exportedFunctionName = FrameworkGetExportedFunctionNameInternal(&ExternalDependencies[index]);
300
301 printf("Calling function '%s' in DLL '%s'.\n",
302 exportedFunctionName,
303 ExternalDependencies[index].FileName);
304
305 address = FrameworkGetFunction(&ExternalDependencies[index]);
306
307 if (address == NULL)
308 {
309 printf("Function '%s' not found in DLL '%s'.\n",
310 exportedFunctionName,
311 ExternalDependencies[index].FileName);
312 }
313 ExternalDependencies[index].FunctionAddress = address;
314
315 return address;
316 }
317
318
319 static __inline VOID
320 _SetHook(PCHAR name,
321 PVOID address)
322 {
323 _PAPI_DESCRIPTION api;
324 ULONG index;
325
326 for (index = 0; index <= MaxExternalDependency; index++)
327 {
328 api = &ExternalDependencies[index];
329 if (strcmp(api->FunctionName, name) == 0)
330 {
331 api->MockFunctionAddress = address;
332 return;
333 }
334 }
335 }
336
337 typedef struct __HOOK
338 {
339 PCHAR FunctionName;
340 PVOID FunctionAddress;
341 } _HOOK, *_PHOOK;
342
343 static __inline VOID
344 _SetHooks(_PHOOK hookTable)
345 {
346 _PHOOK hook;
347
348 hook = &hookTable[0];
349 while (hook->FunctionName != NULL)
350 {
351 _SetHook(hook->FunctionName,
352 hook->FunctionAddress);
353 hook++;
354 }
355 }
356
357 static __inline VOID
358 _UnsetHooks(_PHOOK hookTable)
359 {
360 _PHOOK hook;
361
362 hook = &hookTable[0];
363 while (hook->FunctionName != NULL)
364 {
365 _SetHook(hook->FunctionName,
366 NULL);
367 hook++;
368 }
369 }
370
371 static __inline VOID
372 _UnsetAllHooks()
373 {
374 _PAPI_DESCRIPTION api;
375 ULONG index;
376
377 for (index = 0; index <= MaxExternalDependency; index++)
378 {
379 api = &ExternalDependencies[index];
380 api->MockFunctionAddress = NULL;
381 }
382 }
383
384 #endif /* __REGTESTS_H */