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
10 #define NTOS_MODE_USER
11 #include <ndk/ntndk.h>
12 #include <pseh/pseh.h>
18 typedef struct _PERFORM_TEST_ARGS
20 TestOutputRoutine OutputRoutine
;
31 static LIST_ENTRY AllTests
;
36 InitializeListHead(&AllTests
);
40 FormatExecutionTime(char *buffer
, ULONG milliseconds
)
49 PerformTest(PVOID _arg
)
51 PERFORM_TEST_ARGS
*Args
= (PERFORM_TEST_ARGS
*)_arg
;
52 _PTEST Test
= Args
->Test
;
54 _SetThreadPriority(_GetCurrentThread(), THREAD_PRIORITY_IDLE
);
56 memset(Args
->Buffer
, 0, sizeof(Args
->Buffer
));
60 _Buffer
= Args
->Buffer
;
61 (Test
->Routine
)(TESTCMD_RUN
);
62 Args
->Result
= _Result
;
64 Args
->Result
= TS_FAILED
;
65 sprintf(Args
->Buffer
, "due to exception 0x%lx", _SEH_GetExceptionCode());
71 IsContextChanged(LPCONTEXT context1
, LPCONTEXT context2
)
73 return memcmp(context1
, context2
, sizeof(CONTEXT
)) != 0;
77 ControlNormalTest(HANDLE hThread
,
78 PERFORM_TEST_ARGS
*Args
,
82 FILETIME executionTime
;
85 status
= _WaitForSingleObject(hThread
, TimeOut
);
86 if (status
== WAIT_TIMEOUT
)
88 _TerminateThread(hThread
, 0);
89 Args
->Result
= TS_TIMEDOUT
;
91 status
= _GetThreadTimes(hThread
,
96 Args
->Time
= executionTime
.dwLowDateTime
/ 10000;
100 ControlPerformanceTest(HANDLE hThread
,
101 PERFORM_TEST_ARGS
*Args
,
106 CONTEXT currentContext
;
108 ZeroMemory(&lastContext
, sizeof(CONTEXT
));
109 lastContext
.ContextFlags
= CONTEXT_FULL
;
110 ZeroMemory(¤tContext
, sizeof(CONTEXT
));
111 currentContext
.ContextFlags
= CONTEXT_FULL
;
116 if (_SuspendThread(hThread
) == -1)
119 if (_GetThreadContext(hThread
, ¤tContext
) == 0)
122 if (IsContextChanged(¤tContext
, &lastContext
))
125 if (_ResumeThread(hThread
) == -1)
128 if (Args
->Time
>= TimeOut
)
130 _TerminateThread(hThread
, 0);
131 Args
->Result
= TS_TIMEDOUT
;
135 status
= _WaitForSingleObject(hThread
, 0);
136 if (status
== WAIT_OBJECT_0
|| status
== WAIT_FAILED
)
139 lastContext
= currentContext
;
144 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
, 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
);