diff -r bbd31066657e -r 8bb370ba6d1d testexecfw/stf/stfext/testmodules/scriptermod/src/TestScripter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testexecfw/stf/stfext/testmodules/scriptermod/src/TestScripter.cpp Fri Apr 09 10:46:28 2010 +0800 @@ -0,0 +1,7350 @@ +/* +* 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 file contains TestScripter implementation. +* +*/ + +// INCLUDE FILES +#include +#include +#include "TestScripter.h" +#include "TestKeywords.h" +#include "Logging.h" +#include "TestEngineClient.h" +#include "SettingServerClient.h" +#include "TestScripterInternal.h" +#include "SubTestCaseRunner.h" +#include + + +#include + +// EXTERNAL DATA STRUCTURES +// None + +// EXTERNAL FUNCTION PROTOTYPES +// None + +// CONSTANTS +// None + +const TUid KPropertyCat = + { + 0x101FB3DE + }; +const TUint KPropertyKey = 0x00000001; +// MACROS +#ifdef LOGGER +#undef LOGGER +#endif +#define LOGGER iLog + +// LOCAL CONSTANTS AND MACROS +_LIT( KExecute, "Execute"); +// Printing priorities +const TInt KPrintPriExec = 400; + +// MODULE DATA STRUCTURES +// None + +// LOCAL FUNCTION PROTOTYPES +// None + +// FORWARD DECLARATIONS +// None + +// ==================== LOCAL FUNCTIONS ======================================= + +/* +------------------------------------------------------------------------------- + + Class: - + + Method: CallBack + + Description: (Function pointer) Called from CScriptBase class. Generic + method for call back operations from Test Script Class to + TestScripter. + + Parameters: CTestScripter* aTestScripter: in: Pointer to TestScripter + TStifTSCallBackType aCallType: in: Call back type + const TDesC& aLine: in Script line + + Return Values: TInt: Symbian error code + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CallBack( CTestScripter* aTestScripter, + TStifTSCallBackType aCallType, + const TDesC& aLine ) + { + TInt ret( 0 ); + switch( aCallType ) + { + case EStifTSCallClass: + { + ret = aTestScripter->CallTestClass( aLine ); + break; + } + case EStifTSGetObject: + { + ret = aTestScripter->GetTestScriptObject( aLine ); + break; + } + default: + { + ret = KErrArgument; + break; + } + } + + return ret; + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains the implementation of CTestScripter class + member functions. + +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: CTestScripter + + Description: Default constructor + + C++ default constructor can NOT contain any code, that + might leave. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + + ------------------------------------------------------------------------------- + */ +CTestScripter::CTestScripter() : + iObjects(NULL) + { + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: ConstructL + + Description: Symbian OS second phase constructor + + Symbian OS default constructor can leave. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::ConstructL() + { + __TRACE( KPrint, ( _L("New TestScripter") ) ); + iStdLog = CStifLogger::NewL( KTestScripterLogDir, + KTestScripterLogFile ); + iLog = iStdLog; + + iOOMIgnoreFailure = EFalse; // OFF for default + + iCheckHeapBalance = EFalse; // No checking heap balance by default + + //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); + } + // Close Setting server session + settingServer.Close(); + iAddTestCaseTitleToLogName = loggerSettings.iAddTestCaseTitle; + + // Initialize parser variables + iCurrentParser = NULL; + iCurrentParserReadFirstLine = EFalse; + + TUint ProperKey = RProcess().Id().Id(); + TInt err = RProperty::Define(KPropertyCat, ProperKey, RProperty::EInt); + + iObjects = new (ELeave) RPointerArray ; + err = RProperty::Set(KPropertyCat, ProperKey, (TInt) iObjects); + User::LeaveIfError(err); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: NewL + + Description: Two-phased constructor. + + Parameters: None + + Return Values: CTestScripter*: new object + + Errors/Exceptions: Leaves if new or ConstructL leaves. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CTestScripter* CTestScripter::NewL() + { + + CTestScripter* self = new (ELeave) CTestScripter(); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: ~CTestScripter + + Description: Destructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CTestScripter::~CTestScripter() + { + iTestObjects.ResetAndDestroy(); + iTestModules.ResetAndDestroy(); + iDefinedIni.ResetAndDestroy(); + iDefinedRuntime.ResetAndDestroy(); + iDefinedLocal.ResetAndDestroy(); + iParserStack.ResetAndDestroy(); + iGlobalObjects.ResetAndDestroy(); + iSharedTestModules.ResetAndDestroy(); + iObjects->Reset(); + iTestObjects.Close(); + iTestModules.Close(); + iDefinedIni.Close(); + iGlobalObjects.Close(); + iDefinedRuntime.Close(); + iDefinedLocal.Close(); + iParserStack.Close(); + iObjects->Close(); + iSharedTestModules.Close(); + + iCurrentParser = NULL; + delete iSectionParser; + delete iTestRunner; + delete iObjects; + + iLog = NULL; + delete iStdLog; + iStdLog = NULL; + delete iTCLog; + iTCLog = NULL; + + TUint ProperKey = RProcess().Id().Id(); + TInt err = RProperty::Delete(KPropertyCat, ProperKey); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + 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 CTestScripter::InitL( TFileName& aIniFile, + TBool /*aFirstTime*/ ) + { + + __TRACEFUNC(); + + if( aIniFile.Length() > 0 ) + { + // Read initialization from test case file + ReadInitializationL( aIniFile, iDefinedIni ); + } + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: GetTestCases + + Description: GetTestCases is used to inquired test cases + + Parameters: const TFileName& aConfigFile: in: Test case file + RPointerArray& aTestCases: out: + Array of TestCases + + Return Values: KErrNone: Success + Symbian OS error code + + Errors/Exceptions: Leaves if CStifParser::SectionL leaves + Leaves if CStifParser::NextSectionL leaves + Leaves if memory allocation fails + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestScripter::GetTestCasesL( const TFileName& aConfigFile, + RPointerArray& 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; + + // Open test case file + TRAPD( err, + parser = CStifParser::NewL( _L(""), + aConfigFile, + CStifParser::ECStyleComments ) ); + if( err != KErrNone ) + { + __TRACE( KError, (_L("Given test case script file [%S] not found"), + &aConfigFile ) ); + __RDEBUG( (_L("Given test case script file [%S] not found"), + &aConfigFile ) ); + return err; + } + + CleanupStack::PushL( parser ); + CStifSectionParser* section; + TPtrC tmp; + TInt index = 0; + TInt ret = KErrNone; + + // Find first section + section = parser->SectionL( KTestStartTag, KTestEndTag ); + if( section == NULL ) + { + ret = KErrNotFound; + } + else + { + // Parse all sections + while( section ) + { + CleanupStack::PushL( section ); + + // Get title line + if( section->GetLine( TTestKeywords::Keyword( TTestKeywords::ETitle ), + tmp, ENoTag ) != KErrNone ) + { + __TRACE( KError, (_L("Title not given for test case"))); + User::Leave( KErrNotFound ); + } + else + { + 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; + + // Get timeout if defined + CStifItemParser* item = section->GetItemLineL( + TTestKeywords::Keyword( TTestKeywords::ETimeout ) ); + if( item ) + { + TInt timeout; // In milliseconds + ret = item->GetInt( + TTestKeywords::Keyword( TTestKeywords::ETimeout ), + timeout ); + if( ret != KErrNone ) + { + __TRACE( KError, (_L("Illegal timeout"))); + User::Leave( ret ); + } + + // Type cast timeout to TInt64 + tc->iTimeout = TInt64( timeout ) * 1000; + __TRACE( KMessage, (_L("Timeout: %i"), tc->iTimeout.Int64() )); + } + + // Get priority if defined + item = section->GetItemLineL( + TTestKeywords::Keyword( TTestKeywords::EPriority ) ); + if( item ) + { + // First try to interpret as integer + ret = item->GetInt( + TTestKeywords::Keyword( TTestKeywords::EPriority ), + tc->iPriority ); + if( ret != KErrNone ) + { + TPtrC priority; + // If priority was not given as integer, it must be + // one of the predefined values + ret = item->GetString( + TTestKeywords::Keyword( TTestKeywords::EPriority ), + priority ); + if( ret != KErrNone ) + { + __TRACE( KError, (_L("Illegal priority"))); + User::Leave( ret ); + } + switch( TTestKeywords::Parse( priority, + TTestKeywords::Priority ) ) + { + case TTestKeywords::EPriHigh: + tc->iPriority = TTestCaseInfo::EPriorityHigh; + break; + case TTestKeywords::EPriNormal: + tc->iPriority = TTestCaseInfo::EPriorityNormal; + break; + case TTestKeywords::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: CTestScripter + + Method: GetConstantValue + + Description: Internal fuction to get const value defined in + [Define]...[Enddefine] section of script file + + GetConstantValue gets const value defined in [Define]...[Enddefine] + section of script file + + Parameters: const TDesC& aName: in: constant name + TDes& avalue: out: constant value + + Return Values: KErrNone: Value is returned succesfully. + KErrNotFound: Constant was not found + Any other SymbianOS error + +------------------------------------------------------------------------------- +*/ +EXPORT_C TInt CTestScripter::GetConstantValue( const TDesC& aName, TDes& aValue ) + { + + __TRACEFUNC(); + + TInt count = iDefinedLocal.Count(); + for(TInt i = 0; i < count; i++) + { + if(iDefinedLocal[i]->Name() == aName) + { + aValue.Copy(iDefinedLocal[i]->Value()); + return KErrNone; + } + } + + count = iDefinedIni.Count(); + for( TInt i = 0; i < count; i++ ) + { + if( iDefinedIni[i]->Name() == aName ) + { + aValue.Copy( iDefinedIni[i]->Value() ); + return KErrNone; + } + } + + count = iDefinedRuntime.Count(); + for( TInt i = 0; i < count; i++ ) + { + if( iDefinedRuntime[i]->Name() == aName ) + { + aValue.Copy( iDefinedRuntime[i]->Value() ); + return KErrNone; + } + } + return KErrNotFound; + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: RunTestCaseL + + Description: Run a specified testcase. + + RunTestCaseL is used to run an individual test case. + + Parameters: const TInt aCaseNumber: in: Testcase number + const TFileName& aConfig: in: Test case file + TTestResult& aResult: out: test case result + + Return Values: KErrNone: Test case started succesfully. + KErrNotFound: Testcase not found + KErrUnknown: Unknown TestScripter error + Any other SymbianOS error + + Errors/Exceptions: Leaves if GetTestCaseL leaves + Leaves if RunTestL leaves + Leaves if memory allocation fails + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestScripter::RunTestCaseL( const TInt aCaseNumber, + const TFileName& aConfig, + TTestResult& aResult ) + { + + // Heap is checked by test server + //__UHEAP_MARK; + + __TRACEFUNC(); + + //Open new log file with test case title in file name + if(iAddTestCaseTitleToLogName) + { + //Delete test case logger if exists + if(iTCLog) + { + delete iTCLog; + iTCLog = NULL; + } + + TFileName logFileName; + TName title; + TestModuleIf().GetTestCaseTitleL(title); + + logFileName.Format(KTestScripterLogFileWithTitle, &title); + iTCLog = CStifLogger::NewL(KTestScripterLogDir, logFileName); + iLog = iTCLog; + } + + __TRACE( KMessage, (_L("\n\n***Testcase started***"))); + + // Remove locally defined variables + iDefinedLocal.ResetAndDestroy(); + // Remove existing function parsers (there shouldn't be any) + iParserStack.ResetAndDestroy(); + + // Keep file name of config file + iConfig = aConfig; + + // Read initialization from test case file + ReadInitializationL( aConfig, iDefinedRuntime ); + + // Get case from test case file + iSectionParser = GetTestCaseL( aCaseNumber, aConfig ); + iCurrentParser = iSectionParser; + iCurrentParserReadFirstLine = EFalse; + + // Check parsing result + if( iSectionParser == NULL ) + { + __TRACE( KError, (_L("***Parsing testcase failed***\n\n"))); + // Delete runtime defines + iDefinedRuntime.ResetAndDestroy(); + //__UHEAP_MARKEND; + return KErrNotFound; + } + + // When option is set in cfg file, on EKA2 env memory leaking is enabled + TInt memCellsBef = 0; //memory in current thread allocated before the test case is run + TInt memCellsAft = 0; //memory in current thread allocated after the test case has run + + memCellsBef = User::Heap().Count(); + __TRACE(KMessage, (_L("Allocated memory cells before the test case: %d"), memCellsBef)); + + __TRACE(KMessage, (_L("Memory usage in global objects before the execution:"))); + TInt beforeGlobalMemCells = TraceGlobalObjectsMemoryUsage(); + + + CActiveScheduler* activeScheduler = + new ( ELeave ) CActiveScheduler(); + CleanupStack::PushL( activeScheduler ); + + if ( CActiveScheduler::Current() == NULL ) + { + CActiveScheduler::Install( activeScheduler ); + } + + // Run the given testcase described in iSectionParser section + RunTestL(); + + iTestObjects.ResetAndDestroy(); + iTestModules.ResetAndDestroy(); + iObjects->Reset(); + + // TestScripter must stop Active Scheduler after test + // object is destroyed. Otherwise if unexpected error occurs + // handling is erronous. + CleanupStack::PopAndDestroy( activeScheduler ); + + // Check for memory leak. + // It is reported in log always, but result of test case is changed only + // when option in cfg file is enabled. + memCellsAft = User::Heap().Count(); + __TRACE(KMessage, (_L("Allocated memory cells after the test case: %d"), memCellsAft)); + + + __TRACE(KMessage, (_L("Memory usage in global objects after the execution:"))); + TInt afterGlobalMemCells = TraceGlobalObjectsMemoryUsage(); + + memCellsAft = memCellsAft - afterGlobalMemCells + beforeGlobalMemCells; + + // if there is a difference report memory leak + if(memCellsAft != memCellsBef) + { + __TRACE(KError, (_L("Memory leak, %d cell(s) is missing"), memCellsAft - memCellsBef)); + if(iCheckHeapBalance) + { + // Memory leaks detection is disabled for UI components testing + if ( !( TestModuleIf().UITesting() ) ) + { + UpdateTestCaseResult(KErrGeneral, _L("Memory leak has occured")); + } + } + } + + // Delete parser and set current parser to NULL + iCurrentParser = NULL; + delete iSectionParser; + iSectionParser = NULL; + + // Erase config file name + iConfig = KNullDesC; + + // Return result + aResult = iResult; + + if( iResult.iResult == KErrNone ) + { + __TRACE( KPrint, (_L("***Testcase PASSED***\n\n"))); + TestModuleIf().Printf( KPrintPriNorm, _L("TestScripter"), + _L("***Testcase PASSED***\n\n")); + } + else + { + __TRACE( KPrint, (_L("***Testcase FAILED***\n\n"))); + TestModuleIf().Printf( KPrintPriNorm, _L("TestScripter"), + _L("***Testcase FAILED***\n\n")); + } + User::After(300000); + // Delete runtime defines + iDefinedRuntime.ResetAndDestroy(); + + //__UHEAP_MARKEND; + + //If log was replaced then restore it + if(iAddTestCaseTitleToLogName) + { + iLog = iStdLog; + delete iTCLog; + iTCLog = NULL; + } + + return KErrNone; + + } + +TInt CTestScripter::TraceGlobalObjectsMemoryUsage() + { + __TRACEFUNC(); + + TInt moduleNumber = iSharedTestModules.Count(); + TInt shareObjNumber = iGlobalObjects.Count(); + __TRACE(KMessage, (_L("There are %d item(s) in shared modules list"),moduleNumber)); + __TRACE(KMessage, (_L("There are %d item(s) in shared objects list"),shareObjNumber)); + + TInt listNumber = 0; + + if(moduleNumber != 0) + { + listNumber++; + __TRACE(KMessage, (_L("Shared module list used 1 cell."))); + __TRACE(KMessage, (_L("There are %d shared module(s), they used %d cells"), moduleNumber , moduleNumber * 2)); + } + + if(shareObjNumber != 0) + { + listNumber++; + __TRACE(KMessage, (_L("Shared object list used 1 cell."))); + __TRACE(KMessage, (_L("There are %d shared object(s), they used %d cells"), shareObjNumber, shareObjNumber * 4)); + } + TInt result = listNumber + moduleNumber * 2 + shareObjNumber * 4; + __TRACE(KMessage, (_L("There are %d cells used by shared objects and their modules."), result)); + + return result; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + 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 CTestScripter::ReadInitializationL( + const TDesC& aIniFile, + RPointerArray& aDefines ) + { + + 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 ) ); + + CStifSectionParser* 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 = aDefines.Count(); + TInt i = 0; + for( ; i < count; i++ ) + { + if( aDefines[i]->Name() == name ) + { + // Update existing + aDefines[i]->SetValueL( value ); + __TRACE(KMessage, (_L("Update define [%S]: [%S]"), &name, &value)); + break; + } + } + if( i == count) + { + // New define, store it + CDefinedValue* define = CDefinedValue::NewL( name, value ); + CleanupStack::PushL( define ); + User::LeaveIfError( aDefines.Append( define ) ); + CleanupStack::Pop( define ); + } + + CleanupStack::PopAndDestroy( item ); + item = section->GetNextItemLineL(); + } + CleanupStack::PopAndDestroy( section ); + section = parser->NextSectionL(KDefineStartTag, KDefineEndTag); + } + + //Read StifSettings section and find value for CheckHeapBalance. + //(In cfg file in settings section User may also set CapsModifier + // option. This is handled in TestServerClient.cpp in + // RTestServer::GetCapsModifier method). + section = parser->SectionL(KStifSettingsStartTag, KStifSettingsEndTag); + + if(section) + { + CleanupStack::PushL(section); + __TRACE(KMessage, (_L("Read stif settings"))); + + TPtrC value; + CStifItemParser* item = section->GetItemLineL(_L("")); + while(item) + { + CleanupStack::PushL(item); + __TRACE( KMessage, (_L("Got settings line"))); + + if(item->GetString(_L("CheckHeapBalance="), value) == KErrNone) + { + __TRACE(KMessage, (_L("Got CheckHeapBalance item, value=%S"), &value)); + if(value.Compare(_L("off")) == 0) + { + iCheckHeapBalance = EFalse; + } + else if(value.Compare(_L("on")) == 0) + { + iCheckHeapBalance = ETrue; + } + else + { + __TRACE(KError, (_L("Value '%S' for CheckHeapBalance setting is not supported. Aborting"), &value)); + User::Leave(KErrNotSupported); + } + } + CleanupStack::PopAndDestroy(item); + item = section->GetNextItemLineL(); + } + CleanupStack::PopAndDestroy(section); + } + + + + + //Read data section + section = parser->SectionL(KDataStartTag, KDataEndTag); + + if(section) + { + CleanupStack::PushL(section); + __TRACE(KMessage, (_L("Read data section"))); + + + CStifItemParser* item = section->GetItemLineL(_L("")); + + while(item) + { + CleanupStack::PushL(item); + __TRACE( KMessage, (_L("Got data section line"))); + TPtrC inifile; + TPtrC inisection; + if(item->GetString(_L("File"), inifile) == KErrNone) + { + + __TRACE(KMessage, (_L("Got ini file name: %S"), &inifile)); + + iCurrentFile.Zero(); + + + if(inifile.Find(_L("\\"))==KErrNotFound) + { + iCurrentFile.Append(_L("c:\\TestFramework\\")); + } + + iCurrentFile.Append(inifile); + + + + TPtrC alias; + err=item->GetNextString(alias); + __TRACE(KMessage, (_L("Got ini file alias: %S"), &alias)); + + iCurrentFileAlias.Zero(); + if(err==KErrNone) + { + iCurrentFileAlias.Copy(alias); + } + else + { + TParsePtr filespec(iCurrentFile); + iCurrentFileAlias.Copy(filespec.NameAndExt()); + } + + + + } + else if(item->GetString(_L("Section"), inisection) == KErrNone) + { + + __TRACE(KMessage, (_L("Got Section name: %S"), &inisection)); + + iCurrentSection.Zero(); + iCurrentSection.Copy(inisection); + + + TPtrC alias; + TInt err=item->GetNextString(alias); + __TRACE(KMessage, (_L("Got Section alias: %S"), &alias)); + + iCurrentSectionFileAlias.Zero(); + + if(err==KErrNone) + { + iCurrentSectionFileAlias.Copy(alias); + } + else + { + iCurrentSectionFileAlias.Copy(iCurrentSection); + } + + TParsePtr filespec(iCurrentFile); + + CStifParser* parser=CStifParser::NewL(filespec.DriveAndPath(),filespec.NameAndExt()); + + TBuf section; + section.Append(_L("[")); + section.Append(iCurrentSection); + section.Append(_L("]")); + CStifSectionParser* sectionparser=parser->SectionL(section,KNullDesC,1,EFalse); + + CStifItemParser* itemparser=sectionparser->GetItemLineL(KNullDesC); + + while(itemparser) + { + itemparser->SetParsingType(CStifItemParser::EQuoteStyleParsing); + TPtrC temp; + + itemparser->Remainder(temp); + __TRACE(KMessage, (_L("Got item string: %S"), &temp)); + iCurrentKey.Zero(); + iCurrentKey.Append(KFileFlag); + iCurrentKey.Append(iCurrentFileAlias); + iCurrentKey.Append(KSectionFlag); + iCurrentKey.Append(iCurrentSectionFileAlias); + iCurrentKey.Append(KKeyFlag); + + TBuf tempkey; + TBuf tempvalue; + TLex lex(temp); + TChar ch; + while((ch = lex.Get()) != 0 ) + { + while ((ch = lex.Peek()) != '=') + lex.Inc(); + tempkey.Append(lex.MarkedToken()); + lex.Inc(); + lex.Mark(); + break; + } + tempkey.TrimAll(); + iCurrentKey.Append(tempkey); + iKeys.Append(iCurrentKey); + + + tempvalue.Append(lex.Remainder()); + tempvalue.TrimAll(); + + + iCurrentvalues.Zero(); + iCurrentvalues.Copy(tempvalue); + + + + iValues.Append(iCurrentvalues); + delete itemparser; + itemparser=NULL; + itemparser=sectionparser->GetNextItemLineL(); + + } + + + + + delete sectionparser; + delete parser; + + + + + + + + } + CleanupStack::PopAndDestroy(item); + item = section->GetNextItemLineL(); + } + CleanupStack::PopAndDestroy(section); + } + + + + CleanupStack::PopAndDestroy( parser ); + } + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + 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: CStifSectionParser*: pointer to test case section + + Errors/Exceptions: Leaves if CStifParser::NewL leaves + Leaves if CStifParser::SectionL leaves + Leaves if memory allocation fails + + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CStifSectionParser* CTestScripter::GetTestCaseL( const TInt aCaseNumber, + const TFileName& aConfig ) + { + __TRACEFUNC(); + CStifParser* parser = NULL; + + TRAPD( err, + parser = CStifParser::NewL( _L(""), + aConfig, + CStifParser::ECStyleComments ); ); + if( err != KErrNone ) + { + __TRACE( KError, (_L("Test case file [%S] not found"), &aConfig )); + User::Leave( err ); + } + CleanupStack::PushL( parser ); + + CStifSectionParser* section = NULL; + TRAP( err, + section =parser->SectionL( KTestStartTag, KTestEndTag, aCaseNumber );); + if( err != KErrNone ) + { + __TRACE( KError, + (_L("Section [%S/%d] not found"), &aConfig, aCaseNumber )); + User::Leave( err ); + } + + CleanupStack::PopAndDestroy( parser ); + return section; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: GetSubL + + Description: Get specified function (sub) from stored config file. + + Parameters: const TDesC& aSubName: in: function name + + Return Values: CStifSectionParser*: pointer to test function section + + Errors/Exceptions: Leaves if CStifParser::NewL leaves + Leaves if CStifParser::SectionL leaves + Leaves if memory allocation fails + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CStifSectionParser* CTestScripter::GetSubL(const TDesC& aSubName) + { + __TRACE(KMessage, (_L("Searching sub [%S]."), &aSubName)); + // Check if config file is set + if(iConfig.Length() == 0) + { + __TRACE(KError, (_L("Searching sub [%S]. Config file is not set."), &aSubName)); + User::Leave(KErrBadName); + } + + // Create parser + CStifParser* parser = NULL; + CStifSectionParser* section = NULL; + + TRAPD(err, + parser = CStifParser::NewL(_L(""), iConfig, CStifParser::ECStyleComments); + ); + if(err != KErrNone) + { + __TRACE(KError, (_L("Searching sub [%S]. Error [%d] when loading config file [%S]."), &aSubName, err, &iConfig)); + User::Leave(err); + } + CleanupStack::PushL(parser); + + // Set section tags + _LIT(KEndSubTag, "[EndSub]"); + TName startSubTag; + startSubTag.Copy(_L("[Sub ")); + startSubTag.Append(aSubName); + startSubTag.Append(_L("]")); + + // Load section + TRAP(err, + section = parser->SectionL(startSubTag, KEndSubTag, 1); + ); + if(err != KErrNone) + { + __TRACE(KError, (_L("Searching sub [%S]. Searching section %S%S ended with error [%d]."), &aSubName, &startSubTag, &KEndSubTag, err)); + User::Leave(err); + } + if(!section) + { + __TRACE(KError, (_L("Searching sub [%S]. Section %S%S not found."), &aSubName, &startSubTag, &KEndSubTag)); + User::Leave(err); + } + else + { + __TRACE(KMessage, (_L("Searching sub [%S]. Section %S%S found."), &aSubName, &startSubTag, &KEndSubTag)); + } + + CleanupStack::PopAndDestroy(parser); + return section; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + 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: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::RunTestL() + { + __TRACEFUNC(); + iResult.iResult = KErrNone; + iResult.iResultDes.Zero(); + + // "title" keyword must be in the first line + TPtrC title; + if( iCurrentParser->GetLine( + TTestKeywords::Keyword( TTestKeywords::ETitle ), title, ENoTag ) + != KErrNone ) + { + __TRACE( KError, (_L("title not found from section"))); + User::Leave( KErrNotFound ); + } + iCurrentParserReadFirstLine = ETrue; + + __TRACE( KMessage, (_L("RunTest: %S"), &title )); + + iTestRunner = CTestRunner::NewL( this ); + + TestModuleIf().Printf( KPrintPriNorm, _L("RunTest"), _L("%S"), &title ); + + // Rest of the job is done by test runner + iTestRunner->SetRunnerActive(); + + // Start activeScheduler looping testcase lines + __TRACE( KMessage, (_L("Start CActiveScheduler"))); + CActiveScheduler::Current()->Start(); + + if ( iTestRunner->IsFailedSubTestCaseReported() && !(iPassLimitNotMet) ) + { + TFullTestResult testResult = iTestRunner->GetFailedSubTestCaseResult(); + const CStartInfo* startInfo = iTestRunner->GetFailedSubTestCaseInfo(); + if( testResult.iCaseExecutionResultType == TFullTestResult::ECaseExecuted ) + { + iResult.iResult = testResult.iTestResult.iResult; + } + else + { + iResult.iResult = testResult.iCaseExecutionResultCode; + } + iResult.iResultDes.Format( _L("Sub test case \"%S\" execution failed. "), &startInfo->GetTitle() ); + iResult.iResultDes.AppendFormat( _L("Result [%d], expected result [%d]"), iResult.iResult, startInfo->GetExpectedResult() ); + } + + delete iTestRunner; + iTestRunner = NULL; + __TRACE( KMessage, ( _L("RunTestL: Done"))); + + // Destroy locally defined variables + iDefinedLocal.ResetAndDestroy(); + // Destroy function parsers (there shouldn't be any) + iParserStack.ResetAndDestroy(); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + 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 + + Return Values: CTCTestModule*: pointer to testmodules description + + Errors/Exceptions: Leaves if CTCTestModule::NewL leaves + Leaves if RPointerArray::Append fails + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TTestModule* CTestScripter::LoadTestModuleL( TDesC& aModule ) + { + __TRACEFUNC(); + TInt count = iTestModules.Count(); + for( TInt i=0; i < count; i++ ) + { + if( iTestModules[i]->ModuleName() == aModule ) + { + // Found test module, return description + __TRACE( KMessage, + (_L("GetTestModuleL: Use already loaded TestModule (%S)"), + &aModule )); + return iTestModules[i]; + } + } + + __TRACE( KMessage, (_L("GetTestModuleL: Load new TestModule (%S)"), + &aModule )); + TTestModule* module = new (ELeave) TTestModule(); + CleanupStack::PushL( module ); + module->ModuleName() = aModule; + User::LeaveIfError( iTestModules.Append( module ) ); + CleanupStack::Pop( module ); + + TInt ret = module->iLibrary.Load ( aModule ); + + if( ret != KErrNone ) + { + __TRACE( KMessage, (_L("GetTestModuleL: %S loading failed"), + &aModule )); + TestModuleIf().Printf( KMessage, _L("Load dll"), _L("%S failed"), + &aModule ); + + User::Leave( ret ); + } + + // Get pointer to first exported function + module->iLibEntry = (CInterfaceFactory) module->iLibrary.Lookup(1); + return module; + + } + +/* + ------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: LoadSharedTestModuleL + + 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 + + Return Values: CTCTestModule*: pointer to testmodules description + + Errors/Exceptions: Leaves if CTCTestModule::NewL leaves + Leaves if RPointerArray::Append fails + + Status: Draft + + ------------------------------------------------------------------------------- + */ + +TTestModule* CTestScripter::LoadSharedTestModuleL(TDesC& aModule) + { + __TRACEFUNC(); + TInt count = iSharedTestModules.Count(); + for (TInt i = 0; i < count; i++) + { + if (iSharedTestModules[i]->ModuleName() == aModule) + { + // Found test module, return description + __TRACE( KMessage, + (_L("GetTestModuleL: Use already loaded TestModule (%S)"), + &aModule )); + return iSharedTestModules[i]->Get(); + } + } + + __TRACE( KMessage, (_L("GetTestModuleL: Load new TestModule (%S)"), + &aModule )); + TTestModule* module = new (ELeave) TTestModule(); + CleanupStack::PushL(module); + module->ModuleName() = aModule; + User::LeaveIfError(iSharedTestModules.Append( + new (ELeave) TSharedTestModule(module))); + CleanupStack::Pop(module); + + TInt ret = module->iLibrary.Load(aModule); + TestModuleIf().iNumberInGlbDict++; + + if (ret != KErrNone) + { + __TRACE( KMessage, (_L("GetTestModuleL: %S loading failed"), + &aModule )); + TestModuleIf().Printf(KMessage, _L("Load dll"), _L("%S failed"), + &aModule); + + User::Leave(ret); + } + + // Get pointer to first exported function + module->iLibEntry = (CInterfaceFactory) module->iLibrary.Lookup(1); + return module; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: CreateObjectL + + Description: Load testmodule if not already loaded, otherwise return + description of the loaded testmodule. + + Parameters: TDesC& aModule: in: module name + TDesC& aObjectId: in: object id name + + Return Values: None + + Errors/Exceptions: Leaves on error + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::CreateObjectL( TDesC& aModule, TDesC& aObjectId ) + { + __TRACEFUNC(); + + // Load module and get pointer + TTestModule* module = LoadTestModuleL( aModule ); + TTestObject* object = new (ELeave) TTestObject(); + CleanupStack::PushL( object ); + object->ObjectId() = aObjectId; + object->iModule.Copy(aModule); + User::LeaveIfError( iTestObjects.Append( object ) ); + CleanupStack::Pop( object ); + + // Create object + object->iScript = module->iLibEntry( TestModuleIf() ); + //User::LeaveIfNull ( object->iScript ); + if( object->iScript == NULL ) + { + User::Leave( KErrGeneral ); + } + + // Create continue callback + object->iContinue = CTestContinue::NewL( this, object ); + + // Create function pointer operation to possible + object->iScript->SetScripter( &CallBack, this ); + + TestModuleIf().AddTestObjToCaseDictL(object); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: CreateShareObjectL + + Description: Load testmodule if not already loaded, otherwise return + description of the loaded testmodule. + + Parameters: TDesC& aModule: in: module name + TDesC& aObjectId: in: object id name + + Return Values: None + + Errors/Exceptions: Leaves on error + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::CreateShareObjectL( TDesC& aModule, TDesC& aObjectId ) + { + __TRACEFUNC(); + + // Load module and get pointer + TTestModule* module = LoadSharedTestModuleL(aModule); + TTestObject* object = new (ELeave) TTestObject(); + CleanupStack::PushL( object ); + object->ObjectId() = aObjectId; + CleanupStack::Pop( object ); + object->iModule.Copy(aModule); + // Create object + object->iScript = module->iLibEntry( TestModuleIf() ); + //User::LeaveIfNull ( object->iScript ); + if( object->iScript == NULL ) + { + User::Leave( KErrGeneral ); + } + + TestModuleIf().AddTestObjToCaseDictL(object); + AddTestObjToScripterDictL(object); + TestModuleIf().iNumberInGlbDict++; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: RestoreShareObjectL + + Description: Load testmodule if not already loaded, otherwise return + description of the loaded testmodule. + + Parameters: TDesC& aModule: in: module name + TDesC& aObjectId: in: object id name + + Return Values: None + + Errors/Exceptions: Leaves on error + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::RestoreShareObjectL( TDesC& aObjectId ) + { + __TRACEFUNC(); + + TTestObject* object = NULL; + object = (TTestObject*)GetTestObjFromScripterDict( aObjectId ); + + if( NULL == object ) + { + User::Leave( KErrGeneral ); + } + + //User::LeaveIfNull ( object->iScript ); + if( object->iScript == NULL ) + { + User::Leave( KErrGeneral ); + } + + TestModuleIf().AddTestObjToCaseDictL(object); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: CreateKernelObjectL + + Description: Load testdriver if not already loaded, otherwise return + description of the loaded testdriver. + + Parameters: TDesC& aDriver: in: driver name + TDesC& aObjectId: in: object id name + + Return Values: None + + Errors/Exceptions: Leaves on error + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::CreateKernelObjectL( TDesC& aDriver, TDesC& aObjectId ) + { + + __TRACEFUNC(); + + if( ( aDriver.Length() > KMaxName ) || + ( aObjectId.Length() > KMaxName ) ) + { + __TRACE( KError, (_L("CreateKernelObjectL: Max lenght exceeded") ) ); + User::Leave( KErrArgument ); + } + TInt ret = User::LoadLogicalDevice( aDriver ); + if( ( ret != KErrNone ) && ( ret != KErrAlreadyExists ) ) + { + __TRACE( KError, + (_L("CreateKernelObjectL: User::LoadLogicalDevice failed %d"), + ret ) ); + User::Leave( ret ); + } + + TTestObjectKernel* object = new (ELeave) TTestObjectKernel(); + CleanupStack::PushL( object ); + object->ObjectId() = aObjectId; + object->LddName().Copy( aDriver ); + ret = object->KernelTestClass().Open( + object->KernelTestClass().VersionRequired(), + aDriver ); + if( ret != KErrNone ) + { + __TRACE( KError, + (_L("CreateKernelObjectL: KernelTestClass().Open failed %d"), + ret ) ); + User::Leave( ret ); + } + + User::LeaveIfError( iTestObjects.Append( object ) ); + CleanupStack::Pop( object ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + 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 + + Return Values: CTCTestModule*: pointer to testmodules description + + Errors/Exceptions: Leaves if CTCTestModule::NewL leaves + Leaves if RPointerArray::Append fails + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestScripter::DeleteObjectL( TDesC& aObjectId ) + { + __TRACEFUNC(); + + TestModuleIf().DelTestObjFromCaseDict(aObjectId); + + TInt count = iTestObjects.Count(); + for( TInt i=0; i < count; i++ ) + { + if( iTestObjects[i]->ObjectId() == aObjectId ) + { + TTestObjectBase* object = iTestObjects[i]; + iTestObjects.Remove( i ); + delete object; + return KErrNone; + } + } + + return KErrNone; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: DeleteGlobalObjectL + + Description: Delete test object from dictionary + + Parameters: TDesC& aObjectId: in: object name + + Return Values: void + + Errors/Exceptions: Leaves if CTCTestModule::NewL leaves + Leaves if RPointerArray::Append fails + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestScripter::DeleteScripterObjectL( TDesC& aObjectId ) + { + __TRACEFUNC(); + + TScriptObject* obj = TestModuleIf().GetTestObjFromCaseDict(aObjectId); + if(obj == NULL) + { + return KErrNotFound; + } + + TestModuleIf().DelTestObjFromCaseDict(aObjectId); + DelTestObjFromScripterDict(aObjectId); + + return KErrNone; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + 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: Draft + +------------------------------------------------------------------------------- +*/ +TTestObjectBase* CTestScripter::GetObject( const TDesC& aObjectId ) + { + __TRACEFUNC(); + + TInt count = iTestObjects.Count(); + for( TInt i=0; i < count; i++ ) + { + if( iTestObjects[i]->ObjectId() == aObjectId ) + { + // Found testcase with specified TestId + return iTestObjects[i]; + } + } + + TTestObject* object = NULL; + object = (TTestObject*)TestModuleIf().GetTestObjFromCaseDict( aObjectId ); + + return object; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: CallTestClass + + Description: For sub classing operations. + + Parameters: const TDesC& aLine: in: script line + + Return Values: TInt: Symbian error code + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestScripter::CallTestClass( const TDesC& aLine ) + { + CStifItemParser* item = CStifItemParser::NewL( aLine, 0, aLine.Length() ); + CleanupStack::PushL( item ); + + TPtrC objectName; + TInt ret( KErrNone ); + ret = item->GetString( _L( "" ), objectName ); + if( ret != KErrNone ) + { + CleanupStack::PopAndDestroy( item); + return ret; + } + + TTestObjectBase* obj = GetObject( objectName ); + if( obj == NULL ) + { + CleanupStack::PopAndDestroy(item ); + return KErrNotFound; + } + + TRAPD( commandResult, commandResult = obj->RunMethodL( *item ) ); + + CleanupStack::PopAndDestroy(item ); + + return commandResult; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: GetTestScriptObject + + Description: Get object address. + + Parameters: const TDesC& aObjectName: in: object name + + Return Values: TInt: Symbian error code + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestScripter::GetTestScriptObject( const TDesC& aObjectName ) + { + + TTestObjectBase* objBase = GetObject( aObjectName ); + if( ( objBase == NULL ) || + ( objBase->ObjectType() != TTestObjectBase::EObjectNormal ) ) + { + return KErrNotFound; + } + + TTestObject* object = ( TTestObject* )objBase; + + return (TInt) object->iScript; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: UpdateTestCaseResult + + Description: Updates result of test case. If there is already some + description stored, it is put in the [] brackets. + + Parameters: const TInt aResult: in: error code + const TDesC& aDescr: in: description + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::UpdateTestCaseResult(const TInt aResult, const TDesC& aDescr) + { + // Create buffer + RBuf buf; + + TInt ret = buf.Create(iResult.iResultDes.Length() + aDescr.Length() + 5); + if(ret != KErrNone) + { + __TRACE(KError, (_L("UpdateResultDescription: descriptor creation failed [%d]"), ret)); + return; + } + CleanupClosePushL(buf); + + // Update result + iResult.iResult = aResult; + if(iResult.iResultDes.Length() > 0) + { + buf.Format(_L("%S [%S]"), &aDescr, &iResult.iResultDes); + } + else + { + buf.Copy(aDescr); + } + + SetResultDescription(buf); + + // Close buffer + CleanupStack::PopAndDestroy(&buf); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: SetResultDescription + + Description: Sets result description of test case. + + Parameters: const TDesC& aDescr: in: new description + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +EXPORT_C void CTestScripter::SetResultDescription(const TDesC& aDescr) + { + if(aDescr.Length() > KStifMaxResultDes) + { + iResult.iResultDes.Copy(aDescr.Mid(0, KStifMaxResultDes)); + } + else + { + iResult.iResultDes.Copy(aDescr); + } + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: SetLocalValue + + Description: Internal fuction to set value of local variable defined in script + + Parameters: const TDesC& aName: in: local variable name + const TDesC& avalue: in: local variable value + + Return Values: KErrNone: Value is returned succesfully. + KErrNotFound: Variable was not found + Any other SymbianOS error + +------------------------------------------------------------------------------- +*/ +EXPORT_C TInt CTestScripter::SetLocalValue(const TDesC& aName, const TDesC& aValue) + { + __TRACEFUNC(); + + TInt count = iDefinedLocal.Count(); + for(TInt i = 0; i < count; i++) + { + if(iDefinedLocal[i]->Name() == aName) + { + iDefinedLocal[i]->SetValueL(const_cast(aValue)); + return KErrNone; + } + } + + return KErrNotFound; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: GetLocalValue + + Description: Internal fuction to get value of local variable + + Parameters: const TDesC& aName: in: local variable name + const TDesC& avalue: in: local variable value + + Return Values: KErrNone: Value is returned succesfully. + KErrNotFound: Variable was not found + Any other SymbianOS error + +------------------------------------------------------------------------------- +*/ +EXPORT_C TInt CTestScripter::GetLocalValue(const TDesC& aName, TDes& aValue) + { + __TRACEFUNC(); + + TInt count = iDefinedLocal.Count(); + for(TInt i = 0; i < count; i++) + { + if(iDefinedLocal[i]->Name() == aName) + { + aValue.Copy(iDefinedLocal[i]->Value()); + return KErrNone; + } + } + + return KErrNotFound; + } + +TBool CompareTBuf(const TBuf& aLeft,const TBuf& aRight) +{ + return aLeft.Compare(aRight) == 0 ? ETrue : EFalse; + +} + +void CTestScripter::Substitute(const TDesC& aSrc,TDes& aDest) +{ + TIdentityRelation > relation(CompareTBuf); + + + + + + + + + + TInt fileindex=aSrc.Find(KFileFlag); + TInt sectionindex=aSrc.Find(KSectionFlag); + TInt keyindex=aSrc.Find(KKeyFlag); + TBuf srcbuf; + if(fileindex==KErrNotFound&§ionindex==KErrNotFound&&keyindex!=KErrNotFound) + { + srcbuf.Append(KFileFlag); + srcbuf.Append(iCurrentFileAlias); + srcbuf.Append(KSectionFlag); + srcbuf.Append(iCurrentSectionFileAlias); + + srcbuf.Append(aSrc); + + } + else if(fileindex==KErrNotFound&§ionindex!=KErrNotFound&&keyindex!=KErrNotFound) + { + srcbuf.Append(KFileFlag); + srcbuf.Append(iCurrentFileAlias); + + + srcbuf.Append(aSrc); + + } + else + { + srcbuf.Append(aSrc); + } + + + TInt index=iKeys.Find(srcbuf,relation); + if(index==KErrNotFound) + { + + aDest.Append(aSrc); + } + else + { + + aDest.Append(iValues[index]); + } + +} + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: AddTestObjToDictL + + Description: Add Test Object to dictionary + + Parameters: TTestObject* aObject: in: test object + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::AddTestObjToScripterDictL(TTestObject* aObject) + { + __TRACEFUNC(); + + User::LeaveIfNull( (TAny*)aObject ); + + TInt count = iGlobalObjects.Count(); + for (TInt i = 0; i < count; i++) + { + if (iGlobalObjects[i]->ObjectId() == aObject->ObjectId()) + { + // Found testcase with specified TestId + return; + } + } + + User::LeaveIfError( iGlobalObjects.Append(aObject) ); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: DelTestObjFromDict + + Description: delete Test Object from dictionary + + Parameters: const TDesC& aObjectId: in: id + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestScripter::DelTestObjFromScripterDict(const TDesC& aObjectId) + { + __TRACEFUNC(); + + TInt count = iGlobalObjects.Count(); + for (TInt i = 0; i < count; i++) + { + if (iGlobalObjects[i]->ObjectId() == aObjectId) + { + // Found testcase with specified TestId + TTestObject *object = (TTestObject*) iGlobalObjects[i]; + iGlobalObjects.Remove(i); + TInt count2 = iSharedTestModules.Count(); + for (TInt j = 0; j < count2; j++) + { + if (iSharedTestModules[j]->ModuleName() == object->iModule) + { + delete object; + TestModuleIf().iNumberInGlbDict--; + iSharedTestModules[j]->Del(); + if (iSharedTestModules[j]->RefCount() <= 0) + { + TestModuleIf().iNumberInGlbDict--; + } + delete iSharedTestModules[j]; + iSharedTestModules.Remove(j); + break; + } + } + if(iSharedTestModules.Count() == 0) + { + iSharedTestModules.Reset(); + } + if(iGlobalObjects.Count() == 0) + { + iGlobalObjects.Reset(); + } + return; + } + } + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + Method: GetTestObjFromDict + + Description: delete Test Object from dictionary + + Parameters: const TDesC& aObjectId: in: id + + Return Values: TTestObject* : pointer to TTestObject + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TTestObject* CTestScripter::GetTestObjFromScripterDict(const TDesC& aObjectId) const + { + __TRACEFUNC(); + + TInt count = iGlobalObjects.Count(); + for (TInt i = 0; i < count; i++) + { + if (iGlobalObjects[i]->ObjectId() == aObjectId) + { + // Found testcase with specified TestId + return iGlobalObjects[i]; + } + } + + return NULL; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestScripter + + 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 CTestScripter::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); + } + } + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains the implementation of CTestRunner class + member functions. CTestRunner is used to execute TestScripter testcase by + CTestScripter. + +------------------------------------------------------------------------------- +*/ +// MACROS +#ifdef LOGGER +#undef LOGGER +#endif +#define LOGGER iTestScripter->iLog + +// ================= MEMBER FUNCTIONS ========================================= + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: CTestRunner + + Description: Default constructor + + C++ default constructor can NOT contain any code, that + might leave. + + Parameters: CTestScripter* aTestScripter: in: Backpointer to CTestScripter + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CTestRunner::CTestRunner( CTestScripter* aTestScripter ): + CActive( CActive::EPriorityHigh ), // Executed with highest priority + iState( ERunnerIdle ), + iInternalStateForSubTestCases( EISNotStarted ), + iTestScripter( aTestScripter ), + iRemainingTimeValue( 0 ) + { + 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: Draft + +------------------------------------------------------------------------------- +*/ +void CTestRunner::ConstructL() + { + + iPauseTimer.CreateLocal(); + + // Initiaze all OOM related variables to default. + OOMHeapToNormal(); + + iLoopHelper = CLoopHelper::NewL( this ); + + iSlavesManager = CSlavesManager::NewL( this, iTestScripter->TestModuleIf() ); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: NewL + + Description: Two-phased constructor. + + Parameters: CTestScripter* aTestScripter: in: Backpointer to CTestScripter + + Return Values: CTestRunner*: new object + + Errors/Exceptions: Leaves if new or ConstructL leaves + + Status: Draft + +------------------------------------------------------------------------------- +*/ + +CTestRunner* CTestRunner::NewL( CTestScripter* aTestScripter ) + { + CTestRunner* self = new (ELeave) CTestRunner( aTestScripter ); + + 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(); + + iPauseTimer.Close(); + + delete iLine; + iLine = NULL; + + delete iLoopHelper; + iLoopHelper = NULL; + + iSubTestCases.ResetAndDestroy(); + iSubTestCases.Close(); + + delete iTestIdForComplete; + iTestIdForComplete = NULL; + + delete iFailedSubTestCaseInfo; + iFailedSubTestCaseInfo = NULL; + + TInt count = iEventArray.Count(); + TEventIf event( TEventIf::ERelEvent ); + for( TInt i = 0; i < count; i++ ) + { + HBufC* tmp = iEventArray[0]; + event.SetName( iEventArray[0]->Des() ); + iEventArray.Remove(0); + if( iTestScripter != NULL ) + { + iTestScripter->TestModuleIf().Event( event ); + } + delete tmp; + } + + iTestCaseResults.Reset(); + iEventArray.ResetAndDestroy(); + iTestCaseResults.Close(); + iEventArray.Close(); + + delete iSlavesManager; + iSlavesManager = NULL; + + // Reset test case allow result to CTestModuleIf side too. This is + // used in TAL-TA5L macro handling. + if( iTestScripter != NULL ) + { + User::LeaveIfError( + iTestScripter->TestModuleIf().ResetAllowResult() ); + } + + // Stop all remaining interference object + TInt count_inter = iTestInterferenceArray.Count(); + for( TInt a = 0; a < count_inter; a++ ) + { + if( iTestInterferenceArray[a] != NULL ) + { + iTestInterferenceArray[a]->iInterference->Stop(); + } + } + iTestInterferenceArray.ResetAndDestroy(); + iTestInterferenceArray.Close(); + + // Stop all remaining measurement modules + const TInt count_meas = iTestMeasurementArray.Count(); + for( TInt b = 0; b < count_meas; b++ ) + { + if( iTestMeasurementArray[b] != NULL ) + { + iTestMeasurementArray[b]->iMeasurement->Stop(); + } + } + iTestMeasurementArray.ResetAndDestroy(); + iTestMeasurementArray.Close(); + iPlugins.ResetAndDestroy(); + iPlugins.Close(); + iPluginnames.ResetAndDestroy(); + iPluginnames.Close(); + iLibrary.Close(); + + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: RunL + + Description: Derived from CActive, handles testcase execution. + + Parameters: None. + + Return Values: None. + + Errors/Exceptions: Leaves on error situations. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestRunner::RunL() + { + __TRACEFUNC(); + __TRACE( KMessage, (_L("CTestRunner::RunL: [%d] "), iStatus.Int() )); + + if ( iInternalStateForSubTestCases == EISNotStarted ) + { + iInternalStateForSubTestCases = EISRuning; + } + + // Check if we need to Pause test case again + if( iStatus == KErrNone && iRemainingTimeValue > 0 ) + { + // Maximum time for one RTimer::After request + TInt maximumTime = KMaxTInt / 1000; + + __TRACE( KMessage, (_L("CTestRunner::RunL: Going to reissue After request ") ) ); + __TRACE( KMessage, (_L("CTestRunner::RunL: iRemainingTimeValue = %d"), iRemainingTimeValue ) ); + + if( iRemainingTimeValue < maximumTime ) + { + iPauseTimer.After( iStatus, ( iRemainingTimeValue * 1000 ) ); + iRemainingTimeValue = 0; + } + else + { + iRemainingTimeValue -= maximumTime; + iPauseTimer.After( iStatus, ( maximumTime * 1000 ) ); + } + SetActive(); + } + else + { + TBool continueTask = EFalse; + + User::LeaveIfError( iStatus.Int() ); + + if( ( iTestScripter == NULL ) || + ( iTestScripter->iCurrentParser == NULL ) ) + { + __TRACE( KError, (_L("CTestRunner invalid arguments"))); + User::Leave( KErrGeneral ); + } + + iState = ERunnerIdle; + + // Get next execution line from configuration section + TPtrC line; + // If current parser already has read the first line, then read next line. + // Otherwise read the first line. + if(iTestScripter->iCurrentParserReadFirstLine && iTestScripter->iCurrentParser->GetNextLine(line) == KErrNone + || !iTestScripter->iCurrentParserReadFirstLine && iTestScripter->iCurrentParser->GetLine(KNullDesC, line) == KErrNone) + { + iTestScripter->iCurrentParserReadFirstLine = ETrue; + + // Got new execution line + __TRACE( KMessage, (_L("Executing line [%S]"), &line)); + + CStifItemParser* item = PreprocessLineL( line ); + + CleanupStack::PushL( item ); + + TPtrC keyword; + // Get first word from line, i.e. keyword + User::LeaveIfError( item->GetString( _L(""), keyword ) ); + + __TRACE( KMessage, (_L("CTestRunner execute %S"), &keyword )); + + // Execute script line + continueTask = ExecuteLineL( keyword, item ); + __TRACE( KMessage, (_L("CTestRunner %S executed"), &keyword )); + + if( continueTask ) + { + __TRACE( KMessage, (_L("RunL: continueTask"))); + // Set CTestRunner active again to perform + // next execution line + // from testcase section + SetRunnerActive(); + } + + CleanupStack::PopAndDestroy( item ); + } + else // Stop execution if end of test case + { + __TRACE( KMessage, (_L("Executing line: no more lines from this section"))); + // There is no more lines in current parser, but it needs to be + // checked if the parser is not taken for function (sub). + // If this is true, then we have to get back to the parser which + // has called the function. + TInt lastParserIndex = iTestScripter->iParserStack.Count() - 1; + if(lastParserIndex >= 0) + { + // Delete current (the last one) parser + delete iTestScripter->iParserStack[lastParserIndex]; + iTestScripter->iParserStack.Remove(lastParserIndex); + if(lastParserIndex >= 1) //There is some other parser on the stack + { + iTestScripter->iCurrentParser = iTestScripter->iParserStack[lastParserIndex - 1]; + } + else //The parser stack is empty + { + iTestScripter->iCurrentParser = iTestScripter->iSectionParser; + } + __TRACE(KMessage, (_L("Returning to calling parser stored on section stack"))); + + // Continue with the test case + __TRACE(KMessage, (_L("RunL: continueTask (end of Sub reached)"))); + SetRunnerActive(); + return; + } + // No more execution lines in testcase section + // Check if there are running test cases + if ( iSubTestCases.Count() > 0 ) + { + if ( iInternalStateForSubTestCases != EISFinishedWaitingForSubTestCases ) + { + iInternalStateForSubTestCases = EISFinishedWaitingForSubTestCases; + } + // Continue with the test case + // proper sub test case runner should activate test runner + return; + } + + iInternalStateForSubTestCases = EISFinished; + + + // Release remote resources + RPointerArray& slaves = iSlavesManager->GetSlaves(); + + while ( slaves.Count() > 0 ) + { + slaves[ 0 ]->WaitForSubTestCasesL(); + + RPointerArray& slaveEvents = slaves[ 0 ]->GetEvents(); + for ( TInt k = 0; k < slaveEvents.Count(); k++ ) + { + iSlavesManager->EventReleaseL( slaves[ 0 ], slaveEvents[ k ]->Name() ); + } + slaveEvents.ResetAndDestroy(); + + iSlavesManager->SlaveFreeL( slaves[ 0 ]->GetName() ); + } + + __TRACE( KMessage, + (_L("CTestRunner::RunL: Testcase script done") )); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, + _L("RunL"), _L("Script done")); + + + __TRACE( KMessage, + (_L("RunL: All TestCases done, stop CActiveScheduler"))); + CActiveScheduler::Current()->Stop(); + // Now testcase section is executed, + // so CTestRunner has done its job and stops + } + } + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: DoCancel + + Description: Derived from CActive handles the Cancel + + Parameters: None. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestRunner::DoCancel() + { + __TRACEFUNC(); + __TRACE( KMessage, (_L("CTestRunner::DoCancel"))); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), _L("DoCancel")); + + iPauseTimer.Cancel(); + + CActiveScheduler::Current()->Stop(); + + 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: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestRunner::RunError( TInt aError ) + { + __TRACEFUNC(); + __TRACE( KMessage, (_L("CTestRunner::RunError %d"), aError)); + + if ( iRunErrorMessage.Length() != 0 ) + { + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), + _L("RunError : %S"), &iRunErrorMessage ); + iRunErrorMessage = KNullDesC; + } + else + { + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), + _L("RunError")); + } + + iState = ERunnerError; + + // Return error from here, if none given from execution + if( iTestScripter->iResult.iResult == KErrNone ) + { + iTestScripter->UpdateTestCaseResult(aError, _L("CTestRunner::RunError")); + } + + CActiveScheduler::Current()->Stop(); + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: GetLogger + + Description: Returns TestScripter logger + + Parameters: None + + Return Values: Pointer to TestScripter logger. + + Errors/Exceptions: None. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CStifLogger* CTestRunner::GetLogger() + { + return iTestScripter->iLog; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: PreprocessLineL + + Description: Preprocesses script line + + Parameters: TPtrC& line: in: script line + CStifItemParser*& aItem: out: New CItemParser 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; + TInt ret = 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; + + HBufC* sourceLine = line.AllocL(); + CleanupStack::PushL(sourceLine); + + //Check for local variable definitions + item = CStifItemParser::NewL(sourceLine->Des(), 0, sourceLine->Length()); + CleanupStack::PushL(item); + + ret = item->GetString(KNullDesC, tmp); + TBool isVarDefinition = (tmp == TTestKeywords::Keyword(TTestKeywords::EVar)); + + if(!isVarDefinition) + { + while( ret == KErrNone ) + { + len += CheckDefinedLocals(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); + ret = item->GetNextString(tmp); + if(ret == KErrNone) + { + // Add space only if we got new string + parsedLine.Append(_L(" ")); + } + } + CleanupStack::PopAndDestroy(item); + item = NULL; + CleanupStack::PopAndDestroy(sourceLine); + sourceLine = NULL; + + //Prepare data for checking for defines + sourceLine = parsedLine.AllocL(); + CleanupStack::PushL(sourceLine); + parsedLine.Zero(); + + item = CStifItemParser::NewL(sourceLine->Des(), 0, sourceLine->Length()); + CleanupStack::PushL(item); + + ret = item->GetString(KNullDesC, tmp); + } + + //Check for defines + while(ret == KErrNone) + { + if(!isVarDefinition) + { + 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); + ret = item->GetNextString(tmp); + if( ret == KErrNone ) + { + // Add space only if we got new string + parsedLine.Append(_L(" ")); + } + } + + //Cleaning... + CleanupStack::PopAndDestroy(item); + item = NULL; + CleanupStack::PopAndDestroy(sourceLine); + sourceLine = NULL; + + __TRACE(KMessage, (_L("Preprocessed line [%S]"), &parsedLine)); + 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 diference between new and old word + + Errors/Exceptions: None. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestRunner::CheckDefined( TPtrC& aWord ) + { + + TInt len = 0; + TInt i = 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; + } + + // First, check values defined in test case file + TInt count = iTestScripter->iDefinedRuntime.Count(); + for( i = 0; i < count; i++ ) + { + if( iTestScripter->iDefinedRuntime[i]->Name() == aWord ) + { + len = iTestScripter->iDefinedRuntime[i]->Value().Length() - aWord.Length(); + aWord.Set( iTestScripter->iDefinedRuntime[i]->Value() ); + return len; + } + } + + // Second, check values defined in test module initialization file + count = iTestScripter->iDefinedIni.Count(); + for( i = 0; i < count; i++ ) + { + if( iTestScripter->iDefinedIni[i]->Name() == aWord ) + { + len = iTestScripter->iDefinedIni[i]->Value().Length() - aWord.Length(); + aWord.Set( iTestScripter->iDefinedIni[i]->Value() ); + return len; + } + } + + return len; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: CheckDefinedLocals + + Description: Check if aWord is a local variable + + Parameters: TPtrC& aWord: inout: Parsed word, defined or original returned + + Return Values: TInt: length diference between new and old word + + Errors/Exceptions: None. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestRunner::CheckDefinedLocals( TPtrC& aWord ) + { + + TInt len = 0; + TInt i = 0; + + TInt count = iTestScripter->iDefinedLocal.Count(); + for(i = 0; i < count; i++) + { + if(iTestScripter->iDefinedLocal[i]->Name() == aWord) + { + len = iTestScripter->iDefinedLocal[i]->Value().Length() - aWord.Length(); + aWord.Set(iTestScripter->iDefinedLocal[i]->Value()); + return len; + } + } + + return len; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: ExecuteLineL + + Description: Executes script line + + Parameters: TDesC& aKeyword: in: keyword string + 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::ExecuteLineL( TDesC& aKeyword, + CStifItemParser* aItem ) + { + _LIT( KErrMsgDeleteNoParam, "Delete: Name of object is not defined" ); + _LIT( KErrMsgDeleteObjNotFound, "Delete: Can't delete object %S. Object does not exists." ); + _LIT( KErrMsgPauseTimeoutNotDefined, "Pause: No timeout value given or value has invalid format" ); + _LIT( KErrMsgPauseTimeoutNotPositive, "Pause: Timeout value can't be <0" ); + _LIT( KErrMsgCreateTestModeleNotDefined, "Create: Name of test module is not defined" ); + _LIT( KErrMsgCreateObjectIdNotDefined, "Create: Name of test module object is not defined" ); + _LIT( KErrMsgCreateKernelDriverNotDefined, "CreateKernel: Kernel driver name is not defined" ); + _LIT( KErrMsgCreateKernelObjectNameNotDefined, "CreateKernel: Kernel driver object name is not defined" ); + _LIT( KErrMsgCreateKernelFailed, "CreateKernel: Can't creeate kernel driver %S" ); + _LIT( KErrMsgWaitTestClassNameNotDefined, "WaitTestClass: Test class object name is not defined" ); + _LIT( KErrMsgWaitTestClassObjNotFound, "WaitTestClass: Test class object %S does not exists" ); + _LIT( KErrMsgBringToForegroundNotSupported, "BringToForeground: BringToForeground is not supported in non s60 environment" ); + _LIT( KErrMsgSendToBackgroundNotSupported, "SendToBackground: SendToBackground is not supported in non s60 environment" ); + _LIT( KErrMsgPressKeyNotSupported, "PressKey: PressKey is not supported in non s60 environment. Check if .cfg file name contains ui_ prefix and UITestingSupport= YES entry is defined in TestFrameworkd.ini" ); + _LIT( KErrMsgTypeTextNotSupported, "TypeText: TypeText is not supported in non s60 environment. Check if .cfg file name contains ui_ prefix and UITestingSupport= YES entry is defined in TestFrameworkd.ini" ); + _LIT( KErrMsgSendPointerEventNotSupported, "SendPointerEvent: SendPointerEvent is not supported in non s60 environment. Check if .cfg file name contains ui_ prefix and UITestingSupport= YES entry is defined in TestFrameworkd.ini" ); + _LIT( KErrVarNameError, "Variable: Could not get variable name"); + _LIT( KErrVarValueError, "Variable: Value too long"); + _LIT( KErrSubNameError, "Sub: Could not get name of Sub to be called"); + _LIT( KErrSubGetError, "Sub: Could not get Sub section"); + + TPtrC temp; + RBuf buf; + buf.Create(512); + CleanupClosePushL(buf); + buf.Append(aKeyword); + buf.Append(_L(" ")); + while(aItem->GetNextString(temp)==KErrNone) + { + + + RBuf tempbuf; + tempbuf.Create(512); + iTestScripter->Substitute(temp,tempbuf); + buf.Append(tempbuf); + + buf.Append(_L(" ")); + tempbuf.Close(); + } + + delete aItem; + aItem=NULL; + + temp.Set((TUint16 *)buf.Ptr(),buf.Length()); + aItem=CStifItemParser::NewL(temp,0,temp.Length()); + + aItem->GetString(KNullDesC,temp); + + + iRunErrorMessage = KNullDesC; + TBool continueTask = ETrue; + + TInt key = TTestKeywords::Parse( aKeyword, TTestKeywords::Keyword ); + + switch( key ) + { + // Test case execution control cases + case TTestKeywords::ECreate: + case TTestKeywords::ECreateX: + case TTestKeywords::ECreateShareObj: + { + TPtrC tmp; + TName module; + + // Testmodule name + TInt ret = aItem->GetNextString( tmp ); + + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgCreateTestModeleNotDefined; + User::Leave( KErrArgument ); + } + TParse p; + p.Set( tmp, NULL, NULL ); + // Check if exists in module name + if( p.ExtPresent() ) + { + module.Copy( tmp ); + } + else + { + // No extension in module name, add it here + _LIT( KDllExtension, ".dll"); + module.Copy( tmp ); + module.Append( KDllExtension ); + } + + // objectid + ret = aItem->GetNextString( tmp ); + + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgCreateObjectIdNotDefined; + User::Leave( KErrArgument ); + } + + __TRACE( KMessage, (_L("%S %S"), &aKeyword, &tmp)); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), + _L("%S %S"), &aKeyword, &tmp); + + if( TTestKeywords::ECreateShareObj == key ) + { + iTestScripter->CreateShareObjectL( module, tmp ); + } + else + { + iTestScripter->CreateObjectL( module, tmp ); + } + } + break; + case TTestKeywords::ERestoreShareObj: + { + TPtrC tmp; + + // objectid + TInt ret = aItem->GetNextString( tmp ); + + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgCreateObjectIdNotDefined; + User::Leave( KErrArgument ); + } + + __TRACE( KMessage, (_L("%S %S"), &aKeyword, &tmp)); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), + _L("%S %S"), &aKeyword, &tmp); + + + iTestScripter->RestoreShareObjectL( tmp ); + } + break; + case TTestKeywords::ECreateKernel: + { + TPtrC obj; + TPtrC driver; + + // Testdriver name + TInt ret = aItem->GetNextString( driver ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgCreateKernelDriverNotDefined; + User::Leave( ret ); + } + + // objectid + ret = aItem->GetNextString( obj ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgCreateKernelObjectNameNotDefined; + User::Leave( ret ); + } + + __TRACE( KMessage, (_L("%S %S"), &aKeyword, &obj)); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), + _L("%S %S"), &aKeyword, &obj); + TInt leaveErr = KErrNone; + TRAP( leaveErr, iTestScripter->CreateKernelObjectL( driver, obj )); + if ( leaveErr != KErrNone ) + { + iRunErrorMessage.Format( KErrMsgCreateKernelFailed, &driver ); + User::Leave( leaveErr ); + } + } + break; + case TTestKeywords::EDelete: + { + TPtrC tmp; + // objectid + TInt ret = aItem->GetNextString( tmp ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgDeleteNoParam; + User::Leave( ret ); + } + + __TRACE( KMessage, (_L("%S %S"), &aKeyword, &tmp)); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), + _L("%S %S"), &aKeyword, &tmp); + + ret = iTestScripter->DeleteObjectL( tmp ); + if ( ret != KErrNone ) + { + iRunErrorMessage.Format( KErrMsgDeleteObjNotFound, &tmp ); + User::Leave( ret ); + } + } + break; + case TTestKeywords::EDeleteShareObj: + { + TPtrC tmp; + // objectid + TInt ret = aItem->GetNextString( tmp ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgDeleteNoParam; + User::Leave( ret ); + } + + __TRACE( KMessage, (_L("%S %S"), &aKeyword, &tmp)); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), + _L("%S %S"), &aKeyword, &tmp); + + ret = iTestScripter->DeleteScripterObjectL( tmp ); + if(ret) + { + iRunErrorMessage.Format( KErrMsgDeleteObjNotFound, &tmp ); + User::Leave( ret ); + } + } + break; + case TTestKeywords::ERun: + continueTask = ExecuteRunL( aItem ); + break; + case TTestKeywords::ECancelIfError: + iCancelIfError = ETrue; + break; + case TTestKeywords::EComplete: + continueTask = ExecuteCompleteL( aItem ); + break; + case TTestKeywords::EPauseTest: + continueTask = ControlSubTestCaseL( TTestKeywords::EPauseTest, aItem ); + break; + case TTestKeywords::EResume: + continueTask = ControlSubTestCaseL( TTestKeywords::EResume, aItem ); + break; + case TTestKeywords::ECancel: + continueTask = ControlSubTestCaseL( TTestKeywords::ECancel, aItem ); + break; + case TTestKeywords::ERequest: + case TTestKeywords::EWait: + case TTestKeywords::ERelease: + case TTestKeywords::ESet: + case TTestKeywords::EUnset: + continueTask = ExecuteEventL( aKeyword, aItem ); + break; + case TTestKeywords::EPrint: + { + __TRACE( KMessage, (_L("%S"), &aKeyword)); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Runner"), + _L("%S"), &aKeyword ); + + RBuf buf; + buf.CreateL(1024); + CleanupClosePushL(buf); + + TPtrC tmp; + + while( aItem->GetNextString( tmp ) == KErrNone ) + { + if( buf.Length() + tmp.Length() >= buf.MaxLength() ) + { + buf.ReAllocL(buf.MaxLength() + tmp.Length() * 10); + } + buf.Append( tmp ); + buf.Append( _L(" ") ); + } + + iTestScripter->TestModuleIf().Printf( KPrintPriNorm, + _L("Test"), + _L("%S"), &buf); + RDebug::Print( _L("Print : Test : %S"), &buf ); + CleanupStack::PopAndDestroy(&buf); + } + break; + case TTestKeywords::EAllowNextResult: + { + AddTestCaseResultL( aItem ); + } + break; + case TTestKeywords::EExpectedPanic: + { + AddTestCasePanicL( aItem ); + } + break; + case TTestKeywords::EWaitTestClass: + { + // Just stop script running, continue event is signaled + // from test class with specified object name + TPtrC objectName; + // Get Object name + TInt ret = aItem->GetNextString( objectName ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgWaitTestClassNameNotDefined; + User::Leave( ret ); + } + TTestObjectBase* obj = iTestScripter->GetObject ( objectName ); + //User::LeaveIfNull( obj ); + if( obj == NULL ) + { + iRunErrorMessage.Format( KErrMsgWaitTestClassObjNotFound, &objectName ); + User::Leave( KErrGeneral ); + } + continueTask = obj->Wait(); + + if( continueTask ) + { + // If OOM testing is ongoing ignore result check(given by user) + if( !iTestScripter->iOOMIgnoreFailure ) + { + if( iTestCaseResults.Count() == 0 ) + { + // KErrNone is the default result expected + // if nothing else is given + User::LeaveIfError( iTestCaseResults.Append( + KErrNone ) ); + } + + if( iTestCaseResults.Find( obj->iAsyncResult ) < 0 ) + { + __TRACE( KError, ( _L("Command for [%S] failed (%d)"), + &objectName, obj->iAsyncResult )); + iTestScripter->UpdateTestCaseResult(obj->iAsyncResult, _L("CTestRunner::ExecuteLineL: asynchronous method returned error")); + // Stops execution from CTestRunner::RunError + User::Leave( KErrGeneral ); + } + } + else + { + __TRACE( KMessage, ( + _L( "OOM test: 'oomignorefailure' is ON, test case result will reset" ) ) ); + } + + iTestCaseResults.Reset(); + // Reset test case allow result to CTestModuleIf side too. This is + // used in TAL-TA5L macro handling. + User::LeaveIfError( + iTestScripter->TestModuleIf().ResetAllowResult() ); + } + + } + break; + case TTestKeywords::EPause: + { + // Maximum time for one RTimer::After request + TInt maximumTime = KMaxTInt / 1000; + // Set iRemainingTimeValue to zero + iRemainingTimeValue = 0; + + TInt timeout; + // Read valid results to timeout + if( aItem->GetNextInt( timeout ) != KErrNone ) + { + __TRACE( KError, (_L("CTestRunner::ExecuteLineL: No timeout value given for pause"))); + iRunErrorMessage = KErrMsgPauseTimeoutNotDefined; + User::Leave( KErrArgument ); + } + + // Test case file parsing was success + + __TRACE( KMessage, (_L("CTestRunner::ExecuteLineL: Pause for %d milliseconds"), timeout)); + + if( timeout < 0 ) + { + __TRACE( KError, (_L("CTestRunner::ExecuteLineL: Given pause value < 0"))); + iRunErrorMessage = KErrMsgPauseTimeoutNotPositive; + User::Leave( KErrArgument ); + } + else + { + // Check is pause value suitable for RTimer::After + if( timeout < maximumTime ) + { + iPauseTimer.After( iStatus, ( timeout * 1000 ) ); + } + else + { + // Given pause value after multiplication with 1000 is + // larger than KMaxTInt, so we need to split it and + // re-request After with remaining value from RunL + + iRemainingTimeValue = timeout - maximumTime; + iPauseTimer.After( iStatus, maximumTime * 1000 ); + } + + SetActive(); + + // Stop execution after paused for given timeout + continueTask = EFalse; + } + } + break; + case TTestKeywords::EAllocate: + continueTask = ExecuteAllocateL( aItem ); + break; + case TTestKeywords::EFree: + continueTask = ExecuteFreeL( aItem ); + break; + case TTestKeywords::ERemote: + continueTask = ExecuteRemoteL( aItem ); + break; + case TTestKeywords::ELoop: + continueTask = ExecuteLoopL( aItem ); + break; + case TTestKeywords::EEndLoop: + continueTask = ExecuteEndLoopL( aItem ); + break; + case TTestKeywords::ETimeout: + case TTestKeywords::EPriority: + // not used here + break; + case TTestKeywords::EOOMIgnoreFailure: + { + OOMIgnoreFailureL( aItem ); // Handle parsing + break; + } + case TTestKeywords::EOOMHeapFailNext: + { + OOMHeapFailNextL( aItem ); // Handle parsing + break; + } + case TTestKeywords::EOOMHeapSetFail: + { + OOMHeapSetFailL( aItem ); // Handle parsing + break; + } + case TTestKeywords::EOOMHeapToNormal: + { + // Initialize all OOM related variables back to default. + OOMHeapToNormal(); + __TRACE( KMessage, ( + _L( "'oomheaptonormal' called, OOM initialization or ending OOM test") ) ); + break; + } + case TTestKeywords::ETestInterference: + { + TestInterferenceL( aItem ); // Handle parsing + break; + } + case TTestKeywords::EMeasurement: + { + MeasurementL( aItem ); // Handle parsing + break; + } + case TTestKeywords::EAllowErrorCodes: + { + // Check is KErrNone already appended to iTestCaseResults array. + if( iTestCaseResults.Find( KErrNone ) < 0 ) + { + // 'allowerrorcodes' keyword sets KErrNone as a default + User::LeaveIfError( iTestCaseResults.Append( KErrNone ) ); + // Set test case allow result to CTestModuleIf side too. This + // is used in TAL-TA5L macro handling. + User::LeaveIfError( + iTestScripter->TestModuleIf().SetAllowResult( KErrNone ) ); + } + + // Set user given specific error code to be allowed. + AddTestCaseResultL( aItem ); + } + break; + + case TTestKeywords::EBringToForeground: + { + if ( iTestScripter->TestModuleIf().UITesting() == true ) + { + iTestScripter->TestModuleIf().GetUiEnvProxy()->BringToForeground(); + } + else + { + __TRACE( KError, (_L("ExecuteLineL: Can't execute bringtoforeground in non s60 environment. Check if .cfg file name contains ui_ prefix and UITestingSupport= YES entry is defined in TestFrameworkd.ini"))); + iRunErrorMessage = KErrMsgBringToForegroundNotSupported; + User::Leave( KErrNotSupported ); + } + } + break; + case TTestKeywords::ESendToBackground: + { + if ( iTestScripter->TestModuleIf().UITesting() == true ) + { + iTestScripter->TestModuleIf().GetUiEnvProxy()->SendToBackground(); + } + else + { + __TRACE( KError, (_L("ExecuteLineL: Can't execute sendtobackground in non s60 environment. Check if .cfg file name contains ui_ prefix and UITestingSupport= YES entry is defined in TestFrameworkd.ini"))); + iRunErrorMessage = KErrMsgSendToBackgroundNotSupported; + User::Leave( KErrNotSupported ); + } + } + break; + case TTestKeywords::EPressKey: + { + if ( iTestScripter->TestModuleIf().UITesting() == true ) + { + continueTask = PressKeyL( aItem ); + } + else + { + __TRACE( KError, (_L("ExecuteLineL: Can't execute presskey in non s60 environment. Check if .cfg file name contains ui_ prefix and UITestingSupport= YES entry is defined in TestFrameworkd.ini"))); + iRunErrorMessage = KErrMsgPressKeyNotSupported; + User::Leave( KErrNotSupported ); + } + + // Check if it was global or local presskey + if ( !continueTask ) + { + // Stop execution after key is pressed and wait until it is handled + SetActive(); + } + } + break; + case TTestKeywords::ETypeText: + { + if ( iTestScripter->TestModuleIf().UITesting() == true ) + { + continueTask = TypeTextL( aItem ); + } + else + { + __TRACE( KError, (_L("ExecuteLineL: Can't execute typetext in non s60 environment. Check if .cfg file name contains ui_ prefix and UITestingSupport= YES entry is defined in TestFrameworkd.ini"))); + iRunErrorMessage = KErrMsgTypeTextNotSupported; + User::Leave( KErrNotSupported ); + } + + // Check if it was global or local typetext + if ( !continueTask ) + { + // Stop execution after key is pressed and wait until it is handled + SetActive(); + } + } + break; + case TTestKeywords::EVar: + { + TName name; + TName buf; + TPtrC tmp; + + //Get variable name + if(aItem->GetNextString(tmp) == KErrNone) + { + name.Copy(tmp); + } + else + { + //Error when getting variable name + __TRACE(KError, (_L("ExecuteLineL: Could not read variable name"))); + iRunErrorMessage = KErrVarNameError; + User::Leave(KErrArgument); + } + + //Get value for variable + while(aItem->GetNextString(tmp) == KErrNone) + { + if(buf.Length() + tmp.Length() >= buf.MaxLength()) + { + //Error when getting variable name + __TRACE(KError, (_L("ExecuteLineL: Variable value too long"))); + iRunErrorMessage = KErrVarValueError; + User::Leave(KErrArgument); + } + buf.Append(tmp); + buf.Append(_L(" ")); + } + //Remove last space + if(buf.Length() > 0) + { + buf.SetLength(buf.Length() - 1); + } + + //Store local variable + TInt count = iTestScripter->iDefinedLocal.Count(); + TInt i; + for(i = 0; i < count; i++) + { + if(iTestScripter->iDefinedLocal[i]->Name() == name) + { + // Update existing + iTestScripter->iDefinedLocal[i]->SetValueL(buf); + __TRACE(KMessage, (_L("Update local variable [%S]: [%S]"), &name, &buf)); + break; + } + } + if(i == count) + { + // New define, store it + CDefinedValue* define = CDefinedValue::NewL(name, buf); + CleanupStack::PushL(define); + User::LeaveIfError(iTestScripter->iDefinedLocal.Append(define)); + CleanupStack::Pop(define); + __TRACE(KMessage, (_L("Add local variable [%S]: [%S]"), &name, &buf)); + } + } + break; + case TTestKeywords::ECallSub: + { + // Get sub name + TPtrC subName; + + //Get sub name + TInt err = aItem->GetNextString(subName); + if(err != KErrNone) + { + //Error when getting sub name + __TRACE(KError, (_L("ExecuteLineL: Could not read sub name [%d]"), err)); + iRunErrorMessage = KErrSubNameError; + User::Leave(KErrArgument); + } + + // Load section + CStifSectionParser* subSection = NULL; + TRAP(err, + subSection = iTestScripter->GetSubL(subName); + ); + if((err != KErrNone) || (!subSection)) + { + //Error when getting sub name + if(err == KErrNone) + { + err = KErrArgument; + } + __TRACE(KError, (_L("ExecuteLineL: Could not get section for sub [%d]"), err)); + iRunErrorMessage = KErrSubGetError; + User::Leave(err); + } + + // Handle new section parser + CleanupStack::PushL(subSection); + iTestScripter->iParserStack.AppendL(subSection); + __TRACE(KMessage, (_L("ExecuteLineL: Section for sub [%S] appended to section stack"), &subName)); + CleanupStack::Pop(subSection); + iTestScripter->iCurrentParser = subSection; + iTestScripter->iCurrentParserReadFirstLine = EFalse; //Change it to false, becaue subSection is a new parser and it has nothing read + } + break; + case TTestKeywords::ESetResultDescription: + { + __TRACE(KMessage, (_L("%S"), &aKeyword)); + iTestScripter->TestModuleIf().Printf(KPrintPriLow, _L("Runner"), _L("%S"), &aKeyword); + + TName buf; + TPtrC tmp; + + while(aItem->GetNextString(tmp) == KErrNone) + { + if(buf.Length() + tmp.Length() >= buf.MaxLength()) + { + break; + } + if(buf.Length() > 0) + { + buf.Append(_L(" ")); + } + buf.Append(tmp); + } + + iTestScripter->SetResultDescription(buf); + RDebug::Print( _L("SetDescription to [%S]"), &buf ); + } + break; + case TTestKeywords::ESendPointerEvent: + { + if ( iTestScripter->TestModuleIf().UITesting() == true ) + { + continueTask = SendPointerEventL( aItem ); + } + else + { + __TRACE( KError, (_L("ExecuteLineL: Can't execute sendpointerevent in non s60 environment. Check if .cfg file name contains ui_ prefix and UITestingSupport= YES entry is defined in TestFrameworkd.ini"))); + iRunErrorMessage = KErrMsgSendPointerEventNotSupported; + User::Leave( KErrNotSupported ); + } + + // Check if it was global or local sendpointerevent + if ( !continueTask ) + { + // Stop execution after pointer event is send and wait until it is handled + SetActive(); + } + } + break; + case TTestKeywords::EUsing: + { + TInt err; + TPtrC dll; + err=aItem->GetNextString(dll); + err=iLibrary.Load(dll); + + User::LeaveIfError(err); + TLibraryFunction LibEntryL=iLibrary.Lookup(1); + iPlugins.Append((CStfTestLibPlugin*)LibEntryL()); + TPtrC temp; + err=aItem->GetNextString(temp); + HBufC* alias=HBufC::NewL(temp.Length()); + alias->Des().Copy(temp); + iPluginnames.Append(alias); + + break; + } + default: + { + if(ExecuteLibL(aKeyword, aItem)) + { + + } + else + { + continueTask = ExecuteCommandL( aKeyword, aItem ); + } + } + break; + } + + __TRACE( KMessage, (_L("ExecuteLineL: TestCase line executed"))); + CleanupStack::PopAndDestroy(&buf); + 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"))); + iTestScripter->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->GetModuleName(), startInfo->GetTestCaseNumber() ); + + CSubTestCaseRunner* subTestCaseRunner = CLocalSubTestCaseRunner::NewLC( this ); + + __TRACE( KMessage, ( _L( "Executing sub test case: module=%S cfg=%S tcnum=%d id=%S" ), + &startInfo->GetModuleName(), &startInfo->GetConfig(), + startInfo->GetTestCaseNumber(), &startInfo->GetTestId()) ); + + RDebug::Print( _L( "Executing sub test case: module=%S cfg=%S tcnum=%d id=%S" ), + &startInfo->GetModuleName(), &startInfo->GetConfig(), + startInfo->GetTestCaseNumber(), &startInfo->GetTestId() ); + + subTestCaseRunner->RunSubTestCaseL( *startInfo ); + iSubTestCases.AppendL( subTestCaseRunner ); + if ( iLoopHelper->LoopInProgress() ) + { + iLoopHelper->RegisterInLoopSubTestCaseL( subTestCaseRunner ); + } + + CleanupStack::Pop( subTestCaseRunner ); + + iRunErrorMessage = KNullDesC; + + CleanupStack::PopAndDestroy( startInfo ); + + return ETrue; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: ExecuteCompleteL + + Description: Executes complete 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::ExecuteCompleteL( CStifItemParser* aItem ) + { + _LIT( KErrMsgTestIdNotDefined, "%S : testid is not defined" ); + TPtrC testId; + + TInt ret = KErrNone; + + TPtrC keywordStr = TTestKeywords::Keyword( TTestKeywords::EComplete ); + + // Parse testid + ret = aItem->GetNextString( testId ); + if( ret != KErrNone ) + { + iRunErrorMessage.Format( KErrMsgTestIdNotDefined, &keywordStr ); + User::Leave( ret ); + } + + for ( TInt i = 0; i < iSubTestCases.Count(); i++ ) + { + if ( iSubTestCases[ i ]->GetStartInfo()->GetTestId() == testId ) + { + delete iTestIdForComplete; + iTestIdForComplete = testId.AllocL(); + iInternalStateForSubTestCases = EISWaitingForComplete; + return EFalse; + } + } + + 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.GetModuleName() )); + + // 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.GetConfig() )); + + // Check is TestScripter + if( aStartInfo.GetModuleName().Find( KTestScripterName ) != KErrNotFound ) + { + // TestScripter name is format: 'testscripter_testcasefilename' + + TParse parse; + parse.Set( aStartInfo.GetConfig(), 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.SetModuleNameL( testScripterAndTestCaseFile ); + } + + // Testcase number + TInt testCaseNumber; + ret = aItem->GetInt( tmp, testCaseNumber ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgRunTestcaseNumberNotDefined; + User::Leave( ret ); + } + aStartInfo.SetTestCaseNumber( testCaseNumber ); + + __TRACE( KMessage, (_L("testcasenum: %d"), testCaseNumber ) ); + + // 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( TTestKeywords::Parse( arg, TTestKeywords::RunOptArg ) ) + { + case TTestKeywords::EExpect: + { + TLex ptr( val ); + TInt expectedResult; + ret = ptr.Val( expectedResult ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgRunInvalidExpectValue; + User::Leave( ret ); + } + aStartInfo.SetExpectedResult( expectedResult ); + __TRACE( KMessage, (_L("expect=%d"), expectedResult )); + } + break; + case TTestKeywords::ETestid: + { + aStartInfo.SetTestIdL( val ); + __TRACE( KMessage, (_L("TestId=%S"), &val)); + } + break; + case TTestKeywords::EIni: + { + __TRACE( KMessage, (_L("ini=%S"), &val)); + TFileName iniFileName( val ); + TStifUtil::CorrectFilePathL( iniFileName ); + aStartInfo.SetIniFileL( iniFileName ); + } + break; + case TTestKeywords::ECategory: + { + __TRACE( KMessage, (_L("category=%S"), &val)); + aStartInfo.SetExpectedResultCategory( TTestKeywords::GetResultCategory( val ) ); + if( aStartInfo.GetExpectedResultCategory() == TFullTestResult::ECaseOngoing ) + { + __TRACE( KError, (_L("Unknown or illegal result category"))); + //Unknown or illegal category + iRunErrorMessage = KErrMsgRunUnknownOrIllegalCategory; + User::Leave( KErrGeneral ); + } + } + break; + case TTestKeywords::ECaseTimeout: + { + TInt timeout; + TLex ptr( val ); + ret = ptr.Val( timeout ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgRunInvalidTimeoutValue; + User::Leave( ret ); + } + aStartInfo.SetTimeout( timeout ); + __TRACE( KMessage, (_L("timeout=%d"), timeout ) ); + } + break; + case TTestKeywords::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: 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 ); + + } + +TBool CompareTDesC(const TDesC8& aLeft,const TDesC8& aRight) +{ + return aLeft.Compare(aRight) == 0 ? ETrue : EFalse; + +} + + + +/** +* Executes method call to object script line. +*/ +TBool CTestRunner::ExecuteLibL( TDesC& lib, + CStifItemParser* aItem ) +{ + TBool result=EFalse; + TIdentityRelation relation(CompareTDesC); + TInt count=iPluginnames.Count(); + TInt index; + for( index=0;indexDes(); + if(tempptr==lib) + { + TPtrC partcommand; + TBuf<300> commandline; + TBuf<100> command; + result=ETrue; + TInt i=0; + while(aItem->GetNextString(partcommand)==KErrNone) + { + if(i==0) + { + command.Append(partcommand); + } + commandline.Append(partcommand); + commandline.Append(_L(" ")); + i++; + } + commandline.TrimAll(); + if(iPlugins[index]->IsCommandSupported(command)) + + { + iPlugins[index]->ExecuteCommandL(commandline); + } + break; + } + } + return result; +} +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: PressKeyL + + Description: Send key press event to AppUi + + Parameters: CStifItemParser* aItem: in: script line + + Return Values: None + + Errors/Exceptions: Leaves on error situations. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TBool CTestRunner::PressKeyL( CStifItemParser* aItem ) + { + _LIT( KErrMsgSendKeyEventInvalidParameterValue, "PressKey: Invalid parameter %s value " ); + _LIT( KErrMsgSendKeyEventInvalidParameter, "PressKey: Invalid parameter %s" ); + + _LIT( KKeyCodeParameter, "keycode=" ); + _LIT( KKeyScanCodeParameter, "keyscancode=" ); + _LIT( KModifierParameter, "modifier=" ); + _LIT( KRepeatsParameter, "repeats=" ); + + _LIT( KModeGlobal, "global" ); + _LIT( KModeLocal, "local" ); + + TBool globalMode = EFalse; + TUint keyCode = 0; + TInt keyScanCode = 0; + TUint keyModifiers = 0; + TInt keyRepeats = 0; + + TPtrC parameter; + + CUiEnvProxy* uiEnvProxy = iTestScripter->TestModuleIf().GetUiEnvProxy(); + + while( aItem->GetNextString( parameter ) == KErrNone ) + { + if ( parameter.Find( KKeyCodeParameter ) == 0 ) + { + TPtrC parameterValue = parameter.Right( parameter.Length() - KKeyCodeParameter().Length() ); + TLex parameterValueParser( parameterValue ); + if ( parameterValueParser.Val( keyCode ) != KErrNone ) + { + if ( uiEnvProxy->ParseKeyCode( parameterValue, keyCode ) != KErrNone ) + { + __TRACE( KError, (_L("SendKeyEvent: Invalid parameter value"))); + TBuf<128> errMsg; + errMsg.Format( KErrMsgSendKeyEventInvalidParameterValue, &KKeyCodeParameter() ); + iRunErrorMessage = errMsg; + User::Leave( KErrArgument ); + } + } + } + else if ( parameter.Find( KKeyScanCodeParameter ) == 0 ) + { + TPtrC parameterValue = parameter.Right( parameter.Length() - KKeyScanCodeParameter().Length() ); + TLex parameterValueParser( parameterValue ); + if ( parameterValueParser.Val( keyScanCode ) != KErrNone ) + { + if ( uiEnvProxy->ParseKeyScanCode( parameterValue, keyScanCode ) != KErrNone ) + { + __TRACE( KError, (_L("SendKeyEvent: Invalid parameter value"))); + TBuf<128> errMsg; + errMsg.Format( KErrMsgSendKeyEventInvalidParameterValue, &KKeyCodeParameter() ); + iRunErrorMessage = errMsg; + User::Leave( KErrArgument ); + } + } + } + else if ( parameter.Find( KModifierParameter ) == 0 ) + { + TPtrC parameterValue = parameter.Right( parameter.Length() - KModifierParameter().Length() ); + TLex parameterValueParser( parameterValue ); + if ( parameterValueParser.Val( keyModifiers ) != KErrNone ) + { + if ( uiEnvProxy->ParseModifier( parameterValue, keyModifiers ) != KErrNone ) + { + __TRACE( KError, (_L("SendKeyEvent: Invalid parameter value"))); + TBuf<128> errMsg; + errMsg.Format( KErrMsgSendKeyEventInvalidParameterValue, &KModifierParameter() ); + iRunErrorMessage = errMsg; + User::Leave( KErrArgument ); + } + } + } + else if ( parameter.Find( KRepeatsParameter ) == 0 ) + { + TPtrC parameterValue = parameter.Right( parameter.Length() - KRepeatsParameter().Length() ); + TLex parameterValueParser( parameterValue ); + if ( parameterValueParser.Val( keyRepeats ) != KErrNone ) + { + __TRACE( KError, (_L("SendKeyEvent: Invalid parameter value"))); + TBuf<128> errMsg; + errMsg.Format( KErrMsgSendKeyEventInvalidParameterValue, &KRepeatsParameter() ); + iRunErrorMessage = errMsg; + User::Leave( KErrArgument ); + } + } + else if ( parameter == KModeGlobal ) + { + globalMode = ETrue; + } + else if ( parameter == KModeLocal ) + { + globalMode = EFalse; + } + else if ( uiEnvProxy->ParseKeyCode( parameter, keyCode ) == KErrNone ) + { + } + else if ( parameter.Length() == 1 ) + { + keyCode = parameter[ 0 ]; + } + else + { + __TRACE( KError, (_L("PressKey: Invalid parameter"))); + TBuf<128> errMsg; + errMsg.Format( KErrMsgSendKeyEventInvalidParameter, ¶meter ); + iRunErrorMessage = errMsg; + User::Leave( KErrArgument ); + } + } + + if ( globalMode ) + { + uiEnvProxy->PressKeyL( keyCode, keyScanCode, keyModifiers, keyRepeats ); + } + else + { + uiEnvProxy->PressKeyL( &iStatus, keyCode, keyScanCode, keyModifiers, keyRepeats ); + } + + return globalMode; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: TypeTextL + + Description: Sends text to AppUi + + Parameters: CStifItemParser* aItem: in: script line + + Return Values: None + + Errors/Exceptions: Leaves on error situations. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TBool CTestRunner::TypeTextL( CStifItemParser* aItem ) + { + _LIT( KErrMsgTypeTextInvalidParameter, "TypeText: Invalid parameter %S" ); + _LIT( KErrMsgTypeTextNotEnoughParameters, "TypeText: Not enough parameters" ); + + TBool globalMode = EFalse; + + TPtrC command; + TPtrC text; + aItem->SetParsingType( CStifItemParser::EQuoteStyleParsing ); + + // Read first parameter + TInt ret = aItem->GetNextString( command ); + + if ( ret != KErrNone ) + { + __TRACE( KError, (_L("TypeText: Not enough parameters"))); + iRunErrorMessage = KErrMsgTypeTextNotEnoughParameters; + User::Leave( ret ); + } + + // Read second parameter + ret = aItem->GetNextString( text ); + + // Check if second can be read. if yes then check if first parameters is + // 'global' parameter + if ( ret != KErrNone ) + { + // normal type text + text.Set( command ); + iTestScripter->TestModuleIf().GetUiEnvProxy()->TypeTextL( &iStatus, text ); + globalMode = EFalse; + } + else if ( command == _L("global") ) + { + iTestScripter->TestModuleIf().GetUiEnvProxy()->TypeTextL( text ); + globalMode = ETrue; + } + else + { + __TRACE( KError, (_L("TypeText: Invalid parameter"))); + TBuf<128> errMsg; + errMsg.Format( KErrMsgTypeTextInvalidParameter, &command ); + iRunErrorMessage = errMsg; + User::Leave( KErrNotSupported ); + } + + return globalMode; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: SendPointerEventL + + Description: Send key press event to AppUi + + Parameters: CStifItemParser* aItem: in: script line + + Return Values: None + + Errors/Exceptions: Leaves on error situations. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TBool CTestRunner::SendPointerEventL( CStifItemParser* aItem ) + { + // Error messages + _LIT( KErrMsgNotEnoughParameters, "SendPointerEvent: Not enough parameters" ); + _LIT( KErrMsgPointerEventTypeNotDefined, "SendPointerEvent: Pointer event type not defined" ); + _LIT( KErrMsgInvalidUnknownPointerEventType, "SendPointerEvent: Invalid/Unknown pointer event type %S" ); + _LIT( KErrMsgPositionXNotDefined, "SendPointerEvent: x co-ordinate is not defined" ); + _LIT( KErrMsgPositionYNotDefined, "SendPointerEvent: y co-ordinate is not defined" ); + _LIT( KErrMsgPositionXInvalidValue, "SendPointerEvent: Invalid value of x co-ordinate" ); + _LIT( KErrMsgPositionYInvalidValue, "SendPointerEvent: Invalid value of y co-ordinate" ); + + // Parameters keywords + _LIT( KModeGlobal, "global" ); + _LIT( KModeLocal, "local" ); + + TBool globalMode = EFalse; + TUint eventType = 0; + TPoint position( 0, 0 ); + TPoint parentPosition( 0, 0 ); + + TPtrC parameter; + + CUiEnvProxy* uiEnvProxy = iTestScripter->TestModuleIf().GetUiEnvProxy(); + + // Get first parameter + if ( aItem->GetNextString( parameter ) != KErrNone ) + { + __TRACE( KError, (_L("SendPointerEvent: Not enough parameters"))); + iRunErrorMessage = KErrMsgNotEnoughParameters; + User::Leave( KErrArgument ); + } + else + { + TBool modeSelected = EFalse; + // Check if global/local mode is defined + if ( parameter == KModeLocal ) + { + globalMode = false; + modeSelected = ETrue; + } + else if ( parameter == KModeGlobal ) + { + globalMode = true; + modeSelected = ETrue; + } + + if ( modeSelected ) + { + // First parameter was mode so we need get next parameter which should + // contain event type + if ( aItem->GetNextString( parameter ) != KErrNone ) + { + __TRACE( KError, (_L("SendPointerEvent: Pointer event type not defined"))); + iRunErrorMessage = KErrMsgPointerEventTypeNotDefined; + User::Leave( KErrArgument ); + } + } + } + + // Parse event type + if ( uiEnvProxy->ParsePointerEventType( parameter, eventType ) != KErrNone ) + { + __TRACE( KError, (_L("PressKey: Invalid/Unknown pointer event type %S"), ¶meter )); + iRunErrorMessage.Format( KErrMsgInvalidUnknownPointerEventType, ¶meter ); + User::Leave( KErrArgument ); + } + + if ( aItem->GetNextString( parameter ) != KErrNone ) + { + __TRACE( KError, (_L("SendPointerEvent: x co-ordinate is not defined"))); + iRunErrorMessage = KErrMsgPositionXNotDefined; + User::Leave( KErrArgument ); + } + + TLex parameterParser( parameter ); + if ( parameterParser.Val( position.iX ) != KErrNone ) + { + __TRACE( KError, (_L("SendPointerEvent: Invalid value of x co-ordinate"))); + iRunErrorMessage = KErrMsgPositionXInvalidValue; + User::Leave( KErrArgument ); + } + + if ( aItem->GetNextString( parameter ) != KErrNone ) + { + __TRACE( KError, (_L("SendPointerEvent: y co-ordinate is not defined"))); + iRunErrorMessage = KErrMsgPositionYNotDefined; + User::Leave( KErrArgument ); + } + + parameterParser.Assign( parameter ); + if ( parameterParser.Val( position.iY ) != KErrNone ) + { + __TRACE( KError, (_L("SendPointerEvent: Invalid value of y co-ordinate"))); + iRunErrorMessage = KErrMsgPositionYInvalidValue; + User::Leave( KErrArgument ); + } + + // Send pointer event + if ( globalMode ) + { + uiEnvProxy->SendPointerEventL( eventType, position ); + } + else + { + uiEnvProxy->SendPointerEventL( &iStatus, eventType, position ); + } + + return globalMode; + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: ExecuteEventL + + Description: Executes event command script line + + Parameters: TDesC& aKeyword: in: keyword string + 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::ExecuteEventL( TDesC& aKeyword, + CStifItemParser* aItem ) + { + _LIT( KErrMsgEventNameNotDefined, "%S : Event name not defined" ); + _LIT( KErrMsgUnknowKeyword, "Unknow keyword %S" ); + + TInt ret = KErrNone; + TInt key = TTestKeywords::Parse( aKeyword, TTestKeywords::Keyword ); + TBool continueTask = ETrue; + + TPtrC eventName; + // read eventname + ret = aItem->GetNextString( eventName ); + if ( ret != KErrNone ) + { + iRunErrorMessage.Format( KErrMsgEventNameNotDefined, &aKeyword ); + User::Leave( ret ); + } + + TEventIf event; + event.SetName( eventName ); + + __TRACE( KMessage, (_L("%S %S"), &aKeyword, &eventName)); + iTestScripter->TestModuleIf().Printf( KPrintPriLow, _L("Event"), + _L("%S %S"), &aKeyword, &eventName); + + switch( key ) + { + case TTestKeywords::ERequest: + { + HBufC* eName = eventName.AllocLC(); + User::LeaveIfError( iEventArray.Append( eName ) ); + CleanupStack::Pop( eName ); + event.SetType( TEventIf::EReqEvent ); + ret = iTestScripter->TestModuleIf().Event( event ); + } + break; + case TTestKeywords::EWait: + { + event.SetType( TEventIf::EWaitEvent ); + iTestScripter->TestModuleIf().Event( event, iStatus ); + SetActive(); + continueTask = EFalse; + } + break; + case TTestKeywords::ERelease: + { + event.SetType( TEventIf::ERelEvent ); + ret = iTestScripter->TestModuleIf().Event( event ); + if( ret == KErrNone ) + { + TPtrC eName; + TInt count = iEventArray.Count(); + for( TInt i = 0; i < count; i++ ) + { + eName.Set( iEventArray[i]->Des() ); + if( eName == eventName ) + { + HBufC* tmp = iEventArray[i]; + iEventArray.Remove(i); + delete tmp; + break; + } + } + } + } + break; + case TTestKeywords::ESet: + { + event.SetType( TEventIf::ESetEvent ); + + TPtrC tmp; + // Get optional set argument + if( aItem->GetNextString( tmp ) == KErrNone ) + { + // Parse optional set argument + if( tmp == _L("state") ) + { + __TRACE( KMessage, (_L("State event"))); + event.SetEventType( TEventIf::EState ); + } + else + { + __TRACE( KError, + (_L("Unknown argument for set %S"), + &tmp)); + } + } + + ret = iTestScripter->TestModuleIf().Event( event ); + } + break; + case TTestKeywords::EUnset: + { + event.SetType( TEventIf::EUnsetEvent ); + event.SetEventType( TEventIf::EState ); + ret = iTestScripter->TestModuleIf().Event( event ); + } + break; + default: + __TRACE( KError, (_L("Unknown keyword %S"), &aKeyword)); + iRunErrorMessage.Format( KErrMsgUnknowKeyword, &aKeyword ); + User::Leave( KErrGeneral ); + break; + } + if( ret != KErrNone ) + { + TName resultDescr; + resultDescr.Format(_L("Event %S returned error: %d"), &aKeyword, ret); + iTestScripter->UpdateTestCaseResult(ret, resultDescr); + // Stops execution from CTestRunner::RunError + User::Leave( KErrGeneral ); + } + + return continueTask; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: ExecuteCommandL + + Description: Executes script line + + Parameters: TDesC& aObject: in: object name + 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::ExecuteCommandL( TDesC& aObject, CStifItemParser* aItem) + { + _LIT( KErrMsgUnknownObjOrKeyword, "Unknow keyword/object %S" ); + + + TTestObjectBase* obj = iTestScripter->GetObject ( aObject ); + if( obj == NULL ) + { + iRunErrorMessage.Format( KErrMsgUnknownObjOrKeyword, &aObject ); + User::Leave( KErrGeneral ); + } + + if( iTestCaseResults.Count() == 0 ) + { + // KErrNone is the default result expected if nothing else is given + User::LeaveIfError( iTestCaseResults.Append( KErrNone ) ); + } + + // OOM heap testing with FAILNEXT + if( iHeapFailNext > 0 ) + { + __TRACE( KPrint, ( + _L( "OOM FAILNEXT is used with count value: %d " ), + iHeapFailNext) ); + User::__DbgSetAllocFail( RHeap::EUser, RHeap::EFailNext, iHeapFailNext ); + } + // OOM heap testing with SETFAIL + if( iHeapSetFailValue > 0 ) + { + __TRACE( KPrint, ( + _L("OOM SETFAIL is used with type:[%d] and value(rate):[%d]"), + iHeapSetFailType, iHeapSetFailValue ) ); + User::__DbgSetAllocFail( RHeap::EUser, iHeapSetFailType, iHeapSetFailValue ); + } + + TInt commandResult = KErrNone; + TRAP( commandResult, commandResult = obj->RunMethodL( *aItem ) ); + + + // Reset OOM macro immediately(Otherwise other allocations + // will be blocked) + User::__DbgSetAllocFail( RHeap::EUser, RHeap::ENone, 1 ); + + // OOM test class's build block handling + if( iTestScripter->iOOMIgnoreFailure ) + { + __TRACE( KPrint, ( + _L( "----------< OOM related test information >----------" ) ) ); + if( iHeapFailNext > 0 ) + { + __TRACE( KPrint, ( + _L( "'oomignorefailure' is:[ON] and 'failnextvalue' count is:[%d]" ), + iHeapFailNext ) ); + } + if( iHeapSetFailValue > 0 ) + { + __TRACE( KPrint, ( + _L( "'oomignorefailure' is:[ON], 'setfailtype' type is:[%d] and value is:[%d]" ), + iHeapSetFailType, iHeapSetFailValue ) ); + } + __TRACE( KPrint, ( + _L( "Test class build block execution with result:[%d]" ), + commandResult ) ); + __TRACE( KPrint, ( + _L( "----------------------------------------------------" ) ) ); + + // Continue testing, despite the memory error situations + iTestCaseResults.Reset(); + return ETrue; // Continue script executions + } + + // Normal test class's build block handling + if( iTestCaseResults.Find( commandResult ) < 0 ) + { + __TRACE( KError, ( _L("Command for [%S] failed (%d)"), + &aObject, commandResult )); + + // Added more logging for this special case + if( commandResult == KErrNone ) + { + __TRACE( KError, (_L("Test fails with result KErrGeneral, because execution result was KErrNone and expected results given with 'allownextresult' were Symbian's error codes (<0)"))); + } + + iTestScripter->UpdateTestCaseResult(commandResult, _L("CTestRunner::ExecuteCommandL returned error")); + + // Stops execution from CTestRunner::RunError + User::Leave( KErrGeneral ); + } + + iTestCaseResults.Reset(); + // Reset test case allow result to CTestModuleIf side too. This is + // used in TAL-TA5L macro handling. + User::LeaveIfError( + iTestScripter->TestModuleIf().ResetAllowResult() ); + + return ETrue; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: SetRunnerActive + + Description: Set CTestRunner active and complete. + + Parameters: None. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestRunner::SetRunnerActive() + { + __TRACEFUNC(); + // Update state + iState = ERunnerRunning; + + iStatus = KRequestPending; + TRequestStatus* rs = &iStatus; + SetActive(); + User::RequestComplete( rs, KErrNone ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: OOMIgnoreFailure + + Description: Handles 'oomignorefailure' keyword parsing. + + Parameters: CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestRunner::OOMIgnoreFailureL( CStifItemParser* aItem ) + { + _LIT( KerrMsgOOMIgnoreFailureUnknownArgument, "OOMIgnoreFailure : Invalid argument %S" ); + _LIT( KerrMsgOOMIgnoreFailureNoArgument, "OOMIgnoreFailure : Parameter not defined" ); + + __TRACEFUNC(); + + TPtrC tmp; + // Get result + if( aItem->GetNextString( tmp ) == KErrNone ) + { + if( tmp == _L("ON") || tmp == _L("on") ) + { + __TRACE( KMessage, (_L("OOM related 'oomignorefailure': ON"))); + iTestScripter->iOOMIgnoreFailure = ETrue; + } + else if( tmp == _L("OFF") || tmp == _L("off") ) + { + __TRACE( KMessage, (_L("OOM related 'oomignorefailure': OFF"))); + iTestScripter->iOOMIgnoreFailure = EFalse; + } + else + { + __TRACE( KError, + (_L("Unknown argument for 'oomignorefailure': [%S]"), + &tmp)); + iRunErrorMessage.Format( KerrMsgOOMIgnoreFailureUnknownArgument, &tmp ); + User::Leave( KErrArgument ); + } + } + else + { + __TRACE( KError, ( _L( "Unknown argument for 'oomignorefailure'" ) ) ); + iRunErrorMessage = KerrMsgOOMIgnoreFailureNoArgument; + User::Leave( KErrArgument ); + } + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: OOMHeapFailNext + + Description: Handles 'oomheapfailnext' keyword parsing. + + Parameters: CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestRunner::OOMHeapFailNextL( CStifItemParser* aItem ) + { + _LIT( KErrMsgHeapFailNextNoArgument, "HeapFailNext : Parameters is not defined or has invalid value" ); + _LIT( KErrMsgHeapFailNextInvalidValue, "HeapFailNext : Argument value can't be <0" ); + __TRACEFUNC(); + + TInt heapfailNext( 0 ); + // If LOOP_COUNTER is used the GetNextInt returns a correct + // value(Because of the LOOP_COUNTER implementation). + if( aItem->GetNextInt( heapfailNext ) == KErrNone ) + { + if( heapfailNext < 0 ) + { + __TRACE( KError, ( _L( "Argument value must be >0" ) ) ); + iRunErrorMessage = KErrMsgHeapFailNextInvalidValue; + User::Leave( KErrArgument ); + } + // OOM heap's FAILNEXT range is from 1 to n + iHeapFailNext = heapfailNext + 1; + __TRACE( KMessage, ( _L( "'oomheapfailnext' count value(rate): %d" ), + iHeapFailNext ) ); + } + else + { + __TRACE( KError, ( _L( "Unknown argument for 'oomheapfailnext'" ) ) ); + iRunErrorMessage = KErrMsgHeapFailNextNoArgument; + User::Leave( KErrArgument ); + } + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: OOMHeapSetFail + + Description: Handles 'oomheapsetfail' keyword parsing. + + Parameters: CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestRunner::OOMHeapSetFailL( CStifItemParser* aItem ) + { + _LIT( KErrMsgOOMHeapSetFailTypeNotDefined, "OOMHeapSetFail : Parameter type is not defined" ); + _LIT( KErrMsgOOMHeapSetFailRateNotDefined, "OOMHeapSetFail : Parameter rate is not defined" ); + _LIT( KErrMsgOOMHeapSetFailTypeInvalidValue, "OOMHeapSetFail : Parameter type has invalid value" ); + _LIT( KErrMsgOOMHeapSetFailRateInvalidValue, "OOMHeapSetFail : Parameter rate can't be <0" ); + __TRACEFUNC(); + + _LIT( KRandom, "random"); + _LIT( KTrueRandom, "truerandom"); + _LIT( KDeterministic, "deterministic"); + _LIT( KNone, "none"); + _LIT( KFailNext, "failnext"); + + TPtrC type; + TInt value( 0 ); + + // NOTE: If error in type or value parsing => return without changing + // iHeapSetFailType or iHeapSetFailValue variables. + + // Get type + if( aItem->GetNextString( type ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'oomheapsetfail' type" ) ) ); + iRunErrorMessage = KErrMsgOOMHeapSetFailTypeNotDefined; + User::Leave( KErrArgument ); + } + // Get value(rate) + if( aItem->GetNextInt( value ) != KErrNone ) + { + if(type == KNone) + { + value = 0; + } + else + { + __TRACE( KError, (_L( "Unknown argument for 'oomheapsetfail' value(rate)" ) ) ); + iRunErrorMessage = KErrMsgOOMHeapSetFailRateNotDefined; + User::Leave( KErrArgument ); + } + } + + // All parsing operations are passed, get type and value + + // Get type + if(type == KRandom) + { + __TRACE( KMessage, (_L("'oomheapsetfail' type: random"))); + iHeapSetFailType = RHeap::ERandom; + } + else if(type == KTrueRandom) + { + __TRACE( KMessage, (_L("'oomheapsetfail' type: truerandom"))); + iHeapSetFailType = RHeap::ETrueRandom; + } + else if(type == KDeterministic) + { + __TRACE( KMessage, (_L("'oomheapsetfail' type: deterministic"))); + iHeapSetFailType = RHeap::EDeterministic; + } + else if(type == KNone) + { + __TRACE( KMessage, (_L("'oomheapsetfail' type: none"))); + iHeapSetFailType = RHeap::ENone; + } + else if(type == KFailNext) + { + __TRACE( KMessage, (_L("'oomheapsetfail' type: failnext"))); + iHeapSetFailType = RHeap::EFailNext; + } + else + { + __TRACE( KError, + ( _L( "Unknown argument for 'oomheapsetfail' type: [%S]" ), + &type ) ); + iRunErrorMessage = KErrMsgOOMHeapSetFailTypeInvalidValue; + User::Leave( KErrArgument ); + } + + if( value < 0 ) + { + __TRACE( KError, _L( "'oomheapsetfail' value(rate) can't be <0" ) ); + iRunErrorMessage = KErrMsgOOMHeapSetFailRateInvalidValue; + User::Leave( KErrArgument ); + } + // Get value + // OOM heap's SETFAIL range is from 1 to n + iHeapSetFailValue = value + 1; + __TRACE(KMessage, (_L( "'oomheapsetfail' value(rate): [%d]" ), iHeapSetFailValue)); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: OOMHeapToNormal + + Description: Initialize all OOM related variables. + + Parameters: None. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestRunner::OOMHeapToNormal() + { + __TRACEFUNC(); + + if( iTestScripter ) + { + // This should initialize also + iTestScripter->iOOMIgnoreFailure = EFalse; + } + + iHeapFailNext = 0; + iHeapSetFailType = RHeap::ENone; + iHeapSetFailValue = 0; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: TestInterference + + Description: Starts test interference. + + Parameters: CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestRunner::TestInterferenceL( CStifItemParser* aItem ) + { + _LIT( KErrMsgTestInterferenceNameNotDefined, "TestInterference : Parameter name is not defined" ); + _LIT( KErrMsgTestInterferenceCommandNotDefined, "TestInterference : Parameter command is not defined" ); + _LIT( KErrMsgTestInterferenceCommandInvalidValue, "TestInterference : Parameter command has invalid value" ); + __TRACEFUNC(); + TPtrC name; + TPtrC command; + + // Get name + if( aItem->GetNextString( name ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' name" ) ) ); + iRunErrorMessage = KErrMsgTestInterferenceNameNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + // Get command + if( aItem->GetNextString( command ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' command" ) ) ); + iRunErrorMessage = KErrMsgTestInterferenceCommandNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + + if( command == _L( "start" ) ) + { + __TRACE( KMessage, ( _L( "'testinterference' called, starts test interference") ) ); + StartInterferenceL( name, aItem ); + } + else if( command == _L( "stop" ) ) + { + __TRACE( KMessage, ( _L( "'testinterference' called, stops and releases test interference") ) ); + StopInterferenceL( name ); + } + else + { + __TRACE( KError, ( + _L( "Unknown command for 'testinterference'[%S]" ), &command ) ); + iRunErrorMessage = KErrMsgTestInterferenceCommandInvalidValue; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: StartInterference + + Description: + + Parameters: CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestRunner::StartInterferenceL( TDesC& aName, CStifItemParser* aItem ) + { + _LIT( KErrMsgStartInterferenceCategoryNotDefined, "TestInterference : Parameter category is not defined" ); + _LIT( KErrMsgStartInterferenceCategoryInvalidValue, "TestInterference : Parameter category has invalid value" ); + _LIT( KErrMsgStartInterferenceTypeNotDefined, "TestInterference : Parameter type is not defined" ); + _LIT( KErrMsgStartInterferenceTypeInvalidValue, "TestInterference : Parameter type has invalid value" ); + _LIT( KErrMsgStartInterferenceIdleNotDefined, "TestInterference : Parameter idle is not defined or has invalid value" ); + _LIT( KErrMsgStartInterferenceIdleInvalidValue, "TestInterference : Parameter idle has invalid value" ); + _LIT( KErrMsgStartInterferenceActiveNotDefined, "TestInterference : Parameter active is not defined or has invalid value" ); + _LIT( KErrMsgStartInterferenceActiveInvalidValue, "TestInterference : Parameter active has invalid value" ); + + __TRACEFUNC(); + TPtrC category; + TPtrC type; + TInt idle( 0 ); + TInt active( 0 ); + TInt priority( 0 ); + + // Get category + if( aItem->GetNextString( category ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' category" ) ) ); + iRunErrorMessage = KErrMsgStartInterferenceCategoryNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + // Get type + if( aItem->GetNextString( type ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' type" ) ) ); + iRunErrorMessage = KErrMsgStartInterferenceTypeNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + + TPtrC timeStr; + TReal time; + // Get idle time + if( aItem->GetNextString( timeStr ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' idle" ) ) ); + iRunErrorMessage = KErrMsgStartInterferenceIdleNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + if ( TLex( timeStr ).Val( time, '.' ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' idle" ) ) ); + iRunErrorMessage = KErrMsgStartInterferenceIdleNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + // Convert idle time from milli to micro seconds + idle = time * 1000.0; + + if( idle < 0 ) + { + __TRACE( KError, ( + _L( "Argument 'testinterference' idle can't be <0" ) ) ); + iRunErrorMessage = KErrMsgStartInterferenceIdleInvalidValue; + User::Leave( KErrArgument ); + } + // Get active time + if( aItem->GetNextString( timeStr ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' active" ) ) ); + iRunErrorMessage = KErrMsgStartInterferenceActiveNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + if ( TLex( timeStr ).Val( time, '.' ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' idle" ) ) ); + iRunErrorMessage = KErrMsgStartInterferenceIdleNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + + // Convert active time from milli to micro seconds + active = time * 1000.0; + + if( active < 0 ) + { + __TRACE( KError, ( + _L( "Argument 'testinterference' active can't be <0" ) ) ); + iRunErrorMessage = KErrMsgStartInterferenceActiveInvalidValue; + User::Leave( KErrArgument ); + } + + // Get priority + if( aItem->GetNextInt( priority ) != KErrNone ) + { + // Log information only do not return. Priority value is optional. + __TRACE( KInit, ( + _L( "Unknown argument for 'testinterference' priority or value not given, default priority will be used" ) ) ); + } + + MSTIFTestInterference* interference = NULL; + + // Get category + if( category == _L("activeobject") ) + { + interference = MSTIFTestInterference::NewL( iTestScripter, + MSTIFTestInterference::EActiveObject ); + } + else if( category == _L("thread") ) + { + interference = MSTIFTestInterference::NewL( iTestScripter, + MSTIFTestInterference::EThread ); + } + else + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' category[%S]" ), &category ) ); + iRunErrorMessage = KErrMsgStartInterferenceCategoryInvalidValue; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + + // Create object that include test interference information and append this + // to array. + TTestInterference* object = new (ELeave) TTestInterference(); + object->iName = aName; + object->iInterference = interference; + + // Array for handling test interference between different objects + TInt ret = iTestInterferenceArray.Append( object ); + if( ret != KErrNone ) + { + delete object; + __TRACE( KError, ( + _L( "CTestRunner::StartInterference: iTestInterferenceArray.Append fails:[%d]" ), ret ) ); + User::Leave( ret ); + } + + // Set priority if user given + if( priority != 0 ) + { + interference->SetPriority( priority ); + } + + // Get type + if( type == _L("cpuload") ) + { + interference->StartL( MSTIFTestInterference::ECpuLoadMicroSeconds, idle , active ); + } + else if( type == _L("filesystemreadc") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemReadCMicroSeconds, idle , active ); + } + else if( type == _L("filesystemreadd") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemReadDMicroSeconds, idle , active ); + } + else if( type == _L("filesystemreade") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemReadEMicroSeconds, idle , active ); + } + else if( type == _L("filesystemreadz") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemReadZMicroSeconds, idle , active ); + } + else if( type == _L("filesystemwritec") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemWriteCMicroSeconds, idle , active ); + } + else if( type == _L("filesystemwrited") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemWriteDMicroSeconds, idle , active ); + } + else if( type == _L("filesystemwritee") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemWriteEMicroSeconds, idle , active ); + } + else if( type == _L("filesystemfillandemptyc") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemFillAndEmptyCMicroSeconds, idle , active ); + } + else if( type == _L("filesystemfillandemptyd") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemFillAndEmptyDMicroSeconds, idle , active ); + } + else if( type == _L("filesystemfillandemptye") ) + { + interference->StartL( MSTIFTestInterference::EFileSystemFillAndEmptyEMicroSeconds, idle , active ); + } + else + { + __TRACE( KError, ( + _L( "Unknown argument for 'testinterference' type[%S]" ), &type ) ); + iRunErrorMessage = KErrMsgStartInterferenceTypeInvalidValue; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: StopInterference + + Description: Stops test interference. + + Parameters: TDesC& aName: in: Indicates right test interference object. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestRunner::StopInterferenceL( TDesC& aName ) + { + _LIT( KErrMsgStopInterference, "TestInterference : testinterference %S was not start" ); + __TRACEFUNC(); + + TInt count = iTestInterferenceArray.Count(); + for( TInt i = 0; i < count; i++ ) + { + if( iTestInterferenceArray[i]->iName == aName ) + { + // Found test module, return description + iTestInterferenceArray[i]->iInterference->Stop(); + // Delete data + delete iTestInterferenceArray[i]; + // Remove pointer to deleted data(Append()) + iTestInterferenceArray.Remove( i ); + // iTestMeasurementArray can contain only one type of measurement + // so we can break when type is removed. + return; + } + } + __TRACE( KError, ( + _L( "'testinterference' type[%S] was not start" ), &aName ) ); + iRunErrorMessage.Format( KErrMsgStopInterference, &aName ); + User::Leave( KErrArgument ); // Error in parsing => Leave + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: MeasurementL + + Description: Starts test measurement. + + Parameters: CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: Leaves if StartBappeaMeasurementL() fails. + Leaves if StopBappeaMeasurementL() fails. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestRunner::MeasurementL( CStifItemParser* aItem ) + { + _LIT( KErrMsgMeasurementCommandNotDefined, "TestMeasurement : Parameter command is not defined" ); + _LIT( KErrMsgMeasurementTypeNotDefined, "TestMeasurement : Parameter type is not defined" ); + _LIT( KErrMsgMeasurementUnknownType, "TestMeasurement : Unknown measurement type %S" ); + _LIT( KErrMsgMeasurementUnknownCommand, "TestMeasurement : Unknown command %S" ); + __TRACEFUNC(); + TPtrC type; + TPtrC command; + + // Get command + if( aItem->GetNextString( command ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'measurement' command" ) ) ); + iRunErrorMessage = KErrMsgMeasurementCommandNotDefined; + User::Leave( KErrArgument ); // Error in parsing => Leave + } + // Get name + if( aItem->GetNextString( type ) != KErrNone ) + { + __TRACE( KError, ( + _L( "Unknown argument for 'measurement' type" ) ) ); + iRunErrorMessage = KErrMsgMeasurementTypeNotDefined; + 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 ) ); + iRunErrorMessage.Format( KErrMsgMeasurementUnknownType, &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 ) ); + iRunErrorMessage.Format( KErrMsgMeasurementUnknownCommand, &command ); + User::Leave( KErrArgument ); // Error in commands => Leave + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: StartMeasurementL + + Description: Start measurement + + Parameters: const TDesC& aType: in: Plugin type. + CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: Leaves is measurement operation fails. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestRunner::StartMeasurementL( const TDesC& aType, + CStifItemParser* aItem ) + { + _LIT( KErrMsgMeasurementUnknownPlugin, "Measurement : Unknown measurement plugin %S" ); + _LIT( KErrMsgMeasurementStartFail, "Measurement : Measurement start fails" ); + __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( + iTestScripter, + CSTIFTestMeasurement::KStifMeasurementPlugin01, + configurationInfo ); + } + else if( aType == KParamMeasurement02 ) + { + testMeasurement = CSTIFTestMeasurement::NewL( + iTestScripter, + CSTIFTestMeasurement::KStifMeasurementPlugin02, + configurationInfo ); + } + else if( aType == KParamMeasurement03 ) + { + testMeasurement = CSTIFTestMeasurement::NewL( + iTestScripter, + CSTIFTestMeasurement::KStifMeasurementPlugin03, + configurationInfo ); + } + else if( aType == KParamMeasurement04 ) + { + testMeasurement = CSTIFTestMeasurement::NewL( + iTestScripter, + CSTIFTestMeasurement::KStifMeasurementPlugin04, + configurationInfo ); + } + else if( aType == KParamMeasurement05 ) + { + testMeasurement = CSTIFTestMeasurement::NewL( + iTestScripter, + CSTIFTestMeasurement::KStifMeasurementPlugin05, + configurationInfo ); + } + else if( aType == KParamMeasurementBappea ) + { + testMeasurement = CSTIFTestMeasurement::NewL( + iTestScripter, + CSTIFTestMeasurement::KStifMeasurementBappeaProfiler, + configurationInfo ); + } + else + { + __TRACE( KError, ( _L( "Unknown plugin[%S] for 'measurement'" ), &aType ) ); + iRunErrorMessage.Format( KErrMsgMeasurementUnknownPlugin, &aType ); + User::Leave( KErrArgument ); + } + + // Start test measurement + TInt start_ret( KErrNone ); + start_ret = testMeasurement->Start(); + if( start_ret != KErrNone ) + { + delete testMeasurement; + //CleanupStack::PopAndDestroy( setting_buf ); + __TRACE( KError, ( + _L( "CTestRunner::StartMeasurementL(): Measurement Start() fails:[%d]" ), start_ret ) ); + iRunErrorMessage = KErrMsgMeasurementStartFail; + 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( "CTestRunner::StartMeasurementL(): iTestMeasurementArray.Append fails:[%d]" ), ret ) ); + User::Leave( ret ); + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: StopMeasurementL + + Description: Stops test measurement. + + Parameters: None. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestRunner::StopMeasurementL( const TDesC& aType ) + { + _LIT( KErrMsgMeasurementNotStarted, "Measurement : Measurement %S was not start" ); + __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. + return; + } + } + + __TRACE( KError, ( + _L( "CTestRunner::StopMeasurementL(): Measurement %S was not start" ), &aType ) ); + iRunErrorMessage.Format( KErrMsgMeasurementNotStarted, &aType ); + User::Leave( KErrArgument ); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: AddTestCaseResultL + + Description: Adds new test case result. Used with 'allownextresult' + and 'allowerrorcodes' keywords. + + Parameters: CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: Leaves if iTestCaseResults.Append fails. + Leaves if aItem->GetNextInt() fails. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestRunner::AddTestCaseResultL( CStifItemParser* aItem ) + { + _LIT( KErrMsgAllowNextResultInvalidValue, "No expected result value given or value has invalid format" ); + TInt result; + + TPtrC codeBuf; + TBool found = EFalse; + while( aItem->GetNextString( codeBuf ) == KErrNone ) + { + TLex codeParser( codeBuf ); + if ( codeParser.Val( result ) != KErrNone ) + { + __TRACE( KError, (_L("ExecuteLineL: No expected result value given"))); + iRunErrorMessage = KErrMsgAllowNextResultInvalidValue; + User::Leave( KErrArgument ); + } + else + { + User::LeaveIfError( iTestCaseResults.Append( result ) ); + // Set test case allow result to CTestModuleIf side too. This is + // used in TAL-TA5L macro handling. + User::LeaveIfError( + iTestScripter->TestModuleIf().SetAllowResult( result ) ); + found = ETrue; + } + } + + if ( !found ) + { + __TRACE( KError, (_L("ExecuteLineL: No expected result value given"))); + iRunErrorMessage = KErrMsgAllowNextResultInvalidValue; + User::Leave( KErrArgument ); + } + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: AddTestCasePanicL + + Description: Adds new test case result. Used with 'allowpanic' + and 'allowerrorcodes' keywords. + + Parameters: CStifItemParser* aItem: in: Item object for parsing. + + Return Values: None. + + Errors/Exceptions: Leaves if iTestCaseResults.Append fails. + Leaves if aItem->GetNextInt() fails. + + Status: Approved + +------------------------------------------------------------------------------- +*/ + +void CTestRunner::AddTestCasePanicL( CStifItemParser* aItem ) + { + _LIT( KErrMsgAllowNextPanicInvalidValue, "No expected panic value given or value has invalid format" ); + TInt panic; + + TPtrC codeBuf; + while( aItem->GetNextString( codeBuf ) == KErrNone ) + { + TLex codeParser( codeBuf ); + if ( codeParser.Val( panic ) != KErrNone ) + { + __TRACE( KError, (_L("ExecuteLineL: No expected panic value given"))); + iRunErrorMessage = KErrMsgAllowNextPanicInvalidValue; + User::Leave( KErrArgument ); + } + else + { + //do not add panic result to allowed result of case. + //User::LeaveIfError( iTestCaseResults.Append( panic ) ); + // Set test case allow result to CTestModuleIf side too. This is + // used in TAL-TA5L macro handling. + iTestScripter->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, panic ); + break; + } + } + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: SubTestCaseFinishedL + + Description: Recieves and handles notification about finished sub test + \ case execution. + + Parameters: CSubTestCaseRunner* aSubTestCaseRunner: in: sub test case + runner used to run test case. + + Return Values: None + + Errors/Exceptions: Leaves on error situations. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestRunner::SubTestCaseFinishedL( CSubTestCaseRunner* aSubTestCaseRunner ) + { + if ( iInternalStateForSubTestCases == EISFinished ) + { + if ( aSubTestCaseRunner->GetTestCaseResult().iCaseExecutionResultCode == KErrCancel ) + { + // Test was canceled. Do nothing. + return; + } + else + { + User::Leave( KErrGeneral ); + } + } + + TInt index = iSubTestCases.Find( aSubTestCaseRunner ); + if ( index < 0 ) + { + // Debug info + return; + } + + CSubTestCaseRunner* subTestCaseRunner = iSubTestCases[ index ]; + iSubTestCases.Remove( index ); + CleanupStack::PushL( subTestCaseRunner ); + + TInt runResult = subTestCaseRunner->GetRunResult(); + TFullTestResult testCaseResult = subTestCaseRunner->GetTestCaseResult(); + const CStartInfo* startInfo = subTestCaseRunner->GetStartInfo(); + + __TRACE( KMessage, ( _L( "Sub test case execution finished: module=%S cfg=%S tcnum=%d id=%S" ), + &startInfo->GetModuleName(), &startInfo->GetConfig(), + startInfo->GetTestCaseNumber(), &startInfo->GetTestId()) ); + + __TRACE( KMessage, ( _L( "Sub test case execution result: execution_result=%d, test_result=%d, des=%S" ), + testCaseResult.iCaseExecutionResultCode, testCaseResult.iTestResult.iResult, + &testCaseResult.iTestResult.iResultDes ) ); + + RDebug::Print( _L( "Sub test case execution finished: module=%S cfg=%S tcnum=%d id=%S" ), + &startInfo->GetModuleName(), &startInfo->GetConfig(), + startInfo->GetTestCaseNumber(), &startInfo->GetTestId() ); + + RDebug::Print( _L( "Sub test case execution result: execution_result=%d, test_result=%d, des=%S" ), + testCaseResult.iCaseExecutionResultCode, testCaseResult.iTestResult.iResult, + &testCaseResult.iTestResult.iResultDes ); + + // Check expected execution result type + TBool reportFailedSubTestCase = EFalse; + if( testCaseResult.iCaseExecutionResultType != startInfo->GetExpectedResultCategory() ) + { + reportFailedSubTestCase = true; + } + else + { + if( startInfo->GetExpectedResultCategory() == TFullTestResult::ECaseExecuted ) + { + if ( startInfo->GetExpectedResult() != testCaseResult.iTestResult.iResult ) + { + reportFailedSubTestCase = true; + } + } + else + { + if ( startInfo->GetExpectedResult() != testCaseResult.iCaseExecutionResultCode ) + { + reportFailedSubTestCase = true; + } + } + } + + if ( reportFailedSubTestCase ) + { + // Only remember first failed sub test case + if ( iFailedSubTestCaseReported == EFalse ) + { + // If passlimit is enabled and loop is in progress ignore sub test case fail. + // Fail will be reported only if passlimit is not met. + // It is done in ReportLoopEndResultL + if ( !( iLoopHelper->LoopInProgress() && iPasslimitEnabled ) || iCancelIfError ) + { + iFailedSubTestCaseReported = true; + iFailedSubTestCaseResult = testCaseResult; + iFailedSubTestCaseInfo = CStartInfo::NewL(); + iFailedSubTestCaseInfo->CopyL( *startInfo ); + } + } + } + + switch( iInternalStateForSubTestCases ) + { + case EISRuning: + // Do noting + if ( iLoopHelper->LoopInProgress() ) + { + iLoopHelper->NotifySubTestCaseEndL( subTestCaseRunner, !reportFailedSubTestCase ); + } + break; + case EISWaitingForComplete: + if ( iLoopHelper->LoopInProgress() ) + { + iLoopHelper->NotifySubTestCaseEndL( subTestCaseRunner, !reportFailedSubTestCase ); + } + // Do noting + if ( subTestCaseRunner->GetStartInfo()->GetTestId() == *iTestIdForComplete ) + { + delete iTestIdForComplete; + iTestIdForComplete = NULL; + SetRunnerActive(); // Continue test case execution after complete + iInternalStateForSubTestCases = EISRuning; + } + break; + case EISFinishedWaitingForSubTestCases: + if ( iSubTestCases.Count() <= 0 ) + { + SetRunnerActive(); + } + break; + default: + break; + } + + CleanupStack::PopAndDestroy( subTestCaseRunner ); + + if ( iCancelIfError && iFailedSubTestCaseReported ) + { + // Make sure that DoCancel will be executed + if ( !IsActive() ) + { + SetRunnerActive(); + } + // Stop Test Case execution + Cancel(); + } + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: ReportLoopEndResultL + + Description: Recives report from CLoopHelper about result of loop execution + + Parameters: TInt aPassedIterations: in: number of passed loop iterations + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestRunner::ReportLoopEndResultL( TInt aPassedIterations ) + { + //If passlimit was given and number of passed test is less then expected, stop execution of scripter's test case + if( iPasslimitEnabled && ( aPassedIterations < iPasslimit ) ) + { + __TRACE( KMessage, ( _L( "Loop has failed (passlimit). Finishing with KErrCompletion." ) ) ); + iTestScripter->iPassLimitNotMet = ETrue; + iTestScripter->iResult.iResult = KErrCompletion; + iTestScripter->iResult.iResultDes = _L("Loop has not reached passlimit requirement."); + Cancel(); + } + else if( iPasslimitEnabled && ( aPassedIterations >= iPasslimit ) ) + { + __TRACE( KMessage, ( _L( "Loop has passed (passlimit)" ) ) ); + } + + iPasslimit = 0; + iPasslimitEnabled = EFalse; + } + +void CTestRunner::ReleaseRemoteResourcesAllocatedInLoopL() + { + RPointerArray& inLoopSlaves = iLoopHelper->GetRegisteredInLoopSlaves(); + + for ( TInt i = 0; i < inLoopSlaves.Count(); i++ ) + { + inLoopSlaves[ i ]->WaitForSubTestCasesL(); + + RPointerArray& slaveEvents = inLoopSlaves[ i ]->GetEvents(); + for ( TInt k = 0; k < slaveEvents.Count(); k++ ) + { + iSlavesManager->EventReleaseL( inLoopSlaves[ i ], slaveEvents[ k ]->Name() ); + } + slaveEvents.ResetAndDestroy(); + + iSlavesManager->SlaveFreeL( inLoopSlaves[ i ]->GetName() ); + } + + inLoopSlaves.Reset(); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: IsFailedSubTestCaseReported + + Description: Gets information if there was reported executed sub test + case which failed. + + Parameters: None + + Return Values: ETrue: test case was reported + EFalse: test case was not reported + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TBool CTestRunner::IsFailedSubTestCaseReported() const + { + return iFailedSubTestCaseReported; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: GetFailedSubTestCaseResult + + Description: Returns first failed sub test case result. + + Parameters: None + + Return Values: First failed sub test case result. + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TFullTestResult CTestRunner::GetFailedSubTestCaseResult() const + { + return iFailedSubTestCaseResult; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: GetFailedSubTestCaseInfo + + Description: Returns first failed sub test case info. + + Parameters: None + + Return Values: First failed sub test case info. + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +const CStartInfo* CTestRunner::GetFailedSubTestCaseInfo() const + { + return iFailedSubTestCaseInfo; + } + +void CTestRunner::HandleRemoteReceiveError( TInt aError, const TDesC& aErrorDescription ) + { + iTestScripter->UpdateTestCaseResult( aError, aErrorDescription ); + CActiveScheduler::Current()->Stop(); + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: ControlSubTestCaseL + + Description: Controls sub test case execution + + Parameters: Sub test case id + + Return Values: ETrue: continue script file execution + EFalse: stop script file execution + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TBool CTestRunner::ControlSubTestCaseL( TTestKeywords::TKeywords aOperation, CStifItemParser* aItem ) + { + _LIT( KErrMsgInvalidTestId, "testid is not specified or it has invalid value" ); + _LIT( KErrMsgUnknownCall, "Unknown operation call on sub test case" ); + + TPtrC subTestId; + TInt ret = aItem->GetNextString( subTestId ); + if ( ret != KErrNone ) + { + iRunErrorMessage = KErrMsgInvalidTestId; + User::Leave( KErrArgument ); + } + + TInt subTestCasesCount = iSubTestCases.Count(); + for ( TInt i = 0; i < subTestCasesCount; i++ ) + { + if ( iSubTestCases[ i ]->GetStartInfo()->GetTestId() == subTestId ) + { + switch ( aOperation ) + { + case TTestKeywords::EPauseTest: + { + __TRACE( KMessage, ( _L( "Pause sub test case testid=%S" ), &subTestId ) ); + iSubTestCases[ i ]->PauseSubTestCaseL(); + } + break; + case TTestKeywords::EResume: + { + __TRACE( KMessage, ( _L( "Reasume sub test case testid=%S" ), &subTestId ) ); + iSubTestCases[ i ]->ResumeSubTestCaseL(); + } + break; + case TTestKeywords::ECancel: + { + __TRACE( KMessage, ( _L( "Cancel sub test case testid=%S" ), &subTestId ) ); + CSubTestCaseRunner* subTestCaseRunner = iSubTestCases[ i ]; + subTestCaseRunner->CancelSubTestCaseL(); + if ( subTestCaseRunner->GetType() == CSubTestCaseRunner::ESTTRemote ) + { + CRemoteSubTestCaseRunner* remoteSubTestCaseRunner = + (CRemoteSubTestCaseRunner*)subTestCaseRunner; + CSlave* slave = remoteSubTestCaseRunner->GetSlave(); + slave->UnregisterSubTestCaseL( remoteSubTestCaseRunner ); + } + if ( iLoopHelper->LoopInProgress() ) + { + iLoopHelper->UnregisterInLoopSubTestCaseL( subTestCaseRunner ); + } + delete iSubTestCases[ i ]; + iSubTestCases.Remove( i ); + } + break; + default: + { + iRunErrorMessage = KErrMsgUnknownCall; + User::Leave( KErrArgument ); + } + break; + } + + return true; + } + } + + __TRACE( KMessage, ( _L( "Sub test case testid=%S not found" ), &subTestId ) ); + RDebug::Print( _L( "Sub test case testid=%S not found" ), &subTestId ); + + return true; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: ExecuteLoopL + + Description: Executes loop keyword + + Parameters: CStifItemParser* aItem: in: script line + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TBool CTestRunner::ExecuteLoopL( CStifItemParser* aItem ) + { + _LIT( KErrMsgLoopNested, "Loop: Nested loop are not supported" ); + _LIT( KErrMsgLoopNoParam, "Loop: No loop iterations count given or value has invalid format" ); + _LIT( KErrMsgLoopInvalidParam, "Loop: Loop count must be >0" ); + _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" ); + + if( iLoopTimes > 0 ) + { + __TRACE( KError, (_L("ExecuteLineL: Nested loop are not supported"))); + iRunErrorMessage = KErrMsgLoopNested; + User::Leave( KErrNotSupported ); + } + + iLoopTimes = 0; + iLoopCounter = 0; + iTimedLoop = EFalse; + + if( aItem->GetNextInt( iLoopTimes ) != KErrNone ) + { + __TRACE( KError, (_L("ExecuteLineL: No loop count value given for loop"))); + iRunErrorMessage = KErrMsgLoopNoParam; + User::Leave( KErrArgument ); + } + + if( iLoopTimes < 1 ) + { + __TRACE( KError, (_L("ExecuteLineL: Loop count must be >0"))); + iRunErrorMessage = KErrMsgLoopInvalidParam; + User::Leave( KErrArgument ); + } + + __TRACE( KMessage, (_L("ExecuteLineL: 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("ExecuteLineL: 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("ExecuteLineL: Unknown or unexpected loop option [%S]"), &option)); + iRunErrorMessage = KErrMsgLoopUnknownUnexpectedOption; + User::Leave( KErrNotSupported ); + } + + iLoopStartPos = iTestScripter->iCurrentParser->GetPosition(); + + iLoopHelper->LoopStartL(); + + return ETrue; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestRunner + + Method: ExecuteEndLoopL + + Description: Executes endloop keyword + + Parameters: CStifItemParser* aItem: in: script line + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TBool CTestRunner::ExecuteEndLoopL( CStifItemParser* /*aItem*/ ) + { + _LIT( KErrMsgEndLoopNotOpened, "Endloop: Can't execute endloop. No opened loop exists" ); + + if( iLoopTimes == 0 ) + { + __TRACE( KError, (_L("ExecuteLineL: Can't execute endloop. No opened loop exists"))); + iRunErrorMessage = KErrMsgEndLoopNotOpened; + User::Leave( KErrNotFound ); + } + + iLoopCounter++; + __TRACE( KMessage, + (_L("ExecuteLineL: Loop executed for %d times" ), + iLoopCounter ) ); + + TTime currTime; + currTime.HomeTime(); + + if(((!iTimedLoop) && (iLoopCounter < iLoopTimes)) //Normal loop + || + iTimedLoop && (currTime.MicroSecondsFrom(iStartTime) < iExpectedLoopTime)) //Timed loop + { + // Go to beginning of the loop + User::LeaveIfError( + iTestScripter->iCurrentParser->SetPosition( iLoopStartPos )); + iLoopHelper->IterationEndStartNextIterationL(); + } + else + { + // End looping + iLoopCounter = 0; + iLoopTimes = 0; + iLoopStartPos = 0; + + iLoopHelper->LoopEndL(); + } + + // iLoopHelper will activate runner in proper moment + return EFalse; + } + +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 ); + } + + iTestScripter->TestModuleIf().Printf( KPrintPriExec, KExecute, + _L("Allocate %S"), &name ); + + __TRACE( KMessage, (_L("Allocate %S [name: %S]"), &type, &name)); + + if( iSlavesManager->GetSlave( name ) ) + { + __TRACE( KError, (_L("Slave with name %S already allocated"), + &name ) ); + iRunErrorMessage.Format( KErrMsgAllocateSlaveAlreadyAllocated, &name ); + User::Leave( KErrAlreadyExists ); + } + + iSlavesManager->SlaveAllocateL( name, type ); + + if ( iLoopHelper->LoopInProgress() ) + { + CSlave* slave = iSlavesManager->GetSlave( name ); + iLoopHelper->RegisterInLoopSlaveL( slave ); + } + + return ETrue; + } + +TBool CTestRunner::ExecuteFreeL( CStifItemParser* aItem ) + { + _LIT( KErrMsgFreeSlaveNameNotDefined, "Free : Slave name is not defined" ); + _LIT( KErrMsgFreeSlaveNotFound, "Free : Slave %S not found" ); + __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 ); + } + + iTestScripter->TestModuleIf().Printf( KPrintPriExec, KExecute, + _L("Free %S"), &name ); + + __TRACE( KMessage, (_L("Free %S"), &name ) ); + + CSlave* slave = iSlavesManager->GetSlave( name ); + if( slave == NULL ) + { + __TRACE( KError, (_L("Slave %S not found"), &name )); + iRunErrorMessage.Format( KErrMsgFreeSlaveNotFound, &name ); + User::Leave( KErrNotFound ); + } + + if ( iLoopHelper->LoopInProgress() ) + { + iLoopHelper->UnregisterInLoopSlaveL( slave ); + } + + if ( slave->HasRunningTestCases() ) + { + slave->WaitForSubTestCasesL(); + } + + iSlavesManager->SlaveFreeL( name ); + + return ETrue; + } + +TBool CTestRunner::ExecuteRemoteL( CStifItemParser* aItem ) + { + _LIT( KErrMsgRemoteSlaveNameNotDefined, "Remote : Slave name is not defined" ); + _LIT( KErrMsgRemoteSlaveNotFound, "Remore : Slave %S not found" ); + _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)); + + CSlave* slave = iSlavesManager->GetSlave( name ); + if( slave == NULL ) + { + __TRACE( KError, (_L("Slave %S not found"), &name )); + iRunErrorMessage.Format( KErrMsgRemoteSlaveNotFound, &name ); + User::Leave( KErrArgument ); + } + + // 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 ); + } + + iTestScripter->TestModuleIf().Printf( KPrintPriExec, KExecute, + _L("remote %S %S"), &name, &command ); + + __TRACE( KPrint, (_L("remote %S %S"), &name, &command ) ); + + // Parse command name + TInt key = TTestKeywords::Parse( command, TTestKeywords::Keyword ); + TBool continueTask = ETrue; + + switch( key ) + { + // Test case starting + case TTestKeywords::ERun: + continueTask = ExecuteRemoteRunL( aItem, slave ); + break; + + // Event control cases + case TTestKeywords::ERequest: + case TTestKeywords::EWait: + case TTestKeywords::ERelease: + case TTestKeywords::ESet: + case TTestKeywords::EUnset: + continueTask = ExecuteRemoteEventCtlL( aItem, slave, key ); + break; + // asynchronous 'sendreceive' + case TTestKeywords::ESendReceive: + continueTask = ExecuteRemoteSendReceiveL( aItem, slave ); + break; + + default: + // Some unknown remote command, forward as such + continueTask = ExecuteRemoteUnknownL( aItem, slave, command ); + break; + } + + return continueTask; + } + + +TBool CTestRunner::ExecuteRemoteRunL( CStifItemParser* aItem, CSlave* aSlave, + HBufC *aSetUnsetEvent, + TInt aCaseNumber ) + { + 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->SetTestCaseNumber( aCaseNumber ); + } + else + { + ParseRunParamsL( aItem, *startInfo ); + } + + CRemoteSubTestCaseRunner* remoteSubTestCase = CRemoteSubTestCaseRunner::NewL( + this, + aSlave, + iSlavesManager->GetRemoteCallsProxy() ); + CleanupStack::PushL( remoteSubTestCase ); + + __TRACE( KMessage, ( _L( "Executing sub test case: module=%S cfg=%S tcnum=%d id=%S" ), + &startInfo->GetModuleName(), &startInfo->GetConfig(), + startInfo->GetTestCaseNumber(), &startInfo->GetTestId()) ); + + RDebug::Print( _L( "Executing sub test case: module=%S cfg=%S tcnum=%d id=%S" ), + &startInfo->GetModuleName(), &startInfo->GetConfig(), + startInfo->GetTestCaseNumber(), &startInfo->GetTestId() ); + + remoteSubTestCase->RunSubTestCaseL( *startInfo ); + iSubTestCases.AppendL( remoteSubTestCase ); + if ( iLoopHelper->LoopInProgress() ) + { + iLoopHelper->RegisterInLoopSubTestCaseL( remoteSubTestCase ); + } + + CleanupStack::Pop( remoteSubTestCase ); + + iRunErrorMessage = KNullDesC; + + CleanupStack::PopAndDestroy( startInfo ); + + return ETrue; + } + +TBool CTestRunner::ExecuteRemoteEventCtlL( CStifItemParser* aItem, + CSlave* 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 ); + } + + TBool continueTask = ETrue; + switch( aCmd ) + { + // Event control cases + case TTestKeywords::ERequest: + { + TEventTS* event = aSlave->GetEvent( eventName ); + if( event != NULL ) + { + __TRACE( KError, (_L("Event %S already requested"), + &eventName ) ); + User::Leave( KErrNotFound ); + } + event = new( ELeave ) TEventTS( (TName&)eventName ); + CleanupStack::PushL( event ); + iSlavesManager->EventRequestL( aSlave, event ); + aSlave->AddEventL( event ); + CleanupStack::Pop( event ); + } + break; + case TTestKeywords::ERelease: + { + TEventTS* event = aSlave->GetEvent( eventName ); + if( event == NULL ) + { + __TRACE( KError, (_L("Event not found %S"), + &eventName ) ); + User::Leave( KErrNotFound ); + } + + aSlave->RemoveEventL( event ); + delete event; + // Release event + iSlavesManager->EventReleaseL( aSlave, eventName ); + } + break; + case TTestKeywords::EWait: + { + TEventTS* 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 + continueTask = EFalse; + } + break; + case TTestKeywords::ESet: + { + TPtrC optParam; + ret = aItem->GetNextString( optParam ); + TEventIf::TEventType eventType = TEventIf::EIndication; + if( ret == KErrNone ) + { + if ( optParam != _L("state") ) + { + __TRACE( KError, (_L("Invalid optional argument"))); + User::Leave( KErrArgument ); + } + eventType = TEventIf::EState; + } + iSlavesManager->EventSetL( aSlave, eventName, eventType ); + } + break; + case TTestKeywords::EUnset: + { + iSlavesManager->EventUnsetL( aSlave, eventName ); + } + break; + default: + // Should never come here + User::Leave( KErrGeneral ); + } + + return continueTask; + } + +TBool CTestRunner::ExecuteRemoteSendReceiveL( CStifItemParser* aItem, + CSlave* aSlave ) + { + TPtrC message; + aItem->Remainder( message ); + + iSlavesManager->SendReceiveL( aSlave, message ); + return ETrue; + } + +TBool CTestRunner::ExecuteRemoteUnknownL( CStifItemParser* aItem, + CSlave* aSlave, + TDesC& aCommand ) + { + TPtrC message; + aItem->Remainder( message ); + + iSlavesManager->SendUnknownL( aSlave, aCommand, message ); + return ETrue; + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains the implementation of CTestContinue class + member functions. CTestContinue handles ContinueScript calls from + TestScripter. + +------------------------------------------------------------------------------- +*/ +// MACROS +#ifdef LOGGER +#undef LOGGER +#endif +#define LOGGER iTestScripter->iLog + +// ================= MEMBER FUNCTIONS ========================================= + +/* +------------------------------------------------------------------------------- + + Class: CTestContinue + + Method: CTestContinue + + Description: Default constructor + + Parameters: CTestRunner* aTestRunner: in: Backpointer to CTestRunner + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CTestContinue::CTestContinue( CTestScripter* aTestScripter, + TTestObject* aObject ): + // Executed with lowest priority, must be lower than CTesRunner priority + CActive( CActive::EPriorityLow ), + iTestScripter( aTestScripter ), + iObject( aObject ) + { + CActiveScheduler::Add( this ); + __TRACEFUNC(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestContinue + + Method: ConstructL + + Description: Symbian OS second phase constructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestContinue::ConstructL() + { + + iObject->iScript->EnableSignal( iStatus ); + SetActive(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestContinue + + Method: NewL + + Description: Two-phased constructor. + + Parameters: CTestRunner* aTestRunner: in: Backpointer to CTestRunner + + Return Values: CTestContinue*: new object + + Errors/Exceptions: Leaves if new or ConstructL leaves + + Status: Draft + +------------------------------------------------------------------------------- +*/ + +CTestContinue* CTestContinue::NewL( CTestScripter* aTestScripter, + TTestObject* aObject ) + { + CTestContinue* self = + new (ELeave) CTestContinue( aTestScripter, aObject ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestContinue + + Method: ~CTestContinue + + Description: Destructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ + +CTestContinue::~CTestContinue() + { + __TRACEFUNC(); + Cancel(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestContinue + + Method: RunL + + Description: Derived from CActive, handles testcase execution. + + Parameters: None. + + Return Values: None. + + Errors/Exceptions: Leaves on error situations. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestContinue::RunL() + { + + __TRACEFUNC(); + __TRACE( KMessage, (_L("CTestContinue::RunL: [%d] "), iStatus.Int() )); + + if( iObject->Signal() ) + { + // If OOM testing is ongoing ignore result check(given by user). + if( !iTestScripter->iOOMIgnoreFailure ) + { + // Erronous case RunError will called and test handling continue + // from there. + if( iTestScripter->TestRunner().TestCaseResults().Count() == 0 ) + { + // KErrNone is the default result expected + // if nothing else is given + User::LeaveIfError( iTestScripter->TestRunner(). + TestCaseResults().Append( KErrNone ) ); + } + + if( iTestScripter->TestRunner().TestCaseResults(). + Find( iStatus.Int() ) < 0 ) + { + __TRACE( KError, ( _L("Command for [%S] failed (%d)"), + &iObject->ObjectId(), iStatus.Int() )); + + + if( iStatus.Int() == KErrNone ) + { + User::Leave( KErrGeneral ); + } + else + { + User::Leave( iStatus.Int() ); + } + } + } + else + { + __TRACE( KMessage, ( + _L( "OOM test: 'oomignorefailure' is ON, signal result[%d] ignored" ), + iStatus.Int() )); + } + + iTestScripter->TestRunner().TestCaseResults().Reset(); + + __TRACE( KMessage, (_L("CTestContinue::RunL: Set runner active "))); + iTestScripter->iTestRunner->SetRunnerActive(); + } + else + { + // Signal called from test side but 'waittestclass' not yet processed + iObject->iAsyncResult = iStatus.Int(); + } + + iObject->iScript->EnableSignal( iStatus ); + SetActive(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestContinue + + Method: DoCancel + + Description: Derived from CActive handles the Cancel + + Parameters: None. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CTestContinue::DoCancel() + { + + __TRACEFUNC(); + __TRACE( KMessage, (_L("CTestContinue::DoCancel"))); + + iObject->iScript->CancelSignal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestContinue + + Method: RunError + + Description: Derived from CActive handles the Cancel + + Parameters: None. + + Return Values: None. + + Errors/Exceptions: None. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CTestContinue::RunError( TInt aError ) + { + + // Return error from here, if none given from execution + if( iTestScripter->iResult.iResult == KErrNone ) + { + iTestScripter->UpdateTestCaseResult(aError, _L("CTestContinue::RunError")); + } + CActiveScheduler::Current()->Stop(); + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains the implementation of CDefinedValue class + member functions. +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= +/* +------------------------------------------------------------------------------- + + Class: CDefinedValue + + Method: CDefinedValue + + Description: Default constructor + + C++ default constructor can NOT contain any code, that + might leave. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CDefinedValue::CDefinedValue() + { + } + +/* +------------------------------------------------------------------------------- + + Class: CDefinedValue + + Method: ConstructL + + Description: Symbian OS second phase constructor + + Symbian OS default constructor can leave. + + Parameters: TDesC& aName: in: Define name + TDesC& aValue: in: Define value + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CDefinedValue::ConstructL( TDesC& aName, TDesC& aValue ) + { + + iNameBuf = aName.AllocLC(); + iName.Set( iNameBuf->Des() ); + iValueBuf = aValue.AllocLC(); + iValue.Set( iValueBuf->Des() ); + CleanupStack::Pop( iValueBuf ); + CleanupStack::Pop( iNameBuf ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CDefinedValue + + Method: NewL + + Description: Two-phased constructor. + + Parameters: TDesC& aName: in: Define name + TDesC& aValue: in: Define value + + Return Values: CDefinedValue*: new object + + Errors/Exceptions: Leaves if new or ConstructL leaves. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CDefinedValue* CDefinedValue::NewL( TDesC& aName, TDesC& aValue ) + { + + CDefinedValue* self = new (ELeave) CDefinedValue(); + + CleanupStack::PushL( self ); + self->ConstructL( aName, aValue ); + CleanupStack::Pop(); + + return self; + + } + +/* +------------------------------------------------------------------------------- + + Class: CDefinedValue + + Method: ~CDefinedValue + + Description: Destructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CDefinedValue::~CDefinedValue() + { + + delete iValueBuf; + delete iNameBuf; + + } + +/* +------------------------------------------------------------------------------- + + Class: CDefinedValue + + Method: SetValueL + + Description: Set new define value + + Parameters: TDesC& aValue: in: Define value + + Return Values: None + + Errors/Exceptions: Leaves on error. + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CDefinedValue::SetValueL( TDesC& aValue ) + { + delete iValueBuf; + iValueBuf = 0; + iValueBuf = aValue.AllocLC(); + iValue.Set( iValueBuf->Des() ); + CleanupStack::Pop( iValueBuf ); + + } + + +/* +------------------------------------------------------------------------------- + + Class: CDefinedValue + + Method: Name + + Description: Returns define name. + + Parameters: None + + Return Values: TDesC: Define name + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TDesC& CDefinedValue::Name() + { + return iName; + } + +/* +------------------------------------------------------------------------------- + + Class: CDefinedValue + + Method: Value + + Description: Returns define value. + + Parameters: None + + Return Values: TDesC: Define value + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TDesC& CDefinedValue::Value() + { + return iValue; + } + + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains the implementation of TTestObjectBase class + member functions. +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= +/* +------------------------------------------------------------------------------- + + Class: TTestObjectBase + + Method: TTestObjectBase + + Description: Constructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TTestObjectBase::TTestObjectBase( TObjectType aType ) : + iAsyncResult( KErrNone ), + iType( aType ) + { + + RDebug::Print( _L("TTestObjectBase::TTestObjectBase") ); + iName.Zero(); + + } + + /* +------------------------------------------------------------------------------- + + Class: TTestObjectBase + + Method: ~TTestObjectBase + + Description: Destructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TTestObjectBase::~TTestObjectBase() + { + + RDebug::Print( _L("TTestObjectBase::~TTestObjectBase") ); + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains the implementation of TTestObject class + member functions. +------------------------------------------------------------------------------- +*/ +// ================= MEMBER FUNCTIONS ========================================= + +/* +------------------------------------------------------------------------------- + + Class: TTestObject + + Method: TTestObject + + Description: Constructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TTestObject::TTestObject() : + TTestObjectBase( EObjectNormal ), + iContinue(0), + iCount(0) + { + iScript = 0; + RDebug::Print( _L("TTestObject::TTestObject") ); + + } + +/* +------------------------------------------------------------------------------- + + Class: TTestObject + + Method: ~TTestObject + + Description: Destructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TTestObject::~TTestObject() + { + + RDebug::Print( _L("TTestObject::~TTestObject") ); + delete iContinue; + iContinue = 0; + + } + +/* +------------------------------------------------------------------------------- + + Class: TTestObject + + Method: RunMethodL + + Description: Run specified method from testclass. + + Parameters: CStifItemParser* aItem: in: itemparser + + Return Values: Symbian OS error code + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt TTestObject::RunMethodL( CStifItemParser& aItem ) + { + + return iScript->RunMethodL( aItem ); + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains the implementation of TTestObjectKernel class + member functions. +------------------------------------------------------------------------------- +*/ +// ================= MEMBER FUNCTIONS ========================================= + + +/* +------------------------------------------------------------------------------- + + Class: TTestObjectKernel + + Method: TTestObjectKernel + + Description: Constructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TTestObjectKernel::TTestObjectKernel() : + TTestObjectBase( EObjectKernel ) + { + + RDebug::Print( _L("TTestObjectKernel::TTestObjectKernel") ); + + } + +/* +------------------------------------------------------------------------------- + + Class: TTestObjectKernel + + Method: ~TTestObjectKernel + + Description: Destructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TTestObjectKernel::~TTestObjectKernel() + { + + RDebug::Print( _L("TTestObjectKernel::~TTestObjectKernel") ); + + iTestClass.Close(); + User::FreeLogicalDevice( iLddName ); + + } + +/* +------------------------------------------------------------------------------- + + Class: TTestObjectKernel + + Method: RunMethodL + + Description: Run specified method from kernel testclass. + + Parameters: CStifItemParser& aItem: in: itemparser + + Return Values: Symbian OS error code + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt TTestObjectKernel::RunMethodL( CStifItemParser& aItem ) + { + + TPtrC method; + TPtrC params; + + User::LeaveIfError( aItem.GetNextString( method ) ); + aItem.Remainder( params ); + + TInt result; + TMethodResultDes resultDes; + + // Need to change descriptors from 16bit to 8bit for EKA2 kernel + // because STIF Parser doesn't support 8bit parsing + HBufC8 * myBuf1 = HBufC8::NewL( method.Length() ); + TPtr8 met8 = myBuf1->Des(); + met8.Copy( method ); + + HBufC8 * myBuf2 = HBufC8::NewL( params.Length() ); + TPtr8 par8 = myBuf2->Des(); + par8.Copy( params ); + + TInt ret = iTestClass.RunMethod( met8, par8, result, resultDes ); + + delete myBuf1; + delete myBuf2; + + if( ret != KErrNone ) + { + return ret; + } + + return result; + + }; + + +// ================= OTHER EXPORTED FUNCTIONS ================================= + +/* +------------------------------------------------------------------------------- + + Function: LibEntryL + + Description: Polymorphic Dll Entry Point + + Parameters: None. + + Return Values: CTestScripter*: pointer to new CTestScripter + + Errors/Exceptions: Leaves if NewL leaves. + + Status: Draft + +------------------------------------------------------------------------------- +*/ + +EXPORT_C CTestScripter* LibEntryL() + { + return CTestScripter::NewL(); + + } + + +// End of File