--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/networkingtestandutils/networkingintegrationtest/scheduleTest/parseline.cpp Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,1562 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This module contains CParseLine and CSuiteDll classes
+// CParseLine contains the functions required to execute
+// a line of test script file.
+// CSuiteDll objects contains information about test suite
+// dlls that have been loaded.
+//
+//
+
+/**
+ @file parseLine.cpp
+*/
+
+// system includes
+#include <e32base.h>
+#include <e32cons.h>
+#include "f32file.h"
+
+// test system includes
+#include "../inc/Log.h"
+#include "../inc/TestUtils.h"
+#include "../inc/TestStep.h"
+#include "../inc/TestSuite.h"
+#include "script.h"
+#include "parseline.h"
+
+/**
+DLL fullpath
+@internalComponent
+*/
+_LIT(KTxtDLLpath,"c:\\;c:\\system\\libs\\;d:\\;d:\\system\\libs\\");
+
+#ifdef __WINS__
+/**
+Holds ced_exe DLL string constant
+@internalComponent
+*/
+_LIT(KTxtcedDLL,"ced_exe.dll");
+#endif
+
+/**
+Thread name format
+@internalComponent
+*/
+_LIT(KThreadNameFmt, "DoTestThread_%d");
+
+/**
+Maximum test thread heap size
+@internalComponent
+*/
+const TInt KMaxTestThreadHeapSize = 0x10000;
+
+/**
+extern global data - pointer to test utils
+@internalComponent
+*/
+GLDEF_D CTestUtils * pTestUtils;
+
+/**
+extern global data - pointer to Log system
+@internalComponent
+*/
+GLDEF_D CLog * pLogSystem;
+
+/**
+extern global data - running in automated, non-interactive, stop-for-nothing mode
+@internalComponent
+*/
+GLDEF_D TBool automatedMode = EFalse;
+
+/**
+extern global data - pointer to console
+@internalComponent
+*/
+GLDEF_D CConsoleBase * console;
+
+
+CParseLine::CParseLine():iTestVerdict(EPass)
+/**
+constructor
+*/
+ {}
+void CParseLine::ConstructL(CScript * ptr)
+/**
+create a new Array to store the test steps in
+*/
+ {
+ // create a new Array to store the test steps in
+ iArrayLoadedSuiteDll = new(ELeave) CArrayPtrFlat<CSuiteDll>(1);
+
+ iScript = ptr;
+ iSeverity = ESevrAll;
+ iBreakOnError = EFalse;
+ iThreadNameSuffix = User::TickCount();
+ }
+
+CParseLine* CParseLine::NewL( CScript * ptr)
+/**
+NewL static constructor
+*/
+ {
+ CParseLine * self = new(ELeave) CParseLine;
+ CleanupStack::PushL(self);
+ self->ConstructL(ptr);
+ CleanupStack::Pop();
+ return self;
+ }
+
+CParseLine::~CParseLine()
+/**
+Delete all objects in iArrayLoadedSuiteDll.
+This will unload any loaded test suite DLLS.
+*/
+ {
+
+ // unload DLLs and their records
+ if (iArrayLoadedSuiteDll)
+ {
+ // delete all objects in iArrayLoadedSuiteDll
+ // the destructors will unload any loaded DLLS
+ iArrayLoadedSuiteDll->ResetAndDestroy();
+ delete iArrayLoadedSuiteDll;
+ }
+
+ }
+
+void CParseLine::ProcessLineL(const TPtrC8 &aNrrowline, TInt8 lineNo)
+/**
+Process a line from the script file
+
+@param aNrrowline The line to be parsed
+@param lineNo The current line number
+*/
+ {
+ // make a local unicode buffer
+ TBuf<MAX_SCRIPT_LINE_LENGTH> LineBuf;
+ //If the lenght of the command line is more than MAX_SCRIPT_LINE_LENGTH=200
+ //Igore the line with Warning and the test result would be Inconclusive
+ if (aNrrowline.Length() > LineBuf.MaxLength())
+ {
+ TLex8 lex(aNrrowline);
+ // start at the begining
+ TPtrC8 token=lex.NextToken();
+ TInt firstChar = aNrrowline[0];
+ if(firstChar == '\r' || firstChar == '\n' || firstChar == '#' || firstChar == '/' || token.CompareF((TPtrC8((const TText8 *)("PRINT")))) == 0 || token.CompareF((TPtrC8((const TText8 *)("PAUSE_AT_END")))) == 0 || token.CompareF((TPtrC8((const TText8 *)("PAUSE")))) == 0)
+ {
+ // ignore command line with comments
+ }
+ else
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("WARNING : Command line too Long (Exceeds length of 200) Line:%d"), lineNo);
+ iTestVerdict = EInconclusive;
+ }
+
+ return;
+ }
+
+ LineBuf.Fill( '\0',MAX_SCRIPT_LINE_LENGTH);
+
+ // convert the narrow script file to Unicode
+ TFileName testnameU;
+ testnameU.Copy(aNrrowline);
+
+ // find the end of the line
+ TInt end= testnameU.Locate('\n');
+
+ // copy the line into LineBuf
+ if ((end != -1) && (end < MAX_SCRIPT_LINE_LENGTH))
+ LineBuf = testnameU.Left(end-1);
+ else
+ LineBuf = testnameU;
+
+ // the parser relies on spaces between tokens. Commas are
+ // allowed but are just replaced with spaces
+ while ( LineBuf.Locate(TChar(',')) != KErrNotFound )
+ {
+ // found a comma so replave with space
+ LineBuf.Replace(LineBuf.Locate(TChar(',')),1,_L(" "));
+ }
+
+ // for debugging display the line with a line no
+#ifdef SCRIPT_DEBUG
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Line:%d %s "), lineNo, LineBuf.Ptr() );
+#endif
+
+ // if there has been a failure and the user has selected
+ // x then the next commands in the script are skipped until
+ // a test complete statement is found
+ if ( iBreakOnError )
+ {
+ if (LineBuf.Find(_L("TEST_COMPLETE"))==0)
+ {
+ TestComplete( LineBuf );
+
+ // reset flag now test complete found
+ iBreakOnError = EFalse;
+ }
+
+ // do not process the rest of the line
+ return;
+ }
+
+ // check the line for command keywords
+ if ((LineBuf.Find(_L("//"))==0) || (LineBuf.Find(_L("#"))==0))
+ {
+ // ignore comments
+ }
+ else
+ {
+ // use Tlex to decode the cmd
+ TLex lex(LineBuf);
+ // start at the begining
+ TPtrC token=lex.NextToken();
+
+ if (token.CompareF(_L("LOAD_SUITE"))==0)
+ {
+ LoadSuiteL( LineBuf );
+ }
+ else if (token.CompareF(_L("RUN_SCRIPT"))==0)
+ {
+ RunScriptL( LineBuf );
+ }
+ else if (token.CompareF(_L("RUN_TEST_STEP"))==0)
+ {
+ RunTestStep( LineBuf );
+ }
+ else if (token.CompareF(_L("RUN_PANIC_STEP"))==0)
+ {
+ RunPanicTestStep( LineBuf );
+ }
+ else if (token.CompareF(_L("RUN_UTILS"))==0)
+ {
+ RunUtil( LineBuf );
+ }
+ else if (token.CompareF(_L("CED"))==0)
+ {
+ RunCed( LineBuf );
+ }
+ else if (token.CompareF(_L("RUN_PROGRAM"))==0)
+ {
+ RunProgram( LineBuf );
+ }
+ else if (token.CompareF(_L("UNLOAD"))==0)
+ {
+ Unload(LineBuf);
+ }
+ else if (token.CompareF(_L("HEAP_MARK"))==0)
+ {
+ HeapMark();
+ }
+ else if (token.CompareF(_L("HEAP_MARKEND"))==0)
+ {
+ HeapCheck();
+ }
+ else if (token.CompareF(_L("REQUEST_MARK"))==0)
+ {
+ RequestMark();
+ }
+ else if (token.CompareF(_L("REQUEST_CHECK"))==0)
+ {
+ RequestCheck();
+ }
+ else if (token.CompareF(_L("HANDLES_MARK"))==0)
+ {
+ HandlesMark();
+ }
+ else if (token.CompareF(_L("HANDLES_CHECK"))==0)
+ {
+ HandlesCheck();
+ }
+ else if (token.CompareF(_L("PRINT"))==0)
+ {
+ scriptPrint( LineBuf );
+ }
+ else if (token.CompareF(_L("DELAY"))==0)
+ {
+ Delay( LineBuf );
+ }
+ else if (token.CompareF(_L("SEVERITY"))==0)
+ {
+ SetSeverity( LineBuf );
+ }
+ else if (token.CompareF(_L("PAUSE_AT_END"))==0)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Pause at end enabled "));
+ iScript->iPauseAtEnd = ETrue;
+ }
+ else if (token.CompareF(_L("MULTITHREAD"))==0)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Multithread operation enabled "));
+ iScript->iMultThread = ETrue;
+ }
+ else if (token.CompareF(_L("SINGLETHREAD"))==0)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Single thread operation enabled "));
+ iScript->iMultThread = EFalse;
+ }
+ else if (token.CompareF(_L("PAUSE"))==0)
+ {
+ iScript->Pause();
+ }
+ else if (token.CompareF(_L("BREAK_ON_ERROR"))==0)
+ { // if the current test verdict is not PASS
+ // give the user the chance to quit
+ if ( iTestVerdict != EPass )
+ iBreakOnError = iScript->BreakOnError();
+ }
+ else if (token.CompareF(_L("TEST_COMPLETE"))==0)
+ {
+ // use Tlex to decode the cmd line
+ TestComplete( LineBuf );
+ }
+ else if (token.CompareF(_L("LOG_SETTINGS"))==0)
+ {
+ // use Tlex to decode the cmd line
+ LogSettings( LineBuf );
+ }
+ else if (LineBuf.Length()==0)
+ {
+ // ignore blank lines
+ }
+ else
+ {
+ // failed to decode line
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Error in script line:%d - %s "), lineNo, LineBuf.Ptr() );
+ }
+ }
+
+}
+
+void CParseLine::TestComplete( const TDesC& Text )
+/**
+This function implements the script test complete keyword
+
+@param The contents of Text are added to the log file with the result
+*/
+ {
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC token=lex.NextToken();
+
+ // step over the keyword
+ token.Set(lex.NextToken());
+
+ if (token.Length() !=0 )
+ iCurrentStepName = token;
+
+ // Test cases must be careful to clean up after themselves - any stray signals generated in a test case
+ // lead here to automatic failure of the step. They are caught here to allow further cases to run
+ // without crashing.
+ while (RThread().RequestCount()!=0)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Warning! Test case generated stray signal! (cleaning up)") );
+ User::WaitForAnyRequest();
+ iTestVerdict = EFail;
+ }
+
+ // add the current result to the script
+ iScript->AddResult( iTestVerdict );
+
+ // reset for next test
+ iTestVerdict = EPass;
+ }
+
+void CParseLine::scriptPrint( const TDesC& Text )
+/**
+This function implements the script PRINT Keyword
+
+@param Text The text to be added to the log file
+*/
+ {
+ // display the text after the PRINT and 1 space = 6
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("%s "), (Text.Ptr()+6) );
+ }
+
+void CParseLine::Delay( const TDesC& Text )
+/**
+This function implements the script Delay Keyword
+
+@param Text contains the time to delay in milliseconds
+*/
+ {
+ // if the test has already failed skip the delay
+ if ( iTestVerdict != EPass )
+ {
+ pLogSystem->Log(_L("skipped delay as test has already failed") );
+ return;
+ }
+
+ // get the required time for the delay
+ // first get the value as a string
+ TLex TimeOut(Text);
+ TimeOut.NextToken();
+ TPtrC token=TimeOut.NextToken();
+
+ // convert the value into a int
+ TLex timeoutLex(token);
+ TInt GuardTimerValue =2500;
+ if (timeoutLex.Val(GuardTimerValue) != KErrNone )
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr,
+ _L("error in guard timer value could not decode >%S< as value"),
+ &token,
+ GuardTimerValue );
+ return;
+ }
+
+ // display the text after the PRINT and 1 space = 6
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr,
+ _L("Delay for %d mS"), GuardTimerValue );
+
+ // wait for the required delay
+ RTimer GuardTimer;
+ GuardTimer.CreateLocal(); // create for this thread
+ TRequestStatus TimerStatus;
+ GuardTimer.After(TimerStatus,GuardTimerValue * 1000);
+ User::WaitForRequest(TimerStatus);
+ GuardTimer.Cancel();
+
+ }
+
+void CParseLine::SetSeverity( const TDesC& Text )
+/**
+This function implements the script SetSeverity Keyword
+
+@param Text contains the severity level
+*/
+ {
+ // get the required time for the delay
+ // first get the value as a string
+ TLex SeverityOut(Text);
+ SeverityOut.NextToken();
+ TPtrC token=SeverityOut.NextToken();
+
+ // convert the value into a int
+ TLex Severity(token);
+ TInt SeverityValue = 7;
+ if (Severity.Val(SeverityValue) != KErrNone )
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr,
+ _L("Error in severity level value could not decode >%S< as value"),
+ &token,
+ SeverityValue );
+ return;
+ }
+
+ if(SeverityValue & ~7)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__,
+ ESevrErr, _L("Error in severity value."));
+ SeverityValue = 7;
+ return;
+ }
+ else
+ {
+ iSeverity = SeverityValue;
+
+ TInt NoOfDlls = iArrayLoadedSuiteDll->Count();
+ for ( TInt i=0; i < NoOfDlls; i++ )
+ {
+ CSuiteDll * ptrSuite = iArrayLoadedSuiteDll->At(i);
+ ptrSuite->iTestSuite->SetSeverity(iSeverity);
+ }
+ }
+
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Severity is set to %d"), SeverityValue );
+ }
+
+void CParseLine::RunScriptL( const TDesC& Text )
+/**
+This function implements the script RUN_SCRIPT Keyword
+
+@param Text contains the script file name
+*/
+ {
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC token=lex.NextToken();
+
+ // step over the keyword
+ token.Set(lex.NextToken());
+
+ // format for printing
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("RUN_SCRIPT %S"),&token );
+
+ // create a new Script object (but use the current parse
+ // as it has the dll loaded record
+ CScript* newScript=CScript::NewL(this);
+ CleanupStack::PushL(newScript);
+
+ // read in the script file
+ TFileName scriptFileName=token;
+ if ( newScript->OpenScriptFile( scriptFileName ))
+ {
+ // process it
+ iTestVerdict = newScript->ExecuteScriptL();
+
+ /* verdicts for scripts are not really useful so forget! */
+ /* pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("The final result for test script %S was %s"),
+ &token,
+ pLogSystem->TestResultText( iTestVerdict ) ); */
+
+ // add results from the new script to the owner script
+ iScript->AddResult( newScript );
+ }
+ else
+ {
+ // failed to find script so verdict incloncusive
+ iTestVerdict = EInconclusive;
+ }
+
+ CleanupStack::PopAndDestroy(newScript);
+
+ }
+
+void CParseLine::RunTestStep( const TDesC& Text )
+/**
+RunTestStep
+
+@param Text contains the test step name
+@return KErrNone or an error code
+*/
+ {
+ TPtrC suite, step, config;
+
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC timeout=lex.NextToken();
+
+ // step over the keyword
+ timeout.Set(lex.NextToken());
+
+ // get the other parameters
+ suite.Set(lex.NextToken());
+ step.Set(lex.NextToken());
+ config.Set(lex.NextToken());
+
+ // save the name of the current test step
+ iCurrentStepName = step;
+
+ // conert the guard timer value to a TInt
+ TLex lexTimeOut(timeout);
+ TInt GuardTimerValue;
+ if (lexTimeOut.Val(GuardTimerValue) != KErrNone )
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("error in guard timer value:%S using default 100mS"), &timeout);
+ GuardTimerValue = 100;
+ }
+
+ // log the start of a test step
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("RUN_TEST_STEP:%S suite:%S timeout:%dmS config:%S"),
+ &step,
+ &suite,
+ GuardTimerValue,
+ &config );
+
+ // run the test step
+ enum TVerdict CurrentTestVerdict;
+
+ // check which thread mode selected!
+ if ( iScript->iMultThread )
+ CurrentTestVerdict = DoTestNewThread( suite, step, GuardTimerValue, config );
+ else
+ CurrentTestVerdict = DoTestCurrentThread( suite, step, config );
+
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("TEST_STEP:%S returned:%s "), &step, pLogSystem->TestResultText(CurrentTestVerdict));
+
+ // this result is only significant if every thing else has passed
+ if ( iTestVerdict == EPass )
+ iTestVerdict = CurrentTestVerdict;
+
+ }
+
+void CParseLine::RunPanicTestStep( const TDesC& Text )
+/**
+This function implements the script RUN_PANIC_STEP Keyword.
+This step is expected to panic and gives a pass result if it panics
+and a fail if it does not.
+
+@param Text contains the test step name
+*/
+ {
+ TPtrC suite, step, config;
+
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC timeout=lex.NextToken();
+
+ // step over the keyword
+ timeout.Set(lex.NextToken());
+
+ // get the other parameters
+ suite.Set(lex.NextToken());
+ step.Set(lex.NextToken());
+ config.Set(lex.NextToken());
+
+ // save the name of the current test step
+ iCurrentStepName = step;
+
+ // conert the guard timer value to a TInt
+ TLex lexTimeOut(timeout);
+ TInt GuardTimerValue;
+ if (lexTimeOut.Val(GuardTimerValue) != KErrNone )
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("error in guard timer value:%S using default 10000"), &timeout);
+ GuardTimerValue = 1000000;
+ }
+
+ // log the start of a test step
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("RUN_PANIC_STEP:%S suite:%S timeout:%dmS config:%S"),
+ &step,
+ &suite,
+ GuardTimerValue,
+ &config );
+
+ // run the test step
+ enum TVerdict CurrentTestVerdict;
+
+ // check which thread mode selected!
+ CurrentTestVerdict = DoPanicTest( suite, step, GuardTimerValue, config );
+
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("TEST_STEP:%S returned:%s "), &step, pLogSystem->TestResultText(CurrentTestVerdict));
+
+ // this result is only significant if every thing else has passed
+ if ( iTestVerdict == EPass )
+ iTestVerdict = CurrentTestVerdict;
+
+ }
+
+
+void CParseLine::RunUtil( const TDesC& Text )
+/**
+This function implements the script RUN_UTILS Keyword
+
+@param Text contains the util name
+*/
+ {
+ // Call the utils
+ pTestUtils->RunUtils( Text );
+ }
+
+void CParseLine::Reboot(void)
+/**
+This function implements the script REBOOT Keyword
+*/
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("REBOOT ") );
+ }
+
+TInt CParseLine::threadfn ( TAny * ptr )
+/**
+Static function to call DoTestStep() which is run
+in a separate thread
+
+@param ptr Contains the test step name, and configuration parameters passed to the new thread.
+@return The test result as a TVerdict.
+*/
+ {
+ // get clean-up stack
+ CTrapCleanup* Cleanup=CTrapCleanup::New();
+
+ // get the data for the test
+ CStepData * data = (CStepData *)ptr;
+
+ // do the test step
+ TVerdict result = data->iSuite->iTestSuite->DoTestStep( data->step, data->config);
+
+ // done with the clean up stack
+ delete Cleanup;
+
+ // return the test result
+ return result;
+ }
+
+enum TVerdict CParseLine::DoTestNewThread(TPtrC suite, TPtrC step, TInt GuardTimerValue, const TPtrC &config)
+/**
+Call the test step in the correct suite
+
+@param suite The test suite to use.
+@param step The test step name
+@param the guard timer in milliseconds
+@param reference to the configuration file
+@return The test result as a TVerdict
+*/
+ {
+ // get the number of suites loaded
+ TInt NoOfDlls = iArrayLoadedSuiteDll->Count();
+
+ TVerdict result = ETestSuiteError;
+
+ // search the list of loaded test suite DLLs for the required one
+ for ( TInt i=0; i < NoOfDlls; i++ )
+ {
+ CSuiteDll * ptrSuite = iArrayLoadedSuiteDll->At(i);
+
+ if(ptrSuite->SuiteNameMatch(suite))
+ {
+
+ // do a test in a new thread
+ RThread NewThread;
+
+ CStepData data;
+ data.step = step;
+ data.config = config;
+ data.iSuite = ptrSuite;
+
+ // run in a new thread, with a new heap
+ TBuf<32> threadName;
+ threadName.Format(KThreadNameFmt, iThreadNameSuffix++);
+ TInt res=NewThread.Create(threadName,
+ threadfn,
+ KDefaultStackSize,
+ KMinHeapSize,
+ KMaxTestThreadHeapSize,
+ &data);
+
+ if (res != KErrNone)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("unable to create test thread ") );
+ return EFail;
+ }
+
+ // start the thread and request the status
+ TRequestStatus ThreadStatus;
+ NewThread.Logon(ThreadStatus);
+
+ // if the guard timer value is -1 don't time at all
+ if ( GuardTimerValue == -1 )
+ {
+ // no guard timer
+ NewThread.Resume();
+ User::WaitForRequest( ThreadStatus );
+ }
+ else
+ {
+ // wait for either test thread or timer to end
+ RTimer GuardTimer;
+ GuardTimer.CreateLocal(); // create for this thread
+ TRequestStatus TimerStatus;
+ NewThread.Resume();
+ GuardTimer.After(TimerStatus,GuardTimerValue * 1000);
+ User::WaitForRequest(ThreadStatus, TimerStatus);
+ if (TimerStatus==KRequestPending)
+ {
+ GuardTimer.Cancel();
+ User::WaitForRequest(TimerStatus);
+ }
+ GuardTimer.Close();
+ }
+
+ // get the test result
+ result = (TVerdict)ThreadStatus.Int();
+
+ // check terminated ok
+ switch(NewThread.ExitType() )
+ {
+ case EExitTerminate:
+ case EExitKill:
+ break;
+ case EExitPanic:
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("thread had a panic") );
+ result = EFail;
+ break;
+ case EExitPending:
+ // if the thread is still pending then the guard timer must have expired
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("thread timed out") );
+ // kill the test step thread
+ NewThread.Kill(1);
+ User::WaitForRequest(ThreadStatus);
+ result = EFail;
+ break;
+ default:
+ break;
+ }
+
+ // done with the test thread
+ NewThread.Close();
+
+ // send the log data a line at a time
+ // find the end of the first line
+ TInt nl= ptrSuite->iTestSuite->iLogData.Locate(TChar('\n'));
+
+ // get each line in turn
+ while ( nl != KErrNotFound )
+ {
+ // display line
+ TPtrC16 line = ptrSuite->iTestSuite->iLogData.Left(nl);
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("%S"), &line );
+
+ // remove the line displayed
+ ptrSuite->iTestSuite->iLogData.Replace(0,nl+1,_L(""));
+
+ // find the next newline
+ nl= ptrSuite->iTestSuite->iLogData.Locate(TChar('\n'));
+ }
+
+ // return the test verdict
+ return result;
+ }
+ }
+
+ // the required suite has not been found
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Error in test step:%S cannot find suite:%S" ),
+ &step,
+ &suite );
+
+ return ETestSuiteError;
+}
+
+// DoTest
+enum TVerdict CParseLine::DoPanicTest(TPtrC suite, TPtrC step, TInt GuardTimerValue, const TPtrC &config)
+/**
+Call the test step which is expected to Panic
+
+@param suite The test suite to use.
+@param step The test step name
+@param the guard timer in milliseconds
+@param reference to the configuration file
+@return The test result as a TVerdict
+*/
+ {
+ // get the number of suites loaded
+ TInt NoOfDlls = iArrayLoadedSuiteDll->Count();
+
+ TVerdict result;
+
+ // search the list of loaded test suite DLLs for the required one
+ for ( TInt i=0; i < NoOfDlls; i++ )
+ {
+ CSuiteDll * ptrSuite = iArrayLoadedSuiteDll->At(i);
+
+ if(ptrSuite->SuiteNameMatch(suite))
+ {
+
+ // do a test in a new thread
+ RThread t;
+
+ CStepData data;
+ data.step = step;
+ data.config = config;
+ data.iSuite = ptrSuite;
+
+ // run in a new thread, with a new heap
+ TBuf<32> threadName;
+ threadName.Format(KThreadNameFmt, iThreadNameSuffix++);
+ TInt res=t.Create(threadName,
+ threadfn,
+ KDefaultStackSize,
+ KMinHeapSize,
+ KMaxTestThreadHeapSize,
+ &data);
+
+ if (res != KErrNone)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("unable tp create test thread ") );
+ return EFail;
+ }
+
+ // start the thread and request the status
+ TRequestStatus ThreadStatus;
+ t.Logon(ThreadStatus);
+
+ // if the guard timer value is -1 don't time at all
+ if ( GuardTimerValue == -1 )
+ {
+ // no guard timer
+ t.Resume();
+ User::WaitForRequest( ThreadStatus );
+ }
+ else
+ {
+ // wait for either test thread or timer to end
+ RTimer GuardTimer;
+ GuardTimer.CreateLocal(); // create for this thread
+ TRequestStatus TimerStatus;
+ t.Resume();
+ GuardTimer.After(TimerStatus,GuardTimerValue * 1000);
+ User::WaitForRequest(ThreadStatus, TimerStatus);
+ GuardTimer.Cancel();
+ User::WaitForAnyRequest();
+ }
+
+ // get the test result
+ result = (TVerdict)ThreadStatus.Int();
+
+ TExitCategoryName category(t.ExitCategory());
+ // check terminated ok
+ switch(t.ExitType() )
+ {
+ case EExitPanic:
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Panic occurred of category %S and reason %d"), &category, t.ExitReason());
+ result =
+ category.Left(4)==_L("KERN") || category.Left(3)==_L("E32") ? EFail : EPass;
+ break;
+ case EExitPending:
+ // if the thread is still pending then the guard timer must have expired
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("thread timed out") );
+ // kill the test step thread
+ t.Kill(1);
+ result = EFail;
+ break;
+ case EExitTerminate:
+ case EExitKill:
+ default:
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Test did not panic so fail") );
+ result = EFail;
+ break;
+ }
+
+ // done with the test thread
+ t.Close();
+
+ // send the log data a line at a time
+ // find the end of the first line
+ TInt nl= ptrSuite->iTestSuite->iLogData.Locate(TChar('\n'));
+
+ // get each line in turn
+ while ( nl != KErrNotFound )
+ {
+ // display line
+ TPtrC16 line = ptrSuite->iTestSuite->iLogData.Left(nl);
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("%S"), &line );
+
+ // remove the line displayed
+ ptrSuite->iTestSuite->iLogData.Replace(0,nl+1,_L(""));
+
+ // find the next newline
+ nl= ptrSuite->iTestSuite->iLogData.Locate(TChar('\n'));
+ }
+
+ // return the test verdict
+ return result;
+ }
+ }
+
+ // the required suite has not been found
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Error in test step:%S cannot find suite:%S" ),
+ &step,
+ &suite );
+
+ return ETestSuiteError;
+}
+
+// DoTestCurrentThread
+enum TVerdict CParseLine::DoTestCurrentThread(TPtrC suite, TPtrC step, TPtrC config)
+/**
+Call the test step in the current Thread
+
+@param suite The test suite to use.
+@param step The test step name
+@param reference to the configuration file
+@return The test result as a TVerdict
+*/
+ {
+ // get the number of suites loaded
+ TInt NoOfDlls = iArrayLoadedSuiteDll->Count();
+
+ TVerdict result;
+
+ // search the list of loaded test suite DLLs for the required one
+ for ( TInt i=0; i < NoOfDlls; i++ )
+ {
+
+ CSuiteDll * ptrSuite = iArrayLoadedSuiteDll->At(i);
+
+ if(ptrSuite->SuiteNameMatch(suite))
+ {
+ // execute in the current thread
+ result = ptrSuite->iTestSuite->DoTestStep(step, config);
+
+ // send the log data a line at a time
+ // find the end of the first line
+ TInt nl= ptrSuite->iTestSuite->iLogData.Locate(TChar('\n'));
+
+ // get each line in turn
+ while ( nl != KErrNotFound )
+ {
+ // display line
+ TPtrC16 line = ptrSuite->iTestSuite->iLogData.Left(nl);
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("%S"), &line );
+
+ // remove the line displayed
+ ptrSuite->iTestSuite->iLogData.Replace(0,nl+1,_L(""));
+
+ // find the next newline
+ nl= ptrSuite->iTestSuite->iLogData.Locate(TChar('\n'));
+ }
+
+ // return the test verdict
+ return result;
+ }
+ }
+
+ // the required suite has not been found
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Error in test step:%S cannot find suite:%S" ),
+ &step,
+ &suite );
+
+ return ETestSuiteError;
+ }
+
+
+
+// RunCed
+void CParseLine::RunCed( const TDesC& Text )
+/**
+This function runs CED the commdb tool....
+
+@param text The name of tge ced.cfg file to use
+*/
+ {
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC token=lex.NextToken();
+
+ // step over the keyword "ced" and get the rest
+ token.Set(lex.Remainder());
+
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Run Ced parameters %S"), &token);
+
+ // In the ARM and EKA2 emulator builds run ced as a new process
+ RProcess ced;
+ TBuf<100> CmdLine;
+ CmdLine.Format(_L("-i %S"),&token);
+ TInt ret = ced.Create( _L("z:\\system\\libs\\ced.exe"), CmdLine );
+
+ if ( ret != KErrNone )
+ {
+ TPtrC Errortxt = CLog::EpocErrorToText(ret);
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Failed to start ced process %S"),&Errortxt );
+ return;
+ }
+ else
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("ced.exe started %S"), &CmdLine);
+
+ // create and start a guard timer
+ RTimer GuardTimer;
+ TRequestStatus TimerStatus(KRequestPending);
+ GuardTimer.CreateLocal(); // create for this thread
+ GuardTimer.After(TimerStatus,120 * 1000 *1000);
+
+ // start ced
+ TRequestStatus ThreadStatus;
+ ced.Logon(ThreadStatus);
+ ced.Resume();
+
+ // wait for guard timer or ced
+ User::WaitForRequest(ThreadStatus, TimerStatus);
+
+ // cancel the guard timer now a request has happened
+ GuardTimer.Cancel();
+
+ if(ThreadStatus==KRequestPending)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("<font size=5 color=FF0000>CED TIMED OUT</font>\n") );
+ }
+
+ User::WaitForAnyRequest(); //Need this to balance up the requests/completions
+ //as User::WaitForRequest(ThreadStatus, TimerStatus) only makes one request
+
+ // check return type
+ TVerdict cedVerdict = EInconclusive;
+ TExitType cedExitType = ced.ExitType();
+ if ( cedExitType == EExitTerminate || cedExitType == EExitKill )
+ {
+ TInt exitReason = ced.ExitReason();
+ if(exitReason == 0)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("ced exited with success") );
+ cedVerdict = EPass;
+ }
+ else
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("ced exited with failure %d"), exitReason );
+ }
+ else
+ {
+ // Describe what specifically happened
+ if ( cedExitType == EExitPanic)
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("ced exited with EExitPanic") );
+ else if ( cedExitType == EExitPending)
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("ced still running (!)") );
+ else
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("ced exited with unknown type %d"), cedExitType );
+ }
+ // this result is only significant if every thing else has passed
+ if( iTestVerdict == EPass )
+ {
+ iTestVerdict = cedVerdict;
+ }
+ }
+
+
+
+}
+
+void CParseLine::RunProgram( const TDesC& Text )
+/**
+This function implements the script RunProgram command
+
+@param Text The name of the program to run
+*/
+ {
+ TPtrC Param;
+
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC token=lex.NextToken();
+
+ // step over the keyword
+ token.Set(lex.NextToken());
+
+ // get the parameters
+ Param.Set(lex.NextToken());
+
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Run Program "));
+
+#ifdef __WINS__
+ // this is not supportted in WINS builds
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Warning RUN_PROGRAM is not supported on WINS") );
+#endif
+
+ // In the ARM build run program as a new process
+ // use the rest of the text as parameters
+ RProcess program;
+ TInt ret = program.Create( token, lex.Remainder() );
+
+ if ( ret != KErrNone )
+ {
+ TPtrC Errortxt = CLog::EpocErrorToText(ret);
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Failed to start process %S"),&Errortxt );
+ return;
+ }
+ else
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Program started") );
+
+ // start program
+ TRequestStatus ThreadStatus;
+ program.Logon(ThreadStatus);
+ program.Resume();
+
+ // wait for guard timer or ced
+ User::WaitForRequest(ThreadStatus);
+
+ // check return type
+ if ( program.ExitType() == EExitPanic)
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("program returned EExitPanic") );
+ else if ( program.ExitType() == EExitPending)
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("program returned EExitPending") );
+ else
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("program returned EExitTerminate") );
+ }
+ }
+
+void CParseLine::LogSettings( const TDesC& Text )
+/**
+This function parses "LOG_SETTNGS" command
+Command format is LOG_SETTINGS "put src." (1/0),
+"HTML format" (1/0)
+
+@param string to parse
+*/
+ {
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC token=lex.NextToken();
+
+ // step over the keyword
+ //Get information about source
+ token.Set(lex.NextToken());
+
+ TLex oSrcLex(token);
+ TInt isSrc = ETrue; //Shall we put src information?
+ if (oSrcLex.Val(isSrc) != KErrNone )
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr,
+ _L("Error in LOG_SETTINGS value could not decode >%S< as value(0/1)"),
+ &token);
+ }
+ else
+ {
+ pLogSystem->SetPutSrcInfo(isSrc) ;
+ }
+ //Get information about format
+ //TInt isHtml = ETrue; //Shall we use HTML log format?
+ token.Set(lex.NextToken());
+ TLex oHtmlLex(token);
+
+ if (oHtmlLex.Val(isSrc) != KErrNone )
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr,
+ _L("Error in LOG_SETTINGS value could not decode >%S< as value(0/1)"),
+ &token);
+ }
+ else
+ {
+ pLogSystem->SetHtmlLogMode(isSrc) ;
+ }
+ }
+
+
+void CParseLine::LoadSuiteL( const TDesC& Text )
+/**
+LoadSuite
+This function loads a required test suite DLL
+It also creates a CtestSuite object as a record
+of the loaded dll
+
+@param suite dll name
+*/
+ {
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC token=lex.NextToken();
+
+ // step over the keyword
+ token.Set(lex.NextToken());
+
+
+ RLibrary lib;
+ TInt err = lib.Load(token, KTxtDLLpath);
+ if (err == KErrNone)
+ {
+ lib.Close();
+ }
+
+ if ( err==KErrNotFound )
+ {
+ // this is not going to load !
+ // pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Test suite %S could not be found"),&token );
+ //return;
+ }
+
+ // check not already loaded
+ // by searching the list of loaded test suite DLLs for the required one
+ // start with the number of suites loaded
+ TInt NoOfDlls = iArrayLoadedSuiteDll->Count();
+ for ( TInt i=0; i < NoOfDlls; i++ )
+ {
+ CSuiteDll * ptrSuite = iArrayLoadedSuiteDll->At(i);
+
+ // check the names
+ if ( ptrSuite->iName.CompareF( token ) == 0 )
+ {
+ // this suite DDL is already loaded
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("warning Test suite %S already loaded not re-loaded"),&token );
+ return;
+ }
+ }
+
+ // create a new suitedll object to store info on loaded DLL
+ CSuiteDll * newRef = CSuiteDll::NewL( token );
+ CleanupStack::PushL(newRef);
+
+ // set default severity and logging system
+ newRef->iTestSuite->SetSeverity(iSeverity);
+ newRef->iTestSuite->SetLogSystem(pLogSystem);
+
+ // add to data
+ iArrayLoadedSuiteDll->AppendL( newRef );
+ CleanupStack::Pop(newRef);
+ }
+
+// unload all the loaded DLLS
+void CParseLine::Unload(const TDesC& Text)
+/**
+This function implements the script Unload command
+*/
+ {
+ // use Tlex to decode the cmd line
+ TLex lex(Text);
+
+ // start at the begining
+ TPtrC token=lex.NextToken();
+
+
+ if (!lex.Eos())
+ {
+ // step over the keyword
+ token.Set(lex.NextToken());
+ TInt NoOfDlls = iArrayLoadedSuiteDll->Count();
+ for ( TInt i=0; i < NoOfDlls; i++ )
+ {
+ CSuiteDll * ptrSuite = iArrayLoadedSuiteDll->At(i);
+
+ // check the names
+ if ( ptrSuite->iName.CompareF( token )==0 )
+ {
+ if (NoOfDlls==1)
+ {
+ iArrayLoadedSuiteDll->ResetAndDestroy();
+ }
+ else
+ {
+ // this suite DDL is to be unloaded.
+ iArrayLoadedSuiteDll->Delete(i);
+ iArrayLoadedSuiteDll->Compress();
+ delete ptrSuite;
+ }
+ return;
+ }
+ }
+ }
+ else
+ {
+ if (iArrayLoadedSuiteDll)
+ {
+ // unload all the loaded DLLS and their records
+ iArrayLoadedSuiteDll->ResetAndDestroy();
+ }
+ }
+ }
+
+void CParseLine::HeapMark(void)
+/**
+This function implements the script HeapMark command
+*/
+ {
+ __UHEAP_MARK;
+ }
+
+
+void CParseLine::HeapCheck(void)
+/**
+This function implements the script HeapCheck command
+*/
+ {
+ __UHEAP_MARKEND;
+ }
+
+void CParseLine::RequestMark(void)
+/**
+This function implements the script RequestMark command
+*/
+ {
+ // get number of outstanding requetsts on thread before we run the test
+ iReqsAtStart = RThread().RequestCount();
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Requests at the start %d "),iReqsAtStart);
+ }
+
+
+void CParseLine::RequestCheck(void)
+/**
+This function implements the script RequestCheck command
+*/
+ {
+ // check the number of outstanding requests against recorded value
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Requests at the start %d now %d"),
+ iReqsAtStart,
+ RThread().RequestCount() );
+
+ if ( iReqsAtStart != RThread().RequestCount())
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Test failed on requests count"));
+
+ // this result is only significant if every thing else has passed
+ if ( iTestVerdict == EPass )
+ iTestVerdict = EFail;
+
+ }
+ }
+
+
+void CParseLine::HandlesMark(void)
+/**
+This function implements the script HandlesMark command
+*/
+ {
+ // get number of Handles *before* we start the program
+ RThread().HandleCount(iProcessHandleCountBefore, iThreadHandleCountBefore);
+
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Process handles count %d thread handle count %d"),
+ iProcessHandleCountBefore,
+ iThreadHandleCountBefore );
+ }
+
+void CParseLine::HandlesCheck(void)
+/**
+This function implements the script HandlesCheck command
+*/
+ {
+ TInt processHandleCountAfter;
+ TInt threadHandleCountAfter;
+ RThread().HandleCount(processHandleCountAfter, threadHandleCountAfter);
+
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Process handles count %d thread handle count %d"),
+ processHandleCountAfter,
+ threadHandleCountAfter );
+
+ // check that we are closing all the threads
+ if(iThreadHandleCountBefore != threadHandleCountAfter)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Test failed on thread handle count"));
+
+ // this result is only significant if every thing else has passed
+ if ( iTestVerdict == EPass )
+ iTestVerdict = EFail;
+ }
+
+ // check that we are closing all the handles
+ if(iProcessHandleCountBefore != processHandleCountAfter)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Test failed on Process handle count"));
+
+ // this result is only significant if every thing else has passed
+ if ( iTestVerdict == EPass )
+ iTestVerdict = EFail;
+ }
+ }
+
+CSuiteDll* CSuiteDll::NewL( const TDesC& aName )
+ {
+ CSuiteDll* self = new(ELeave) CSuiteDll(aName);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CSuiteDll::CSuiteDll( const TDesC& aName )
+/**
+Constructor.
+@param aName The name of the test suite DLL to be loaded (can contain file path)
+*/
+ {
+ // save the name
+ iName.Copy( aName );
+ }
+
+
+/**
+Load a test suite dll and save the name and test
+test suite pointers
+*/
+void CSuiteDll::ConstructL()
+ {
+ // load DLL by name
+ TInt ret = iLibrary.Load(iName, KTxtDLLpath);
+ if ( ret != KErrNone )
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Test suite %S found but would not load"),&iName );
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("check any other Dlls required by %S "),&iName );
+ User::Leave(ret);
+ }
+
+ // save the suite name dll without file path
+ TParse parse;
+ parse.Set(iName, NULL, NULL);
+ iName.Copy(parse.NameAndExt());
+
+ // get the interface pointer at ordinal 1
+ TLibraryFunction entry=iLibrary.Lookup(1);
+
+ // Call this interface pointer to create new CTestSuite
+ // If this call goes to the wrong function then the test
+ // suite does not have the correct function at ordinal 1
+ // This is usually caused by an error in the def file
+ iTestSuite = (CTestSuite*) entry();
+
+ // Second-phase constructor for CTestSuite
+ TRAPD(error,iTestSuite->ConstructL() );
+
+ //-- set the suite name (internal variable) the same as suite name dll file name (without extention)
+ iTestSuite->OverrideSuiteName(parse.NameAndExt());
+
+ if (error)
+ {
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("Failed to contruct test suite"));
+ User::Leave(error);
+ }
+
+ // set suite severity level
+ iTestSuite->SetSeverity(pLogSystem->Severity());
+
+ // get the version information
+ TPtrC Versiontxt = iTestSuite->GetVersion();
+
+ // add to log
+ pLogSystem->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, _L("LOAD_SUITE %S version %S loaded ok"),&iName, &Versiontxt );
+ }
+
+
+CSuiteDll::~CSuiteDll()
+/**
+destructor Delete the TestSuiteObject in the loaded DLL and close
+and unload the library
+*/
+ {
+ // delete the TestSuiteObject in the loaded DLL
+ if (iTestSuite)
+ {
+ delete iTestSuite;
+ }
+
+ // close and unload the library
+ iLibrary.Close();
+ }
+
+/**
+* Find out if the suite name matches the suite dll name.
+*
+* @param aSuiteName suite name (without file extention)
+* @return ETrue if the given suite name matches suite name dll file name.
+*/
+TBool CSuiteDll::SuiteNameMatch(const TDesC& aSuiteName) const
+{
+ TParse parse;
+
+ //-- iName contains suite dll name with file extention, strip the extention
+ parse.Set(iName, NULL, NULL);
+
+ //-- using CompareF instead of FindF to avoid situation when "AAA" suite name can match "AAA123"
+ TBool bFound = (aSuiteName.CompareF(parse.Name()) ==0 ) ? ETrue : EFalse;
+
+ return bFound;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+