class DemoTester;
typedef CComObject<DemoTester>
CComObjectDemoTester;
virtual Result execute(ULONG ActionId,ULONG numberOfParameters, VARIANT *parameters);
virtual bool open(ULONG numberOfParameters, VARIANT *parameters);
virtual bool close();
enum ActionId
{
ePass,
eFail,
eRandom,
eRandomValue
};
void addAction(unsigned ActionId,
const char *actionType,
const char *description,
...);
The ActionId is one of your enumeration values, actionType is the name of the action to be used in the script, description is a free format text describing what the action does and the variable parameter list is a the list of parameters and return values for the action each list separated by a 0. In this case these calls are as follows:-
addAction(ePass, //Action Id
"Pass", //Action name
"Return TestPassed", //Action Description
0, //End of action parameters
0); //End of action return values
addAction(eFail, //Action Id
"Fail". //Action name
"Return TestFailed", //Action Description
0, //End of action parameters
0); //End of action return values
addAction(eRandom, //Action Id
"Random", //Action name
"Random Passed/Failed", //Action Description
"int value=2", //int parameter with a default value of 2
0, //End of action parameters
0); //End of action return values
addAction(eRandomValue, //Action Id
"RandomValue", //Action name
"Return a random value",//Action Description
"int value=2", //int parameter with a default value of 2
0, //End of action parameters
"int rndval", //int return value
0); //End of action return values
bool DemoTester::open(ULONG numberOfParameters, VARIANT *parameters)
{
return true;
}
bool DemoTester::close()
{
return true;
}
Result DemoTester::execute(ULONG ActionId, ULONG numberOfParameters, VARIANT *parameters)
{
switch(ActionId)
{
case ePass:
return TestPassed;
case eFail:
return TestFailed;
case eRandom:
{
int val = 2; // Default to 2 as per addAction documentation
if ((numberOfParameters == 1) &&
(parameters[0].vt == VT_I4))
{
val = parameters[0].intVal;
}
if (val > 0)
{
return ((rand() % val) == 0) ? TestFailed : TestPassed;
}
break;
}
case eRandomValue:
{
int val = 2; // Default to 2 as per addAction documentation
if ((numberOfParameters == 1) &&
(parameters[0].vt == VT_I4))
{
val = parameters[0].intVal;
}
if (val > 0)
{
value(rand() % val);
return TestPassed;
}
break;
}
}
return TestError;
}
STDMETHOD(create)(unsigned long TesterNumber, ITester * * tester)
{
if (0 != tester)
{
if (TesterNumber == 0)
{
CComObjectDemoTester *temp;
CComObjectDemoTester::CreateInstance(&temp);
temp->AddRef();
*tester = temp;
return S_OK;
}
return E_INVALIDARG;
}
return E_POINTER;
}
STDMETHOD(get_NumberOfTypes)(unsigned long * pVal)
{
if (0 != pVal)
{
*pVal = 1;
return S_OK;
}
return E_POINTER;
}
STDMETHOD(get_Version)(BSTR * pVal)
{
if (0 != pVal)
{
*pVal = CComBSTR("2.0").Detach();
return S_OK;
}
return E_POINTER;
}
COM_INTERFACE_ENTRY2(IDispatch,ITesterCreator1).
Also change the line COM_INTERFACE_ENTRY(ITesterCreator) to COM_INTERFACE_ENTRY2(ITesterCreator,ITesterCreator1).
Demo_C2005.DemoTesterCreator
d = new Demo() # Create a demo tester
i = 0
while i < 20 do # loop for 20 iterations
d.pass()
d.fail()
d.random(5)
r = d.randomValue(10)
sleep(r) # sleep length is random 0 - 9
i++
endwhile
If you wish to add logging information to your tester object you can call the log method at any point. All logging entries from configuration to sever will be displayed in the logger view window and in the log file. If you wish to add debug log entries then use levels finest, finer and fine levels and change the logging level via the Logging->Set Logging Level option.
You can download the demo plug-in at MS2005 C++ Demo Tester.