9e63c0f5545dd6aeadcdf95b7f9b7b66cc87be77
[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 #include <windows.h>
12
13 extern void SetupOnce();
14
15 #define _SetupOnce() \
16 void SetupOnce()
17
18 /* Valid values for Command parameter of TestRoutine */
19 #define TESTCMD_RUN 0 /* Buffer contains information about what failed */
20 #define TESTCMD_TESTNAME 1 /* Buffer contains description of test */
21
22 /* Valid values for return values of TestRoutine */
23 #define TS_EXCEPTION -1
24 #define TS_OK 0
25 #define TS_FAILED 1
26
27 extern int _Result;
28 extern char *_Buffer;
29
30 /* Macros to simplify tests */
31 #define _Dispatcher(FunctionName, TestName) \
32 void \
33 FunctionName(int Command) \
34 { \
35 switch (Command) \
36 { \
37 case TESTCMD_RUN: \
38 RunTest(); \
39 break; \
40 case TESTCMD_TESTNAME: \
41 strcpy(_Buffer, TestName); \
42 break; \
43 default: \
44 _Result = TS_FAILED; \
45 break; \
46 } \
47 }
48
49 static inline void
50 AppendAssertion(char *message)
51 {
52 if (strlen(_Buffer) != 0)
53 strcat(_Buffer, "\n");
54 strcat(_Buffer, message);
55 _Result = TS_FAILED;
56 }
57
58 #define _AssertTrue(_Condition) \
59 { \
60 if (!(_Condition)) \
61 { \
62 char _message[100]; \
63 sprintf(_message, "Condition was not true at %s:%d", \
64 __FILE__, __LINE__); \
65 AppendAssertion(_message); \
66 } \
67 }
68
69 #define _AssertFalse(_Condition) \
70 { \
71 if (_Condition) \
72 { \
73 char _message[100]; \
74 sprintf(_message, "Condition was not false at %s:%d", \
75 __FILE__, __LINE__); \
76 AppendAssertion(_message); \
77 } \
78 }
79
80 #define _AssertEqualValue(_Expected, _Actual) \
81 { \
82 ULONG __Expected = (ULONG) (_Expected); \
83 ULONG __Actual = (ULONG) (_Actual); \
84 if ((__Expected) != (__Actual)) \
85 { \
86 char _message[100]; \
87 sprintf(_message, "Expected %d/0x%.08x was %d/0x%.08x at %s:%d", \
88 (__Expected), (__Expected), (__Actual), (__Actual), __FILE__, __LINE__); \
89 AppendAssertion(_message); \
90 } \
91 }
92
93 #define _AssertEqualWideString(_Expected, _Actual) \
94 { \
95 LPWSTR __Expected = (LPWSTR) (_Expected); \
96 LPWSTR __Actual = (LPWSTR) (_Actual); \
97 if (wcscmp((__Expected), (__Actual)) != 0) \
98 { \
99 char _message[100]; \
100 sprintf(_message, "Expected %S was %S at %s:%d", \
101 (__Expected), (__Actual), __FILE__, __LINE__); \
102 AppendAssertion(_message); \
103 } \
104 }
105
106 #define _AssertNotEqualValue(_Expected, _Actual) \
107 { \
108 ULONG __Expected = (ULONG) (_Excepted); \
109 ULONG __Actual = (ULONG) (_Actual); \
110 if ((__Expected) == (__Actual)) \
111 { \
112 char _message[100]; \
113 sprintf(_message, "Actual value expected to be different from %d/0x%.08x at %s:%d", \
114 (__Expected), (__Expected), __FILE__, __LINE__); \
115 AppendAssertion(_message); \
116 } \
117 }
118
119
120 /*
121 * Test routine prototype
122 * Command - The command to process
123 */
124 typedef void (*TestRoutine)(int Command);
125
126 /*
127 * Test output routine prototype
128 * Buffer - Address of buffer with text to output
129 */
130 typedef void (*TestOutputRoutine)(char *Buffer);
131
132 /*
133 * Test driver entry routine.
134 * OutputRoutine - Output routine.
135 * TestName - If NULL all tests are run. If non-NULL specifies the test to be run
136 */
137 typedef void STDCALL (*TestDriverMain)(TestOutputRoutine OutputRoutine, char *TestName);
138
139 typedef struct _ROS_TEST
140 {
141 LIST_ENTRY ListEntry;
142 TestRoutine Routine;
143 } ROS_TEST, *PROS_TEST;
144
145 extern LIST_ENTRY AllTests;
146
147 extern VOID InitializeTests();
148 extern VOID RegisterTests();
149 extern VOID PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName);
150
151
152 typedef struct _API_DESCRIPTION
153 {
154 PCHAR FileName;
155 PCHAR FunctionName;
156 PCHAR ForwardedFunctionName;
157 PVOID FunctionAddress;
158 PVOID MockFunctionAddress;
159 } API_DESCRIPTION, *PAPI_DESCRIPTION;
160
161 extern API_DESCRIPTION ExternalDependencies[];
162 extern ULONG MaxExternalDependency;
163
164 HMODULE STDCALL
165 _GetModuleHandleA(LPCSTR lpModuleName);
166
167 FARPROC STDCALL
168 _GetProcAddress(HMODULE hModule,
169 LPCSTR lpProcName);
170
171 HINSTANCE STDCALL
172 _LoadLibraryA(LPCSTR lpLibFileName);
173
174 static inline PCHAR
175 FrameworkGetExportedFunctionNameInternal(PAPI_DESCRIPTION ApiDescription)
176 {
177 if (ApiDescription->ForwardedFunctionName != NULL)
178 {
179 return ApiDescription->ForwardedFunctionName;
180 }
181 else
182 {
183 return ApiDescription->FunctionName;
184 }
185 }
186
187 static inline PVOID
188 FrameworkGetFunction(PAPI_DESCRIPTION ApiDescription)
189 {
190 HMODULE hModule;
191 PVOID function;
192 PCHAR exportedFunctionName;
193
194 exportedFunctionName = FrameworkGetExportedFunctionNameInternal(ApiDescription);
195
196 hModule = _GetModuleHandleA(ApiDescription->FileName);
197 if (hModule != NULL)
198 {
199 function = _GetProcAddress(hModule, exportedFunctionName);
200 }
201 else
202 {
203 hModule = _LoadLibraryA(ApiDescription->FileName);
204 if (hModule != NULL)
205 {
206 function = _GetProcAddress(hModule, exportedFunctionName);
207 //FreeLibrary(hModule);
208 }
209 }
210 return function;
211 }
212
213 static inline PVOID
214 FrameworkGetHookInternal(ULONG index)
215 {
216 PVOID address;
217 PCHAR exportedFunctionName;
218
219 if (index > MaxExternalDependency)
220 return NULL;
221
222 if (ExternalDependencies[index].MockFunctionAddress != NULL)
223 return ExternalDependencies[index].MockFunctionAddress;
224
225 if (ExternalDependencies[index].FunctionAddress != NULL)
226 return ExternalDependencies[index].FunctionAddress;
227
228 exportedFunctionName = FrameworkGetExportedFunctionNameInternal(&ExternalDependencies[index]);
229
230 printf("Calling function '%s' in DLL '%s'.\n",
231 exportedFunctionName,
232 ExternalDependencies[index].FileName);
233
234 address = FrameworkGetFunction(&ExternalDependencies[index]);
235
236 if (address == NULL)
237 {
238 printf("Function '%s' not found in DLL '%s'.\n",
239 exportedFunctionName,
240 ExternalDependencies[index].FileName);
241 }
242 ExternalDependencies[index].FunctionAddress = address;
243
244 return address;
245 }
246
247
248 static inline VOID
249 _SetHook(PCHAR name,
250 PVOID address)
251 {
252 PAPI_DESCRIPTION api;
253 ULONG index;
254
255 for (index = 0; index <= MaxExternalDependency; index++)
256 {
257 api = &ExternalDependencies[index];
258 if (strcmp(api->FunctionName, name) == 0)
259 {
260 api->MockFunctionAddress = address;
261 return;
262 }
263 }
264 }
265
266 typedef struct _HOOK
267 {
268 PCHAR FunctionName;
269 PVOID FunctionAddress;
270 } HOOK, *PHOOK;
271
272 static inline VOID
273 _SetHooks(PHOOK hookTable)
274 {
275 PHOOK hook;
276
277 hook = &hookTable[0];
278 while (hook->FunctionName != NULL)
279 {
280 _SetHook(hook->FunctionName,
281 hook->FunctionAddress);
282 hook++;
283 }
284 }
285
286 static inline VOID
287 _UnsetHooks(PHOOK hookTable)
288 {
289 PHOOK hook;
290
291 hook = &hookTable[0];
292 while (hook->FunctionName != NULL)
293 {
294 _SetHook(hook->FunctionName,
295 NULL);
296 hook++;
297 }
298 }
299
300 static inline VOID
301 _UnsetAllHooks()
302 {
303 PAPI_DESCRIPTION api;
304 ULONG index;
305
306 for (index = 0; index <= MaxExternalDependency; index++)
307 {
308 api = &ExternalDependencies[index];
309 api->MockFunctionAddress = NULL;
310 }
311 }