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
16 typedef struct _PERFORM_TEST_ARGS
18 TestOutputRoutine OutputRoutine
;
29 static LIST_ENTRY AllTests
;
34 InitializeListHead(&AllTests
);
38 FormatExecutionTime(char *buffer
, ULONG milliseconds
)
47 PerformTest(PVOID _arg
)
49 PERFORM_TEST_ARGS
*Args
= (PERFORM_TEST_ARGS
*)_arg
;
50 _PTEST Test
= Args
->Test
;
52 _SetThreadPriority(_GetCurrentThread(), THREAD_PRIORITY_IDLE
);
54 memset(Args
->Buffer
, 0, sizeof(Args
->Buffer
));
58 _Buffer
= Args
->Buffer
;
59 (Test
->Routine
)(TESTCMD_RUN
);
60 Args
->Result
= _Result
;
62 Args
->Result
= TS_FAILED
;
63 sprintf(Args
->Buffer
, "due to exception 0x%lx", _SEH_GetExceptionCode());
69 IsContextChanged(LPCONTEXT context1
, LPCONTEXT context2
)
71 return memcmp(context1
, context2
, sizeof(CONTEXT
)) != 0;
75 ControlNormalTest(HANDLE hThread
,
76 PERFORM_TEST_ARGS
*Args
,
80 FILETIME executionTime
;
83 status
= _WaitForSingleObject(hThread
, TimeOut
);
84 if (status
== WAIT_TIMEOUT
)
86 _TerminateThread(hThread
, 0);
87 Args
->Result
= TS_TIMEDOUT
;
89 status
= _GetThreadTimes(hThread
,
94 Args
->Time
= executionTime
.dwLowDateTime
/ 10000;
98 ControlPerformanceTest(HANDLE hThread
,
99 PERFORM_TEST_ARGS
*Args
,
104 CONTEXT currentContext
;
106 ZeroMemory(&lastContext
, sizeof(CONTEXT
));
107 lastContext
.ContextFlags
= CONTEXT_FULL
;
108 ZeroMemory(¤tContext
, sizeof(CONTEXT
));
109 currentContext
.ContextFlags
= CONTEXT_FULL
;
114 if (_SuspendThread(hThread
) == -1)
117 if (_GetThreadContext(hThread
, ¤tContext
) == 0)
120 if (IsContextChanged(¤tContext
, &lastContext
))
123 if (_ResumeThread(hThread
) == -1)
126 if (Args
->Time
>= TimeOut
)
128 _TerminateThread(hThread
, 0);
129 Args
->Result
= TS_TIMEDOUT
;
133 status
= _WaitForSingleObject(hThread
, 0);
134 if (status
== WAIT_OBJECT_0
|| status
== WAIT_FAILED
)
137 lastContext
= currentContext
;
142 DisplayResult(PERFORM_TEST_ARGS
* Args
,
148 if (Args
->Result
== TS_OK
)
150 sprintf(OutputBuffer
,
151 "[%s] Success [%s]\n",
153 FormatExecutionTime(Format
,
156 else if (Args
->Result
== TS_TIMEDOUT
)
158 sprintf(OutputBuffer
,
159 "[%s] Timed out [%s]\n",
161 FormatExecutionTime(Format
,
165 sprintf(OutputBuffer
, "[%s] Failed (%s)\n", Args
->TestName
, Buffer
);
167 if (Args
->OutputRoutine
!= NULL
)
168 (*Args
->OutputRoutine
)(OutputBuffer
);
170 DbgPrint(OutputBuffer
);
174 ControlTest(HANDLE hThread
,
175 PERFORM_TEST_ARGS
*Args
,
182 ControlNormalTest(hThread
, Args
, TimeOut
);
185 ControlPerformanceTest(hThread
, Args
, TimeOut
);
188 printf("Unknown test type %ld\n", TestType
);
194 PerformTests(TestOutputRoutine OutputRoutine
, LPSTR TestName
)
196 PLIST_ENTRY CurrentEntry
;
197 PLIST_ENTRY NextEntry
;
199 PERFORM_TEST_ARGS Args
;
201 char OutputBuffer
[1024];
206 Args
.OutputRoutine
= OutputRoutine
;
207 Args
.TestName
= Name
;
210 CurrentEntry
= AllTests
.Flink
;
211 for (; CurrentEntry
!= &AllTests
; CurrentEntry
= NextEntry
)
213 NextEntry
= CurrentEntry
->Flink
;
214 Current
= CONTAINING_RECORD(CurrentEntry
, _TEST
, ListEntry
);
217 /* Get name of test */
218 memset(Name
, 0, sizeof(Name
));
222 (Current
->Routine
)(TESTCMD_TESTNAME
);
223 if (_Result
!= TS_OK
)
225 if (TestName
!= NULL
)
227 strcpy(Name
, "Unnamed");
230 if ((TestName
!= NULL
) && (_stricmp(Name
, TestName
) != 0))
233 TestType
= TT_NORMAL
;
235 _Buffer
= (char *)&TestType
;
236 (Current
->Routine
)(TESTCMD_TESTTYPE
);
237 if (_Result
!= TS_OK
)
238 TestType
= TT_NORMAL
;
240 /* Get timeout for test */
243 _Buffer
= (char *)&TimeOut
;
244 (Current
->Routine
)(TESTCMD_TIMEOUT
);
245 if (_Result
!= TS_OK
|| TimeOut
== INFINITE
)
248 /* Run test in a separate thread */
249 hThread
= _CreateThread(NULL
, 0, PerformTest
, (PVOID
)&Args
, 0, NULL
);
252 printf("[%s] Failed (CreateThread() failed: %ld)\n",
255 Args
.Result
= TS_FAILED
;
258 ControlTest(hThread
, &Args
, TestType
, TimeOut
);
260 DisplayResult(&Args
, OutputBuffer
);
265 AddTest(TestRoutine Routine
)
269 Test
= (_PTEST
) malloc(sizeof(_TEST
));
272 DbgPrint("Out of memory");
276 Test
->Routine
= Routine
;
278 InsertTailList(&AllTests
, &Test
->ListEntry
);
282 FrameworkGetHook(ULONG index
)
284 return FrameworkGetHookInternal(index
);