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