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