--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stif/TestCombiner/src/TestCombiner.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,6539 @@
+/*
+* Copyright (c) 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 the implementation of
+* CTestCombiner class member functions.
+*
+*/
+
+// INCLUDE FILES
+#include <StifTestEventInterface.h>
+#include <StifLogger.h>
+#include "TestCombiner.h"
+#include "TestKeywords.h"
+#include "TestCase.h"
+#include "TestCombinerEvent.h"
+#include "Logging.h"
+//--PYTHON-- begin
+#include "StifPython.h"
+#include "StifPythonFunComb.h"
+//--PYTHON-- end
+#include "SettingServerClient.h"
+
+// EXTERNAL DATA STRUCTURES
+// None
+
+// EXTERNAL FUNCTION PROTOTYPES
+// None
+
+// CONSTANTS
+_LIT( KTestRunner, "CTestRunner" );
+_LIT( KRemoteTimer, "CRemoteTimer" );
+_LIT( KRemoteReceiver, "CRemoteReceiver" );
+
+// MACROS
+#ifdef LOGGER
+#undef LOGGER
+#endif
+#define LOGGER iLog
+
+// LOCAL CONSTANTS AND MACROS
+_LIT(KTitle, "title");
+_LIT(KTimeout, "timeout");
+_LIT(KPriority, "priority");
+
+//printing macros
+ _LIT( KExecute, "Execute");
+
+// MODULE DATA STRUCTURES
+// None
+
+// LOCAL FUNCTION PROTOTYPES
+// None
+
+// FORWARD DECLARATIONS
+// None
+
+// ==================== LOCAL FUNCTIONS =======================================
+// None
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: CTestCombiner
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCombiner::CTestCombiner():
+ iSchedulerActive( EFalse ),
+ iRunningTests( 0 ),
+ iResult( KErrNone ),
+ iEventPckg( iEvent ),
+ iRemoteTimeout( KRemoteProtocolTimeout ),
+ iCancelIfError( EFalse ),
+ iFailedTestCase( 0 ),
+ iLoopIsUsed( EFalse )
+ {
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::ConstructL()
+ {
+ // TRAPed to avoid crashing if logfile creation fails,
+ // so we can run test without logging to file
+ TRAPD( err, iStdLog = CStifLogger::NewL( KTestCombinerLogDir,
+ KTestCombinerLogFile );
+ );
+ if( err != KErrNone )
+ {
+ iStdLog = NULL;
+ __RDEBUG( (_L("Creating logfile failed") ) );
+ }
+ iLog = iStdLog;
+
+ //Read logger settings to check whether test case name is to be
+ //appended to log file name.
+ RSettingServer settingServer;
+ TInt ret = settingServer.Connect();
+ if(ret != KErrNone)
+ {
+ User::Leave(ret);
+ }
+ // Struct to StifLogger settigs.
+ TLoggerSettings loggerSettings;
+ // Parse StifLogger defaults from STIF initialization file.
+ ret = settingServer.GetLoggerSettings(loggerSettings);
+ if(ret != KErrNone)
+ {
+ User::Leave(ret);
+ }
+
+ // Get engine settings
+ TEngineSettings engineSettings;
+ ret = settingServer.GetEngineSettings(engineSettings);
+ if(ret != KErrNone)
+ {
+ __TRACE(KError, (_L("Could not retrieve engine settings from SettingServer [%d]"), ret));
+ iUITestingSupport = EFalse;
+ iSeparateProcesses = EFalse;
+ }
+ else
+ {
+ iUITestingSupport = engineSettings.iUITestingSupport;
+ iSeparateProcesses = engineSettings.iSeparateProcesses;
+ __TRACE(KMessage, (_L("Engine settings retrieved from SettingServer. UITestingSupport [%d] SeparateProcesses [%d]"), iUITestingSupport, iSeparateProcesses));
+ }
+
+ // Close Setting server session
+ settingServer.Close();
+ iAddTestCaseTitleToLogName = loggerSettings.iAddTestCaseTitle;
+
+ iIndexTestModuleControllers = 1;
+
+ __TRACE( KPrint, ( _L("New TestCombiner") ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: None
+
+ Return Values: CTestCombiner*: new object
+
+ Errors/Exceptions: Leaves if new or ConstructL leaves.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCombiner* CTestCombiner::NewL()
+ {
+
+ CTestCombiner* self = new (ELeave) CTestCombiner();
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: ~CTestCombiner
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCombiner::~CTestCombiner()
+ {
+ iLoopAllocationArray.Reset();
+ iLoopAllocationArray.Close();
+ iLoopIsUsed = EFalse;
+
+ iTestCases.ResetAndDestroy();
+ iTestModules.ResetAndDestroy();
+ iEventArray.ResetAndDestroy();
+ iSlaveArray.ResetAndDestroy();
+ iSendReceive.ResetAndDestroy();
+
+ iTestCases.Close();
+ iTestModules.Close();
+ iEventArray.Close();
+ iSlaveArray.Close();
+ iSendReceive.Close();
+
+ // Stop all remaining measurement modules
+ const TInt count_meas = iTestMeasurementArray.Count();
+ for( TInt b = 0; b < count_meas; b++ )
+ {
+ iTestMeasurementArray[b]->iMeasurement->Stop();
+ }
+ iTestMeasurementArray.ResetAndDestroy();
+ iTestMeasurementArray.Close();
+
+ delete iSectionParser;
+ delete iRemoteReceiver;
+ delete iTestRunner;
+
+ iLog = NULL;
+ delete iStdLog;
+ iStdLog = NULL;
+ delete iTCLog;
+ iTCLog = NULL;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: InitL
+
+ Description: InitL is used to initialize the Test Module.
+
+ Parameters: const TFileName& aIniFile: in: Initialization file
+ TBool aFirstTime: in: First time flag
+
+ Return Values: Symbian OS error code
+
+ Errors/Exceptions: Leaves if ReadInitializationL leaves
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCombiner::InitL( TFileName& aIniFile,
+ TBool /*aFirstTime*/ )
+ {
+
+ __TRACEFUNC();
+
+ if( aIniFile.Length() > 0 )
+ {
+ // Read initialization from test case file
+ ReadInitializationL( aIniFile );
+ }
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetTestCases
+
+ Description: GetTestCases is used to inquired test cases
+
+ Parameters: const TFileName& aConfigFile: in: Config file name
+ RPointerArray<RTestEngine::TTestCaseInfo>& aTestCases: out:
+ Array of TestCases
+
+ Return Values: KErrNone: Success
+ KErrNotFound: Testcases not found
+
+ Errors/Exceptions: Leaves if CStifParser::NewL leaves
+ Leaves if CStifParser::SectionL leaves
+ Leaves if CStifParser::NextSectionL leaves
+ Leaves if memory allocation fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCombiner::GetTestCasesL( const TFileName& aConfigFile,
+ RPointerArray<TTestCaseInfo>& aTestCases )
+ {
+ __TRACEFUNC();
+
+ if( aConfigFile.Length() == 0 )
+ {
+ __TRACE( KError, (_L("No test case script file given") ) );
+ __RDEBUG( (_L("No test case script file given") ) );
+ return KErrNotFound;
+ }
+
+ CStifParser* parser = NULL;
+ TRAPD( err, parser =
+ CStifParser::NewL( _L(""), aConfigFile, CStifParser::ECStyleComments ) );
+ if( err != KErrNone )
+ {
+ __TRACE( KError, (_L("Test case script file not found") ) );
+ __RDEBUG( (_L("Test case script file not found") ) );
+ return KErrNotFound;
+ }
+ CleanupStack::PushL( parser );
+ CStifSectionParser* section;
+ TPtrC tmp;
+ TInt index = 0;
+ TInt ret = KErrNone;
+
+ section = parser->SectionL( KTestStartTag, KTestEndTag );
+ if( section == NULL )
+ {
+ ret = KErrNotFound;
+ }
+ else
+ {
+ while( section )
+ {
+ CleanupStack::PushL( section );
+
+ if( section->GetLine( KTitle, tmp, ENoTag ) == KErrNone )
+ {
+ if( tmp.Length() > KMaxName )
+ {
+ tmp.Set( tmp.Left( KMaxName ) );
+ }
+ TTestCaseInfo* tc = new ( ELeave ) TTestCaseInfo();
+ CleanupStack::PushL( tc );
+ __TRACE( KVerbose, (_L("TestCase: %S"), &tmp));
+ tc->iTitle.Copy( tmp );
+ tc->iCaseNumber = ++index;
+ CStifItemParser* item = section->GetItemLineL( KTimeout );
+ if( item )
+ {
+ TInt timeout; // In milliseconds
+ ret = item->GetInt( KTimeout, timeout );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, (_L("Illegal timeout")));
+ User::Leave( ret );
+ }
+ tc->iTimeout = (TInt64)timeout*1000;
+ __TRACE( KMessage, (_L("Timeout: %i"), tc->iTimeout.Int64() ));
+ }
+ item = section->GetItemLineL( KPriority );
+ if( item )
+ {
+ ret = item->GetInt( KPriority, tc->iPriority );
+ if( ret != KErrNone )
+ {
+ TPtrC priority;
+ ret = item->GetString( KPriority, priority );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, (_L("Illegal priority")));
+ User::Leave( ret );
+ }
+ switch( TTCKeywords::Parse( priority,
+ TTCKeywords::Priority ) )
+ {
+ case TTCKeywords::EPriHigh:
+ tc->iPriority = TTestCaseInfo::EPriorityHigh;
+ break;
+ case TTCKeywords::EPriNormal:
+ tc->iPriority = TTestCaseInfo::EPriorityNormal;
+ break;
+ case TTCKeywords::EPriLow:
+ tc->iPriority = TTestCaseInfo::EPriorityLow;
+ break;
+ default:
+ __TRACE( KError, (_L("Illegal priority")));
+ User::Leave( KErrArgument );
+ }
+ }
+ __TRACE( KMessage, (_L("Priority: %i"), tc->iPriority ));
+ }
+
+ aTestCases.Append(tc);
+ CleanupStack::Pop( tc );
+ }
+ CleanupStack::PopAndDestroy( section );
+ section = parser->NextSectionL( KTestStartTag, KTestEndTag );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( parser );
+
+ __TRACE( KPrint, ( _L( "Configfile '%S', testcases %d" ),
+ &aConfigFile, index ));
+
+ return ret;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: RunTestCaseL
+
+ Description: Run a specified testcase.
+
+ RunTestCaseL is used to run an individual test case specified
+ by aTestCase.
+
+ Parameters: const TInt aCaseNumber: in: Testcase number
+ const TFileName& aConfig: in: Configuration file name
+ TTestResult& aResult: out; test case result
+
+ Return Values: KErrNone: Test case started succesfully.
+ KErrNotFound: Testcase not found
+ KErrUnknown: Unknown TestCombiner error
+ Any other SymbianOS error
+
+ Errors/Exceptions: Leaves if GetTestCaseL leaves
+ Leaves if RunTestL leaves
+ Leaves if memory allocation fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCombiner::RunTestCaseL( const TInt aCaseNumber,
+ const TFileName& aConfig,
+ TTestResult& aResult )
+ {
+ __TRACEFUNC();
+
+ __TRACE( KMessage, (_L("***Testcase started***")));
+
+ //Open new log file with test case title in file name
+ if(iAddTestCaseTitleToLogName)
+ {
+ //Close test case log if exists
+ if(iTCLog)
+ {
+ delete iTCLog;
+ iTCLog = NULL;
+ }
+ TFileName logFileName;
+ TName title;
+ TestModuleIf().GetTestCaseTitleL(title);
+
+ logFileName.Format(KTestCombinerLogFileWithTitle, &title);
+ iTCLog = CStifLogger::NewL(KTestCombinerLogDir, logFileName);
+ iLog = iTCLog;
+ }
+
+ /*
+ * Allow memory leaks, because Defines are leaved untouched
+ * after test case execution. Real memory leaks are detected with
+ * UHEAP macros.
+ */
+ TestModuleIf().SetBehavior( CTestModuleIf::ETestLeaksMem );
+
+ // Read initialization from test case file
+ ReadInitializationL( aConfig );
+
+ __UHEAP_MARK;
+
+ iSectionParser = GetTestCaseL( aCaseNumber, aConfig );
+
+ // Check parsing result
+ if( iSectionParser == NULL )
+ {
+ __TRACE( KError, (_L("***Parsing testcase failed***")));
+ __UHEAP_MARKEND;
+ return KErrNotFound;
+ }
+
+ CActiveScheduler* activeScheduler =
+ new ( ELeave ) CActiveScheduler();
+ CleanupStack::PushL( activeScheduler );
+ CActiveScheduler::Install( activeScheduler );
+
+ // Resetting these variables to normal state @js
+ iFailedTestCase = 0;
+ iCancelIfError = EFalse;
+ iScriptFailed = KErrNone;
+ iScriptFailedDescription.Copy(KNullDesC);
+
+ // Run the given testcase described in iSectionParser section
+ RunTestL();
+
+ CleanupStack::PopAndDestroy( activeScheduler );
+
+ delete iSectionParser;
+ iSectionParser = NULL;
+
+ TInt ret = KErrNone;
+ // Check if test case starting failed
+ if( iResult != KErrNone )
+ {
+ TestModuleIf().Printf( KPrintPriHigh, _L("Result"), _L("Starting FAILED"));
+ __TRACE( KError, (_L("***Starting testcase FAILED***")));
+ ret = iResult;
+ aResult.iResult = -2;
+ aResult.iResultDes = _L("Testcase script execution failed");
+ }
+ else if(iScriptFailed != KErrNone)
+ {
+ TestModuleIf().Printf( KPrintPriHigh, _L("Result"), _L("Script execution FAILED"));
+ __TRACE( KError, (_L("***Sscript execution FAILED***")));
+ aResult.iResult = iScriptFailed;
+ if(iScriptFailedDescription != KNullDesC)
+ {
+ aResult.iResultDes.Copy(iScriptFailedDescription);
+ }
+ else
+ {
+ aResult.iResultDes = _L("Testcase script execution failed");
+ }
+ }
+ else
+ {
+ __TRACE( KPrint, (_L("***Testcase completed***")));
+
+ // Testcombiner succeeded to start all testcases,
+ // check individual testcase results
+ TInt count = iTestCases.Count();
+ TInt i = iFailedTestCase;
+ // iFailedTestCase is either 0 or the number of failed test case if
+ // canceliferror was given and a test case has failed
+
+ for(; i < count; i++ )
+ {
+ // All cases should be completed now
+ if( iTestCases[i]->State() != CTCTestCase::ETestCaseCompleted )
+ {
+ // This is some unknown internal TestCombiner error
+ // Should not happen
+ __TRACE( KError, (_L("TestCase (%S) not completed"),
+ &iTestCases[i]->TestId() ));
+ ret = KErrUnknown;
+ break;
+ }
+
+ // Interpret execution result type from returned result
+ TInt executionResult = TFullTestResult::ECaseExecuted; // Ok
+ if( iTestCases[i]->iResult.iCaseExecutionResultType >=
+ TFullTestResult::ECaseLeave )
+ {
+ // Some abnormal execution result type
+ executionResult = iTestCases[i]->iResult.iCaseExecutionResultType;
+ }
+
+ // Check expected execution result type
+ if( executionResult != iTestCases[i]->ExpectedResultCategory() )
+ {
+ // expected and returned result types differ
+ aResult.iResult = KErrGeneral;
+ aResult.iResultDes.Copy( _L("Test case completed with ") );
+ aResult.iResultDes.Append(
+ TTCKeywords::ResultCategory(
+ iTestCases[i]->iResult.iCaseExecutionResultType ));
+ aResult.iResultDes.Append( _L(" and expected was ") );
+ aResult.iResultDes.Append(
+ TTCKeywords::ResultCategory(
+ iTestCases[i]->ExpectedResultCategory() ));
+ AppendTestResultToResultDes(aResult.iResultDes, iTestCases[i]->iResult.iTestResult.iResultDes);
+ __TRACE( KPrint, ( _L( "%S"), &aResult.iResultDes ) );
+ break;
+ }
+
+ // Check normal test result
+ if( iTestCases[i]->ExpectedResultCategory() ==
+ TFullTestResult:: ECaseExecuted )
+ {
+ // Normal completion, check result
+ if( iTestCases[i]->iResult.iTestResult.iResult !=
+ iTestCases[i]->ExpectedResult() )
+ {
+ __TRACE( KPrint, ( _L( "Test failed, expect(%d) != result(%d)"),
+ iTestCases[i]->ExpectedResult(),
+ iTestCases[i]->iResult.iTestResult.iResult ));
+ // We return the first error result as aResult
+ if( iTestCases[i]->iResult.iTestResult.iResult != KErrNone )
+ {
+ aResult = iTestCases[i]->iResult.iTestResult;
+ }
+ else
+ {
+ aResult.iResult = KErrGeneral;
+ aResult.iResultDes.Copy( _L("Test case completed with KErrNone and expected "));
+ aResult.iResultDes.AppendNum( iTestCases[i]->ExpectedResult() );
+ AppendTestResultToResultDes(aResult.iResultDes, iTestCases[i]->iResult.iTestResult.iResultDes);
+ }
+ break;
+ }
+ }
+ else
+ {
+ // Abnormal completion, i.e. panic, leave, exception or timeout
+ if( iTestCases[i]->iResult.iCaseExecutionResultCode !=
+ iTestCases[i]->ExpectedResult() )
+ {
+ __TRACE( KPrint, ( _L( "Test failed, expect errorcode(%d) != result(%d)"),
+ iTestCases[i]->ExpectedResult(),
+ iTestCases[i]->iResult.iCaseExecutionResultCode ) );
+ // We return the first error result as aResult
+ aResult = iTestCases[i]->iResult.iTestResult;
+ // override result with real error code
+ aResult.iResult = iTestCases[i]->iResult.iCaseExecutionResultCode;
+ break;
+ }
+ }
+ }
+ if( i == count )
+ {
+ TestModuleIf().Printf( KPrintPriHigh, _L("Result"), _L("PASSED"));
+ __TRACE( KPrint, (_L("***Test case result: PASSED***")));
+ aResult.iResult = KErrNone;
+ aResult.iResultDes.Copy( _L("Test case succeeded") );
+ }
+ else
+ {
+ TestModuleIf().Printf( KPrintPriHigh, _L("Result"), _L("FAILED"));
+ __TRACE( KPrint, (_L("***Test case result: FAILED***")));
+ }
+ }
+
+ // Release all pending event requests
+ TEventIf event( TEventIf::ERelEvent );
+ TInt eventCount = iEventArray.Count();
+ for( TInt ind=0; ind < eventCount; ind++ )
+ {
+ event.SetName( iEventArray[ind]->Name() );
+ TestModuleIf().Event( event );
+ }
+
+ iLoopAllocationArray.Reset();
+ iLoopAllocationArray.Close();
+ iLoopIsUsed = EFalse;
+
+ // Delete all completed and checked testcases
+ // Do not change the deletion order of events and test cases!!!
+ iEventArray.ResetAndDestroy();
+ iTestCases.ResetAndDestroy();
+ iTestModules.ResetAndDestroy();
+ iSlaveArray.ResetAndDestroy();
+
+ iSendReceive.ResetAndDestroy();
+
+ // Stop all remaining measurement modules
+ const TInt count_meas = iTestMeasurementArray.Count();
+ for( TInt b = 0; b < count_meas; b++ )
+ {
+ iTestMeasurementArray[b]->iMeasurement->Stop();
+ }
+ iTestMeasurementArray.ResetAndDestroy();
+ iTestMeasurementArray.Close();
+
+ __UHEAP_MARKEND;
+
+ //If log was replaced then restore it
+ if(iAddTestCaseTitleToLogName)
+ {
+ iLog = iStdLog;
+ delete iTCLog;
+ iTCLog = NULL;
+ }
+
+ return ret;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetTestCaseL
+
+ Description: Get specified test case section from configfile.
+
+ Parameters: const TInt aCaseNumber: in: Test case number
+ const TFileName& aConfig: in: Configfile name
+
+ Return Values: CSectionParser*: pointer to test case section
+
+ Errors/Exceptions: Leaves if CStifParser::NewL leaves
+ Leaves if CStifParser::SectionL leaves
+ Leaves if memory allocation fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CStifSectionParser* CTestCombiner::GetTestCaseL( const TInt aCaseNumber,
+ const TFileName& aConfig )
+ {
+ __TRACEFUNC();
+ CStifParser* parser =
+ CStifParser::NewL( _L(""), aConfig, CStifParser::ECStyleComments );
+ CleanupStack::PushL( parser );
+
+ CStifSectionParser* section =
+ parser->SectionL( KTestStartTag, KTestEndTag, aCaseNumber );
+
+ CleanupStack::PopAndDestroy( parser );
+ return section;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: ReadInitializationL
+
+ Description: Read initialization from file.
+
+ Parameters: const TDesC& aIniFile: in: File that contains initialization
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::ReadInitializationL( const TDesC& aIniFile )
+ {
+ CStifParser* parser = NULL;
+
+ // Open file
+ TRAPD( err, parser =
+ CStifParser::NewL( _L(""), aIniFile, CStifParser::ECStyleComments ) );
+ if( ( err == KErrNone ) && parser )
+ {
+ CleanupStack::PushL( parser );
+ __TRACE( KMessage, (_L("Read initialization from [%S]"),
+ &aIniFile ) );
+
+ // Read initialization parameters
+ CStifSectionParser* section = parser->SectionL( KInitStartTag,
+ KInitEndTag );
+ if( section )
+ {
+ CleanupStack::PushL( section );
+ __TRACE( KMessage, (_L("Read initializations")) );
+
+ // Read RCP timeout
+ CStifItemParser* item = section->GetItemLineL( KInitRcpTimeout );
+ if( item != NULL )
+ {
+ __TRACE( KMessage, (_L("Got RCP timeout definition")) );
+ CleanupStack::PushL( item );
+
+ TInt value;
+ if( item->GetInt( KInitRcpTimeout, value )
+ != KErrNone )
+ {
+ __TRACE( KError, (_L("No RCP timeout value given")) );
+ User::Leave( KErrGeneral );
+ }
+ // Change from seconds to milliseconds
+ iRemoteTimeout = value*1000*1000;
+ CleanupStack::PopAndDestroy( item );
+ }
+
+ CleanupStack::PopAndDestroy( section );
+ }
+
+ // Read defines
+ section = parser->SectionL( KDefineStartTag, KDefineEndTag );
+ while(section)
+ {
+ CleanupStack::PushL( section );
+ __TRACE( KMessage, (_L("Read defines")) );
+
+ TPtrC name;
+ TPtrC value;
+ CStifItemParser* item = section->GetItemLineL( _L("") );
+ while( item )
+ {
+ CleanupStack::PushL( item );
+
+ if( item->GetString( _L(""), name ) != KErrNone )
+ {
+ __TRACE( KError, (_L("No define name given")) );
+ User::Leave( KErrGeneral );
+ }
+ if( item->Remainder( value ) != KErrNone )
+ {
+ __TRACE( KError, (_L("No define value given")) );
+ User::Leave( KErrGeneral );
+ }
+ TInt count = iDefined.Count();
+ TInt i = 0;
+ for( ; i < count; i++ )
+ {
+ if( iDefined[i]->Name() == name )
+ {
+ __TRACE( KMessage, (_L("Update define %S:%S"), &name, &value ) );
+ // Update existing
+ iDefined[i]->SetValueL( value );
+ break;
+ }
+ }
+ if( i == count)
+ {
+ // New define, store it
+ CDefinedValue* define = CDefinedValue::NewL( name, value );
+ CleanupStack::PushL( define );
+ User::LeaveIfError( iDefined.Append( define ) );
+ CleanupStack::Pop( define );
+ }
+
+ CleanupStack::PopAndDestroy( item );
+ item = section->GetNextItemLineL();
+ }
+ CleanupStack::PopAndDestroy( section );
+ section = parser->NextSectionL(KDefineStartTag, KDefineEndTag);
+ }
+ CleanupStack::PopAndDestroy( parser );
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: RunTestL
+
+ Description: Run a testcase specified by iSectionParser.
+
+ Parameters: None
+
+ Return Values: None.
+
+ Errors/Exceptions: Leaves if CSectionParser::GetItemLineL leaves
+ Leaves if CTestRunner::NewL leaves
+ Leaves if memory allocation fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::RunTestL()
+ {
+ __TRACEFUNC();
+ iResult = KErrNone;
+
+ TPtrC line;
+ // "title" keyword must be in the first line
+ User::LeaveIfError( iSectionParser->GetLine( KTitle, line, ENoTag ) );
+
+ iTestRunner = CTestRunner::NewL( this );
+ iRemoteReceiver = CRemoteReceiver::NewL( this );
+ iRemoteReceiver->Start();
+
+ __TRACE( KMessage, (_L("Run: %S"), &line));
+
+ TestModuleIf().Printf( KPrintPriNorm, _L("Run"), _L("%S"), &line);
+ // Rest of the job is done by test runner
+ iTestRunner->SetRunnerActive();
+
+ // Start activeScheduler looping testcase lines
+ iSchedulerActive = ETrue;
+ __TRACE( KMessage, (_L("Start CActiveScheduler")));
+ CActiveScheduler::Current()->Start();
+
+ TestModuleIf().Printf( KPrintPriNorm, _L("Executed"), _L("%S"), &line);
+ __TRACE( KMessage, (_L("Executed: %S"), &line));
+
+ delete iRemoteReceiver;
+ iRemoteReceiver = NULL;
+ delete iTestRunner;
+ iTestRunner = NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetTestModuleL
+
+ Description: Load testmodule if not already loaded, otherwise return
+ description of the loaded testmodule.
+
+ Parameters: TDesC& aModule: in: Module name.
+ TDesC& aIniFile: in: Ini file name.
+ const TDesC& aConfigFile: in: Test case(config) file name.
+
+ Return Values: CTCTestModule*: pointer to testmodules description
+
+ Errors/Exceptions: Leaves if CTCTestModule::NewL leaves
+ Leaves if RPointerArray::Append fails
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CTCTestModule* CTestCombiner::GetTestModuleL( TDesC& aModule,
+ TDesC& aIniFile,
+ const TDesC& aConfigFile )
+ {
+ __TRACEFUNC();
+ TInt count = iTestModules.Count();
+ TInt i, j;
+ TInt counttc;
+ TInt running;
+ TBool newWay = EFalse;
+
+ __TRACE(KMessage, (_L("Find test module for [%S]"), &aModule));
+
+ //Name for new module controller
+ TName newModuleName = aModule;
+
+ //Check if it is python case or UITestingSupport or SeparateProcesses mode
+ newWay = (aModule.Find(KPythonScripter) == 0)
+ || (iUITestingSupport && aModule.Find(KTestScripterName) == 0)
+ || (iSeparateProcesses);
+
+ if(newWay)
+ {
+ __TRACE(KMessage, (_L("TCTestModule operating mode: exclusive")));
+
+ //Find module of given name
+ __TRACE(KMessage, (_L("Looking for module [%S]"), &aModule));
+ if(iUITestingSupport && aModule.Find(KTestScripterName) == 0)
+ {
+ __TRACE(KMessage, (_L("UITestingSupport option is on. New module controller will be created always")));
+ }
+ else
+ {
+ for(i = 0; i < count; i++)
+ {
+ TPtrC modName = iTestModules[i]->ModuleName();
+ if(modName.Find(aModule) == 0)
+ {
+ //Check if there is running test case
+ counttc = iTestCases.Count();
+ running = 0;
+ for(j = 0; j < counttc; j++)
+ {
+ if(iTestCases[j]->TestModule() == iTestModules[i] && iTestCases[j]->State() != CTestCase::ETestCaseCompleted)
+ {
+ //We have found at least one running test case. There is no reason to find any more,
+ //because there shouldn't be because test module may run only one python scripter test case.
+ running++;
+ __TRACE(KMessage, (_L("Module controller found [%S], but it has running test cases"), &modName));
+ break;
+ }
+ }
+ if(running == 0)
+ {
+ __TRACE(KMessage, (_L("Free module controller has been found [%S]"), &modName));
+ return iTestModules[i];
+ }
+ }
+ }
+ }
+ //Update name of new module to be created
+ newModuleName.AppendFormat(_L("@%d_"), GetIndexForNewTestModuleController());
+ newModuleName.LowerCase();
+ }
+ else
+ {
+ __TRACE(KMessage, (_L("TCTestModule operating mode: normal")));
+ for(i = 0; i < count; i++)
+ {
+ if(iTestModules[i]->ModuleName() == aModule)
+ {
+ // Found test module, return description
+ __TRACE(KMessage, (_L("Module controller [%S] found"), &aModule));
+ return iTestModules[i];
+ }
+ }
+ }
+
+ __TRACE(KMessage, (_L("Creating new test module controller [%S] with ini [%S]"), &newModuleName, &aIniFile));
+ CTCTestModule* module = CTCTestModule::NewL(this, newModuleName, aIniFile, aConfigFile);
+ CleanupStack::PushL(module);
+
+ //Enumerate test cases
+ module->GetTestCasesForCombiner(aConfigFile);
+
+ //Append new module to list
+ User::LeaveIfError(iTestModules.Append(module));
+ CleanupStack::Pop(module);
+
+ //Log some info
+ if(newWay)
+ {
+ __TRACE(KMessage, (_L("Module [%S] added to list. Currently there are following controllers of [%S] type:"), &newModuleName, &aModule));
+ j = 1;
+ for(i = 0; i < iTestModules.Count(); i++)
+ {
+ if(iTestModules[i]->ModuleName().Find(aModule) == 0)
+ {
+ __TRACE(KMessage, (_L(" %d. [%S]"), j, &iTestModules[i]->ModuleName()));
+ j++;
+ }
+ }
+ }
+
+ if( iLoopIsUsed )
+ {
+ User::LeaveIfError( iLoopAllocationArray.Append( module ) );
+ }
+
+ return module;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetTest
+
+ Description: Get test case from testcase array.
+
+ Parameters: TDesC& aTestId: in: TestId for testcase
+
+ Return Values: CTCTestCase*: running/runned testcase
+ NULL: Testcase with aTestId not running/runned
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCase* CTestCombiner::GetTest( TDesC& aTestId )
+ {
+ __TRACEFUNC();
+ // TestId is not mandatory, so length may be zero
+ if( aTestId.Length() == 0 )
+ {
+ return NULL;
+ }
+
+ TInt count = iTestCases.Count();
+ for( TInt i=0; i < count; i++ )
+ {
+ if( iTestCases[i]->TestId() == aTestId )
+ {
+ // Found testcase with specified TestId
+ return iTestCases[i];
+ }
+ }
+ // Test case with aTestId not found
+ return NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetRunningTest
+
+ Description: Get running test case.
+
+ Parameters: TDesC& aTestId: in: TestId for testcase
+
+ Return Values: CTCTestCase*: running testcase
+ NULL: Testcase with aTestId not running
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCase* CTestCombiner::GetRunningTest( TDesC& aTestId )
+ {
+ __TRACEFUNC();
+
+ CTestCase* test = GetTest( aTestId );
+ if( test )
+ {
+ if( test->State() == CTestCase::ETestCaseRunning )
+ {
+ return test;
+ }
+ else
+ {
+ __TRACE( KMessage, (_L("GetTest: Searched task (%S) not running (%i)"),
+ &aTestId, test->State() ));
+ }
+ }
+
+ return NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetLocalTest
+
+ Description: Get local test case from testcase array.
+
+ Parameters: TDesC& aTestId: in: TestId for testcase
+
+ Return Values: CTCTestCase*: running/runned testcase
+ NULL: Testcase with aTestId not running/runned
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CTCTestCase* CTestCombiner::GetLocalTest( TDesC& aTestId )
+ {
+ __TRACEFUNC();
+ CTestCase* testCase = GetTest( aTestId );
+ if( testCase )
+ {
+ if( testCase->Type() != CTestCase::ECaseLocal )
+ {
+ __TRACE( KMessage, (_L("GetLocalTest: Searched task (%S) not local"),
+ &aTestId ));
+ return NULL;
+ }
+ }
+ return ( CTCTestCase* ) testCase;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetLocalRunningTest
+
+ Description: Get local running test case.
+
+ Parameters: TDesC& aTestId: in: TestId for testcase
+
+ Return Values: CTCTestCase*: running/runned testcase
+ NULL: Testcase with aTestId not running/runned
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CTCTestCase* CTestCombiner::GetLocalRunningTest( TDesC& aTestId )
+ {
+ __TRACEFUNC();
+ CTestCase* testCase = GetRunningTest( aTestId );
+ if( testCase )
+ {
+ if( testCase->Type() != CTestCase::ECaseLocal )
+ {
+ __TRACE( KMessage, (_L("GetLocalRunningTest: Searched task (%S) not local"),
+ &aTestId ));
+ return NULL;
+ }
+ }
+
+ return ( CTCTestCase* ) testCase;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetRemoteTest
+
+ Description: Get local test case from testcase array.
+
+ Parameters: TDesC& aTestId: in: TestId for testcase
+
+ Return Values: CTCTestCase*: running/runned testcase
+ NULL: Testcase with aTestId not running/runned
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CRemoteTestCase* CTestCombiner::GetRemoteTest( TDesC& aTestId )
+ {
+ __TRACEFUNC();
+ CTestCase* testCase = GetTest( aTestId );
+ if( testCase )
+ {
+ if( testCase->Type() != CTestCase::ECaseRemote )
+ {
+ __TRACE( KMessage, (_L("GetRemoteTest: Searched task (%S) not remote"),
+ &aTestId ));
+ return NULL;
+ }
+ }
+
+ return ( CRemoteTestCase* ) testCase;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetRemoteTest
+
+ Description: Get remote test case from slave array.
+
+ Parameters: TUint32 aSlaveId: in: Slave id for testcase
+
+ Return Values: TCaseInfo*: running/runned testcase
+ NULL: Testcase with aTestId not running/runned
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CRemoteTestCase* CTestCombiner::GetRemoteTest( TUint32 aSlaveId )
+ {
+
+ __TRACEFUNC();
+
+ // Check all remote testcases
+ TInt caseCount = iTestCases.Count();
+ CRemoteTestCase* testCase = NULL;
+ for( TInt caseInd = 0; caseInd < caseCount; caseInd++ )
+ {
+ if( iTestCases[caseInd]->Type() == CTestCase::ECaseRemote )
+ {
+ testCase = ( CRemoteTestCase* )iTestCases[caseInd];
+ if( testCase->iSlaveId == aSlaveId )
+ {
+ return testCase;
+ }
+ }
+ }
+
+ return NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetRemoteTestRunSent
+
+ Description: Get remote test case from slave array
+
+ Parameters: TUint32 aSlaveId: in: Slave id for testcase
+
+ Return Values: TCaseInfo*: running/runned testcase
+ NULL: Testcase with aTestId not running/runned
+
+ Errors/Exceptions: None
+
+ Status: Draft @js
+
+-------------------------------------------------------------------------------
+*/
+
+CRemoteTestCase* CTestCombiner::GetRemoteTestRunSent( TUint32 aSlaveId )
+ {
+
+ __TRACEFUNC();
+
+ // Check all remote testcases
+ TInt caseCount = iTestCases.Count();
+ CRemoteTestCase* testCase = NULL;
+ for( TInt caseInd = 0; caseInd < caseCount; caseInd++ )
+ {
+ if( iTestCases[caseInd]->Type() == CTestCase::ECaseRemote )
+ {
+ testCase = ( CRemoteTestCase* )iTestCases[caseInd];
+
+ if( testCase->iRemoteState != CRemoteTestCase::ECaseRunSent )
+ {
+ continue;
+ }
+ if( testCase->iSlaveId == aSlaveId )
+ {
+ return testCase;
+ }
+ }
+ }
+
+ return NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetRemoteTest
+
+ Description: Get remote test case from slave array.
+
+ Parameters: TUint32 aSlaveId: in: Slave id for testcase
+
+ Return Values: TCaseInfo*: running/runned testcase
+ NULL: Testcase with aTestId not running/runned
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CRemoteTestCase* CTestCombiner::GetRunningRemoteTest( TUint32 aSlaveId )
+ {
+
+ __TRACEFUNC();
+
+ // Check all remote testcases
+ TInt caseCount = iTestCases.Count();
+ CRemoteTestCase* testCase = NULL;
+ for( TInt caseInd = 0; caseInd < caseCount; caseInd++ )
+ {
+ if( ( iTestCases[caseInd]->Type() == CTestCase::ECaseRemote ) &&
+ ( iTestCases[caseInd]->State() == CTestCase::ETestCaseRunning ) )
+ {
+ testCase = ( CRemoteTestCase* )iTestCases[caseInd];
+
+ if( ( testCase->iRemoteState != CRemoteTestCase::ECaseRunSent ) &&
+ ( testCase->iRemoteState != CRemoteTestCase::ECaseRunning ) &&
+ ( testCase->iRemoteState != CRemoteTestCase::ECaseCancelled ))
+ {
+ //User::Leave( KErrGeneral );
+ continue;
+ }
+
+ if( testCase->iSlaveId == aSlaveId )
+ {
+ return testCase;
+ }
+ }
+ }
+
+ return NULL;
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetRemoteTestSlave
+
+ Description: Get remote test case running on slave
+
+ Parameters: TUint32 aSlaveDevId: in: Slave id for testcase
+
+ Return Values: CRemoteTestCase*: running/runned testcase
+ NULL: Testcase with aTestId not running/runned
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CRemoteTestCase* CTestCombiner::GetRemoteRunningTestOnSlave(
+ TUint32 aSlaveDevId )
+ {
+
+ __TRACEFUNC();
+
+ // Check all remote testcases
+ TInt caseCount = iTestCases.Count();
+ CRemoteTestCase* testCase = NULL;
+ for( TInt caseInd = 0; caseInd < caseCount; caseInd++ )
+ {
+ if( ( iTestCases[caseInd]->Type() == CTestCase::ECaseRemote ) &&
+ ( iTestCases[caseInd]->State() == CTestCase::ETestCaseRunning ) )
+ {
+ testCase = ( CRemoteTestCase* )iTestCases[caseInd];
+ if( DEVID( testCase->iSlaveId ) == DEVID( aSlaveDevId ) )
+ {
+ return testCase;
+ }
+ }
+ }
+
+ return NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetRemoteTestSlave
+
+ Description: Gets a correct CRemoteSendReceive object on slave with
+ aSlaveId.
+
+ Parameters: TUint32 aSlaveId: in: Slave id CRemoteSendReceive object
+
+ Return Values: CRemoteSendReceive*: Current CRemoteSendReceive object.
+ NULL: CRemoteSendReceive object do not exist or found.
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CRemoteSendReceive* CTestCombiner::GetRemoteSendReceive( TUint32 aSlaveId )
+ {
+ __TRACEFUNC();
+
+ for( TInt sr = 0; sr < iSendReceive.Count(); sr++ )
+ {
+ if( iSendReceive[sr]->iSlaveId == aSlaveId )
+ {
+ return iSendReceive[sr];
+ }
+ }
+
+ return NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetSlave
+
+ Description: Get remote slave.
+
+ Parameters: TUint32 aSlaveId: in: Slave id
+
+ Return Values: CSlaveInfo*: reserved slave
+ NULL: slave with aSlaveId not reserved
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CSlaveInfo* CTestCombiner::GetSlave( TUint32 aSlaveId )
+ {
+
+ __TRACEFUNC();
+
+ TInt count = iSlaveArray.Count();
+ for( TInt index = 0; index < count; index++ )
+ {
+ if( DEVID( iSlaveArray[index]->iSlaveDevId ) == DEVID( aSlaveId) )
+ {
+ return iSlaveArray[index];
+ }
+ }
+
+ return NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetSlave
+
+ Description: Get remote slave.
+
+ Parameters: TDesC& aSlaveName: in: Slave name
+
+ Return Values: CSlaveInfo*: reserved slave
+ NULL: slave with aSlaveId not reserved
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CSlaveInfo* CTestCombiner::GetSlave( TDesC& aSlaveName )
+ {
+
+ __TRACEFUNC();
+
+ TInt count = iSlaveArray.Count();
+ for( TInt index = 0; index < count; index++ )
+ {
+ if( iSlaveArray[index]->iName == aSlaveName )
+ {
+ return iSlaveArray[index];
+ }
+ }
+
+ return NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: StartTestL
+
+ Description: Start specified test case from testmodule.
+
+ Parameters: CStartInfo& aStartInfo: in: Test case information
+
+ Return Values: KErrNone: Testcase started
+ KErrAlreadyExists: testcase with same aTestId is already
+ running
+ Any other SymbianOS errorcode
+
+ Errors/Exceptions: Leaves if CTCTestCase::NewL leaves
+ Leaves if arguments are illegal
+ Leaves if GetTestModuleL leaves
+ Leaves if CTestExecution::Open fails
+ Leaves if CTCTestCase::StartL leaves
+ Leaves if RPointerArray::Append fails
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCombiner::StartTestL( CStartInfo& aStartInfo )
+ {
+ __TRACEFUNC();
+ // Check that TestId is unique.
+ if( GetTest( aStartInfo.iTestId ) != NULL )
+ {
+ // If loop testing is ongoing, allow already defined testid.
+ if( iLoopIsUsed )
+ {
+ __TRACE( KVerbose, ( _L("StartTestL: TestId (%S) already in use. Loop allows already defined TestId"),
+ &aStartInfo.iTestId ));
+ }
+ else
+ {
+ __TRACE( KError, ( _L("StartTestL: TestId (%S) already in use"),
+ &aStartInfo.iTestId ));
+ return KErrAlreadyExists;
+ }
+ }
+
+ __ASSERT_ALWAYS( aStartInfo.iModule.Length() < KMaxFileName,
+ User::Leave( KErrArgument ) );
+ __ASSERT_ALWAYS( aStartInfo.iIniFile.Length() < KMaxFileName,
+ User::Leave( KErrArgument ) );
+ __ASSERT_ALWAYS( aStartInfo.iConfig.Length() < KMaxFileName,
+ User::Leave( KErrArgument ) );
+ __ASSERT_ALWAYS( aStartInfo.iTestId.Length() < KMaxName,
+ User::Leave( KErrArgument ) );
+
+ __TRACE( KMessage, ( _L("Call GetTestModuleL") ));
+
+ // Load Test Module
+ CTCTestModule* module = NULL;
+ if( (aStartInfo.iModule.Find( KTestScripterName ) != KErrNotFound)
+ || (aStartInfo.iModule.Find( KPythonScripter ) != KErrNotFound)
+ || (aStartInfo.iModule.Find( KTestCombinerName ) != KErrNotFound)
+ )
+ {
+ // TestScripter in use. Give config file for parsing STIF Settings.
+ module = GetTestModuleL( aStartInfo.iModule,
+ aStartInfo.iIniFile,
+ aStartInfo.iConfig );
+ }
+ else
+ {
+ module = GetTestModuleL( aStartInfo.iModule,
+ aStartInfo.iIniFile,
+ KNullDesC );
+ }
+
+ __TRACE( KMessage, ( _L("Create CTCTestCase") ));
+
+ CTCTestCase* tc =
+ CTCTestCase::NewL( this,
+ aStartInfo.iModule,
+ aStartInfo.iTestId,
+ aStartInfo.iExpectedResult,
+ aStartInfo.iCategory,
+ module ); //--PYTHON--
+
+ CleanupStack::PushL( tc );
+
+ //If name of testcase was given, find testcase number
+ if(aStartInfo.iTitle != KNullDesC)
+ {
+ __TRACE(KMessage, (_L("Trying to find test case entitled \"%S\""), &aStartInfo.iTitle));
+ aStartInfo.iCaseNum = -1;
+ TInt ret = module->GetCaseNumByTitle(aStartInfo.iTitle, aStartInfo.iCaseNum);
+ if(ret != KErrNone)
+ {
+ __TRACE(KError, (_L("Couldn't find test case entitled \"%S\". Error %d"), &aStartInfo.iTitle, ret));
+ }
+ else
+ {
+ __TRACE(KMessage, (_L("Found test case entitled \"%S\". Case num %d"), &aStartInfo.iTitle, aStartInfo.iCaseNum));
+ }
+ }
+
+ __TRACE( KMessage, ( _L("Open TestExecution") ));
+
+ User::LeaveIfError( tc->TestExecution().Open( module->TestServer(),
+ aStartInfo.iCaseNum,
+ aStartInfo.iConfig ) );
+
+ __TRACE( KMessage, ( _L("Start testcase runner") ));
+
+ // Enable testcase control before calling RunTestCase
+ tc->StartL();
+
+ __TRACE( KMessage,
+ ( _L("Start: testid(%S), module(%S), ini(%S), config(%S), case(%d), expect(%d/%d), timeout(%d)"),
+ &aStartInfo.iTestId, &aStartInfo.iModule, &aStartInfo.iIniFile,
+ &aStartInfo.iConfig, aStartInfo.iCaseNum, aStartInfo.iExpectedResult,
+ aStartInfo.iCategory, aStartInfo.iTimeout ));
+
+ TestModuleIf().Printf( KPrintPriLow, _L("Start"),
+ _L("testid(%S), module(%S), ini(%S), config(%S), case(%d), expect(%d)"),
+ &aStartInfo.iTestId, &aStartInfo.iModule, &aStartInfo.iIniFile,
+ &aStartInfo.iConfig, aStartInfo.iCaseNum, aStartInfo.iExpectedResult );
+
+ tc->TestExecution().RunTestCase( tc->iResultPckg, tc->iStatus );
+
+ iRunningTests++;
+
+ User::LeaveIfError( iTestCases.Append( tc ) );
+ if( iLoopIsUsed )
+ {
+ User::LeaveIfError( iLoopAllocationArray.Append( tc ) );
+ }
+ CleanupStack::Pop( tc );
+
+ return KErrNone;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: Complete
+
+ Description: Handle completed test case.
+
+ Parameters: CTCTestCase* aTestCase: in: Test case to complete
+
+ Return Values: None.
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::Complete( CTestCase* aTestCase, TInt aError )
+ {
+ __TRACEFUNC();
+
+ if( aError != KErrNone )
+ {
+ iResult = aError;
+ }
+
+ TInt count = iTestCases.Count();
+ TInt i = 0;
+ for(; i < count; i++ )
+ {
+ if( iTestCases[i] == aTestCase )
+ {
+ // Test Case completed
+ __TRACE( KPrint, ( _L( "Complete: %S result: %d, execution result: %d, expected: %d"),
+ &aTestCase->TestId(), aTestCase->iResult.iTestResult.iResult,
+ aTestCase->iResult.iCaseExecutionResultCode, aTestCase->ExpectedResult() ));
+ TestModuleIf().Printf( KPrintPriLow, _L("Complete"),
+ _L( "%S results: test(%d) exe(%d) expect(%d)"),
+ &aTestCase->TestId(), aTestCase->iResult.iTestResult.iResult,
+ aTestCase->iResult.iCaseExecutionResultCode, aTestCase->ExpectedResult() );
+ iRunningTests--;
+ break;
+ }
+ }
+ if( i == count )
+ {
+ __TRACE( KError, (_L("CTestCombiner::Complete: Test case not found!!")));
+ }
+
+ // Check if we were waiting this case to complete
+ if( ( iWaitTestCase.Length() > 0 ) &&
+ ( iWaitTestCase == aTestCase->TestId() ) )
+ {
+ // We were waiting this case to complete
+ // Now we can proceed executing the testcase
+ __TRACE( KMessage, (_L("TestCase was waiting, set runner active")));
+ iTestRunner->SetRunnerActive();
+ iWaitTestCase.Zero();
+
+ //return; - return removed due to STIF-509 CancelIfError won't work when used together with complete command
+
+ }
+ else if( aTestCase->Type() == CTestCase::ECaseRemote )
+ {
+ __TRACE( KMessage, (_L("CTestCombiner::Complete: Remote case complete")));
+ // Completed testcase was remote case,
+ // check if slave should be freed
+ CRemoteTestCase* remote = ( CRemoteTestCase* )aTestCase;
+ if( remote->iFreeSlave )
+ {
+ CSlaveInfo* slave = GetSlave( remote->iSlaveId );
+ if( slave )
+ {
+ // Free slave now
+ TRAPD( err, iTestRunner->ExecuteFreeL( slave ) );
+ // Continue if freeing fails
+ if( err == KErrNone )
+ {
+ __TRACE( KMessage, (_L("Complete: Freeing slave")));
+ return;
+ }
+ else
+ {
+ __TRACE( KError, (_L("Complete: Freeing slave failed")));
+ }
+ }
+ else
+ {
+ __TRACE( KError, (_L("Complete: Slave not found")));
+ }
+ }
+ }
+
+ // If running test is 0, active scheduler is active and CTestRunner is
+ // ready then stop active scheduler.(Operations continue from
+ // CTestCombiner::RunTestL() after active scheduler start).
+ if( ( iRunningTests == 0 ) &&
+ iSchedulerActive &&
+ ( iTestRunner->iState == CTestRunner::ERunnerReady ) )
+ {
+ // This was last running testcase, so we can stop
+ // activescheduler
+ __TRACE( KMessage, (_L("All TestCases completed, stop CActiveScheduler")));
+ CActiveScheduler::Current()->Stop();
+ iSchedulerActive = EFalse;
+ }
+ else
+ {
+ __TRACE( KMessage,
+ (_L("CTestCombiner::Complete: %d test cases running"), iRunningTests ));
+ __TRACE( KMessage,
+ (_L("CTestCombiner::Complete: active %d"), iSchedulerActive ));
+ if(iSchedulerActive)
+ {
+ __TRACE( KMessage,
+ (_L("CTestCombiner::Complete: state %d"), iTestRunner->iState ));
+ }
+ }
+
+ // Checking if user wants to skip the rest of the execution in case of error @js
+ if(iCancelIfError && iSchedulerActive)
+ {
+ // Interpret execution result type from returned result
+ TInt executionResult = TFullTestResult::ECaseExecuted; // Ok
+ if( (aTestCase->iResult.iCaseExecutionResultType >=
+ TFullTestResult::ECaseLeave ))
+ {
+ __TRACE( KMessage, (_L("The test case ended with error!")));
+
+ // Some abnormal execution result type
+ executionResult = iTestCases[i]->iResult.iCaseExecutionResultType;
+ }
+
+ // Check expected execution result type
+ if( executionResult != aTestCase->ExpectedResultCategory() )
+ {
+ // expected and returned result types differ
+ __TRACE( KMessage, (_L("The test case has wrong result category!")));
+ // There was an error and we must stop test case execution
+ iFailedTestCase = i;
+ iRunningTests--;
+ __TRACE( KMessage, (_L("Stopping the CActiveScheduler.")));
+ CActiveScheduler::Current()->Stop();
+ iSchedulerActive = EFalse;
+ }
+
+ // Check normal test result if activescheduler is still up & running
+ if( iSchedulerActive )
+ {
+ if( aTestCase->ExpectedResultCategory() ==
+ TFullTestResult:: ECaseExecuted)
+ {
+ // Normal completion, check result
+ if( iTestCases[i]->iResult.iTestResult.iResult !=
+ iTestCases[i]->ExpectedResult() )
+ {
+ __TRACE( KMessage, (_L("Result category is not what was expected!")));
+ // There was an error and we must stop test case execution
+ iFailedTestCase = i;
+ iRunningTests = 0; //The whole test is stopped. Reset value of running tests.
+ //This line caused that variable value to be -1. Test could not finish. //iRunningTests--;
+ __TRACE( KMessage, (_L("Stopping the CActiveScheduler.")));
+ CActiveScheduler::Current()->Stop();
+ iSchedulerActive = EFalse;
+ }
+ }
+ else
+ {
+ // Abnormal completion, i.e. panic, leave, exception or timeout
+ if( aTestCase->iResult.iCaseExecutionResultCode !=
+ aTestCase->ExpectedResult())
+ {
+ __TRACE( KMessage, (_L("The test case has abnormal completion!")));
+ // There was an error and we must stop test case execution
+ iFailedTestCase = i;
+ iRunningTests--;
+ __TRACE( KMessage, (_L("Stopping the CActiveScheduler.")));
+ CActiveScheduler::Current()->Stop();
+ iSchedulerActive = EFalse;
+ }
+ }
+ }
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: NotifyEvent
+
+ Description: Asynchronous event command interface
+
+ Check requested events and send unset to first requested
+
+ Parameters: TEventIf& aEvent: in: Event command
+ TRequestStatus& aStatus: in: TRequestStatus used in
+ asynchronous command
+
+ Return Values: ETrue: asynchronous command given
+ EFalse: asyncronous command not given
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestCombiner::UnsetEvent( TEventIf& aEvent,
+ TRequestStatus& aStatus )
+ {
+
+ __TRACE( KMessage, ( _L("CTestCombiner::NotifyEvent")));
+
+ // First check TestCombiner events
+ TInt eventCount = iEventArray.Count();
+ for( TInt i = 0; i < eventCount; i++ )
+ {
+ if( aEvent.Name() == iEventArray[i]->Name() )
+ {
+ __TRACE( KMessage, (
+ _L( "Set unset pending for testcombiner's %S event"),
+ &aEvent.Name() ));
+ iEventArray[i]->SetRequestStatus( &aStatus );
+ return ETrue;
+ }
+ }
+
+ // Check all local testcases
+ TInt caseCount = iTestCases.Count();
+ TInt eventInd;
+ CTCTestCase* testCase = NULL;
+ for( TInt caseInd = 0; caseInd < caseCount; caseInd++ )
+ {
+ if( iTestCases[caseInd]->Type() == CTestCase::ECaseLocal )
+ {
+ testCase = ( CTCTestCase* )iTestCases[caseInd];
+ eventCount = testCase->EventArray().Count();
+
+ // Check all requested events
+ for( eventInd = 0; eventInd < eventCount; eventInd++)
+ {
+ const TName& eventName =
+ testCase->EventArray()[eventInd]->Event().Name();
+ if( eventName == aEvent.Name() )
+ {
+ // Event request is pending, send control command
+ iEvent.Copy( aEvent );
+ __TRACE( KMessage, (
+ _L( "Set unset pending for client's %S event"),
+ &aEvent.Name() ));
+ testCase->TestExecution().NotifyEvent( iEventPckg,
+ aStatus );
+ return ETrue;
+ }
+ }
+ }
+ }
+
+ return EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: ReceiveResponse
+
+ Description: Handles responce received from slave
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::ReceiveResponse( TDesC& aMsg )
+ {
+
+ __TRACEFUNC();
+
+ TBool continueTask = ETrue;
+ TRAPD( err, continueTask = iTestRunner->ReceiveResponseL( aMsg ) );
+
+ // We start receiver again, even in error situation
+ iRemoteReceiver->Start();
+
+ if( err != KErrNone )
+ {
+ __TRACE( KError, ( _L("CTestCombiner::ReceiveResponse ERROR")));
+ iResult = err;
+ if( iTestRunner->IsActive() )
+ {
+ iTestRunner->Cancel();
+ }
+ else
+ {
+ iTestRunner->CancelTestCases();
+ }
+ return;
+ }
+
+ if( continueTask && !iTestRunner->IsActive() )
+ {
+ iTestRunner->SetRunnerActive();
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: RemoteTimeout
+
+ Description: Handles timeouts.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::RemoteTimeout()
+ {
+
+ __TRACEFUNC();
+
+ iResult = KErrTimedOut;
+ if( iTestRunner->IsActive() )
+ {
+ __TRACE( KError, (_L("Remote timeout, Cancel runner")));
+ iTestRunner->Cancel();
+ }
+ else
+ {
+ __TRACE( KError, (_L("Remote timeout, Cancel test cases")));
+ iTestRunner->CancelTestCases();
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: ExecuteMeasurementL
+
+ Description: Executes measurement script line.
+
+ Parameters: CStifItemParser* aItem: in: parsed line
+
+ Return Values: TBool: in no error ETrue returned
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::ExecuteMeasurementL( CStifItemParser* aItem )
+ {
+ __TRACEFUNC();
+
+ __TRACEFUNC();
+ TPtrC type;
+ TPtrC command;
+
+ // Get command
+ if( aItem->GetNextString( command ) != KErrNone )
+ {
+ __TRACE( KError, (
+ _L( "Unknown argument for 'measurement' command" ) ) );
+ User::Leave( KErrArgument ); // Error in parsing => Leave
+ }
+ // Get name
+ if( aItem->GetNextString( type ) != KErrNone )
+ {
+ __TRACE( KError, (
+ _L( "Unknown argument for 'measurement' type" ) ) );
+ User::Leave( KErrArgument ); // Error in parsing => Leave
+ }
+
+ // Verify measurement type
+ if( !( type == KParamMeasurement01 ||
+ type == KParamMeasurement02 ||
+ type == KParamMeasurement03 ||
+ type == KParamMeasurement04 ||
+ type == KParamMeasurement05 ||
+ type == KParamMeasurementBappea ) )
+
+ {
+ __TRACE( KError, (
+ _L( "Unknown measurement type:[%S]" ), &type ) );
+ User::Leave( KErrArgument ); // Error in types => Leave
+ }
+
+ // Verify command
+ if( command == _L( "start" ) )
+ {
+ // START measurement's process
+ __TRACE( KMessage, ( _L( "Start 'measurement' with '%S'"), &type ) );
+ StartMeasurementL( type, aItem );
+ }
+ else if( command == _L( "stop" ) )
+ {
+ // STOP measurement's process
+ __TRACE( KMessage, ( _L( "'Stop 'measurement' with '%S'"), &type ) );
+ StopMeasurementL( type );
+ }
+ else
+ {
+ __TRACE( KError, (
+ _L( "Unknown command for 'measurement' command:[%S] or type:[%S]" ), &command, &type ) );
+ User::Leave( KErrArgument ); // Error in commands => Leave
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: StartMeasurementL
+
+ Description:
+
+ Parameters: const TDesC& aType: in: Plugin type.
+ CStifItemParser* aItem: in: Item object for parsing.
+
+ Return Values: None.
+
+ Errors/Exceptions: Leaves is bappea start or timed operation fails.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::StartMeasurementL( const TDesC& aType,
+ CStifItemParser* aItem )
+ {
+ __TRACEFUNC();
+
+ CSTIFTestMeasurement* testMeasurement = NULL;
+
+ // Get Measurement configuration info
+ TPtrC configurationInfo( KNullDesC() );
+ if( aItem->Remainder( configurationInfo ) != KErrNone )
+ {
+ __TRACE( KInit, (
+ _L( "Using default path and file name for measurement configure" ) ) );
+ }
+
+ if( aType == KParamMeasurement01 )
+ {
+ testMeasurement = CSTIFTestMeasurement::NewL(
+ this,
+ CSTIFTestMeasurement::KStifMeasurementPlugin01,
+ configurationInfo );
+ }
+ else if( aType == KParamMeasurement02 )
+ {
+ testMeasurement = CSTIFTestMeasurement::NewL(
+ this,
+ CSTIFTestMeasurement::KStifMeasurementPlugin02,
+ configurationInfo );
+ }
+ else if( aType == KParamMeasurement03 )
+ {
+ testMeasurement = CSTIFTestMeasurement::NewL(
+ this,
+ CSTIFTestMeasurement::KStifMeasurementPlugin03,
+ configurationInfo );
+ }
+ else if( aType == KParamMeasurement04 )
+ {
+ testMeasurement = CSTIFTestMeasurement::NewL(
+ this,
+ CSTIFTestMeasurement::KStifMeasurementPlugin04,
+ configurationInfo );
+ }
+ else if( aType == KParamMeasurement05 )
+ {
+ testMeasurement = CSTIFTestMeasurement::NewL(
+ this,
+ CSTIFTestMeasurement::KStifMeasurementPlugin05,
+ configurationInfo );
+ }
+ else if( aType == KParamMeasurementBappea )
+ {
+ testMeasurement = CSTIFTestMeasurement::NewL(
+ this,
+ CSTIFTestMeasurement::KStifMeasurementBappeaProfiler,
+ configurationInfo );
+ }
+ else
+ {
+ __TRACE( KError, ( _L( "Unknown plugin[%S] for 'measurement'" ), &aType ) );
+ User::Leave( KErrArgument );
+ }
+
+ // Start test measurement
+ TInt start_ret( KErrNone );
+ start_ret = testMeasurement->Start();
+ if( start_ret != KErrNone )
+ {
+ delete testMeasurement;
+ __TRACE( KError, (
+ _L( "CTestCombiner::StartMeasurementL(): Measurement Start() fails:[%d]" ), start_ret ) );
+ User::Leave( start_ret );
+ }
+
+ TTestMeasurement* object = new (ELeave) TTestMeasurement();
+ object->iName = aType;
+ object->iMeasurement = testMeasurement;
+
+ // Array for handling test measurement between different objects
+ TInt ret = iTestMeasurementArray.Append( object );
+ if( ret != KErrNone )
+ {
+ delete object;
+ __TRACE( KError, (
+ _L( "CTestCombiner::StartMeasurementL(): iTestMeasurementArray.Append fails:[%d]" ), ret ) );
+ User::Leave( ret );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: StopMeasurementL
+
+ Description: Stops test measurement.
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::StopMeasurementL( const TDesC& aType )
+ {
+ __TRACEFUNC();
+
+ TInt count = iTestMeasurementArray.Count();
+ for( TInt i = 0; i < count; i++ )
+ {
+ if( iTestMeasurementArray[i]->iName == aType )
+ {
+ // Found measurement module, stop
+ iTestMeasurementArray[i]->iMeasurement->Stop();
+ // Delete data
+ delete iTestMeasurementArray[i];
+ // Remove pointer to deleted data(Append())
+ iTestMeasurementArray.Remove( i );
+ // iTestMeasurementArray can contain only one type of measurement
+ // so we can break when type is removed.
+ break;
+ }
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: AppendTestResultToResultDes
+
+ Description: Append to TC's result description (if possible due to length)
+ limitation provided text in [] brackets.
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestCombiner::AppendTestResultToResultDes(TDes& aResultDescr, const TDesC& aTestCaseResultDescr)
+ {
+ if(aTestCaseResultDescr != KNullDesC)
+ {
+ _LIT(KAdditionalInfo, " [%S]");
+ TInt len = aResultDescr.Length() + KAdditionalInfo().Length() + aTestCaseResultDescr.Length();
+
+ if(len > KStifMaxResultDes)
+ {
+ len = KStifMaxResultDes - aResultDescr.Length() - KAdditionalInfo().Length();
+ if(len > 0)
+ {
+ TPtrC descr = aTestCaseResultDescr.Mid(0, len);
+ aResultDescr.AppendFormat(KAdditionalInfo, &descr);
+ }
+ }
+ else
+ {
+ aResultDescr.AppendFormat(KAdditionalInfo, &aTestCaseResultDescr);
+ }
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCombiner
+
+ Method: GetIndexForNewTestModuleController
+
+ Description: Returns new index for test module controller.
+ This number is appended to module controller name.
+ This method is used when option to run every test case in
+ separate process is set to on.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCombiner::GetIndexForNewTestModuleController(void)
+ {
+ return iIndexTestModuleControllers++;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains the implementation of CTestRunner class
+ member functions. CTestRunner is used to execute TestCombiner testcase by
+ CTestCombiner.
+
+-------------------------------------------------------------------------------
+*/
+// MACROS
+#ifdef LOGGER
+#undef LOGGER
+#endif
+#define LOGGER iTestCombiner->iLog
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: CTestRunner
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestCombiner* aTestCombiner: in: Backpointer to CTestCombiner
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestRunner::CTestRunner( CTestCombiner* aTestCombiner ):
+ CActive( CActive::EPriorityLow ), // Executed with lowest priority
+ iState( ERunnerIdle ),
+ iTestCombiner( aTestCombiner )
+ {
+ CActiveScheduler::Add( this );
+ __TRACEFUNC();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::ConstructL()
+ {
+
+ iPauseTimer.CreateLocal();
+
+ iRemoteTimer = CRemoteTimer::NewL( iTestCombiner );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestCombiner* aTestCombiner: in: Backpointer to CTestCombiner
+
+ Return Values: CTestRunner*: new object
+
+ Errors/Exceptions: Leaves if new or ConstructL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+
+CTestRunner* CTestRunner::NewL( CTestCombiner* aTestCombiner )
+ {
+ CTestRunner* self = new (ELeave) CTestRunner( aTestCombiner );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ~CTestRunner
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+
+CTestRunner::~CTestRunner()
+ {
+ __TRACEFUNC();
+ Cancel();
+
+ delete iRemoteTimer;
+ iRemoteTimer = 0;
+
+ delete iLine;
+ iLine = 0;
+
+ iPauseTimer.Close();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: RunL
+
+ Description: Derived from CActive, handles testcase execution.
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::RunL()
+ {
+ __TRACEFUNC();
+ __TRACE( KMessage, (_L("CTestRunner::RunL: [%d] "), iStatus.Int() ));
+
+ User::LeaveIfError( iStatus.Int() );
+
+ if( ( iTestCombiner == NULL ) ||
+ ( iTestCombiner->iSectionParser == NULL ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+
+ TBool continueTask = EFalse;
+
+ switch( iState )
+ {
+ case ERunnerWaitTimeout:
+ {
+ __TRACE( KMessage, (_L("Resume %S"), &iPausedTestCase));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec,
+ KExecute, _L("Resume %S"), &iPausedTestCase);
+ // Get running testcase identified with testid
+ CTestCase* testCase = iTestCombiner->GetRunningTest( iPausedTestCase );
+ if( testCase == NULL ) User::Leave( KErrNotFound );
+ iPausedTestCase.Zero();
+ if( testCase->Type() == CTestCase::ECaseLocal )
+ {
+ CTCTestCase* localTestCase = ( CTCTestCase* )testCase;
+ // Resume execution
+ User::LeaveIfError( localTestCase->TestExecution().Resume() );
+ continueTask = ETrue;
+ }
+ else // ECaseRemote
+ {
+ CRemoteTestCase* remoteTestCase = ( CRemoteTestCase* )testCase;
+ // Resume execution
+ if( ExecuteRemoteTestCtlL( NULL,
+ remoteTestCase,
+ TTCKeywords::EResume ) )
+ {
+ continueTask = ETrue;
+ }
+ }
+ }
+ break;
+ case ERunnerWaitUnset:
+ iState = ERunnerIdle;
+
+ // Check Unset event
+ if( !CheckUnsetEvent() )
+ {
+ // Got event and unset has not completed
+ // Should never come here
+ User::Panic( KTestRunner, KErrGeneral );
+ }
+ break;
+
+ case ERunnerRunning:
+ {
+ iState = ERunnerIdle;
+
+ // Get next execution line from configuration section
+ iEndLoopStartPos = iTestCombiner->iSectionParser->GetPosition();
+ TPtrC line;
+ if( iTestCombiner->iSectionParser->GetNextLine( line ) == KErrNone )
+ {
+ // Got new execution line
+ __TRACE( KMessage, (_L("CTestRunner got line")));
+
+ CStifItemParser* item = PreprocessLineL( line );
+
+ if( item )
+ {
+ // Got new execution line
+ CleanupStack::PushL( item );
+
+ // Execute script line
+ if( ExecuteLineL( item ) )
+ {
+ __TRACE( KMessage, (_L("RunL: continueTask")));
+ // Set CTestRunner active again to perform
+ // next execution line
+ // from testcase section
+ continueTask = ETrue;
+ }
+ CleanupStack::PopAndDestroy( item );
+ }
+ }
+ else
+ {
+ // No more execution lines in testcase section
+ __TRACE( KMessage,
+ (_L("CTestRunner::RunL: Testcase script done (%d running)"),
+ iTestCombiner->iRunningTests));
+
+ if( ( iTestCombiner->iRunningTests == 0 ) &&
+ iTestCombiner->iSchedulerActive )
+ {
+ __TRACE( KMessage,
+ (_L("RunL: All TestCases done, stop CActiveScheduler")));
+ CActiveScheduler::Current()->Stop();
+ iTestCombiner->iSchedulerActive = EFalse;
+ }
+ // Now testcase section is executed,
+ // so CTestRunner has done its job and stops
+ iState = ERunnerReady;
+
+ //If we're inside loop, then we have error
+ if(iTestCombiner->iLoopIsUsed)
+ {
+ __TRACE(KError, (_L("Endloop keyword not found. Cannot finish test case properly.")));
+ iTestCombiner->iResult = KErrGeneral;
+ }
+ }
+ }
+ break;
+ case ERunnerAllocate:
+ case ERunnerFree:
+ case ERunnerRemote:
+ default:
+ __TRACE( KError,
+ (_L("CTestRunner::RunL: Entered in illegal state(%d)"), iState ));
+ User::Panic( KTestRunner, KErrGeneral );
+ break;
+ }
+ if( continueTask )
+ {
+ SetRunnerActive();
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: DoCancel
+
+ Description: Derived from CActive handles the Cancel
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::DoCancel()
+ {
+ __TRACEFUNC();
+ __TRACE( KMessage, (_L("CTestRunner::DoCancel")));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), _L("DoCancel"));
+
+ switch( iState )
+ {
+ case ERunnerWaitTimeout:
+ iPauseTimer.Cancel();
+ break;
+ case ERunnerWaitUnset:
+ break;
+ case ERunnerRunning:
+ break;
+ case ERunnerAllocate:
+ case ERunnerFree:
+ case ERunnerRemote:
+ // Cancel remote test cases
+ break;
+ default:
+ __TRACE( KError,
+ (_L("CTestRunner::DoCancel: Entered in illegal state(%d)"), iState ));
+ User::Panic( KTestRunner, KErrGeneral );
+ break;
+ }
+
+ // Cancel all testcases
+ CancelTestCases();
+
+ iState = ERunnerCancel;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: RunError
+
+ Description: Derived from CActive handles errors from active handler.
+
+ Parameters: TInt aError: in: error from CActive
+
+ Return Values: KErrNone: success
+
+ Errors/Exceptions: None.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestRunner::RunError( TInt aError )
+ {
+ __TRACEFUNC();
+ __TRACE( KMessage, (_L("CTestRunner::RunError %d"), aError));
+
+ if ( iRunErrorMessage.Length() != 0 )
+ {
+ iTestCombiner->TestModuleIf().Printf( KPrintPriLow, _L("Runner"),
+ _L("RunError : %S"), &iRunErrorMessage );
+ iRunErrorMessage = KNullDesC;
+ }
+ else
+ {
+ iTestCombiner->TestModuleIf().Printf( KPrintPriLow, _L("Runner"),
+ _L("RunError"));
+ }
+
+ iState = ERunnerError;
+
+ // Return error from here
+ iTestCombiner->iResult = aError;
+
+ CancelTestCases();
+ return KErrNone;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: PreprocessLineL
+
+ Description: Preprocesses script line
+
+ Parameters: TPtrC& line: in: script line
+ CStifItemParser*& aItem: out: New CStifItemParser for script
+ line.
+
+ Return Values: HBufC* pointer if new memory that has been allocated
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+CStifItemParser* CTestRunner::PreprocessLineL( TDesC& line )
+ {
+
+ CStifItemParser* item = NULL;
+ TPtrC tmp;
+ TInt len = 0;
+
+ // Decide how long buffer should be allocated
+ if( line.Length() < KMaxName/2 )
+ {
+ len = KMaxName;
+ }
+ else
+ {
+ len = line.Length() + KMaxName;
+ }
+ delete iLine;
+ iLine = 0;
+ iLine = HBufC::NewL( len );
+ TPtr parsedLine( iLine->Des() );
+ len = 0;
+
+ item = CStifItemParser::NewL( line, 0, line.Length() );
+ CleanupStack::PushL( item);
+
+ TInt ret = item->GetString( _L(""), tmp );
+ while( ret == KErrNone )
+ {
+ len += CheckDefined( tmp );
+ if( ( parsedLine.Length() + tmp.Length() + 1 ) > parsedLine.MaxLength() )
+ {
+ // Allocate bigger buffer
+ HBufC* tmpBuf = HBufC::NewL( parsedLine.MaxLength() + KMaxName );
+ CleanupStack::PushL( tmpBuf );
+ TPtrC ptr( iLine->Des() );
+ parsedLine.Set( tmpBuf->Des() );
+ parsedLine.Copy( ptr );
+ delete iLine;
+ iLine = tmpBuf;
+ CleanupStack::Pop( tmpBuf );
+ }
+ parsedLine.Append( tmp );
+ parsedLine.Append( _L(" ") );
+ ret = item->GetNextString( tmp );
+ }
+
+ CleanupStack::PopAndDestroy( item );
+
+ item = CStifItemParser::NewL( parsedLine, 0, parsedLine.Length() );
+
+ return item;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: CheckDefined
+
+ Description: Check if aWord is some defined word
+
+ Parameters: TPtrC& aWord: inout: Parsed word, defined or original returned
+
+ Return Values: TInt: Length difference between new and old word
+
+ Errors/Exceptions: None.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestRunner::CheckDefined( TPtrC& aWord )
+ {
+ TInt len = 0;
+
+ // KLoopCounter word changing to current loop count value.
+ if( aWord == KLoopCounter )
+ {
+ iLoopCounterDes.Zero();
+ iLoopCounterDes.AppendNum( iLoopCounter );
+ len = iLoopCounterDes.Length() - aWord.Length();
+ aWord.Set( iLoopCounterDes );
+ return len;
+ }
+
+ TInt count = iTestCombiner->iDefined.Count();
+ for( TInt i = 0; i < count; i++ )
+ {
+ if( iTestCombiner->iDefined[i]->Name() == aWord )
+ {
+ len = iTestCombiner->iDefined[i]->Value().Length() - aWord.Length();
+ aWord.Set( iTestCombiner->iDefined[i]->Value() );
+ break;
+ }
+ }
+ return len;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteLineL
+
+ Description: Executes script line
+
+ Parameters: CStifItemParser* aItem: in: script line
+ TTCKeywords::TKeywords aKeyword: in: keyword index
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteLineL( CStifItemParser* aItem )
+ {
+ _LIT( KErrMsgUnknownKeyword, "Unknown or illegal keyword %S" );
+ _LIT( KErrMsgMeasurementInvalidArgument, "Measurement : Invalid argument" );
+ TBool continueTask = ETrue;
+ TPtrC tmp;
+
+ TPtrC keywordItem;
+ // Get first word from line, i.e. keyword
+ User::LeaveIfError( aItem->GetString( _L(""), keywordItem ) );
+ // Parse keyword
+ TInt keyword = TTCKeywords::Parse( keywordItem, TTCKeywords::Keyword );
+
+ switch( keyword )
+ {
+ // Test case execution control cases
+ case TTCKeywords::EPauseCombiner:
+ continueTask = ExecuteCombinerPauseL( aItem );
+ break;
+ case TTCKeywords::ERun:
+ continueTask = ExecuteRunL( aItem );
+ break;
+ case TTCKeywords::EPause:
+ case TTCKeywords::EComplete:
+ case TTCKeywords::ECancel:
+ case TTCKeywords::EResume:
+ continueTask = ExecuteTestCtlL( aItem, (TTCKeywords::TKeywords)keyword );
+ break;
+
+ // Event control cases
+ case TTCKeywords::ESet:
+ continueTask = ExecuteEventSetL( aItem );
+ break;
+ case TTCKeywords::EUnset:
+ continueTask = ExecuteEventUnsetL( aItem );
+ break;
+ case TTCKeywords::ERequest:
+ case TTCKeywords::EWait:
+ case TTCKeywords::ERelease:
+ continueTask = ExecuteEventCtlL( aItem, (TTCKeywords::TKeywords)keyword );
+ break;
+ case TTCKeywords::EPrint:
+ {
+ TName buf;
+ while( aItem->GetNextString( tmp ) == KErrNone )
+ {
+ if( buf.Length() + tmp.Length() >= buf.MaxLength() )
+ {
+ break;
+ }
+ buf.Append( tmp );
+ buf.Append( _L(" ") );
+ }
+
+ __TRACE( KMessage, (_L("Test: %S"), &buf ));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriHigh,
+ _L("Test"),
+ _L("%S"), &buf);
+ }
+ break;
+ case TTCKeywords::EAllocate:
+ continueTask = ExecuteAllocateL( aItem );
+ break;
+ case TTCKeywords::EFree:
+ continueTask = ExecuteFreeL( aItem );
+ break;
+ case TTCKeywords::ERemote:
+ continueTask = ExecuteRemoteL( aItem );
+ break;
+ case TTCKeywords::ETimeout:
+ case TTCKeywords::EPriority:
+ // not used here
+ break;
+ case TTCKeywords::ECancelIfError:
+ // @js
+ iTestCombiner->iCancelIfError = ETrue;
+ break;
+ case TTCKeywords::EMeasurement:
+ TRAPD( retErr, iTestCombiner->ExecuteMeasurementL( aItem ) );
+ if ( retErr == KErrArgument )
+ {
+ iRunErrorMessage = KErrMsgMeasurementInvalidArgument;
+ }
+ if ( retErr != KErrNone )
+ {
+ User::Leave( retErr );
+ }
+ break;
+ case TTCKeywords::ELoop:
+ ExecuteLoopL( aItem );
+ iTestCombiner->iLoopIsUsed = ETrue;
+ break;
+ case TTCKeywords::EEndLoop:
+ continueTask = ExecuteEndLoopL();
+ break;
+ case TTCKeywords::ETitle:
+ // title has been handled already, this is duplicate
+ default:
+ {
+ __TRACE( KError, (_L("Unknown or illegal keyword") ) );
+ // Unknown or illegal keyword
+ iRunErrorMessage.Format( KErrMsgUnknownKeyword, &keywordItem );
+ User::Leave( KErrGeneral );
+ }
+ break;
+ }
+
+ __TRACE( KMessage, (_L("RunL: TestCase line executed")));
+
+ return continueTask;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteRunL
+
+ Description: Executes run line
+
+ Parameters: CStifItemParser* aItem: in: script line
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteRunL( CStifItemParser* aItem )
+ {
+ _LIT( KErrMsgCaseRunError, "Run : %S[case=%d] run error" );
+ __TRACE( KMessage, (_L("Run")));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec, KExecute, _L("Run"));
+
+ CStartInfo* startInfo = CStartInfo::NewL();
+ CleanupStack::PushL( startInfo );
+
+ ParseRunParamsL( aItem, *startInfo );
+
+ // Start new case with configurations parsed above
+
+ iRunErrorMessage.Format( KErrMsgCaseRunError, &startInfo->iModule, startInfo->iCaseNum );
+ User::LeaveIfError(
+ iTestCombiner->StartTestL( *startInfo ) );
+ iRunErrorMessage = KNullDesC;
+
+ CleanupStack::PopAndDestroy( startInfo );
+
+ return ETrue;
+
+}
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ParseRunParamsL
+
+ Description: Parses run parameters
+
+ Parameters: CStifItemParser* aItem: in: script line
+ CStartInfo& aStartInfo: out: Parsed information
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::ParseRunParamsL( CStifItemParser* aItem,
+ CStartInfo& aStartInfo )
+ {
+ _LIT( KErrMsgRunTestmoduleNameNotDefined, "Run : Testmodule name is not defined " );
+ _LIT( KErrMsgRunCfgFileNotDefined, "Run : Testmodule configuration file is not defined" );
+ _LIT( KErrMsgRunTestcaseNumberNotDefined, "Run : Testcase number is not defined or has invalid value" );
+ _LIT( KErrMsgRunCfgFileNameToLong, "Run : TestScripter test case file(config)'s name is too long. Current length[%d], allowed max length[%d]. Cannot continue" );
+ _LIT( KErrMsgRunInvalidExpectValue, "Run : Invalid expected result value" );
+ _LIT( KErrMsgRunUnknownOrIllegalCategory, "Run : Unknown or illegal result category" );
+ _LIT( KErrMsgRunInvalidTimeoutValue, "Run: Invalid testcase timeout value" );
+ _LIT( KErrMsgRunUnknowOrIllegalKeyword, "Run: Unknown or illegal keyword %S" );
+
+ TPtrC tmp;
+ TInt ret = KErrNone;
+
+ // Get mandatory run arguments
+ // Testmodule name
+ ret = aItem->GetNextString( tmp );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgRunTestmoduleNameNotDefined;
+ User::Leave( ret );
+ }
+
+ aStartInfo.SetModuleNameL( tmp );
+ __TRACE( KMessage, (_L("module: %S"), &aStartInfo.iModule ));
+
+ // Configuration file
+ ret = aItem->GetNextString( tmp );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgRunCfgFileNotDefined;
+ User::Leave( ret );
+ }
+
+ TFileName cfgFileName( tmp );
+ TStifUtil::CorrectFilePathL( cfgFileName );
+ aStartInfo.SetConfigL( cfgFileName );
+
+ __TRACE( KMessage, (_L("config: %S"), &aStartInfo.iConfig ));
+
+ // Check is TestScripter
+ if( aStartInfo.iModule.Find( KTestScripterName ) != KErrNotFound )
+ {
+ // TestScripter name is format: 'testscripter_testcasefilename'
+
+ TParse parse;
+ parse.Set( aStartInfo.iConfig, NULL, NULL );
+
+ // Maximum length of TestScripter's name(Max limitation from
+ // CTestModuleController creation)
+ TInt maximumLength = KMaxName - ( KTestScripterNameLength + 1 );
+
+ TFileName testScripterAndTestCaseFile; // InitL() takes TFileName
+ testScripterAndTestCaseFile.Copy( KTestScripterName );
+ testScripterAndTestCaseFile.Append( _L( "_" ) );
+ if( parse.Name().Length() < maximumLength )
+ {
+ testScripterAndTestCaseFile.Append( parse.Name() );
+ }
+ else
+ {
+ __TRACE( KInit, ( CStifLogger::ERed,
+ _L( "TestScripter test case file(config)'s name is too long. Current length[%d], allowed max length[%d]. Cannot continue" ),
+ parse.Name().Length(), maximumLength ) );
+ iRunErrorMessage.Format( KErrMsgRunCfgFileNameToLong, parse.Name().Length(), maximumLength );
+ User::Leave( KErrArgument );
+ }
+// ----
+ aStartInfo.DeleteModuleName(); // Delete old name buffer for new one
+ aStartInfo.SetModuleNameL( testScripterAndTestCaseFile );
+ }
+
+ // Testcase number
+ ret = aItem->GetInt( tmp, aStartInfo.iCaseNum );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgRunTestcaseNumberNotDefined;
+ User::Leave( ret );
+ }
+
+ __TRACE( KMessage, (_L("testcasenum: %d"), aStartInfo.iCaseNum ) );
+
+ // Set mode of item parser to be able to read titles with spaces inside
+ aItem->SetParsingType(CStifItemParser::EQuoteStyleParsing);
+
+ // Get optional run arguments
+ while( aItem->GetNextString( tmp ) == KErrNone )
+ {
+ TPtrC val;
+ TPtrC arg;
+ ParseOptArgL( tmp, arg, val );
+ CheckDefined( val );
+
+ // Parse optional argument
+ switch( TTCKeywords::Parse( arg, TTCKeywords::RunOptArg ) )
+ {
+ case TTCKeywords::EExpect:
+ {
+ TLex ptr( val );
+ ret = ptr.Val( aStartInfo.iExpectedResult );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgRunInvalidExpectValue;
+ User::Leave( ret );
+ }
+ __TRACE( KMessage, (_L("expect=%d"), aStartInfo.iExpectedResult));
+ }
+ break;
+ case TTCKeywords::ETestid:
+ {
+ aStartInfo.SetTestIdL( val );
+ __TRACE( KMessage, (_L("TestId=%S"), &val));
+ }
+ break;
+ case TTCKeywords::EIni:
+ {
+ __TRACE( KMessage, (_L("ini=%S"), &val));
+ TFileName iniFileName( val );
+ TStifUtil::CorrectFilePathL( iniFileName );
+ aStartInfo.SetIniFileL( iniFileName );
+ }
+ break;
+ case TTCKeywords::ECategory:
+ {
+ __TRACE( KMessage, (_L("category=%S"), &val));
+ aStartInfo.iCategory = TTCKeywords::GetResultCategory( val );
+ if( aStartInfo.iCategory == TFullTestResult::ECaseOngoing )
+ {
+ __TRACE( KError, (_L("Unknown or illegal result category")));
+ //Unknown or illegal category
+ iRunErrorMessage = KErrMsgRunUnknownOrIllegalCategory;
+ User::Leave( KErrGeneral );
+ }
+ }
+ break;
+ case TTCKeywords::ECaseTimeout:
+ {
+ TLex ptr( val );
+ ret = ptr.Val( aStartInfo.iTimeout );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgRunInvalidTimeoutValue;
+ User::Leave( ret );
+ }
+ __TRACE( KMessage, (_L("timeout=%d"), aStartInfo.iTimeout ) );
+ }
+ break;
+ case TTCKeywords::ECaseTitle:
+ {
+ __TRACE( KMessage, (_L("case title=%S"), &val));
+ aStartInfo.SetTitleL(val);
+ break;
+ }
+ default:
+ {
+ __TRACE( KError, (_L("Unknown or illegal keyword")));
+ //Unknown or illegal keyword
+ iRunErrorMessage.Format( KErrMsgRunUnknowOrIllegalKeyword, &arg );
+ User::Leave( KErrGeneral );
+ }
+ }
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteTestCtlL
+
+ Description: Executes script line
+
+ Parameters: CStifItemParser* aItem: in: script line
+ TTCKeywords::TKeywords aKeyword: in: keyword index
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteTestCtlL( CStifItemParser* aItem,
+ TTCKeywords::TKeywords aKeyword )
+ {
+ _LIT( KErrMsgTestIdNotDefined, "%S : testid is not defined" );
+ _LIT( KErrMsgTestCaseNotFound, "%S : Test case %S not found" );
+ TBool continueTask = ETrue;
+ TPtrC tmp;
+
+ TInt ret = KErrNone;
+
+ TPtrC keywordStr = TTCKeywords::Keyword( aKeyword );
+
+ // Parse testid
+ ret = aItem->GetNextString( tmp );
+ if( ret != KErrNone )
+ {
+ iRunErrorMessage.Format( KErrMsgTestIdNotDefined, &keywordStr );
+ User::Leave( ret );
+ }
+
+ // Get testcase identified with testid
+ CTestCase* testCase = iTestCombiner->GetTest( tmp );
+ if( testCase == NULL )
+ {
+ __TRACE( KError, (_L("ExecuteTestCtlL: Test case %S not found"),
+ &tmp));
+ iRunErrorMessage.Format( KErrMsgTestCaseNotFound, &keywordStr, &tmp );
+ User::Leave( KErrNotFound );
+ }
+
+ switch( aKeyword )
+ {
+ // Test case execution control cases
+ case TTCKeywords::EPause:
+ continueTask = ExecutePauseL( aItem, testCase );
+ break;
+ case TTCKeywords::EComplete:
+ continueTask = ExecuteCompleteL( aItem, testCase );
+ break;
+ case TTCKeywords::ECancel:
+ __TRACE( KMessage, (_L("Cancel %S"), &tmp));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec,
+ KExecute, _L("Cancel %S"), &tmp);
+ if( testCase->Type() == CTestCase::ECaseRemote )
+ {
+ continueTask =
+ ExecuteRemoteTestCtlL( aItem, testCase, aKeyword );
+ }
+ else
+ {
+ if( testCase->State() != CTestCase::ETestCaseRunning )
+ {
+ __TRACE( KMessage, (_L("Cancelled task (%S) not running (%i)"),
+ &tmp, testCase->State() ));
+ User::Leave( KErrNotFound );
+ }
+ CTCTestCase* test = ( CTCTestCase* )testCase;
+ // Cancel local testcase
+ test->TestExecution().CancelAsyncRequest( ETestExecutionRunTestCase );
+ }
+ break;
+ case TTCKeywords::EResume:
+ {
+ __TRACE( KMessage, (_L("Resume %S"), &tmp));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec,
+ KExecute, _L("Resume %S"), &tmp);
+ if( testCase->Type() == CTestCase::ECaseRemote )
+ {
+ continueTask =
+ ExecuteRemoteTestCtlL( aItem, testCase, aKeyword );
+ }
+ else
+ {
+ if( testCase->State() != CTestCase::ETestCaseRunning )
+ {
+ __TRACE( KMessage, (_L("Resumed task (%S) not running (%i)"),
+ &tmp, testCase->State() ));
+ User::Leave( KErrNotFound );
+ }
+ CTCTestCase* test = ( CTCTestCase* )testCase;
+ // Resume execution
+ User::LeaveIfError( test->TestExecution().Resume() );
+ }
+ }
+ break;
+
+ default:
+ // Should never come here
+ User::Leave( KErrGeneral );
+ break;
+ }
+
+ return continueTask;
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteCombinerPauseL
+
+ Description: Executes causes pause in TestCombiner
+
+ Parameters: CStifItemParser* aItem: in: script line
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteCombinerPauseL( CStifItemParser* aItem )
+{
+ _LIT( KErrMsgPauseTimeoutNotDefined, "PauseCombiner : No timeout value given or value has invalid format" );
+ _LIT( KErrMsgPauseTimeoutNotPositive, "PauseCombiner : Timeout value can't be <0" );
+
+ TBool continueTask = ETrue;
+ TInt pauseTime;
+ TInt ret = KErrNone;
+
+ // Parse testid
+ ret = aItem->GetNextInt( pauseTime );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgPauseTimeoutNotDefined;
+ User::Leave( ret );
+ }
+
+ if( pauseTime < 0 )
+ {
+ __TRACE( KError, (_L("CTestRunner::ExecuteCombinerPauseL: Given pause value < 0")));
+ iRunErrorMessage = KErrMsgPauseTimeoutNotPositive;
+ User::Leave( KErrArgument );
+ }
+
+ //Time given by End User should be given in miliseconds
+ pauseTime*=1000;
+
+ __TRACE( KMessage, (_L("time=%d"), pauseTime ) );
+
+ User::After( pauseTime );
+
+ return continueTask;
+}
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecutePauseL
+
+ Description: Executes pause line
+
+ Parameters: CStifItemParser* aItem: in: script line
+ CTestCase* aTestcase: in: test case
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecutePauseL( CStifItemParser* aItem,
+ CTestCase* aTestcase )
+ {
+ _LIT( KErrMsgPauseUnknownKeyword, "Pause : Unknown or illegal keyword %S" );
+ _LIT( KErrMsgPauseTimeInvalidValue, "Pause : Pause time is not defined or has invalid value" );
+ _LIT( KErrMsgPauseTimeNotPositive, "Pause : Pause time can't be <0" );
+ TBool continueTask = ETrue;
+
+ // Get optional pause arguments
+ TPtrC tmp;
+ iPauseTime = 0;
+ while( aItem->GetNextString( tmp ) == KErrNone )
+ {
+ TPtrC val;
+ TPtrC arg;
+ ParseOptArgL( tmp, arg, val );
+ CheckDefined( val );
+
+ // Parse optional argument
+ switch( TTCKeywords::Parse( arg, TTCKeywords::PauseOptArg ) )
+ {
+ case TTCKeywords::ETime:
+ {
+ TLex ptr( val );
+ TInt ret = KErrNone;
+ ret = ptr.Val( iPauseTime );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgPauseTimeInvalidValue;
+ User::Leave( ret );
+ }
+ if ( iPauseTime < 0 )
+ {
+ iRunErrorMessage = KErrMsgPauseTimeNotPositive;
+ User::Leave( KErrArgument );
+ }
+ __TRACE( KMessage, (_L("time=%d"), iPauseTime ));
+ }
+ break;
+ default:
+ __TRACE( KError, (_L("Unknown or illegal keyword")));
+ //Unknown or illegal keyword
+ iRunErrorMessage.Format( KErrMsgPauseUnknownKeyword, &arg );
+ User::Leave( KErrGeneral );
+ }
+ }
+
+ // Store paused testcase id if timeout was given as pause argument
+ if( iPauseTime != 0 )
+ {
+ iPausedTestCase.Copy( aTestcase->TestId() );
+ }
+
+ if( aTestcase->Type() == CTestCase::ECaseRemote )
+ {
+ return ExecuteRemoteTestCtlL( aItem, aTestcase, TTCKeywords::EPause );
+ }
+ if( aTestcase->State() != CTestCase::ETestCaseRunning )
+ {
+ __TRACE( KMessage, (_L("Paused task (%S) not running (%i)"),
+ &aTestcase->TestId(), aTestcase->State() ));
+ User::Leave( KErrNotFound );
+ }
+ CTCTestCase* test = ( CTCTestCase* )aTestcase;
+
+ // Pause execution
+ User::LeaveIfError( test->TestExecution().Pause() );
+
+ // Resume paused case if timeout was given
+ if( iPauseTime != 0 )
+ {
+ continueTask = EFalse;
+ iState = ERunnerWaitTimeout;
+ iPauseTimer.After( iStatus, iPauseTime*1000 );
+ SetActive();
+ }
+
+ return continueTask;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteCompleteL
+
+ Description: Executes complete line
+
+ Parameters: CStifItemParser* aItem: in: script line
+ CTestCase* aTestcase: in: test case
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteCompleteL( CStifItemParser* /* aItem */,
+ CTestCase* aTestcase )
+ {
+ TBool ret = ETrue;
+
+ if( aTestcase->State() == CTestCase::ETestCaseCompleted )
+ {
+ // Requested testcase is completed already,
+ // proceed testcase execution
+ __TRACE( KMessage, (_L("Already completed")));
+ }
+ else if( aTestcase->State() == CTCTestCase::ETestCaseRunning )
+ {
+ // Wait testcase to complete
+ iTestCombiner->iWaitTestCase.Copy( aTestcase->TestId() );
+ // Stop testcase execution until testcase completed
+ ret = EFalse;
+ iState = ERunnerWaitTestCase;
+ }
+ else
+ {
+ // This should newer happen
+ User::Leave( KErrGeneral );
+ }
+
+ return ret;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteEventSetL
+
+ Description: Executes event set line
+
+ Parameters: CStifItemParser* aItem: in: script line
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteEventSetL( CStifItemParser* aItem )
+ {
+ _LIT( KErrMsgSetEventNameNotDefined, "Set : event name is not defined" );
+ _LIT( KErrMsgSetUnknownOrIllegalKeyword, "Set :Unknown or illegal keyword %S" );
+ _LIT( KErrMsgSetStateInvalidValue, "Set : State value is not defined or has invalid format" );
+ TPtrC tmp;
+ TPtrC eventName;
+ TInt ret = KErrNone;
+
+ // Get event name
+ ret = aItem->GetNextString( eventName );
+ if( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgSetEventNameNotDefined;
+ User::Leave( ret );
+ }
+ __TRACE( KMessage, (_L("Set %S"), &eventName));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec, KExecute,
+ _L("Set %S"), &eventName);
+ iEvent.SetName( eventName );
+ iEvent.SetType( TEventIf::ESetEvent );
+
+ // Get optional set arguments
+ while( aItem->GetNextString( tmp ) == KErrNone )
+ {
+ TPtrC val;
+ TPtrC arg;
+ ParseOptArgL( tmp, arg, val );
+ CheckDefined( val );
+
+ // Parse optional set argument
+ switch( TTCKeywords::Parse( arg, TTCKeywords::EventOptArg ) )
+ {
+ case TTCKeywords::EState:
+ {
+ TLex ptr( val );
+ TInt tmpVal = 0;
+ ret = ptr.Val( tmpVal );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgSetStateInvalidValue;
+ User::Leave( ret );
+ }
+
+ // Only value 1 has special meaning, others are ignored
+ if( tmpVal == 1 )
+ {
+ __TRACE( KMessage, (_L("State event")));
+ iEvent.SetEventType( TEventIf::EState );
+ }
+ }
+ break;
+ default:
+ __TRACE( KError, (_L("Unknown or illegal keyword")));
+ //Unknown or illegal keyword
+ iRunErrorMessage.Format( KErrMsgSetUnknownOrIllegalKeyword, &arg );
+ User::Leave( KErrGeneral );
+ }
+ }
+
+ // Set event
+ iTestCombiner->TestModuleIf().Event( iEvent, iStatus );
+ iState = ERunnerRunning;
+ SetActive();
+
+ return EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteEventUnsetL
+
+ Description: Executes event unset line
+
+ Parameters: CStifItemParser* aItem: in: script line
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteEventUnsetL( CStifItemParser* aItem )
+ {
+ _LIT( KErrMsgUnsetEventNameNotDefined, "Unset : Event name is not defined" );
+ TPtrC eventName;
+ TInt ret = KErrNone;
+ // Get event name
+ ret = aItem->GetNextString( eventName );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage = KErrMsgUnsetEventNameNotDefined;
+ User::Leave( ret );
+ }
+
+ __TRACE( KMessage, (_L("Unset %S"), &eventName));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec, KExecute,
+ _L("Unset %S"), &eventName);
+ iEvent.Set( TEventIf::EUnsetEvent, eventName, TEventIf::EState );
+
+ // Check if trying to unset an event that is requested
+ // by testcombiner (otherwise testcombiner would deadlock)
+ TInt count = iTestCombiner->iEventArray.Count();
+ TInt ind = 0;
+ for(; ind < count; ind++ )
+ {
+ if( eventName == iTestCombiner->iEventArray[ind]->Name() )
+ {
+ User::Leave( KErrInUse );
+ }
+ }
+
+ // Check if some testmodule below
+ // has event request pending
+ if( iTestCombiner->UnsetEvent( iEvent,
+ iStatus ) == EFalse )
+ {
+ // If they haven't requested event,
+ // then check others above
+ iTestCombiner->TestModuleIf().Event( iEvent, iStatus );
+ iState = ERunnerRunning;
+ SetActive();
+
+ }
+ else
+ {
+ // Some testmodule below has requested the event
+ // Wait unset to complete
+ SetActive();
+ __TRACE( KPrint, ( _L("Unset: Start" ) ) );
+ iState = ERunnerWaitUnset;
+ // Stop execution until unset has completed
+ }
+ return EFalse;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteLineL
+
+ Description: Executes script line
+
+ Parameters: CStifItemParser* aItem: in: script line
+ TTCKeywords::TKeywords aKeyword: in: keyword index
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteEventCtlL( CStifItemParser* aItem,
+ TTCKeywords::TKeywords aKeyword )
+ {
+ _LIT( KErrMsgEventNameNotDefined, "%S : Event name is not defined" );
+ _LIT( KErrMsgEequestEventAlreadyExist, "Request : Requested event %S already exists" );
+ _LIT( KErrMsgWaitEventNotRequested, "Wait :Waited event %S is not requested" );
+ _LIT( KErrMsgReleaseEventNotRequested, "Release : Released event %S is not requested" );
+
+ TBool continueTask = ETrue;
+ TPtrC eventName;
+ TInt ret = KErrNone;
+ TPtrC keywordStr = TTCKeywords::Keyword( aKeyword );
+ // Get event name
+ ret = aItem->GetNextString( eventName );
+ if ( ret != KErrNone )
+ {
+ iRunErrorMessage.Format( KErrMsgEventNameNotDefined, &keywordStr );
+ User::Leave( ret );
+ }
+
+ TInt count = iTestCombiner->iEventArray.Count();
+ TInt ind = 0;
+ for(; ind < count; ind++ )
+ {
+ if( eventName == iTestCombiner->iEventArray[ind]->Name() )
+ {
+ break;
+ }
+ }
+
+ switch( aKeyword )
+ {
+ case TTCKeywords::ERequest:
+ {
+ __TRACE( KMessage, (_L("Request %S"), &eventName));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec,
+ KExecute, _L("Request %S"), &eventName);
+
+ // Check that event is not already requested
+ if( ind < count )
+ {
+ __TRACE( KError, (_L("Requested event %S already exists"),
+ &eventName));
+ iRunErrorMessage.Format( KErrMsgEequestEventAlreadyExist, &eventName );
+ User::Leave( KErrAlreadyExists );
+ }
+
+ // Add event to event array
+ iEvent.SetName( eventName );
+ iEvent.SetType( TEventIf::EReqEvent );
+ TEventTc* event = new (ELeave) TEventTc( iTestCombiner->iLog );
+ CleanupStack::PushL( event );
+ event->Copy( iEvent );
+ User::LeaveIfError( iTestCombiner->iEventArray.Append( event ));
+ if( iTestCombiner->iLoopIsUsed )
+ {
+ User::LeaveIfError( iTestCombiner->iLoopAllocationArray.Append( event ) );
+ }
+ CleanupStack::Pop( event );
+
+ // Request event
+ iTestCombiner->TestModuleIf().Event( iEvent, iStatus );
+ iState = ERunnerRunning;
+ SetActive();
+ continueTask = EFalse;
+ }
+ break;
+ case TTCKeywords::EWait:
+ {
+ __TRACE( KMessage, (_L("Wait %S"), &eventName));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec, KExecute,
+ _L("Wait %S"), &eventName);
+
+ // Check that event is requested
+ if( ind == count )
+ {
+ __TRACE( KError, (_L("Waited event %S is not requested"),
+ &eventName));
+ iRunErrorMessage.Format( KErrMsgWaitEventNotRequested, &eventName );
+ User::Leave( KErrNotFound );
+ }
+ iEvent.SetName( eventName );
+ iEvent.SetType( TEventIf::EWaitEvent );
+ // Wait event
+ iTestCombiner->TestModuleIf().Event( iEvent, iStatus );
+ iState = ERunnerRunning;
+ SetActive();
+ continueTask = EFalse;
+ }
+ break;
+ case TTCKeywords::ERelease:
+ {
+ __TRACE( KMessage, (_L("Release %S"), &eventName));
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec, KExecute,
+ _L("Release %S"), &eventName);
+ // Check that event is requested
+ if( ind == count )
+ {
+ __TRACE( KError, (_L("Released event %S is not requested"),
+ &eventName));
+ iRunErrorMessage.Format( KErrMsgReleaseEventNotRequested, &eventName );
+ User::Leave( KErrNotFound );
+ }
+ // Remove event from array
+ TEventTc* event = iTestCombiner->iEventArray[ind];
+ iTestCombiner->iEventArray.Remove( ind );
+ delete event;
+ iEvent.SetName( eventName );
+ iEvent.SetType( TEventIf::ERelEvent );
+
+ // Release event
+ iTestCombiner->TestModuleIf().Event( iEvent, iStatus );
+ iState = ERunnerRunning;
+ SetActive();
+ continueTask = EFalse;
+ }
+ break;
+ default:
+ {
+ __TRACE( KError, (_L("Illegal keyword") ) );
+
+ // Unknown or illegal keyword
+ User::Leave( KErrGeneral );
+ }
+ break;
+
+ }
+ return continueTask;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteAllocateL
+
+ Description: Executes allocate line
+
+ Parameters: CStifItemParser* aItem: in: script line
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteAllocateL( CStifItemParser* aItem )
+ {
+ _LIT( KErrMsgAllocateSlaveTypeNotDefined, "Allocate : Slave type was not given for allocate" );
+ _LIT( KErrMsgAllocateSlaveNameNotDefined, "Allocate : Slave name is not defined" );
+ _LIT( KErrMsgAllocateSlaveAlreadyAllocated, "Allocate : Slave with name %S already allocated" );
+ __TRACE( KMessage, (_L("Allocate")));
+
+ TPtrC type;
+ TPtrC name;
+ // Get slave type
+ TInt ret = aItem->GetNextString( type );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, (_L("Slave type was not given for allocate")));
+ iRunErrorMessage = KErrMsgAllocateSlaveTypeNotDefined;
+ User::Leave( KErrArgument );
+ }
+
+ // Get slave name
+ ret = aItem->GetNextString( name );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, (_L("Slave name was not given for allocate")));
+ iRunErrorMessage = KErrMsgAllocateSlaveNameNotDefined;
+ User::Leave( KErrArgument );
+ }
+
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec, KExecute,
+ _L("Allocate %S"), &name );
+
+ __TRACE( KMessage, (_L("Allocate %S [name: %S]"), &type, &name));
+
+ if( iTestCombiner->GetSlave( name ) )
+ {
+ __TRACE( KError, (_L("Slave with name %S already allocated"),
+ &name ) );
+ iRunErrorMessage.Format( KErrMsgAllocateSlaveAlreadyAllocated, &name );
+ User::Leave( KErrAlreadyExists );
+ }
+
+ CSlaveInfo* slave = CSlaveInfo::NewL( name, KRemoteProtocolMasterId );
+ CleanupStack::PushL( slave );
+ User::LeaveIfError( iTestCombiner->iSlaveArray.Append( slave ) );
+ if( iTestCombiner->iLoopIsUsed )
+ {
+ User::LeaveIfError( iTestCombiner->iLoopAllocationArray.Append( slave ) );
+ }
+ CleanupStack::Pop( slave );
+
+ CStifTFwIfProt* req = CStifTFwIfProt::NewL();
+ CleanupStack::PushL( req );
+ req->CreateL();
+
+ // Reserve message
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgReserve ) );
+ // Srcid. i.e. master id
+ User::LeaveIfError(
+ req->AppendId( slave->iMasterId ) );
+ // DstId, broacast id
+ User::LeaveIfError(
+ req->AppendId( slave->iSlaveDevId ) );
+ // Slave type
+ User::LeaveIfError( req->Append( type ) );
+
+ User::LeaveIfError(
+ iTestCombiner->TestModuleIf().RemoteSend( req->Message() ) );
+
+ iState = ERunnerAllocate;
+ slave->iState = CSlaveInfo::ESlaveReserveSent;
+
+ // Start timer
+ iRemoteTimer->SetTimerActive( iTestCombiner->iRemoteTimeout );
+
+ CleanupStack::PopAndDestroy( req );
+
+ return EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteFreeL
+
+ Description: Executes free line
+
+ Parameters: CStifItemParser* aItem: in: script line
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteFreeL( CStifItemParser* aItem )
+ {
+ _LIT( KErrMsgFreeSlaveNameNotDefined, "Free : Slave name is not defined" );
+ _LIT( KErrMsgFreeSlaveNotFound, "Free : Slave %S not found" );
+ _LIT( KErrMsgFreeSlaveReserved, "Free : Slave %S in illegal state %d, cannot be released" );
+ __TRACE( KMessage, (_L("Free")));
+
+ TPtrC name;
+ // Get slave name
+ TInt ret = aItem->GetNextString( name );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, (_L("Slave name was not given for free")));
+ iRunErrorMessage = KErrMsgFreeSlaveNameNotDefined;
+ User::Leave( KErrArgument );
+ }
+
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec, KExecute,
+ _L("Free %S"), &name );
+
+ __TRACE( KMessage, (_L("Free %S"), &name ) );
+
+ CSlaveInfo* slave = iTestCombiner->GetSlave( name );
+ if( slave == NULL )
+ {
+ __TRACE( KError, (_L("Slave %S not found"), &name ));
+ iRunErrorMessage.Format( KErrMsgFreeSlaveNotFound, &name );
+ User::Leave( KErrNotFound );
+ }
+ if( slave->iState != CSlaveInfo::ESlaveReserved )
+ {
+ __TRACE( KError, (_L("Slave %S in illegal state %d, cannot be released"),
+ &name, slave->iState ));
+ iRunErrorMessage.Format( KErrMsgFreeSlaveReserved, &name, slave->iState );
+ User::Leave( KErrGeneral );
+ }
+
+ ExecuteFreeL( slave );
+
+ return EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteFreeL
+
+ Description: Executes free line
+
+ Parameters: CSlaveInfo* aSlave: in: slave info
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::ExecuteFreeL( CSlaveInfo* aSlave )
+ {
+
+ CRemoteTestCase* testCase =
+ iTestCombiner->GetRemoteRunningTestOnSlave( aSlave->iSlaveDevId );
+
+ if( testCase )
+ {
+ __TRACE( KMessage,
+ (_L("Postpone free until testcases completed")));
+ // Test cases still running on slave,
+ // Free slave after test case has completed
+ testCase->iFreeSlave = ETrue;
+ return;
+ }
+
+ CStifTFwIfProt* req = CStifTFwIfProt::NewL();
+ CleanupStack::PushL( req );
+ req->CreateL();
+
+ // Release message
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRelease ) );
+ // Srcid. i.e. master id
+ User::LeaveIfError(
+ req->AppendId( aSlave->iMasterId ) );
+ // DstId is device broadcast
+ User::LeaveIfError(
+ req->AppendId( SETID( DEVID( aSlave->iSlaveDevId ), 0 ) ) );
+
+ User::LeaveIfError(
+ iTestCombiner->TestModuleIf().RemoteSend( req->Message() ) );
+
+ iState = ERunnerFree;
+ aSlave->iState = CSlaveInfo::ESlaveReleaseSent;
+
+ // Start timer
+ iRemoteTimer->SetTimerActive( iTestCombiner->iRemoteTimeout );
+
+ CleanupStack::PopAndDestroy( req );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteRemoteL
+
+ Description: Executes remote line
+
+ Parameters: CStifItemParser* aItem: in: script line
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteRemoteL( CStifItemParser* aItem )
+ {
+ _LIT( KErrMsgRemoteSlaveNameNotDefined, "Remote : Slave name is not defined" );
+ _LIT( KErrMsgRemoteSlaveNotFound, "Remore : Slave %S not found" );
+ _LIT( KErrMsgRemoteIllegalState, "Remote : Slave %S in illegal state %d, cannot send remote call" );
+ _LIT( KErrMsgRemoteCommandNotDefined, "Slave command name was not given for remote" );
+ TPtrC name;
+ TPtrC command;
+ // Get slave name
+ TInt ret = aItem->GetNextString( name );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, (_L("Slave name was not given for remote")));
+ iRunErrorMessage = KErrMsgRemoteSlaveNameNotDefined;
+ User::Leave( KErrArgument );
+ }
+
+ __TRACE( KMessage, (_L("Remote command to %S"), &name));
+
+ CSlaveInfo* slave = iTestCombiner->GetSlave( name );
+ if( slave == NULL )
+ {
+ __TRACE( KError, (_L("Slave %S not found"), &name ));
+ iRunErrorMessage.Format( KErrMsgRemoteSlaveNotFound, &name );
+ User::Leave( KErrArgument );
+ }
+ if( slave->iState != CSlaveInfo::ESlaveReserved )
+ {
+ __TRACE( KError, (_L("Slave %S in illegal state %d, cannot send remote call"),
+ &name, slave->iState ));
+ iRunErrorMessage.Format( KErrMsgRemoteIllegalState, &name, slave->iState );
+ User::Leave( KErrNotReady );
+ }
+
+ // Get remote command name
+ ret = aItem->GetNextString( command );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, (_L("Slave command name was not given for remote")));
+ iRunErrorMessage = KErrMsgRemoteCommandNotDefined;
+ User::Leave( KErrArgument );
+ }
+
+ iTestCombiner->TestModuleIf().Printf( KPrintPriExec, KExecute,
+ _L("remote %S %S"), &name, &command );
+
+ __TRACE( KPrint, (_L("remote %S %S"), &name, &command ) );
+
+ // Parse command name
+ TInt key = TTCKeywords::Parse( command, TTCKeywords::Keyword );
+ TBool continueTask = ETrue;
+
+ switch( key )
+ {
+ // Test case starting
+ case TTCKeywords::ERun:
+ continueTask = ExecuteRemoteRunL( aItem, slave );
+ break;
+
+ // Event control cases
+ case TTCKeywords::ERequest:
+ case TTCKeywords::EWait:
+ case TTCKeywords::ERelease:
+ continueTask = ExecuteRemoteEventCtlL( aItem, slave, key );
+ break;
+
+ case TTCKeywords::ESet:
+ case TTCKeywords::EUnset:
+ continueTask = ExecuteRemoteSetUnsetEventL(aItem, slave, key);
+ break;
+ // asynchronous 'sendreceive'
+ case TTCKeywords::ESendReceive:
+ continueTask = ExecuteRemoteSendReceiveL( aItem, slave );
+ break;
+
+ default:
+ // Some unknown remote command, forward as such
+ continueTask = ExecuteRemoteUnknownL( aItem, slave, command );
+ break;
+ }
+
+ return continueTask;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteRemoteRunL
+
+ Description: Handles remote run
+
+ Parameters: CStifItemParser* aItem: in: script line
+ CSlaveInfo* aSlave: in: slave info
+ HBufC *aSetUnsetEvent: in: data needed for startInfo
+ TInt aCaseNumber: in: data needed for startInfo
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution and wait response
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteRemoteRunL( CStifItemParser* aItem,
+ CSlaveInfo* aSlave,
+ HBufC *aSetUnsetEvent,
+ TInt aCaseNumber )
+ {
+
+ CStifTFwIfProt* req = CStifTFwIfProt::NewL();
+ CleanupStack::PushL( req );
+ req->CreateL();
+
+ CStartInfo* startInfo = CStartInfo::NewL();
+ CleanupStack::PushL( startInfo );
+ //if aSetUnsetEvent is given, then get start info from this argument
+ if(aSetUnsetEvent != NULL)
+ {
+ TBuf<10> tmpModuleName;
+ tmpModuleName.Copy(_L("suevent"));
+ startInfo->SetModuleNameL(tmpModuleName);
+ startInfo->SetConfigL(*aSetUnsetEvent);
+ startInfo->iCaseNum = aCaseNumber;
+ }
+ else
+ {
+ ParseRunParamsL( aItem, *startInfo );
+}
+
+ if( iTestCombiner->GetTest( startInfo->iTestId ) )
+ {
+ /*
+ __TRACE( KError, (_L("´Slave test running already with testid %S"),
+ &startInfo->iTestId ) );
+ */
+ User::Leave( KErrAlreadyExists );
+ }
+
+ CRemoteTestCase* remote =
+ CRemoteTestCase::NewL( iTestCombiner,
+ startInfo->iTestId,
+ startInfo->iExpectedResult,
+ startInfo->iCategory );
+
+ CleanupStack::PushL( remote );
+
+ // Remote message
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote ) );
+ // Srcid. i.e. master id
+ User::LeaveIfError( req->AppendId( aSlave->iMasterId ) );
+ // DstId is device broadcast
+ User::LeaveIfError(
+ req->AppendId( SETID( DEVID( aSlave->iSlaveDevId ), 0 ) ) );
+ // Run command
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdRun ) );
+ // Run parameters
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::RunParams,
+ CStifTFwIfProt::ERunModule,
+ startInfo->iModule ) );
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::RunParams,
+ CStifTFwIfProt::ERunTestcasenum,
+ startInfo->iCaseNum ));
+ if( startInfo->iIniFile.Length() > 0 )
+ {
+ // Initialization file
+ __TRACE( KMessage, (_L("ini: %S"), &startInfo->iIniFile ));
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::RunParams,
+ CStifTFwIfProt::ERunInifile,
+ startInfo->iIniFile ) );
+ }
+ if( startInfo->iConfig.Length() > 0 )
+ {
+ // Initialization file
+ __TRACE( KMessage, (_L("config: %S"), &startInfo->iConfig ));
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::RunParams,
+ CStifTFwIfProt::ERunTestcasefile,
+ startInfo->iConfig ));
+ }
+ //Title (must be given between quotation marks in case of any spaces inside
+ if( startInfo->iTitle.Length() > 0 )
+ {
+ __TRACE(KMessage, (_L("title: %S"), &startInfo->iTitle));
+ TName tit;
+ tit.Format(_L("\"title=%S\""), &startInfo->iTitle);
+ User::LeaveIfError(req->Append(tit));
+ }
+
+ User::LeaveIfError(
+ iTestCombiner->TestModuleIf().RemoteSend( req->Message() ) );
+
+ remote->iRemoteState = CRemoteTestCase::ECaseRunSent;
+ remote->iSlaveId = aSlave->iSlaveDevId;
+ remote->StartL();
+ User::LeaveIfError( iTestCombiner->iTestCases.Append( remote ) );
+ if( iTestCombiner->iLoopIsUsed )
+ {
+ User::LeaveIfError( iTestCombiner->iLoopAllocationArray.Append( remote ) );
+ }
+ CleanupStack::Pop( remote );
+
+ CleanupStack::PopAndDestroy( startInfo );
+
+ iTestCombiner->iRunningTests++;
+
+ // Start timer
+ iRemoteTimer->SetTimerActive( iTestCombiner->iRemoteTimeout );
+
+ iState = ERunnerRemote;
+
+ CleanupStack::PopAndDestroy( req );
+
+ return EFalse;
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteRemoteTestCtlL
+
+ Description: Handles remote testcase controlling
+
+ Parameters: CStifItemParser* aItem: in: script line
+ CTestCase* aTestCase: in: test case
+ TInt aCmd: in: remote command
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution and wait response
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteRemoteTestCtlL( CStifItemParser* /* aItem */,
+ CTestCase* aTestCase,
+ TInt aCmd )
+ {
+
+ CRemoteTestCase* caseInfo = ( CRemoteTestCase* ) aTestCase;
+
+ CStifTFwIfProt* req = CStifTFwIfProt::NewL();
+ CleanupStack::PushL( req );
+ req->CreateL();
+ // Remote message
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote ) );
+ // Srcid. i.e. master id
+ //req->AppendId( ( TUint32 ) this );
+ User::LeaveIfError(
+ req->AppendId( KRemoteProtocolMasterId ));
+ // DstId, i.e.slave id
+ User::LeaveIfError(
+ req->AppendId( caseInfo->iSlaveId ));
+
+ switch( aCmd )
+ {
+ case TTCKeywords::EPause:
+ if( caseInfo->iRemoteState != CRemoteTestCase::ECaseRunning )
+ {
+ __TRACE( KError, (_L("Test case with testid %S not running"),
+ &aTestCase->TestId() ));
+ User::Leave( KErrGeneral );
+ }
+ // Pause command
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdPause ) );
+ caseInfo->iRemoteState = CRemoteTestCase::ECasePauseSent;
+ break;
+ case TTCKeywords::EResume:
+ if( caseInfo->iRemoteState != CRemoteTestCase::ECasePaused )
+ {
+ __TRACE( KError, (_L("Test case with testid %S not paused"),
+ &aTestCase->TestId() ));
+ User::Leave( KErrGeneral );
+ }
+ // Resume command
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdResume ));
+ caseInfo->iRemoteState = CRemoteTestCase::ECaseResumeSent;
+ break;
+ case TTCKeywords::ECancel:
+ if( ( caseInfo->iRemoteState != CRemoteTestCase::ECaseRunning ) &&
+ ( caseInfo->iRemoteState != CRemoteTestCase::ECasePaused ) )
+ {
+ __TRACE( KError, (_L("Test case with testid %S not running"),
+ &aTestCase->TestId() ));
+ User::Leave( KErrGeneral );
+ }
+ // Cancel command
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdCancel ));
+ caseInfo->iRemoteState = CRemoteTestCase::ECaseCancelSent;
+ break;
+ case TTCKeywords::EComplete:
+ if( caseInfo->iRemoteState == CRemoteTestCase::ECaseCompleted )
+ {
+ __TRACE( KError, (_L("Test case with testid %S already completed"),
+ &aTestCase->TestId() ));
+ CleanupStack::PopAndDestroy( req );
+ return ETrue;
+ }
+ else
+ {
+ iTestCombiner->iWaitTestCase = aTestCase->TestId();
+ CleanupStack::PopAndDestroy( req );
+ return EFalse;
+ }
+ default:
+ // Should never come here
+ User::Leave( KErrGeneral );
+ }
+
+ User::LeaveIfError(
+ iTestCombiner->TestModuleIf().RemoteSend( req->Message() ) );
+
+ // Start timer
+ iRemoteTimer->SetTimerActive( iTestCombiner->iRemoteTimeout );
+
+ iState = ERunnerRemote;
+
+ CleanupStack::PopAndDestroy( req );
+
+ return EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteRemoteEventCtlL
+
+ Description: Handles remote event controlling
+
+ Parameters: CStifItemParser* aItem: in: script line
+ CSlaveInfo* aSlave: in: slave info
+ TInt aCmd: in: remote command
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution and wait response
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteRemoteEventCtlL( CStifItemParser* aItem,
+ CSlaveInfo* aSlave,
+ TInt aCmd )
+ {
+
+ TPtrC eventName;
+ // Get event name
+ TInt ret = aItem->GetNextString( eventName );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, (_L("Event name was not given for remote")));
+ User::Leave( KErrArgument );
+ }
+
+ if( aCmd == TTCKeywords::EWait )
+ {
+ TEventTc* event = aSlave->GetEvent( eventName );
+ if( event == NULL )
+ {
+ __TRACE( KError, (_L("Waited event %S not requested"),
+ &eventName ) );
+ User::Leave( KErrNotFound );
+ }
+ iState = ERunnerRunning;
+ SetActive();
+ event->WaitEvent( iStatus );
+ // Execution continue if waited event is set or after it is set
+ return EFalse;
+ }
+
+ CStifTFwIfProt* req = CStifTFwIfProt::NewL();
+ CleanupStack::PushL( req );
+
+ req->CreateL();
+ // Remote message
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote ));
+ // Srcid. i.e. master id
+ User::LeaveIfError( req->AppendId( aSlave->iMasterId ) );
+ // DstId, i.e.slave device id
+ User::LeaveIfError( req->AppendId( aSlave->iSlaveDevId ) );
+
+ switch( aCmd )
+ {
+ // Event control cases
+ case TTCKeywords::ERequest:
+ {
+ TEventTc* event = aSlave->GetEvent( eventName );
+ if( event != NULL )
+ {
+ __TRACE( KError, (_L("Event %S already requested"),
+ &eventName ) );
+ User::Leave( KErrNotFound );
+ }
+ event = new( ELeave ) TEventTc( (TName&)eventName,
+ iTestCombiner->iLog );
+ CleanupStack::PushL( event );
+ User::LeaveIfError( aSlave->iEvents.Append( event ) );
+ CleanupStack::Pop( event );
+ // Request event
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdRequest ));
+ }
+ break;
+
+ case TTCKeywords::ERelease:
+ {
+ TEventIf* event = NULL;
+ TInt count = aSlave->iEvents.Count();
+ TInt i = 0;
+ for( ; i < count; i++ )
+ {
+ if( aSlave->iEvents[i]->Name() == eventName )
+ {
+ event = aSlave->iEvents[i];
+ break;
+ }
+ }
+ if( event == NULL )
+ {
+ __TRACE( KError, (_L("Event not found %S"),
+ &eventName ) );
+ User::Leave( KErrNotFound );
+ }
+
+ aSlave->iEvents.Remove(i);
+ delete event;
+ // Release event
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdRelease ));
+ }
+ break;
+
+ case TTCKeywords::ESet:
+ {
+ __TRACE( KPrint, (_L("JIRA51 CTestRunner::ExecuteRemoteEventCtlL case ESet")));
+ User::LeaveIfError(req->Append(CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdSetEvent));
+ break;
+ }
+ case TTCKeywords::EUnset:
+ {
+ __TRACE( KPrint, (_L("JIRA51 CTestRunner::ExecuteRemoteEventCtlL case EUnset")));
+ User::LeaveIfError(req->Append(CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdUnsetEvent));
+ break;
+ }
+ default:
+ // Should never come here
+ User::Leave( KErrGeneral );
+ }
+
+ // Event name
+ User::LeaveIfError( req->Append( eventName ) );
+
+ if(aCmd == TTCKeywords::ESet)
+ {
+ TPtrC stateEvent;
+ TInt ret = aItem->GetNextString(stateEvent);
+ if(ret == KErrNotFound) //indication event - add indicate keyword to message
+ {
+ User::LeaveIfError(req->Append(CStifTFwIfProt::EventType, TEventIf::EIndication));
+ }
+ else if(ret == KErrNone) //possibly state event
+ {
+ if(stateEvent.Compare(_L("state")) == 0) //state event - add state keyword to message
+ {
+ User::LeaveIfError(req->Append(CStifTFwIfProt::EventType, TEventIf::EState));
+ }
+ else //syntax error in the line
+ {
+ __TRACE(KError, (_L("Unknown keyword %S"), &stateEvent));
+ }
+ }
+ else //syntax error in the line
+ {
+ __TRACE(KError, (_L("Unknown keyword (2) %S"), &stateEvent));
+ }
+ }
+ User::LeaveIfError(
+ iTestCombiner->TestModuleIf().RemoteSend( req->Message() ) );
+
+ // Start timer
+ iRemoteTimer->SetTimerActive( iTestCombiner->iRemoteTimeout );
+
+ iState = ERunnerRemote;
+
+ CleanupStack::PopAndDestroy( req );
+
+ return EFalse;
+
+ }
+
+TBool CTestRunner::ExecuteRemoteSetUnsetEventL(CStifItemParser* aItem,
+ CSlaveInfo* aSlave,
+ TInt aCmd)
+ {
+ TPtrC eventName;
+ // Get event name
+ TInt ret = aItem->GetNextString(eventName);
+ if(ret != KErrNone)
+ {
+ __TRACE(KError, (_L("Event name was not given for remote")));
+ User::Leave(KErrArgument);
+ }
+ // Check if this is a state set, indication set, or unset command
+ TInt caseNumber = -1;
+ if(aCmd == TTCKeywords::ESet)
+ {
+ TPtrC stateEvent;
+ TInt ret = aItem->GetNextString(stateEvent);
+ if(ret == KErrNotFound) //indication event - add indicate keyword to message
+ {
+ caseNumber = 1;
+ }
+ else if(ret == KErrNone) //possibly state event
+ {
+ if(stateEvent.Compare(_L("state")) == 0) //state event - add state keyword to message
+ {
+ caseNumber = 0;
+ }
+ else //syntax error in the line
+ {
+ __TRACE(KError, (_L("Unknown keyword %S"), &stateEvent));
+ }
+ }
+ else //syntax error in the line
+ {
+ }
+ }
+ else //TTCKeyword::EUnset
+ {
+ caseNumber = 2;
+ }
+
+ if(caseNumber == -1)
+ {
+ __TRACE(KError, _L("Should never occur"));
+ }
+ // Build new descriptor with command to run hardcoded suevent test case on remote phone
+ HBufC* cmd = HBufC::NewL(100);
+ CleanupStack::PushL(cmd);
+ TPtr cmdPtr(cmd->Des());
+ cmdPtr.Copy(eventName);
+ // Run remotely test case
+RDebug::Print(_L("CTestRunner::ExecuteRemoteSetUnsetEventL calling ExecuteRemoteRun"));
+ TBool retval = ExecuteRemoteRunL(aItem, aSlave, cmd, caseNumber);
+ // Clean data
+ CleanupStack::PopAndDestroy(cmd);
+RDebug::Print(_L("CTestRunner::ExecuteRemoteSetUnsetEventL end"));
+ return retval;
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteRemoteSendReceiveL
+
+ Description: Handles asynchronous remote sendreceive controlling
+
+ Parameters: CStifItemParser* aItem: in: script line
+ CSlaveInfo* aSlave: in: slave info
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution and wait response
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteRemoteSendReceiveL( CStifItemParser* aItem,
+ CSlaveInfo* aSlave )
+ {
+ CStifTFwIfProt* req = CStifTFwIfProt::NewL();
+ CleanupStack::PushL( req );
+
+ // Create CRemoteSendReceive object for taking sendreceive information to
+ // save for later use.
+ CRemoteSendReceive* remoteSendReceive =
+ CRemoteSendReceive::NewL( iTestCombiner );
+
+ CleanupStack::PushL( remoteSendReceive );
+
+ req->CreateL();
+ // Remote message
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote ) );
+ // Srcid. i.e. master id
+ User::LeaveIfError( req->AppendId( aSlave->iMasterId ) );
+ // DstId, i.e.slave device id
+ User::LeaveIfError( req->AppendId( aSlave->iSlaveDevId ) );
+ // Run command
+ User::LeaveIfError( req->Append(
+ CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdSendReceive ) );
+ // asynchronous sendreceive's parameters
+ TPtrC tmp;
+
+ while( aItem->GetNextString( tmp ) == KErrNone )
+ {
+ // Append parameters
+ User::LeaveIfError( req->Append( tmp ) );
+ }
+
+ User::LeaveIfError(
+ iTestCombiner->TestModuleIf().RemoteSend( req->Message() ) );
+
+ remoteSendReceive->iRemoteState = CRemoteSendReceive::ECaseSend;
+ remoteSendReceive->iSlaveId = aSlave->iSlaveDevId;
+
+ // Take CRemoteSendReceive object to save in array. This can be used in
+ // TestCombiner when handling responses.
+ User::LeaveIfError(
+ iTestCombiner->iSendReceive.Append( remoteSendReceive ) );
+ if( iTestCombiner->iLoopIsUsed )
+ {
+ User::LeaveIfError(
+ iTestCombiner->iLoopAllocationArray.Append( remoteSendReceive ) );
+ }
+ CleanupStack::Pop( remoteSendReceive );
+
+ // Start timer
+ iRemoteTimer->SetTimerActive( iTestCombiner->iRemoteTimeout );
+
+ iState = ERunnerRemote;
+
+ CleanupStack::PopAndDestroy( req );
+
+ // Return EFalse=>start waiting response...
+ return EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteRemoteUnknownL
+
+ Description: Forwards messages as such
+
+ Parameters: CStifItemParser* aItem: in: script line
+ CSlaveInfo* aSlave: in: slave info
+ TInt aCmd: in: remote command
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution and wait response
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteRemoteUnknownL( CStifItemParser* aItem,
+ CSlaveInfo* aSlave,
+ TDesC& aCommand )
+ {
+
+ CStifTFwIfProt* req = CStifTFwIfProt::NewL();
+ CleanupStack::PushL( req );
+
+ req->CreateL();
+ // Remote message
+ User::LeaveIfError(
+ req->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote ) );
+ // Srcid. i.e. master id
+ User::LeaveIfError( req->AppendId( aSlave->iMasterId ) );
+ // DstId, i.e.slave device id
+ User::LeaveIfError( req->AppendId( aSlave->iSlaveDevId ) );
+
+ // Append command name
+ User::LeaveIfError( req->Append( aCommand ) );
+
+ TPtrC tmp;
+ while( aItem->GetNextString( tmp ) == KErrNone )
+ {
+ // Append parameters
+ User::LeaveIfError( req->Append( tmp ) );
+ }
+
+ User::LeaveIfError(
+ iTestCombiner->TestModuleIf().RemoteSend( req->Message() ) );
+
+ // Start timer
+ iRemoteTimer->SetTimerActive( iTestCombiner->iRemoteTimeout );
+
+ iState = ERunnerRemote;
+
+ CleanupStack::PopAndDestroy( req );
+
+ return EFalse;
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ReceiveResponseL
+
+ Description: Handles responce received from slave
+
+ Parameters: TDesC& aMsg: in: message
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ReceiveResponseL( TDesC& aMsg )
+ {
+ __TRACE( KMessage, (_L("ReceiveResponse")));
+
+ iRemoteTimer->Cancel();
+
+ CStifTFwIfProt* msg = CStifTFwIfProt::NewL();
+ CleanupStack::PushL( msg );
+ TRAPD( err, msg->SetL( aMsg ); );
+ if( err != KErrNone )
+ {
+ __TRACE( KError, (_L("Response parsing failed")));
+ User::Leave( err );
+ }
+
+ // Check protocol identifiers
+ if( ( msg->SrcDevId() == 0 ) ||
+ ( msg->DstDevId() == 0 ) ||
+ ( msg->DstTestId() == 0 ) )
+ {
+ __TRACE( KError, (_L("Illegal deviceid received")));
+ User::Leave( KErrGeneral );
+ }
+
+ // This is master, cannot receive anything else but responses
+ if( msg->iMsgType != CStifTFwIfProt::EMsgResponse )
+ {
+ __TRACE( KError, (_L("Illegal message received %d"),
+ msg->iMsgType ));
+ User::Leave( KErrGeneral );
+ }
+
+ TBool continueTask = ETrue;
+ switch( msg->iRespType )
+ {
+ case CStifTFwIfProt::EMsgReserve:
+ {
+ __TRACE( KMessage, (_L("ReceiveResponse Reserve")));
+ if( iState != ERunnerAllocate )
+ {
+ __TRACE( KError, (_L("Response reserve received in illegal state %d"),
+ iState ));
+ User::Leave( KErrGeneral );
+ }
+ // Check protocol Src test id
+ if( msg->SrcTestId() != 0 )
+ {
+ __TRACE( KError, (_L("Illegal deviceid received")));
+ User::Leave( KErrGeneral );
+ }
+ if( msg->iResult != KErrNone )
+ {
+ __TRACE( KError, (_L("Response with error %d"), msg->iResult ));
+ User::Leave( msg->iResult );
+ }
+ CSlaveInfo* slave = NULL;
+ TInt count = iTestCombiner->iSlaveArray.Count();
+ for( TInt index = 0; index < count; index++ )
+ {
+ slave = iTestCombiner->iSlaveArray[index];
+ if( ( slave->iSlaveDevId == 0 ) &&
+ ( slave->iState == CSlaveInfo::ESlaveReserveSent ) )
+ {
+ break;
+ }
+ slave = NULL;
+ }
+ if( slave == NULL )
+ {
+ User::Leave( KErrNotFound );
+ }
+ slave->iSlaveDevId = msg->SrcId();
+ slave->iState = CSlaveInfo::ESlaveReserved;
+ __TRACE( KMessage, (_L("Slave allocated succesfully, continue execution")));
+ }
+ break;
+ case CStifTFwIfProt::EMsgRelease:
+ {
+ __TRACE( KMessage, (_L("ReceiveResponse Release")));
+ if( iState != ERunnerFree )
+ {
+ __TRACE( KError, (_L("Response release received in illegal state %d"),
+ iState ));
+ User::Leave( KErrGeneral );
+ }
+ // Check protocol Src test id
+ if( msg->SrcTestId() != 0 )
+ {
+ __TRACE( KError, (_L("Illegal deviceid received")));
+ User::Leave( KErrGeneral );
+ }
+ if( msg->iResult != KErrNone )
+ {
+ __TRACE( KError, (_L("Response with error %d"), msg->iResult ));
+ User::Leave( msg->iResult );
+ }
+
+ CSlaveInfo* slave = iTestCombiner->GetSlave( msg->SrcId() );
+ if( slave == NULL )
+ {
+ User::Leave( KErrNotFound );
+ }
+ slave->iState = CSlaveInfo::ESlaveReleased;
+ __TRACE( KMessage, (_L("Slave freed succesfully, continue execution")));
+ }
+ break;
+ case CStifTFwIfProt::EMsgRemote:
+ {
+ __TRACE( KMessage, (_L("ReceiveResponse Remote")));
+ switch( msg->iCmdType )
+ {
+ case CStifTFwIfProt::ECmdRun:
+ continueTask = ReceiveResponseRunL( *msg );
+ break;
+ case CStifTFwIfProt::ECmdPause:
+ case CStifTFwIfProt::ECmdResume:
+ case CStifTFwIfProt::ECmdCancel:
+ continueTask = ReceiveResponseTestCtlL( *msg );
+ break;
+ case CStifTFwIfProt::ECmdRequest:
+ case CStifTFwIfProt::ECmdRelease:
+ case CStifTFwIfProt::ECmdSetEvent:
+ case CStifTFwIfProt::ECmdUnsetEvent:
+ continueTask = ReceiveResponseEventCtlL( *msg );
+ break;
+ case CStifTFwIfProt::ECmdSendReceive:
+ continueTask = ReceiveResponseSendReceiveL( *msg );
+ break;
+ default:
+ continueTask = ReceiveResponseUnknownL( *msg );
+ break;
+ }
+ }
+ break;
+ default:
+ User::Leave( KErrGeneral );
+ }
+
+
+ CleanupStack::PopAndDestroy( msg );
+ return continueTask;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ReceiveResponseRunL
+
+ Description: Handles response for run received from slave
+
+ Parameters: CStifTFwIfProt& aMsg: in: protocol message parser
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ReceiveResponseRunL( CStifTFwIfProt& aMsg )
+ {
+
+ TPtrC tmp = CStifTFwIfProt::RunStatus(aMsg.iRunStatus);
+ __TRACE( KMessage, (_L("ReceiveResponse Remote Run %S"), &tmp ));
+
+ TBool continueTask = ETrue;
+ switch( aMsg.iRunStatus )
+ {
+ case CStifTFwIfProt::ERunStarted:
+ {
+ // Locate testcase
+ CRemoteTestCase* tcase =
+ iTestCombiner->GetRemoteTestRunSent( GETDEVID( aMsg.SrcId() ) );
+ if( tcase == NULL )
+ {
+ __TRACE( KError, (_L("Testcase not found")));
+ User::Leave( KErrNotFound );
+ }
+ tcase->iSlaveId = aMsg.SrcId();
+
+ tcase->iRemoteState = CRemoteTestCase::ECaseRunning;
+ }
+ break;
+ case CStifTFwIfProt::ERunError:
+ case CStifTFwIfProt::ERunReady:
+ {
+ // Locate testcase
+ CRemoteTestCase* tcase =
+ iTestCombiner->GetRunningRemoteTest( aMsg.SrcId() );
+ if( tcase == NULL )
+ {
+ __TRACE( KError, (_L("Testcase not found")));
+ User::Leave( KErrNotFound );
+ }
+
+ switch( aMsg.iResultCategory )
+ {
+ case CStifTFwIfProt::EResultNormal:
+ tcase->iResult.iCaseExecutionResultType =
+ TFullTestResult::ECaseExecuted;
+ tcase->iResult.iTestResult.iResult = aMsg.iResult;
+ tcase->iResult.iCaseExecutionResultCode = 0;
+ break;
+ case CStifTFwIfProt::EResultPanic:
+ tcase->iResult.iCaseExecutionResultType =
+ TFullTestResult::ECasePanic;
+ tcase->iResult.iTestResult.iResult = KErrGeneral;
+ tcase->iResult.iCaseExecutionResultCode = aMsg.iResult;
+ break;
+ case CStifTFwIfProt::EResultException:
+ tcase->iResult.iCaseExecutionResultType =
+ TFullTestResult::ECaseException;
+ tcase->iResult.iTestResult.iResult = KErrGeneral;
+ tcase->iResult.iCaseExecutionResultCode = aMsg.iResult;
+ break;
+ case CStifTFwIfProt::EResultTimeout:
+ tcase->iResult.iCaseExecutionResultType =
+ TFullTestResult::ECaseTimeout;
+ tcase->iResult.iTestResult.iResult = KErrGeneral;
+ tcase->iResult.iCaseExecutionResultCode = aMsg.iResult;
+ break;
+ case CStifTFwIfProt::EResultLeave:
+ tcase->iResult.iCaseExecutionResultType =
+ TFullTestResult::ECaseLeave;
+ tcase->iResult.iTestResult.iResult = KErrGeneral;
+ tcase->iResult.iCaseExecutionResultCode = aMsg.iResult;
+ break;
+ default:
+ User::Leave( KErrGeneral );
+ }
+
+ if( ( tcase->iRemoteState == CRemoteTestCase::ECaseCancelled ) ||
+ ( tcase->iRemoteState == CRemoteTestCase::ECaseRunSent ) )
+ {
+ // Complete for cancelled testcase or error for run request,
+ // set runner active again
+ continueTask = ETrue;
+ }
+ else
+ {
+ // Continued from Complete in state ECaseRunning
+ continueTask = EFalse;
+ }
+
+ tcase->iRemoteState = CRemoteTestCase::ECaseCompleted;
+
+ __TRACE( KMessage, (_L("ReceiveResponse Remote Run rq comp")));
+
+ TRequestStatus* rs = &tcase->iStatus;
+ // Complete testcase
+ User::RequestComplete( rs, KErrNone );
+
+ }
+ break;
+ default:
+ // Should never come here
+ User::Leave( KErrGeneral );
+ }
+
+ return continueTask;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ReceiveResponseTestCtlL
+
+ Description: Handles responses for test control commands
+ received from slave
+
+ Parameters: CStifTFwIfProt& aMsg: in: protocol message parser
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ReceiveResponseTestCtlL( CStifTFwIfProt& aMsg )
+ {
+
+ if( aMsg.iResult != KErrNone )
+ {
+ __TRACE( KError, (_L("Response with error %d"), aMsg.iResult ));
+ User::Leave( aMsg.iResult );
+ }
+
+ // Locate testcase
+ CRemoteTestCase* tcase = iTestCombiner->GetRemoteTest( aMsg.SrcId() );
+ if( tcase == NULL )
+ {
+ __TRACE( KError, (_L("Testcase not found")));
+ User::Leave( KErrNotFound );
+ }
+
+ TBool continueTask = ETrue;
+
+ switch( aMsg.iCmdType )
+ {
+ case CStifTFwIfProt::ECmdPause:
+ __TRACE( KMessage, (_L("ReceiveResponse Remote Pause")));
+
+ if( tcase->iRemoteState != CRemoteTestCase::ECasePauseSent )
+ {
+ __TRACE( KError, (_L("Pause response received in illegal state")));
+ User::Leave( KErrGeneral );
+ }
+ tcase->iRemoteState = CRemoteTestCase::ECasePaused;
+
+ // Start pause timer if timeout was given
+ if( ( iPausedTestCase.Length() > 0 ) &&
+ ( iPauseTime != 0 ) )
+ {
+ continueTask = EFalse;
+ iState = ERunnerWaitTimeout;
+ iPauseTimer.After( iStatus, iPauseTime*1000 );
+ SetActive();
+ }
+ break;
+ case CStifTFwIfProt::ECmdResume:
+ __TRACE( KMessage, (_L("ReceiveResponse Remote Resume")));
+
+ if( tcase->iRemoteState != CRemoteTestCase::ECaseResumeSent )
+ {
+ __TRACE( KError, (_L("Resume response received in illegal state")));
+ User::Leave( KErrGeneral );
+ }
+ tcase->iRemoteState = CRemoteTestCase::ECaseRunning;
+ break;
+ case CStifTFwIfProt::ECmdCancel:
+ __TRACE( KMessage, (_L("ReceiveResponse Remote Cancel")));
+
+ if( tcase->iRemoteState != CRemoteTestCase::ECaseCancelSent )
+ {
+ __TRACE( KError, (_L("Cancel response received in illegal state")));
+ User::Leave( KErrGeneral );
+ }
+ tcase->iRemoteState = CRemoteTestCase::ECaseCancelled;
+ // Need to wait Run response with KErrCancel
+ continueTask = EFalse;
+ // Start timer
+ iRemoteTimer->SetTimerActive( iTestCombiner->iRemoteTimeout );
+ break;
+ default:
+ // Should never come here
+ User::Leave( KErrGeneral );
+ }
+
+ return continueTask;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ReceiveResponseEventCtlL
+
+ Description: Handles responses for event system control commands
+ received from slave
+
+ Parameters: CStifTFwIfProt& aMsg: in: protocol message parser
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ReceiveResponseEventCtlL( CStifTFwIfProt& aMsg )
+ {
+
+ CSlaveInfo* slave = iTestCombiner->GetSlave( aMsg.SrcId() );
+ if( slave == NULL )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ TBool continueTask = ETrue;
+ switch( aMsg.iCmdType )
+ {
+ case CStifTFwIfProt::ECmdRequest:
+ {
+ __TRACE( KMessage, (_L("ReceiveResponse Request")));
+
+ TEventTc* event = slave->GetEvent( aMsg.iEventName );
+ if( event == NULL )
+ {
+ User::Leave( KErrNotFound );
+ }
+ switch( aMsg.iEventStatus )
+ {
+ case CStifTFwIfProt::EEventActive:
+ __TRACE( KMessage, (_L("Event %S active"), &aMsg.iEventName ));
+ break;
+ case CStifTFwIfProt::EEventSet:
+ __TRACE( KMessage, (_L("Event %S set"), &aMsg.iEventName ));
+ // Set event
+ event->SetEvent( aMsg.iEventType );
+ continueTask = EFalse;
+ break;
+ case CStifTFwIfProt::EEventError:
+ __TRACE( KMessage, (_L("Event %S error %d"),
+ &aMsg.iEventName, aMsg.iResult ));
+ User::Leave( aMsg.iResult );
+ default:
+ User::Leave( KErrGeneral );
+ }
+ }
+ break;
+ case CStifTFwIfProt::ECmdRelease:
+ __TRACE( KMessage, (_L("ReceiveResponse Release")));
+ if( aMsg.iResult != KErrNone )
+ {
+ __TRACE( KError, (_L("Response with error %d"), aMsg.iResult ));
+ User::Leave( aMsg.iResult );
+ }
+
+ // Everything ok, no need to do anything
+ break;
+ case CStifTFwIfProt::ECmdSetEvent:
+ __TRACE( KMessage, (_L("ReceiveResponse SetEvent")));
+ if( aMsg.iResult != KErrNone )
+ {
+ __TRACE( KError, (_L("Response with error %d"), aMsg.iResult ));
+ User::Leave( aMsg.iResult );
+ }
+
+ // Everything ok, no need to do anything
+ break;
+ case CStifTFwIfProt::ECmdUnsetEvent:
+ __TRACE( KMessage, (_L("ReceiveResponse Unset")));
+ if( aMsg.iResult != KErrNone )
+ {
+ __TRACE( KError, (_L("Response with error %d"), aMsg.iResult ));
+ User::Leave( aMsg.iResult );
+ }
+ // Everything ok, no need to do anything
+ break;
+ default:
+ // Should never come here
+ User::Leave( KErrGeneral );
+ }
+
+ return continueTask;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ReceiveResponseSendReceiveL
+
+ Description: Handles responses for asynchronous sendreceive commands
+ received from slave
+
+ Parameters: CStifTFwIfProt& aMsg: in: protocol message parser
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ReceiveResponseSendReceiveL( CStifTFwIfProt& aMsg )
+ {
+
+ TPtrC tmp = CStifTFwIfProt::RunStatus(aMsg.iRunStatus);
+ __TRACE( KMessage, (
+ _L("ReceiveResponseSendReceiveL asynchronous Remote SendReceive %S"),
+ &tmp ) );
+
+ TBool continueTask = EFalse;
+ switch( aMsg.iRunStatus )
+ {
+ case CStifTFwIfProt::ERunStarted:
+ {
+ // Locate CRemoteSendReceive object
+ CRemoteSendReceive* sendreceive =
+ iTestCombiner->GetRemoteSendReceive( GETDEVID(
+ aMsg.SrcId() ) );
+ if( sendreceive == NULL )
+ {
+ __TRACE( KError, (_L("CRemoteSendReceive object not found")));
+ User::Leave( KErrNotFound );
+ }
+ sendreceive->iRemoteState = CRemoteSendReceive::ECaseSend;
+
+ // continueTask is EFalse=>stop script file execution
+ break;
+ }
+ case CStifTFwIfProt::ERunError:
+ case CStifTFwIfProt::ERunReady:
+ {
+ if( aMsg.iResult != KErrNone )
+ {
+ __TRACE( KError, (_L("sendreceive response with error %d"), aMsg.iResult ));
+ User::Leave( aMsg.iResult );
+ }
+
+ // Locate CRemoteSendReceive object
+ CRemoteSendReceive* sendreceive =
+ iTestCombiner->GetRemoteSendReceive( aMsg.SrcId() );
+ if( sendreceive == NULL )
+ {
+ __TRACE( KError, (_L("CRemoteSendReceive object not found")));
+ User::Leave( KErrNotFound );
+ }
+
+ // continueTask is ETrue=>continue script file execution
+ continueTask = ETrue;
+
+ sendreceive->iRemoteState = CRemoteSendReceive::ECaseCompleted;
+
+ __TRACE( KMessage, (
+ _L( "ReceiveResponseSendReceiveL asynchronous Remote SendReceive rq comp" ) ) );
+ break;
+ }
+ default:
+ {
+ // Should never come here
+ User::Leave( KErrGeneral );
+ }
+ }
+ return continueTask;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ReceiveResponseUnknownL
+
+ Description: Handles responses for unspecified commands
+
+ Parameters: CStifTFwIfProt& aMsg: in: protocol message parser
+
+ Return Values: ETrue: continue script file execution
+ EFalse: stop script file execution
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ReceiveResponseUnknownL( CStifTFwIfProt& aMsg )
+ {
+
+ CSlaveInfo* slave = iTestCombiner->GetSlave( aMsg.SrcId() );
+ if( slave == NULL )
+ {
+ User::Leave( KErrNotFound );
+ }
+ if( aMsg.iResult != KErrNone )
+ {
+ __TRACE( KError, (_L("Response with error %d"), aMsg.iResult ));
+ User::Leave( aMsg.iResult );
+ }
+
+ return ETrue;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ParseOptArgL
+
+ Description: Parses optional argument
+
+ Parameters: const TDesC& aOptArg: in:
+ argument-value pair (format arg=value)
+ TPtrC& aArg: out: parsed argument
+ TPtrC& aVal: out: parsed value
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if parsing fails.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::ParseOptArgL( const TDesC& aOptArg, TPtrC& aArg, TPtrC& aVal)
+ {
+ _LIT( KErrMsgUnknownOrIllegalKeyword, "Unknown or illegal argument %S" );
+ _LIT( KErrMsgValueNotDefined, "Value of optional argument %S is not defined" );
+ TInt length = aOptArg.Length();
+ for( TInt i=0; i < length; i++)
+ {
+ // find the '=' sign
+ if( aOptArg[i] == '=' )
+ {
+ if( i+1 >= length )
+ {
+ __TRACE( KError,
+ (_L("Illegal optional argument(%S), no value"),
+ &aOptArg ));
+ TPtrC tmp = aOptArg.Left( i );
+ iRunErrorMessage.Format( KErrMsgValueNotDefined, &tmp );
+ User::Leave( KErrArgument );
+ }
+ aArg.Set( aOptArg.Left( i ) );
+ aVal.Set( aOptArg.Mid( i+1 ) );
+ __TRACE( KMessage, ( _L( "arg '%S', val '%S'" ),
+ &aArg, &aVal ));
+ return;
+ }
+ }
+ __TRACE( KError, (_L("Illegal optional argument(%S)"), &aOptArg ));
+ iRunErrorMessage.Format( KErrMsgUnknownOrIllegalKeyword, &aOptArg );
+ User::Leave( KErrArgument );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: CancelTestCases
+
+ Description: Cancels all running testcases
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::CancelTestCases()
+ {
+ __TRACEFUNC();
+
+ TInt count = iTestCombiner->iTestCases.Count();
+ for( TInt i=0; i < count; i++ )
+ {
+ if( iTestCombiner->iTestCases[i]->State() ==
+ CTCTestCase::ETestCaseRunning )
+ {
+ iTestCombiner->iTestCases[i]->Cancel();
+ }
+ }
+
+ if( ( iTestCombiner->iRunningTests == 0 ) &&
+ iTestCombiner->iSchedulerActive )
+ {
+ // Stop execution
+ CActiveScheduler::Current()->Stop();
+ iTestCombiner->iSchedulerActive = EFalse;
+ return;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: SetRunnerActive
+
+ Description: Set CTestRunner active and complete.
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::SetRunnerActive()
+ {
+ __TRACEFUNC();
+
+ if( IsActive() )
+ {
+ __TRACE( KError, ( _L("Runner already active %d"), iState ));
+ User::Panic( KTestRunner, KErrInUse );
+ }
+
+ // Update state
+ iState = ERunnerRunning;
+
+ iStatus = KRequestPending;
+ TRequestStatus* rs = &iStatus;
+ SetActive();
+ User::RequestComplete( rs, KErrNone );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: CheckUnsetEvent
+
+ Description: Check unset event.
+
+ Parameters: None
+
+ Return Values: ETrue: Unset event completed
+ EFalse: No unset event pending
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::CheckUnsetEvent()
+ {
+ if( iEvent.Name().Length() == 0 )
+ {
+ return EFalse;
+ }
+
+ __TRACE( KMessage, (_L("Unset event completed") ));
+ // Check if some testmodule below has still event request pending
+ if( iTestCombiner->UnsetEvent( iEvent, iStatus ) == EFalse )
+ {
+ // No event request pending
+ // then check other testmodules (may block)
+ TInt res = iTestCombiner->TestModuleIf().Event( iEvent );
+ if( res != KErrNone )
+ {
+ iTestCombiner->iResult = res;
+ }
+
+ __TRACE( KPrint, (_L("Unset: Complete") ) );
+ iEvent.SetName( _L("") );
+ // Proceed testcase section execution
+ SetRunnerActive();
+ }
+ else
+ {
+ iState = ERunnerWaitUnset;
+ // Wait for unset to complete
+ SetActive();
+ }
+
+ return ETrue;
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteLoopL
+
+ Description: Handle the loop keyword operations.
+
+ Parameters: CStifItemParser* aItem: in: Pointer to parsed item object.
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestRunner::ExecuteLoopL( CStifItemParser* aItem )
+ {
+ _LIT( KErrMsgLoopNestedLoop, "Loop: Nested loops are not supported " );
+ _LIT( KErrMsgLoopInvalidLoopCountParam, "Loop: No loop count value given for loop or value has invalid format" );
+ _LIT( KErrMsgLoopUnknownUnexpectedOption, "Loop: Unknown or unexpected loop option");
+ _LIT( KErrMsgLoopPasslimitInvalidValue, "Loop: No passlimit value given for loop or value has invalid format" );
+ _LIT( KErrMsgLoopPasslimitNotInRange, "Loop: Passlimit value is lower than 0 or higher than loop count" );
+ __TRACEFUNC();
+
+ if( iLoopTimes != 0 )
+ {
+ __TRACE( KError, (_L("ExecuteLoopL: Nested loop are not supported")));
+ iRunErrorMessage = KErrMsgLoopNestedLoop;
+ User::Leave( KErrNotSupported );
+ }
+
+ iLoopTimes = 0;
+ iLoopCounter = 0;
+ iPasslimitEnabled = EFalse;
+ iTimedLoop = EFalse;
+
+ if( aItem->GetNextInt( iLoopTimes ) != KErrNone )
+ {
+ __TRACE( KError, (_L("ExecuteLoopL: No loop count value given for loop")));
+ iRunErrorMessage = KErrMsgLoopInvalidLoopCountParam;
+ User::Leave( KErrArgument );
+ }
+ __TRACE( KMessage, (_L("ExecuteLoopL: Loop for %d times" ), iLoopTimes ) );
+
+ //Check loop options
+ TPtrC option;
+ TInt ret = aItem->GetNextString(option);
+ if(ret == KErrNone)
+ {
+ if(option.Compare(_L("msec")) == 0) //time loop option
+ {
+ iTimedLoop = ETrue;
+ iStartTime.HomeTime();
+ iExpectedLoopTime = TInt64(iLoopTimes) * TInt64(1000); //convert to micro seconds
+ __TRACE(KMessage, (_L("ExecuteLoopL: Timed loop for %d msec" ), iLoopTimes));
+
+ ret = aItem->GetNextString(option); //Get next option
+ }
+ }
+
+ if(ret == KErrNone)
+ {
+ if(option.Compare(_L("passlimit")) == 0) //passlimit option
+ {
+ iPasslimit = 0;
+ if( aItem->GetNextInt( iPasslimit ) != KErrNone )
+ {
+ __TRACE( KError, ( _L( "ExecuteLoopL: No passlimit value given for loop." ) ) );
+ iRunErrorMessage = KErrMsgLoopPasslimitInvalidValue;
+ User::Leave( KErrArgument );
+ }
+ __TRACE( KMessage, ( _L( "ExecuteLoopL: Passlimit set on %d" ), iPasslimit ) );
+ //Check if passlimit has valid value
+ if(iPasslimit < 0 || (iPasslimit > iLoopTimes && !iTimedLoop))
+ {
+ __TRACE( KError, ( _L( "ExecuteLoopL: Passlimit value is lower than 0 or higher than loop count." ) ) );
+ iRunErrorMessage = KErrMsgLoopPasslimitNotInRange;
+ User::Leave( KErrArgument );
+ }
+ iPasslimitEnabled = ETrue;
+
+ ret = aItem->GetNextString(option); //Get next option
+ }
+ }
+
+ if(ret == KErrNone)
+ {
+ __TRACE( KError, ( _L( "ExecuteLoopL: Unknown or unexpected loop option [%S]" ), &option ) );
+ iRunErrorMessage = KErrMsgLoopUnknownUnexpectedOption;
+ User::Leave( KErrNotSupported );
+ }
+
+ iPassedIterationCnt = 0;
+
+ iLoopStartPos = iTestCombiner->iSectionParser->GetPosition();
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestRunner
+
+ Method: ExecuteEndLoopL
+
+ Description: Handle the endloop keyword operations.
+
+ Parameters: None.
+
+ Return Values: TBool: Boolean value for indicate can testing continue.
+
+ Errors/Exceptions: None.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestRunner::ExecuteEndLoopL()
+ {
+ __TRACEFUNC();
+
+ // Fail test case if there was no loop started
+ if(iTestCombiner->iLoopIsUsed == EFalse)
+ {
+ __TRACE(KError, (_L("Encountered \'endloop\' without \'loop\'. Aborting test case.")));
+ iTestCombiner->iResult = KErrGeneral;
+ iState = ERunnerError;
+ CancelTestCases();
+ return ETrue; // Test case file parsing can be continue
+ }
+
+ TBool iterationFailed = EFalse; //Has last iteration failed (at least one of test cases has failed)
+
+ // First we check is all test cases that is set to run inside the loop
+ // completed. If not completed we wait until test case completes.
+ // Is some loop executions fails that is not allowed then loop execution
+ // will be stopped and error result is given to TestCombiner
+
+ for( TInt s = 0; s < iTestCombiner->iTestCases.Count(); s++ )
+ {
+ CTestCase* testCase = (CTestCase*)iTestCombiner->iTestCases[s];
+ if( testCase == NULL )
+ {
+ __TRACE( KError, (_L("ExecuteEndLoopL: CTestCase object not found") ) );
+ return ETrue;
+ }
+ // Check that testCase object is allocated inside the loop
+ TBool isLoopTestCase( EFalse );
+ for( TInt p = 0; p < iTestCombiner->iLoopAllocationArray.Count(); p++ )
+ {
+ if( iTestCombiner->iLoopAllocationArray[p] == testCase )
+ {
+ isLoopTestCase = ETrue;
+ break;
+ }
+ }
+ // testCase object is allocated inside loop
+ if( isLoopTestCase )
+ {
+ // Test case is completed
+ //if( testCase->State() == CTCTestCase::ETestCaseCompleted )
+ if(testCase->IsCompletelyFinished())
+ {
+ // Check normal test result
+ if( testCase->iExpectedResultCategory == TFullTestResult:: ECaseExecuted )
+ {
+ // Normal completion, check result
+ if( testCase->iResult.iTestResult.iResult != testCase->iExpectedResult )
+ {
+ __TRACE( KPrint, ( _L( "Test failed, expect(%d) != result(%d)"),
+ testCase->iExpectedResult,
+ testCase->iResult.iTestResult.iResult ));
+ //If no passlimit is provided behave in old way
+ if( !iPasslimitEnabled )
+ {
+ // We return the first error result as aResult
+ if( testCase->iResult.iTestResult.iResult != KErrNone )
+ {
+ iTestCombiner->iScriptFailed = testCase->iResult.iCaseExecutionResultCode;
+ iTestCombiner->iScriptFailedDescription.Copy(testCase->iResult.iTestResult.iResultDes);
+ }
+ else
+ {
+ iTestCombiner->iScriptFailed = testCase->iResult.iCaseExecutionResultCode;
+ iTestCombiner->iScriptFailedDescription.Copy(_L("Test case has not finished with expected result (in loop)."));
+ }
+
+ iState = ERunnerError;
+ CancelTestCases();
+ return ETrue; // Test case file parsing can be continue
+ }
+ else
+ {
+ // Set flag that one of test cases has failed, so whole iteration is failed
+ iterationFailed = ETrue;
+ }
+ }
+ }
+ // Abnormal completion, i.e. panic, leave, exception or timeout
+ else
+ {
+ if( testCase->iResult.iCaseExecutionResultCode != testCase->iExpectedResult )
+ {
+ __TRACE( KPrint, ( _L( "Test failed, expect errorcode(%d) != result(%d)"),
+ testCase->iExpectedResult,
+ testCase->iResult.iCaseExecutionResultCode ) );
+ //If no passlimit is provided behave in old way
+ if( !iPasslimitEnabled )
+ {
+ // We return the first error result as aResult
+ iTestCombiner->iScriptFailed = testCase->iResult.iCaseExecutionResultCode;
+ iTestCombiner->iScriptFailedDescription.Copy(_L("Test case has not finished with expected execution error (in loop)."));
+
+ iState = ERunnerError;
+ // Return error from here
+ CancelTestCases();
+ return ETrue; // Test case file parsing can be continue
+ }
+ else
+ {
+ // Set flag that one of test cases has failed, so whole iteration is failed
+ iterationFailed = ETrue;
+ }
+ }
+
+ // Requested testcase is completed already,
+ // proceed testcase execution
+ __TRACE( KMessage, (_L("Already completed")));
+ }
+ } // End "Test case is completed"
+ // Test case is running state, set to wait the test case complete
+ else if( testCase->State() == CTCTestCase::ETestCaseRunning )
+ {
+ // Wait testcase to complete. If no id there should generate
+ // id that test case complete will be handled correctly
+ if( testCase->TestId().Length() == 0 )
+ {
+ TPtrC generatedTestId( _L( "stif" ) );
+ delete testCase->iTestId;
+ testCase->iTestId = generatedTestId.Alloc();
+ }
+ iTestCombiner->iWaitTestCase.Copy( testCase->TestId() );
+ // Stop testcase execution until testcase completed
+ iState = ERunnerWaitTestCase;
+ // Go to beginning of the endloop
+ User::LeaveIfError(
+ iTestCombiner->iSectionParser->SetPosition( iEndLoopStartPos ));
+
+ // Testing is ongoing, test case file parsing cannot
+ // be continue. Next line will be run when some AO
+ // will be complete and allow parsing to continue
+ return EFalse;
+ }
+ else if(testCase->State() == CTCTestCase::ETestCaseCompleted)
+ {
+ // Go to beginning of the endloop
+ User::LeaveIfError(iTestCombiner->iSectionParser->SetPosition(iEndLoopStartPos));
+
+ // Testing is ongoing, test case file parsing cannot
+ // be continue. Next line will be run when some AO
+ // will be complete and allow parsing to continue
+ return ETrue;
+ }
+ else
+ {
+ // This should newer happen
+ __TRACE( KError, (_L("ExecuteEndLoopL: Illegal branch") ) );
+ }
+ }
+ } // end for-loop
+
+ iLoopCounter++;
+ __TRACE( KMessage, (_L("ExecuteLineL: Loop executed for %d times" ),
+ iLoopCounter ) );
+
+ //If passlimit (endurance) is enabled, we must check if any of test case in this iteration has failed
+ if( iPasslimitEnabled && !iterationFailed )
+ {
+ iPassedIterationCnt++;
+ }
+
+ TTime currTime;
+ currTime.HomeTime();
+ //if( iLoopCounter < iLoopTimes )
+ if(((!iTimedLoop) && (iLoopCounter < iLoopTimes)) //Normal loop
+ ||
+ iTimedLoop && (currTime.MicroSecondsFrom(iStartTime) < iExpectedLoopTime)) //Timed loop
+ {
+ // Go to beginning of the loop
+ User::LeaveIfError(
+ iTestCombiner->iSectionParser->SetPosition( iLoopStartPos ));
+ }
+ else
+ {
+ // End looping
+ if( iPasslimitEnabled )
+ {
+ __TRACE(KMessage, (_L("ExecuteLoopL: Loop executed. Iterations: %d, passed: %d, expected: %d"), iLoopCounter, iPassedIterationCnt, iPasslimit));
+ }
+
+ iLoopCounter = 0;
+ iLoopTimes = 0;
+ iLoopStartPos = 0;
+ // Loop related initializations
+ iTestCombiner->iLoopIsUsed = EFalse;
+ //--LOOPBUG-- Do not zero counter because there could be some test cases run before the loop (Stif-83)
+ //--LOOPBUG-- iTestCombiner->iRunningTests = 0;
+
+ //If passlimit was given and number of passed test is less then expected, stop execution of combiner's test case
+ if( iPasslimitEnabled && iPassedIterationCnt < iPasslimit )
+ {
+ __TRACE( KMessage, ( _L( "ExecuteLoopL: Loop has failed (passlimit). Finishing with KErrCompletion." ) ) );
+ iTestCombiner->iScriptFailed = KErrCompletion;
+ iTestCombiner->iScriptFailedDescription = _L("Loop has not reached passlimit requirement.");
+ iState = ERunnerError;
+ CancelTestCases();
+ return ETrue; // Test case file parsing can be continue
+ }
+ else if( iPasslimitEnabled && iPassedIterationCnt >= iPasslimit )
+ {
+ __TRACE( KMessage, ( _L( "ExecuteLoopL: Loop has passed (passlimit)" ) ) );
+ }
+ iPassedIterationCnt = 0;
+ iPasslimit = 0;
+ iPasslimitEnabled = EFalse;
+ }
+
+ // Loop time is executed, free allocations that is allocated during loop
+ TInt a( 0 );
+ TInt b( 0 );
+
+ for( b = 0; b < iTestCombiner->iLoopAllocationArray.Count(); b++ )
+ {
+ //for( a = 0; a < iTestCombiner->iLoopAllocationArray.Count(); a++ )
+ for( a = 0; a < iTestCombiner->iTestCases.Count(); a++ )
+ {
+ if( a < iTestCombiner->iTestCases.Count() && iTestCombiner->iTestCases[a] == iTestCombiner->iLoopAllocationArray[b] )
+ {
+ delete iTestCombiner->iTestCases[a];
+ iTestCombiner->iTestCases.Remove( a );
+ }
+ }
+ }
+
+ for( b = 0; b < iTestCombiner->iLoopAllocationArray.Count(); b++ )
+ {
+ //for( a = 0; a < iTestCombiner->iLoopAllocationArray.Count(); a++ )
+ for( a = 0; a < iTestCombiner->iTestModules.Count(); a++ )
+ {
+ if( a < iTestCombiner->iTestModules.Count() && iTestCombiner->iTestModules[a] == iTestCombiner->iLoopAllocationArray[b] )
+ {
+ delete iTestCombiner->iTestModules[a];
+ iTestCombiner->iTestModules.Remove( a );
+ }
+ }
+ }
+
+ for( b = 0; b < iTestCombiner->iLoopAllocationArray.Count(); b++ )
+ {
+ //for( a = 0; a < iTestCombiner->iLoopAllocationArray.Count(); a++ )
+ for( a = 0; a < iTestCombiner->iEventArray.Count(); a++ )
+ {
+ if( a < iTestCombiner->iEventArray.Count() && iTestCombiner->iEventArray[a] == iTestCombiner->iLoopAllocationArray[b] )
+ {
+ delete iTestCombiner->iEventArray[a];
+ iTestCombiner->iEventArray.Remove( a );
+ }
+ }
+ }
+ for( b = 0; b < iTestCombiner->iLoopAllocationArray.Count(); b++ )
+ {
+ //for( a = 0; a < iTestCombiner->iLoopAllocationArray.Count(); a++ )
+ for( a = 0; a < iTestCombiner->iSlaveArray.Count(); a++ )
+ {
+ if( a < iTestCombiner->iSlaveArray.Count() && iTestCombiner->iSlaveArray[a] == iTestCombiner->iLoopAllocationArray[b] )
+ {
+ delete iTestCombiner->iSlaveArray[a];
+ iTestCombiner->iSlaveArray.Remove( a );
+ }
+ }
+ }
+ for( b = 0; b < iTestCombiner->iLoopAllocationArray.Count(); b++ )
+ {
+ //for( a = 0; a < iTestCombiner->iLoopAllocationArray.Count(); a++ )
+ for( a = 0; a < iTestCombiner->iSendReceive.Count(); a++ )
+ {
+ if( a < iTestCombiner->iSendReceive.Count() && iTestCombiner->iSendReceive[a] == iTestCombiner->iLoopAllocationArray[b] )
+ {
+ delete iTestCombiner->iSendReceive[a];
+ iTestCombiner->iSendReceive.Remove( a );
+ }
+ }
+ }
+
+ // Test operation can be continued
+ return ETrue; // Test case file parsing can be continue
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains the implementation of CRemoteTimer class
+ member functions.
+
+-------------------------------------------------------------------------------
+*/
+// MACROS
+#ifdef LOGGER
+#undef LOGGER
+#endif
+#define LOGGER iTestRunner->iTestCombiner->iLog
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteTimer
+
+ Method: CRemoteTimer
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestRunner* aTestRunner: in: Backpointer to CTestRunner
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CRemoteTimer::CRemoteTimer( CTestCombiner* aTestCombiner ):
+ CActive( CActive::EPriorityLow ), // Executed with lowest priority
+ iState( ETimerIdle ),
+ iTestCombiner( aTestCombiner )
+ {
+ CActiveScheduler::Add( this );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteTimer
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CRemoteTimer::ConstructL()
+ {
+
+ iTimer.CreateLocal();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteTimer
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestCombiner* aTestCombiner: in: Backpointer to CTestCombiner
+
+ Return Values: CRemoteTimer*: new object
+
+ Errors/Exceptions: Leaves if new or ConstructL leaves
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+
+CRemoteTimer* CRemoteTimer::NewL( CTestCombiner* aTestCombiner )
+ {
+
+ CRemoteTimer* self = new (ELeave) CRemoteTimer( aTestCombiner );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteTimer
+
+ Method: ~CRemoteTimer
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+
+CRemoteTimer::~CRemoteTimer()
+ {
+
+ Cancel();
+
+ iTimer.Close();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteTimer
+
+ Method: RunL
+
+ Description: Derived from CActive, handles testcase execution.
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CRemoteTimer::RunL()
+ {
+
+ if( iState != ETimerPending )
+ {
+ User::Panic( KRemoteTimer, KErrGeneral );
+ }
+
+ if( iStatus.Int() != KErrNone )
+ {
+ User::Panic( KRemoteTimer, KErrDied );
+ }
+
+ iState = ETimerIdle;
+
+ iTestCombiner->RemoteTimeout();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteTimer
+
+ Method: DoCancel
+
+ Description: Derived from CActive handles the Cancel
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CRemoteTimer::DoCancel()
+ {
+ iTimer.Cancel();
+ iState = ETimerIdle;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteTimer
+
+ Method: SetTimerActive
+
+ Description: Starts timer
+
+ Parameters: TTimeIntervalMicroSeconds32 anInterval: in: Timeout
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CRemoteTimer::SetTimerActive( TTimeIntervalMicroSeconds32 anInterval )
+ {
+ if( iState != ETimerIdle )
+ {
+ User::Panic( KRemoteTimer, KErrGeneral );
+ }
+
+ iState = ETimerPending;
+
+ iTimer.After( iStatus, anInterval );
+ SetActive();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains the implementation of CRemoteReceiver class
+ member functions.
+
+-------------------------------------------------------------------------------
+*/
+// MACROS
+#ifdef LOGGER
+#undef LOGGER
+#endif
+#define LOGGER iTestCombiner->iLog
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteReceiver
+
+ Method: CRemoteReceiver
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestCombiner* aTestCombiner: in: Backpointer to CTestCombiner
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CRemoteReceiver::CRemoteReceiver( CTestCombiner* aTestCombiner ):
+ CActive( CActive::EPriorityStandard ),
+ iState( EReceiverIdle ),
+ iTestCombiner( aTestCombiner )
+ {
+ CActiveScheduler::Add( this );
+ __TRACEFUNC();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteReceiver
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CRemoteReceiver::ConstructL()
+ {
+
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteReceiver
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestCombiner* aTestCombiner: in: Backpointer to CTestCombiner
+
+ Return Values: CRemoteReceiver*: new object
+
+ Errors/Exceptions: Leaves if new or ConstructL leaves
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+
+CRemoteReceiver* CRemoteReceiver::NewL( CTestCombiner* aTestCombiner )
+ {
+ CRemoteReceiver* self = new (ELeave) CRemoteReceiver( aTestCombiner );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteReceiver
+
+ Method: ~CRemoteReceiver
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+
+CRemoteReceiver::~CRemoteReceiver()
+ {
+ __TRACEFUNC();
+ Cancel();
+
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteReceiver
+
+ Method: StartL
+
+ Description: Activates receiving.
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CRemoteReceiver::Start()
+ {
+ __TRACEFUNC();
+ __ASSERT_ALWAYS( iState == EReceiverIdle,
+ User::Panic( KRemoteReceiver, KErrGeneral ) );
+ iState = EReceiverPending;
+
+ iTestCombiner->TestModuleIf().RemoteReceive( iRemoteMsg, iStatus );
+ SetActive();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteReceiver
+
+ Method: RunL
+
+ Description: Derived from CActive, handles testcase execution.
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: Leaves on error situations.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CRemoteReceiver::RunL()
+ {
+ __TRACEFUNC();
+
+ __ASSERT_ALWAYS( iState == EReceiverPending,
+ User::Panic( KRemoteReceiver, KErrGeneral ) );
+ iState = EReceiverIdle;
+
+ iTestCombiner->ReceiveResponse( iRemoteMsg );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRemoteReceiver
+
+ Method: DoCancel
+
+ Description: Derived from CActive handles the Cancel
+
+ Parameters: None.
+
+ Return Values: None.
+
+ Errors/Exceptions: None.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CRemoteReceiver::DoCancel()
+ {
+ __TRACEFUNC();
+
+ iTestCombiner->TestModuleIf().RemoteReceiveCancel();
+
+ }
+
+// ================= OTHER EXPORTED FUNCTIONS =================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: LibEntryL
+
+ Description: Polymorphic Dll Entry Point
+
+ Parameters: None.
+
+ Return Values: CTestCombiner*: pointer to new CTestCombiner
+
+ Errors/Exceptions: Leaves if NewL leaves.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+
+EXPORT_C CTestCombiner* LibEntryL()
+ {
+ return CTestCombiner::NewL();
+ }
+
+
+
+// End of File