#include "StdAfx.h"
#include "UnitTestFrameWork.h"
#include <excpt.h>
#include <Shellapi.h>
void UnitTestSuite::RegisterTest(UnitTest * test, char * testName)
{
TestList * newTest = new TestList();
newTest->TestName = testName;
newTest->Test = test;
newTest->pNext = 0;
if (pLastTest)
{
pLastTest->pNext = newTest;
pLastTest = newTest;
}
else
{
pFirstTest = newTest;
pLastTest = newTest;
}
}
UnitTestSuite::UnitTestSuite()
{
pFirstTest = 0;
pLastTest = 0;
pNextTestSuite = 0;
}
UnitTestSuite::~UnitTestSuite()
{
TestList * pCurTest = pFirstTest;
while(pCurTest)
{
pFirstTest = pFirstTest->pNext;
delete pCurTest;
pCurTest = pFirstTest;
}
pFirstTest = 0;
pLastTest = 0;
pNextTestSuite = 0;
}
int UnitTestSuite::HandleException(unsigned int c, struct _EXCEPTION_POINTERS *e)
{
unsigned int code = 0;
struct _EXCEPTION_POINTERS *ep = NULL;
code = c;
ep = e;
printf("\tException Detected: ");
switch (code)
{
case EXCEPTION_ACCESS_VIOLATION:
printf("EXCEPTION_ACCESS_VIOLATION\r\n");
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
printf("EXCEPTION_DATATYPE_MISALIGNMENT\r\n");
break;
case EXCEPTION_BREAKPOINT:
printf("EXCEPTION_BREAKPOINT\r\n");
break;
case EXCEPTION_SINGLE_STEP:
printf("EXCEPTION_SINGLE_STEP\r\n");
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
printf("EXCEPTION_ARRAY_BOUNDS_EXCEEDED\r\n");
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
printf("EXCEPTION_FLT_DENORMAL_OPERAND\r\n");
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
printf("EXCEPTION_FLT_DIVIDE_BY_ZERO\r\n");
break;
case EXCEPTION_FLT_INEXACT_RESULT:
printf("EXCEPTION_FLT_INEXACT_RESULT\r\n");
break;
case EXCEPTION_FLT_INVALID_OPERATION:
printf("EXCEPTION_FLT_INVALID_OPERATION\r\n");
break;
case EXCEPTION_FLT_OVERFLOW:
printf("EXCEPTION_FLT_OVERFLOW\r\n");
break;
case EXCEPTION_FLT_STACK_CHECK:
printf("EXCEPTION_FLT_STACK_CHECK\r\n");
break;
case EXCEPTION_FLT_UNDERFLOW:
printf("EXCEPTION_FLT_UNDERFLOW\r\n");
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
printf("EXCEPTION_INT_DIVIDE_BY_ZERO\r\n");
break;
case EXCEPTION_INT_OVERFLOW:
printf("EXCEPTION_INT_OVERFLOW\r\n");
break;
case EXCEPTION_PRIV_INSTRUCTION:
printf("EXCEPTION_PRIV_INSTRUCTION\r\n");
break;
case EXCEPTION_IN_PAGE_ERROR:
printf("EXCEPTION_IN_PAGE_ERROR\r\n");
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
printf("EXCEPTION_ILLEGAL_INSTRUCTION\r\n");
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
printf("EXCEPTION_NONCONTINUABLE_EXCEPTION\r\n");
break;
case EXCEPTION_STACK_OVERFLOW:
printf("EXCEPTION_STACK_OVERFLOW\r\n");
break;
case EXCEPTION_INVALID_DISPOSITION:
printf("EXCEPTION_INVALID_DISPOSITION\r\n");
break;
case EXCEPTION_GUARD_PAGE:
printf("EXCEPTION_GUARD_PAGE\r\n");
break;
case EXCEPTION_INVALID_HANDLE:
printf("EXCEPTION_INVALID_HANDLE\r\n");
break;
//case EXCEPTION_POSSIBLE_DEADLOCK:
// printf("EXCEPTION_POSSIBLE_DEADLOCK\r\n");
// break;
default:
printf("UNKOWN EXCEPTION\r\n");
break;
}
return EXCEPTION_EXECUTE_HANDLER;
}
LPPROCESS_INFORMATION UnitTestSuite::RunProgram(char * cmdLine, char * cwd, bool newConsole, bool waitForExit)
{
LPSTARTUPINFOA si = new STARTUPINFOA;
LPPROCESS_INFORMATION pi = new PROCESS_INFORMATION;
ZeroMemory( si, sizeof(STARTUPINFOA) );
si->cb = sizeof(si);
ZeroMemory( pi, sizeof(PROCESS_INFORMATION) );
// Start the child process.
if( !CreateProcessA(
NULL, // No module name (use command line)
cmdLine, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
newConsole?CREATE_NEW_CONSOLE:0, // No creation flags
NULL, // Use parent's environment block
cwd, // Starting directory
si, // Pointer to STARTUPINFO structure
pi ) // Pointer to PROCESS_INFORMATION structure
)
{
printf( "CreateProcess failed (%d).\n", GetLastError() );
return NULL;
}
if (waitForExit)
{
// Wait until child process exits.
WaitForSingleObject( pi->hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi->hProcess );
CloseHandle( pi->hThread );
}
delete si;
return pi;
}
bool UnitTestSuite::EndProcess(LPPROCESS_INFORMATION pi)
{
TerminateProcess( pi->hProcess, 0);
// Wait until child process exits.
WaitForSingleObject( pi->hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi->hProcess );
CloseHandle( pi->hThread );
delete pi;
return true;
}
bool UnitTestSuite::rmDir(char * path)
{
char szDir[MAX_PATH+1]; // +1 for the double null terminate
SHFILEOPSTRUCTA fos = {0};
strcpy(szDir, path);
int len = strlen(szDir);
szDir[len+1] = 0; // double null terminate for SHFileOperation
// delete the folder and everything inside
fos.wFunc = FO_DELETE;
fos.pFrom = szDir;
fos.fFlags = FOF_NO_UI;
return SHFileOperation( &fos );
}
void UnitTestSuite::RunTests()
{
TestList * pCurrentTest = pFirstTest;
while (pCurrentTest)
{
unsigned int code = 0;
struct _EXCEPTION_POINTERS *ep = NULL;
__try
{
printf("Test %s:\r\n", pCurrentTest->TestName);
if (!Setup())
{
printf("\tSetup Failed!!\r\n");
UnitTestFrameWork::IncrementTestsFailed();
if (endOnFailure)
return;
}
else
{
bool passed = (*pCurrentTest->Test)();
bool tearDownPassed = TearDown(pCurrentTest->TestName);
if (passed)
printf("\tPassed\r\n");
else
printf("\t<<<<***Failed!!***>>>>\r\n");
if (!tearDownPassed)
printf("\tTearDown Failed!!\r\n");
if (!passed || !tearDownPassed)
{
UnitTestFrameWork::IncrementTestsFailed();
if (endOnFailure)
return;
}
UnitTestFrameWork::IncrementTestsPassed();
}
}
__except (HandleException(GetExceptionCode(), GetExceptionInformation()))
{
UnitTestFrameWork::IncrementTestsFailed();
if (endOnFailure)
return;
}
pCurrentTest = pCurrentTest->pNext;
}
if (pNextTestSuite)
pNextTestSuite->RunTests();
}
bool UnitTestSuite::Assert(bool condition, char* FailStr, int Line, char * FileName)
{
if (condition) // It's as expected
return true;
if (breakOnFailure)
__debugbreak();
printf("\t%s: Line: %d, %s:\r\n", FailStr, Line, FileName);
return false;
}
bool UnitTestSuite::breakOnFailure = false;
bool UnitTestSuite::endOnFailure = false;
UnitTestFrameWork::UnitTestFrameWork(void)
{
}
UnitTestSuite * UnitTestFrameWork::pFirstTestSuite = 0;
UnitTestSuite * UnitTestFrameWork::pLastTestSuite = 0;
void UnitTestFrameWork::RegisterTestSuite(UnitTestSuite * pSuite)
{
if (pLastTestSuite)
{
pLastTestSuite->NextTestSuite(pSuite);
pLastTestSuite = pSuite;
}
else
{
pFirstTestSuite = pSuite;
pLastTestSuite = pSuite;
}
}
int UnitTestFrameWork::testsPassed = 0;
int UnitTestFrameWork::testsFailed = 0;
void UnitTestFrameWork::RunTests()
{
testsPassed = 0;
testsFailed = 0;
if (pFirstTestSuite)
pFirstTestSuite->RunTests();
printf("Tests Passed %d, TestFailed: %d\r\n", testsPassed, testsFailed);
// delete all the test suites
while (pFirstTestSuite)
{
UnitTestSuite * pCurrentTestSuite = pFirstTestSuite;
pFirstTestSuite = pCurrentTestSuite->NextTestSuite();
delete pCurrentTestSuite;
}
p4base::Cleanup();
}
# |
Change |
User |
Description |
Committed |
|
#1
|
11467 |
Norman Morse |
branch from main |
|
|
//guest/perforce_software/p4api.net/p4bridge-unit-test/UnitTestFrameWork.cpp |
#3
|
11220 |
Matt Attaway |
Update Workshop version with most recent 14.2 patch of p4api.net |
|
|
#2
|
8964 |
Bill |
fix line endings |
|
|
#1
|
8873 |
Matt Attaway |
Initial add of the P4API.NET source code |
|
|