--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stif/TestEngine/src/TestEngine.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,6106 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This module contains implementation of
+* CTestEngineServer class member functions.
+*
+*/
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <e32svr.h>
+#include <f32file.h>
+#include "TestEngine.h"
+#include "TestEngineClient.h"
+#include "TestEngineCommon.h"
+#include <stifinternal/TestServerClient.h>
+#include "TestModuleController.h"
+#include "TestCaseController.h"
+#include "TestReport.h"
+#include "Logging.h"
+#include "SettingServerClient.h"
+//--PYTHON-- begin
+#include "StifPython.h"
+#include "StifPythonFunEng.h"
+//--PYTHON-- end
+
+// EXTERNAL DATA STRUCTURES
+// None
+
+// EXTERNAL FUNCTION PROTOTYPES
+// None
+
+// CONSTANTS
+_LIT( KTestModule, "TestModule=" );
+_LIT( KTestCaseFile, "TestCaseFile=" );
+_LIT( KTestCaseNumber, "TestCaseNumber=" );
+_LIT( KTestCaseTitle, "TestCaseTitle=" );
+_LIT( KStateCode, "StateCode=" );
+_LIT( KStateName, "StateName=" );
+
+// MACROS
+// None
+
+// LOCAL CONSTANTS AND MACROS
+// None
+
+// MODULE DATA STRUCTURES
+struct TThreadStartTestEngine
+ {
+ RThread iEngineThread; // The server thread
+ RSemaphore iStarted; // Startup syncronisation semaphore
+ };
+
+// LOCAL FUNCTION PROTOTYPES
+// None
+
+// FORWARD DECLARATIONS
+// None
+
+// ==================== LOCAL FUNCTIONS =======================================
+// None
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Function: ErrorPrint
+
+ Description: ErrorPrint
+
+ Parameters: const TInt aPriority: in: Priority of error
+ TPtrC aError: in: Error description
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ErrorPrint( const TInt aPriority,
+ TPtrC aError )
+ {
+ TErrorNotification error;
+ TErrorNotificationPckg errorPckg ( error );
+
+ error.iModule = _L("TestEngine");
+ error.iPriority = aPriority;
+ error.iText = aError;
+
+ ErrorPrint( errorPckg );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModule
+
+ Method: ErrorPrint
+
+ Description: Sends error notification
+
+ Parameters: TErrorNotificationPckg aError: in: Error
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ErrorPrint( TErrorNotificationPckg aError )
+ {
+ // Add new item to end of queue
+ if ( iErrorQueue.Append ( aError() ) != KErrNone )
+ {
+ RDebug::Print (_L("Error message lost"));
+ return;
+ }
+
+ ProcessErrorQueue();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModule
+
+ Method: ProcessErrorQueue
+
+ Description: Process error queue
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ProcessErrorQueue()
+ {
+ // If message is available, complete first item from queue
+ if ( iErrorMessageAvailable )
+ {
+
+ if ( iErrorQueue.Count() > 0 )
+ {
+ TErrorNotification err = iErrorQueue[0];
+ TErrorNotificationPckg errPckg(err);
+ iErrorQueue.Remove(0);
+
+ TInt r( KErrNone );
+
+ TRAP( r, iErrorMessage.WriteL( 0, errPckg ) );
+
+ // Do not handle errors
+
+ iErrorMessageAvailable = EFalse;
+ iErrorMessage.Complete( KErrNone );
+ }
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: LeaveIfErrorWithNotify
+
+ Description: If error leave with notify
+
+ Parameters: TInt aCode: in: Error code
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::LeaveIfErrorWithNotify( TInt aCode )
+ {
+ LeaveIfErrorWithNotify ( aCode, _L("Check testengine log") );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: LeaveIfErrorWithNotify
+
+ Description: If error leave with notify
+
+ Parameters: TInt aCode: in: Error code
+ const TDesC& aText: in: Descriptive text
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::LeaveIfErrorWithNotify( TInt aCode,
+ const TDesC& aText )
+ {
+ if ( aCode != KErrNone )
+ {
+ LeaveWithNotifyL ( aCode, aText );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: LeaveWithNotifyL
+
+ Description: Leave with notify
+
+ Parameters: TInt aCode: in: Error code
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::LeaveWithNotifyL( TInt aCode )
+ {
+ LeaveWithNotifyL ( aCode, _L("Check testengine log") );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: LeaveWithNotifyL
+
+ Description: Leave with notify
+
+ Parameters: TInt aCode: in: Error code
+ const TDesC& aText: in: Descriptive text
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::LeaveWithNotifyL( TInt aCode,
+ const TDesC& aText )
+ {
+ ErrorPrint ( 0, aText );
+ User::Leave ( aCode );
+
+ }
+
+#define LOGGER iLogger
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: ThreadFunction
+
+ Description: The thread function, where Test Engine lives in.
+
+ Parameters: TAny* aStarted: in: Start info
+
+ Return Values: TInt: Returns always KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngineServer::ThreadFunction( TAny* aStarted )
+ {
+// __UHEAP_MARK;
+
+ // Create cleanup stack
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ __ASSERT_ALWAYS( cleanup, PanicServer( ECreateTrapCleanup ) );
+
+ // Get start-up information
+ TThreadStartTestEngine* startInfo = ( TThreadStartTestEngine* ) aStarted;
+ __ASSERT_ALWAYS( startInfo, PanicServer( ENoStartupInformation ) );
+
+ // Construct and install active scheduler
+ CActiveScheduler* scheduler = new CActiveScheduler;
+ __ASSERT_ALWAYS( scheduler, PanicServer( EMainSchedulerError ) );
+ CActiveScheduler::Install( scheduler );
+
+ // Construct server, an active object
+ CTestEngineServer* server = NULL;
+ TRAPD( err, server = CTestEngineServer::NewL() );
+ __ASSERT_ALWAYS( !err, PanicServer( ESvrCreateServer ) );
+
+ // Inform that we are up and running
+ startInfo->iStarted.Signal();
+
+ // Global mutex(handling according to the name)
+ RMutex startupMutex;
+ // Try to create global mutex, CREATE
+ TInt ret = startupMutex.CreateGlobal( KStifTestServerStartupMutex );
+ if( ret != KErrNone )
+ {
+ // Mutex already create, OPEN
+ ret = startupMutex.OpenGlobal( KStifTestServerStartupMutex );
+ }
+ if( ret != KErrNone )
+ {
+ // Not able to create or open mutex
+ return ret;
+ }
+
+ // Start handling requests
+ CActiveScheduler::Start();
+
+ startupMutex.Close();
+
+ // Should come here after RTestEngineServer is closed
+ delete server;
+ delete scheduler;
+ delete cleanup;
+
+// __UHEAP_MARKEND;
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: CTestEngineServer
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEngineServer::CTestEngineServer() :
+ CServer2( CTestEngineServer::ETestEngineServerPriority ),
+ iSessionCount( 0 )
+ {
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if CObjectConIx::NewL leaves
+ Leaves if CStifLogger::NewL leaves
+ Leaves if StartL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngineServer::ConstructL()
+ {
+ // Create container
+ iContainerIndex = CObjectConIx::NewL();
+
+ // Create logger, in Wins use HTML in HW default logger
+ TLoggerSettings loggerSettings;
+
+ // Directory must create by hand if test engine log wanted
+ loggerSettings.iCreateLogDirectories = EFalse;
+
+ loggerSettings.iOverwrite = ETrue;
+ loggerSettings.iTimeStamp = ETrue;
+ loggerSettings.iLineBreak = ETrue;
+ loggerSettings.iEventRanking = EFalse;
+ loggerSettings.iThreadId = EFalse;
+ loggerSettings.iHardwareFormat = CStifLogger::ETxt;
+#ifndef FORCE_STIF_INTERNAL_LOGGING_TO_RDEBUG
+ loggerSettings.iEmulatorFormat = CStifLogger::EHtml;
+ loggerSettings.iEmulatorOutput = CStifLogger::EFile;
+ loggerSettings.iHardwareOutput = CStifLogger::EFile;
+#else
+ RDebug::Print( _L( "STIF Test Engine logging forced to RDebug" ) );
+ loggerSettings.iEmulatorFormat = CStifLogger::ETxt;
+ loggerSettings.iEmulatorOutput = CStifLogger::ERDebug;
+ loggerSettings.iHardwareOutput = CStifLogger::ERDebug;
+#endif
+ loggerSettings.iUnicode = EFalse;
+ loggerSettings.iAddTestCaseTitle = EFalse;
+
+ iLogger = CStifLogger::NewL( _L( "C:\\logs\\testframework\\testengine\\"),
+ _L( "testengine" ),
+ loggerSettings );
+ // Start Server
+ StartL( KTestEngineName );
+
+ __TRACE(KVerbose, (_L( "CTestEngineServer::ConstructL: Server Created" ) ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: None
+
+ Return Values: CTestEngineServer* : pointer to CTestEngineServer object
+
+ Errors/Exceptions: Leaves if construction of CBufferArray fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEngineServer* CTestEngineServer::NewL()
+ {
+ CTestEngineServer* self = new ( ELeave ) CTestEngineServer();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: ~CTestEngineServer
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEngineServer::~CTestEngineServer()
+ {
+ delete iContainerIndex;
+
+ __TRACE(KAlways, ( _L( "---------------- Log Ended ----------------" ) ) );
+ delete iLogger;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: NewContainerL
+
+ Description: Create new container
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if called CreateL method leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CObjectCon* CTestEngineServer::NewContainerL()
+ {
+ CObjectCon* container = iContainerIndex->CreateL();
+
+ iSessionCount++;
+
+ return container;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: DeleteContainer
+
+ Description: Deletes a container
+
+ Parameters: CObjectCon*
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngineServer::DeleteContainer( CObjectCon* aContainer )
+ {
+ iContainerIndex->Remove( aContainer );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: SessionClosed
+
+ Description: Inform Server that session is closed.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngineServer::SessionClosed()
+ {
+ // Decrease session count
+ iSessionCount--;
+
+ // Check if last session is closed
+ if ( iSessionCount <= 0 )
+ {
+ // Stop the active scheduler
+ // Execution will continue in ThreadFunction()
+ CActiveScheduler::Stop();
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: NewSessionL
+
+ Description: Create a new client session for this server.
+
+ Parameters: const TVersion& aVersion: in: Client side version number
+
+ Return Values: CSharableSession* : pointer to CSharableSession object
+
+ Errors/Exceptions: Leaves if given version is incorrect
+ Leaves if CTestEngine::NewL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CSession2* CTestEngineServer::NewSessionL( const TVersion &aVersion,
+ const RMessage2& /*aMessage*/ ) const
+ {
+ // Check that version is ok
+ TVersion v( KTestEngineMajorVersionNumber,
+ KTestEngineMinorVersionNumber,
+ KTestEngineBuildVersionNumber );
+ if ( !User::QueryVersionSupported( v, aVersion ) )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ return CTestEngine::NewL( ( CTestEngineServer* ) this );
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: PanicServer
+
+ Description: Panic the server
+
+ Parameters: TTestEnginePanic aPanic: in: Panic number
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngineServer::PanicServer( TTestEnginePanic aPanic )
+ {
+ _LIT( KTestServer, "CTestEngineServer" );
+ User::Panic( KTestServer, aPanic );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineServer
+
+ Method: Logger
+
+ Description: Return the pointer to iLogger.
+
+ Parameters: None
+
+ Return Values: CStifLogger*: Pointer to StifLogger
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CStifLogger* CTestEngineServer::Logger()
+ {
+ return iLogger;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestEngine class member functions.
+
+-------------------------------------------------------------------------------
+*/
+#undef LOGGER
+#define LOGGER Logger()
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: CTestEngine
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: RThread& aClient: in: Client's thread
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+ CTestEngine::CTestEngine() :
+ CSession2(),
+ iReportMode( CTestReport::ETestReportFull ),
+ iReportOutput( CTestReport::ETestReportNone ),
+ iEnumerateModuleCount( 0 ),
+ iIsTestReportGenerated( EFalse ),
+ iDisableMeasurement( EEnableAll)
+ {
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: CTestEngineServer* aServer: in: Pointer to CTestEngineServer
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ConstructL( CTestEngineServer* aServer )
+ {
+ // Second-phase construct base class
+ //CSession2::CreateL();
+
+ iTestEngineServer = aServer;
+
+ // Create new object index
+ iTestEngineSubSessions = CObjectIx::NewL();
+
+ // Create new object index
+ iTestCases = CObjectIx::NewL();
+
+ // Initialize the object container from Server
+ iContainer = iTestEngineServer->NewContainerL();
+
+ __TRACE( KInit, ( _L( "CTestEngine::ConstructL: Test Engine Created" ) ) );
+
+
+ RFs iFs;
+ User::LeaveIfError( iFs.Connect() );
+ _LIT(KCSteve,"C:\\Testframework\\");
+ iFs.MkDirAll(KCSteve);
+
+ iFs.Close();
+
+ iRebootDefaultPath.Set( _L( "C:\\TestFramework\\" ) );
+ iRebootDefaultFilename.Set( _L( "Reboot.txt" ) );
+
+ TPtrC dllName;
+ dllName.Set( _L( "StifHWResetStub.dll" ) );
+ iDeviceResetDllName = dllName.AllocL();
+
+ iDefaultTimeout = 0;
+ iUITestingSupport = EFalse;
+ iSeparateProcesses = EFalse;
+
+ iIndexTestModuleControllers = 1;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: RThread& aClient : Client's thread
+ CTestEngineServer* aServer : Pointer to CTestEngineServer
+
+ Return Values: CTestEngine* : pointer to CTestEngine object
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEngine* CTestEngine::NewL( CTestEngineServer* aServer )
+ {
+ CTestEngine* self = new ( ELeave ) CTestEngine();
+ CleanupStack::PushL( self );
+ self->ConstructL( aServer );
+ CleanupStack::Pop();
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: CloseSession
+
+ Description: Close client server session to Test Engine
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::CloseSession()
+ {
+ __TRACE( KInit, ( _L( "CTestEngine::CloseSession" ) ) );
+
+ iErrorQueue.Close();
+
+ // Delete test report
+ delete iTestReport;
+ iTestReport = NULL;
+
+ // Delete device reset module's DLL name
+ delete iDeviceResetDllName;
+ iDeviceResetDllName = NULL;
+
+ // Delete state events
+ iStateEvents.ResetAndDestroy();
+ iStateEvents.Close();
+
+ //Delete Client events
+ iClientEvents.ResetAndDestroy();
+ iClientEvents.Close();
+
+ // Remove contents of iTestCases
+ if ( iTestCases )
+ {
+ TInt handle;
+ CObject* object = NULL;
+ TInt count = iTestCases->Count();
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ object = iTestCases->operator[](i);
+ if ( object )
+ {
+ handle = iTestCases->At( object );
+ iTestCases->Remove( handle );
+ }
+ }
+
+ delete iTestCases;
+ iTestCases = NULL;
+ }
+
+ delete iTestEngineSubSessions;
+ iTestEngineSubSessions = NULL;
+
+ // Delete the object container
+ // This provides unique ids for the objects of this session
+ iTestEngineServer->DeleteContainer( iContainer );
+
+ // Inform server that session is closed
+ iTestEngineServer->SessionClosed();
+
+ delete iIniFile;
+ iIniFile = NULL;
+
+ delete iRebootPath;
+ iRebootPath = NULL;
+
+ delete iRebootFilename;
+ iRebootFilename = NULL;
+
+ delete iRebootParams;
+ iRebootParams = 0;
+
+ __TRACE(KVerbose, ( _L( "CTestEngine::CloseSession finished" ) ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: CountResources
+
+ Description: Resource counding
+
+ Parameters: None
+
+ Return Values: TInt Resource count
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::CountResources()
+ {
+ return iResourceCount;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: NumResources
+
+ Description: Get resources, writes to Message()
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::NumResources( const RMessage2& aMessage )
+ {
+
+ TInt ret( 0 );
+
+ TPckgBuf<TInt> countPckg( iResourceCount );
+
+ TRAP( ret, aMessage.WriteL( 0, countPckg ) );
+
+ if ( ret != KErrNone )
+ {
+ PanicClient( EBadDescriptor, aMessage );
+ }
+
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: PanicClient
+
+ Description: Panic the client
+
+ Parameters: TTestEnginePanic aPanic: in: Panic number
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::PanicClient( TTestEnginePanic aPanic,
+ const RMessage2& aMessage ) const
+ {
+ iTestEngineServer->Logger()->Log( CStifLogger::ERed, _L( "CTestEngine::PanicClient [%d]" ), aPanic );
+
+ _LIT( KTestEngine, "CTestEngine" );
+
+ aMessage.Panic( KTestEngine, aPanic );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ServiceL
+
+ Description: Message handling method that calls trapped DispatchMessageL
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Error from DispatchMessageL is trapped and handled
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ServiceL( const RMessage2& aMessage )
+ {
+ TRAPD( ret, DispatchMessageL( aMessage ) );
+ if ( ret != KErrNone )
+ {
+ __TRACE(KError, ( CStifLogger::ERed, _L( "CTestEngine::DispatchMessageL Function=[%d], left with [%d]" ),
+ aMessage.Function(), ret ) );
+ if( ret == KErrNoMemory )
+ {
+ __TRACE( KError, ( CStifLogger::ERed, _L( "No memory available. Some possibility to do: 1. Reduce test case count. 2. Increase StifTestEngine's heap size." ) ) );
+ }
+ aMessage.Complete( ret );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: DispatchMessageL
+
+ Description: Actual message handling
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::DispatchMessageL( const RMessage2& aMessage )
+ {
+ iComplete = ETrue;
+ iReturn = KErrNone;
+
+ switch ( aMessage.Function() )
+ {
+ case ETestEngineServerCloseSession:
+ {
+ if ( !iIsTestReportGenerated && iTestReport )
+ {
+ iTestReport->GenerateReportL();
+ iIsTestReportGenerated = ETrue;
+ }
+ CloseSession();
+ break;
+ }
+ case ETestEngineCreateSubSession:
+ {
+ InitEngineL( aMessage );
+ break;
+ }
+ case ETestEngineCloseSubSession:
+ {
+ CloseTestEngineL( aMessage.Int3() );
+ break;
+ }
+ case ETestEngineSetAttribute:
+ {
+ SetAttributeL( aMessage );
+ break;
+ }
+
+ case ETestEngineAddTestModule:
+ {
+ AddTestModuleL( aMessage );
+ break;
+ }
+ case ETestEngineRemoveTestModule:
+ {
+ iReturn = RemoveTestModuleL( aMessage );
+ break;
+ }
+ case ETestEngineAddConfigFile:
+ {
+ AddConfigFileL( aMessage );
+ break;
+ }
+ case ETestEngineRemoveConfigFile:
+ {
+ RemoveConfigFileL( aMessage );
+ break;
+ }
+ case ETestEngineEnumerateTestCases:
+ {
+ EnumerateTestCasesL( aMessage );
+ break;
+ }
+ case ETestEngineGetTestCases:
+ {
+ GetTestCasesL( aMessage );
+ break;
+ }
+ case ETestEngineCancelAsyncRequest:
+ {
+ CancelAsyncRequest( aMessage );
+ break;
+ }
+ case ETestEngineEvent:
+ {
+ EventControlL( aMessage );
+ iComplete = EFalse;
+ break;
+ }
+ case ETestEngineErrorNotification:
+ {
+ HandleErrorNotificationL( aMessage );
+ iComplete = EFalse;
+ break;
+ }
+ case ETestEngineLoggerSettings:
+ {
+ LoggerSettings( aMessage );
+ break;
+ }
+ case ETestEngineCloseLoggerSettings:
+ {
+ CloseLoggerSettings();
+ break;
+ }
+ case ETestEngineReportTestCase:
+ {
+ iReturn = AddTestCaseToTestReport(aMessage);
+ break;
+ }
+ // Subsession specific functions
+ case ETestCaseCreateSubSession:
+ {
+ NewTestCaseL( aMessage );
+ break;
+ }
+ case ETestCaseCloseSubSession:
+ {
+ DeleteTestCase( aMessage.Int3() );
+ break;
+ }
+ case ETestCaseRunTestCase:
+ {
+ TestCaseByHandle( aMessage.Int3(), aMessage )->RunTestCaseL( aMessage );
+ iComplete = EFalse;
+ break;
+ }
+ case ETestCasePause:
+ {
+ iReturn = TestCaseByHandle( aMessage.Int3(), aMessage )->Pause();
+ break;
+ }
+ case ETestCaseResume:
+ {
+ iReturn = TestCaseByHandle( aMessage.Int3(), aMessage )->Resume();
+ break;
+ }
+ case ETestCaseNotifyProgress:
+ {
+ TestCaseByHandle( aMessage.Int3(), aMessage )->NotifyProgressL( aMessage );
+ iComplete = EFalse;
+ break;
+ }
+ case ETestCaseNotifyRemoteType:
+ {
+ TestCaseByHandle( aMessage.Int3(), aMessage )->NotifyRemoteTypeL( aMessage );
+ iComplete = EFalse;
+ break;
+ }
+ case ETestCaseNotifyRemoteMsg:
+ {
+ TestCaseByHandle( aMessage.Int3(), aMessage )->NotifyRemoteMsgL( aMessage );
+ iComplete = EFalse;
+ break;
+ }
+ case ETestCaseCancelAsyncRequest:
+ {
+ TestCaseByHandle(
+ aMessage.Int3(), aMessage )->CancelAsyncRequest( aMessage );
+ break;
+ }
+ default:
+ {
+ User::Leave( KErrNotSupported );
+ break;
+ }
+ }
+
+ if ( iComplete )
+ {
+ aMessage.Complete( iReturn );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: InitTestReportAndLoggerVarL
+
+ Description: Initialize Test report and Logger's overwrite parameters
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if memory allocation fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::InitTestReportAndLoggerVarL()
+ {
+ // Test report settings initialization
+ iTestEngineServer->iTestReportSettings.iCreateTestReport = ETrue;
+ _LIT( path, "C:\\LOGS\\TestFramework\\");
+ _LIT( name, "TestReport");
+ iTestEngineServer->iTestReportSettings.iPath = path().AllocL();
+ iTestEngineServer->iTestReportSettings.iName = name().AllocL();
+ iTestEngineServer->iTestReportSettings.iFormat = CStifLogger::ETxt;
+ iTestEngineServer->iTestReportSettings.iOutput = CStifLogger::EFile;
+ iTestEngineServer->iTestReportSettings.iOverwrite = ETrue;
+
+ // Initializations to indicator is setting in use
+ iTestEngineServer->iLoggerSettings.iIsDefined.iCreateLogDir = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iPath = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iHwPath = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iFormat = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iHwFormat = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iOutput = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iHwOutput = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iOverwrite = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iLineBreak = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iTimeStamp = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iEventRanking = EFalse;
+ iTestEngineServer->iLoggerSettings.iIsDefined.iThreadId = EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: InitEngineL
+
+ Description: Init the test engine
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::InitEngineL( const RMessage2& aMessage )
+ {
+
+ // Parse reboot file
+ ParseRebootParamsL();
+
+ TName iniFileName;
+
+ // Read ini file name from aMessage
+ aMessage.ReadL( 0, iniFileName );
+ TStifUtil::CorrectFilePathL( iniFileName );
+
+ iIniFile = iniFileName.AllocL();
+
+ // HBufC to TPtrC
+ TPtrC iniFile( iIniFile->Des() );
+
+ __TRACE( KInit, ( CStifLogger::EBold, _L( "CTestEngine::InitEngineL\t iIniFile=[%S]" ), iIniFile ) );
+
+ // Connect to the Setting server and open handle(Handle will close when
+ // closing TestEngine).
+ TInt ret = iSettingServer.Connect();
+ if ( ret != KErrNone )
+ {
+ User::Leave( ret );
+ }
+
+ InitTestReportAndLoggerVarL();
+
+ if ( iniFile.Length() > 0 )
+ {
+ Logger()->WriteDelimiter();
+ __TRACE( KInit,( _L( "Starting to parse initialization file" ) ) );
+
+ // Set initialization file information to Setting server's side.
+ ret = iSettingServer.SetIniFileInformation( iniFileName );
+ if ( ret != KErrNone )
+ {
+ User::Leave( ret );
+ }
+ // Struct to Logger settigs.
+ TLoggerSettings loggerSettings;
+ // Parse Logger defaults from STIF initialization file.
+ ret = iSettingServer.ReadLoggerSettingsFromIniFile( loggerSettings );
+ if ( ret != KErrNone )
+ {
+ User::Leave( ret );
+ }
+
+ // Create parser for parsing ini file
+ CStifParser* parser = NULL;
+ TRAPD( r, parser = CStifParser::NewL( _L(""), iniFile ) );
+ if ( r != KErrNone )
+ {
+ __TRACE( KError,( CStifLogger::ERed, _L( "Can't open ini-file [%S], code %d" ), &iniFile, r ) );
+ LeaveWithNotifyL(r);
+ }
+
+ CleanupStack::PushL( parser );
+
+ CSTIFTestFrameworkSettings* settings = NULL;
+ TRAPD( settings_ret, settings = CSTIFTestFrameworkSettings::NewL() );
+ CleanupStack::PushL( settings );
+ if ( settings_ret != KErrNone )
+ {
+ __TRACE( KError,( CStifLogger::ERed, _L( "CSTIFTestFrameworkSettings class object creation fails") ) );
+ LeaveWithNotifyL( settings_ret );
+ }
+
+ ReadEngineDefaultsL( parser, settings );
+
+ SetLoggerSettings( loggerSettings ) ;
+
+ ReadTestModulesL( parser );
+
+ CleanupStack::PopAndDestroy( settings );
+ CleanupStack::PopAndDestroy( parser );
+ __TRACE( KInit, ( _L( "Configuration file reading finished" ) ) );
+ }
+ else
+ {
+ __TRACE( KInit,( CStifLogger::EBold, _L( "Initialisation file not specified." ) ) );
+ }
+
+ Logger()->WriteDelimiter();
+
+ // Create Test Reporter if allowed
+ if ( iTestEngineServer->iTestReportSettings.iCreateTestReport )
+ {
+ TRAPD(err, iTestReport =
+ CTestReport::NewL( iTestEngineServer->iTestReportSettings,
+ ( CTestReport::TTestReportMode ) iReportMode ));
+ if(err!=KErrNone)
+ {
+ iTestReport = NULL;
+ __TRACE( KInit,( CStifLogger::ERed, _L( "Test report creation failed with error: %d, test report not created." ), err ) );
+ __TRACE( KInit,( CStifLogger::ERed, _L( "Check your testreport settings from testframework.ini file (e.g. TestReportFilePath)." ) ) );
+ }
+ }
+
+ // Create test engine subsession object
+ CTestEngineSubSession* testEngineSubSession =
+ CTestEngineSubSession::NewL( this );
+ CleanupStack::PushL( testEngineSubSession );
+
+ // Add object to object container to generate unique id
+ iContainer->AddL( testEngineSubSession );
+
+ // Add object to object index
+ // This returns a unique handle so we can get it again
+ TInt handle = iTestEngineSubSessions->AddL( testEngineSubSession );
+
+ // Write the handle to client
+ TPckg<TInt> handlePckg( handle );
+
+ TRAPD( res, aMessage.WriteL( 3, handlePckg ) );
+ if ( res != KErrNone )
+ {
+ iTestEngineSubSessions->Remove( handle );
+ PanicClient( EBadDescriptor, aMessage );
+ return;
+ }
+
+ CleanupStack::Pop( testEngineSubSession );
+
+ // Notch up another resource
+ iResourceCount++;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ReadEngineDefaults
+
+ Description: Parse Test Engine defaults from STIF
+ initialization file.
+
+ Parameters: CStifParser& parser: in: CStifParser object
+ CSTIFTestFrameworkSettings* aSettings: in:
+ CSTIFTestFrameworkSettings object
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ReadEngineDefaultsL( CStifParser* aParser,
+ CSTIFTestFrameworkSettings* aSettings )
+ {
+ __TRACE( KInit,( _L( "" ) ) );
+ __TRACE( KInit,( _L( "Start parsing engine defaults" ) ) );
+ TInt get_ret( KErrNone );
+
+ CStifSectionParser* sectionParser = NULL;
+
+ // Parse Engine's default values
+ _LIT( KDefaultsStart, "[Engine_Defaults]" );
+ _LIT( KDefaultsEnd, "[End_Defaults]" );
+ __TRACE( KInit,( _L( "Starting to search sections" ) ) );
+ sectionParser = aParser->SectionL( KDefaultsStart, KDefaultsEnd );
+ CleanupStack::PushL( sectionParser );
+ if ( sectionParser )
+ {
+ __TRACE( KInit,( _L( "Found '%S' and '%S' sections" ), &KDefaultsStart, &KDefaultsEnd ) );
+
+ // Get Test Report Mode
+ __TRACE( KInit,( _L( "Parsing Test report mode" ) ) );
+ TUint reportMode( 0 );
+ get_ret = aSettings->GetReportModeL( sectionParser,
+ _L( "TestReportMode=" ), reportMode );
+ if ( get_ret == KErrNone )
+ {
+ __TRACE( KInit,( _L( "Report mode: %d"), reportMode ) );
+ iReportMode = reportMode;
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Report mode not found or not given" ) ) );
+ }
+
+ // Indicator to test report creation
+ __TRACE( KInit,( _L( "Parsing Test report creation indicator" ) ) );
+ TBool createTestReport( 0 );
+ get_ret = aSettings->GetBooleanSettingsL( sectionParser,
+ _L( "CreateTestReport=" ), createTestReport );
+ if ( get_ret == KErrNone )
+ {
+ __TRACE( KInit,( _L( "Test report creation indicator: %d"), createTestReport ) );
+ iTestEngineServer->iTestReportSettings.iCreateTestReport = createTestReport;
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Creation indicator not found or not given" ) ) );
+ }
+
+ // Get Test report path settings
+ if ( iTestEngineServer->iTestReportSettings.iCreateTestReport )
+ {
+ __TRACE( KInit,( _L( "Parsing Test report path" ) ) );
+ TPtrC path;
+ get_ret = aSettings->GetFileSetting( sectionParser,
+ _L( "TestReportFilePath=" ), path );
+ if ( get_ret == KErrNone )
+ {
+ __TRACE( KInit,( _L( "Test report path: %S"), &path ) );
+ // Delete old one before setting new one
+ delete iTestEngineServer->iTestReportSettings.iPath;
+ iTestEngineServer->iTestReportSettings.iPath = NULL;
+ iTestEngineServer->iTestReportSettings.iPath = path.AllocL();
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Path not found or not given" ) ) );
+ }
+ }
+
+ // Get Test report name settings
+ if ( iTestEngineServer->iTestReportSettings.iCreateTestReport )
+ {
+ __TRACE( KInit,( _L( "Parsing Test report filename" ) ) );
+ TPtrC name;
+ get_ret = aSettings->GetFileSetting( sectionParser,
+ _L( "TestReportFileName=" ), name );
+ if ( get_ret == KErrNone )
+ {
+ __TRACE( KInit,( _L( "Test report filename: %S"), &name ) );
+ // Delete old one before setting new one
+ delete iTestEngineServer->iTestReportSettings.iName;
+ iTestEngineServer->iTestReportSettings.iName = NULL;
+ iTestEngineServer->iTestReportSettings.iName = name.AllocL();
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Filename not found or not given" ) ) );
+ }
+ }
+
+ // Get Test report format settings
+ if ( iTestEngineServer->iTestReportSettings.iCreateTestReport )
+ {
+ __TRACE( KInit,( _L( "Parsing Test report format" ) ) );
+ CStifLogger::TLoggerType type;
+ TBool xml;
+ get_ret = aSettings->GetFormatL( sectionParser,
+ _L( "TestReportFormat=" ), type, xml );
+ if ( get_ret == KErrNone )
+ {
+ __TRACE( KInit,( _L( "Test report format: %d, xml: %d"), type, xml ) );
+ iTestEngineServer->iTestReportSettings.iFormat = type;
+ iTestEngineServer->iTestReportSettings.iXML = xml;
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Format not found or not given" ) ) );
+ }
+ }
+
+ // Get Test report output settings
+ if ( iTestEngineServer->iTestReportSettings.iCreateTestReport )
+ {
+ __TRACE( KInit,( _L( "Parsing Test report output" ) ) );
+ CStifLogger::TOutput output;
+ get_ret = aSettings->GetOutputL( sectionParser,
+ _L( "TestReportOutput=" ), output );
+ if ( get_ret == KErrNone )
+ {
+ __TRACE( KInit,( _L( "Test report output: %d"), output ) );
+ iTestEngineServer->iTestReportSettings.iOutput = output;
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Output not found or not given" ) ) );
+ }
+ }
+
+ // Get Test report file creation mode (overwrite settings)
+ if ( iTestEngineServer->iTestReportSettings.iCreateTestReport )
+ {
+ __TRACE( KInit,( _L( "Parsing Test report file writing mode" ) ) );
+ TBool overwrite;
+ get_ret = aSettings->GetOverwriteL( sectionParser,
+ _L( "TestReportFileCreationMode=" ), overwrite );
+ if ( get_ret == KErrNone )
+ {
+ __TRACE( KInit,( _L( "Test report file creation mode: %d"), overwrite ) );
+ iTestEngineServer->iTestReportSettings.iOverwrite = overwrite;
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Writing mode not found or not given" ) ) );
+ }
+ }
+ // Get device reset module's DLL name
+ __TRACE( KInit,( _L( "Parsing device reset module's DLL name" ) ) );
+ TPtrC deviceResetName;
+ get_ret = aSettings->GetFileSetting( sectionParser,
+ _L( "DeviceResetDllName=" ), deviceResetName );
+ if ( get_ret == KErrNone )
+ {
+ __TRACE( KInit,( _L( "Device reset module's name: %S"), &deviceResetName ) );
+ // Delete old one before setting new one
+ delete iDeviceResetDllName;
+ iDeviceResetDllName = NULL;
+ iDeviceResetDllName = deviceResetName.AllocL();
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Device reset module's name not found or not given" ) ) );
+ }
+
+ // Get measurement disable option
+ CStifItemParser* item = NULL;
+ TRAPD( ret, item = sectionParser->GetItemLineL( _L( "DisableMeasurement=" ), ENoTag ) );
+ if( ( ret != KErrNone ) || ( item == NULL ) )
+ {
+ __TRACE( KInit,( _L( "Measurement 'DiableMeasurement=' not found or not given" ) ) );
+ delete item;
+ item = NULL;
+ }
+ else
+ {
+ CleanupStack::PushL( item );
+ TPtrC string;
+ ret = item->GetString( KNullDesC(), string );
+ while( ret == KErrNone )
+ {
+ HBufC* stringHbuf = string.AllocL();
+ TPtr modifiableString = stringHbuf->Des();
+ modifiableString.LowerCase();
+
+ if( modifiableString == KStifMeasurementDisableNone ||
+ modifiableString == KStifMeasurementDisableAll ||
+ modifiableString == KStifMeasurement01 ||
+ modifiableString == KStifMeasurement02 ||
+ modifiableString == KStifMeasurement03 ||
+ modifiableString == KStifMeasurement04 ||
+ modifiableString == KStifMeasurement05 ||
+ modifiableString == KStifMeasurementBappea )
+ {
+ __TRACE( KInit,( _L( "Measurement disable option: %S"), &modifiableString ) );
+ DisableStifMeasurement( modifiableString );
+ }
+ else if( modifiableString == _L( "#" ) )
+ {
+ delete stringHbuf;
+ stringHbuf = NULL;
+ break;
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Measurement disable option not found or not given" ) ) );
+ delete stringHbuf;
+ stringHbuf = NULL;
+ break;
+ }
+ delete stringHbuf;
+ ret = item->GetNextString( string );
+ }
+ CleanupStack::PopAndDestroy( item );
+ item = NULL;
+ }
+
+ // Get timeout value option
+ __TRACE(KInit, (_L("Parsing default timeout value")));
+ iDefaultTimeout = 0;
+ item = NULL;
+ TRAP(ret, item = sectionParser->GetItemLineL(_L("Timeout=" ), ENoTag));
+ if( ( ret != KErrNone ) || ( item == NULL ) )
+ {
+ __TRACE(KInit, (_L("'Timeout' option not found or not given")));
+ delete item;
+ item = NULL;
+ }
+ else
+ {
+ CleanupStack::PushL( item );
+ TPtrC string;
+ ret = item->GetString(KNullDesC(), string);
+ if(string.Length() > 0)
+ {
+ TLex lex(string);
+ ret = lex.Val(iDefaultTimeout);
+ if(ret != KErrNone)
+ {
+ __TRACE(KError, (_L("Could not convert timeout value '%S' to integer. Error %d. Ignoring this setting."), &string, ret));
+ }
+ if(iDefaultTimeout < 0)
+ {
+ __TRACE(KError, (_L("'Timeout' value cannot be negative. Resetting to 0.")));
+ iDefaultTimeout = 0;
+ }
+ }
+ else
+ {
+ __TRACE(KInit, (_L("'Timeout' value not given")));
+ }
+ CleanupStack::PopAndDestroy( item );
+ item = NULL;
+ }
+ __TRACE(KInit, (_L("'Timeout' value set to %d"), iDefaultTimeout));
+ iDefaultTimeout *= 1000;
+
+ // Get UITestingSupport value option
+ __TRACE(KInit, (_L("Parsing UITestingSupport value")));
+ iUITestingSupport = EFalse;
+ item = NULL;
+ TRAP(ret, item = sectionParser->GetItemLineL(_L("UITestingSupport=" ), ENoTag));
+ if((ret != KErrNone) || (item == NULL))
+ {
+ __TRACE(KInit, (_L("'UITestingSupport' option not found")));
+ delete item;
+ item = NULL;
+ }
+ else
+ {
+ CleanupStack::PushL(item);
+ TPtrC string;
+ ret = item->GetString(KNullDesC(), string);
+ if(string.Length() > 0)
+ {
+ iUITestingSupport = (string == _L("YES"));
+ }
+ else
+ {
+ __TRACE(KInit, (_L("'UITestingSupport' value not given")));
+ }
+ CleanupStack::PopAndDestroy(item);
+ item = NULL;
+ }
+ __TRACE(KInit, (_L("'UITestingSupport' value set to %d"), iUITestingSupport));
+
+ // Get SeparateProcesses value option
+ __TRACE(KInit, (_L("Parsing SeparateProcesses value")));
+ iSeparateProcesses = EFalse;
+ item = NULL;
+ TRAP(ret, item = sectionParser->GetItemLineL(_L("SeparateProcesses=" ), ENoTag));
+ if((ret != KErrNone) || (item == NULL))
+ {
+ __TRACE(KInit, (_L("'SeparateProcesses' option not found")));
+ delete item;
+ item = NULL;
+ }
+ else
+ {
+ CleanupStack::PushL(item);
+ TPtrC string;
+ ret = item->GetString(KNullDesC(), string);
+ if(string.Length() > 0)
+ {
+ iSeparateProcesses = (string == _L("YES"));
+ }
+ else
+ {
+ __TRACE(KInit, (_L("'SeparateProcesses' value not given")));
+ }
+ CleanupStack::PopAndDestroy(item);
+ item = NULL;
+ }
+ __TRACE(KInit, (_L("'SeparateProcesses' value set to %d"), iSeparateProcesses));
+ }
+ else
+ {
+ __TRACE( KInit,( _L( "Not found '%S' and '%S' sections" ), &KDefaultsStart, &KDefaultsEnd ) );
+ }
+ __TRACE( KInit,( _L( "End parsing engine defaults" ) ) );
+ CleanupStack::PopAndDestroy( sectionParser );
+
+ // Store engine settings to SettingServer
+ RSettingServer settingServer;
+ TInt ret = settingServer.Connect();
+ if(ret != KErrNone)
+ {
+ __TRACE(KError, (_L("Could not connect to SettingServer [%d] and store engine settings"), ret));
+ }
+ else
+ {
+ TEngineSettings settings;
+ settings.iUITestingSupport = iUITestingSupport;
+ settings.iSeparateProcesses = iSeparateProcesses;
+ ret = settingServer.StoreEngineSettings(settings);
+ if(ret != KErrNone)
+ {
+ __TRACE(KError, (_L("Could not store engine settings to SettingServer [%d]"), ret));
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Engine settings succesfully stored to SettingServer")));
+ }
+ settingServer.Close();
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: SetLoggerSettings
+
+ Description: Set parsed logger's settings to TestEngine side.
+
+ Parameters: TLoggerSettings& aLoggerSettings: in: Parsed logger settings
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::SetLoggerSettings( TLoggerSettings& aLoggerSettings )
+ {
+ iTestEngineServer->iLoggerSettings = aLoggerSettings;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ParseTestModulesL
+
+ Description: Parse and search for module info and fill list of modules.
+
+ Parameters: CStifParser* aParser: in: CStifParser object
+ CTestModuleList* aModuleList: in: list of modules
+ TPtrC& aSectionStart: in: descriptor with start of section string
+ TPTrC& aSectionEnd: in: descriptor with end of section string
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ParseTestModulesL(CStifParser* aParser, CTestModuleList* aModuleList, const TDesC& aSectionStart, const TDesC& aSectionEnd)
+ {
+ //First let's find all modules given in Stif's ini file and store that info in CTestModuleList object
+ CStifSectionParser* sectionParser = NULL;
+ CStifItemParser* item = NULL;
+
+ sectionParser = aParser->SectionL(aSectionStart, aSectionEnd);
+
+ while(sectionParser)
+ {
+ __TRACE(KInit, (_L("Found '%S' and '%S' sections"), &aSectionStart, &aSectionEnd));
+ CleanupStack::PushL(sectionParser);
+ __TRACE(KInit, (_L("Starting to read module information")));
+
+ // Get name of module
+ _LIT(KModuleName, "ModuleName=");
+ item = sectionParser->GetItemLineL(KModuleName);
+ CleanupStack::PushL(item);
+ if(!item)
+ {
+ CleanupStack::PopAndDestroy(item);
+ __TRACE(KError, (CStifLogger::ERed, _L("'%S' not found from Module section"), &KModuleName));
+ LeaveIfErrorWithNotify(KErrNotFound);
+ }
+ else
+ {
+ __TRACE(KInit, (_L("'%S' found"), &KModuleName));
+ }
+
+ TPtrC name;
+ TName moduleName;
+ TInt ret(KErrNone);
+ ret = item->GetString(KModuleName, name);
+ if(ret != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(item);
+ __TRACE(KError, (CStifLogger::ERed, _L("Module name parsing left with error %d"), ret));
+ LeaveIfErrorWithNotify(ret);
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Module '%S' found from ini-file"), &name));
+ moduleName.Copy(name);
+ moduleName.LowerCase();
+ ret = aModuleList->AddTestModule(moduleName);
+ if(ret != KErrNone && ret != KErrAlreadyExists)
+ {
+ CleanupStack::PopAndDestroy(item);
+ __TRACE(KError, (CStifLogger::ERed, _L("Could not add module to list of modules. Error %d"), ret));
+ LeaveIfErrorWithNotify(ret);
+ }
+ }
+ CleanupStack::PopAndDestroy(item);
+
+ //Get pointer to added module
+ CTestModuleInfo* moduleInfo = aModuleList->GetModule(moduleName);
+ if(!moduleInfo)
+ {
+ __TRACE(KError, (CStifLogger::ERed, _L("Could not add get module info from list")));
+ LeaveIfErrorWithNotify(KErrNotFound);
+ }
+
+ // Get ini file, if it exists
+ __TRACE(KInit, (_L("Start parsing ini file")));
+ _LIT(KIniFile, "IniFile=");
+ item = sectionParser->GetItemLineL(KIniFile);
+ if(item)
+ {
+ __TRACE(KInit, (_L("'%S' found"), &KIniFile));
+ CleanupStack::PushL(item);
+ TPtrC iniFile;
+ ret = item->GetString(KIniFile, iniFile);
+ if(ret == KErrNone)
+ {
+ // Module inifile (might be empty) OK
+ TFileName filename;
+ filename.Copy(iniFile);
+ TStifUtil::CorrectFilePathL( filename );
+ filename.LowerCase();
+ __TRACE(KInit, (CStifLogger::EBold, _L("Initialization file '%S' found, file can be empty"), &iniFile));
+ moduleInfo->SetIniFile(filename);
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Initialization file not found")));
+ }
+ CleanupStack::PopAndDestroy(item);
+ }
+ else
+ {
+ __TRACE(KInit, (_L("'%S' not found"), &KIniFile));
+ }
+
+ // Get config (testcase) file
+ __TRACE(KInit, (_L("Start parsing cfg files")));
+ TPtrC cfgTag;
+ for(TInt i = 0; i < 2; i++)
+ {
+ //Set tag for config files
+ if(i == 0)
+ {
+ cfgTag.Set(_L("ConfigFile="));
+ }
+ else
+ {
+ cfgTag.Set(_L("TestCaseFile="));
+ }
+ //Read data
+ item = sectionParser->GetItemLineL(cfgTag);
+ while(item)
+ {
+ CleanupStack::PushL(item);
+ __TRACE(KInit, (_L("Item '%S' found"), &cfgTag));
+ TPtrC cfgFile;
+ ret = item->GetString(cfgTag, cfgFile);
+ if(ret == KErrNone)
+ {
+ TFileName ifile;
+ ifile.Copy(cfgFile);
+ TStifUtil::CorrectFilePathL( ifile );
+ ifile.LowerCase();
+ __TRACE(KInit, (_L("Configuration file '%S' found"), &ifile));
+ moduleInfo->AddCfgFile(ifile);
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Configuration file not found")));
+ }
+ CleanupStack::PopAndDestroy(item);
+ item = sectionParser->GetNextItemLineL(cfgTag);
+ }
+ }
+
+ __TRACE(KInit, (_L("Module '%S' information read correctly"), &moduleName));
+
+ // Get next section...
+ CleanupStack::PopAndDestroy(sectionParser);
+ sectionParser = aParser->NextSectionL(aSectionStart, aSectionEnd);
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ReadTestModules
+
+ Description: Parse Test modules and module information from
+ STIF initialization file.
+
+ Parameters: CStifParser& parser: in: CStifParser object
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ReadTestModulesL(CStifParser* aParser)
+ {
+ __TRACE( KInit, (_L("")));
+ __TRACE( KInit, (CStifLogger::EBold, _L("Start parsing test modules")));
+
+ //Create CTestModuleList object. It will keep information about all found test modules,
+ //its initialization files and test case (config) files.
+ CTestModuleList* moduleList = CTestModuleList::NewL(Logger());
+ CleanupStack::PushL(moduleList);
+
+ // Parse Test Module information
+ _LIT(KTestModuleStart, "[New_Module]");
+ _LIT(KTestModuleEnd, "[End_Module]");
+
+ __TRACE(KInit, (_L("Starting to search module sections")));
+ ParseTestModulesL(aParser, moduleList, KTestModuleStart, KTestModuleEnd);
+ __TRACE(KInit, (CStifLogger::EBold, _L("End parsing test modules")));
+ __TRACE(KInit, (_L("")));
+
+ //Now, find included test modules and also add them to CTestModuleList object.
+ _LIT(KIncludeModuleStart, "[New_Include_Module]");
+ _LIT(KIncludeModuleEnd, "[End_Include_Module]");
+
+ __TRACE(KInit, (CStifLogger::EBold, _L("Start parsing included modules")));
+ CTestCaseFileInfo* finfo = moduleList->GetUncheckedCfgFile();
+ while(finfo)
+ {
+ TFileName fname;
+ finfo->GetCfgFileName(fname);
+
+ __TRACE(KInit, (_L("checking file: '%S'"), &fname));
+ finfo->SetChecked();
+
+ CStifParser* parser = NULL;
+
+ TRAPD(err, parser = CStifParser::NewL(_L(""), fname));
+ if(err == KErrNotFound)
+ {
+ __TRACE(KError, (CStifLogger::ERed, _L("Could not open file '%S'"), &fname));
+ }
+ else if(err != KErrNone)
+ {
+ __TRACE(KError, (CStifLogger::ERed, _L("Could not create parser for file '%S'"), &fname));
+ LeaveIfErrorWithNotify(err);
+ }
+ else
+ {
+ CleanupStack::PushL(parser);
+
+ ParseTestModulesL(parser, moduleList, KIncludeModuleStart, KIncludeModuleEnd);
+
+ CleanupStack::PopAndDestroy(parser);
+ }
+
+ finfo = moduleList->GetUncheckedCfgFile();
+ }
+
+ __TRACE(KInit, (CStifLogger::EBold, _L("End parsing included modules")));
+ __TRACE(KInit, (_L("")));
+
+ //Now, when all modules have been found, create them
+ __TRACE(KInit, (CStifLogger::EBold, _L("Start creating modules")));
+ TBool afterReset = EFalse;
+ if(iRebootParams)
+ {
+ afterReset = ETrue;
+ }
+ CTestModuleInfo* moduleInfo = NULL;
+ TInt i;
+ TInt modCnt = moduleList->Count();
+
+ for(i = 0; i < modCnt; i++)
+ {
+ moduleInfo = moduleList->GetModule(i);
+ if(!moduleInfo)
+ {
+ __TRACE(KInit, (CStifLogger::ERed, _L("Could not get module info at index %d"), i));
+ TName error;
+ error.AppendFormat(_L("Could not get module info at index %d"), i);
+ ErrorPrint(1, error);
+ continue;
+ }
+
+ TName moduleName;
+ moduleInfo->GetModuleName(moduleName);
+
+ // Create module controller
+ __TRACE(KInit, (_L("Creating module controller for '%S'"), &moduleName));
+ CTestModuleController* module = NULL;
+ if( moduleName == _L( "testscripter" ) )
+ {
+ module = CTestModuleController::NewL(this, moduleName, afterReset, ETrue);
+ }
+ else
+ {
+ module = CTestModuleController::NewL(this, moduleName, afterReset);
+ }
+ CleanupStack::PushL(module);
+ __TRACE(KInit, (_L("Module controller created")));
+
+ // Get ini file, if exists
+ __TRACE(KInit, (_L("Checking ini file")));
+ TFileName ini;
+ moduleInfo->GetIniFileName(ini);
+ if(ini.Length() == 0)
+ {
+ __TRACE(KInit, (_L("Ini file not found")));
+ }
+
+ TRAPD(err, module->InitL(ini, KNullDesC));
+ if(err != KErrNone)
+ {
+ __TRACE(KInit, (CStifLogger::ERed, _L("Module '%S' loading failed: %d"), &moduleName, err));
+ TName error;
+ error.AppendFormat(_L("Module '%S' loading failed: %d"), &moduleName, err);
+ ErrorPrint(1, error);
+
+ CleanupStack::PopAndDestroy(module);
+ continue;
+ }
+
+ //Add test case files
+ __TRACE(KInit, (_L("Checking cfg files")));
+ TInt cfgCnt = moduleInfo->CountCfgFiles();
+ TInt j;
+ TFileName cfgFile;
+ for(j = 0; j < cfgCnt; j++)
+ {
+ moduleInfo->GetCfgFileName(j, cfgFile);
+ if(cfgFile.Length() > 0)
+ {
+ __TRACE(KInit, (_L("Adding config file '%S'"), &cfgFile));
+ module->AddConfigFileL(cfgFile);
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Got empty config filename")));
+ }
+ }
+ if(cfgCnt == 0)
+ {
+ __TRACE(KInit, (_L("Cfg file not found")));
+ }
+
+ __TRACE(KInit, (_L("Module '%S' created correctly"), &moduleName));
+
+ // Store module for later use
+ User::LeaveIfError(iModules.Append(module));
+ CleanupStack::Pop(module);
+ }
+
+ __TRACE(KInit, (CStifLogger::EBold, _L("End creating test modules")));
+ __TRACE(KInit, (_L("")));
+
+ //Check if there are any modules added to Stif
+ if (iModules.Count() == 0)
+ {
+ __TRACE(KInit, (_L("Not found '%S' and '%S' sections"), &KTestModuleStart, &KTestModuleEnd));
+ __TRACE(KInit, (CStifLogger::EBold, _L("Test module(s) not defined in initialisation file")));
+ // Note is printed from UI, not from here anymore
+ // ErrorPrint( 0 , _L("Test modules not found. Check testengine log"));
+ }
+
+ //Delete CTestModuleList object. It is not needed any more
+ CleanupStack::PopAndDestroy(moduleList);
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: TestModuleConfigFileL
+
+ Description: Add config file to test module
+
+ Parameters: CTestModuleController* aModule: in: CTestModuleController
+ object.
+ CStifSectionParser* aSectionParser: in: CStifSectionParser
+ object.
+ TDesC& aTag :in: Founded tag.
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if GetNextItemLineL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::TestModuleConfigFileL( CTestModuleController* aModule,
+ CStifSectionParser* aSectionParser,
+ TDesC& aTag )
+ {
+ // Add config files to Test Module
+ TPtrC configFile;
+ CStifItemParser* item = NULL;
+ item = aSectionParser->GetItemLineL( aTag );
+
+ TInt cfgFiles = 0;
+ TFileName config;
+
+ TInt ret( 0 );
+
+ while ( item )
+ {
+ __TRACE( KInit,( _L( "Found '%S' section" ), &aTag ) );
+ CleanupStack::PushL( item );
+ ret = item->GetString( aTag, configFile );
+ if ( ret != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( item );
+ __TRACE( KError, ( CStifLogger::ERed, _L( "File parsing left with error [%d]" ), ret ) );
+ }
+ else
+ {
+ config = configFile;
+ aModule->AddConfigFileL( config );
+
+ // Module configfile (might be empty) OK
+ __TRACE( KInit,( _L( "Adding configuration file [%S]" ), &config ) );
+ cfgFiles++;
+ CleanupStack::PopAndDestroy( item );
+ }
+ item = aSectionParser->GetNextItemLineL( aTag );
+ }
+
+ // Print trace
+ if ( cfgFiles == 0)
+ {
+ __TRACE( KInit,( _L( "Module does not have '%S' files") , &aTag ) );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ModuleControllerByName
+
+ Description: Return the module controller specified by given parameter.
+
+ Parameters: const TName& aModuleName: in: Test module name
+
+ Return Values: CTestModuleController* : pointer to CTestModuleController
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController* CTestEngine::ModuleControllerByName(
+ const TName& aModuleName )
+ {
+ TInt modules = iModules.Count();
+
+ for ( TInt i = 0; i < modules; i++ )
+ {
+ if ( iModules[i]->ModuleName( aModuleName ) == aModuleName )
+ {
+ return iModules[i];
+ }
+ }
+ return NULL;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: GetFreeOrCreateModuleControllerL
+
+ Description: Return free module controller specified by given parameter.
+ If it can't be found, new one will be created.
+
+ Parameters: TTestInfo& aTestInfo: test info structure
+ CTestModuleController** aRealModuleController: for test scripter a real module controller will be returned
+
+ Return Values: CTestModuleController* : pointer to CTestModuleController
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController* CTestEngine::GetFreeOrCreateModuleControllerL(TTestInfo& aTestInfo,
+ CTestModuleController** aRealModuleController)
+ {
+ TInt i, j;
+ *aRealModuleController = NULL;
+
+ TInt modules = iModules.Count();
+
+ //Find out which way it should be processed
+ //New way means that Stif is going to find free test module controller
+ //(free means that it does not run any test case)
+ TBool oldWay = ETrue;
+ if((iUITestingSupport && aTestInfo.iModuleName.Find(KTestScripterName) == 0)
+ || (aTestInfo.iModuleName == KPythonScripter)
+ || (iSeparateProcesses))
+ {
+ __TRACE(KInit, (_L("Module controllers handling mode: exclusive")));
+ //Exclusive mode means that every test case must be run in separate module controller.
+ oldWay = EFalse;
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Module controllers handling mode: normal")));
+ oldWay = ETrue;
+ }
+
+ //If option is not set and it is not python scripter case
+ //(python scripter always should look for free module controller)
+ //This is the old way
+ if(oldWay)
+ {
+ __TRACE(KInit, (_L("Find test module controller for [%S]"), &aTestInfo.iModuleName));
+ for(i = 0; i < modules; i++)
+ {
+ if(iModules[i]->ModuleName(aTestInfo.iModuleName) == aTestInfo.iModuleName)
+ {
+ __TRACE(KInit, (_L("Found test module controller for [%S]"), &aTestInfo.iModuleName));
+ return iModules[i];
+ }
+ }
+ __TRACE(KInit, (_L("Test module controller for [%S] NOT FOUND"), &aTestInfo.iModuleName));
+ return NULL;
+ }
+
+ //This is a new way
+ __TRACE(KInit, (_L("Find free test module controller for [%S]"), &aTestInfo.iModuleName));
+
+ TName moduleName(aTestInfo.iModuleName);
+ CTestModuleController* parentController = NULL;
+
+ //First find original test module controller (parent)
+ for(TInt i = 0; i < modules; i++)
+ {
+ if(iModules[i]->ModuleName(moduleName) == moduleName)
+ {
+ parentController = iModules[i];
+ __TRACE(KInit, (_L("Original (parent) module controller found [%S]"), &moduleName));
+ break;
+ }
+ }
+
+ //Search free module controller among parent's children
+ if(parentController)
+ {
+ //TestScripter is handled in other way
+ if(moduleName.Find(KTestScripterName) == 0)
+ {
+ __TRACE(KInit, (_L("This is testscripter case. Searching real module controller.")));
+ *aRealModuleController = parentController->GetFreeOrCreateModuleControllerL(aTestInfo, iUITestingSupport);
+ return parentController;
+ }
+
+ //When UITestingSupport always create new module controller!
+ TInt childrenCount = parentController->iChildrenControllers.Count();
+ for(TInt i = 0; i < childrenCount; i++)
+ {
+ if(parentController->iChildrenControllers[i]->iTestCaseCounter == 0)
+ {
+ if(iUITestingSupport && aTestInfo.iModuleName.Find(KTestScripterName) == 0)
+ {
+ __TRACE(KInit, (_L("Free module controller found but in UITestingSupport mode always new one will be created")));
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Free module controller found [%S]"), parentController->iChildrenControllers[i]->iName));
+ return parentController->iChildrenControllers[i];
+ }
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Module controller [%S] found but it is not free (it runs %d test cases)"), parentController->iChildrenControllers[i]->iName, parentController->iChildrenControllers[i]->iTestCaseCounter));
+ }
+ }
+ }
+ else
+ {
+ __TRACE(KError, (_L("Parent module controller NOT found [%S]"), &moduleName));
+ User::Leave(KErrNotFound);
+ }
+
+ //No free module controller has been found. Create new one.
+ TBuf<10> ind;
+ ind.Format(_L("%d"), GetIndexForNewTestModuleController());
+ moduleName.Append(_L("@"));
+ moduleName.Append(ind);
+ __TRACE(KInit, (_L("Free module controller not found. Creating new one [%S]."), &moduleName));
+
+ //Create server and active object (This uses CTestModuleController::InitL())
+ CTestModuleController* module = CTestModuleController::NewL(this, moduleName, parentController->iAfterReboot);
+ CleanupStack::PushL(module);
+
+ TRAPD(err, module->InitL(parentController->iInifile, aTestInfo.iConfig));
+ if(err != KErrNone)
+ {
+ __TRACE(KInit, (_L("InitL fails with error: %d for module [%S]" ), err, &moduleName));
+ User::Leave(err);
+ }
+ __TRACE(KInit, (_L("New module controller created [%S]."), &moduleName));
+
+ // Store module for later use
+ User::LeaveIfError(parentController->iChildrenControllers.Append(module));
+ CleanupStack::Pop(module);
+ __TRACE(KInit, (_L("Child added to [%S] controller. Currently it has %d children:"), parentController->iName, parentController->iChildrenControllers.Count()));
+ for(j = 0; j < parentController->iChildrenControllers.Count(); j++)
+ {
+ __TRACE(KInit, (_L(" %d. [%S]"), j + 1, parentController->iChildrenControllers[j]->iName));
+ }
+
+ return module;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: SetAttributeL
+
+ Description: Sets attributes to Test Framework
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leave if ReadL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::SetAttributeL( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::SetAttributeL" ) ) );
+
+ TAttribute attribute;
+ TName genericTName;
+
+ // Read attribute from aMessage
+ attribute = (TAttribute)aMessage.Int0();
+
+ switch( attribute )
+ {
+ // Path attribute
+ case ELogPath:
+ {
+ // Read path from aMessage.
+ // NOTE!If message length is over TName, ReadL will cut the message
+ // to allowed size and won't return any error code or leave code.
+ aMessage.ReadL( 1, genericTName );
+
+ // Handle to Setting server.
+ RSettingServer settingServer;
+ // Connect to the Setting server and create session
+ TInt ret = settingServer.Connect();
+ if ( ret != KErrNone )
+ {
+ User::Leave( ret );
+ }
+ settingServer.SetNewIniFileSetting( genericTName );
+ // Close Setting server session
+ settingServer.Close();
+ break;
+ }
+ // Reboot directory
+ case ERebootPath:
+ {
+ // Read reboot path from aMessage.
+ // NOTE!If message length is over TName, ReadL will cut the message
+ // to allowed size and won't return any error code or leave code.
+ aMessage.ReadL( 1, genericTName );
+ // Allocated dynamically iRebootPath size and copies aMessage path.
+ iRebootPath = genericTName.AllocL();
+ break;
+ }
+ // Reboot path
+ case ERebootFilename:
+ {
+ // Read reboot path from aMessage.
+ // NOTE!If message length is over TName, ReadL will cut the message
+ // to allowed size and won't return any error code or leave code.
+ aMessage.ReadL( 1, genericTName );
+ // Allocated dynamically iRebootFilename size and copies aMessage
+ // filename.
+ iRebootFilename = genericTName.AllocL();
+ break;
+ }
+ // Measurement configuration info
+ case EStifMeasurementOn:
+ {
+ // Read Measurement configuration info from aMessage.
+ aMessage.ReadL( 1, genericTName );
+
+ // Set info to test engine
+ User::LeaveIfError( EnableStifMeasurement( genericTName ) );
+ break;
+ }
+ // Measurement configuration info
+ case EStifMeasurementOff:
+ {
+ // Read Measurement configuration info from aMessage.
+ aMessage.ReadL( 1, genericTName );
+
+ // Set info to test engine
+ User::LeaveIfError( DisableStifMeasurement( genericTName ) );
+ break;
+ }
+ default:
+ {
+ __TRACE( KVerbose, ( _L( "Not valid attribute" ) ) );
+ }
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: AddTestModuleL
+
+ Description: Adds new Test Module
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+ Leaves if name length is zero
+
+ Status: Approved: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::AddTestModuleL( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::AddTestModuleL" ) ) );
+ TName name;
+ TFileName iniFile;
+
+ // Read test module name from aMessage
+ aMessage.ReadL( 0, name );
+
+ if( name.Length() == 0 )
+ {
+ LeaveWithNotifyL( KErrArgument );
+ }
+ // Read ini file name from aMessage
+ aMessage.ReadL( 1, iniFile );
+
+ name.LowerCase();
+ // Remove optional '.DLL' from file name
+ TParse parse;
+ parse.Set( name, NULL, NULL );
+
+ if ( parse.Ext() == _L(".dll") )
+ {
+ const TInt len = parse.Ext().Length();
+ name.Delete ( name.Length()-len, len );
+ }
+
+ __TRACE( KInit, (
+ _L( "CTestEngine::AddTestModuleL, Adding Module:[%S]"), &name ) );
+
+ // Check if test module already exists
+ CTestModuleController* testModule = ModuleControllerByName( name );
+ if ( testModule == NULL )
+ {
+ TBool afterReset = EFalse;
+ if( iRebootParams && iRebootParams->iTestModule == name )
+ {
+ afterReset = ETrue;
+ }
+
+ // Create module controller
+ CTestModuleController* module = NULL;
+ if( name == _L( "testscripter" ) )
+ {
+ module = CTestModuleController::NewL( this, name, afterReset, ETrue );
+ }
+ else
+ {
+ //CTestModuleController* module =
+ module = CTestModuleController::NewL( this, name, afterReset );
+ }
+ CleanupStack::PushL( module );
+
+ module->InitL( iniFile, KNullDesC );
+
+ // Store module for later use
+ User::LeaveIfError( iModules.Append( module ) );
+ CleanupStack::Pop( module );
+ // Done
+ iReturn = KErrNone;
+
+ __TRACE( KInit, (
+ _L( "CTestEngine::AddTestModuleL, module added correctly") ) );
+ }
+ else
+ {
+ iReturn = KErrAlreadyExists;
+ __TRACE( KInit, (
+ _L( "CTestEngine::AddTestModuleL, module already added, all ok.") ) );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: RemoveTestModuleL
+
+ Description: Removes Test Module
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: TInt KErrNone: No errors occurred
+ KErrNotFound: Test module not found
+ KErrInUse: Test module is in use, cannot be removed
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+ Leaves if moduleName length is zero
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::RemoveTestModuleL( const RMessage2& aMessage )
+ {
+ __TRACE( KInit, ( _L( "CTestEngine::RemoveTestModuleL" ) ) );
+ // Read Module name from message
+ TName moduleName;
+ aMessage.ReadL( 0, moduleName );
+ if( moduleName.Length() == 0 )
+ {
+ LeaveWithNotifyL( KErrArgument );
+ }
+
+ moduleName.LowerCase();
+ // Remove optional '.DLL' from file name
+ TParse parse;
+ parse.Set( moduleName, NULL, NULL );
+
+ if ( parse.Ext() == _L(".dll") )
+ {
+ const TInt len = parse.Ext().Length();
+ moduleName.Delete ( moduleName.Length()-len, len );
+ }
+
+ __TRACE(KInit, (_L("Going to remove module controller [%S]"), &moduleName));
+ // Check that the module that will be removed exists
+ TInt moduleCount = iModules.Count();
+ TBool found = EFalse;
+ TInt moduleIndex;
+ for ( moduleIndex = 0; moduleIndex < moduleCount; moduleIndex++ )
+ {
+ if ( iModules[moduleIndex]->ModuleName( moduleName ) == moduleName )
+ {
+ found = ETrue;
+ break;
+ }
+ }
+
+ if ( !found )
+ {
+ // Test Module does not exists
+ __TRACE(KInit, (_L("Module controller [%S] to be removed NOT FOUND"), &moduleName));
+ return KErrNotFound;
+ }
+ // Check module controller and its children
+ if(iModules[moduleIndex]->iTestCaseCounter > 0)
+ {
+ __TRACE(KInit, (_L("Cannot remove module controller [%S], it is running %d test cases"), &moduleName, iModules[moduleIndex]->iTestCaseCounter));
+ return KErrInUse;
+ }
+ TInt j;
+ for(j = 0; j < iModules[moduleIndex]->iChildrenControllers.Count(); j++)
+ {
+ if(iModules[moduleIndex]->iChildrenControllers[j]->iTestCaseCounter > 0)
+ {
+ __TRACE(KInit, (_L("Cannot remove module controller [%S], its child [%S] is running %d test cases"), &moduleName, iModules[moduleIndex]->iChildrenControllers[j]->iName, iModules[moduleIndex]->iChildrenControllers[j]->iTestCaseCounter));
+ return KErrInUse;
+ }
+ }
+ // Test cases not running so we can remove the Test Module
+ __TRACE(KInit, (_L("Removing module controller [%S]"), &moduleName));
+ CTestModuleController* module = iModules[moduleIndex];
+ iModules.Remove(moduleIndex);
+ delete module;
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: CloseTestEngineL
+
+ Description: Close test engine
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if GenerateReportL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::CloseTestEngineL( TUint aHandle )
+ {
+ __TRACE( KInit, ( _L( "CTestEngine::CloseTestEngineL" ) ) );
+ // Remove all module controllers
+ iModules.ResetAndDestroy();
+ iModules.Close();
+
+ // If test report is created
+ if( iTestReport )
+ {
+ iTestReport->GenerateReportL();
+ iIsTestReportGenerated = ETrue;
+ }
+
+ // Close Setting server, no handle available anymore
+ iSettingServer.Close();
+
+ // Get test case from container
+ CTestEngineSubSession* testEngineSubSession = ( CTestEngineSubSession* )iTestEngineSubSessions->At( aHandle );
+
+ // Do nothing if invalid handle
+ if ( testEngineSubSession == NULL )
+ {
+ // Handle might be already deleted, so do nothing.
+ return;
+ }
+
+ iTestEngineSubSessions->Remove( aHandle );
+
+ // Decrement resource count
+ iResourceCount--;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: AddConfigFileL
+
+ Description: Adds new config file to Test Module
+
+ Parameters: const RMessage& aMessage: in: Server Message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+ Leaves if module length is zero
+ Leaves if configFile length is zero
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::AddConfigFileL( const RMessage2& aMessage )
+ {
+ TName module;
+ TFileName configFile;
+
+ // Read module name from aMessage
+ aMessage.ReadL( 0, module );
+
+ if( module.Length() == 0 )
+ {
+ LeaveWithNotifyL( KErrArgument );
+ }
+ // Read config file name from aMessage
+ aMessage.ReadL( 1, configFile );
+
+ if( configFile.Length() == 0 )
+ {
+ LeaveWithNotifyL( KErrArgument );
+ }
+
+ module.LowerCase();
+ // Remove optional '.DLL' from file name
+ TParse parse;
+ parse.Set( module, NULL, NULL );
+
+ if ( parse.Ext() == _L(".dll") )
+ {
+ const TInt len = parse.Ext().Length();
+ module.Delete ( module.Length()-len, len );
+ }
+
+ __TRACE( KInit, ( _L( "Adding config file [%S] to [%S] module"), &configFile, &module ) );
+
+ // Get correct test module controller
+ CTestModuleController* testModule = ModuleControllerByName( module );
+ if ( testModule == NULL )
+ {
+ __TRACE( KError, ( CStifLogger::ERed, _L( "Added configure file has an invalid module:[%S]"), &module ) );
+ LeaveWithNotifyL ( KErrNotFound );
+ }
+
+ // Add config file to Module
+ testModule->AddConfigFileL( configFile );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: RemoveConfigFileL
+
+ Description: Removes a config file from test module
+
+ Parameters: const RMessage& aMessage: in: Server Message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+ Leaves if module length is zero
+ Leaves if configFile length is zero
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::RemoveConfigFileL( const RMessage2& aMessage )
+ {
+ TName module;
+ TFileName configFile;
+
+ // Read module name from aMessage
+ aMessage.ReadL( 0, module );
+
+ if( module.Length() == 0 )
+ {
+ LeaveWithNotifyL( KErrArgument );
+ }
+ // Read config file name from aMessage
+ aMessage.ReadL( 1, configFile );
+
+ if( configFile.Length() == 0 )
+ {
+ LeaveWithNotifyL( KErrArgument );
+ }
+
+ module.LowerCase();
+ // Remove optional '.DLL' from file name
+ TParse parse;
+ parse.Set( module, NULL, NULL );
+
+ if ( parse.Ext() == _L(".dll") )
+ {
+ const TInt len = parse.Ext().Length();
+ module.Delete ( module.Length()-len, len );
+ }
+
+ __TRACE( KInit, ( _L( "Removing config file [%S] from [%S] module"), &configFile, &module ) );
+
+ // Get correct test module controller
+ CTestModuleController* testModule = ModuleControllerByName( module );
+ if ( testModule == NULL )
+ {
+ __TRACE( KError, ( CStifLogger::ERed, _L( "Added configure file has an invalid module:[%S]"), &module ) );
+ LeaveWithNotifyL ( KErrNotFound );
+ }
+
+ // Remove config file from Module
+ testModule->RemoveConfigFileL( configFile );
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: EnumerateTestCasesL
+
+ Description: Enumerates test cases
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Panics the client if enumeration is already pending
+ Leaves if called StartEnumerateL method leaves
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::EnumerateTestCasesL( const RMessage2& aMessage )
+ {
+ __TRACE( KInit, ( _L( "CTestEngine::EnumerateTestCasesL" ) ) );
+ // Check if enumerate is ongoing!!
+ __ASSERT_ALWAYS( iEnumerateModuleCount == 0, PanicClient( EReqPending, aMessage ) );
+
+ iCaseCount = 0;
+ iEnumError = KErrNone;
+
+ TInt count = iModules.Count();
+ if ( count == 0 )
+ {
+
+ __TRACE( KInit, ( CStifLogger::EBold, _L( "Test module(s) not loaded - returning 0 test cases" ) ) );
+
+ // Note is printed from UI
+ // ErrorPrint(0, _L("No test modules, check testengine log"));
+ // Write test case count to client
+ TCaseCount countPckg( 0 );
+ TRAPD( err, aMessage.WriteL( 0, countPckg ) );
+
+ // Request will be completed in DispatchMessageL
+ iReturn = err;
+ }
+ else
+ {
+ for ( TInt i = 0; i < count; i++ )
+ {
+ // Send enumerate request to each test module.
+ iModules[i]->StartEnumerateL();
+ iEnumerateModuleCount++;
+ }
+
+ // Message is completed later from EnumerationCompleted function
+ iComplete = EFalse;
+
+ // Store the message
+ iEnumerationMessage = aMessage;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: EnumerationCompleted
+
+ Description: Return the module controller specified by given parameter.
+
+ Parameters: TInt aCount: in: Count of test cases
+ TInt aError: in: Symbian OS Error code: Error from Test Module
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::EnumerationCompleted( TInt aCount, TInt aError )
+ {
+ // Increment test case count by aCount
+ iCaseCount+= aCount;
+
+ if ( aError != KErrNone )
+ {
+ iEnumError = aError;
+ }
+
+ iEnumerateModuleCount--;
+
+ if ( iEnumerateModuleCount == 0 )
+ {
+
+ TInt attrib = CStifLogger::ENoStyle;
+ if ( iCaseCount == 0 )
+ {
+ attrib = CStifLogger::EBold;
+ }
+ __TRACE( KInit, ( attrib, _L( "Test case enumeration completed, testcase count %d"), iCaseCount ) );
+
+ // Write test case count to client
+ TCaseCount countPckg( iCaseCount );
+ TRAPD( err, iEnumerationMessage.WriteL( 0, countPckg ) );
+
+ if ( err != KErrNone )
+ {
+ iEnumError = err;
+ __TRACE( KError, ( CStifLogger::ERed, _L( "CTestEngine::EnumerationCompleted: Failed %d"), iEnumError ) );
+ }
+
+ // Complete request
+ iEnumerationMessage.Complete( iEnumError );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: GetTestCasesL
+
+ Description: Get test cases
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if enumeration is not yet complete
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::GetTestCasesL( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::GetTestCasesL" ) ) );
+
+ const TInt len = sizeof( TTestInfo );
+
+ // Loop through all test modules
+ TInt moduleCount = iModules.Count();
+ TInt pos = 0;
+ TInt totalCount = 0;
+ for ( TInt i = 0; i < moduleCount; i++ )
+ {
+ CTestModuleController* module = iModules[i];
+
+ // Check that test cases are enumerated first
+ if ( !module->EnumerationComplete() )
+ {
+ __TRACE( KError, ( CStifLogger::ERed, _L( "CTestEngine::GetTestCasesL, Test Cases not yet enumerated!" ) ) );
+ LeaveIfErrorWithNotify( KErrNotFound );
+ }
+
+ CFixedFlatArray<TTestInfo>* testCases = module->TestCasesL();
+ CleanupStack::PushL( testCases );
+
+ // Loop through all test cases got from test module
+ const TInt caseCount = testCases->Count();
+ totalCount+=caseCount;
+
+ for ( TInt j = 0; j < caseCount; j++ )
+ {
+ if(((*testCases)[j]).iTestCaseInfo.iTimeout == 0 && iDefaultTimeout > 0)
+ {
+ ((*testCases)[j]).iTestCaseInfo.iTimeout = iDefaultTimeout;
+ }
+
+ // Construct package for source data
+ TTestInfoPckg tmpPackage( ( *testCases )[j] );
+
+ // Copy test case package to client's memory
+ aMessage.WriteL( 0, tmpPackage, pos ) ;
+
+ pos = pos + len;
+ }
+ CleanupStack::PopAndDestroy( testCases );
+
+ // Free allocated test cases because not needed anymore
+ module->FreeTestCases();
+
+ }
+
+ __TRACE( KVerbose, ( _L( "CTestEngine::GetTestCasesL, case count %d" ), totalCount ) );
+
+ // Finished
+ iReturn = KErrNone;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: CancelAsyncRequest
+
+ Description: Asynchronous requests are canceled by this function.
+
+ Parameters: const RMessage aMessage
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::CancelAsyncRequest( const RMessage2& aMessage )
+ {
+ switch ( aMessage.Int0() )
+ {
+ case ETestEngineEnumerateTestCases:
+ {
+ TInt count = iModules.Count();
+ for ( TInt i=0; i < count; i++ )
+ {
+ // Cancel enumerate
+ iModules[i]->Cancel();
+ }
+ break;
+ }
+
+ case ETestEngineErrorNotification:
+ {
+ if ( iErrorMessageAvailable )
+ {
+ iErrorMessageAvailable = EFalse;
+ iErrorMessage.Complete ( KErrCancel );
+ }
+ }
+ break;
+ case ETestEngineEvent:
+ // Event command cannot be cancelled
+ // Only EWaitEvent can be cancelled with ECancelWait
+ default:
+ PanicClient( EBadRequest, aMessage );
+ break;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: EventControlL
+
+ Description: Controls event system.
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::EventControlL( const RMessage2& aMessage )
+
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::EventControlL" ) ) );
+ TInt ret = KErrNone;
+
+ // Read EventIf from aMessage
+ TEventIf event;
+ TEventIfPckg eventIfPckg( event );
+ aMessage.ReadL( 0, eventIfPckg );
+
+ // EWaitEvent, EReqEvent and ERelEvent need processing here
+ if( ( event.Type() == TEventIf::EWaitEvent ) ||
+ ( event.Type() == TEventIf::EReqEvent ) ||
+ ( event.Type() == TEventIf::ERelEvent ) ||
+ ( event.Type() == TEventIf::ECancelWait ) )
+ {
+ TInt ind = 0;
+ TInt count = iClientEvents.Count();
+ const TDesC& eventName = event.Name();
+ // Search event from client event list
+ for( ind=0; ind < count; ind++ )
+ {
+ if( iClientEvents[ind]->Name() == eventName )
+ {
+ break;
+ }
+ }
+
+ switch( event.Type() )
+ {
+ // Handle event waiting
+ case TEventIf::EWaitEvent:
+ {
+ // Check that we found event from client events list
+ if( ind == count )
+ {
+ ret = KErrNotFound;
+ }
+ else
+ {
+ TEventMsg* eventEntry = iClientEvents[ind];
+
+ __TRACE( KVerbose, ( _L( "CTestEngine::EventControlL: Waiting %S (count %i)"),
+ &event.Name(), count ) );
+
+ // Waiting is completed either from here in Wait method
+ // if event is already pending,
+ // or from Set method in CtlEvent when event is set.
+ eventEntry->Wait( aMessage );
+ return;
+ }
+ }
+ break;
+ case TEventIf::ECancelWait:
+ {
+ // Check that we found event from client events list
+ if( ind == count )
+ {
+ ret = KErrNotFound;
+ }
+ else
+ {
+ TEventMsg* eventEntry = iClientEvents[ind];
+
+ __TRACE( KVerbose, ( _L( "CTestEngine::EventControlL: Cancel waiting %S (count %i)"),
+ &event.Name(), count ) );
+
+ eventEntry->CancelWait();
+ }
+ }
+ break;
+ // Handle event request
+ case TEventIf::EReqEvent:
+ {
+ // Check that event is not already requested
+ if( ind < count )
+ {
+ // Already exists
+ ret = KErrArgument;
+ }
+ else
+ {
+ // Requested events are added to iClientEvents
+ TEventMsg* eventEntry = new TEventMsg;
+ if( eventEntry == NULL )
+ {
+ ret = KErrNoMemory;
+ }
+ else
+ {
+ CleanupStack::PushL( eventEntry );
+ eventEntry->Copy( event );
+ // Check if state event is set already
+ if( IsStateEventAndSet( event.Name() ) )
+ {
+ // If it was set already, set the event
+ eventEntry->Set( TEventIf::EState );
+ }
+ ret = iClientEvents.Append( eventEntry );
+ if( ret != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( eventEntry );
+ }
+ else
+ {
+ CleanupStack::Pop( eventEntry );
+
+ __TRACE( KVerbose, ( _L( "CTestEngine::EventControlL: Req added %S (count %i)"),
+ &event.Name(), iClientEvents.Count() ) );
+ }
+ }
+ }
+ }
+ break;
+ // Release event
+ case TEventIf::ERelEvent:
+ {
+ // Released events are deleted from iClientEvents
+ // Check that we found entry from client events list
+ if( ind == count )
+ {
+ ret = KErrNotFound;
+ }
+ else
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::EventControlL: Release event %S (count %i)"),
+ &event.Name(), iClientEvents.Count() ) );
+
+ TEventMsg* eventEntry = iClientEvents[ind];
+ iClientEvents.Remove( ind );
+ eventEntry->Release();
+ delete eventEntry;
+ }
+ }
+ break;
+ default: // This should never happen!!!
+ {
+ _LIT( KEngine, "CTestEngine" );
+ User::Panic( KEngine, KErrGeneral );
+ }
+ break;
+ }
+ }
+ else
+ {
+ // ESetEvent and EUnsetEvent are only forwarded
+ TRequestStatus req;
+ CtlEventL( event, req );
+ User::WaitForRequest( req );
+ }
+
+ aMessage.Complete( ret );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: HandleErrorNotificationL
+
+ Description: Handle error notifications.
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::HandleErrorNotificationL( const RMessage2& aMessage )
+ {
+ iErrorMessage = aMessage;
+ iErrorMessageAvailable = ETrue;
+
+ ProcessErrorQueue();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: LoggerSettings
+
+ Description: Get Logger's overwrite parameters
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Panics if WriteL fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::LoggerSettings( const RMessage2& aMessage )
+ {
+ __TRACE( KInit, ( _L( "CTestEngine::LoggerSettings" ) ) );
+
+ // Copies logger settings to the package
+ TPckg<TLoggerSettings> loggerSettingsPckg( iTestEngineServer->iLoggerSettings );
+
+ // Writes a packege that includes the logger overwrite settings to aMessage
+ TRAPD( err, aMessage.WriteL( 0, loggerSettingsPckg ) );
+ if ( err != KErrNone )
+ {
+ PanicClient( EBadDescriptor, aMessage );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: CloseLoggerSettings
+
+ Description: Close logger settings
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::CloseLoggerSettings()
+ {
+ __TRACE( KInit, ( _L( "CTestEngine::CloseLoggerSettings" ) ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: TestCaseByHandle
+
+ Description: Return test case specified by aHandle
+
+ Parameters: TUint aHandle : in : TUint : Handle to TestCase subsession
+
+ Return Values: CTestCase* : pointer to CTestCase object
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCase* CTestEngine::TestCaseByHandle( TUint aHandle, const RMessage2& aMessage )
+ {
+ // Try to get test case from test case container
+ CTestCase* testCase =
+ ( CTestCase* )iTestCases->At( aHandle );
+ if ( testCase == NULL )
+ {
+ PanicClient( EBadSubsessionHandle, aMessage );
+ }
+
+ return testCase;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: NewTestCaseL
+
+ Description: Create new test execution subsession
+
+ Parameters: const RMessage& aMessage: in: Server Message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving method leaves
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::NewTestCaseL( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::NewTestCaseL start" ) ) );
+
+ // Get data from message
+ TTestInfo testInfo;
+ TTestInfoPckg testInfoPckg = testInfo;
+
+ TRAPD( res, aMessage.ReadL( 0, testInfoPckg ) );
+ if ( res != KErrNone )
+ {
+ PanicClient( EBadDescriptor, aMessage );
+ return;
+ }
+
+ testInfo.iModuleName.LowerCase();
+ // Remove optional '.DLL' from file name
+ TParse parse;
+ parse.Set( testInfo.iModuleName, NULL, NULL );
+
+ if ( parse.Ext() == _L(".dll") )
+ {
+ const TInt len = parse.Ext().Length();
+ testInfo.iModuleName.Delete ( testInfo.iModuleName.Length()-len, len );
+ }
+
+ // Get correct test module controller
+ CTestModuleController* scrModule = NULL;
+ CTestModuleController* module = GetFreeOrCreateModuleControllerL(testInfo, &scrModule);
+ if ( module == NULL )
+ {
+ //@spe PanicClient( EInvalidModuleName, aMessage );
+ //@spe return;
+ __TRACE( KError, ( CStifLogger::ERed, _L( "Invalid module:[%S]"), &testInfo.iModuleName ) );
+ LeaveWithNotifyL ( KErrNotFound );
+ }
+
+ // Create test case object
+ CTestCase* testCase =
+ CTestCase::NewL( this, module, iTestReport, testInfo, scrModule);
+ CleanupStack::PushL( testCase );
+
+ // Add object to object container to generate unique id
+ iContainer->AddL( testCase );
+
+ // Add object to object index
+ // This returns a unique handle so we can get it again
+ TInt handle = iTestCases->AddL( testCase );
+
+ // Write the handle to client
+ TPckg<TInt> handlePckg( handle );
+
+ TRAP( res, aMessage.WriteL( 3, handlePckg ) );
+ if ( res != KErrNone )
+ {
+ iTestCases->Remove( handle );
+ PanicClient( EBadDescriptor, aMessage );
+ return;
+ }
+
+ // Add new test case to testcase array
+ User::LeaveIfError( iTestCaseArray.Append( testCase ) );
+ CleanupStack::Pop( testCase );
+
+ // Notch up another resource
+ iResourceCount++;
+
+ iReturn = KErrNone;
+
+ __TRACE( KVerbose, ( _L( "CTestEngine::NewTestCaseL done" ) ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: DeleteTestCase
+
+ Description: Delete test case from container list
+
+ Parameters: TUint aHandle: in: Handle to test case to be removed
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::DeleteTestCase( TUint aHandle )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::DeleteTestCase" ) ) );
+
+ // Get test case from container
+ CTestCase* testCase = ( CTestCase* )iTestCases->At( aHandle );
+
+ // Do nothing if invalid handle
+ if ( testCase == NULL )
+ {
+ // Handle might be already deleted, so do nothing.
+ return;
+ }
+
+ //Get controllers
+ CTestModuleController* moduleController;
+ CTestModuleController* realModuleController;
+
+ moduleController = testCase->GetModuleControllers(&realModuleController);
+
+ // Check if module controllers have crashed
+ TBool moduleControllerCrashed = EFalse;
+ TBool realModuleControllerCrashed = EFalse;
+
+ if(moduleController)
+ {
+ moduleControllerCrashed = moduleController->iTestModuleCrashDetected;
+ }
+ if(realModuleController)
+ {
+ realModuleControllerCrashed = realModuleController->iTestModuleCrashDetected;
+ }
+
+ //__TRACE(KInit, (_L("CTestEngine::DeleteTestCase moduleController=[%x] crashed=[%d] realModuleController=[%x] crashed=[%d]"), moduleController, moduleControllerCrashed, realModuleController, realModuleControllerCrashed));
+ // For UITestingSupport, SeparateProcesses and PythonSupport, when module is crashed,
+ // remove it from module lists, because it will be deleted when closing test case.
+ if(moduleController)
+ {
+ if(moduleControllerCrashed && iUITestingSupport && moduleController->iName->Find(KTestScripterName) == 0
+ || moduleControllerCrashed && iSeparateProcesses
+ || moduleControllerCrashed && moduleController->iName->Find(KPythonScripter) == 0
+ )
+ {
+ __TRACE(KInit, (_L("Removing module controller from module list because of crash")));
+ //Look for specific module controller and delete it
+ TInt i;
+ TInt j, children;
+ TInt modules = iModules.Count();
+ for(i = 0; i < modules; i++)
+ {
+ if(iModules[i] == moduleController)
+ {
+ __TRACE(KInit, (_L("Module controller found - removing")));
+ iModules.Remove(i);
+ break;
+ }
+
+ //Check children of the module and if module to be deleted found there, remove it
+ children = iModules[i]->iChildrenControllers.Count();
+ __TRACE(KInit, (_L("Checking %d children of [%S]"), children, iModules[i]->iName));
+ for(j = 0; j < children; j++)
+ {
+ if(iModules[i]->iChildrenControllers[j] == moduleController)
+ {
+ __TRACE(KInit, (_L("Module controller found (child) - removing")));
+
+ iModules[i]->iChildrenControllers.Remove(j);
+
+ __TRACE(KInit, (_L("Child removed from [%S] controller. Currently it has %d children:"), iModules[i]->iName, iModules[i]->iChildrenControllers.Count()));
+ for(TInt k = 0; k < iModules[i]->iChildrenControllers.Count(); k++)
+ {
+ __TRACE(KInit, (_L(" %d. [%S]"), k + 1, iModules[i]->iChildrenControllers[k]->iName));
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(moduleController && realModuleController)
+ {
+ if(realModuleControllerCrashed && iUITestingSupport && realModuleController->iName->Find(KTestScripterName) == 0
+ || realModuleControllerCrashed && iSeparateProcesses
+ || realModuleControllerCrashed && realModuleController->iName->Find(KPythonScripter) == 0
+ )
+ {
+ __TRACE(KInit, (_L("Removing real module controller from module list because of crash")));
+ //Remove module controller from scripter controller
+ moduleController->RemoveModuleController(realModuleController);
+ }
+ }
+
+ // Close test case and remove it from container
+ //testCase->CloseTestCase();
+ iTestCases->Remove( aHandle );
+
+ // Decrement resource count
+ iResourceCount--;
+
+ // Remove from testcase array
+ iTestCaseArray.Remove( iTestCaseArray.Find( testCase ) );
+
+ //If this is UITestingSupport and module is not crashed, delete controller
+ //(in other words, kill process, because we need somehow reset the test server).
+ if(moduleController && !moduleControllerCrashed)
+ {
+ if(iUITestingSupport && moduleController->iName->Find(KTestScripterName) == 0)
+ {
+ if(realModuleController)
+ {
+ if(!realModuleControllerCrashed)
+ {
+ __TRACE(KInit, (_L("Delete module controller (and kill process in which test case was run).")));
+ __TRACE(KInit, (_L("Real module controller provided - processing")));
+ //Remove module controller from scripter controller
+ moduleController->DeleteModuleController(realModuleController);
+ }
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Delete module controller (and kill process in which test case was run).")));
+ __TRACE(KInit, (_L("Real module controller not provided, checking normal controllers")));
+ //Look for specific module controller and delete it
+ TInt i;
+ TInt j, children;
+ TInt modules = iModules.Count();
+ for(i = 0; i < modules; i++)
+ {
+ if(iModules[i] == moduleController)
+ {
+ __TRACE(KInit, (_L("Module controller found - deleting")));
+ delete iModules[i];
+ iModules.Remove(i);
+ break;
+ }
+
+ //Check children of the module and if module to be deleted found there, remove it
+ children = iModules[i]->iChildrenControllers.Count();
+ __TRACE(KInit, (_L("Checking %d children of [%S]"), children, iModules[i]->iName));
+ for(j = 0; j < children; j++)
+ {
+ if(iModules[i]->iChildrenControllers[j] == moduleController)
+ {
+ __TRACE(KInit, (_L("Module controller found (child) - deleting")));
+
+ delete iModules[i]->iChildrenControllers[j];
+ iModules[i]->iChildrenControllers.Remove(j);
+
+ __TRACE(KInit, (_L("Child removed from [%S] controller. Currently it has %d children:"), iModules[i]->iName, iModules[i]->iChildrenControllers.Count()));
+ for(TInt k = 0; k < iModules[i]->iChildrenControllers.Count(); k++)
+ {
+ __TRACE(KInit, (_L(" %d. [%S]"), k + 1, iModules[i]->iChildrenControllers[k]->iName));
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: IsStateEventAndSet
+
+ Description: Callback to check state event status.
+
+ Parameters: const TName& aEventName: in: Event name
+
+ Return Values: ETrue: event is set
+ EFalse: event is not set
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestEngine::IsStateEventAndSet( const TName& aEventName )
+ {
+ TInt count = iStateEvents.Count();
+ for( TInt i = 0; i < count; i++ )
+ {
+ TPtrC name = iStateEvents[i]->Des();
+ if( name == aEventName )
+ {
+ // Requested state event set already
+ return ETrue;
+ }
+ }
+ return EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: CtlEventL
+
+ Description: Callback to control events.
+
+ Parameters: const TEventIf& aEvent: in: event information
+ TRequestStatus& aStatus: in: Request status
+
+ Return Values: CTestEventController*: CTestEventController object
+
+ Errors/Exceptions: Leaves if CtlEventL leaves
+ Leaves if memory allocation fails
+ Leaves if unset event not found from pending
+ state event list
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEventController* CTestEngine::CtlEventL( const TEventIf& aEvent,
+ TRequestStatus& aStatus )
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::CtlEventL" ) ) );
+
+ aStatus = KRequestPending;
+
+ UpdateEventL( aEvent );
+ return CTestEventController::NewL( this, aEvent, &aStatus );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: UpdateEventL
+
+ Description: Update event lists.
+
+ Parameters: const TEventIf& aEvent: in: event information
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if CtlEventL leaves
+ Leaves if memory allocation fails
+ Leaves if unset event not found from pending
+ state event list
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::UpdateEventL( const TEventIf& aEvent )
+ {
+ // Handle ESetEvent and EUnsetEvent for state events here
+ if( aEvent.EventType() == TEventIf::EState )
+ {
+ // Find event from the list
+ TInt count = iStateEvents.Count();
+ TInt index = 0;
+ const TDesC& eventName = aEvent.Name();
+ for( ; index < count; index++ )
+ {
+ TPtrC name = iStateEvents[index]->Des();
+ if( name == eventName )
+ {
+ break;
+ }
+ }
+
+ if( aEvent.Type() == TEventIf::ESetEvent )
+ {
+ // Check that event is not already pending
+ if( index < count )
+ {
+ User::Leave( KErrAlreadyExists );
+ }
+
+ // Add set event to pending state event list
+ HBufC* name = aEvent.Name().AllocLC();
+ User::LeaveIfError( iStateEvents.Append( name ) );
+ CleanupStack::Pop( name );
+ }
+ else if( aEvent.Type() == TEventIf::EUnsetEvent )
+ {
+ if( index == count )
+ {
+ // Not found from state event list
+ User::Leave( KErrNotFound );
+ }
+ HBufC* tmp = iStateEvents[index];
+ iStateEvents.Remove( index );
+ delete tmp;
+ }
+ }
+ else if( aEvent.Type() == TEventIf::EUnsetEvent )
+ {
+ // Can not give Unset for indication event
+ User::Leave( KErrNotSupported );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: Logger
+
+ Description: Return the pointer to Logger.
+
+ Parameters: None
+
+ Return Values: CStifLogger*: Pointer to StifLogger
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CStifLogger* CTestEngine::Logger()
+ {
+ return iTestEngineServer->Logger();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: WriteRebootParams
+
+ Description: Write the Reboot's state parameters.
+
+ Parameters: TTestInfo& aTestInfo: in: Test case information.
+ TInt& aCode: in: Reboot related integer information.
+ TDesC& aName: in: Reboot related string information.
+
+ Return Values: TInt: Symbian OS error
+
+ Errors/Exceptions: Error code returned if Logger creation fails.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::WriteRebootParams( TTestInfo& aTestInfo,
+ TInt& aCode,
+ TDesC& aName )
+ {
+ __TRACE( KVerbose, ( _L( "WriteRebootParams() starts..." ) ) );
+
+ // Logger's setting definitions
+ TLoggerSettings loggerSettings;
+
+ loggerSettings.iCreateLogDirectories = ETrue;
+ loggerSettings.iOverwrite = ETrue;
+ loggerSettings.iTimeStamp = EFalse;
+ loggerSettings.iLineBreak = EFalse;
+ loggerSettings.iEventRanking = EFalse;
+ loggerSettings.iThreadId = EFalse;
+ // EData format because now we don't have to check file type when
+ // parsing this.
+ loggerSettings.iHardwareFormat = CStifLogger::EData;
+ loggerSettings.iHardwareOutput = CStifLogger::EFile;
+ loggerSettings.iEmulatorFormat = CStifLogger::EData;
+ loggerSettings.iEmulatorOutput = CStifLogger::EFile;
+ loggerSettings.iUnicode = EFalse;
+ loggerSettings.iAddTestCaseTitle = EFalse;
+
+ // Use default setting if path or filename are not set by SetAttribute()
+ if( iRebootPath == NULL )
+ {
+ iRebootPath= iRebootDefaultPath.Alloc();
+ }
+ if( iRebootFilename == NULL )
+ {
+ iRebootFilename= iRebootDefaultFilename.Alloc();
+ }
+
+ CStifLogger* logger = NULL;
+ TRAPD( ret, logger = CStifLogger::NewL( *iRebootPath,
+ *iRebootFilename,
+ loggerSettings ) );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, ( _L( "WriteRebootParams() Logger creation fails with error: " ), ret ) );
+ delete logger;
+ return ret;
+ }
+
+ // Write reboot parameters
+ // Because logging format is EData we need add line breaks by hand.
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "This is TestFramework's file which includes Reboot related informations" ) );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "Reboot case's related information:" ) );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "%S %S" ), &KTestModule, &aTestInfo.iModuleName );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "%S %S" ), &KTestCaseFile, &aTestInfo.iConfig );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "%S %d" ), &KTestCaseNumber, aTestInfo.iTestCaseInfo.iCaseNumber );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "%S %S" ), &KTestCaseTitle, &aTestInfo.iTestCaseInfo.iTitle );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "%S %d" ), &KStateCode, aCode );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "%S " ), &KStateName );
+ logger->Log( aName );
+ logger->Log( _L( "\r\n" ) );
+ logger->Log( _L( "\r\n" ) );
+
+ delete logger;
+
+ __TRACE( KVerbose, ( _L( "WriteRebootParams() ends" ) ) );
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ReadRebootParams
+
+ Description: Read the Reboot parameters.
+
+ Parameters: TTestInfo& aTestInfo: in: Test case information.
+
+ Return Values: TInt: Symbian OS error
+
+ Errors/Exceptions: Error code returned if Parser creation fails.
+ Error code returned if section creation fails.
+ Error code returned if item creation fails.
+ Error code returned if parsing operation fails.
+ KErrArgument returned if parsed values and test case
+ values are different.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::ReadRebootParams( TTestInfo& aTestInfo,
+ TDes& aStateDes,
+ TInt& aState )
+ {
+ __TRACE( KVerbose, ( _L( "ReadRebootParams() starts..." ) ) );
+
+ if( iRebootParams == NULL )
+ {
+ __TRACE( KVerbose, ( _L( "ReadRebootParams(): Reboot not done" )) );
+ return KErrNotFound;
+ }
+
+ // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--
+ // Checks parsed values and test case values
+ // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--
+ if( iRebootParams->iTestModule != aTestInfo.iModuleName ||
+ iRebootParams->iTestCaseFile != aTestInfo.iConfig ||
+ iRebootParams->iCaseNumber != aTestInfo.iTestCaseInfo.iCaseNumber )
+ {
+ __TRACE( KVerbose,
+ ( _L( "ReadRebootParams(): Reboot not done by %S" ),
+ &aTestInfo.iModuleName) );
+ return KErrArgument;
+ }
+
+ aStateDes.Copy( iRebootParams->iStateName );
+ aState = iRebootParams->iStateCode;
+
+ // delete reboot params, to ensure that same test case
+ // does not get indication about reboot again
+ delete iRebootParams;
+ iRebootParams = 0;
+
+ __TRACE( KVerbose, ( _L("ReadRebootParams() ends" ) ) );
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ParseRebootParamsL
+
+ Description: Parse the Reboot parameters.
+
+ Parameters: None
+
+ Return Values: TInt: Symbian OS error
+
+ Errors/Exceptions: Error code returned if Parser creation fails.
+ Error code returned if section creation fails.
+ Error code returned if item creation fails.
+ Error code returned if parsing operation fails.
+ KErrArgument returned if parsed values and test case
+ values are different.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::ParseRebootParamsL()
+ {
+ __TRACE( KVerbose, ( _L( "ParseRebootParamsL() starts..." ) ) );
+
+ TInt ret_parsing( 0 );
+ TPtrC tmp;
+
+ // Use default setting if path or filename are not set by SetAttribute()
+ if( iRebootPath == NULL )
+ {
+ iRebootPath= iRebootDefaultPath.Alloc();
+ }
+ if( iRebootFilename == NULL )
+ {
+ iRebootFilename= iRebootDefaultFilename.Alloc();
+ }
+
+ // Create parser object
+ CStifParser* parser = NULL;
+ TRAPD( ret, parser = CStifParser::NewL( *iRebootPath,
+ *iRebootFilename ) );
+ if( ret != KErrNone )
+ {
+ __TRACE( KError, ( _L( "ReadRebootParams(): Reboot file not found" )) );
+ return ret;
+ }
+ CleanupStack::PushL( parser );
+
+ // Create section object
+ CStifSectionParser* section = parser->SectionL( KNullDesC, KNullDesC );
+ CleanupStack::PushL( section );
+
+ // Delete old reboot params
+ delete iRebootParams;
+ iRebootParams = 0;
+ iRebootParams = CRebootParams::NewL();
+
+ // ----------------------Test module parsing
+ CStifItemParser* item = section->GetItemLineL( KTestModule );
+ CleanupStack::PushL( item );
+
+ // Parsing integer
+ ret_parsing = item->GetString( KTestModule, tmp );
+ if( ret_parsing == KErrNone || ret_parsing == KErrNotFound )
+ {
+ __TRACE( KVerbose, ( _L("ReadRebootParams(): TestModule: %S" ), &tmp ) );
+ }
+ else
+ {
+ __TRACE( KError,
+ ( _L("ReadRebootParams(): TestModule parsing fails with error: " ),
+ ret_parsing ) );
+ User::Leave( ret_parsing );
+ }
+ iRebootParams->SetTestModuleNameL( tmp );
+ CleanupStack::PopAndDestroy( item );
+
+ // ----------------------Testcase parsing
+ item = section->GetItemLineL( KTestCaseFile );
+ CleanupStack::PushL( item );
+
+ // Parsing string
+ ret_parsing = item->GetString( KTestCaseFile, tmp );
+ if( ret_parsing == KErrNone )
+ {
+ __TRACE( KVerbose, ( _L("ReadRebootParams(): TestCaseFile: %S" ), &tmp ) );
+ iRebootParams->SetTestCaseFileNameL( tmp );
+ }
+ else if( ret_parsing == KErrNotFound )
+ {
+ __TRACE( KVerbose,
+ ( _L("ReadRebootParams(): No testcasefile defined for test module" )) );
+ }
+ else
+ {
+ __TRACE( KError,
+ ( _L("ReadRebootParams(): TestCaseFile parsing fails with error: %d " ),
+ ret_parsing ) );
+ User::Leave( ret_parsing );
+ }
+ CleanupStack::PopAndDestroy( item );
+
+ // ----------------------Testcase number parsing
+ item = section->GetItemLineL( KTestCaseNumber );
+ CleanupStack::PushL( item );
+
+ // Parsing integer
+ ret_parsing = item->GetInt( KTestCaseNumber, iRebootParams->iCaseNumber );
+ if( ret_parsing == KErrNone || ret_parsing == KErrNotFound )
+ {
+ __TRACE( KVerbose, ( _L("ReadRebootParams(): TestCaseNumber: %d" ),
+ iRebootParams->iCaseNumber ) );
+ }
+ else
+ {
+ __TRACE( KError,
+ ( _L("ReadRebootParams(): TestCaseNumber parsing fails with error: %d " ),
+ ret_parsing ) );
+ User::Leave( ret_parsing );
+ }
+ CleanupStack::PopAndDestroy( item );
+
+ // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--
+ // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--
+ // Next state code and name parsing if no error found
+ // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--.--
+
+ // ----------------------State code parsing
+ item = section->GetItemLineL( KStateCode );
+ CleanupStack::PushL( item );
+
+ // Parsing integer
+ ret_parsing = item->GetInt( KStateCode, iRebootParams->iStateCode );
+ if( ret_parsing == KErrNone || ret_parsing == KErrNotFound )
+ {
+ __TRACE( KVerbose, ( _L("ReadRebootParams(): StateCode: %d" ),
+ iRebootParams->iStateCode ) );
+ }
+ else
+ {
+ __TRACE( KError,
+ ( _L("ReadRebootParams(): StateCode parsing fails with error: %d " ),
+ ret_parsing ) );
+ User::Leave( ret_parsing );
+ }
+ CleanupStack::PopAndDestroy( item );
+
+ // ----------------------State name parsing
+ ret_parsing = section->GetLine( KStateName, tmp, ENoTag );
+ if( ret_parsing != KErrNone )
+ {
+ __TRACE( KError,
+ ( _L("ReadRebootParams(): State name parsing fails with error: %d " ),
+ ret_parsing ) );
+ User::Leave( ret_parsing );
+ }
+
+ iRebootParams->SetTestCaseStateL( tmp );
+
+ __TRACE( KVerbose, ( _L("ReadRebootParams() ends" ) ) );
+
+ CleanupStack::PopAndDestroy( section );
+ CleanupStack::PopAndDestroy( parser );
+
+ // Delete file
+ RFs rf;
+ TInt retVal = rf.Connect();
+ if( retVal != KErrNone )
+ {
+ User::Leave( retVal );
+ }
+
+ TFileName file( *iRebootPath );
+ file.Append( *iRebootFilename );
+ rf.Delete( file );
+ rf.Close();
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: PauseAllTestCases
+
+ Description: Pause all test case(s) which are/is running.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::PauseAllTestCases()
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::PauseAllTestCases()" ) ) );
+
+ TInt count( 0 );
+ count = iTestCaseArray.Count();
+
+ for( TInt a = 0; a < count; a++ )
+ {
+ // Pause test case
+ iTestCaseArray[a]->Pause();
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: FlushAtsLogger
+
+ Description: Flush ATS logger's
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::FlushAtsLogger()
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::FlushAtsLogger()" ) ) );
+
+ TInt count( 0 );
+ count = iModules.Count();
+
+ for( TInt a = 0; a < count; a++ )
+ {
+ // Pause test case
+ iModules[a]->AtsLogger().SaveForRebootL();
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: GetDeviceResetDllName
+
+ Description: Get device reset module's DLL name.
+
+ Parameters: None
+
+ Return Values: TPtrC
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+TPtrC CTestEngine::GetDeviceResetDllName()
+ {
+ __TRACE( KVerbose, ( _L( "CTestEngine::GetDeviceResetDllName()" ) ) );
+
+ return iDeviceResetDllName->Des();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: EnableStifMeasurement
+
+ Description: Set measurements related information, enable measurement.
+
+ Parameters: const TName& aInfoType: in: Enabled measurement type
+
+ Return Values: TInt: Symbian error code
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::EnableStifMeasurement( const TDesC& aInfoType )
+ {
+ __TRACE( KInit, ( _L( "Measurement [%S] enabled" ), &aInfoType ) );
+
+ if( aInfoType == KStifMeasurement01 )
+ {
+ iDisableMeasurement &= ~EMeasurement01;
+ }
+ else if( aInfoType == KStifMeasurement02 )
+ {
+ iDisableMeasurement &= ~EMeasurement02;
+ }
+ else if( aInfoType == KStifMeasurement03 )
+ {
+ iDisableMeasurement &= ~EMeasurement03;
+ }
+ else if( aInfoType == KStifMeasurement04 )
+ {
+ iDisableMeasurement &= ~EMeasurement04;
+ }
+ else if( aInfoType == KStifMeasurement05 )
+ {
+ iDisableMeasurement &= ~EMeasurement05;
+ }
+ else if( aInfoType == KStifMeasurementBappea )
+ {
+ iDisableMeasurement &= ~EBappea;
+ }
+ else if( aInfoType == KStifMeasurementDisableAll )
+ {
+ __TRACE( KInit, ( _L( "All measurements are disabled" ) ) );
+ iDisableMeasurement &= EDisableAll; // Does change anything !!!
+ }
+ else if( aInfoType == KStifMeasurementEnableAll )
+ {
+ __TRACE( KInit, ( _L( "All measurements types are enabled" ) ) );
+ iDisableMeasurement &= EEnableAll;
+ }
+ else
+ {
+ __TRACE( KInit, ( _L( "Measurement [%S] not recognized" ), &aInfoType ) );
+ return KErrArgument;
+ }
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: DisableStifMeasurement
+
+ Description: Set measurements related information, disable measurement.
+
+ Parameters: const TName& aInfoType: in: Disabled measurement type
+
+ Return Values: TInt: Symbian error code
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::DisableStifMeasurement( const TDesC& aInfoType )
+ {
+ __TRACE( KInit, ( _L( "Measurement [%S] disabled" ), &aInfoType ) );
+
+ if( aInfoType == KStifMeasurement01 )
+ {
+ iDisableMeasurement |= EMeasurement01;
+ }
+ else if( aInfoType == KStifMeasurement02 )
+ {
+ iDisableMeasurement |= EMeasurement02;
+ }
+ else if( aInfoType == KStifMeasurement03 )
+ {
+ iDisableMeasurement |= EMeasurement03;
+ }
+ else if( aInfoType == KStifMeasurement04 )
+ {
+ iDisableMeasurement |= EMeasurement04;
+ }
+ else if( aInfoType == KStifMeasurement05 )
+ {
+ iDisableMeasurement |= EMeasurement05;
+ }
+ else if( aInfoType == KStifMeasurementBappea )
+ {
+ iDisableMeasurement |= EBappea;
+ }
+ else if( aInfoType == KStifMeasurementDisableAll )
+ {
+ __TRACE( KInit, ( _L( "All measurements are disabled" ) ) );
+ iDisableMeasurement |= EDisableAll;
+ }
+ else if( aInfoType == KStifMeasurementEnableAll )
+ {
+ __TRACE( KInit, ( _L( "All measurements types are enabled" ) ) );
+ iDisableMeasurement |= EEnableAll; // Does change anything !!!
+ }
+ // This option can be defined in TestFramework.ini file
+ else if( aInfoType == KStifMeasurementDisableNone )
+ {
+ __TRACE( KInit, ( _L( "All measurements types are enabled" ) ) );
+ iDisableMeasurement = EEnableAll; // Sets to 0
+ }
+ else
+ {
+ __TRACE( KInit, ( _L( "Measurement [%S] not recognized" ), &aInfoType ) );
+ return KErrArgument;
+ }
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: StifMeasurement
+
+ Description: Get measurements related information. Returns is measurement
+ disable.
+
+ Parameters: None
+
+ Return Values: TInt: Indication what measurement types is/are disabled.
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::StifMeasurement()
+ {
+ return iDisableMeasurement;
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: TestModuleCrash
+
+ Description: This method is called only when test module crashed
+ with KErrServerTerminated (-15).
+ Clones new TestModuleController:
+ - Find crashed testmodulecontroller
+ - Creates new copy of that testmodulecontroller
+ - Replaces old crashed testmodulecontroller with this new one
+
+ Parameters: CTestModuleController* aTestModuleController: in: TestModuleController
+ Return Values: None
+
+ Errors/Exceptions: Leaves if error happens when adding clone to the list
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::TestModuleCrash(CTestModuleController* aTestModuleController)
+ {
+ TName crashModuleName = aTestModuleController->ModuleName(KNullDesC);
+ __TRACE(KInit, (_L("Handling crashed test module [%S]"), &crashModuleName));
+ TBool isTestScripter(EFalse);
+
+ // Find crashed test module controller
+ CTestScripterController* testScripterController = aTestModuleController->iTestScripterController;
+ if(testScripterController)
+ {
+ isTestScripter = ETrue;
+ }
+
+ // If UITestingSupport or SeparateProcesses is enabled, there is no need
+ // to create clone of Test Module Controller, because it will be created
+ // automatically when needed.
+ if(iUITestingSupport && crashModuleName.Find(KTestScripterName) == 0
+ || iSeparateProcesses
+ || (crashModuleName.Find(KPythonScripter) == 0)
+ )
+ {
+ __TRACE(KInit, (_L("Handling crashed test module with enabled UITestingSupport or SeparateProcesses is not needed")));
+ aTestModuleController->iTestModuleCrashDetected = ETrue;
+ return;
+ }
+
+ // Clone crashed module
+ TBool afterReset = EFalse;
+ if(iRebootParams && iRebootParams->iTestModule == crashModuleName)
+ {
+ afterReset = ETrue;
+ }
+
+ CTestModuleController* clone;
+ clone = aTestModuleController->CloneL(aTestModuleController, afterReset, testScripterController);
+
+ // Replaces crashed testmodulecontroller with this new one
+ // Note: Old Testmodulecontroller is deleted in CTestModuleController::CaseFinished
+ // that is called from CTestCase::~CTestCase()
+
+ TInt index = KErrNotFound;
+ if(isTestScripter)
+ {
+ index = testScripterController->iTestScripter.Find(aTestModuleController);
+ __TRACE(KInit, (_L("Crashed module index [%d]"), index));
+ if(index != KErrNotFound)
+ {
+ testScripterController->iTestScripter.Remove(index);
+ }
+ testScripterController->iTestScripter.Append(clone);
+ }
+ else
+ {
+ index = iModules.Find(aTestModuleController);
+ __TRACE(KInit, (_L("Crashed module index [%d]"), index));
+ if(index != KErrNotFound)
+ {
+ iModules.Remove(index);
+ }
+ iModules.Append(clone);
+ }
+ __TRACE(KInit, (_L("End of handling crashed test module")));
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: ExecuteCommandL
+
+ Description: Executes command received from test case.
+ The method was created to allow test case to kill itself.
+
+ Parameters: aTestCaseHandle: handler to test case
+ Return Values: None
+
+ Errors/Exceptions: Leaves if error happens when adding clone to the list
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngine::ExecuteCommandL(TCommand aCommand, TDesC8& aParamsPckg)
+ {
+ TInt testCaseHandle = 0;
+ // Get params
+ switch(aCommand)
+ {
+ case EStopExecution:
+ {
+ //Unpack received parameters
+ TStopExecutionCommandParams par;
+ TStopExecutionCommandParamsPckg parPack(par);
+ parPack.Copy(aParamsPckg);
+
+ __TRACE(KInit, (_L("CTestEngine::ExecuteCommandL received command [%d] type [%d] code [%d] test handle [%d]"), TInt(aCommand), TInt(par.iType), TInt(par.iCode), par.iTestCaseHandle));
+
+ //Get test case handle
+ testCaseHandle = par.iTestCaseHandle;
+
+ break;
+ }
+ case ESendTestModuleVersion:
+ {
+ TSendTestModuleVesionCommandParams par;
+ TSendTestModuleVesionCommandParamsPckg parPack(par);
+ parPack.Copy(aParamsPckg);
+
+ TTestModuleVersionInfo testModuleVersionInfo;
+ testModuleVersionInfo.iMajor = par.iMajor;
+ testModuleVersionInfo.iMinor = par.iMinor;
+ testModuleVersionInfo.iBuild = par.iBuild;
+ testModuleVersionInfo.iTestModuleName = par.iTestModuleName;
+ if(iTestReport)
+ {
+ iTestReport->AddTestModuleVersion(testModuleVersionInfo);
+ }
+
+ return;
+ }
+ default:
+ __TRACE(KError, (_L("CTestEngine::ExecuteCommandL Unknown command [%d]"), TInt(aCommand)));
+ return;
+ }
+
+ // Get test case from container
+ CTestCase* testCase = (CTestCase*)iTestCases->At(testCaseHandle);
+
+ // Log some info if invalid handle
+ if(testCase == NULL)
+ {
+ __TRACE(KInit, ( _L( "CTestEngine::ExecuteCommandL - invalid handle. Unable to get test case to execute command [%d]"), TInt(aCommand)));
+ return;
+ }
+
+ testCase->ExecuteCommandL(aCommand, aParamsPckg);
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: GetIndexForNewTestModuleController
+
+ Description: Returns new index for test module controller.
+ This number is appended to module controller name.
+ This method is used when option to run every test case in
+ separate process is set to on.
+
+ Parameters: aTestCaseHandle: handler to test case
+ Return Values: None
+
+ Errors/Exceptions: Leaves if error happens when adding clone to the list
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::GetIndexForNewTestModuleController(void)
+ {
+ return iIndexTestModuleControllers++;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngine
+
+ Method: AddTestCaseToTestReport
+
+ Description: Get parameters from message and add test case to test report.
+
+ Parameters: aMessage: message
+ Return Values: error id
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestEngine::AddTestCaseToTestReport(const RMessage2& aMessage)
+ {
+ if(iTestReport)
+ {
+ // Read test data
+ TTestInfo testInfo;
+ TTestInfoPckg testInfoPckg(testInfo);
+
+ TFullTestResult fullTestResult;
+ TFullTestResultPckg fullTestResultPckg(fullTestResult);
+
+ TRAPD(err, aMessage.ReadL(0, testInfoPckg));
+ if(err)
+ {
+ __TRACE(KError, (_L("Leave when reading TTestInfo in AddTestCaseToTestReport [%d]"), err));
+ return err;
+ }
+
+ TRAP(err, aMessage.ReadL(1, fullTestResultPckg));
+ if(err)
+ {
+ __TRACE(KError, (_L("Leave when reading TFullTestResult in AddTestCaseToTestReport [%d]"), err));
+ return err;
+ }
+
+ TRAP(err, iTestReport->AddTestCaseResultL(testInfo, fullTestResult, aMessage.Int2()));
+ if(err)
+ {
+ __TRACE(KError, (_L("Leave from test report in AddTestCaseToTestReport [%d]"), err));
+ return err;
+ }
+ }
+ else
+ {
+ __TRACE(KError, (_L("TestReport not initialized in AddTestCaseToTestReport")));
+ return KErrNotReady;
+ }
+
+ return KErrNone;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestEngineSubSession class member functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineSubSession
+
+ Method: CTestEngineSubSession
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to Test Engine
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CTestEngineSubSession::CTestEngineSubSession( CTestEngine* aEngine ) :
+ iTestEngine( aEngine )
+ {
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineSubSession
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestEngineSubSession::ConstructL()
+ {
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineSubSession
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to Test Engine
+
+ Return Values: CTestEngineSubSession* : pointer to created CTestEngineSubSession object
+
+ Errors/Exceptions: Leaves if ConstructL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEngineSubSession* CTestEngineSubSession::NewL( CTestEngine* aEngine )
+ {
+ CTestEngineSubSession* self = new ( ELeave ) CTestEngineSubSession( aEngine );
+ CleanupClosePushL( *self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestEngineSubSession
+
+ Method: ~CTestEngineSubSession
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestEngineSubSession::~CTestEngineSubSession()
+ {
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestCase class member functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: CTestCase
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to Test Engine
+ CTestModuleController* aModuleController: in: Pointer to
+ Module Controller
+ TTestInfo& aTestInfo: in: Test info for this test case
+ CTestModuleController* aRealModuleController: in: Pointer to
+ module controller used inside in scripter controller
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CTestCase::CTestCase( CTestEngine* aEngine,
+ CTestModuleController* aModuleController,
+ TTestInfo& aTestInfo,
+ CTestModuleController* aRealModuleController ) :
+ iTestEngine( aEngine ),
+ iTestModule( aModuleController ),
+ iRealModuleController (aRealModuleController)
+ {
+
+ // This method must be called to find out how
+ // many testcases are currently ongoing by increasing iTestCaseCounter.
+ // This is a part of the implementation for
+ // supporting test module crashing with -15
+ iTestModule->CaseCreated();
+
+ // Store handle to RTestServer
+ //If test scripter is used (it uses internally module controllers)
+ //then use it (real module controller).
+ if(iRealModuleController)
+ {
+ iTestServer = iRealModuleController->Server(aTestInfo);
+ }
+ else
+ {
+ iTestServer = iTestModule->Server( aTestInfo );
+ }
+
+ //If real test module controller is provided, increase test case count
+ if(iRealModuleController)
+ {
+ iRealModuleController->CaseCreated();
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: CTestReport* aTestReport: in: Pointer to Test Report
+ TTestInfo& aTestInfo: in: Test Info for this test case
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if RTestExecution::Open returns error
+ Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::ConstructL( CTestReport* aTestReport,
+ TTestInfo& aTestInfo )
+ {
+ __TRACE( KVerbose, ( _L( "CTestCase::ConstructL" ) ) );
+
+ // Open handle to RTestExecution
+ User::LeaveIfError( iTestExecution.Open( iTestServer,
+ aTestInfo.iTestCaseInfo.iCaseNumber, aTestInfo.iConfig ) );
+
+ // Make new test case runner
+ iTestCaseController = CTestCaseController::NewL( iTestEngine,
+ aTestReport, iTestModule->AtsLogger(), iTestExecution, aTestInfo );
+
+ // Make new test case printer
+ iTestCasePrint = CTestProgressNotifier::NewL( iTestEngine,
+ iTestExecution );
+
+ iTestCaseEvent = CTestEventNotifier::NewL( iTestEngine, iTestExecution );
+
+ iTestCaseRemoteCmd = CTestRemoteCmdNotifier::NewL( iTestEngine,
+ iTestExecution,
+ iTestCaseController,
+ iTestModule->AtsLogger() );
+
+ iTestCaseCommand = CTestCommandNotifier::NewL(iTestEngine, iTestExecution);
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to Test Engine
+ CTestModuleController* aModuleController: in: Pointer to
+ Module Controller
+ CTestReport* aTestReport: in: Pointer to Test Report
+ TTestInfo& aTestInfo: in: Test Info for this test case
+
+ Return Values: CTestCase* : pointer to created CTestCase object
+
+ Errors/Exceptions: Leaves if ConstructL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCase* CTestCase::NewL( CTestEngine* aEngine,
+ CTestModuleController* aModuleController,
+ CTestReport* aTestReport,
+ TTestInfo& aTestInfo,
+ CTestModuleController* aRealModuleController )
+ {
+ CTestCase* self = new ( ELeave ) CTestCase( aEngine, aModuleController, aTestInfo, aRealModuleController );
+ CleanupClosePushL( *self );
+ self->ConstructL( aTestReport, aTestInfo );
+ CleanupStack::Pop();
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: ~CTestCase
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestCase::~CTestCase()
+ {
+ CloseTestCase();
+
+ // This added method call is a part of the implementation for
+ // supporting test module crashing with -15.
+ // It checks that can old Testmodulecontroller be deletd or not
+ if( iTestModule != NULL )
+ {
+ iTestModule->CaseFinished();
+ }
+
+ //If real test module controller is provided, decrease test case count
+ if( iRealModuleController != NULL )
+ {
+ iRealModuleController->CaseFinished();
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: CloseTestCase
+
+ Description: Close session
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::CloseTestCase()
+ {
+ __TRACE( KVerbose, ( _L( "CTestCase::CloseTestCase" ) ) );
+
+ // Free allocated resources
+ delete iTestCaseController;
+ iTestCaseController = NULL;
+ delete iTestCasePrint;
+ iTestCasePrint = NULL;
+ delete iTestCaseRemoteCmd;
+ iTestCaseRemoteCmd = NULL;
+
+ delete iTestCaseEvent;
+ iTestCaseEvent = NULL;
+
+ delete iTestCaseCommand;
+ iTestCaseCommand = NULL;
+
+ iTestExecution.Close();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: RunTestCaseL
+
+ Description: Enumerates test cases
+
+ Parameters: const RMessage& aMessage: in: Server Message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::RunTestCaseL( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestCase::RunTestCaseL" ) ) );
+ // Start active objects for running test case
+ iTestCaseController->StartL( aMessage );
+ iTestCaseEvent->Start();
+ iTestCaseCommand->Start();
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: Pause
+
+ Description: Suspend the test case execution
+
+ Parameters: None
+
+ Return Values: TInt: Return value from RTestExecution::Pause
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCase::Pause()
+ {
+ __TRACE( KVerbose, ( _L( "CTestCase::Pause" ) ) );
+
+ return iTestExecution.Pause();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: Resume
+
+ Description: Resume the suspended test case execution
+
+ Parameters: None
+
+ Return Values: TInt: Return value from RTestExecution::Resume
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestCase::Resume()
+ {
+ __TRACE( KVerbose, ( _L( "CTestCase::Resume" ) ) );
+
+ return iTestExecution.Resume();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: NotifyProgressL
+
+ Description: Notifies progresses from Test Module
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if called StartL method leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::NotifyProgressL( const RMessage2& aMessage )
+ {
+ __TRACE( KVerbose, ( _L( "CTestCase::NotifyProgressL" ) ) );
+ iTestCasePrint->StartL( aMessage );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: NotifyRemoteTypeL
+
+ Description: Notifies remote commands from Test Module
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if called StartL method leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::NotifyRemoteTypeL( const RMessage2& aMessage )
+ {
+
+ __TRACE( KVerbose, ( _L( "CTestCase::NotifyRemoteTypeL" ) ) );
+ iTestCaseRemoteCmd->EnableReceive( aMessage );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: NotifyRemoteMsgL
+
+ Description: Notifies remote commands from Test Module
+
+ Parameters: const RMessage& aMessage: in: Server message
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if called StartL method leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::NotifyRemoteMsgL( const RMessage2& aMessage )
+ {
+
+ __TRACE( KVerbose, ( _L( "CTestCase::NotifyRemoteMsgL" ) ) );
+ switch( aMessage.Int1() )
+ {
+ case EStifCmdSend:
+ {
+ iTestCaseRemoteCmd->GetReceivedMsg( aMessage );
+ }
+ break;
+ case EStifCmdReceive:
+ {
+ TInt len = aMessage.Int2();
+ if( len <= 0 )
+ {
+ User::Leave( KErrGeneral );
+ }
+ HBufC8* buf = HBufC8::NewLC( len );
+
+ TPtr8 tmp = buf->Des();
+ aMessage.ReadL( 0, tmp );
+
+ TInt ret = iTestExecution.ReadRemoteCmdInfo( tmp, EStifCmdReceive );
+
+ CleanupStack::PopAndDestroy( buf );
+
+ aMessage.Complete( ret );
+ }
+ break;
+ case EStifCmdRebootProceed:
+ {
+ TInt value = 0;
+ TPckg<TInt> tmp( value );
+ aMessage.ReadL( 0, tmp );
+
+ TInt ret = iTestExecution.ReadRemoteCmdInfo( tmp,
+ EStifCmdRebootProceed,
+ value );
+ aMessage.Complete( ret );
+ }
+ break;
+ default:
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: CancelAsyncRequest
+
+ Description: Asynchronous requests are canceled by this function.
+
+ Parameters: const RMessage aMessage
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::CancelAsyncRequest( const RMessage2& aMessage )
+ {
+ switch ( aMessage.Int0() )
+ {
+ case ETestCaseRunTestCase:
+ {
+ iTestCaseController->Cancel();
+ iTestCaseEvent->Cancel();
+ break;
+ }
+ case ETestCaseNotifyProgress:
+ {
+ iTestCasePrint->Cancel();
+ break;
+ }
+ case ETestCaseNotifyRemoteType:
+ {
+ iTestCaseRemoteCmd->CancelReq();
+ break;
+ }
+ case ETestCaseNotifyCommand:
+ {
+ iTestCaseCommand->Cancel();
+ break;
+ }
+ default:
+ iTestEngine->PanicClient( EBadRequest, aMessage );
+ break;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: ModuleName
+
+ Description: Return the name of Test Module.
+
+ Parameters: None
+
+ Return Values: const TFileName& : Test Module owning this test case
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+const TDesC& CTestCase::ModuleName()
+ {
+ return iTestModule->ModuleName( KNullDesC );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: CtlEvent
+
+ Description: Control events
+
+ Parameters: const TEventIf& aEvent: in: Event
+ TRequestStatus& aStatus: in: Request status
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::CtlEvent( const TEventIf& aEvent, TRequestStatus& aStatus )
+ {
+ __ASSERT_ALWAYS( iTestCaseEvent, User::Panic( _L( "TestEngine event panic" ), KErrArgument ) );
+
+ iTestCaseEvent->CtlEvent( aEvent, aStatus );
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: CheckCtlEvent
+
+ Description: Check if CtlEvent should be called
+
+ Parameters: const TEventIf& aEvent: in: Event
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestCase::CheckCtlEvent( const TEventIf& aEvent )
+ {
+ return iTestCaseEvent->CheckCtlEvent( aEvent );
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: Logger
+
+ Description: Return the pointer to Logger.
+
+ Parameters: None
+
+ Return Values: CStifLogger*: Pointer to StifLogger
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CStifLogger* CTestCase::Logger()
+ {
+ return iTestEngine->Logger();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: ExecuteCommaandL
+
+ Description: Executes command received from test case.
+
+ Parameters: aStifCommand command to be executed
+ aParam1 parameter to command
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::ExecuteCommandL(TCommand aCommand, TDesC8& aParamsPckg)
+ {
+ switch(aCommand)
+ {
+ case EStopExecution:
+ {
+ //Unpack received parameters
+ TStopExecutionCommandParams par;
+ TStopExecutionCommandParamsPckg parPack(par);
+ parPack.Copy(aParamsPckg);
+
+ __TRACE(KVerbose, (_L("CTestCase::ExecuteCommandL command [%d] type [%d] code [%d]"), TInt(aCommand), TInt(par.iType), par.iCode));
+
+ iTestCaseController->Suicide(par.iType, par.iCode);
+ break;
+ }
+ default:
+ __TRACE(KVerbose, (_L("CTestCase::ExecuteCommandL unknown command [%d]"), TInt(aCommand)));
+ return;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: GetModuleControllers
+
+ Description: Return module controller and real module controller
+
+ Parameters: aRealModuleController: out: real module controller
+
+ Return Values: module controller
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController* CTestCase::GetModuleControllers(CTestModuleController** aRealModuleController)
+ {
+ *aRealModuleController = iRealModuleController;
+ return iTestModule;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: ResetModuleController
+
+ Description: Set new module controller for test case (only in case when
+ original controller crashed)
+
+ Parameters: aModuleController: in: new module controller
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::ResetModuleController(CTestModuleController* aModuleController)
+ {
+ iTestModule = aModuleController;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestCase
+
+ Method: ResetRealModuleController
+
+ Description: Set new real module controller for test case (only in case
+ when original controller crashed).
+
+ Parameters: aRealModuleController: in: new real module controller
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestCase::ResetRealModuleController(CTestModuleController* aRealModuleController)
+ {
+ iRealModuleController = aRealModuleController;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CRebootParams class member functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRebootParams
+
+ Method: CRebootParams
+
+ Description: Default constructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+CRebootParams::CRebootParams()
+ {
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRebootParams
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if RTestExecution::Open returns error
+ Leaves if some of called leaving methods leaves
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CRebootParams::ConstructL()
+ {
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRebootParams
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: none
+
+ Return Values: CRebootParams* : pointer to created CRebootParams object
+
+ Errors/Exceptions: Leaves if ConstructL leaves
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+CRebootParams* CRebootParams::NewL()
+ {
+
+ CRebootParams* self = new ( ELeave ) CRebootParams();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRebootParams
+
+ Method: ~CRebootParams
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+CRebootParams::~CRebootParams()
+ {
+
+ delete iTestModuleBuf;
+ iTestModuleBuf = 0;
+ delete iTestCaseFileBuf;
+ iTestCaseFileBuf = 0;
+ delete iTestCaseTitleBuf;
+ iTestCaseTitleBuf = 0;
+ delete iStateNameBuf;
+ iStateNameBuf = 0;
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRebootParams
+
+ Method: SetTestModuleNameL
+
+ Description: Setter
+
+ Parameters: const TDesC& aName: in: name to set
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if memory allocation fails
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CRebootParams::SetTestModuleNameL( const TDesC& aName )
+ {
+
+ delete iTestModuleBuf;
+ iTestModuleBuf = 0;
+ iTestModuleBuf = aName.AllocLC();
+ iTestModule.Set( iTestModuleBuf->Des() );
+ CleanupStack::Pop( iTestModuleBuf );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRebootParams
+
+ Method: SetTestModuleNameL
+
+ Description: Setter
+
+ Parameters: const TDesC& aName: in: name to set
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if memory allocation fails
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CRebootParams::SetTestCaseFileNameL( const TDesC& aName )
+ {
+
+ delete iTestCaseFileBuf;
+ iTestCaseFileBuf = 0;
+ iTestCaseFileBuf = aName.AllocLC();
+ iTestCaseFile.Set( iTestCaseFileBuf->Des() );
+ CleanupStack::Pop( iTestCaseFileBuf );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRebootParams
+
+ Method: SetTestModuleNameL
+
+ Description: Setter
+
+ Parameters: const TDesC& aName: in: name to set
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if memory allocation fails
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CRebootParams::SetTestCaseTitleL( const TDesC& aName )
+ {
+
+ delete iTestCaseTitleBuf;
+ iTestCaseTitleBuf = 0;
+ iTestCaseTitleBuf = aName.AllocLC();
+ iTestCaseTitle.Set( iTestCaseTitleBuf->Des() );
+ CleanupStack::Pop( iTestCaseTitleBuf );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CRebootParams
+
+ Method: SetTestModuleNameL
+
+ Description: Setter
+
+ Parameters: const TDesC& aName: in: name to set
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if memory allocation fails
+
+ Status: Draft
+
+-------------------------------------------------------------------------------
+*/
+void CRebootParams::SetTestCaseStateL( const TDesC& aName )
+ {
+
+ delete iStateNameBuf;
+ iStateNameBuf = 0;
+ iStateNameBuf = aName.AllocLC();
+ iStateName.Set( iStateNameBuf->Des() );
+ CleanupStack::Pop( iStateNameBuf );
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of TEventMsg class member functions.
+
+-------------------------------------------------------------------------------
+*/
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: TEventMsg
+
+ Method: TEventMsg
+
+ Description: Default constructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TEventMsg::TEventMsg():
+ TEventIf(),
+ iWaitPending(EFalse),
+ iStateEventPending(EFalse),
+ iStatus( NULL )
+ {
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: TEventMsg
+
+ Method: ~TEventMsg
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TEventMsg::~TEventMsg()
+ {
+ if( iWaitPending )
+ {
+ iWaitMsg.Complete( KErrCancel );
+ iWaitPending = EFalse;
+ }
+
+ if( iStatus )
+ {
+ User::RequestComplete( iStatus, KErrCancel );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: TEventMsg
+
+ Method: Set
+
+ Description: Set event.
+
+ Parameters: TEventType aEventType: in: Event type
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void TEventMsg::Set( TEventType aEventType )
+ {
+ iEventType = aEventType;
+ if( aEventType == EState )
+ {
+ iStateEventPending = ETrue;
+ }
+ if( iWaitPending )
+ {
+ TEventIf event;
+ event.Copy( *this );
+ TEventIfPckg eventIfPckg( event );
+ iWaitMsg.WriteL( 0, eventIfPckg );
+
+ iWaitMsg.Complete( KErrNone );
+ iWaitPending = EFalse;
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: TEventMsg
+
+ Method: Wait
+
+ Description: Wait event.
+
+ Parameters: const RMessage& aMessage: in: Message
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void TEventMsg::Wait( const RMessage2& aMessage )
+ {
+ if( iStateEventPending )
+ {
+ TEventIf event;
+ event.Copy( *this );
+ TEventIfPckg eventIfPckg( event );
+ aMessage.WriteL( 0, eventIfPckg );
+ aMessage.Complete( KErrNone );
+ }
+ else
+ {
+ iWaitMsg = aMessage;
+ iWaitPending = ETrue;
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: TEventMsg
+
+ Method: CancelWait
+
+ Description: Cancel pending Wait
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void TEventMsg::CancelWait()
+ {
+ if( iWaitPending )
+ {
+ iWaitMsg.Complete( KErrCancel );
+ iWaitPending = EFalse;
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: TEventMsg
+
+ Method: Release
+
+ Description: Release event. Unset released.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void TEventMsg::Release()
+ {
+
+ if( iStatus )
+ {
+ User::RequestComplete( iStatus, KErrNone );
+ }
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: TEventMsg
+
+ Method: Unset
+
+ Description: Unset event. Blocks until Release is called.
+
+ Parameters: TRequestStatus& aStatus: in: Status
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void TEventMsg::Unset( TRequestStatus& aStatus )
+ {
+
+ iStatus = &aStatus;
+
+ }
+
+// ================= OTHER EXPORTED FUNCTIONS =================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: StartEngine
+
+ Description: This is called from the client.
+
+ Parameters: None
+
+ Return Values: TInt KErrNone: No errors occured
+ KErrNoMemory: Memory is too low to create Test Engine
+ Other error code: Error got from iEngineThread.Create()
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+EXPORT_C TInt StartEngine()
+ {
+ __UHEAP_MARK;
+
+ // check server not already started
+ TFindServer findTestEngineServer( KTestEngineName );
+ TFullName name;
+ if ( findTestEngineServer.Next( name ) == KErrNone )
+ {
+ // Server already started, nothing to do
+ __UHEAP_MARKEND;
+ return KErrNone;
+ }
+
+ // Construct start-up information object
+ TThreadStartTestEngine* startInfo = new TThreadStartTestEngine();
+ if ( startInfo == NULL )
+ {
+ __UHEAP_MARKEND;
+ return KErrNoMemory;
+ }
+
+ startInfo->iStarted.CreateLocal( 0 ); // Create start-up semaphore
+
+ // Create thread
+ TInt ret = startInfo->iEngineThread.Create(
+ KTestEngineName , // name of thread
+ CTestEngineServer::ThreadFunction, // thread function
+ KDefaultStackSize*4, // stack
+ KTestEngineMinHeapSize,KTestEngineMaxHeapSize*4,// Heap
+ startInfo // parameter to thread
+ // function
+ );
+
+ if ( ret != KErrNone )
+ {
+ startInfo->iStarted.Close();
+ delete startInfo;
+ __UHEAP_MARKEND;
+ return ret;
+ }
+
+ // Now start thread
+ startInfo->iEngineThread.SetPriority( EPriorityMuchMore ); // set its
+ // priority
+ startInfo->iEngineThread.Resume(); // kick it
+ // into life
+
+ // Wait until the thread is started
+ startInfo->iStarted.Wait();
+
+ // Clean-up
+ startInfo->iEngineThread.Close();
+ startInfo->iStarted.Close();
+
+
+ delete startInfo;
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+
+ }
+
+
+// End of File