480 lines
12 KiB
C++
480 lines
12 KiB
C++
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Microsoft Windows
|
|||
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|||
|
//
|
|||
|
// File: task.cpp
|
|||
|
//
|
|||
|
// Contents: The global task list and helper function implementations
|
|||
|
//
|
|||
|
// Classes:
|
|||
|
//
|
|||
|
// Functions: HandleTestEnd
|
|||
|
// RunAllTests
|
|||
|
// RunApp
|
|||
|
// RunTestOnThread
|
|||
|
//
|
|||
|
// History: dd-mmm-yy Author Comment
|
|||
|
// 06-Jan-95 t-scotth added apartment thread test and RunTestOnThread
|
|||
|
// 06-Feb-94 alexgo author
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
// Folks adding new tests will need to insert their test
|
|||
|
// into the global array.
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
|
|||
|
#include "oletest.h"
|
|||
|
#include "cotest.h"
|
|||
|
#include "letest.h"
|
|||
|
#include "attest.h"
|
|||
|
|
|||
|
// global, zero'ed task item
|
|||
|
TaskItem vzTaskItem;
|
|||
|
|
|||
|
// the global task list array.
|
|||
|
// Multi-test entries go first, followed by individual tests.
|
|||
|
|
|||
|
#ifdef WIN32
|
|||
|
|
|||
|
const TaskItem vrgTaskList[] =
|
|||
|
{
|
|||
|
// the constant should be the index at which individual tests
|
|||
|
// begin. RunAllTests will run every test in this list after
|
|||
|
// that index.
|
|||
|
{ "Run All Tests", RunAllTests, (void *)2},
|
|||
|
// the constant below should be the index at which individual
|
|||
|
// upper layer unit tests exist. All tests at that index and
|
|||
|
// beyond will be run
|
|||
|
{ "Run All Upper Layer Tests", RunAllTests, (void *)5 },
|
|||
|
{ "OleBind", RunApp, (void *)"olebind.exe"},
|
|||
|
{ "Threads", RunApi, (void *) ThreadUnitTest },
|
|||
|
{ "Storage DRT", RunApp, (void *)"stgdrt.exe"},
|
|||
|
{ "LE: Insert Object Test 1", LETest1, &letiInsertObjectTest1 },
|
|||
|
{ "LE: Clipboard Test 1", RunApi, (void *)LEClipTest1},
|
|||
|
{ "LE: Clipboard Test 2 (clipboard data object)", RunApi,
|
|||
|
(void *)LEClipTest2 },
|
|||
|
{ "LE: Inplace Test 1", LETest1, &letiInplaceTest1 },
|
|||
|
{ "LE: Data Advise Holder Test", RunApi,
|
|||
|
(void *) LEDataAdviseHolderTest},
|
|||
|
{ "LE: OLE Advise Holder Test", RunApi, (void *) LEOleAdviseHolderTest},
|
|||
|
{ "LE: OLE1 Clipboard Test 1", RunApi, (void *)LEOle1ClipTest1},
|
|||
|
{ "LE: Insert Object Test 2", LETest1, &letiInsertObjectTest2 },
|
|||
|
{ "LE: OLE1 Clipboard Test 2", LEOle1ClipTest2, NULL },
|
|||
|
{ "LE: OleQueryCreateFromData Test 1", RunApi,
|
|||
|
(void *)TestOleQueryCreateFromDataMFCHack },
|
|||
|
{ "LE: Apartment Thread Test", RunTestOnThread, (void *)ATTest },
|
|||
|
{ 0, 0, 0 }
|
|||
|
};
|
|||
|
|
|||
|
#else
|
|||
|
|
|||
|
// Win16 tests
|
|||
|
|
|||
|
const TaskItem vrgTaskList[] =
|
|||
|
{
|
|||
|
// the constant should be the index at which individual tests
|
|||
|
// begin. RunAllTests will run every test in this list after
|
|||
|
// that index.
|
|||
|
{ "Run All Tests", RunAllTests, (void *)1},
|
|||
|
{ "LE: Clipboard Test 1", RunApi, (void *)LEClipTest1},
|
|||
|
{ "LE: Clipboard Test 2 (clipboard data object)", RunApi,
|
|||
|
(void *)LEClipTest2 },
|
|||
|
{ "LE: OLE1 Clipboard Test 1", RunApi, (void *)LEOle1ClipTest1},
|
|||
|
{ 0, 0, 0 }
|
|||
|
};
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: HandleTestEnd
|
|||
|
//
|
|||
|
// Synopsis: Handles processing for the WM_TESTEND message.
|
|||
|
//
|
|||
|
// Effects:
|
|||
|
//
|
|||
|
// Arguments: void
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Returns: void
|
|||
|
//
|
|||
|
// Signals:
|
|||
|
//
|
|||
|
// Modifies:
|
|||
|
//
|
|||
|
// Algorithm: execute the next task in the task stack or sends
|
|||
|
// a TESTSCOMPLETED message back the message queue
|
|||
|
//
|
|||
|
// History: dd-mmm-yy Author Comment
|
|||
|
// 06-Feb-94 alexgo author
|
|||
|
// 13-Dec-94 MikeW Allow testing to continue after failures
|
|||
|
//
|
|||
|
// Notes: vApp must be initialized correctly for this function to
|
|||
|
// work properly.
|
|||
|
//
|
|||
|
// BUGBUG::Need to add output routines in here.
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
void HandleTestEnd( void )
|
|||
|
{
|
|||
|
assert(vApp.m_message == WM_TESTEND);
|
|||
|
|
|||
|
switch( vApp.m_wparam )
|
|||
|
{
|
|||
|
case TEST_UNKNOWN:
|
|||
|
//we usually get this message from a test run
|
|||
|
//by RunApp (i.e. one that does not communicate
|
|||
|
//with us via windows messages). We'll check
|
|||
|
//the exit code and decide what to do.
|
|||
|
|
|||
|
if( vApp.m_lparam != 0 )
|
|||
|
{
|
|||
|
//presumably an error
|
|||
|
OutputString("Test End, Status Unknown "
|
|||
|
"( %lx )\r\n\r\n", vApp.m_lparam);
|
|||
|
|
|||
|
vApp.m_fGotErrors = TRUE;
|
|||
|
break;
|
|||
|
}
|
|||
|
// otherwise we fall through to the success case.
|
|||
|
case TEST_SUCCESS:
|
|||
|
OutputString("Test Success ( %lx )!\r\n\r\n",
|
|||
|
vApp.m_lparam);
|
|||
|
break;
|
|||
|
|
|||
|
case TEST_FAILURE:
|
|||
|
OutputString("Test FAILED! ( %lx )\r\n\r\n", vApp.m_lparam);
|
|||
|
vApp.m_fGotErrors = TRUE;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
assert(0); //we should never get here
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
vApp.Reset();
|
|||
|
|
|||
|
//
|
|||
|
// Now check to see if there are any more tests
|
|||
|
//
|
|||
|
|
|||
|
while (!vApp.m_TaskStack.IsEmpty())
|
|||
|
{
|
|||
|
TaskItem ti;
|
|||
|
|
|||
|
vApp.m_TaskStack.Pop(&ti);
|
|||
|
|
|||
|
if (ti.szName != (LPSTR) 0)
|
|||
|
{
|
|||
|
vApp.m_TaskStack.Push(&ti);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (vApp.m_TaskStack.IsEmpty())
|
|||
|
{
|
|||
|
PostMessage(vApp.m_hwndMain,
|
|||
|
WM_TESTSCOMPLETED,
|
|||
|
vApp.m_wparam, vApp.m_lparam);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//if the stack is not empty, run
|
|||
|
//the next task
|
|||
|
PostMessage(vApp.m_hwndMain,
|
|||
|
WM_TESTSTART,
|
|||
|
0, 0);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: HandleTestsCompleted
|
|||
|
//
|
|||
|
// Synopsis: Handles processing for the WM_TESTSCOMPLETED message.
|
|||
|
//
|
|||
|
// Effects:
|
|||
|
//
|
|||
|
// Arguments: void
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Returns: void
|
|||
|
//
|
|||
|
// Signals:
|
|||
|
//
|
|||
|
// Modifies:
|
|||
|
//
|
|||
|
// Algorithm:
|
|||
|
//
|
|||
|
// History: dd-mmm-yy Author Comment
|
|||
|
// 06-Feb-94 alexgo author
|
|||
|
//
|
|||
|
// Notes: vApp must be initialized correctly for this function to
|
|||
|
// work properly.
|
|||
|
//
|
|||
|
// BUGBUG::Need to add more output routines in here.
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
void HandleTestsCompleted( void )
|
|||
|
{
|
|||
|
char szBuf[128];
|
|||
|
|
|||
|
assert(vApp.m_message == WM_TESTSCOMPLETED);
|
|||
|
|
|||
|
//temporary output
|
|||
|
|
|||
|
switch(vApp.m_fGotErrors)
|
|||
|
{
|
|||
|
case FALSE:
|
|||
|
OutputString("Tests PASSED!!\n");
|
|||
|
break;
|
|||
|
case TRUE:
|
|||
|
sprintf(szBuf, "Tests FAILED, code %lx",
|
|||
|
vApp.m_lparam);
|
|||
|
MessageBox(vApp.m_hwndMain, szBuf, "Ole Test Driver",
|
|||
|
MB_ICONEXCLAMATION | MB_OK);
|
|||
|
break;
|
|||
|
default:
|
|||
|
assert(0);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Reset the got error status
|
|||
|
//
|
|||
|
|
|||
|
vApp.m_fGotErrors = FALSE;
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: RunAllTests
|
|||
|
//
|
|||
|
// Synopsis: Runs all the individual tests in the global list
|
|||
|
//
|
|||
|
// Effects:
|
|||
|
//
|
|||
|
// Arguments: pvArg -- the index at which individual tests
|
|||
|
// start in the global list.
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Returns: void
|
|||
|
//
|
|||
|
// Signals:
|
|||
|
//
|
|||
|
// Modifies:
|
|||
|
//
|
|||
|
// Algorithm:
|
|||
|
//
|
|||
|
// History: dd-mmm-yy Author Comment
|
|||
|
// 06-Feb-94 alexgo author
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
// Tests will be run in the order they appear in the global
|
|||
|
// list.
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
|
|||
|
void RunAllTests( void *pvArg )
|
|||
|
{
|
|||
|
ULONG index = (ULONG)pvArg;
|
|||
|
ULONG i;
|
|||
|
|
|||
|
//find the number of tasks in the list (so we can push
|
|||
|
//them in reverse order).
|
|||
|
|
|||
|
for (i = 0; vrgTaskList[i].szName != 0; i++ )
|
|||
|
{
|
|||
|
;
|
|||
|
}
|
|||
|
|
|||
|
assert( i > 1 );
|
|||
|
|
|||
|
//now push the tasks onto the stack in reverse order.
|
|||
|
|
|||
|
for (i--; i >= index; i-- )
|
|||
|
{
|
|||
|
vApp.m_TaskStack.Push(vrgTaskList + i);
|
|||
|
}
|
|||
|
|
|||
|
//start the first one.
|
|||
|
|
|||
|
vApp.m_TaskStack.PopAndExecute(NULL);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: RunApi
|
|||
|
//
|
|||
|
// Synopsis: Runs the specified Api
|
|||
|
//
|
|||
|
// Effects:
|
|||
|
//
|
|||
|
// Arguments: [pvArg] -- the api to run
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Returns: void
|
|||
|
//
|
|||
|
// Signals:
|
|||
|
//
|
|||
|
// Modifies:
|
|||
|
//
|
|||
|
// Algorithm:
|
|||
|
//
|
|||
|
// History: dd-mmm-yy Author Comment
|
|||
|
// 23-Mar-94 alexgo author
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
|
|||
|
void RunApi( void *pvArg )
|
|||
|
{
|
|||
|
HRESULT hresult;
|
|||
|
|
|||
|
|
|||
|
hresult = (*((HRESULT (*)(void))pvArg))();
|
|||
|
|
|||
|
vApp.Reset();
|
|||
|
vApp.m_wparam = (hresult == NOERROR) ? TEST_SUCCESS : TEST_FAILURE;
|
|||
|
vApp.m_lparam = (LPARAM)hresult;
|
|||
|
vApp.m_message = WM_TESTEND;
|
|||
|
|
|||
|
HandleTestEnd();
|
|||
|
}
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: RunApp
|
|||
|
//
|
|||
|
// Synopsis: Runs the app specified in the argument
|
|||
|
//
|
|||
|
// Effects:
|
|||
|
//
|
|||
|
// Arguments: pvArg -- a string with the app to execute
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Returns: void
|
|||
|
//
|
|||
|
// Signals:
|
|||
|
//
|
|||
|
// Modifies:
|
|||
|
//
|
|||
|
// Algorithm: Create the process and wait for it to finish. The exit
|
|||
|
// status is then returned.
|
|||
|
//
|
|||
|
// History: dd-mmm-yy Author Comment
|
|||
|
// 06-Feb-94 alexgo author
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
|
|||
|
void RunApp( void *pvArg )
|
|||
|
{
|
|||
|
WPARAM wparam = 0;
|
|||
|
DWORD error = 0;
|
|||
|
|
|||
|
#ifdef WIN32
|
|||
|
|
|||
|
PROCESS_INFORMATION procinfo;
|
|||
|
static STARTUPINFO startinfo; //to make it all zero
|
|||
|
|
|||
|
assert(pvArg); //should be a valid ANSI string.
|
|||
|
|
|||
|
startinfo.cb = sizeof(startinfo);
|
|||
|
|
|||
|
if( CreateProcess(NULL, (LPTSTR)pvArg, NULL, NULL, NULL, NULL, NULL,
|
|||
|
NULL, &startinfo, &procinfo) )
|
|||
|
{
|
|||
|
//the process started, now wait for it to finish.
|
|||
|
WaitForSingleObject(procinfo.hProcess, INFINITE);
|
|||
|
|
|||
|
//now get the return code of the process.
|
|||
|
|
|||
|
GetExitCodeProcess(procinfo.hProcess, &error);
|
|||
|
wparam = TEST_UNKNOWN;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
wparam = TEST_FAILURE;
|
|||
|
error = GetLastError();
|
|||
|
}
|
|||
|
|
|||
|
#endif // WIN32
|
|||
|
|
|||
|
// since there will be no WM_TESTEND message, we must do the
|
|||
|
// test end processing ourselves.
|
|||
|
vApp.Reset();
|
|||
|
vApp.m_wparam = wparam;
|
|||
|
vApp.m_lparam = error;
|
|||
|
vApp.m_message = WM_TESTEND;
|
|||
|
|
|||
|
HandleTestEnd();
|
|||
|
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: RunTestOnThread
|
|||
|
//
|
|||
|
// Synopsis: creates a thread to run a test function
|
|||
|
//
|
|||
|
// Effects: creates a new thread
|
|||
|
//
|
|||
|
// Arguments: [pvArg] -- a function pointer to the test function
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Returns: void
|
|||
|
//
|
|||
|
// Signals:
|
|||
|
//
|
|||
|
// Modifies:
|
|||
|
//
|
|||
|
// Algorithm:
|
|||
|
//
|
|||
|
// History: dd-mmm-yy Author Comment
|
|||
|
// 04-Jan-95 t-ScottH author
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
void RunTestOnThread(void *pvArg)
|
|||
|
{
|
|||
|
HANDLE hMainTestThread;
|
|||
|
DWORD dwThreadId = 0;
|
|||
|
|
|||
|
hMainTestThread = CreateThread(
|
|||
|
NULL, // security attributes
|
|||
|
0, // stack size (default)
|
|||
|
(LPTHREAD_START_ROUTINE)pvArg, // address of thread function
|
|||
|
NULL, // arguments of thread function
|
|||
|
0, // creation flags
|
|||
|
&dwThreadId ); // address of new thread ID
|
|||
|
|
|||
|
assert(hMainTestThread);
|
|||
|
|
|||
|
CloseHandle(hMainTestThread);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|