--- trunk/reactos/regtests/shared/regtests.c 2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/regtests/shared/regtests.c 2005-06-19 12:41:22 UTC (rev 16091)
@@ -24,6 +24,9 @@
TestOutputRoutine OutputRoutine;
_PTEST Test;
LPSTR TestName;
+ DWORD Result;
+ char Buffer[5000];
+ DWORD Time;
} PERFORM_TEST_ARGS;
int _Result;
@@ -38,13 +41,11 @@
}
char*
-FormatExecutionTime(char *buffer, LPFILETIME time)
+FormatExecutionTime(char *buffer, ULONG milliseconds)
{
- ULONG milliseconds = time->dwLowDateTime / 10000;
-
sprintf(buffer,
- "%ldms",
- milliseconds);
+ "%ldms",
+ milliseconds);
return buffer;
}
@@ -52,58 +53,150 @@
PerformTest(PVOID _arg)
{
PERFORM_TEST_ARGS *Args = (PERFORM_TEST_ARGS *)_arg;
- TestOutputRoutine OutputRoutine = Args->OutputRoutine;
_PTEST Test = Args->Test;
- LPSTR TestName = Args->TestName;
- HANDLE hThread;
- FILETIME time;
- FILETIME ExecutionTime;
- char OutputBuffer[5000];
- char Buffer[5000];
- char Format[100];
- hThread = _GetCurrentThread();
- _SetThreadPriority(hThread, THREAD_PRIORITY_IDLE);
+ _SetThreadPriority(_GetCurrentThread(), THREAD_PRIORITY_IDLE);
- memset(Buffer, 0, sizeof(Buffer));
-
+ memset(Args->Buffer, 0, sizeof(Args->Buffer));
+
_SEH_TRY {
_Result = TS_OK;
- _Buffer = Buffer;
+ _Buffer = Args->Buffer;
(Test->Routine)(TESTCMD_RUN);
+ Args->Result = _Result;
} _SEH_HANDLE {
- _Result = TS_FAILED;
- sprintf(Buffer, "due to exception 0x%lx", _SEH_GetExceptionCode());
+ Args->Result = TS_FAILED;
+ sprintf(Args->Buffer, "due to exception 0x%lx", _SEH_GetExceptionCode());
} _SEH_END;
+ return 1;
+}
- if (_Result == TS_OK)
- {
- if (!_GetThreadTimes(hThread,
- &time,
- &time,
- &time,
- &ExecutionTime))
+BOOL
+IsContextChanged(LPCONTEXT context1, LPCONTEXT context2)
+{
+ return memcmp(context1, context2, sizeof(CONTEXT)) != 0;
+}
+
+VOID
+ControlNormalTest(HANDLE hThread,
+ PERFORM_TEST_ARGS *Args,
+ DWORD TimeOut)
+{
+ FILETIME time;
+ FILETIME executionTime;
+ DWORD status;
+
+ status = _WaitForSingleObject(hThread, TimeOut);
+ if (status == WAIT_TIMEOUT)
+ {
+ _TerminateThread(hThread, 0);
+ Args->Result = TS_TIMEDOUT;
+ }
+ status = _GetThreadTimes(hThread,
+ &time,
+ &time,
+ &time,
+ &executionTime);
+ Args->Time = executionTime.dwLowDateTime / 10000;
+}
+
+VOID
+ControlPerformanceTest(HANDLE hThread,
+ PERFORM_TEST_ARGS *Args,
+ DWORD TimeOut)
+{
+ DWORD status;
+ CONTEXT lastContext;
+ CONTEXT currentContext;
+
+ ZeroMemory(&lastContext, sizeof(CONTEXT));
+ lastContext.ContextFlags = CONTEXT_FULL;
+ ZeroMemory(¤tContext, sizeof(CONTEXT));
+ currentContext.ContextFlags = CONTEXT_FULL;
+
+ do {
+ _Sleep(1);
+
+ if (_SuspendThread(hThread) == -1)
+ break;
+
+ if (_GetThreadContext(hThread, ¤tContext) == 0)
+ break;
+
+ if (IsContextChanged(¤tContext, &lastContext))
+ Args->Time++;
+
+ if (_ResumeThread(hThread) == -1)
+ break;
+
+ if (Args->Time >= TimeOut)
{
- ExecutionTime.dwLowDateTime = 0;
- ExecutionTime.dwHighDateTime = 0;
+ _TerminateThread(hThread, 0);
+ Args->Result = TS_TIMEDOUT;
+ break;
}
+
+ status = _WaitForSingleObject(hThread, 0);
+ if (status == WAIT_OBJECT_0 || status == WAIT_FAILED)
+ break;
+
+ lastContext = currentContext;
+ } while (TRUE);
+}
+
+VOID
+DisplayResult(PERFORM_TEST_ARGS* Args,
+ LPSTR OutputBuffer)
+{
+ char Buffer[5000];
+ char Format[100];
+
+ if (Args->Result == TS_OK)
+ {
sprintf(OutputBuffer,
"[%s] Success [%s]\n",
- TestName,
+ Args->TestName,
FormatExecutionTime(Format,
- &ExecutionTime));
+ Args->Time));
}
+ else if (Args->Result == TS_TIMEDOUT)
+ {
+ sprintf(OutputBuffer,
+ "[%s] Timed out [%s]\n",
+ Args->TestName,
+ FormatExecutionTime(Format,
+ Args->Time));
+ }
else
- sprintf(OutputBuffer, "[%s] Failed (%s)\n", TestName, Buffer);
+ sprintf(OutputBuffer, "[%s] Failed (%s)\n", Args->TestName, Buffer);
- if (OutputRoutine != NULL)
- (*OutputRoutine)(OutputBuffer);
+ if (Args->OutputRoutine != NULL)
+ (*Args->OutputRoutine)(OutputBuffer);
else
- DbgPrint(OutputBuffer);
- return 1;
+ DbgPrint(OutputBuffer);
}
VOID
+ControlTest(HANDLE hThread,
+ PERFORM_TEST_ARGS *Args,
+ DWORD TestType,
+ DWORD TimeOut)
+{
+ switch (TestType)
+ {
+ case TT_NORMAL:
+ ControlNormalTest(hThread, Args, TimeOut);
+ break;
+ case TT_PERFORMANCE:
+ ControlPerformanceTest(hThread, Args, TimeOut);
+ break;
+ default:
+ printf("Unknown test type %ld\n", TestType);
+ break;
+ }
+}
+
+VOID
PerformTests(TestOutputRoutine OutputRoutine, LPSTR TestName)
{
PLIST_ENTRY CurrentEntry;
@@ -113,11 +206,13 @@
HANDLE hThread;
char OutputBuffer[1024];
char Name[200];
+ DWORD TestType;
DWORD TimeOut;
Args.OutputRoutine = OutputRoutine;
Args.TestName = Name;
-
+ Args.Time = 0;
+
CurrentEntry = AllTests.Flink;
for (; CurrentEntry != &AllTests; CurrentEntry = NextEntry)
{
@@ -141,40 +236,34 @@
if ((TestName != NULL) && (_stricmp(Name, TestName) != 0))
continue;
+ TestType = TT_NORMAL;
+ _Result = TS_OK;
+ _Buffer = (char *)&TestType;
+ (Current->Routine)(TESTCMD_TESTTYPE);
+ if (_Result != TS_OK)
+ TestType = TT_NORMAL;
+
/* Get timeout for test */
TimeOut = 0;
_Result = TS_OK;
_Buffer = (char *)&TimeOut;
(Current->Routine)(TESTCMD_TIMEOUT);
if (_Result != TS_OK || TimeOut == INFINITE)
- TimeOut = 5000;
+ TimeOut = 5000;
- /* Run test in thread */
+ /* Run test in a separate thread */
hThread = _CreateThread(NULL, 0, PerformTest, (PVOID)&Args, 0, NULL);
if (hThread == NULL)
- sprintf(OutputBuffer,
- "[%s] Failed (CreateThread() failed: %d)\n",
- Name, (unsigned int)_GetLastError());
- else if (_WaitForSingleObject(hThread, TimeOut) == WAIT_TIMEOUT)
{
- if (!_TerminateThread(hThread, 0))
- sprintf(OutputBuffer,
- "[%s] Failed (timed out after %dms; TerminateThread() failed: %d)\n",
- Name, (int)TimeOut, (unsigned int)_GetLastError());
- else
- sprintf(OutputBuffer, "[%s] Failed (timed out after %dms)\n", Name, (int)TimeOut);
- _CloseHandle(hThread);
+ printf("[%s] Failed (CreateThread() failed: %ld)\n",
+ Name,
+ _GetLastError());
+ Args.Result = TS_FAILED;
}
else
- {
- _CloseHandle(hThread);
- continue;
- }
+ ControlTest(hThread, &Args, TestType, TimeOut);
- if (OutputRoutine != NULL)
- (*OutputRoutine)(OutputBuffer);
- else
- DbgPrint(OutputBuffer);
+ DisplayResult(&Args, OutputBuffer);
}
}
--- trunk/reactos/regtests/shared/regtests.h 2005-06-19 12:14:31 UTC (rev 16090)
+++ trunk/reactos/regtests/shared/regtests.h 2005-06-19 12:41:22 UTC (rev 16091)
@@ -16,10 +16,16 @@
/* Valid values for Command parameter of TestRoutine */
#define TESTCMD_RUN 0 /* Buffer contains information about what failed */
-#define TESTCMD_TESTNAME 1 /* Buffer contains description of test */
-#define TESTCMD_TIMEOUT 2 /* Buffer contains timeout for test (DWORD, default is 5000 ms) */
+#define TESTCMD_TESTTYPE 1 /* Buffer contains type of test */
+#define TESTCMD_TESTNAME 2 /* Buffer contains description of test */
+#define TESTCMD_TIMEOUT 3 /* Buffer contains timeout for test (DWORD, default is 5000 ms) */
+/* Test types */
+#define TT_NORMAL 0
+#define TT_PERFORMANCE 1
+
/* Valid values for return values of TestRoutine */
+#define TS_TIMEDOUT -2
#define TS_EXCEPTION -1
#define TS_OK 0
#define TS_FAILED 1
@@ -28,7 +34,7 @@
extern char *_Buffer;
/* Macros to simplify tests */
-#define _DispatcherTimeout(FunctionName, TestName, TimeOut) \
+#define _DispatcherTypeTimeout(FunctionName, TestName, TestType, TimeOut) \
void \
FunctionName(int Command) \
{ \
@@ -37,6 +43,9 @@
case TESTCMD_RUN: \
RunTest(); \
break; \
+ case TESTCMD_TESTTYPE: \
+ *(PDWORD)_Buffer = (DWORD)TestType; \
+ break; \
case TESTCMD_TESTNAME: \
strcpy(_Buffer, TestName); \
break; \
@@ -49,8 +58,15 @@
} \
}
-#define _Dispatcher(FunctionName, TestName) _DispatcherTimeout(FunctionName, TestName, 5000)
+#define _DispatcherTimeout(FunctionName, TestName, TimeOut) \
+ _DispatcherTypeTimeout(FunctionName, TestName, TT_NORMAL, TimeOut)
+#define _DispatcherType(FunctionName, TestName, TestType) \
+ _DispatcherTypeTimeout(FunctionName, TestName, TestType, 5000)
+
+#define _Dispatcher(FunctionName, TestName) \
+ _DispatcherTimeout(FunctionName, TestName, 5000)
+
static inline void
AppendAssertion(char *message)
{
@@ -211,7 +227,19 @@
HANDLE STDCALL
_GetCurrentThread();
+BOOL STDCALL
+_GetThreadContext(HANDLE hThread, LPCONTEXT lpContext);
+DWORD STDCALL
+_SuspendThread(HANDLE hThread);
+
+DWORD STDCALL
+_ResumeThread(HANDLE hThread);
+
+VOID STDCALL
+_Sleep(DWORD dwMilliseconds);
+
+
static inline PCHAR
FrameworkGetExportedFunctionNameInternal(_PAPI_DESCRIPTION ApiDescription)
{