2 * PROJECT: ReactOS kernel
3 * FILE: regtests/shared/regtests.c
4 * PURPOSE: Regression testing framework
5 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * 06-07-2003 CSH Created
9 #define WIN32_NO_STATUS
11 #define NTOS_MODE_USER
12 #include <ndk/ntndk.h>
13 #include <pseh/pseh.h>
19 typedef struct _PERFORM_TEST_ARGS
21 TestOutputRoutine OutputRoutine
;
32 static LIST_ENTRY AllTests
;
37 InitializeListHead(&AllTests
);
41 FormatExecutionTime(char *buffer
, ULONG milliseconds
)
50 PerformTest(PVOID _arg
)
52 PERFORM_TEST_ARGS
*Args
= (PERFORM_TEST_ARGS
*)_arg
;
53 _PTEST Test
= Args
->Test
;
55 _SetThreadPriority(_GetCurrentThread(), THREAD_PRIORITY_IDLE
);
57 memset(Args
->Buffer
, 0, sizeof(Args
->Buffer
));
61 _Buffer
= Args
->Buffer
;
62 (Test
->Routine
)(TESTCMD_RUN
);
63 Args
->Result
= _Result
;
65 Args
->Result
= TS_FAILED
;
66 sprintf(Args
->Buffer
, "due to exception 0x%lx", _SEH_GetExceptionCode());
72 IsContextChanged(LPCONTEXT context1
, LPCONTEXT context2
)
74 return memcmp(context1
, context2
, sizeof(CONTEXT
)) != 0;
78 ControlNormalTest(HANDLE hThread
,
79 PERFORM_TEST_ARGS
*Args
,
83 _FILETIME executionTime
;
86 status
= _WaitForSingleObject(hThread
, TimeOut
);
87 if (status
== WAIT_TIMEOUT
)
89 _TerminateThread(hThread
, 0);
90 Args
->Result
= TS_TIMEDOUT
;
92 status
= _GetThreadTimes(hThread
,
97 Args
->Time
= executionTime
.dwLowDateTime
/ 10000;
101 ControlPerformanceTest(HANDLE hThread
,
102 PERFORM_TEST_ARGS
*Args
,
107 CONTEXT currentContext
;
109 ZeroMemory(&lastContext
, sizeof(CONTEXT
));
110 lastContext
.ContextFlags
= CONTEXT_FULL
;
111 ZeroMemory(¤tContext
, sizeof(CONTEXT
));
112 currentContext
.ContextFlags
= CONTEXT_FULL
;
117 if (_SuspendThread(hThread
) == (DWORD
)-1)
120 if (_GetThreadContext(hThread
, ¤tContext
) == 0)
123 if (IsContextChanged(¤tContext
, &lastContext
))
126 if (_ResumeThread(hThread
) == (DWORD
)-1)
129 if (Args
->Time
>= TimeOut
)
131 _TerminateThread(hThread
, 0);
132 Args
->Result
= TS_TIMEDOUT
;
136 status
= _WaitForSingleObject(hThread
, 0);
137 if (status
== WAIT_OBJECT_0
|| status
== WAIT_FAILED
)
140 lastContext
= currentContext
;
145 DisplayResult(PERFORM_TEST_ARGS
* Args
,
150 if (Args
->Result
== TS_OK
)
152 sprintf(OutputBuffer
,
153 "[%s] Success [%s]\n",
155 FormatExecutionTime(Format
,
158 else if (Args
->Result
== TS_TIMEDOUT
)
160 sprintf(OutputBuffer
,
161 "[%s] Timed out [%s]\n",
163 FormatExecutionTime(Format
,
167 sprintf(OutputBuffer
, "[%s] Failed (%s)\n", Args
->TestName
, Args
->Buffer
);
169 if (Args
->OutputRoutine
!= NULL
)
170 (*Args
->OutputRoutine
)(OutputBuffer
);
172 DbgPrint(OutputBuffer
);
176 ControlTest(HANDLE hThread
,
177 PERFORM_TEST_ARGS
*Args
,
184 ControlNormalTest(hThread
, Args
, TimeOut
);
187 ControlPerformanceTest(hThread
, Args
, TimeOut
);
190 printf("Unknown test type %ld\n", TestType
);
196 PerformTests(TestOutputRoutine OutputRoutine
, LPSTR TestName
)
198 PLIST_ENTRY CurrentEntry
;
199 PLIST_ENTRY NextEntry
;
201 PERFORM_TEST_ARGS Args
;
203 char OutputBuffer
[1024];
208 Args
.OutputRoutine
= OutputRoutine
;
209 Args
.TestName
= Name
;
212 CurrentEntry
= AllTests
.Flink
;
213 for (; CurrentEntry
!= &AllTests
; CurrentEntry
= NextEntry
)
215 NextEntry
= CurrentEntry
->Flink
;
216 Current
= CONTAINING_RECORD(CurrentEntry
, _TEST
, ListEntry
);
219 /* Get name of test */
220 memset(Name
, 0, sizeof(Name
));
224 (Current
->Routine
)(TESTCMD_TESTNAME
);
225 if (_Result
!= TS_OK
)
227 if (TestName
!= NULL
)
229 strcpy(Name
, "Unnamed");
232 if ((TestName
!= NULL
) && (_stricmp(Name
, TestName
) != 0))
235 TestType
= TT_NORMAL
;
237 _Buffer
= (char *)&TestType
;
238 (Current
->Routine
)(TESTCMD_TESTTYPE
);
239 if (_Result
!= TS_OK
)
240 TestType
= TT_NORMAL
;
242 /* Get timeout for test */
245 _Buffer
= (char *)&TimeOut
;
246 (Current
->Routine
)(TESTCMD_TIMEOUT
);
247 if (_Result
!= TS_OK
|| TimeOut
== INFINITE
)
250 /* Run test in a separate thread */
251 hThread
= _CreateThread(NULL
, 0, PerformTest
, (PVOID
)&Args
, 0, NULL
);
254 printf("[%s] Failed (CreateThread() failed: %ld)\n",
257 Args
.Result
= TS_FAILED
;
260 ControlTest(hThread
, &Args
, TestType
, TimeOut
);
262 DisplayResult(&Args
, OutputBuffer
);
267 AddTest(TestRoutine Routine
)
271 Test
= (_PTEST
) malloc(sizeof(_TEST
));
274 DbgPrint("Out of memory");
278 Test
->Routine
= Routine
;
280 InsertTailList(&AllTests
, &Test
->ListEntry
);
284 FrameworkGetHook(ULONG index
)
286 return FrameworkGetHookInternal(index
);