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
14 #define NTOS_MODE_USER
22 typedef struct _PERFORM_TEST_ARGS
24 TestOutputRoutine OutputRoutine
;
35 static LIST_ENTRY AllTests
;
40 InitializeListHead(&AllTests
);
44 FormatExecutionTime(char *buffer
, ULONG milliseconds
)
53 PerformTest(PVOID _arg
)
55 PERFORM_TEST_ARGS
*Args
= (PERFORM_TEST_ARGS
*)_arg
;
56 _PTEST Test
= Args
->Test
;
58 _SetThreadPriority(_GetCurrentThread(), THREAD_PRIORITY_IDLE
);
60 memset(Args
->Buffer
, 0, sizeof(Args
->Buffer
));
64 _Buffer
= Args
->Buffer
;
65 (Test
->Routine
)(TESTCMD_RUN
);
66 Args
->Result
= _Result
;
68 Args
->Result
= TS_FAILED
;
69 sprintf(Args
->Buffer
, "due to exception 0x%lx", _SEH_GetExceptionCode());
75 IsContextChanged(LPCONTEXT context1
, LPCONTEXT context2
)
77 return memcmp(context1
, context2
, sizeof(CONTEXT
)) != 0;
81 ControlNormalTest(HANDLE hThread
,
82 PERFORM_TEST_ARGS
*Args
,
86 FILETIME executionTime
;
89 status
= _WaitForSingleObject(hThread
, TimeOut
);
90 if (status
== WAIT_TIMEOUT
)
92 _TerminateThread(hThread
, 0);
93 Args
->Result
= TS_TIMEDOUT
;
95 status
= _GetThreadTimes(hThread
,
100 Args
->Time
= executionTime
.dwLowDateTime
/ 10000;
104 ControlPerformanceTest(HANDLE hThread
,
105 PERFORM_TEST_ARGS
*Args
,
110 CONTEXT currentContext
;
112 ZeroMemory(&lastContext
, sizeof(CONTEXT
));
113 lastContext
.ContextFlags
= CONTEXT_FULL
;
114 ZeroMemory(¤tContext
, sizeof(CONTEXT
));
115 currentContext
.ContextFlags
= CONTEXT_FULL
;
120 if (_SuspendThread(hThread
) == -1)
123 if (_GetThreadContext(hThread
, ¤tContext
) == 0)
126 if (IsContextChanged(¤tContext
, &lastContext
))
129 if (_ResumeThread(hThread
) == -1)
132 if (Args
->Time
>= TimeOut
)
134 _TerminateThread(hThread
, 0);
135 Args
->Result
= TS_TIMEDOUT
;
139 status
= _WaitForSingleObject(hThread
, 0);
140 if (status
== WAIT_OBJECT_0
|| status
== WAIT_FAILED
)
143 lastContext
= currentContext
;
148 DisplayResult(PERFORM_TEST_ARGS
* Args
,
154 if (Args
->Result
== TS_OK
)
156 sprintf(OutputBuffer
,
157 "[%s] Success [%s]\n",
159 FormatExecutionTime(Format
,
162 else if (Args
->Result
== TS_TIMEDOUT
)
164 sprintf(OutputBuffer
,
165 "[%s] Timed out [%s]\n",
167 FormatExecutionTime(Format
,
171 sprintf(OutputBuffer
, "[%s] Failed (%s)\n", Args
->TestName
, Buffer
);
173 if (Args
->OutputRoutine
!= NULL
)
174 (*Args
->OutputRoutine
)(OutputBuffer
);
176 DbgPrint(OutputBuffer
);
180 ControlTest(HANDLE hThread
,
181 PERFORM_TEST_ARGS
*Args
,
188 ControlNormalTest(hThread
, Args
, TimeOut
);
191 ControlPerformanceTest(hThread
, Args
, TimeOut
);
194 printf("Unknown test type %ld\n", TestType
);
200 PerformTests(TestOutputRoutine OutputRoutine
, LPSTR TestName
)
202 PLIST_ENTRY CurrentEntry
;
203 PLIST_ENTRY NextEntry
;
205 PERFORM_TEST_ARGS Args
;
207 char OutputBuffer
[1024];
212 Args
.OutputRoutine
= OutputRoutine
;
213 Args
.TestName
= Name
;
216 CurrentEntry
= AllTests
.Flink
;
217 for (; CurrentEntry
!= &AllTests
; CurrentEntry
= NextEntry
)
219 NextEntry
= CurrentEntry
->Flink
;
220 Current
= CONTAINING_RECORD(CurrentEntry
, _TEST
, ListEntry
);
223 /* Get name of test */
224 memset(Name
, 0, sizeof(Name
));
228 (Current
->Routine
)(TESTCMD_TESTNAME
);
229 if (_Result
!= TS_OK
)
231 if (TestName
!= NULL
)
233 strcpy(Name
, "Unnamed");
236 if ((TestName
!= NULL
) && (_stricmp(Name
, TestName
) != 0))
239 TestType
= TT_NORMAL
;
241 _Buffer
= (char *)&TestType
;
242 (Current
->Routine
)(TESTCMD_TESTTYPE
);
243 if (_Result
!= TS_OK
)
244 TestType
= TT_NORMAL
;
246 /* Get timeout for test */
249 _Buffer
= (char *)&TimeOut
;
250 (Current
->Routine
)(TESTCMD_TIMEOUT
);
251 if (_Result
!= TS_OK
|| TimeOut
== INFINITE
)
254 /* Run test in a separate thread */
255 hThread
= _CreateThread(NULL
, 0, PerformTest
, (PVOID
)&Args
, 0, NULL
);
258 printf("[%s] Failed (CreateThread() failed: %ld)\n",
261 Args
.Result
= TS_FAILED
;
264 ControlTest(hThread
, &Args
, TestType
, TimeOut
);
266 DisplayResult(&Args
, OutputBuffer
);
271 AddTest(TestRoutine Routine
)
275 Test
= (_PTEST
) malloc(sizeof(_TEST
));
278 DbgPrint("Out of memory");
282 Test
->Routine
= Routine
;
284 InsertTailList(&AllTests
, &Test
->ListEntry
);
288 FrameworkGetHook(ULONG index
)
290 return FrameworkGetHookInternal(index
);